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()

```

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',

{"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"}]}