We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Append entrypoint url argument only to `about:logins` page


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `snippets/base/util.py`
Content:
```
1 import copy
2 import datetime
3 import re
4 from urllib.parse import ParseResult, urlparse, urlencode
5 
6 from django.http import QueryDict
7 from django.utils.encoding import smart_bytes
8 
9 from product_details import product_details
10 from product_details.version_compare import version_list
11 
12 EPOCH = datetime.datetime.utcfromtimestamp(0)
13 
14 
15 def get_object_or_none(model_class, **filters):
16     """
17     Identical to Model.get, except instead of throwing exceptions, this returns
18     None.
19     """
20     try:
21         return model_class.objects.get(**filters)
22     except (model_class.DoesNotExist, model_class.MultipleObjectsReturned):
23         return None
24 
25 
26 def first(collection, callback):
27     """
28     Find the first item in collection that, when passed to callback, returns
29     True. Returns None if no such item is found.
30     """
31     return next((item for item in collection if callback(item)), None)
32 
33 
34 def create_locales():
35     from snippets.base.models import TargetedLocale
36 
37     for code, name in product_details.languages.items():
38         locale = TargetedLocale.objects.get_or_create(code=code.lower())[0]
39         name = name['English']
40         if locale.name != name:
41             locale.name = name
42             locale.save()
43 
44 
45 def create_countries():
46     from snippets.base.models import TargetedCountry
47 
48     for code, name in product_details.get_regions('en-US').items():
49         country = TargetedCountry.objects.get_or_create(code=code.upper())[0]
50         if country.name != name:
51             country.name = name
52             country.save()
53 
54 
55 def current_firefox_major_version():
56     full_version = version_list(
57         product_details.firefox_history_major_releases)[0]
58 
59     return full_version.split('.', 1)[0]
60 
61 
62 def urlparams(url_, fragment=None, query_dict=None, replace=True, **query):
63     """
64     Add a fragment and/or query parameters to a URL.
65     New query params will be appended to exising parameters, except duplicate
66     names, which will be replaced when replace=True otherwise preserved.
67 
68     Copied from mozilla/kuma, modified:
69      - to not always replace vars
70      - to not escape `[]` characters
71     """
72     url_ = urlparse(url_)
73     fragment = fragment if fragment is not None else url_.fragment
74 
75     q = url_.query
76     new_query_dict = (QueryDict(smart_bytes(q), mutable=True) if
77                       q else QueryDict('', mutable=True))
78     if query_dict:
79         for k, l in query_dict.lists():
80             if not replace and k in new_query_dict:
81                 continue
82             new_query_dict[k] = None
83             for v in l:
84                 new_query_dict.appendlist(k, v)
85 
86     for k, v in query.items():
87         if not replace and k in new_query_dict:
88             continue
89 
90         if isinstance(v, list):
91             new_query_dict.setlist(k, v)
92         else:
93             new_query_dict[k] = v
94 
95     query_string = urlencode([(k, v) for k, l in new_query_dict.lists() for
96                               v in l if v is not None], safe='[]')
97     new = ParseResult(url_.scheme, url_.netloc, url_.path or '/',
98                       url_.params, query_string, fragment)
99     return new.geturl()
100 
101 
102 def convert_special_link(url):
103     action = args = entrypoint_name = entrypoint_value = None
104     if url.startswith('special:menu:'):
105         action = 'OPEN_APPLICATIONS_MENU'
106         args = url.rsplit(':', 1)[1]
107     elif url.startswith('special:about:'):
108         action = 'OPEN_ABOUT_PAGE'
109         args = url.rsplit(':', 1)[1]
110         entrypoint_name = 'entryPoint'
111         entrypoint_value = 'snippet'
112     elif url.startswith('special:highlight:'):
113         action = 'HIGHLIGHT_FEATURE'
114         args = url.rsplit(':', 1)[1]
115     elif url == 'special:preferences':
116         action = 'OPEN_PREFERENCES_PAGE'
117         entrypoint_value = 'snippet'
118     elif url == 'special:accounts':
119         action = 'SHOW_FIREFOX_ACCOUNTS'
120     elif url == 'special:monitor':
121         action = 'ENABLE_FIREFOX_MONITOR'
122         args = {
123             'url': ('https://monitor.firefox.com/oauth/init?'
124                     'utm_source=desktop-snippet&utm_term=[[job_id]]&'
125                     'utm_content=[[channels]]&utm_campaign=[[campaign_slug]]&'
126                     'entrypoint=snippets&form_type=button'),
127             'flowRequestParams': {
128                 'entrypoint': 'snippets',
129                 'utm_term': 'snippet-job-[[job_id]]',
130                 'form_type': 'button'
131             }
132         }
133     return action, args, entrypoint_name, entrypoint_value
134 
135 
136 def fluent_link_extractor(data, variables):
137     """Replaces all <a> elements with fluent.js link elements sequentially
138     numbered.
139 
140     Returns a tuple with the new text and a dict of all the links with url and
141     custom metric where available.
142 
143     """
144     class Replacer:
145         link_counter = 0
146         links = {}
147 
148         def __call__(self, matchobj):
149             keyname = 'link{0}'.format(self.link_counter)
150             replacement = '<{keyname}>{text}</{keyname}>'.format(
151                 keyname=keyname,
152                 text=matchobj.group('innerText'))
153             # Find the URL
154             url_match = re.search('href="(?P<url>.+?)"', matchobj.group('attrs'))
155             url = ''
156 
157             if url_match:
158                 url = url_match.group('url')
159 
160             action, args, entrypoint_name, entrypoint_value = convert_special_link(url)
161 
162             if action:
163                 self.links[keyname] = {
164                     'action': action,
165                 }
166                 if args:
167                     self.links[keyname]['args'] = args
168                 if entrypoint_name:
169                     self.links[keyname]['entrypoint_name'] = entrypoint_name
170                 if entrypoint_value:
171                     self.links[keyname]['entrypoint_value'] = entrypoint_value
172             else:
173                 self.links[keyname] = {
174                     'url': url,
175                 }
176 
177             # Find the optional data-metric attrib
178             metric_match = re.search('data-metric="(?P<metric>.+?)"', matchobj.group('attrs'))
179             if metric_match:
180                 self.links[keyname]['metric'] = metric_match.group('metric')
181 
182             self.link_counter += 1
183             return replacement
184 
185     local_data = copy.deepcopy(data)
186     replacer = Replacer()
187     for variable in variables:
188         if variable not in local_data:
189             continue
190         local_data[variable] = re.sub('(<a(?P<attrs> .*?)>)(?P<innerText>.+?)(</a>)',
191                                       replacer, local_data[variable])
192 
193     local_data['links'] = replacer.links
194     return local_data
195 
196 
197 def deep_search_and_replace(data, search_string, replace_string):
198     for key, value in data.items():
199         if isinstance(value, str):
200             data[key] = value.replace(search_string, replace_string)
201 
202         elif isinstance(value, list):
203             data[key] = [v.replace(search_string, replace_string) for v in value]
204 
205         elif isinstance(value, dict):
206             data[key] = deep_search_and_replace(value, search_string, replace_string)
207 
208     return data
209
```
--- 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/snippets/base/util.py b/snippets/base/util.py
--- a/snippets/base/util.py
+++ b/snippets/base/util.py
@@ -107,8 +107,9 @@
     elif url.startswith('special:about:'):
         action = 'OPEN_ABOUT_PAGE'
         args = url.rsplit(':', 1)[1]
