First commit

This commit is contained in:
Magnus Walbeck 2024-05-16 20:57:33 +02:00
commit 64bb4da7dd
Signed by: mwalbeck
SSH key fingerprint: SHA256:LW2enW+zg6O/tGp+u4fVcpo+4Bn9y1qGj9SxUIBdK3s
18 changed files with 604 additions and 0 deletions

18
.editorconfig Normal file
View file

@ -0,0 +1,18 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
[**.py]
indent_style = space
indent_size = 4
[**.js]
indent_style = space
indent_size = 4

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
*.pyc
*.swp
.idea
*.iml
build
dist
*.egg*
.DS_Store
*.zip

4
MANIFEST.in Normal file
View file

@ -0,0 +1,4 @@
include README.md
recursive-include octoprint_QRCodeSpoolSwitcher/templates *
recursive-include octoprint_QRCodeSpoolSwitcher/translations *
recursive-include octoprint_QRCodeSpoolSwitcher/static *

17
README.md Normal file
View file

@ -0,0 +1,17 @@
# OctoPrint-Qrcodespoolswitcher
**TODO:** Describe what your plugin does.
## Setup
Install via the bundled [Plugin Manager](https://docs.octoprint.org/en/master/bundledplugins/pluginmanager.html)
or manually using this URL:
https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher/archive/master.zip
**TODO:** Describe how to install your plugin, if more needs to be done than just installing it via pip or through
the plugin manager.
## Configuration
**TODO:** Describe your plugin's configuration options (if any).

8
babel.cfg Normal file
View file

@ -0,0 +1,8 @@
[python: */**.py]
[jinja2: */**.jinja2]
silent=false
extensions=jinja2.ext.do, octoprint.util.jinja.trycatch
[javascript: */**.js]
extract_messages = gettext, ngettext

View file

@ -0,0 +1,101 @@
---
layout: plugin
id: QRCodeSpoolSwitcher
title: OctoPrint-Qrcodespoolswitcher
description: Switch selected spool using QR codes and a webcam
authors:
- Magnus Walbeck
license: AGPLv3
# TODO
date: today's date in format YYYY-MM-DD, e.g. 2015-04-21
homepage: https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher
source: https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher
archive: https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher/archive/master.zip
# TODO
# Set this to true if your plugin uses the dependency_links setup parameter to include
# library versions not yet published on PyPi. SHOULD ONLY BE USED IF THERE IS NO OTHER OPTION!
#follow_dependency_links: false
# TODO
tags:
- a list
- of tags
- that apply
- to your plugin
- (take a look at the existing plugins for what makes sense here)
# TODO
# When registering a plugin on plugins.octoprint.org, all screenshots should be uploaded not linked from external sites.
screenshots:
- url: url of a screenshot, /assets/img/...
alt: alt-text of a screenshot
caption: caption of a screenshot
- url: url of another screenshot, /assets/img/...
alt: alt-text of another screenshot
caption: caption of another screenshot
- ...
# TODO
featuredimage: url of a featured image for your plugin, /assets/img/...
# TODO
# You only need the following if your plugin requires specific OctoPrint versions or
# specific operating systems to function - you can safely remove the whole
# "compatibility" block if this is not the case.
compatibility:
# List of compatible versions
#
# A single version number will be interpretated as a minimum version requirement,
# e.g. "1.3.1" will show the plugin as compatible to OctoPrint versions 1.3.1 and up.
# More sophisticated version requirements can be modelled too by using PEP440
# compatible version specifiers.
#
# You can also remove the whole "octoprint" block. Removing it will default to all
# OctoPrint versions being supported.
octoprint:
- 1.4.0
# List of compatible operating systems
#
# Valid values:
#
# - windows
# - linux
# - macos
# - freebsd
#
# There are also two OS groups defined that get expanded on usage:
#
# - posix: linux, macos and freebsd
# - nix: linux and freebsd
#
# You can also remove the whole "os" block. Removing it will default to all
# operating systems being supported.
os:
- linux
- windows
- macos
- freebsd
# Compatible Python version
#
# It is recommended to only support Python 3 for new plugins, in which case this should be ">=3,<4"
#
# Plugins that wish to support both Python 2 and 3 should set it to ">=2.7,<4".
#
# Plugins that only support Python 2 will not be accepted into the plugin repository.
python: ">=3,<4"
---
**TODO**: Longer description of your plugin, configuration examples etc. This part will be visible on the page at
http://plugins.octoprint.org/plugin/QRCodeSpoolSwitcher/

16
extras/README.txt Normal file
View file

@ -0,0 +1,16 @@
Currently Cookiecutter generates the following helpful extras to this folder:
QRCodeSpoolSwitcher.md
Data file for plugins.octoprint.org. Fill in the missing TODOs once your
plugin is ready for release and file a PR as described at
https://plugins.octoprint.org/help/registering/ to get it published.
github/bug_report.yml
A GitHub issue form for bug reports. Adjust as desired & place in your
repository as `.github/bug_report.yml` to activate.
github/feature_request.yml
A GitHub issue form for feature requests. Adjust as desired and place in
your repository as `.github/feature_request.yml` to activate.
This folder may be safely removed if you don't need it.

View file

@ -0,0 +1,96 @@
name: 🐛 Report a bug
description: Create a bug report to help improve OctoPrint-Qrcodespoolswitcher
body:
- type: markdown
attributes:
value: >-
**Thank you for wanting to report a bug in OctoPrint-Qrcodespoolswitcher!**
* First, be sure you are running the [latest version of the OctoPrint-Qrcodespoolswitcher plugin](https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher/releases).
* You will also need to [enable debugging on the plugin](https://docs.octoprint.org/en/master/configuration/logging_yaml.html).
* This may be done through the *Settings* > *OctoPrint* > *Logging* > *Logging Levels* section.
* Select the "octoprint.plugins.QRCodeSpoolSwitcher" name, and make sure Level is "DEBUG".
* Save, then restart OctoPrint, which allows the developers to see debug information from the moment the plugin is loaded.
* Finally, when submitting a bug report, you **must** [include a Systeminfo Bundle](https://community.octoprint.org/t/what-is-a-systeminfo-bundle-and-how-can-i-obtain-one/29887), generated after the point the bug occurs. This allows the developers to examine the debug logs produced from your plugin installation.
Thank you for your help!
- type: textarea
attributes:
label: The problem
description: >-
Describe the issue you are experiencing here. Tell us what you were trying to do
step by step, and what happened that you did not expect.
Provide a clear and concise description of what the problem is and include as many
details as possible.
placeholder: |
1. ...
2. ...
3. ...
validations:
required: true
- type: markdown
attributes:
value: |
## Environment
- type: input
attributes:
label: Version of OctoPrint-Qrcodespoolswitcher
description: Can be found in *Settings* > *Plugin Manager*, next to "OctoPrint-Qrcodespoolswitcher".
validations:
required: true
- type: input
attributes:
label: Version of OctoPrint
description: Can be found in the lower left corner of the web interface.
validations:
required: true
- type: input
attributes:
label: Operating system running OctoPrint
description: >-
OctoPi, Linux, Windows, MacOS, something else? With version please? OctoPi's
version can be found in `/etc/octopi_version` or in the lower left corner of the
web interface.
validations:
required: true
- type: input
attributes:
label: Printer model & used firmware incl. version
description: If applicable, always include if unsure
- type: input
attributes:
label: Browser and version of browser, operating system running browser
description: If applicable, always include if unsure
- type: markdown
attributes:
value: |
## Logs and other files needed for analysis
- type: markdown
attributes:
value: >-
Please also be sure to upload the following files below:
* Systeminfo Bundle: See [here](https://community.octoprint.org/t/what-is-a-systeminfo-bundle-and-how-can-i-obtain-one/29887) if you don't know where to find that. Just attach down below as-is. Note that you'll need at least OctoPrint 1.6.0 for this to be available - we no longer accept bug reports created for older versions than this.
* If you are reporting an issue that involves communicating with you printer, **be sure to enable `serial.log` before reproducing and creating the Systeminfo Bundle**!
* Your browser's JavaScript console, if you are reporting a problem with the
user interface. See [here](https://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers) on where to find that.
* If possible, screenshots or videos showing the problem, especially if you
are reporting a problem with the user interface!
* GCODE files with which to reproduce, if you are reporting an issue with
GCODE file analysis or printing behaviour.
Please be aware that unless at least Systeminfo Bundle is included, your bug report
will not be processed and closed after a while.
- type: checkboxes
attributes:
label: Checklist of files to include below
options:
- label: Systeminfo Bundle (always include!)
required: true
- label: Contents of the JavaScript browser console (always include in cases of issues with the user interface)
- label: Screenshots and/or videos showing the problem (always include in case of issues with the user interface)
- label: GCODE file with which to reproduce (always include in case of issues with GCODE analysis or printing behaviour)
- type: textarea
attributes:
label: Additional information & file uploads

View file

@ -0,0 +1,26 @@
name: ✨ Request a feature
description: Request a new feature to implement in OctoPrint-Qrcodespoolswitcher
title: "[Request]"
body:
- type: markdown
attributes:
value: >
**Thank you for wanting to request a feature in OctoPrint-Qrcodespoolswitcher!**
- type: textarea
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear and concise description of what the problem is. Eg, "I'm always frustrated when [...]".
- type: textarea
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,136 @@
# coding=utf-8
from __future__ import absolute_import
import threading
import cv2
import numpy as np
import requests
from time import sleep
import octoprint.plugin
class QrcodespoolswitcherPlugin(
octoprint.plugin.StartupPlugin,
octoprint.plugin.SettingsPlugin,
octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.EventHandlerPlugin,
):
def __init__(self):
self.snapshot = ""
self.toolId = 0
self.selectedSpoolId = None
self.commitCurrentSpoolValues = True
self.frequency = 5
self.watching = False
def get_settings_defaults(self):
return {
"snapshot": "http://127.0.0.1:8080/?action=snapshot",
"toolId": 0,
"commitCurrentSpoolValues": True,
"frequency": 5,
}
def get_assets(self):
return {
"js": ["js/QRCodeSpoolSwitcher.js"],
"css": ["css/QRCodeSpoolSwitcher.css"],
"less": ["less/QRCodeSpoolSwitcher.less"],
}
def get_update_information(self):
return {
"QRCodeSpoolSwitcher": {
"displayName": "Qrcodespoolswitcher Plugin",
"displayVersion": self._plugin_version,
"type": "github_release",
"user": "mwalbeck",
"repo": "OctoPrint-Qrcodespoolswitcher",
"current": self._plugin_version,
"pip": "https://git.walbeck.it/mwalbeck/OctoPrint-Qrcodespoolswitcher/archive/{target_version}.zip",
}
}
def on_after_startup(self):
self.snapshot = self._settings.get(["snapshot"])
self.toolId = self._settings.get_int(["toolId"])
self.frequency = self._settings.get_int(["frequency"])
self.commitCurrentSpoolValues = self._settings.get_boolean(
["commitCurrentSpoolValues"]
)
self._logger.info("Starting QR code watcher")
watcher = threading.Thread(target=self.watch_for_qr)
watcher.start()
def on_event(self, event, payload):
if event == "plugin_spoolmanager_spool_selected":
if payload["toolId"] == self.toolId:
if payload["databaseId"] != self.selectedSpoolId:
self.selectedSpoolId = payload["databaseId"]
def watch_for_qr(self):
self.watching = True
qrcode_detector = cv2.QRCodeDetector()
while self.watching:
sleep(self.frequency)
try:
response = requests.get(self.snapshot, timeout=2)
response.raise_for_status()
except requests.RequestException as e:
self._logger.error(f"Failed to fetch image for QR code scaning: {e}")
continue
image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
image = cv2.imdecode(image_array, cv2.IMREAD_UNCHANGED)
retval, decoded_info, points, straight_qrcode = (
qrcode_detector.detectAndDecodeMulti(image)
)
if retval:
self._logger.info(decoded_info)
for string in decoded_info:
if "SpoolManager/selectSpoolByQRCode" in string:
spoolId = int(string.split("/")[-1])
self._logger.info(f"Found spool {spoolId}")
if spoolId != self.selectedSpoolId:
self.select_spool(spoolId)
break
def select_spool(self, spoolId):
self.selectedSpoolId = spoolId
self._logger.info(f"Changed active spool to {spoolId}")
# payload = {
# "databaseId": spoolId,
# "toolIndex": self.toolId,
# "commitCurrentSpoolValues": self.commitCurrentSpoolValues,
# }
# try:
# requests.put(
# "http://localhost:5000/plugin/SpoolManager/selectSpool", json=payload
# )
# except requests.RequestException as e:
# self._logger.error(f"Error occured during request to change spool: {e}")
__plugin_name__ = "QRCodeSpoolSwitcher"
__plugin_pythoncompat__ = ">=3,<4"
def __plugin_load__():
global __plugin_implementation__
__plugin_implementation__ = QrcodespoolswitcherPlugin()
global __plugin_hooks__
__plugin_hooks__ = {
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information
}

View file

@ -0,0 +1 @@
/* TODO: Have your plugin's CSS files generated to here. */

View file

@ -0,0 +1,29 @@
/*
* View model for OctoPrint-Qrcodespoolswitcher
*
* Author: Magnus Walbeck
* License: AGPLv3
*/
$(function() {
function QrcodespoolswitcherViewModel(parameters) {
var self = this;
// assign the injected parameters, e.g.:
// self.loginStateViewModel = parameters[0];
// self.settingsViewModel = parameters[1];
// TODO: Implement your plugin's view model here.
}
/* view model class, parameters for constructor, container to bind to
* Please see http://docs.octoprint.org/en/master/plugins/viewmodels.html#registering-custom-viewmodels for more details
* and a full list of the available options.
*/
OCTOPRINT_VIEWMODELS.push({
construct: QrcodespoolswitcherViewModel,
// ViewModels your plugin depends on, e.g. loginStateViewModel, settingsViewModel, ...
dependencies: [ /* "loginStateViewModel", "settingsViewModel" */ ],
// Elements to bind to, e.g. #settings_plugin_QRCodeSpoolSwitcher, #tab_plugin_QRCodeSpoolSwitcher, ...
elements: [ /* ... */ ]
});
});

View file

@ -0,0 +1 @@
// TODO: Put your plugin's LESS here, have it generated to ../css.

View file

@ -0,0 +1 @@
Put your plugin's Jinja2 templates here.

9
requirements.txt Normal file
View file

@ -0,0 +1,9 @@
###
# This file is only here to make sure that something like
#
# pip install -e .
#
# works as expected. Requirements can be found in setup.py.
###
.

2
setup.cfg Normal file
View file

@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1

102
setup.py Normal file
View file

@ -0,0 +1,102 @@
# coding=utf-8
########################################################################################################################
### Do not forget to adjust the following variables to your own plugin.
# The plugin's identifier, has to be unique
plugin_identifier = "QRCodeSpoolSwitcher"
# The plugin's python package, should be "octoprint_<plugin identifier>", has to be unique
plugin_package = "octoprint_QRCodeSpoolSwitcher"
# The plugin's human readable name. Can be overwritten within OctoPrint's internal data via __plugin_name__ in the
# plugin module
plugin_name = "OctoPrint-Qrcodespoolswitcher"
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.0"
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
plugin_description = """Switch selected spool using QR codes and a webcam"""
# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
plugin_author = "Magnus Walbeck"
# The plugin's author's mail address.
plugin_author_email = "mw@mwalbeck.org"
# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
plugin_url = "https://github.com/mwalbeck/OctoPrint-Qrcodespoolswitcher"
# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
plugin_license = "AGPLv3"
# Any additional requirements besides OctoPrint should be listed here
plugin_requires = ["opencv-python"]
### --------------------------------------------------------------------------------------------------------------------
### More advanced options that you usually shouldn't have to touch follow after this point
### --------------------------------------------------------------------------------------------------------------------
# Additional package data to install for this plugin. The subfolders "templates", "static" and "translations" will
# already be installed automatically if they exist. Note that if you add something here you'll also need to update
# MANIFEST.in to match to ensure that python setup.py sdist produces a source distribution that contains all your
# files. This is sadly due to how python's setup.py works, see also http://stackoverflow.com/a/14159430/2028598
plugin_additional_data = []
# Any additional python packages you need to install with your plugin that are not contained in <plugin_package>.*
plugin_additional_packages = []
# Any python packages within <plugin_package>.* you do NOT want to install with your plugin
plugin_ignored_packages = []
# Additional parameters for the call to setuptools.setup. If your plugin wants to register additional entry points,
# define dependency links or other things like that, this is the place to go. Will be merged recursively with the
# default setup parameters as provided by octoprint_setuptools.create_plugin_setup_parameters using
# octoprint.util.dict_merge.
#
# Example:
# plugin_requires = ["someDependency==dev"]
# additional_setup_parameters = {"dependency_links": ["https://github.com/someUser/someRepo/archive/master.zip#egg=someDependency-dev"]}
# "python_requires": ">=3,<4" blocks installation on Python 2 systems, to prevent confused users and provide a helpful error.
# Remove it if you would like to support Python 2 as well as 3 (not recommended).
additional_setup_parameters = {"python_requires": ">=3,<4"}
########################################################################################################################
from setuptools import setup
try:
import octoprint_setuptools
except:
print(
"Could not import OctoPrint's setuptools, are you sure you are running that under "
"the same python installation that OctoPrint is installed under?"
)
import sys
sys.exit(-1)
setup_parameters = octoprint_setuptools.create_plugin_setup_parameters(
identifier=plugin_identifier,
package=plugin_package,
name=plugin_name,
version=plugin_version,
description=plugin_description,
author=plugin_author,
mail=plugin_author_email,
url=plugin_url,
license=plugin_license,
requires=plugin_requires,
additional_packages=plugin_additional_packages,
ignored_packages=plugin_ignored_packages,
additional_data=plugin_additional_data,
)
if len(additional_setup_parameters):
from octoprint.util import dict_merge
setup_parameters = dict_merge(setup_parameters, additional_setup_parameters)
setup(**setup_parameters)

28
translations/README.txt Normal file
View file

@ -0,0 +1,28 @@
Your plugin's translations will reside here. The provided setup.py supports a
couple of additional commands to make managing your translations easier:
babel_extract
Extracts any translateable messages (marked with Jinja's `_("...")` or
JavaScript's `gettext("...")`) and creates the initial `messages.pot` file.
babel_refresh
Reruns extraction and updates the `messages.pot` file.
babel_new --locale=<locale>
Creates a new translation folder for locale `<locale>`.
babel_compile
Compiles the translations into `mo` files, ready to be used within
OctoPrint.
babel_pack --locale=<locale> [ --author=<author> ]
Packs the translation for locale `<locale>` up as an installable
language pack that can be manually installed by your plugin's users. This is
interesting for languages you can not guarantee to keep up to date yourself
with each new release of your plugin and have to depend on contributors for.
If you want to bundle translations with your plugin, create a new folder
`octoprint_QRCodeSpoolSwitcher/translations`. When that folder exists,
an additional command becomes available:
babel_bundle --locale=<locale>
Moves the translation for locale `<locale>` to octoprint_QRCodeSpoolSwitcher/translations,
effectively bundling it with your plugin. This is interesting for languages
you can guarantee to keep up to date yourself with each new release of your
plugin.