internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: alltheplaces/alltheplaces

Issue:
Hardee's
https://www.hardees.com/locations


Discussion:

Resolving patch:
diff --git a/locations/spiders/hardees_carlsjr.py b/locations/spiders/hardees_carlsjr.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/hardees_carlsjr.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+import urllib.parse
+
+import scrapy
+from scrapy.spiders import SitemapSpider
+
+from locations.hours import OpeningHours
+from locations.items import GeojsonPointItem
+
+BRANDS = {
+    "locations.carlsjr.com": {"brand": "Carl's Jr.", "brand_wikidata": "Q1043486"},
+    "locations.hardees.com": {"brand": "Hardee's", "brand_wikidata": "Q1585088"},
+}
+
+
+class HardeesCarlsJrSpider(SitemapSpider):
+    name = "hardees_carlsjr"
+    allowed_domains = ["locations.hardees.com", "locations.carlsjr.com"]
+    sitemap_urls = [
+        "https://locations.hardees.com/robots.txt",
+        "https://locations.carlsjr.com/robots.txt",
+    ]
+    sitemap_rules = [(r"https://locations\..*\.com/.*/.*/.*", "parse")]
+
+    def parse(self, response):
+        hours = OpeningHours()
+        for row in response.xpath('//*[@itemprop="openingHours"]/@content').extract():
+            day, interval = row.split(" ", 1)
+            if interval == "All Day":
+                interval = "00:00-00:00"
+            elif interval == "Closed":
+                continue
+            open_time, close_time = interval.split("-")
+            hours.add_range(day, open_time, close_time)
+        properties = {
+            "ref": response.css("main").attrib["itemid"],
+            "website": response.url,
+            "lat": response.css('[itemprop="latitude"]').attrib["content"],
+            "lon": response.css('[itemprop="longitude"]').attrib["content"],
+            "name": response.xpath("//title/text()").get().split(":")[0],
+            "street_address": response.css('[itemprop="streetAddress"]').attrib[
+                "content"
+            ],
+            "city": response.css(".Address-city::text").get(),
+            "state": response.css('[itemprop="addressRegion"]::text').get(),
+            "postcode": response.css('[itemprop="postalCode"]::text').get(),
+            "phone": response.css('[itemprop="telephone"]::text').get(),
+            "opening_hours": hours.as_opening_hours(),
+        }
+        hostname = urllib.parse.urlparse(response.url).hostname
+        properties.update(BRANDS[hostname])
+        return GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Spider western_family is broken
During the global build at 2021-08-04-14-42-45, spider **western_family** failed with **0 features** and **0 errors**.

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


Discussion:

Resolving patch:
diff --git a/locations/spiders/western_family.py b/locations/spiders/western_family.py
deleted file mode 100644
--- a/locations/spiders/western_family.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-import scrapy
-
-from locations.items import GeojsonPointItem
-
-
-class WesternFamilySpider(scrapy.Spider):
-
-    name = "western_family"
-    item_attributes = {"brand": "Western Family"}
-    allowed_domains = ["www.westernfamily.com"]
-    start_urls = (
-        "http://www.westernfamily.com/wp-admin/admin-ajax.php?action=store_search&lat=45.5230622&lng=-122.67648159999999&max_results=2500&search_radius=50000&autoload=1",
-    )
-
-    def parse(self, response):
-        results = response.json()
-        for data in results:
-            properties = {
-                "ref": data["id"],
-                "name": data["store"],
-                "lat": data["lat"],
-                "lon": data["lng"],
-                "addr_full": data["address"],
-                "city": data["city"],
-                "state": data["state"],
-                "postcode": data["zip"],
-                "country": data["country"],
-                "phone": data["phone"],
-                "website": data["url"],
-            }
-
-            yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Spider wafflehouse is broken
During the global build at 2021-06-02-14-42-40, spider **wafflehouse** failed with **0 features** and **0 errors**.

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


Discussion:

