prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Spider upsstore is broken
  During the global build at 2021-10-13-14-42-23, spider **upsstore** failed with **5176 features** and **5 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/logs/upsstore.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/upsstore.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/upsstore.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/upsstore.py`
  Content:
  ```
  1 import scrapy
  2 import json
  3 import re
  4 from locations.items import GeojsonPointItem
  5 from locations.hours import OpeningHours
  6 
  7 DAY_MAPPING = {
  8     "MONDAY": "Mo",
  9     "TUESDAY": "Tu",
  10     "WEDNESDAY": "We",
  11     "THURSDAY": "Th",
  12     "FRIDAY": "Fr",
  13     "SATURDAY": "Sa",
  14     "SUNDAY": "Su"
  15 }
  16 
  17 
  18 class UpsStoreSpider(scrapy.Spider):
  19     name = "upsstore"
  20     item_attributes = { 'brand': "UPS Store" }
  21     allowed_domains = ["theupsstore.com"]
  22     download_delay = 0.1
  23     start_urls = (
  24         'https://locations.theupsstore.com/',
  25     )
  26 
  27     def parse_hours(self, hours):
  28         """
  29         :param hours:
  30         :return:
  31         """
  32         hours = json.loads(hours)
  33         o = OpeningHours()
  34 
  35         for day in hours["hours"]["days"]:
  36             if not day["isClosed"]:
  37                 interval = day["intervals"][0]
  38 
  39                 o.add_range(DAY_MAPPING[day["day"]],
  40                             open_time=str(interval["start"]),
  41                             close_time=str(interval["end"]),
  42                             time_format="%H%M")
  43         return o.as_opening_hours()
  44 
  45     def parse_store(self, response):
  46         ref = response.xpath('//input[@id="store_id"]/@value').extract_first()
  47         if not ref:
  48             ref = re.search(r'store(\d+)@theupsstore.com',
  49                             response.xpath('//a[@itemprop="email"]/text()').extract_first()).groups()
  50 
  51         properties = {
  52             'name': response.xpath('//span[@class="LocationName-geo"]/text()').extract_first(),
  53             'phone': response.xpath('//span[@itemprop="telephone"]/text()').extract_first(),
  54             'addr_full': response.xpath('//meta[@itemprop="streetAddress"]/@content').extract_first(),
  55             'city': response.xpath('//meta[@itemprop="addressLocality"]/@content').extract_first(),
  56             'state': response.xpath('//abbr[@itemprop="addressRegion"]/text()').extract_first(),
  57             'country': response.xpath('//abbr[@itemprop="addressCountry"]/text()').extract_first(),
  58             'postcode': response.xpath('//span[@itemprop="postalCode"]/text()').extract_first(),
  59             'ref': ref,
  60             'website': response.url,
  61             'lat': float(response.xpath('//meta[@itemprop="latitude"]/@content').extract_first()),
  62             'lon': float(response.xpath('//meta[@itemprop="longitude"]/@content').extract_first()),
  63         }
  64 
  65         hours = response.xpath('//script[@id="location_info_hours"]/text()').extract_first()
  66         try:
  67             hours = self.parse_hours(hours)
  68             if hours:
  69                 properties['opening_hours'] = hours
  70         except:
  71             pass
  72 
  73         yield GeojsonPointItem(**properties)
  74 
  75     def parse(self, response):
  76         urls = response.xpath('//a[@class="Directory-listLink"]/@href').extract()
  77 
  78         if urls:
  79             for url in urls:
  80                 if len(url.split('/')) == 3:
  81                     callback = self.parse_store
  82                 else:
  83                     callback = self.parse
  84 
  85                 yield scrapy.Request(
  86                     response.urljoin(url),
  87                     callback=callback,
  88                 )
  89 
  90         else:
  91             urls = response.xpath('//a[@class="Link"]/@href').extract()
  92             for url in urls:
  93                 yield scrapy.Request(
  94                     response.urljoin(url),
  95                     callback=self.parse_store,
  96                 )
  ```
  --- 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/upsstore.py b/locations/spiders/upsstore.py
  --- a/locations/spiders/upsstore.py
  +++ b/locations/spiders/upsstore.py
  @@ -43,6 +43,9 @@
           return o.as_opening_hours()
   
       def parse_store(self, response):
  +        if "Permanently Closed" in response.text:
  +            return
  +
           ref = response.xpath('//input[@id="store_id"]/@value').extract_first()
           if not ref:
               ref = re.search(r'store(\d+)@theupsstore.com',
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/upsstore.py b/locations/spiders/upsstore.py\n--- a/locations/spiders/upsstore.py\n+++ b/locations/spiders/upsstore.py\n@@ -43,6 +43,9 @@\n         return o.as_opening_hours()\n \n     def parse_store(self, response):\n+        if \"Permanently Closed\" in response.text:\n+            return\n+\n         ref = response.xpath('//input[@id=\"store_id\"]/@value').extract_first()\n         if not ref:\n             ref = re.search(r'store(\\d+)@theupsstore.com',\n", "issue": "Spider upsstore is broken\nDuring the global build at 2021-10-13-14-42-23, spider **upsstore** failed with **5176 features** and **5 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/logs/upsstore.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/upsstore.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-10-13-14-42-23/output/upsstore.geojson))\n", "before_files": [{"content": "import scrapy\nimport json\nimport re\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nDAY_MAPPING = {\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 UpsStoreSpider(scrapy.Spider):\n    name = \"upsstore\"\n    item_attributes = { 'brand': \"UPS Store\" }\n    allowed_domains = [\"theupsstore.com\"]\n    download_delay = 0.1\n    start_urls = (\n        'https://locations.theupsstore.com/',\n    )\n\n    def parse_hours(self, hours):\n        \"\"\"\n        :param hours:\n        :return:\n        \"\"\"\n        hours = json.loads(hours)\n        o = OpeningHours()\n\n        for day in hours[\"hours\"][\"days\"]:\n            if not day[\"isClosed\"]:\n                interval = day[\"intervals\"][0]\n\n                o.add_range(DAY_MAPPING[day[\"day\"]],\n                            open_time=str(interval[\"start\"]),\n                            close_time=str(interval[\"end\"]),\n                            time_format=\"%H%M\")\n        return o.as_opening_hours()\n\n    def parse_store(self, response):\n        ref = response.xpath('//input[@id=\"store_id\"]/@value').extract_first()\n        if not ref:\n            ref = re.search(r'store(\\d+)@theupsstore.com',\n                            response.xpath('//a[@itemprop=\"email\"]/text()').extract_first()).groups()\n\n        properties = {\n            'name': response.xpath('//span[@class=\"LocationName-geo\"]/text()').extract_first(),\n            'phone': response.xpath('//span[@itemprop=\"telephone\"]/text()').extract_first(),\n            'addr_full': response.xpath('//meta[@itemprop=\"streetAddress\"]/@content').extract_first(),\n            'city': response.xpath('//meta[@itemprop=\"addressLocality\"]/@content').extract_first(),\n            'state': response.xpath('//abbr[@itemprop=\"addressRegion\"]/text()').extract_first(),\n            'country': response.xpath('//abbr[@itemprop=\"addressCountry\"]/text()').extract_first(),\n            'postcode': response.xpath('//span[@itemprop=\"postalCode\"]/text()').extract_first(),\n            'ref': ref,\n            'website': response.url,\n            'lat': float(response.xpath('//meta[@itemprop=\"latitude\"]/@content').extract_first()),\n            'lon': float(response.xpath('//meta[@itemprop=\"longitude\"]/@content').extract_first()),\n        }\n\n        hours = response.xpath('//script[@id=\"location_info_hours\"]/text()').extract_first()\n        try:\n            hours = self.parse_hours(hours)\n            if hours:\n                properties['opening_hours'] = hours\n        except:\n            pass\n\n        yield GeojsonPointItem(**properties)\n\n    def parse(self, response):\n        urls = response.xpath('//a[@class=\"Directory-listLink\"]/@href').extract()\n\n        if urls:\n            for url in urls:\n                if len(url.split('/')) == 3:\n                    callback = self.parse_store\n                else:\n                    callback = self.parse\n\n                yield scrapy.Request(\n                    response.urljoin(url),\n                    callback=callback,\n                )\n\n        else:\n            urls = response.xpath('//a[@class=\"Link\"]/@href').extract()\n            for url in urls:\n                yield scrapy.Request(\n                    response.urljoin(url),\n                    callback=self.parse_store,\n                )", "path": "locations/spiders/upsstore.py"}], "after_files": [{"content": "import scrapy\nimport json\nimport re\nfrom locations.items import GeojsonPointItem\nfrom locations.hours import OpeningHours\n\nDAY_MAPPING = {\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 UpsStoreSpider(scrapy.Spider):\n    name = \"upsstore\"\n    item_attributes = { 'brand': \"UPS Store\" }\n    allowed_domains = [\"theupsstore.com\"]\n    download_delay = 0.1\n    start_urls = (\n        'https://locations.theupsstore.com/',\n    )\n\n    def parse_hours(self, hours):\n        \"\"\"\n        :param hours:\n        :return:\n        \"\"\"\n        hours = json.loads(hours)\n        o = OpeningHours()\n\n        for day in hours[\"hours\"][\"days\"]:\n            if not day[\"isClosed\"]:\n                interval = day[\"intervals\"][0]\n\n                o.add_range(DAY_MAPPING[day[\"day\"]],\n                            open_time=str(interval[\"start\"]),\n                            close_time=str(interval[\"end\"]),\n                            time_format=\"%H%M\")\n        return o.as_opening_hours()\n\n    def parse_store(self, response):\n        if \"Permanently Closed\" in response.text:\n            return\n\n        ref = response.xpath('//input[@id=\"store_id\"]/@value').extract_first()\n        if not ref:\n            ref = re.search(r'store(\\d+)@theupsstore.com',\n                            response.xpath('//a[@itemprop=\"email\"]/text()').extract_first()).groups()\n\n        properties = {\n            'name': response.xpath('//span[@class=\"LocationName-geo\"]/text()').extract_first(),\n            'phone': response.xpath('//span[@itemprop=\"telephone\"]/text()').extract_first(),\n            'addr_full': response.xpath('//meta[@itemprop=\"streetAddress\"]/@content').extract_first(),\n            'city': response.xpath('//meta[@itemprop=\"addressLocality\"]/@content').extract_first(),\n            'state': response.xpath('//abbr[@itemprop=\"addressRegion\"]/text()').extract_first(),\n            'country': response.xpath('//abbr[@itemprop=\"addressCountry\"]/text()').extract_first(),\n            'postcode': response.xpath('//span[@itemprop=\"postalCode\"]/text()').extract_first(),\n            'ref': ref,\n            'website': response.url,\n            'lat': float(response.xpath('//meta[@itemprop=\"latitude\"]/@content').extract_first()),\n            'lon': float(response.xpath('//meta[@itemprop=\"longitude\"]/@content').extract_first()),\n        }\n\n        hours = response.xpath('//script[@id=\"location_info_hours\"]/text()').extract_first()\n        try:\n            hours = self.parse_hours(hours)\n            if hours:\n                properties['opening_hours'] = hours\n        except:\n            pass\n\n        yield GeojsonPointItem(**properties)\n\n    def parse(self, response):\n        urls = response.xpath('//a[@class=\"Directory-listLink\"]/@href').extract()\n\n        if urls:\n            for url in urls:\n                if len(url.split('/')) == 3:\n                    callback = self.parse_store\n                else:\n                    callback = self.parse\n\n                yield scrapy.Request(\n                    response.urljoin(url),\n                    callback=callback,\n                )\n\n        else:\n            urls = response.xpath('//a[@class=\"Link\"]/@href').extract()\n            for url in urls:\n                yield scrapy.Request(\n                    response.urljoin(url),\n                    callback=self.parse_store,\n                )", "path": "locations/spiders/upsstore.py"}]}