Coverage for src/backend/InvenTree/plugin/urls.py: 24%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1"""URL lookup for plugin app.""" 

2 

3from django.conf import settings 

4from django.urls import include, re_path 

5from django.urls.exceptions import Resolver404 

6from django.views.generic.base import RedirectView 

7 

8from common.validators import get_global_setting 

9from InvenTree.exceptions import log_error 

10from plugin import PluginMixinEnum 

11 

12PLUGIN_BASE = 'plugin' # Constant for links 

13 

14 

15def get_plugin_urls(): 

16 """Returns a urlpattern that can be integrated into the global urls.""" 

17 from plugin.registry import registry 

18 

19 urls = [] 

20 

21 if registry.is_ready: 

22 if ( 

23 get_global_setting('ENABLE_PLUGINS_URL', False) 

24 or settings.PLUGIN_TESTING_SETUP 

25 ): 

26 for plugin in registry.with_mixin(PluginMixinEnum.URLS): 

27 try: 

28 if plugin_urls := plugin.urlpatterns: 

29 # Check if the plugin has a custom URL pattern 

30 for url in plugin_urls: 

31 # Attempt to resolve against the URL pattern as a validation check 

32 try: 

33 url.resolve('') 

34 except Resolver404: 

35 pass 

36 

37 urls.append( 

38 re_path( 

39 f'^{plugin.slug}/', 

40 include((plugin_urls, plugin.slug)), 

41 name=plugin.slug, 

42 ) 

43 ) 

44 except Exception: 

45 log_error('get_plugin_urls', plugin=plugin.slug) 

46 continue 

47 

48 # Redirect anything else to the root index 

49 urls.append( 

50 re_path( 

51 r'^.*$', 

52 RedirectView.as_view(url=f'/{settings.FRONTEND_URL_BASE}', permanent=False), 

53 name='index', 

54 ) 

55 ) 

56 

57 return re_path(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))