Resolving patch:
diff --git a/locations/spiders/wafflehouse.py b/locations/spiders/wafflehouse.py
--- a/locations/spiders/wafflehouse.py
+++ b/locations/spiders/wafflehouse.py
@@ -44,10 +44,11 @@ def parse_store(self, response):
             "website": response.url,
             "name": data["name"],
             "phone": data["telephone"],
-            "addr_full": data["address"]["streetAddress"],
+            "street_address": data["address"]["streetAddress"],
             "city": data["address"]["addressLocality"],
             "state": data["address"]["addressRegion"],
             "postcode": data["address"]["postalCode"],
             "opening_hours": hours.as_opening_hours(),
         }
+
         yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
A1 Bulgaria
https://www.a1.bg/1/mm/shops/mc/index/ma/index/mo/1?ajaxaction=getShopsWithWorkTime

The working days are written in Cyrrilic. Here are the translations:
Понеделник - Monday
Вторник - Tuesday
Сряда - Wednesday
Четвъртък - Thursday
Петък - Friday
Събота - Saturday
Неделя - Sunday

Brand tags:
```
brand=A1
brand:wikidata=Q1941592
```


Discussion:

Resolving patch:
diff --git a/locations/hours.py b/locations/hours.py
--- a/locations/hours.py
+++ b/locations/hours.py
@@ -13,6 +13,8 @@ def add_range(self, day, open_time, close_time, time_format="%H:%M"):
         if day not in DAYS:
             raise ValueError("day must be one of " + ", ".join(DAYS))
 
+        if open_time is None or close_time is None:
+            return
         if open_time.lower() == "closed":
             return
         if close_time.lower() == "closed":
diff --git a/locations/spiders/a1.py b/locations/spiders/a1.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/a1.py
@@ -0,0 +1,50 @@
+import scrapy
+
+from locations.hours import OpeningHours
+from locations.items import GeojsonPointItem
+
+DAY_MAPPING = {
+    "Понеделник": "Mo",
+    "Вторник": "Tu",
+    "Сряда": "We",
+    "Четвъртък": "Th",
+    "Петък": "Fr",
+    "Събота": "Sa",
+    "Неделя": "Su",
+}
+
+
+class A1Spider(scrapy.Spider):
+    name = "a1"
+    item_attributes = {"brand": "A1", "brand_wikidata": "Q1941592", "country": "BG"}
+    allowed_domains = ["www.a1.bg"]
+    start_urls = [
+        "https://www.a1.bg/1/mm/shops/mc/index/ma/index/mo/1?ajaxaction=getShopsWithWorkTime"
+    ]
+
+    def parse(self, response):
+        data = response.json()
+
+        for store in data["response"]:
+            item = GeojsonPointItem()
+            item["ref"] = store["id"]
+            item["name"] = store["name"]
+            item["addr_full"] = store["address"].strip()
+            item["lat"] = store["latitude"]
+            item["lon"] = store["longitude"]
+
+            if store.get("phone"):
+                item["phone"] = "+" + store["phone"]
+
+            oh = OpeningHours()
+            for day in store["worktime"]:
+                oh.add_range(
+                    DAY_MAPPING[day["weekday"]],
+                    day["hour_from"],
+                    day["hour_to"],
+                    "%H:%M:%S",
+                )
+
+            item["opening_hours"] = oh.as_opening_hours()
+
+            yield item


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
boots.py spider doesn't correctly pick up all opticians
The current test in boots.py to switch the brand tags for opticians is `properties["name"].startswith("Opticians - ")`:
https://github.com/alltheplaces/alltheplaces/blob/master/locations/spiders/boots.py#L73

But this is not general enough to catch all of them. The displayed name of some opticians branches only start with "Opticians " or "Opticians-". For example https://www.boots.com/stores/3730-tewkesbury-high-street-opticians-gl20-5jz and https://www.boots.com/stores/3947-camden-high-street-opticians-nw1-0lu

I think you could safely change the test to `properties["name"].startswith("Opticians")` but the code a few lines below to strip out the "Opticians" prefix would need to be more complicated.


