prompt: 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()
  
  ```
  
golden_diff: 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()
  
verification_info: {"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"}]}