From 18a875bbee4bd768400b43e899998d53b9ead292 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 21:55:17 +0200 Subject: [PATCH 1/8] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4f01249..2122f12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "inventree-wled-locator" -version = "0.2.1" +version = "0.2.2" description="Use WLED to locate InvenTree StockLocations." readme = "README.md" license = {text = "MIT license"} From 0ee50a752588ea11b181595fff17d38be0ad090b Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 22:27:27 +0200 Subject: [PATCH 2/8] Add list of current locations --- src/inventree_wled_locator/WledPlugin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index 05ac1ac..eda3632 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -80,9 +80,17 @@ def setup_urls(self): def get_settings_content(self, request): """Add context to the settings panel.""" + stocklocations = StockLocation.objects.filter(metadata__isnull=False).all() + + target_locs = [{'name': loc.pathstring, 'led': loc.get_metadata('wled_led'), 'id': loc.id} for loc in stocklocations if loc.get_metadata('wled_led')] + stock_strings = ''.join([f'{a["name"]}{a["led"]}{a["id"]}' for a in target_locs]) return f"""

WLED controlls

Turn off all LEDs: turn off

+ + + {stock_strings} +
LocationLEDActions
""" def _set_led(self, target_led: int = None): From 258b55d83a314a0832720de806e13ebafd5d377f Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 22:51:51 +0200 Subject: [PATCH 3/8] add permission check --- src/inventree_wled_locator/WledPlugin.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index eda3632..fdccc50 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -14,10 +14,15 @@ from plugin import InvenTreePlugin from plugin.mixins import LocateMixin, SettingsMixin, UrlsMixin from stock.models import StockLocation +from django.contrib.auth.decorators import user_passes_test logger = logging.getLogger('inventree') +def superuser_check(user): + return user.is_superuser + + class WledPlugin(UrlsMixin, LocateMixin, SettingsMixin, InvenTreePlugin): """Use WLED to locate InvenTree StockLocations..""" @@ -67,6 +72,7 @@ def locate_stock_location(self, location_pk): except (ValueError, StockLocation.DoesNotExist): # pragma: no cover logger.error(f"Location ID {location_pk} does not exist!") + @user_passes_test(superuser_check) def view_off(self, request): """Turn off all LEDs.""" self._set_led() From 00d36fca02dd2919a9d292f5ee5ffdae237ae451 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 23:23:46 +0200 Subject: [PATCH 4/8] fix permission test --- src/inventree_wled_locator/WledPlugin.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index fdccc50..1f3896b 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -14,12 +14,12 @@ from plugin import InvenTreePlugin from plugin.mixins import LocateMixin, SettingsMixin, UrlsMixin from stock.models import StockLocation -from django.contrib.auth.decorators import user_passes_test logger = logging.getLogger('inventree') def superuser_check(user): + """Check if a user is a superuser.""" return user.is_superuser @@ -72,9 +72,11 @@ def locate_stock_location(self, location_pk): except (ValueError, StockLocation.DoesNotExist): # pragma: no cover logger.error(f"Location ID {location_pk} does not exist!") - @user_passes_test(superuser_check) def view_off(self, request): """Turn off all LEDs.""" + if not superuser_check(request.user): + raise PermissionError("Only superusers can turn off all LEDs") + self._set_led() return redirect(self.settings_url) From b10ce6dbeacb82aa915b13dbe00b40844bd92617 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 23:24:12 +0200 Subject: [PATCH 5/8] enable usage of first LED --- src/inventree_wled_locator/WledPlugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index 1f3896b..b6c97b9 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -61,8 +61,8 @@ def locate_stock_location(self, location_pk): try: location = StockLocation.objects.get(pk=location_pk) - led_nbr = location.get_metadata('wled_led') - if led_nbr: + led_nbr = int(location.get_metadata('wled_led')) + if led_nbr is not None: self._set_led(led_nbr) else: # notify superusers that a location has no LED number @@ -111,5 +111,5 @@ def _set_led(self, target_led: int = None): requests.post(base_url, json={"seg": {"i": [0, self.get_setting("MAX_LEDS"), color_black]}}) # Turn on target led - if target_led: + if target_led is not None: requests.post(base_url, json={"seg": {"i": [target_led, color_marked]}}) From aee3419bebb430c83676b2a7963034dbf0158a62 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 23:24:24 +0200 Subject: [PATCH 6/8] Add register/unregister function --- src/inventree_wled_locator/WledPlugin.py | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index b6c97b9..3b9e95b 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -80,10 +80,36 @@ def view_off(self, request): self._set_led() return redirect(self.settings_url) + def view_unregister(self, request, pk): + """Unregister an LED.""" + if not superuser_check(request.user): + raise PermissionError("Only superusers can turn off all LEDs") + + try: + item = StockLocation.objects.get(pk=pk) + item.set_metadata('wled_led', None) + except StockLocation.DoesNotExist: + pass + return redirect(self.settings_url) + + def view_register(self, request, pk, led): + """Register an LED.""" + if not superuser_check(request.user): + raise PermissionError("Only superusers can turn off all LEDs") + + try: + item = StockLocation.objects.get(pk=pk) + item.set_metadata('wled_led', led) + except StockLocation.DoesNotExist: + pass + return redirect(self.settings_url) + def setup_urls(self): """Return the URLs defined by this plugin.""" return [ url(r'off/', self.view_off, name='off'), + url(r'unregister/(?P\d+)/', self.view_unregister, name='unregister'), + url(r'register/(?P\d+)/(?P\w+)/', self.view_register, name='register'), ] def get_settings_content(self, request): @@ -91,7 +117,11 @@ def get_settings_content(self, request): stocklocations = StockLocation.objects.filter(metadata__isnull=False).all() target_locs = [{'name': loc.pathstring, 'led': loc.get_metadata('wled_led'), 'id': loc.id} for loc in stocklocations if loc.get_metadata('wled_led')] - stock_strings = ''.join([f'{a["name"]}{a["led"]}{a["id"]}' for a in target_locs]) + stock_strings = ''.join([f""" + {a["name"]} + {a["led"]} + unregister + """ for a in target_locs]) return f"""

