We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Spider konagrill is broken
During the global build at 2021-06-16-14-42-20, spider **konagrill** failed with **0 features** and **24 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/konagrill.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/konagrill.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/konagrill.geojson))
Spider konagrill is broken
During the global build at 2021-10-13-14-42-23, spider **konagrill** failed with **0 features** and **24 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/logs/konagrill.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/konagrill.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/konagrill.geojson))

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `locations/spiders/kona_grill.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 import json
3 import scrapy
4 
5 from locations.items import GeojsonPointItem
6 from locations.hours import OpeningHours
7 
8 STATES = [
9     "AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DC", "DE", "FL",
10     "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME",
11     "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH",
12     "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI",
13     "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI",
14     "WY",
15 ]
16 
17 WEEKDAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]
18 
19 
20 class KonaGrillSpider(scrapy.Spider):
21     download_delay = 0.2
22     name = "konagrill"
23     item_attributes = {"brand": "Kona Grill", "brand_wikidata": "Q6428706"}
24     allowed_domains = ["konagrill.com"]
25 
26     def start_requests(self):
27         url_by_state = "https://www.konagrill.com/ajax/getlocationsbystate"
28         headers = {"content-type": "application/x-www-form-urlencoded"}
29 
30         # Get store id per state
31         for state in STATES:
32             yield scrapy.http.Request(
33                 url_by_state,
34                 method="POST",
35                 body="state={}".format(state),
36                 callback=self.parse,
37                 headers=headers,
38             )
39 
40     def parse(self, response):
41         store_data = json.loads(response.text)
42         url_location_details = "https://www.konagrill.com/ajax/getlocationdetails"
43         headers = {"content-type": "application/x-www-form-urlencoded"}
44         store_ids = []
45 
46         if not store_data.get("data"):
47             return
48 
49         store_ids += [s.get("id") for _, s in store_data.get("data").items()]
50 
51         # Get store details
52         for i in store_ids:
53             yield scrapy.http.Request(
54                 url_location_details,
55                 method="POST",
56                 body="id={}".format(i),
57                 callback=self.parse_store,
58                 headers=headers,
59             )
60 
61     def parse_store(self, response):
62         response_data = json.loads(response.text)
63         if not response_data.get("data"):
64             return
65 
66         store = response_data.get("data")
67         dh = store.get("dininghours")
68         # Data is inconsistent some keys were found with a trailing space
69         opening_hours = self.parse_hours(dh.get("dining hours") or dh.get("dining hours "))
70         properties = {
71             "addr_full": store.get("address"),
72             "city": store.get("city"),
73             "extras": {"email": store.get("email"),},
74             "lat": store.get("latitude"),
75             "lon": store.get("longitude"),
76             "name": store.get("title"),
77             "opening_hours": opening_hours,
78             "phone": store.get("phone_number"),
79             "postcode": store.get("zip"),
80             "ref": store.get("id"),
81             "state": store.get("state"),
82             "website": store.get("order_online_url"),
83         }
84 
85         yield GeojsonPointItem(**properties)
86 
87     def parse_hours(self, hours):
88         oh = OpeningHours()
89 
90         for t in hours:
91             days = self.parse_days(t.get("days"))
92             open_time, close_time = t.get("hours").split("-")
93             ot = open_time.strip()
94             ct = close_time.strip()
95             for day in days:
96                 oh.add_range(day=day, open_time=ot, close_time=ct, time_format="%I%p")
97 
98         return oh.as_opening_hours()
99 
100     def parse_days(self, days):
101         """Parse day ranges and returns a list of days it represent
102         The following formats are considered:
103           - Single day, e.g. "Mon", "Monday"
104           - Range, e.g. "Mon-Fri", "Tue-Sund", "Sat-Sunday"
105           - Two days, e.g. "Sat & Sun", "Friday & Su"
106 
107         Returns a list with the weekdays
108         """
109         parsed_days = []
110 
111         # Range
112         # Produce a list of weekdays between two days e.g. su-sa, mo-th, etc.
113         if "-" in days:
114             d = days.split("-")
115             r = [i.strip()[:2] for i in d]
116             s = WEEKDAYS.index(r[0].title())
117             e = WEEKDAYS.index(r[1].title())
118             if s <= e:
119                 return WEEKDAYS[s : e + 1]
120             else:
121                 return WEEKDAYS[s:] + WEEKDAYS[: e + 1]
122         # Two days
123         if "&" in days:
124             d = days.split("&")
125             return [i.strip()[:2].title() for i in d]
126         # Single days
127         else:
128             return [days.strip()[:2].title()]
129
```
--- 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/locations/spiders/kona_grill.py b/locations/spiders/kona_grill.py
--- a/locations/spiders/kona_grill.py
+++ b/locations/spiders/kona_grill.py
@@ -88,6 +88,10 @@
         oh = OpeningHours()
 
         for t in hours:
+            # Some day entries contain invalid week data, e.g. "Brunch"
+            # "Brunch" is a special dining hour that is contained in regular hours, ignore it
+            if "Brunch" in t.get("days"):
+                continue
             days = self.parse_days(t.get("days"))
             open_time, close_time = t.get("hours").split("-")
             ot = open_time.strip()

{"golden_diff": "diff --git a/locations/spiders/kona_grill.py b/locations/spiders/kona_grill.py\n--- a/locations/spiders/kona_grill.py\n+++ b/locations/spiders/kona_grill.py\n@@ -88,6 +88,10 @@\n         oh = OpeningHours()\n \n         for t in hours:\n+            # Some day entries contain invalid week data, e.g. \"Brunch\"\n+            # \"Brunch\" is a special dining hour that is contained in regular hours, ignore it\n+            if \"Brunch\" in t.get(\"days\"):\n+                continue\n             days = self.parse_days(t.get(\"days\"))\n             open_time, close_time = t.get(\"hours\").split(\"-\")\n             ot = open_time.strip()\n", "issue": "Spider konagrill is broken\nDuring the global build at 2021-06-16-14-42-20, spider **konagrill** failed with **0 features** and **24 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/konagrill.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/konagrill.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/konagrill.geojson))\nSpider konagrill is broken\nDuring the global build at 2021-10-13-14-42-23, spider **konagrill** failed with **0 features** and **24 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/logs/konagrill.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/konagrill.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/konagrill.geojson))\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport json\nimport scrapy\n\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nSTATES = [\n    \"AL\", \"AK\", \"AZ\", \"AR\", \"CA\", \"CO\", \"CT\", \"DC\", \"DE\", \"FL\",\n    \"GA\", \"HI\", \"ID\", \"IL\", \"IN\", \"IA\", \"KS\", \"KY\", \"LA\", \"ME\",\n    \"MD\", \"MA\", \"MI\", \"MN\", \"MS\", \"MO\", \"MT\", \"NE\", \"NV\", \"NH\",\n    \"NJ\", \"NM\", \"NY\", \"NC\", \"ND\", \"OH\", \"OK\", \"OR\", \"PA\", \"RI\",\n    \"SC\", \"SD\", \"TN\", \"TX\", \"UT\", \"VT\", \"VA\", \"WA\", \"WV\", \"WI\",\n    \"WY\",\n]\n\nWEEKDAYS = [\"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"]\n\n\nclass KonaGrillSpider(scrapy.Spider):\n    download_delay = 0.2\n    name = \"konagrill\"\n    item_attributes = {\"brand\": \"Kona Grill\", \"brand_wikidata\": \"Q6428706\"}\n    allowed_domains = [\"konagrill.com\"]\n\n    def start_requests(self):\n        url_by_state = \"https://www.konagrill.com/ajax/getlocationsbystate\"\n        headers = {\"content-type\": \"application/x-www-form-urlencoded\"}\n\n        # Get store id per state\n        for state in STATES:\n            yield scrapy.http.Request(\n                url_by_state,\n                method=\"POST\",\n                body=\"state={}\".format(state),\n                callback=self.parse,\n                headers=headers,\n            )\n\n    def parse(self, response):\n        store_data = json.loads(response.text)\n        url_location_details = \"https://www.konagrill.com/ajax/getlocationdetails\"\n        headers = {\"content-type\": \"application/x-www-form-urlencoded\"}\n        store_ids = []\n\n        if not store_data.get(\"data\"):\n            return\n\n        store_ids += [s.get(\"id\") for _, s in store_data.get(\"data\").items()]\n\n        # Get store details\n        for i in store_ids:\n            yield scrapy.http.Request(\n                url_location_details,\n                method=\"POST\",\n                body=\"id={}\".format(i),\n                callback=self.parse_store,\n                headers=headers,\n            )\n\n    def parse_store(self, response):\n        response_data = json.loads(response.text)\n        if not response_data.get(\"data\"):\n            return\n\n        store = response_data.get(\"data\")\n        dh = store.get(\"dininghours\")\n        # Data is inconsistent some keys were found with a trailing space\n        opening_hours = self.parse_hours(dh.get(\"dining hours\") or dh.get(\"dining hours \"))\n        properties = {\n            \"addr_full\": store.get(\"address\"),\n            \"city\": store.get(\"city\"),\n            \"extras\": {\"email\": store.get(\"email\"),},\n            \"lat\": store.get(\"latitude\"),\n            \"lon\": store.get(\"longitude\"),\n            \"name\": store.get(\"title\"),\n            \"opening_hours\": opening_hours,\n            \"phone\": store.get(\"phone_number\"),\n            \"postcode\": store.get(\"zip\"),\n            \"ref\": store.get(\"id\"),\n            \"state\": store.get(\"state\"),\n            \"website\": store.get(\"order_online_url\"),\n        }\n\n        yield GeojsonPointItem(**properties)\n\n    def parse_hours(self, hours):\n        oh = OpeningHours()\n\n        for t in hours:\n            days = self.parse_days(t.get(\"days\"))\n            open_time, close_time = t.get(\"hours\").split(\"-\")\n            ot = open_time.strip()\n            ct = close_time.strip()\n            for day in days:\n                oh.add_range(day=day, open_time=ot, close_time=ct, time_format=\"%I%p\")\n\n        return oh.as_opening_hours()\n\n    def parse_days(self, days):\n        \"\"\"Parse day ranges and returns a list of days it represent\n        The following formats are considered:\n          - Single day, e.g. \"Mon\", \"Monday\"\n          - Range, e.g. \"Mon-Fri\", \"Tue-Sund\", \"Sat-Sunday\"\n          - Two days, e.g. \"Sat & Sun\", \"Friday & Su\"\n\n        Returns a list with the weekdays\n        \"\"\"\n        parsed_days = []\n\n        # Range\n        # Produce a list of weekdays between two days e.g. su-sa, mo-th, etc.\n        if \"-\" in days:\n            d = days.split(\"-\")\n            r = [i.strip()[:2] for i in d]\n            s = WEEKDAYS.index(r[0].title())\n            e = WEEKDAYS.index(r[1].title())\n            if s <= e:\n                return WEEKDAYS[s : e + 1]\n            else:\n                return WEEKDAYS[s:] + WEEKDAYS[: e + 1]\n        # Two days\n        if \"&\" in days:\n            d = days.split(\"&\")\n            return [i.strip()[:2].title() for i in d]\n        # Single days\n        else:\n            return [days.strip()[:2].title()]\n", "path": "locations/spiders/kona_grill.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport json\nimport scrapy\n\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nSTATES = [\n    \"AL\", \"AK\", \"AZ\", \"AR\", \"CA\", \"CO\", \"CT\", \"DC\", \"DE\", \"FL\",\n    \"GA\", \"HI\", \"ID\", \"IL\", \"IN\", \"IA\", \"KS\", \"KY\", \"LA\", \"ME\",\n    \"MD\", \"MA\", \"MI\", \"MN\", \"MS\", \"MO\", \"MT\", \"NE\", \"NV\", \"NH\",\n    \"NJ\", \"NM\", \"NY\", \"NC\", \"ND\", \"OH\", \"OK\", \"OR\", \"PA\", \"RI\",\n    \"SC\", \"SD\", \"TN\", \"TX\", \"UT\", \"VT\", \"VA\", \"WA\", \"WV\", \"WI\",\n    \"WY\",\n]\n\nWEEKDAYS = [\"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"]\n\n\nclass KonaGrillSpider(scrapy.Spider):\n    download_delay = 0.2\n    name = \"konagrill\"\n    item_attributes = {\"brand\": \"Kona Grill\", \"brand_wikidata\": \"Q6428706\"}\n    allowed_domains = [\"konagrill.com\"]\n\n    def start_requests(self):\n        url_by_state = \"https://www.konagrill.com/ajax/getlocationsbystate\"\n        headers = {\"content-type\": \"application/x-www-form-urlencoded\"}\n\n        # Get store id per state\n        for state in STATES:\n            yield scrapy.http.Request(\n                url_by_state,\n                method=\"POST\",\n                body=\"state={}\".format(state),\n                callback=self.parse,\n                headers=headers,\n            )\n\n    def parse(self, response):\n        store_data = json.loads(response.text)\n        url_location_details = \"https://www.konagrill.com/ajax/getlocationdetails\"\n        headers = {\"content-type\": \"application/x-www-form-urlencoded\"}\n        store_ids = []\n\n        if not store_data.get(\"data\"):\n            return\n\n        store_ids += [s.get(\"id\") for _, s in store_data.get(\"data\").items()]\n\n        # Get store details\n        for i in store_ids:\n            yield scrapy.http.Request(\n                url_location_details,\n                method=\"POST\",\n                body=\"id={}\".format(i),\n                callback=self.parse_store,\n                headers=headers,\n            )\n\n    def parse_store(self, response):\n        response_data = json.loads(response.text)\n        if not response_data.get(\"data\"):\n            return\n\n        store = response_data.get(\"data\")\n        dh = store.get(\"dininghours\")\n        # Data is inconsistent some keys were found with a trailing space\n        opening_hours = self.parse_hours(dh.get(\"dining hours\") or dh.get(\"dining hours \"))\n        properties = {\n            \"addr_full\": store.get(\"address\"),\n            \"city\": store.get(\"city\"),\n            \"extras\": {\"email\": store.get(\"email\"),},\n            \"lat\": store.get(\"latitude\"),\n            \"lon\": store.get(\"longitude\"),\n            \"name\": store.get(\"title\"),\n            \"opening_hours\": opening_hours,\n            \"phone\": store.get(\"phone_number\"),\n            \"postcode\": store.get(\"zip\"),\n            \"ref\": store.get(\"id\"),\n            \"state\": store.get(\"state\"),\n            \"website\": store.get(\"order_online_url\"),\n        }\n\n        yield GeojsonPointItem(**properties)\n\n    def parse_hours(self, hours):\n        oh = OpeningHours()\n\n        for t in hours:\n            # Some day entries contain invalid week data, e.g. \"Brunch\"\n            # \"Brunch\" is a special dining hour that is contained in regular hours, ignore it\n            if \"Brunch\" in t.get(\"days\"):\n                continue\n            days = self.parse_days(t.get(\"days\"))\n            open_time, close_time = t.get(\"hours\").split(\"-\")\n            ot = open_time.strip()\n            ct = close_time.strip()\n            for day in days:\n                oh.add_range(day=day, open_time=ot, close_time=ct, time_format=\"%I%p\")\n\n        return oh.as_opening_hours()\n\n    def parse_days(self, days):\n        \"\"\"Parse day ranges and returns a list of days it represent\n        The following formats are considered:\n          - Single day, e.g. \"Mon\", \"Monday\"\n          - Range, e.g. \"Mon-Fri\", \"Tue-Sund\", \"Sat-Sunday\"\n          - Two days, e.g. \"Sat & Sun\", \"Friday & Su\"\n\n        Returns a list with the weekdays\n        \"\"\"\n        parsed_days = []\n\n        # Range\n        # Produce a list of weekdays between two days e.g. su-sa, mo-th, etc.\n        if \"-\" in days:\n            d = days.split(\"-\")\n            r = [i.strip()[:2] for i in d]\n            s = WEEKDAYS.index(r[0].title())\n            e = WEEKDAYS.index(r[1].title())\n            if s <= e:\n                return WEEKDAYS[s : e + 1]\n            else:\n                return WEEKDAYS[s:] + WEEKDAYS[: e + 1]\n        # Two days\n        if \"&\" in days:\n            d = days.split(\"&\")\n            return [i.strip()[:2].title() for i in d]\n        # Single days\n        else:\n            return [days.strip()[:2].title()]\n", "path": "locations/spiders/kona_grill.py"}]}