Discussion:
`.replace("Opticians", "").strip("- ")` should drop the prefix.

Resolving patch:
diff --git a/locations/spiders/boots.py b/locations/spiders/boots.py
--- a/locations/spiders/boots.py
+++ b/locations/spiders/boots.py
@@ -70,10 +70,10 @@ def parse_stores(self, response):
         if hours:
             properties["opening_hours"] = hours
 
-        if properties["name"].startswith("Opticians - "):
+        if properties["name"].startswith("Opticians"):
             properties["brand"] = "Boots Opticians"
             properties["brand_wikidata"] = "Q4944037"
-            properties["name"] = properties["name"][12:]
+            properties["name"] = properties["name"].replace("Opticians", "").strip("- ")
 
         yield GeojsonPointItem(**properties)
 


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Vivacom
https://www.vivacom.bg/bg/residential/magazini

Brand tags:
```
brand=Vivacom
brand:wikidata=Q7937522
```


Discussion:

Resolving patch:
diff --git a/locations/spiders/vivacom_bg.py b/locations/spiders/vivacom_bg.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/vivacom_bg.py
@@ -0,0 +1,59 @@
+import re
+
+from scrapy import Spider
+
+from locations.items import GeojsonPointItem
+
+
+class VivacomBGSpider(Spider):
+    name = "vivacom_bg"
+    item_attributes = {
+        "brand": "Vivacom",
+        "brand_wikidata": "Q7937522",
+        "country": "BG",
+    }
+    start_urls = ["https://www.vivacom.bg/bg/stores/xhr?method=getJSON"]
+
+    def parse(self, response):
+        for store in response.json():
+
+            if "partners" in store["store_img"]:
+                continue
+
+            item = GeojsonPointItem()
+
+            item["ref"] = store["store_id"]
+            item["lat"], item["lon"] = store["latlng"].split(",")
+            item["name"] = store["store_name"]
+            item["phone"] = store["store_phone"]
+
+            opening_hours = (
+                store["store_time"]
+                .strip()
+                .replace("почивен ден", "off")
+                .replace("пон.", "Mo")
+                .replace("пт.", "Fr")
+                .replace("пет.", "Fr")
+                .replace("съб.", "Sa")
+                .replace("съб", "Sa")
+                .replace("нед.", "Su")
+                .replace("нд.", "Su")
+                .replace("  ", " ")
+            )
+            oh = []
+            for rule in re.findall(
+                r"(\w{2})\s?-?\s?(\w{2})?:?\s?(\d{2}(\.|:)\d{2})\s?-\s?(\d{2}(\.|:)\d{2})",
+                opening_hours,
+            ):
+                start_day, end_day, start_time, _, end_time, _ = rule
+                start_time = start_time.replace(".", ":")
+                end_time = end_time.replace(".", ":")
+
+                if end_day:
+                    oh.append(f"{start_day}-{end_day} {start_time}-{end_time}")
+                else:
+                    oh.append(f"{start_day} {start_time}-{end_time}")
+
+            item["opening_hours"] = "; ".join(oh)
+
+            yield item


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Yettel Bulgaria
https://www.yettel.bg/store-locator/json

The address data is contained in `gsl_addressfield`. `thoroughfare` is the street name and street number, `locality` is `addr:city`.
```
<div class="street-block">
  <div class="thoroughfare">ул. Хаджи Димитър 6</div>
</div>
<div class="addressfield-container-inline locality-block country-BG">
  <span class="postal-code">7100</span>
  <span class="locality">Бяла</span></div>
<span class="country">България</span>
```

Brand tags:
```
brand=Yettel
brand:wikidata=Q14915070
```


Discussion:

Resolving patch:
diff --git a/locations/spiders/yettel_bg.py b/locations/spiders/yettel_bg.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/yettel_bg.py
@@ -0,0 +1,34 @@
+from scrapy import Spider, Selector
+
+from locations.items import GeojsonPointItem
+
+
+class YettelBGSpider(Spider):
+    name = "yettel_bg"
+    item_attributes = {
+        "brand": "Yettel",
+        "brand_wikidata": "Q14915070",
+        "country": "BG",
+    }
+    start_urls = ["https://www.yettel.bg/store-locator/json"]
+
+    def parse(self, response):
+        for store in response.json()["features"]:
+            item = GeojsonPointItem()
+
+            item["lon"], item["lat"] = store["geometry"]["coordinates"]
+
+            item["ref"] = store["properties"]["title"]
+            item["phone"] = store["properties"]["gsl_props_phone"]
+
+            address_block = Selector(text=store["properties"]["gsl_addressfield"])
+
+            item["street_address"] = address_block.xpath(
+                '//div[@class="thoroughfare"]/text()'
+            ).get()
+            item["postcode"] = address_block.xpath(
+                '//span[@class="postal-code"]/text()'
+            ).get()
+            item["city"] = address_block.xpath('//span[@class="locality"]/text()').get()
+
+            yield item


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Festival Foods
https://www.festfoods.com/my-store/store-locator


Discussion:

Resolving patch:
diff --git a/locations/dict_parser.py b/locations/dict_parser.py
--- a/locations/dict_parser.py
+++ b/locations/dict_parser.py
@@ -40,7 +40,8 @@ def parse(obj) -> GeojsonPointItem:
         item["city"] = DictParser.get_first_key(address, ["city", "town"])
         item["state"] = DictParser.get_first_key(address, ["state", "region"])
         item["postcode"] = DictParser.get_first_key(
-            address, ["postCode", "post_code", "postalCode", "zipCode", "zip"]
+            address,
+            ["postCode", "post_code", "postalCode", "postal_code", "zipCode", "zip"],
         )
         item["country"] = DictParser.get_first_key(address, ["country", "countryCode"])
 
diff --git a/locations/spiders/festival_foods.py b/locations/spiders/festival_foods.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/festival_foods.py
@@ -0,0 +1,35 @@
+from scrapy import Spider
+
+from locations.dict_parser import DictParser
+
+
+class FestivalFoodsSpider(Spider):
+    name = "festival_foods"
+    item_attributes = {
+        "brand": "festival_foods",
+        "brand_wikidata": "Q5445707",
+        "country": "US",
+    }
+    start_urls = ["https://api.freshop.com/1/stores?app_key=festival_foods_envano"]
+
+    def parse(self, response):
+        for store in response.json()["items"]:
+
+            # Other types are not stores
+            if store["type_id"] != "1567647":
+                continue
+
+            # 6449 is "Festival Gift Cards", not a physical location
+            if store["id"] == "6449":
+                continue
+
+            item = DictParser.parse(store)
+
+            item["street_address"] = store["address_1"]
+
+            item["website"] = "https://www.festfoods.com" + store["url"]
+
+            if store.get("identifier"):
+                item["ref"] = store["identifier"]
+
+            yield item


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
BreWingz
https://www.brewingz.com/locations-2/


Discussion:

Resolving patch:
diff --git a/locations/spiders/bre_wingz.py b/locations/spiders/bre_wingz.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/bre_wingz.py
@@ -0,0 +1,19 @@
+from scrapy import Spider
+
+from locations.dict_parser import DictParser
+
+
+class BreWingzSpider(Spider):
+    name = "bre_wingz"
+    item_attributes = {"brand": "BreWingz"}
+    start_urls = [
+        "https://www.brewingz.com/wp-admin/admin-ajax.php?action=store_search&autoload=1"
+    ]
+
+    def parse(self, response):
+        for store in response.json():
+            item = DictParser.parse(store)
+
+            item["name"] = store["store"]
+
+            yield item


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Primrose Schools
Is generating 1,221 errors. Adding a if statement for `content` should fix it. Could also be turned into a sitemap spider.


Discussion:

Resolving patch:
diff --git a/locations/spiders/primrose_schools.py b/locations/spiders/primrose_schools.py
--- a/locations/spiders/primrose_schools.py
+++ b/locations/spiders/primrose_schools.py
@@ -30,12 +30,17 @@ def parse(self, response):
 
     def parse_search(self, response):
         content = response.xpath('//script[@type="application/json"]/text()').get()