WLED controlls

Turn off all LEDs: turn off

From 7fb90ff6e712de53a515725511740d54a85b9895 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Sun, 25 Jun 2023 23:29:01 +0200 Subject: [PATCH 7/8] use btn for action --- src/inventree_wled_locator/WledPlugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index 3b9e95b..de88297 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -120,11 +120,11 @@ def get_settings_content(self, request): stock_strings = ''.join([f""" {a["name"]} {a["led"]} - unregister + unregister """ for a in target_locs]) return f"""

WLED controlls

-

Turn off all LEDs: turn off

+ Turn off {stock_strings} From 095b5194774d3ec9521ebac54f5cc47a1b7f0bc2 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Mon, 26 Jun 2023 00:28:06 +0200 Subject: [PATCH 8/8] Add UI to handle registering --- src/inventree_wled_locator/WledPlugin.py | 28 +++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/inventree_wled_locator/WledPlugin.py b/src/inventree_wled_locator/WledPlugin.py index de88297..3db73be 100644 --- a/src/inventree_wled_locator/WledPlugin.py +++ b/src/inventree_wled_locator/WledPlugin.py @@ -1,5 +1,6 @@ """Use WLED to locate InvenTree StockLocations..""" +import json import logging import requests @@ -7,6 +8,7 @@ from django.conf.urls import url from django.contrib.auth import get_user_model from django.core.validators import MinValueValidator +from django.http import JsonResponse from django.shortcuts import redirect from django.urls import reverse from django.utils.translation import ugettext_lazy as _ @@ -92,11 +94,18 @@ def view_unregister(self, request, pk): pass return redirect(self.settings_url) - def view_register(self, request, pk, led): + def view_register(self, request, pk=None, led=None, context=None): """Register an LED.""" if not superuser_check(request.user): raise PermissionError("Only superusers can turn off all LEDs") + if pk is None and led is None and str(request.body, encoding='utf8') == '': + return JsonResponse({'actions': {'POST': ['stocklocation', 'led', ], }}) + elif request.body is not None: + data = json.loads(request.body) + pk = data.get('stocklocation') + led = data.get('led') + try: item = StockLocation.objects.get(pk=pk) item.set_metadata('wled_led', led) @@ -110,6 +119,7 @@ def setup_urls(self): url(r'off/', self.view_off, name='off'), url(r'unregister/(?P\d+)/', self.view_unregister, name='unregister'), url(r'register/(?P\d+)/(?P\w+)/', self.view_register, name='register'), + url(r'register/', self.view_register, name='register-simple'), ] def get_settings_content(self, request): @@ -125,10 +135,26 @@ def get_settings_content(self, request): return f"""

WLED controlls

Turn off +
LocationLEDActions
{stock_strings}
LocationLEDActions
+ """ def _set_led(self, target_led: int = None):