mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	Plugin url fix (#9833)
* Handle error when loading plugin URLs - Error separation between plugins - Format plugin URLs outside the plugin code - Add "catch-all" URL * Attempt to resolve URL * Accept 404 error * Cleanup * Tweak unit tests
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| """Plugin mixin class for UrlsMixin.""" | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.urls import include, re_path | ||||
|  | ||||
| import structlog | ||||
|  | ||||
| @@ -72,12 +71,8 @@ class UrlsMixin: | ||||
|  | ||||
|     @property | ||||
|     def urlpatterns(self): | ||||
|         """Urlpatterns for this plugin.""" | ||||
|         if self.has_urls: | ||||
|             return re_path( | ||||
|                 f'^{self.slug}/', include((self.urls, self.slug)), name=self.slug | ||||
|             ) | ||||
|         return None | ||||
|         """URL patterns for this plugin.""" | ||||
|         return self.urls or None | ||||
|  | ||||
|     @property | ||||
|     def has_urls(self): | ||||
|   | ||||
| @@ -113,13 +113,10 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase): | ||||
|         target_pattern = re_path( | ||||
|             f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name | ||||
|         ) | ||||
|         self.assertEqual( | ||||
|             self.mixin.urlpatterns.reverse_dict, target_pattern.reverse_dict | ||||
|         ) | ||||
|  | ||||
|         # resolve the view | ||||
|         self.assertEqual(self.mixin.urlpatterns.resolve('/testpath').func(), 'ccc') | ||||
|         self.assertEqual(self.mixin.urlpatterns.reverse('test'), 'testpath') | ||||
|         self.assertEqual(target_pattern.resolve('/testpath').func(), 'ccc') | ||||
|         self.assertEqual(target_pattern.reverse('test'), 'testpath') | ||||
|  | ||||
|         # no url | ||||
|         self.assertIsNone(self.mixin_nothing.urls) | ||||
|   | ||||
| @@ -2,8 +2,11 @@ | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.urls import include, re_path | ||||
| from django.urls.exceptions import Resolver404 | ||||
| from django.views.generic.base import RedirectView | ||||
|  | ||||
| from common.validators import get_global_setting | ||||
| from InvenTree.exceptions import log_error | ||||
| from plugin import PluginMixinEnum | ||||
|  | ||||
| PLUGIN_BASE = 'plugin'  # Constant for links | ||||
| @@ -16,8 +19,35 @@ def get_plugin_urls(): | ||||
|     urls = [] | ||||
|  | ||||
|     if get_global_setting('ENABLE_PLUGINS_URL', False) or settings.PLUGIN_TESTING_SETUP: | ||||
|         for plugin in registry.plugins.values(): | ||||
|             if plugin.mixin_enabled(PluginMixinEnum.URLS): | ||||
|                 urls.append(plugin.urlpatterns) | ||||
|         for plugin in registry.with_mixin(PluginMixinEnum.URLS): | ||||
|             try: | ||||
|                 if plugin_urls := plugin.urlpatterns: | ||||
|                     # Check if the plugin has a custom URL pattern | ||||
|                     for url in plugin_urls: | ||||
|                         # Attempt to resolve against the URL pattern as a validation check | ||||
|                         try: | ||||
|                             url.resolve('') | ||||
|                         except Resolver404: | ||||
|                             pass | ||||
|  | ||||
|                     urls.append( | ||||
|                         re_path( | ||||
|                             f'^{plugin.slug}/', | ||||
|                             include((plugin_urls, plugin.slug)), | ||||
|                             name=plugin.slug, | ||||
|                         ) | ||||
|                     ) | ||||
|             except Exception: | ||||
|                 log_error('get_plugin_urls', plugin=plugin.slug) | ||||
|                 continue | ||||
|  | ||||
|     # Redirect anything else to the root index | ||||
|     urls.append( | ||||
|         re_path( | ||||
|             r'^.*$', | ||||
|             RedirectView.as_view(url=f'/{settings.FRONTEND_URL_BASE}', permanent=False), | ||||
|             name='index', | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|     return re_path(f'^{PLUGIN_BASE}/', include((urls, 'plugin'))) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user