We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Hide "Edit chants (Fulltext & Volpiano editor)" link from my sources sidebar on flatpages
To prevent encountering a 404 error, we should hide the link from the "My Sources" sidebar on flatpages when the corresponding source has no chants.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `django/cantusdb_project/main_app/templatetags/helper_tags.py`
Content:
```
1 import calendar
2 from typing import Union, Optional
3 from django import template
4 from main_app.models import Source
5 from articles.models import Article
6 from django.utils.safestring import mark_safe
7 from django.urls import reverse
8 from django.core.paginator import Paginator
9 
10 
11 register = template.Library()
12 
13 
14 @register.simple_tag(takes_context=False)
15 def recent_articles():
16     """
17     Generates a html unordered list of recent articles for display on the homepage
18 
19     Used in:
20         templates/flatpages/default.html
21     """
22     articles = Article.objects.order_by("-date_created")[:5]
23     list_item_template = '<li style="padding-bottom: 0.5em;"><a href="{url}">{title}</a><br><small>{date}</small></li>'
24     list_items = [
25         list_item_template.format(
26             url=a.get_absolute_url(),
27             title=a.title,
28             date=a.date_created.strftime("%A %B %-d, %Y"),
29         )
30         for a in articles
31     ]
32     list_items_string = "".join(list_items)
33     recent_articles_string = "<ul>{lis}</ul>".format(lis=list_items_string)
34     return mark_safe(recent_articles_string)
35 
36 
37 @register.simple_tag(takes_context=False)
38 def my_sources(user):
39     """
40     Generates a html unordered list of sources the currently logged-in user has access to edit, for display on the homepage
41 
42     Used in:
43         templates/flatpages/default.html
44     """
45 
46     def make_source_detail_link_with_siglum(source):
47         id = source.id
48         siglum = source.rism_siglum
49         url = reverse("source-detail", args=[id])
50         link = '<a href="{}">{}</a>'.format(url, siglum)
51         return link
52 
53     def make_source_detail_link_with_title(source):
54         id = source.id
55         title = source.title
56         url = reverse("source-detail", args=[id])
57         link = '<a href="{}">{}</a>'.format(url, title)
58         return link
59 
60     def make_add_new_chants_link(source):
61         id = source.id
62         url = reverse("chant-create", args=[id])
63         link = '<a href="{}">+ Add new chant</a>'.format(url)
64         return link
65 
66     def make_edit_chants_link(source):
67         id = source.id
68         url = reverse("source-edit-chants", args=[id])
69         link = '<a href="{}">Edit chants (Fulltext & Volpiano editor)</a>'.format(url)
70         return link
71 
72     def make_links_for_source(source):
73         link_with_siglum = make_source_detail_link_with_siglum(source)
74         link_with_title = make_source_detail_link_with_title(source)
75         add_new_chants_link = make_add_new_chants_link(source)
76         edit_chants_link = make_edit_chants_link(source)
77         template = """{sigl}<br>
78         <small>
79             <b>{title}</b><br>
80             {add}<br>
81             {edit}<br>
82         </small>
83         """
84         links_string = template.format(
85             sigl=link_with_siglum,
86             title=link_with_title,
87             add=add_new_chants_link,
88             edit=edit_chants_link,
89         )
90         return links_string
91 
92     MAX_SOURCES_TO_DISPLAY = 6
93     sources = list(user.sources_user_can_edit.all())[:MAX_SOURCES_TO_DISPLAY]
94     source_links = [make_links_for_source(source) for source in sources]
95     list_items = ["<li>{}</li>".format(link) for link in source_links]
96     joined_list_items = "".join(list_items)
97     links_ul = "<ul>{}</ul>".format(joined_list_items)
98     return mark_safe(links_ul)
99 
100 
101 @register.filter(name="month_to_string")
102 def month_to_string(value: Optional[Union[str, int]]) -> Optional[Union[str, int]]:
103     """
104     Converts month number to textual representation, 3 letters (Jan, Mar, etc)
105 
106     used in:
107         main_app/templates/feast_detail.html
108         main_app/templates/feast_list.html
109     """
110     if type(value) == int and value in range(1, 13):
111         return calendar.month_abbr[value]
112     else:
113         return value
114 
115 
116 @register.simple_tag(takes_context=True)
117 def url_add_get_params(context, **kwargs):
118     """
119     accounts for the situations where there may be two paginations in one page
120 
121     Used in:
122         main_app/templates/pagination.html
123         main_app/templates/user_source_list.html
124     """
125     query = context["request"].GET.copy()
126     if "page" in kwargs:
127         query.pop("page", None)
128     if "page2" in kwargs:
129         query.pop("page2", None)
130     query.update(kwargs)
131     return query.urlencode()
132 
133 
134 @register.simple_tag(takes_context=False)
135 def source_links():
136     """
137     Generates a series of html option tags linking to sources in Cantus Dabase, for display on the homepage
138 
139     Used in:
140         templates/flatpages/default.html
141     """
142     sources = (
143         Source.objects.filter(published=True, segment__id=4063)
144         .exclude(siglum=None)
145         .values("siglum", "id")
146         .order_by("siglum")
147     )
148     options = ""
149     for source in sources:
150         option_str = (
151             f"<option value=source/{source['id']}>{source['siglum']}</option>\n"
152         )
153         options += option_str
154 
155     return mark_safe(options)
156 
157 
158 @register.filter
159 def classname(obj):
160     """
161     Returns the name of the object's class
162     A use-case is: {% if object|classname == "Notation" %}
163 
164     Used in:
165         main_app/templates/content_overview.html
166     """
167     return obj.__class__.__name__
168 
169 
170 @register.filter
171 def admin_url_name(class_name, action):
172     """
173     Accepts the name of a class in "main_app", and an action (either "change" or "delete") as arguments.
174     Returns the name of the URL for changing/deleting an object in the admin interface.
175 
176     Used in:
177         main_app/templates/content_overview.html
178     """
179     class_name = class_name.lower()
180     action = action.lower()
181 
182     return f"admin:main_app_{class_name}_{action}"
183 
184 
185 @register.filter(name="has_group")
186 def has_group(user, group_name):
187     """
188     Used in:
189         templates/base.html
190     """
191     return user.groups.filter(name=group_name).exists()
192 
193 
194 @register.simple_tag(takes_context=True)
195 def get_user_source_pagination(context):
196     user_created_sources = (
197         Source.objects.filter(created_by=context["user"])
198         .order_by("-date_created")
199         .distinct()
200     )
201     paginator = Paginator(user_created_sources, 10)
202     page_number = context["request"].GET.get("page")
203     page_obj = paginator.get_page(page_number)
204     return page_obj
205
```
--- 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/django/cantusdb_project/main_app/templatetags/helper_tags.py b/django/cantusdb_project/main_app/templatetags/helper_tags.py
--- a/django/cantusdb_project/main_app/templatetags/helper_tags.py
+++ b/django/cantusdb_project/main_app/templatetags/helper_tags.py
@@ -73,7 +73,10 @@
         link_with_siglum = make_source_detail_link_with_siglum(source)
         link_with_title = make_source_detail_link_with_title(source)
         add_new_chants_link = make_add_new_chants_link(source)