+        if content is None:
+            return
+
         schools = json.loads(content)
         for i in schools:
             if i["address_1"]:
                 properties = {
                     "name": i["name"],
-                    "addr_full": i["address_1"] + " " + i["address_2"],
+                    "street_address": ", ".join(
+                        filter(None, [i["address_1"], i["address_2"]])
+                    ),
                     "city": i["city"],
                     "state": i["state"],
                     "postcode": i["zip_code"],


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Spider dominos_pizza_jp is broken
During the global build at 2021-06-30-14-42-26, spider **dominos_pizza_jp** failed with **0 features** and **0 errors**.

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


Discussion:
It's erroring on the phone regex. It looks like it's just doing a weird `.strip()`, doing that, or nothing _should_ fix this.

Resolving patch:
diff --git a/locations/spiders/dominos_pizza_jp.py b/locations/spiders/dominos_pizza_jp.py
--- a/locations/spiders/dominos_pizza_jp.py
+++ b/locations/spiders/dominos_pizza_jp.py
@@ -8,7 +8,11 @@
 
 class DominosPizzaJPSpider(scrapy.Spider):
     name = "dominos_pizza_jp"
-    item_attributes = {"brand": "Domino's", "brand_wikidata": "Q839466"}
+    item_attributes = {
+        "brand": "Domino's",
+        "brand_wikidata": "Q839466",
+        "country": "JP",
+    }
     allowed_domains = ["dominos.jp"]
     start_urls = [
         "https://www.dominos.jp/sitemap.aspx",
@@ -27,28 +31,24 @@ def parse_store(self, response):
         properties = {
             "ref": ref,
             "name": response.xpath(
-                'normalize-space(//div[@class="storetitle"][1]/text())'
+                'normalize-space(//h1[@class="storetitle"][1]/text())'
             ).extract_first(),
             "addr_full": response.xpath(
-                'normalize-space(//span[@id="store-address-info"]/p/a/text())'
+                'normalize-space(//span[@id="store-address-info"]/p/text()[4])'
             ).extract_first(),
             "postcode": re.search(
                 r"([\d-]*)$",
                 response.xpath(
-                    'normalize-space(//div[@class="store-details-text"][1]/p/text())'
+                    'normalize-space(//div[@class="store-details-text"]/span/p/text()[2])'
                 ).extract_first(),
             ).group(1),
-            "country": "JP",
             "lat": response.xpath(
                 'normalize-space(//input[@id="store-lat"]/@value)'
             ).extract_first(),
             "lon": response.xpath(
                 'normalize-space(//input[@id="store-lon"]/@value)'
             ).extract_first(),
-            "phone": re.search(
-                r"\s([\d-]*)$",
-                response.xpath('//div[@id="store-tel"]/a/text()').extract_first(),
-            ).group(1),
+            "phone": response.xpath('//div[@id="store-tel"]/a/text()').extract_first(),
             "website": response.url,
         }
 


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Rock Bottom 
https://rockbottom.com/locations/


Discussion:

Resolving patch:
diff --git a/locations/spiders/rock_bottom.py b/locations/spiders/rock_bottom.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/rock_bottom.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from scrapy.spiders import CrawlSpider, Rule
+from scrapy.linkextractors import LinkExtractor
+from locations.linked_data_parser import LinkedDataParser
+
+
+class RockBottomSpider(CrawlSpider):
+    name = "rock_bottom"
+    item_attributes = {"brand": "Rock Bottom", "brand_wikidata": "Q73504866"}
+    allowed_domains = ["rockbottom.com"]
+    download_delay = 0.5
+    start_urls = ["https://www.rockbottom.com/locations"]
+    rules = [Rule(LinkExtractor(allow="/locations/"), callback="parse", follow=False)]
+
+    def parse(self, response):
+        if item := LinkedDataParser.parse(response, "Restaurant"):
+            item["ref"] = response.url
+            yield item


Test patch: