We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Embed information on 3rd-party libraries
I would like to create a place (I suggest the "about" modal) where all the great used libraries get mentioned and their licenses linked. The legal depts. in bigger organisations like to see something like that to be sure there is nothing bad going on licensing wise ([like this](https://www.theregister.com/2021/03/25/ruby_rails_code/)).

@SchrodingersGat 
Thoughts / did I oversee that there already is something like that? I made a tech-demo (not polished) how it could look in [my public repo](https://github.com/matmair/InvenTree/tree/3rdparty-info).

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `InvenTree/part/templatetags/inventree_extras.py`
Content:
```
1 """ This module provides template tags for extra functionality
2 over and above the built-in Django tags.
3 """
4 import os
5 
6 from django import template
7 from django.urls import reverse
8 from django.utils.safestring import mark_safe
9 from django.templatetags.static import StaticNode
10 from InvenTree import version, settings
11 
12 import InvenTree.helpers
13 
14 from common.models import InvenTreeSetting, ColorTheme
15 
16 register = template.Library()
17 
18 
19 @register.simple_tag()
20 def define(value, *args, **kwargs):
21     """
22     Shortcut function to overcome the shortcomings of the django templating language
23 
24     Use as follows: {% define "hello_world" as hello %}
25 
26     Ref: https://stackoverflow.com/questions/1070398/how-to-set-a-value-of-a-variable-inside-a-template-code
27     """
28 
29     return value
30 
31 
32 @register.simple_tag()
33 def decimal(x, *args, **kwargs):
34     """ Simplified rendering of a decimal number """
35 
36     return InvenTree.helpers.decimal2string(x)
37 
38 
39 @register.simple_tag()
40 def str2bool(x, *args, **kwargs):
41     """ Convert a string to a boolean value """
42 
43     return InvenTree.helpers.str2bool(x)
44 
45 
46 @register.simple_tag()
47 def inrange(n, *args, **kwargs):
48     """ Return range(n) for iterating through a numeric quantity """
49     return range(n)
50     
51 
52 @register.simple_tag()
53 def multiply(x, y, *args, **kwargs):
54     """ Multiply two numbers together """
55     return InvenTree.helpers.decimal2string(x * y)
56 
57 
58 @register.simple_tag()
59 def add(x, y, *args, **kwargs):
60     """ Add two numbers together """
61     return x + y
62     
63 
64 @register.simple_tag()
65 def part_allocation_count(build, part, *args, **kwargs):
66     """ Return the total number of <part> allocated to <build> """
67 
68     return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part))
69 
70 
71 @register.simple_tag()
72 def inventree_instance_name(*args, **kwargs):
73     """ Return the InstanceName associated with the current database """
74     return version.inventreeInstanceName()
75 
76 
77 @register.simple_tag()
78 def inventree_title(*args, **kwargs):
79     """ Return the title for the current instance - respecting the settings """
80     return version.inventreeInstanceTitle()
81 
82 
83 @register.simple_tag()
84 def inventree_version(*args, **kwargs):
85     """ Return InvenTree version string """
86     return version.inventreeVersion()
87 
88 
89 @register.simple_tag()
90 def django_version(*args, **kwargs):
91     """ Return Django version string """
92     return version.inventreeDjangoVersion()
93 
94 
95 @register.simple_tag()
96 def inventree_commit_hash(*args, **kwargs):
97     """ Return InvenTree git commit hash string """
98     return version.inventreeCommitHash()
99 
100 
101 @register.simple_tag()
102 def inventree_commit_date(*args, **kwargs):
103     """ Return InvenTree git commit date string """
104     return version.inventreeCommitDate()
105 
106 
107 @register.simple_tag()
108 def inventree_github_url(*args, **kwargs):
109     """ Return URL for InvenTree github site """
110     return "https://github.com/InvenTree/InvenTree/"
111 
112 
113 @register.simple_tag()
114 def inventree_docs_url(*args, **kwargs):
115     """ Return URL for InvenTree documenation site """
116     return "https://inventree.readthedocs.io/"
117 
118 
119 @register.simple_tag()
120 def setting_object(key, *args, **kwargs):
121     """
122     Return a setting object speciifed by the given key
123     (Or return None if the setting does not exist)
124     """
125 
126     setting = InvenTreeSetting.get_setting_object(key)
127 
128     return setting
129 
130 
131 @register.simple_tag()
132 def settings_value(key, *args, **kwargs):
133     """
134     Return a settings value specified by the given key
135     """
136 
137     return InvenTreeSetting.get_setting(key)
138 
139 
140 @register.simple_tag()
141 def get_color_theme_css(username):
142     try:
143         user_theme = ColorTheme.objects.filter(user=username).get()
144         user_theme_name = user_theme.name
145         if not user_theme_name or not ColorTheme.is_valid_choice(user_theme):
146             user_theme_name = 'default'
147     except ColorTheme.DoesNotExist:
148         user_theme_name = 'default'
149 
150     # Build path to CSS sheet
151     inventree_css_sheet = os.path.join('css', 'color-themes', user_theme_name + '.css')
152 
153     # Build static URL
154     inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet)
155 
156     return inventree_css_static_url
157 
158 
159 @register.simple_tag()
160 def authorized_owners(group):
161     """ Return authorized owners """
162 
163     owners = []
164 
165     try:
166         for owner in group.get_related_owners(include_group=True):
167             owners.append(owner.owner)
168     except AttributeError:
169         # group is None
170         pass
171     except TypeError:
172         # group.get_users returns None
173         pass
174     
175     return owners
176 
177 
178 @register.simple_tag()
179 def object_link(url_name, pk, ref):
180     """ Return highlighted link to object """
181 
182     ref_url = reverse(url_name, kwargs={'pk': pk})
183     return mark_safe('<b><a href="{}">{}</a></b>'.format(ref_url, ref))
184 
185 
186 class I18nStaticNode(StaticNode):
187     """
188     custom StaticNode
189     replaces a variable named *lng* in the path with the current language
190     """
191     def render(self, context):
192         self.path.var = self.path.var.format(lng=context.request.LANGUAGE_CODE)
193         ret = super().render(context)
194         return ret
195 
196 
197 @register.tag('i18n_static')
198 def do_i18n_static(parser, token):
199     """
200     Overrides normal static, adds language - lookup for prerenderd files #1485
201 
202     usage (like static):
203     {% i18n_static path [as varname] %}
204     """
205     bits = token.split_contents()
206     loc_name = settings.STATICFILES_I18_PREFIX
207 
208     # change path to called ressource
209     bits[1] = f"'{loc_name}/{{lng}}.{bits[1][1:-1]}'"
210     token.contents = ' '.join(bits)
211     return I18nStaticNode.handle_token(parser, token)
212
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -116,6 +116,12 @@
     return "https://inventree.readthedocs.io/"
 
 
+@register.simple_tag()
+def inventree_credits_url(*args, **kwargs):
+    """ Return URL for InvenTree credits site """
+    return "https://inventree.readthedocs.io/en/latest/credits/"
+
+
 @register.simple_tag()
 def setting_object(key, *args, **kwargs):
     """

{"golden_diff": "diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py\n--- a/InvenTree/part/templatetags/inventree_extras.py\n+++ b/InvenTree/part/templatetags/inventree_extras.py\n@@ -116,6 +116,12 @@\n     return \"https://inventree.readthedocs.io/\"\n \n \n+@register.simple_tag()\n+def inventree_credits_url(*args, **kwargs):\n+    \"\"\" Return URL for InvenTree credits site \"\"\"\n+    return \"https://inventree.readthedocs.io/en/latest/credits/\"\n+\n+\n @register.simple_tag()\n def setting_object(key, *args, **kwargs):\n     \"\"\"\n", "issue": "Embed information on 3rd-party libraries\nI would like to create a place (I suggest the \"about\" modal) where all the great used libraries get mentioned and their licenses linked. The legal depts. in bigger organisations like to see something like that to be sure there is nothing bad going on licensing wise ([like this](https://www.theregister.com/2021/03/25/ruby_rails_code/)).\r\n\r\n@SchrodingersGat \r\nThoughts / did I oversee that there already is something like that? I made a tech-demo (not polished) how it could look in [my public repo](https://github.com/matmair/InvenTree/tree/3rdparty-info).\n", "before_files": [{"content": "\"\"\" This module provides template tags for extra functionality\nover and above the built-in Django tags.\n\"\"\"\nimport os\n\nfrom django import template\nfrom django.urls import reverse\nfrom django.utils.safestring import mark_safe\nfrom django.templatetags.static import StaticNode\nfrom InvenTree import version, settings\n\nimport InvenTree.helpers\n\nfrom common.models import InvenTreeSetting, ColorTheme\n\nregister = template.Library()\n\n\n@register.simple_tag()\ndef define(value, *args, **kwargs):\n    \"\"\"\n    Shortcut function to overcome the shortcomings of the django templating language\n\n    Use as follows: {% define \"hello_world\" as hello %}\n\n    Ref: https://stackoverflow.com/questions/1070398/how-to-set-a-value-of-a-variable-inside-a-template-code\n    \"\"\"\n\n    return value\n\n\n@register.simple_tag()\ndef decimal(x, *args, **kwargs):\n    \"\"\" Simplified rendering of a decimal number \"\"\"\n\n    return InvenTree.helpers.decimal2string(x)\n\n\n@register.simple_tag()\ndef str2bool(x, *args, **kwargs):\n    \"\"\" Convert a string to a boolean value \"\"\"\n\n    return InvenTree.helpers.str2bool(x)\n\n\n@register.simple_tag()\ndef inrange(n, *args, **kwargs):\n    \"\"\" Return range(n) for iterating through a numeric quantity \"\"\"\n    return range(n)\n    \n\n@register.simple_tag()\ndef multiply(x, y, *args, **kwargs):\n    \"\"\" Multiply two numbers together \"\"\"\n    return InvenTree.helpers.decimal2string(x * y)\n\n\n@register.simple_tag()\ndef add(x, y, *args, **kwargs):\n    \"\"\" Add two numbers together \"\"\"\n    return x + y\n    \n\n@register.simple_tag()\ndef part_allocation_count(build, part, *args, **kwargs):\n    \"\"\" Return the total number of <part> allocated to <build> \"\"\"\n\n    return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part))\n\n\n@register.simple_tag()\ndef inventree_instance_name(*args, **kwargs):\n    \"\"\" Return the InstanceName associated with the current database \"\"\"\n    return version.inventreeInstanceName()\n\n\n@register.simple_tag()\ndef inventree_title(*args, **kwargs):\n    \"\"\" Return the title for the current instance - respecting the settings \"\"\"\n    return version.inventreeInstanceTitle()\n\n\n@register.simple_tag()\ndef inventree_version(*args, **kwargs):\n    \"\"\" Return InvenTree version string \"\"\"\n    return version.inventreeVersion()\n\n\n@register.simple_tag()\ndef django_version(*args, **kwargs):\n    \"\"\" Return Django version string \"\"\"\n    return version.inventreeDjangoVersion()\n\n\n@register.simple_tag()\ndef inventree_commit_hash(*args, **kwargs):\n    \"\"\" Return InvenTree git commit hash string \"\"\"\n    return version.inventreeCommitHash()\n\n\n@register.simple_tag()\ndef inventree_commit_date(*args, **kwargs):\n    \"\"\" Return InvenTree git commit date string \"\"\"\n    return version.inventreeCommitDate()\n\n\n@register.simple_tag()\ndef inventree_github_url(*args, **kwargs):\n    \"\"\" Return URL for InvenTree github site \"\"\"\n    return \"https://github.com/InvenTree/InvenTree/\"\n\n\n@register.simple_tag()\ndef inventree_docs_url(*args, **kwargs):\n    \"\"\" Return URL for InvenTree documenation site \"\"\"\n    return \"https://inventree.readthedocs.io/\"\n\n\n@register.simple_tag()\ndef setting_object(key, *args, **kwargs):\n    \"\"\"\n    Return a setting object speciifed by the given key\n    (Or return None if the setting does not exist)\n    \"\"\"\n\n    setting = InvenTreeSetting.get_setting_object(key)\n\n    return setting\n\n\n@register.simple_tag()\ndef settings_value(key, *args, **kwargs):\n    \"\"\"\n    Return a settings value specified by the given key\n    \"\"\"\n\n    return InvenTreeSetting.get_setting(key)\n\n\n@register.simple_tag()\ndef get_color_theme_css(username):\n    try:\n        user_theme = ColorTheme.objects.filter(user=username).get()\n        user_theme_name = user_theme.name\n        if not user_theme_name or not ColorTheme.is_valid_choice(user_theme):\n            user_theme_name = 'default'\n    except ColorTheme.DoesNotExist:\n        user_theme_name = 'default'\n\n    # Build path to CSS sheet\n    inventree_css_sheet = os.path.join('css', 'color-themes', user_theme_name + '.css')\n\n    # Build static URL\n    inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet)\n\n    return inventree_css_static_url\n\n\n@register.simple_tag()\ndef authorized_owners(group):\n    \"\"\" Return authorized owners \"\"\"\n\n    owners = []\n\n    try:\n        for owner in group.get_related_owners(include_group=True):\n            owners.append(owner.owner)\n    except AttributeError:\n        # group is None\n        pass\n    except TypeError:\n        # group.get_users returns None\n        pass\n    \n    return owners\n\n\n@register.simple_tag()\ndef object_link(url_name, pk, ref):\n    \"\"\" Return highlighted link to object \"\"\"\n\n    ref_url = reverse(url_name, kwargs={'pk': pk})\n    return mark_safe('<b><a href=\"{}\">{}</a></b>'.format(ref_url, ref))\n\n\nclass I18nStaticNode(StaticNode):\n    \"\"\"\n    custom StaticNode\n    replaces a variable named *lng* in the path with the current language\n    \"\"\"\n    def render(self, context):\n        self.path.var = self.path.var.format(lng=context.request.LANGUAGE_CODE)\n        ret = super().render(context)\n        return ret\n\n\n@register.tag('i18n_static')\ndef do_i18n_static(parser, token):\n    \"\"\"\n    Overrides normal static, adds language - lookup for prerenderd files #1485\n\n    usage (like static):\n    {% i18n_static path [as varname] %}\n    \"\"\"\n    bits = token.split_contents()\n    loc_name = settings.STATICFILES_I18_PREFIX\n\n    # change path to called ressource\n    bits[1] = f\"'{loc_name}/{{lng}}.{bits[1][1:-1]}'\"\n    token.contents = ' '.join(bits)\n    return I18nStaticNode.handle_token(parser, token)\n", "path": "InvenTree/part/templatetags/inventree_extras.py"}], "after_files": [{"content": "\"\"\" This module provides template tags for extra functionality\nover and above the built-in Django tags.\n\"\"\"\nimport os\n\nfrom django import template\nfrom django.urls import reverse\nfrom django.utils.safestring import mark_safe\nfrom django.templatetags.static import StaticNode\nfrom InvenTree import version, settings\n\nimport InvenTree.helpers\n\nfrom common.models import InvenTreeSetting, ColorTheme\n\nregister = template.Library()\n\n\n@register.simple_tag()\ndef define(value, *args, **kwargs):\n    \"\"\"\n    Shortcut function to overcome the shortcomings of the django templating language\n\n    Use as follows: {% define \"hello_world\" as hello %}\n\n    Ref: https://stackoverflow.com/questions/1070398/how-to-set-a-value-of-a-variable-inside-a-template-code\n    \"\"\"\n\n    return value\n\n\n@register.simple_tag()\ndef decimal(x, *args, **kwargs):\n    \"\"\" Simplified rendering of a decimal number \"\"\"\n\n    return InvenTree.helpers.decimal2string(x)\n\n\n@register.simple_tag()\ndef str2bool(x, *args, **kwargs):\n    \"\"\" Convert a string to a boolean value \"\"\"\n\n    return InvenTree.helpers.str2bool(x)\n\n\n@register.simple_tag()\ndef inrange(n, *args, **kwargs):\n    \"\"\" Return range(n) for iterating through a numeric quantity \"\"\"\n    return range(n)\n    \n\n@register.simple_tag()\ndef multiply(x, y, *args, **kwargs):\n    \"\"\" Multiply two numbers together \"\"\"\n    return InvenTree.helpers.decimal2string(x * y)\n\n\n@register.simple_tag()\ndef add(x, y, *args, **kwargs):\n    \"\"\" Add two numbers together \"\"\"\n    return x + y\n    \n\n@register.simple_tag()\ndef part_allocation_count(build, part, *args, **kwargs):\n    \"\"\" Return the total number of <part> allocated to <build> \"\"\"\n\n    return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part))\n\n\n@register.simple_tag()\ndef inventree_instance_name(*args, **kwargs):\n    \"\"\" Return the InstanceName associated with the current database \"\"\"\n    return version.inventreeInstanceName()\n\n\n@register.simple_tag()\ndef inventree_title(*args, **kwargs):\n    \"\"\" Return the title for the current instance - respecting the settings \"\"\"\n    return version.inventreeInstanceTitle()\n\n\n@register.simple_tag()\ndef inventree_version(*args, **kwargs):\n    \"\"\" Return InvenTree version string \"\"\"\n    return version.inventreeVersion()\n\n\n@register.simple_tag()\ndef django_version(*args, **kwargs):\n    \"\"\" Return Django version string \"\"\"\n    return version.inventreeDjangoVersion()\n\n\n@register.simple_tag()\ndef inventree_commit_hash(*args, **kwargs):\n    \"\"\" Return InvenTree git commit hash string \"\"\"\n    return version.inventreeCommitHash()\n\n\n@register.simple_tag()\ndef inventree_commit_date(*args, **kwargs):\n    \"\"\" Return InvenTree git commit date string \"\"\"\n    return version.inventreeCommitDate()\n\n\n@register.simple_tag()\ndef inventree_github_url(*args, **kwargs):\n    \"\"\" Return URL for InvenTree github site \"\"\"\n    return \"https://github.com/InvenTree/InvenTree/\"\n\n\n@register.simple_tag()\ndef inventree_docs_url(*args, **kwargs):\n    \"\"\" Return URL for InvenTree documenation site \"\"\"\n    return \"https://inventree.readthedocs.io/\"\n\n\n@register.simple_tag()\ndef inventree_credits_url(*args, **kwargs):\n    \"\"\" Return URL for InvenTree credits site \"\"\"\n    return \"https://inventree.readthedocs.io/en/latest/credits/\"\n\n\n@register.simple_tag()\ndef setting_object(key, *args, **kwargs):\n    \"\"\"\n    Return a setting object speciifed by the given key\n    (Or return None if the setting does not exist)\n    \"\"\"\n\n    setting = InvenTreeSetting.get_setting_object(key)\n\n    return setting\n\n\n@register.simple_tag()\ndef settings_value(key, *args, **kwargs):\n    \"\"\"\n    Return a settings value specified by the given key\n    \"\"\"\n\n    return InvenTreeSetting.get_setting(key)\n\n\n@register.simple_tag()\ndef get_color_theme_css(username):\n    try:\n        user_theme = ColorTheme.objects.filter(user=username).get()\n        user_theme_name = user_theme.name\n        if not user_theme_name or not ColorTheme.is_valid_choice(user_theme):\n            user_theme_name = 'default'\n    except ColorTheme.DoesNotExist:\n        user_theme_name = 'default'\n\n    # Build path to CSS sheet\n    inventree_css_sheet = os.path.join('css', 'color-themes', user_theme_name + '.css')\n\n    # Build static URL\n    inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet)\n\n    return inventree_css_static_url\n\n\n@register.simple_tag()\ndef authorized_owners(group):\n    \"\"\" Return authorized owners \"\"\"\n\n    owners = []\n\n    try:\n        for owner in group.get_related_owners(include_group=True):\n            owners.append(owner.owner)\n    except AttributeError:\n        # group is None\n        pass\n    except TypeError:\n        # group.get_users returns None\n        pass\n    \n    return owners\n\n\n@register.simple_tag()\ndef object_link(url_name, pk, ref):\n    \"\"\" Return highlighted link to object \"\"\"\n\n    ref_url = reverse(url_name, kwargs={'pk': pk})\n    return mark_safe('<b><a href=\"{}\">{}</a></b>'.format(ref_url, ref))\n\n\nclass I18nStaticNode(StaticNode):\n    \"\"\"\n    custom StaticNode\n    replaces a variable named *lng* in the path with the current language\n    \"\"\"\n    def render(self, context):\n        self.path.var = self.path.var.format(lng=context.request.LANGUAGE_CODE)\n        ret = super().render(context)\n        return ret\n\n\n@register.tag('i18n_static')\ndef do_i18n_static(parser, token):\n    \"\"\"\n    Overrides normal static, adds language - lookup for prerenderd files #1485\n\n    usage (like static):\n    {% i18n_static path [as varname] %}\n    \"\"\"\n    bits = token.split_contents()\n    loc_name = settings.STATICFILES_I18_PREFIX\n\n    # change path to called ressource\n    bits[1] = f\"'{loc_name}/{{lng}}.{bits[1][1:-1]}'\"\n    token.contents = ' '.join(bits)\n    return I18nStaticNode.handle_token(parser, token)\n", "path": "InvenTree/part/templatetags/inventree_extras.py"}]}