-        edit_chants_link = make_edit_chants_link(source)
+        if source.chant_set.exists():
+            edit_chants_link = make_edit_chants_link(source)
+        else:
+            edit_chants_link = ""
         template = """{sigl}<br>
         <small>
             <b>{title}</b><br>

{"golden_diff": "diff --git a/django/cantusdb_project/main_app/templatetags/helper_tags.py b/django/cantusdb_project/main_app/templatetags/helper_tags.py\n--- a/django/cantusdb_project/main_app/templatetags/helper_tags.py\n+++ b/django/cantusdb_project/main_app/templatetags/helper_tags.py\n@@ -73,7 +73,10 @@\n         link_with_siglum = make_source_detail_link_with_siglum(source)\n         link_with_title = make_source_detail_link_with_title(source)\n         add_new_chants_link = make_add_new_chants_link(source)\n-        edit_chants_link = make_edit_chants_link(source)\n+        if source.chant_set.exists():\n+            edit_chants_link = make_edit_chants_link(source)\n+        else:\n+            edit_chants_link = \"\"\n         template = \"\"\"{sigl}<br>\n         <small>\n             <b>{title}</b><br>\n", "issue": "Hide \"Edit chants (Fulltext & Volpiano editor)\" link from my sources sidebar on flatpages\nTo prevent encountering a 404 error, we should hide the link from the \"My Sources\" sidebar on flatpages when the corresponding source has no chants.\n", "before_files": [{"content": "import calendar\nfrom typing import Union, Optional\nfrom django import template\nfrom main_app.models import Source\nfrom articles.models import Article\nfrom django.utils.safestring import mark_safe\nfrom django.urls import reverse\nfrom django.core.paginator import Paginator\n\n\nregister = template.Library()\n\n\n@register.simple_tag(takes_context=False)\ndef recent_articles():\n    \"\"\"\n    Generates a html unordered list of recent articles for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n    articles = Article.objects.order_by(\"-date_created\")[:5]\n    list_item_template = '<li style=\"padding-bottom: 0.5em;\"><a href=\"{url}\">{title}</a><br><small>{date}</small></li>'\n    list_items = [\n        list_item_template.format(\n            url=a.get_absolute_url(),\n            title=a.title,\n            date=a.date_created.strftime(\"%A %B %-d, %Y\"),\n        )\n        for a in articles\n    ]\n    list_items_string = \"\".join(list_items)\n    recent_articles_string = \"<ul>{lis}</ul>\".format(lis=list_items_string)\n    return mark_safe(recent_articles_string)\n\n\n@register.simple_tag(takes_context=False)\ndef my_sources(user):\n    \"\"\"\n    Generates a html unordered list of sources the currently logged-in user has access to edit, for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n\n    def make_source_detail_link_with_siglum(source):\n        id = source.id\n        siglum = source.rism_siglum\n        url = reverse(\"source-detail\", args=[id])\n        link = '<a href=\"{}\">{}</a>'.format(url, siglum)\n        return link\n\n    def make_source_detail_link_with_title(source):\n        id = source.id\n        title = source.title\n        url = reverse(\"source-detail\", args=[id])\n        link = '<a href=\"{}\">{}</a>'.format(url, title)\n        return link\n\n    def make_add_new_chants_link(source):\n        id = source.id\n        url = reverse(\"chant-create\", args=[id])\n        link = '<a href=\"{}\">+ Add new chant</a>'.format(url)\n        return link\n\n    def make_edit_chants_link(source):\n        id = source.id\n        url = reverse(\"source-edit-chants\", args=[id])\n        link = '<a href=\"{}\">Edit chants (Fulltext & Volpiano editor)</a>'.format(url)\n        return link\n\n    def make_links_for_source(source):\n        link_with_siglum = make_source_detail_link_with_siglum(source)\n        link_with_title = make_source_detail_link_with_title(source)\n        add_new_chants_link = make_add_new_chants_link(source)\n        edit_chants_link = make_edit_chants_link(source)\n        template = \"\"\"{sigl}<br>\n        <small>\n            <b>{title}</b><br>\n            {add}<br>\n            {edit}<br>\n        </small>\n        \"\"\"\n        links_string = template.format(\n            sigl=link_with_siglum,\n            title=link_with_title,\n            add=add_new_chants_link,\n            edit=edit_chants_link,\n        )\n        return links_string\n\n    MAX_SOURCES_TO_DISPLAY = 6\n    sources = list(user.sources_user_can_edit.all())[:MAX_SOURCES_TO_DISPLAY]\n    source_links = [make_links_for_source(source) for source in sources]\n    list_items = [\"<li>{}</li>\".format(link) for link in source_links]\n    joined_list_items = \"\".join(list_items)\n    links_ul = \"<ul>{}</ul>\".format(joined_list_items)\n    return mark_safe(links_ul)\n\n\n@register.filter(name=\"month_to_string\")\ndef month_to_string(value: Optional[Union[str, int]]) -> Optional[Union[str, int]]:\n    \"\"\"\n    Converts month number to textual representation, 3 letters (Jan, Mar, etc)\n\n    used in:\n        main_app/templates/feast_detail.html\n        main_app/templates/feast_list.html\n    \"\"\"\n    if type(value) == int and value in range(1, 13):\n        return calendar.month_abbr[value]\n    else:\n        return value\n\n\n@register.simple_tag(takes_context=True)\ndef url_add_get_params(context, **kwargs):\n    \"\"\"\n    accounts for the situations where there may be two paginations in one page\n\n    Used in:\n        main_app/templates/pagination.html\n        main_app/templates/user_source_list.html\n    \"\"\"\n    query = context[\"request\"].GET.copy()\n    if \"page\" in kwargs:\n        query.pop(\"page\", None)\n    if \"page2\" in kwargs:\n        query.pop(\"page2\", None)\n    query.update(kwargs)\n    return query.urlencode()\n\n\n@register.simple_tag(takes_context=False)\ndef source_links():\n    \"\"\"\n    Generates a series of html option tags linking to sources in Cantus Dabase, for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n    sources = (\n        Source.objects.filter(published=True, segment__id=4063)\n        .exclude(siglum=None)\n        .values(\"siglum\", \"id\")\n        .order_by(\"siglum\")\n    )\n    options = \"\"\n    for source in sources:\n        option_str = (\n            f\"<option value=source/{source['id']}>{source['siglum']}</option>\\n\"\n        )\n        options += option_str\n\n    return mark_safe(options)\n\n\n@register.filter\ndef classname(obj):\n    \"\"\"\n    Returns the name of the object's class\n    A use-case is: {% if object|classname == \"Notation\" %}\n\n    Used in:\n        main_app/templates/content_overview.html\n    \"\"\"\n    return obj.__class__.__name__\n\n\n@register.filter\ndef admin_url_name(class_name, action):\n    \"\"\"\n    Accepts the name of a class in \"main_app\", and an action (either \"change\" or \"delete\") as arguments.\n    Returns the name of the URL for changing/deleting an object in the admin interface.\n\n    Used in:\n        main_app/templates/content_overview.html\n    \"\"\"\n    class_name = class_name.lower()\n    action = action.lower()\n\n    return f\"admin:main_app_{class_name}_{action}\"\n\n\n@register.filter(name=\"has_group\")\ndef has_group(user, group_name):\n    \"\"\"\n    Used in:\n        templates/base.html\n    \"\"\"\n    return user.groups.filter(name=group_name).exists()\n\n\n@register.simple_tag(takes_context=True)\ndef get_user_source_pagination(context):\n    user_created_sources = (\n        Source.objects.filter(created_by=context[\"user\"])\n        .order_by(\"-date_created\")\n        .distinct()\n    )\n    paginator = Paginator(user_created_sources, 10)\n    page_number = context[\"request\"].GET.get(\"page\")\n    page_obj = paginator.get_page(page_number)\n    return page_obj\n", "path": "django/cantusdb_project/main_app/templatetags/helper_tags.py"}], "after_files": [{"content": "import calendar\nfrom typing import Union, Optional\nfrom django import template\nfrom main_app.models import Source\nfrom articles.models import Article\nfrom django.utils.safestring import mark_safe\nfrom django.urls import reverse\nfrom django.core.paginator import Paginator\n\n\nregister = template.Library()\n\n\n@register.simple_tag(takes_context=False)\ndef recent_articles():\n    \"\"\"\n    Generates a html unordered list of recent articles for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n    articles = Article.objects.order_by(\"-date_created\")[:5]\n    list_item_template = '<li style=\"padding-bottom: 0.5em;\"><a href=\"{url}\">{title}</a><br><small>{date}</small></li>'\n    list_items = [\n        list_item_template.format(\n            url=a.get_absolute_url(),\n            title=a.title,\n            date=a.date_created.strftime(\"%A %B %-d, %Y\"),\n        )\n        for a in articles\n    ]\n    list_items_string = \"\".join(list_items)\n    recent_articles_string = \"<ul>{lis}</ul>\".format(lis=list_items_string)\n    return mark_safe(recent_articles_string)\n\n\n@register.simple_tag(takes_context=False)\ndef my_sources(user):\n    \"\"\"\n    Generates a html unordered list of sources the currently logged-in user has access to edit, for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n\n    def make_source_detail_link_with_siglum(source):\n        id = source.id\n        siglum = source.rism_siglum\n        url = reverse(\"source-detail\", args=[id])\n        link = '<a href=\"{}\">{}</a>'.format(url, siglum)\n        return link\n\n    def make_source_detail_link_with_title(source):\n        id = source.id\n        title = source.title\n        url = reverse(\"source-detail\", args=[id])\n        link = '<a href=\"{}\">{}</a>'.format(url, title)\n        return link\n\n    def make_add_new_chants_link(source):\n        id = source.id\n        url = reverse(\"chant-create\", args=[id])\n        link = '<a href=\"{}\">+ Add new chant</a>'.format(url)\n        return link\n\n    def make_edit_chants_link(source):\n        id = source.id\n        url = reverse(\"source-edit-chants\", args=[id])\n        link = '<a href=\"{}\">Edit chants (Fulltext & Volpiano editor)</a>'.format(url)\n        return link\n\n    def make_links_for_source(source):\n        link_with_siglum = make_source_detail_link_with_siglum(source)\n        link_with_title = make_source_detail_link_with_title(source)\n        add_new_chants_link = make_add_new_chants_link(source)\n        if source.chant_set.exists():\n            edit_chants_link = make_edit_chants_link(source)\n        else:\n            edit_chants_link = \"\"\n        template = \"\"\"{sigl}<br>\n        <small>\n            <b>{title}</b><br>\n            {add}<br>\n            {edit}<br>\n        </small>\n        \"\"\"\n        links_string = template.format(\n            sigl=link_with_siglum,\n            title=link_with_title,\n            add=add_new_chants_link,\n            edit=edit_chants_link,\n        )\n        return links_string\n\n    MAX_SOURCES_TO_DISPLAY = 6\n    sources = list(user.sources_user_can_edit.all())[:MAX_SOURCES_TO_DISPLAY]\n    source_links = [make_links_for_source(source) for source in sources]\n    list_items = [\"<li>{}</li>\".format(link) for link in source_links]\n    joined_list_items = \"\".join(list_items)\n    links_ul = \"<ul>{}</ul>\".format(joined_list_items)\n    return mark_safe(links_ul)\n\n\n@register.filter(name=\"month_to_string\")\ndef month_to_string(value: Optional[Union[str, int]]) -> Optional[Union[str, int]]:\n    \"\"\"\n    Converts month number to textual representation, 3 letters (Jan, Mar, etc)\n\n    used in:\n        main_app/templates/feast_detail.html\n        main_app/templates/feast_list.html\n    \"\"\"\n    if type(value) == int and value in range(1, 13):\n        return calendar.month_abbr[value]\n    else:\n        return value\n\n\n@register.simple_tag(takes_context=True)\ndef url_add_get_params(context, **kwargs):\n    \"\"\"\n    accounts for the situations where there may be two paginations in one page\n\n    Used in:\n        main_app/templates/pagination.html\n        main_app/templates/user_source_list.html\n    \"\"\"\n    query = context[\"request\"].GET.copy()\n    if \"page\" in kwargs:\n        query.pop(\"page\", None)\n    if \"page2\" in kwargs:\n        query.pop(\"page2\", None)\n    query.update(kwargs)\n    return query.urlencode()\n\n\n@register.simple_tag(takes_context=False)\ndef source_links():\n    \"\"\"\n    Generates a series of html option tags linking to sources in Cantus Dabase, for display on the homepage\n\n    Used in:\n        templates/flatpages/default.html\n    \"\"\"\n    sources = (\n        Source.objects.filter(published=True, segment__id=4063)\n        .exclude(siglum=None)\n        .values(\"siglum\", \"id\")\n        .order_by(\"siglum\")\n    )\n    options = \"\"\n    for source in sources:\n        option_str = (\n            f\"<option value=source/{source['id']}>{source['siglum']}</option>\\n\"\n        )\n        options += option_str\n\n    return mark_safe(options)\n\n\n@register.filter\ndef classname(obj):\n    \"\"\"\n    Returns the name of the object's class\n    A use-case is: {% if object|classname == \"Notation\" %}\n\n    Used in:\n        main_app/templates/content_overview.html\n    \"\"\"\n    return obj.__class__.__name__\n\n\n@register.filter\ndef admin_url_name(class_name, action):\n    \"\"\"\n    Accepts the name of a class in \"main_app\", and an action (either \"change\" or \"delete\") as arguments.\n    Returns the name of the URL for changing/deleting an object in the admin interface.\n\n    Used in:\n        main_app/templates/content_overview.html\n    \"\"\"\n    class_name = class_name.lower()\n    action = action.lower()\n\n    return f\"admin:main_app_{class_name}_{action}\"\n\n\n@register.filter(name=\"has_group\")\ndef has_group(user, group_name):\n    \"\"\"\n    Used in:\n        templates/base.html\n    \"\"\"\n    return user.groups.filter(name=group_name).exists()\n\n\n@register.simple_tag(takes_context=True)\ndef get_user_source_pagination(context):\n    user_created_sources = (\n        Source.objects.filter(created_by=context[\"user\"])\n        .order_by(\"-date_created\")\n        .distinct()\n    )\n    paginator = Paginator(user_created_sources, 10)\n    page_number = context[\"request\"].GET.get(\"page\")\n    page_obj = paginator.get_page(page_number)\n    return page_obj\n", "path": "django/cantusdb_project/main_app/templatetags/helper_tags.py"}]}