-        entrypoint_name = 'entryPoint'
-        entrypoint_value = 'snippet'
+        if url.startswith('special:about:logins'):
+            entrypoint_name = 'entryPoint'
+            entrypoint_value = 'snippet'
     elif url.startswith('special:highlight:'):
         action = 'HIGHLIGHT_FEATURE'
         args = url.rsplit(':', 1)[1]

{"golden_diff": "diff --git a/snippets/base/util.py b/snippets/base/util.py\n--- a/snippets/base/util.py\n+++ b/snippets/base/util.py\n@@ -107,8 +107,9 @@\n     elif url.startswith('special:about:'):\n         action = 'OPEN_ABOUT_PAGE'\n         args = url.rsplit(':', 1)[1]\n-        entrypoint_name = 'entryPoint'\n-        entrypoint_value = 'snippet'\n+        if url.startswith('special:about:logins'):\n+            entrypoint_name = 'entryPoint'\n+            entrypoint_value = 'snippet'\n     elif url.startswith('special:highlight:'):\n         action = 'HIGHLIGHT_FEATURE'\n         args = url.rsplit(':', 1)[1]\n", "issue": "Append entrypoint url argument only to `about:logins` page\n\n", "before_files": [{"content": "import copy\nimport datetime\nimport re\nfrom urllib.parse import ParseResult, urlparse, urlencode\n\nfrom django.http import QueryDict\nfrom django.utils.encoding import smart_bytes\n\nfrom product_details import product_details\nfrom product_details.version_compare import version_list\n\nEPOCH = datetime.datetime.utcfromtimestamp(0)\n\n\ndef get_object_or_none(model_class, **filters):\n    \"\"\"\n    Identical to Model.get, except instead of throwing exceptions, this returns\n    None.\n    \"\"\"\n    try:\n        return model_class.objects.get(**filters)\n    except (model_class.DoesNotExist, model_class.MultipleObjectsReturned):\n        return None\n\n\ndef first(collection, callback):\n    \"\"\"\n    Find the first item in collection that, when passed to callback, returns\n    True. Returns None if no such item is found.\n    \"\"\"\n    return next((item for item in collection if callback(item)), None)\n\n\ndef create_locales():\n    from snippets.base.models import TargetedLocale\n\n    for code, name in product_details.languages.items():\n        locale = TargetedLocale.objects.get_or_create(code=code.lower())[0]\n        name = name['English']\n        if locale.name != name:\n            locale.name = name\n            locale.save()\n\n\ndef create_countries():\n    from snippets.base.models import TargetedCountry\n\n    for code, name in product_details.get_regions('en-US').items():\n        country = TargetedCountry.objects.get_or_create(code=code.upper())[0]\n        if country.name != name:\n            country.name = name\n            country.save()\n\n\ndef current_firefox_major_version():\n    full_version = version_list(\n        product_details.firefox_history_major_releases)[0]\n\n    return full_version.split('.', 1)[0]\n\n\ndef urlparams(url_, fragment=None, query_dict=None, replace=True, **query):\n    \"\"\"\n    Add a fragment and/or query parameters to a URL.\n    New query params will be appended to exising parameters, except duplicate\n    names, which will be replaced when replace=True otherwise preserved.\n\n    Copied from mozilla/kuma, modified:\n     - to not always replace vars\n     - to not escape `[]` characters\n    \"\"\"\n    url_ = urlparse(url_)\n    fragment = fragment if fragment is not None else url_.fragment\n\n    q = url_.query\n    new_query_dict = (QueryDict(smart_bytes(q), mutable=True) if\n                      q else QueryDict('', mutable=True))\n    if query_dict:\n        for k, l in query_dict.lists():\n            if not replace and k in new_query_dict:\n                continue\n            new_query_dict[k] = None\n            for v in l:\n                new_query_dict.appendlist(k, v)\n\n    for k, v in query.items():\n        if not replace and k in new_query_dict:\n            continue\n\n        if isinstance(v, list):\n            new_query_dict.setlist(k, v)\n        else:\n            new_query_dict[k] = v\n\n    query_string = urlencode([(k, v) for k, l in new_query_dict.lists() for\n                              v in l if v is not None], safe='[]')\n    new = ParseResult(url_.scheme, url_.netloc, url_.path or '/',\n                      url_.params, query_string, fragment)\n    return new.geturl()\n\n\ndef convert_special_link(url):\n    action = args = entrypoint_name = entrypoint_value = None\n    if url.startswith('special:menu:'):\n        action = 'OPEN_APPLICATIONS_MENU'\n        args = url.rsplit(':', 1)[1]\n    elif url.startswith('special:about:'):\n        action = 'OPEN_ABOUT_PAGE'\n        args = url.rsplit(':', 1)[1]\n        entrypoint_name = 'entryPoint'\n        entrypoint_value = 'snippet'\n    elif url.startswith('special:highlight:'):\n        action = 'HIGHLIGHT_FEATURE'\n        args = url.rsplit(':', 1)[1]\n    elif url == 'special:preferences':\n        action = 'OPEN_PREFERENCES_PAGE'\n        entrypoint_value = 'snippet'\n    elif url == 'special:accounts':\n        action = 'SHOW_FIREFOX_ACCOUNTS'\n    elif url == 'special:monitor':\n        action = 'ENABLE_FIREFOX_MONITOR'\n        args = {\n            'url': ('https://monitor.firefox.com/oauth/init?'\n                    'utm_source=desktop-snippet&utm_term=[[job_id]]&'\n                    'utm_content=[[channels]]&utm_campaign=[[campaign_slug]]&'\n                    'entrypoint=snippets&form_type=button'),\n            'flowRequestParams': {\n                'entrypoint': 'snippets',\n                'utm_term': 'snippet-job-[[job_id]]',\n                'form_type': 'button'\n            }\n        }\n    return action, args, entrypoint_name, entrypoint_value\n\n\ndef fluent_link_extractor(data, variables):\n    \"\"\"Replaces all <a> elements with fluent.js link elements sequentially\n    numbered.\n\n    Returns a tuple with the new text and a dict of all the links with url and\n    custom metric where available.\n\n    \"\"\"\n    class Replacer:\n        link_counter = 0\n        links = {}\n\n        def __call__(self, matchobj):\n            keyname = 'link{0}'.format(self.link_counter)\n            replacement = '<{keyname}>{text}</{keyname}>'.format(\n                keyname=keyname,\n                text=matchobj.group('innerText'))\n            # Find the URL\n            url_match = re.search('href=\"(?P<url>.+?)\"', matchobj.group('attrs'))\n            url = ''\n\n            if url_match:\n                url = url_match.group('url')\n\n            action, args, entrypoint_name, entrypoint_value = convert_special_link(url)\n\n            if action:\n                self.links[keyname] = {\n                    'action': action,\n                }\n                if args:\n                    self.links[keyname]['args'] = args\n                if entrypoint_name:\n                    self.links[keyname]['entrypoint_name'] = entrypoint_name\n                if entrypoint_value:\n                    self.links[keyname]['entrypoint_value'] = entrypoint_value\n            else:\n                self.links[keyname] = {\n                    'url': url,\n                }\n\n            # Find the optional data-metric attrib\n            metric_match = re.search('data-metric=\"(?P<metric>.+?)\"', matchobj.group('attrs'))\n            if metric_match:\n                self.links[keyname]['metric'] = metric_match.group('metric')\n\n            self.link_counter += 1\n            return replacement\n\n    local_data = copy.deepcopy(data)\n    replacer = Replacer()\n    for variable in variables:\n        if variable not in local_data:\n            continue\n        local_data[variable] = re.sub('(<a(?P<attrs> .*?)>)(?P<innerText>.+?)(</a>)',\n                                      replacer, local_data[variable])\n\n    local_data['links'] = replacer.links\n    return local_data\n\n\ndef deep_search_and_replace(data, search_string, replace_string):\n    for key, value in data.items():\n        if isinstance(value, str):\n            data[key] = value.replace(search_string, replace_string)\n\n        elif isinstance(value, list):\n            data[key] = [v.replace(search_string, replace_string) for v in value]\n\n        elif isinstance(value, dict):\n            data[key] = deep_search_and_replace(value, search_string, replace_string)\n\n    return data\n", "path": "snippets/base/util.py"}], "after_files": [{"content": "import copy\nimport datetime\nimport re\nfrom urllib.parse import ParseResult, urlparse, urlencode\n\nfrom django.http import QueryDict\nfrom django.utils.encoding import smart_bytes\n\nfrom product_details import product_details\nfrom product_details.version_compare import version_list\n\nEPOCH = datetime.datetime.utcfromtimestamp(0)\n\n\ndef get_object_or_none(model_class, **filters):\n    \"\"\"\n    Identical to Model.get, except instead of throwing exceptions, this returns\n    None.\n    \"\"\"\n    try:\n        return model_class.objects.get(**filters)\n    except (model_class.DoesNotExist, model_class.MultipleObjectsReturned):\n        return None\n\n\ndef first(collection, callback):\n    \"\"\"\n    Find the first item in collection that, when passed to callback, returns\n    True. Returns None if no such item is found.\n    \"\"\"\n    return next((item for item in collection if callback(item)), None)\n\n\ndef create_locales():\n    from snippets.base.models import TargetedLocale\n\n    for code, name in product_details.languages.items():\n        locale = TargetedLocale.objects.get_or_create(code=code.lower())[0]\n        name = name['English']\n        if locale.name != name:\n            locale.name = name\n            locale.save()\n\n\ndef create_countries():\n    from snippets.base.models import TargetedCountry\n\n    for code, name in product_details.get_regions('en-US').items():\n        country = TargetedCountry.objects.get_or_create(code=code.upper())[0]\n        if country.name != name:\n            country.name = name\n            country.save()\n\n\ndef current_firefox_major_version():\n    full_version = version_list(\n        product_details.firefox_history_major_releases)[0]\n\n    return full_version.split('.', 1)[0]\n\n\ndef urlparams(url_, fragment=None, query_dict=None, replace=True, **query):\n    \"\"\"\n    Add a fragment and/or query parameters to a URL.\n    New query params will be appended to exising parameters, except duplicate\n    names, which will be replaced when replace=True otherwise preserved.\n\n    Copied from mozilla/kuma, modified:\n     - to not always replace vars\n     - to not escape `[]` characters\n    \"\"\"\n    url_ = urlparse(url_)\n    fragment = fragment if fragment is not None else url_.fragment\n\n    q = url_.query\n    new_query_dict = (QueryDict(smart_bytes(q), mutable=True) if\n                      q else QueryDict('', mutable=True))\n    if query_dict:\n        for k, l in query_dict.lists():\n            if not replace and k in new_query_dict:\n                continue\n            new_query_dict[k] = None\n            for v in l:\n                new_query_dict.appendlist(k, v)\n\n    for k, v in query.items():\n        if not replace and k in new_query_dict:\n            continue\n\n        if isinstance(v, list):\n            new_query_dict.setlist(k, v)\n        else:\n            new_query_dict[k] = v\n\n    query_string = urlencode([(k, v) for k, l in new_query_dict.lists() for\n                              v in l if v is not None], safe='[]')\n    new = ParseResult(url_.scheme, url_.netloc, url_.path or '/',\n                      url_.params, query_string, fragment)\n    return new.geturl()\n\n\ndef convert_special_link(url):\n    action = args = entrypoint_name = entrypoint_value = None\n    if url.startswith('special:menu:'):\n        action = 'OPEN_APPLICATIONS_MENU'\n        args = url.rsplit(':', 1)[1]\n    elif url.startswith('special:about:'):\n        action = 'OPEN_ABOUT_PAGE'\n        args = url.rsplit(':', 1)[1]\n        if url.startswith('special:about:logins'):\n            entrypoint_name = 'entryPoint'\n            entrypoint_value = 'snippet'\n    elif url.startswith('special:highlight:'):\n        action = 'HIGHLIGHT_FEATURE'\n        args = url.rsplit(':', 1)[1]\n    elif url == 'special:preferences':\n        action = 'OPEN_PREFERENCES_PAGE'\n        entrypoint_value = 'snippet'\n    elif url == 'special:accounts':\n        action = 'SHOW_FIREFOX_ACCOUNTS'\n    elif url == 'special:monitor':\n        action = 'ENABLE_FIREFOX_MONITOR'\n        args = {\n            'url': ('https://monitor.firefox.com/oauth/init?'\n                    'utm_source=desktop-snippet&utm_term=[[job_id]]&'\n                    'utm_content=[[channels]]&utm_campaign=[[campaign_slug]]&'\n                    'entrypoint=snippets&form_type=button'),\n            'flowRequestParams': {\n                'entrypoint': 'snippets',\n                'utm_term': 'snippet-job-[[job_id]]',\n                'form_type': 'button'\n            }\n        }\n    return action, args, entrypoint_name, entrypoint_value\n\n\ndef fluent_link_extractor(data, variables):\n    \"\"\"Replaces all <a> elements with fluent.js link elements sequentially\n    numbered.\n\n    Returns a tuple with the new text and a dict of all the links with url and\n    custom metric where available.\n\n    \"\"\"\n    class Replacer:\n        link_counter = 0\n        links = {}\n\n        def __call__(self, matchobj):\n            keyname = 'link{0}'.format(self.link_counter)\n            replacement = '<{keyname}>{text}</{keyname}>'.format(\n                keyname=keyname,\n                text=matchobj.group('innerText'))\n            # Find the URL\n            url_match = re.search('href=\"(?P<url>.+?)\"', matchobj.group('attrs'))\n            url = ''\n\n            if url_match:\n                url = url_match.group('url')\n\n            action, args, entrypoint_name, entrypoint_value = convert_special_link(url)\n\n            if action:\n                self.links[keyname] = {\n                    'action': action,\n                }\n                if args:\n                    self.links[keyname]['args'] = args\n                if entrypoint_name:\n                    self.links[keyname]['entrypoint_name'] = entrypoint_name\n                if entrypoint_value:\n                    self.links[keyname]['entrypoint_value'] = entrypoint_value\n            else:\n                self.links[keyname] = {\n                    'url': url,\n                }\n\n            # Find the optional data-metric attrib\n            metric_match = re.search('data-metric=\"(?P<metric>.+?)\"', matchobj.group('attrs'))\n            if metric_match:\n                self.links[keyname]['metric'] = metric_match.group('metric')\n\n            self.link_counter += 1\n            return replacement\n\n    local_data = copy.deepcopy(data)\n    replacer = Replacer()\n    for variable in variables:\n        if variable not in local_data:\n            continue\n        local_data[variable] = re.sub('(<a(?P<attrs> .*?)>)(?P<innerText>.+?)(</a>)',\n                                      replacer, local_data[variable])\n\n    local_data['links'] = replacer.links\n    return local_data\n\n\ndef deep_search_and_replace(data, search_string, replace_string):\n    for key, value in data.items():\n        if isinstance(value, str):\n            data[key] = value.replace(search_string, replace_string)\n\n        elif isinstance(value, list):\n            data[key] = [v.replace(search_string, replace_string) for v in value]\n\n        elif isinstance(value, dict):\n            data[key] = deep_search_and_replace(value, search_string, replace_string)\n\n    return data\n", "path": "snippets/base/util.py"}]}