prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Spider papa_johns is broken
  During the global build at 2021-08-18-14-42-26, spider **papa_johns** failed with **3199 features** and **1 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/logs/papa_johns.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/output/papa_johns.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/output/papa_johns.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/papa_johns.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 import scrapy
  3 import json
  4 
  5 from locations.items import GeojsonPointItem
  6 from locations.hours import OpeningHours
  7 
  8 day_map = {'MONDAY': 'Mo', 'TUESDAY': 'Tu', 'WEDNESDAY': 'We', 'THURSDAY': 'Th',
  9            'FRIDAY': 'Fr', 'SATURDAY': 'Sa', 'SUNDAY': 'Su'}
  10 
  11 
  12 class PapaJohnsSpider(scrapy.Spider):
  13 
  14     name = "papa_johns"
  15     item_attributes = { 'brand': "Papa John's Pizza", 'brand_wikidata': "Q2759586" }
  16     allowed_domains = ["papajohns.com", ]
  17 
  18     start_urls = (
  19         'https://locations.papajohns.com/',
  20     )
  21     download_delay = 0.2
  22 
  23     def parse_hours(self, hours):
  24         if not hours:
  25             return ''
  26         try:
  27             opening_hours = OpeningHours()
  28             the_hours = json.loads(hours[0])
  29             for day in the_hours:
  30                 the_day = day_map[day['day']]
  31                 the_start = str(day['intervals'][0]['start'])
  32                 the_end = str(day['intervals'][0]['end'])
  33                 if the_start == '0':
  34                     the_start = '000'
  35                 if the_end == '0':
  36                     the_end = '000'
  37                 opening_hours.add_range(day=the_day, open_time=the_start, close_time=the_end, time_format='%H%M')
  38             return opening_hours.as_opening_hours()
  39         except IndexError:
  40             return ''
  41 
  42     def parse_store(self, response):
  43         hours = response.xpath('//div[@class="c-location-hours-details-wrapper js-location-hours"]/@data-days').extract()
  44         opening_hours = self.parse_hours(hours)
  45 
  46         if response.xpath('//address[@class="c-address"]/div[3]/span/text()').extract_first() is not None:
  47             city = response.xpath('//address[@class="c-address"]/div[3]/span/text()').extract_first()
  48         else:
  49             city = response.xpath('//address[@class="c-address"]/div[2]/span/text()').extract_first()
  50 
  51         if response.xpath('//address[@class="c-address"]/div[2]/abbr/text()').extract_first() is not None:
  52             the_state = response.xpath('//address[@class="c-address"]/div[2]/abbr/text()').extract_first()
  53             the_postal = response.xpath('//address[@class="c-address"]/div[2]/span[2]/text()').extract_first()
  54         else:
  55             the_state = response.xpath('//address[@class="c-address"]/div[3]/abbr/text()').extract_first()
  56             the_postal = response.xpath('//address[@class="c-address"]/div[3]/span[2]/text()').extract_first()
  57 
  58         if '/united-states/' in response.url:
  59             country = 'US'
  60         elif '/canada/' in response.url:
  61             country = 'CA'
  62         else:
  63             country = ''
  64 
  65         props = {
  66             'ref': response.xpath('//main/@itemid').extract_first().split('#')[1],
  67             'website': response.url,
  68             'addr_full': response.xpath('//address[@class="c-address"]/div[1]/span/text()').extract_first(),
  69             'phone': response.xpath('//div[@class="c-phone-number c-phone-main-number"]/a/text()').extract_first(),
  70             'city': city,
  71             'postcode': the_postal,
  72             'state': the_state,
  73             'opening_hours': opening_hours,
  74             'country': country,
  75             'lat': float(response.xpath('//span[@class="coordinates"]/meta[1]/@content').extract_first()),
  76             'lon': float(response.xpath('//span[@class="coordinates"]/meta[2]/@content').extract_first()),
  77         }
  78 
  79         yield GeojsonPointItem(**props)
  80 
  81     def parse_within_city(self, response):
  82         stores = response.xpath('//h2[@class="Teaser-title"]/a/@href').extract()
  83 
  84         for store in stores:
  85             yield scrapy.Request(
  86                 response.urljoin(store),
  87                 callback=self.parse_store
  88             )
  89 
  90     def parse_city(self, response):
  91         cities = response.xpath('//li[@class="Directory-listItem"]/a/@href').extract()
  92 
  93         for city in cities:
  94             determine_multi_state = city.split('/')
  95             if len(determine_multi_state) == 4:
  96                 yield scrapy.Request(
  97                     response.urljoin(city),
  98                     callback=self.parse_within_city
  99                 )
  100             else:
  101                 yield scrapy.Request(
  102                     response.urljoin(city),
  103                     callback=self.parse_store
  104                 )
  105 
  106     def parse_state(self, response):
  107         states = response.xpath('//li[@class="Directory-listItem"]/a/@href').extract()
  108 
  109         for state in states:
  110             determine_multi_state = state.split('/')
  111             if len(determine_multi_state) <= 5:
  112                 yield scrapy.Request(
  113                     response.urljoin(state),
  114                     callback=self.parse_city
  115                 )
  116             else:
  117                 yield scrapy.Request(
  118                     response.urljoin(state),
  119                     callback=self.parse_store
  120                 )
  121 
  122     def parse(self, response):
  123         countries = response.xpath('//li[@class="Directory-listItem"]/a/@href').extract()
  124 
  125         for country in countries:
  126             yield scrapy.Request(
  127                 response.urljoin(country),
  128                 callback=self.parse_state
  129             )
  130
  ```
  --- 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/papa_johns.py b/locations/spiders/papa_johns.py
  --- a/locations/spiders/papa_johns.py
  +++ b/locations/spiders/papa_johns.py
  @@ -5,14 +5,20 @@
   from locations.items import GeojsonPointItem
   from locations.hours import OpeningHours
   
  -day_map = {'MONDAY': 'Mo', 'TUESDAY': 'Tu', 'WEDNESDAY': 'We', 'THURSDAY': 'Th',
  -           'FRIDAY': 'Fr', 'SATURDAY': 'Sa', 'SUNDAY': 'Su'}
  +day_map = {
  +    'MONDAY': 'Mo',
  +    'TUESDAY': 'Tu',
  +    'WEDNESDAY': 'We',
  +    'THURSDAY': 'Th',
  +    'FRIDAY': 'Fr',
  +    'SATURDAY': 'Sa',
  +    'SUNDAY': 'Su',
  +}
   
   
   class PapaJohnsSpider(scrapy.Spider):
  -
       name = "papa_johns"
  -    item_attributes = { 'brand': "Papa John's Pizza", 'brand_wikidata': "Q2759586" }
  +    item_attributes = {'brand': "Papa John's Pizza", 'brand_wikidata': "Q2759586"}
       allowed_domains = ["papajohns.com", ]
   
       start_urls = (
  @@ -59,6 +65,8 @@
               country = 'US'
           elif '/canada/' in response.url:
               country = 'CA'
  +        elif response.url == 'https://locations.papajohns.com/index.html':
  +            return
           else:
               country = ''
   
  @@ -72,8 +80,8 @@
               'state': the_state,
               'opening_hours': opening_hours,
               'country': country,
  -            'lat': float(response.xpath('//span[@class="coordinates"]/meta[1]/@content').extract_first()),
  -            'lon': float(response.xpath('//span[@class="coordinates"]/meta[2]/@content').extract_first()),
  +            'lat': response.xpath('//span[@class="coordinates"]/meta[1]/@content').extract_first(),
  +            'lon': response.xpath('//span[@class="coordinates"]/meta[2]/@content').extract_first(),
           }
   
           yield GeojsonPointItem(**props)
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/papa_johns.py b/locations/spiders/papa_johns.py\n--- a/locations/spiders/papa_johns.py\n+++ b/locations/spiders/papa_johns.py\n@@ -5,14 +5,20 @@\n from locations.items import GeojsonPointItem\n from locations.hours import OpeningHours\n \n-day_map = {'MONDAY': 'Mo', 'TUESDAY': 'Tu', 'WEDNESDAY': 'We', 'THURSDAY': 'Th',\n-           'FRIDAY': 'Fr', 'SATURDAY': 'Sa', 'SUNDAY': 'Su'}\n+day_map = {\n+    'MONDAY': 'Mo',\n+    'TUESDAY': 'Tu',\n+    'WEDNESDAY': 'We',\n+    'THURSDAY': 'Th',\n+    'FRIDAY': 'Fr',\n+    'SATURDAY': 'Sa',\n+    'SUNDAY': 'Su',\n+}\n \n \n class PapaJohnsSpider(scrapy.Spider):\n-\n     name = \"papa_johns\"\n-    item_attributes = { 'brand': \"Papa John's Pizza\", 'brand_wikidata': \"Q2759586\" }\n+    item_attributes = {'brand': \"Papa John's Pizza\", 'brand_wikidata': \"Q2759586\"}\n     allowed_domains = [\"papajohns.com\", ]\n \n     start_urls = (\n@@ -59,6 +65,8 @@\n             country = 'US'\n         elif '/canada/' in response.url:\n             country = 'CA'\n+        elif response.url == 'https://locations.papajohns.com/index.html':\n+            return\n         else:\n             country = ''\n \n@@ -72,8 +80,8 @@\n             'state': the_state,\n             'opening_hours': opening_hours,\n             'country': country,\n-            'lat': float(response.xpath('//span[@class=\"coordinates\"]/meta[1]/@content').extract_first()),\n-            'lon': float(response.xpath('//span[@class=\"coordinates\"]/meta[2]/@content').extract_first()),\n+            'lat': response.xpath('//span[@class=\"coordinates\"]/meta[1]/@content').extract_first(),\n+            'lon': response.xpath('//span[@class=\"coordinates\"]/meta[2]/@content').extract_first(),\n         }\n \n         yield GeojsonPointItem(**props)\n", "issue": "Spider papa_johns is broken\nDuring the global build at 2021-08-18-14-42-26, spider **papa_johns** failed with **3199 features** and **1 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/logs/papa_johns.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/output/papa_johns.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-08-18-14-42-26/output/papa_johns.geojson))\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport scrapy\nimport json\n\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nday_map = {'MONDAY': 'Mo', 'TUESDAY': 'Tu', 'WEDNESDAY': 'We', 'THURSDAY': 'Th',\n           'FRIDAY': 'Fr', 'SATURDAY': 'Sa', 'SUNDAY': 'Su'}\n\n\nclass PapaJohnsSpider(scrapy.Spider):\n\n    name = \"papa_johns\"\n    item_attributes = { 'brand': \"Papa John's Pizza\", 'brand_wikidata': \"Q2759586\" }\n    allowed_domains = [\"papajohns.com\", ]\n\n    start_urls = (\n        'https://locations.papajohns.com/',\n    )\n    download_delay = 0.2\n\n    def parse_hours(self, hours):\n        if not hours:\n            return ''\n        try:\n            opening_hours = OpeningHours()\n            the_hours = json.loads(hours[0])\n            for day in the_hours:\n                the_day = day_map[day['day']]\n                the_start = str(day['intervals'][0]['start'])\n                the_end = str(day['intervals'][0]['end'])\n                if the_start == '0':\n                    the_start = '000'\n                if the_end == '0':\n                    the_end = '000'\n                opening_hours.add_range(day=the_day, open_time=the_start, close_time=the_end, time_format='%H%M')\n            return opening_hours.as_opening_hours()\n        except IndexError:\n            return ''\n\n    def parse_store(self, response):\n        hours = response.xpath('//div[@class=\"c-location-hours-details-wrapper js-location-hours\"]/@data-days').extract()\n        opening_hours = self.parse_hours(hours)\n\n        if response.xpath('//address[@class=\"c-address\"]/div[3]/span/text()').extract_first() is not None:\n            city = response.xpath('//address[@class=\"c-address\"]/div[3]/span/text()').extract_first()\n        else:\n            city = response.xpath('//address[@class=\"c-address\"]/div[2]/span/text()').extract_first()\n\n        if response.xpath('//address[@class=\"c-address\"]/div[2]/abbr/text()').extract_first() is not None:\n            the_state = response.xpath('//address[@class=\"c-address\"]/div[2]/abbr/text()').extract_first()\n            the_postal = response.xpath('//address[@class=\"c-address\"]/div[2]/span[2]/text()').extract_first()\n        else:\n            the_state = response.xpath('//address[@class=\"c-address\"]/div[3]/abbr/text()').extract_first()\n            the_postal = response.xpath('//address[@class=\"c-address\"]/div[3]/span[2]/text()').extract_first()\n\n        if '/united-states/' in response.url:\n            country = 'US'\n        elif '/canada/' in response.url:\n            country = 'CA'\n        else:\n            country = ''\n\n        props = {\n            'ref': response.xpath('//main/@itemid').extract_first().split('#')[1],\n            'website': response.url,\n            'addr_full': response.xpath('//address[@class=\"c-address\"]/div[1]/span/text()').extract_first(),\n            'phone': response.xpath('//div[@class=\"c-phone-number c-phone-main-number\"]/a/text()').extract_first(),\n            'city': city,\n            'postcode': the_postal,\n            'state': the_state,\n            'opening_hours': opening_hours,\n            'country': country,\n            'lat': float(response.xpath('//span[@class=\"coordinates\"]/meta[1]/@content').extract_first()),\n            'lon': float(response.xpath('//span[@class=\"coordinates\"]/meta[2]/@content').extract_first()),\n        }\n\n        yield GeojsonPointItem(**props)\n\n    def parse_within_city(self, response):\n        stores = response.xpath('//h2[@class=\"Teaser-title\"]/a/@href').extract()\n\n        for store in stores:\n            yield scrapy.Request(\n                response.urljoin(store),\n                callback=self.parse_store\n            )\n\n    def parse_city(self, response):\n        cities = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for city in cities:\n            determine_multi_state = city.split('/')\n            if len(determine_multi_state) == 4:\n                yield scrapy.Request(\n                    response.urljoin(city),\n                    callback=self.parse_within_city\n                )\n            else:\n                yield scrapy.Request(\n                    response.urljoin(city),\n                    callback=self.parse_store\n                )\n\n    def parse_state(self, response):\n        states = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for state in states:\n            determine_multi_state = state.split('/')\n            if len(determine_multi_state) <= 5:\n                yield scrapy.Request(\n                    response.urljoin(state),\n                    callback=self.parse_city\n                )\n            else:\n                yield scrapy.Request(\n                    response.urljoin(state),\n                    callback=self.parse_store\n                )\n\n    def parse(self, response):\n        countries = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for country in countries:\n            yield scrapy.Request(\n                response.urljoin(country),\n                callback=self.parse_state\n            )\n", "path": "locations/spiders/papa_johns.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport scrapy\nimport json\n\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nday_map = {\n    'MONDAY': 'Mo',\n    'TUESDAY': 'Tu',\n    'WEDNESDAY': 'We',\n    'THURSDAY': 'Th',\n    'FRIDAY': 'Fr',\n    'SATURDAY': 'Sa',\n    'SUNDAY': 'Su',\n}\n\n\nclass PapaJohnsSpider(scrapy.Spider):\n    name = \"papa_johns\"\n    item_attributes = {'brand': \"Papa John's Pizza\", 'brand_wikidata': \"Q2759586\"}\n    allowed_domains = [\"papajohns.com\", ]\n\n    start_urls = (\n        'https://locations.papajohns.com/',\n    )\n    download_delay = 0.2\n\n    def parse_hours(self, hours):\n        if not hours:\n            return ''\n        try:\n            opening_hours = OpeningHours()\n            the_hours = json.loads(hours[0])\n            for day in the_hours:\n                the_day = day_map[day['day']]\n                the_start = str(day['intervals'][0]['start'])\n                the_end = str(day['intervals'][0]['end'])\n                if the_start == '0':\n                    the_start = '000'\n                if the_end == '0':\n                    the_end = '000'\n                opening_hours.add_range(day=the_day, open_time=the_start, close_time=the_end, time_format='%H%M')\n            return opening_hours.as_opening_hours()\n        except IndexError:\n            return ''\n\n    def parse_store(self, response):\n        hours = response.xpath('//div[@class=\"c-location-hours-details-wrapper js-location-hours\"]/@data-days').extract()\n        opening_hours = self.parse_hours(hours)\n\n        if response.xpath('//address[@class=\"c-address\"]/div[3]/span/text()').extract_first() is not None:\n            city = response.xpath('//address[@class=\"c-address\"]/div[3]/span/text()').extract_first()\n        else:\n            city = response.xpath('//address[@class=\"c-address\"]/div[2]/span/text()').extract_first()\n\n        if response.xpath('//address[@class=\"c-address\"]/div[2]/abbr/text()').extract_first() is not None:\n            the_state = response.xpath('//address[@class=\"c-address\"]/div[2]/abbr/text()').extract_first()\n            the_postal = response.xpath('//address[@class=\"c-address\"]/div[2]/span[2]/text()').extract_first()\n        else:\n            the_state = response.xpath('//address[@class=\"c-address\"]/div[3]/abbr/text()').extract_first()\n            the_postal = response.xpath('//address[@class=\"c-address\"]/div[3]/span[2]/text()').extract_first()\n\n        if '/united-states/' in response.url:\n            country = 'US'\n        elif '/canada/' in response.url:\n            country = 'CA'\n        elif response.url == 'https://locations.papajohns.com/index.html':\n            return\n        else:\n            country = ''\n\n        props = {\n            'ref': response.xpath('//main/@itemid').extract_first().split('#')[1],\n            'website': response.url,\n            'addr_full': response.xpath('//address[@class=\"c-address\"]/div[1]/span/text()').extract_first(),\n            'phone': response.xpath('//div[@class=\"c-phone-number c-phone-main-number\"]/a/text()').extract_first(),\n            'city': city,\n            'postcode': the_postal,\n            'state': the_state,\n            'opening_hours': opening_hours,\n            'country': country,\n            'lat': response.xpath('//span[@class=\"coordinates\"]/meta[1]/@content').extract_first(),\n            'lon': response.xpath('//span[@class=\"coordinates\"]/meta[2]/@content').extract_first(),\n        }\n\n        yield GeojsonPointItem(**props)\n\n    def parse_within_city(self, response):\n        stores = response.xpath('//h2[@class=\"Teaser-title\"]/a/@href').extract()\n\n        for store in stores:\n            yield scrapy.Request(\n                response.urljoin(store),\n                callback=self.parse_store\n            )\n\n    def parse_city(self, response):\n        cities = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for city in cities:\n            determine_multi_state = city.split('/')\n            if len(determine_multi_state) == 4:\n                yield scrapy.Request(\n                    response.urljoin(city),\n                    callback=self.parse_within_city\n                )\n            else:\n                yield scrapy.Request(\n                    response.urljoin(city),\n                    callback=self.parse_store\n                )\n\n    def parse_state(self, response):\n        states = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for state in states:\n            determine_multi_state = state.split('/')\n            if len(determine_multi_state) <= 5:\n                yield scrapy.Request(\n                    response.urljoin(state),\n                    callback=self.parse_city\n                )\n            else:\n                yield scrapy.Request(\n                    response.urljoin(state),\n                    callback=self.parse_store\n                )\n\n    def parse(self, response):\n        countries = response.xpath('//li[@class=\"Directory-listItem\"]/a/@href').extract()\n\n        for country in countries:\n            yield scrapy.Request(\n                response.urljoin(country),\n                callback=self.parse_state\n            )\n", "path": "locations/spiders/papa_johns.py"}]}