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

Issue:
Metro Diner
https://metrodiner.com/locations/


Discussion:

Resolving patch:
diff --git a/locations/spiders/metrodiner.py b/locations/spiders/metrodiner.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/metrodiner.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+
+import re
+import scrapy
+from scrapy.selector import Selector
+import json
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+DAY_MAPPING = {
+    '1': 'Mo',
+    '2': 'Tu',
+    '3': 'We',
+    '4': 'Th',
+    '5': 'Fr',
+    '6': 'Sa',
+    '7': 'Su'
+}
+
+class MetroDinerSpider(scrapy.Spider):
+    name = "metrodiner"
+    allowed_domains = ['metrodiner.com']
+    start_urls = [
+        'https://metrodiner.com/locations-sitemap.xml',
+    ]
+
+    def parse_hours(self, hours):
+        opening_hours = OpeningHours()
+        hours = hours.split(";")
+        hours = hours[:7]
+
+        for days in hours:
+            day, open_time, close_time = days.split(",")
+
+            for eachday in days:
+                opening_hours.add_range(day=DAY_MAPPING[day],
+                                        open_time=open_time,
+                                        close_time=close_time,
+                                        time_format='%H%M')
+
+        return opening_hours.as_opening_hours()
+
+    def parse_location(self, response):
+        data = response.xpath('//div[@class="site-header__top-wrapper container"]/div/script/text()').re_first(r'locations:\s*(\[.*\])')
+        data = json.loads(data)
+
+        for location in data:
+            if location["link"] == response.url:
+                properties = {
+                    'addr_full': location["address"],
+                    'phone': location["phone"],
+                    'country': 'US',
+                    'ref': response.url,
+                    'website': response.url,
+                    'lat': float(location["latitude"]),
+                    'lon': float(location["longitude"]),
+                    'name': location["name"]
+                }
+
+                hours = self.parse_hours(location["hours"])
+                if hours:
+                    properties["opening_hours"] = hours
+
+        yield GeojsonPointItem(**properties)
+
+    def parse(self, response):
+        xml = Selector(response)
+        xml.remove_namespaces()
+
+        urls = xml.xpath('//loc/text()').extract()
+        urls = [url.strip() for url in urls]
+
+        for url in urls:
+            if re.search(r'orlando-university',url):
+                pass
+            elif re.search(r'locations/',url):
+                yield scrapy.Request(url, callback=self.parse_location)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Godfather's Pizza
https://godfathers.com/?findLocation=true&reset=true


Discussion:

Resolving patch:
diff --git a/locations/spiders/godfathers_pizza.py b/locations/spiders/godfathers_pizza.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/godfathers_pizza.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+import json
+import re
+
+import scrapy
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+
+class GodfathersPizzaSpider(scrapy.Spider):
+    name = "godfathers_pizza"
+    item_attributes = {'brand': "Godfather's Pizza"}
+    allowed_domains = ["tillster.com"]
+    start_urls = [
+        'https://api-prod-gfp-us-a.tillster.com/mobilem8-web-service/rest/storeinfo/distance?_=1601656666666&\
+        disposition=DINE_IN,PICKUP,DELIVERY&latitude=39.0213953&longitude=-94.3116155&maxResults=2000&radius=5000&\
+        statuses=ACTIVE,TEMP-INACTIVE,ORDERING-DISABLED&tenant=gfp-us',
+    ]
+
+    def parse(self, response):
+        stores = json.loads(response.body_as_unicode())
+
+        for store in stores["getStoresResult"]["stores"]:
+            properties = {
+                'ref': store["storeName"],
+                'name': store["storeName"],
+                'addr_full': store["street"],
+                'city': store["city"],
+                'state': store["state"],
+                'postcode': store["zipCode"],
+                'country': "US",
+                'lat': store["latitude"],
+                'lon': store["longitude"],
+                'phone': store["phoneNumber"]
+            }
+
+            yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Vancouver Coastal Health
http://www.vch.ca/locations-services


Discussion:

Resolving patch:
diff --git a/locations/spiders/vancouver_coastal_health.py b/locations/spiders/vancouver_coastal_health.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/vancouver_coastal_health.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+import re
+
+import scrapy
+
+from locations.items import GeojsonPointItem
+
+BASE_URL = "http://www.vch.ca/_api/Web/Lists(guid'51d09f82-eddf-47c9-95e9-9f5f0ec838c5')/"
+
+
+class VancouverCoastalHealthSpider(scrapy.Spider):
+    name = "vancouver_coastal_health"
+    item_attributes = {'brand': 'Vancouver Coastal Health'}
+    allowed_domains = ['www.vch.ca']
+    start_urls = [
+        "http://www.vch.ca/StaticDirectoryPages/sitemap1.xml",
+    ]
+    download_delay = 0.5
+
+    def parse(self, response):
+        response.selector.remove_namespaces()
+
+        locations = response.xpath('//url/loc/text()').extract()
+        location_ids = [re.search(r'\/([0-9]+)\.aspx', location_id).group(1) for location_id in locations]
+        urls = [BASE_URL + f"Items({location_id})" for location_id in location_ids]
+
+        for url in urls:
+            yield scrapy.Request(url, callback=self.parse_location)
+
+    def parse_location(self, response):
+        response.selector.remove_namespaces()
+        ref = response.xpath('//ID/text()').extract_first()
+        coords = response.xpath('//Geocode/text()').extract_first()
+        if coords:
+            lat, lon = coords.split(',')
+            if float(lat) < 45.0:
+                lat, lon = None, None
+        else:
+            lat = None
+            lon = None
+        city = response.xpath('//City_x0020_Field/text()').extract_first()
+        if city == "[blank]":
+            city = None
+        phone_str = response.xpath('//Phone_x0020_1/text()').extract_first()
+        if phone_str:
+            phone = ''.join(re.findall(r'([0-9]+)', phone_str))
+        else:
+            phone = None
+        website = 'http://www.vch.ca/Locations-Services/result?res_id=' + ref
+
+        properties = {
+            'ref': ref,
+            'name': response.xpath('//Specific_x0020_Title/text()').extract_first(),
+            'addr_full': response.xpath('//Address_x0020_1/text()').extract_first(),
+            'city': city,
+            'state': response.xpath('//Province/text()').extract_first(),
+            'postcode': response.xpath('//Postal_x0020_Code/text()').extract_first(),
+            'country': 'CA',
+            'lat': lat,
+            'lon': lon,
+            'phone': phone,
+            'website': website
+        }
+
+        yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
ATI Physical Therapy
https://locations.atipt.com/


Discussion:

Resolving patch:
diff --git a/locations/spiders/ati_pt.py b/locations/spiders/ati_pt.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/ati_pt.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+import re
+import json
+import scrapy
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+
+class ATIPhysicalTherapySpider(scrapy.Spider):
+    download_delay = 10
+    name = "ati_physical_therapy"
+    item_attributes = {"brand": "ATI Physical Therapy", "brand_wikidata": "Q50039703"}
+    allowed_domains = ["locations.atipt.com"]
+    start_urls = ("https://locations.atipt.com/",)
+
+    def parse(self, response):
+        urls = response.xpath('//ul[@class="list-unstyled"]/li/a/@href').extract()
+        for path in urls:
+            yield scrapy.Request(response.urljoin(path), callback=self.parse_state)
+
+    def parse_state(self, response):
+        urls = response.xpath('//ul[@class="list-unstyled"]/li/a/@href').extract()
+        for path in urls:
+            yield scrapy.Request(response.urljoin(path), callback=self.parse_city)
+
+    def parse_city(self, response):
+        urls = response.xpath('//div[@id="group-list"]/div/div/a/@href').extract()
+        for path in urls:
+            yield scrapy.Request(response.urljoin(path), callback=self.parse_store)
+
+    def parse_store(self, response):
+        oh = OpeningHours()
+        ref = re.findall(r"[^(\/)]+$", response.url)[0]
+        data = json.loads(
+            response.xpath('//script[@type="application/ld+json"]/text()').extract_first()
+        )
+
+        address = {}
+        geo = {}
+        if data.get("address"):
+            address["full"] = data["address"].get("streetAddress")
+            address["zip"] = data["address"].get("postalCode")
+            address["state"] = data["address"].get("addressRegion")
+            address["city"] = data["address"].get("addressLocality")
+        if data.get("geo"):
+            geo["lat"] = data["geo"].get("latitude")
+            geo["lon"] = data["geo"].get("longitude")
+        if data.get("openingHours"):
+            for t in data.get("openingHours"):
+                (day, ot, ct) = t.split()
+                oh.add_range(day, ot.strip(), ct.strip())
+
+        properties = {
+            "addr_full": address.get("full"),
+            "phone": data.get("telephone"),
+            "city": address.get("city"),
+            "state": address.get("state"),
+            "postcode": address.get("zip"),
+            "ref": ref,
+            "website": response.url,
+            "lat": geo.get("lat"),
+            "lon": geo.get("lon"),
+            "extras": {"email": data.get("email"),},
+            "opening_hours": oh.as_opening_hours(),
+        }
+        yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Screwfix
https://www.screwfix.com/jsp/tradeCounter/tradeCounterAllStoresPage.jsp


Discussion:
@thekuiperbelt, I would like to work on this. Will you guys be adding the `Hacktoberfest` label to the repository? Without it, contributions will not be counted, unfortunately.
I added the label. Go for it!
Great! Gonna do it soon.

Resolving patch:
diff --git a/locations/spiders/screwfix.py b/locations/spiders/screwfix.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/screwfix.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+import scrapy
+from locations.items import GeojsonPointItem
+
+class ScrewfixSpider(scrapy.Spider):
+    name = "screwfix"
+    allowed_domains = ["www.screwfix.com"]
+    download_delay = 0.1
+    start_urls = (
+        "https://www.screwfix.com/jsp/tradeCounter/tradeCounterAllStoresPage.jsp",
+    )
+
+    def parse(self, response):
+        for storeurl in response.xpath(".//ul[@class='store-name']//a/@href").extract():
+            yield scrapy.Request(response.urljoin(storeurl), callback=self.parse_location)
+    
+    def parse_location(self, response):
+        ref = response.url
+        addr = [i.strip() for i in response.xpath(".//address/text()").extract()]
+        addr = ', '.join(i for i in addr)
+        properties = {
+            'brand': 'Screwfix',
+            'ref': ref,
+            'name': response.xpath(".//span[@class='tcName']/text()").extract_first(),
+            'addr_full': addr,
+            'opening_hours': str('; ' .join([i.strip() for i in response.xpath(".//dl/dd/text()").extract()])),
+            'lat': float(response.xpath(".//input[@id='lat']/@value").extract_first()),
+            'lon': float(response.xpath(".//input[@id='lng']/@value").extract_first()),
+            'website': ref
+        }
+        yield GeojsonPointItem(**properties)
\ No newline at end of file


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
American Eagle
https://storelocations.ae.com/index.html


Discussion:

Resolving patch:
diff --git a/locations/spiders/american_eagle_outfitters.py b/locations/spiders/american_eagle_outfitters.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/american_eagle_outfitters.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+import json
+import re
+import csv
+
+import scrapy
+
+from scrapy.selector import Selector
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+
+class AmericanEagleOutfittersSpider(scrapy.Spider):
+    name = "american_eagle_outfitters"
+    allowed_domains = ["ae.com"]
+    start_urls = ['http://stores.aeostores.com/sitemap.xml']
+
+    def parse(self, response):
+        xml = Selector(response)
+        xml.remove_namespaces()
+
+        urls = xml.xpath('//loc/text()').extract()
+
+        for url in urls:
+            yield scrapy.Request(url, callback=self.parse_store)
+
+    def parse_hours(self, hours):
+        opening_hours = OpeningHours()
+
+        for hour in hours:
+            try:
+                day, open_time, close_time = re.search(r'([A-Za-z]{2})\s([\d:]+)-([\d:]+)', hour).groups()
+            except:
+                continue
+            opening_hours.add_range(day=day, open_time=open_time, close_time=close_time, time_format='%H:%M')
+
+        return opening_hours.as_opening_hours()
+
+    def parse_store(self, response):
+        single_location = response.xpath('//*[@class="Core-address"]').extract_first()
+
+        if single_location:
+
+            properties = {
+                'ref': "_".join(re.search(r".+/(.+?)/(.+?)/(.+?)/?(?:\.html|$)", response.url).groups()),
+                'name': response.xpath('//*[@class="LocationName-geo"]/text()').extract_first(),
+                'addr_full': response.xpath('//*[@class="c-address-street-1"]/text()').extract_first(),
+                'city': response.xpath('//*[@class="c-address-city"]/text()').extract_first(),
+                'state': response.xpath('//*[@class="c-address-state"]/text()').extract_first(),
+                'postcode': response.xpath('//*[@class="c-address-postal-code"]/text()').extract_first(),
+                'country': response.xpath('//*[@itemprop="addressCountry"]/text()').extract_first(),
+                'lat': response.xpath('//*[@itemprop="latitude"]/@content').extract_first(),
+                'lon': response.xpath('//*[@itemprop="longitude"]/@content').extract_first(),
+                'phone': response.xpath('//*[@data-ya-track="phone"]/text()').extract_first(),
+                'brand': response.xpath('//*[@class="LocationName-brand"]/text()').extract_first(),
+                'website': response.url
+            }
+
+            hours = self.parse_hours(response.xpath('//tr[@itemprop="openingHours"]/@content').extract())
+
+            if hours:
+                properties['opening_hours'] = hours
+
+            yield GeojsonPointItem(**properties)
+
+        else:
+            pass


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
Academy Sports + Outdoors
https://www.academy.com/shop/storelocator


Discussion:

Resolving patch:
diff --git a/locations/spiders/academy.py b/locations/spiders/academy.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/academy.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+import json
+import re
+
+import scrapy
+from scrapy.utils.gz import gunzip
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+
+class AcademySpider(scrapy.Spider):
+    name = "academy"
+    item_attributes = {'brand': 'Academy Sports + Outdoors', 'brand_wikidata': 'Q4671380'}
+    allowed_domains = []
+    start_urls = [
+        'https://www.academy.com/sitemap_store_1.xml.gz',
+    ]
+
+    def parse(self, response):
+        body = gunzip(response.body)
+        body = scrapy.Selector(text=body)
+        body.remove_namespaces()
+        urls = body.xpath('//url/loc/text()').extract()
+        for path in urls:
+            store_url = re.compile(r'http://www.academy.com/shop/storelocator/.+?/.+?/store-\d+')
+            if re.search(store_url, path):
+                yield scrapy.Request(
+                    path.strip(),
+                    callback=self.parse_store
+                )
+
+    def parse_hours(self, hours):
+        opening_hours = OpeningHours()
+
+        for elem in hours:
+            day, open_time, close_time = re.search(r'([A-Za-z]+)\s([\d:]+)\s-\s([\d:]+)', elem).groups()
+            opening_hours.add_range(day=day[:2], open_time=open_time, close_time=close_time)
+
+        return opening_hours.as_opening_hours()
+
+    def parse_store(self, response):
+        properties = {
+            'ref': re.search(r'.+/(.+?)/?(?:\.html|$)', response.url).group(1),
+            'name': response.xpath('normalize-space(//h1[@itemprop="name"]//text())').extract_first(),
+            'addr_full': response.xpath('normalize-space(//span[@itemprop="streetAddress"]//text())').extract_first(),
+            'city': response.xpath('normalize-space(//span[@itemprop="addressLocality"]//text())').extract_first(),
+            'state': response.xpath('normalize-space(//span[@itemprop="addressRegion"]//text())').extract_first(),
+            'postcode': response.xpath('normalize-space(//span[@itemprop="postalCode"]//text())').extract_first(),
+            'phone': response.xpath('//a[@id="storePhone"]/text()').extract_first(),
+            'website': response.url,
+            'lat': float(response.xpath('//input[@id="params"]/@data-lat').extract_first()),
+            'lon': float(response.xpath('//input[@id="params"]/@data-lng').extract_first()),
+        }
+        
+        properties['opening_hours'] = self.parse_hours(
+            response.xpath('//*[@itemprop="openingHours"]/@datetime').extract()
+        )
+        
+        yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
LloydsPharmacy
https://lloydspharmacy.com/pages/store-locator


Discussion:

Resolving patch:
diff --git a/locations/spiders/lloyds_pharmacy.py b/locations/spiders/lloyds_pharmacy.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/lloyds_pharmacy.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+import json
+
+import scrapy
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+URL = 'https://store-locator.mohc.net/store-locator'
+DAY_MAPPING = {
+    "mon": "Mo",
+    "tue": "Tu",
+    "wed": "We",
+    "thu": "Th",
+    "fri": "Fr",
+    "sat": "Sa",
+    "sun": "Su"
+}
+
+
+class LloydsPharmacySpider(scrapy.Spider):
+    name = "lloyds_pharmacy"
+    allowed_domains = ['mohc.net']
+    item_attributes = {'brand': "LloydsPharmacy", "brand_wikidata": "Q6662870"}
+
+    def start_requests(self):
+        yield scrapy.http.Request(url=URL, callback=self.parse, method='GET')
+
+    def parse_hours(self, hours):
+        opening_hours = OpeningHours()
+
+        for day in DAY_MAPPING:
+            weekday = DAY_MAPPING[day]
+            weekday_hours = hours[day]
+            if weekday_hours:
+                open_time = weekday_hours[0]
+                close_time = weekday_hours[1]
+                opening_hours.add_range(day=weekday,
+                                        open_time=open_time,
+                                        close_time=close_time,
+                                        time_format='%H:%M')
+            else:
+                continue
+
+        return opening_hours.as_opening_hours()
+
+    def parse(self, response):
+        store_data = json.loads(response.text)
+        stores = store_data.get('stores')
+
+        for store in stores:
+            address = store["address"]
+            town = address["town"]
+            locality = address["locality"]
+
+            if locality and locality != town:
+                if town:
+                    city = town
+                    addr = " ".join([address["street"], locality])
+                else:
+                    city = locality
+                    addr = address["street"]
+            else:
+                city = town
+                addr = address["street"]
+
+            coords = store["location"]
+            lat = coords.get('lat')
+            lon = coords.get('lng')
+            if lat == 0:
+                lat, lon = None, None
+
+            properties = {
+                'ref': store["id"],
+                'name': store["name"],
+                'addr_full': addr,
+                'city': city,
+                'postcode': address["postcode"],
+                'country': "GB",
+                'lat': lat,
+                'lon': lon,
+                'phone': store["phone"],
+            }
+
+            hours = store.get("hours")
+            if hours:
+                properties['opening_hours'] = self.parse_hours(hours)
+
+            yield GeojsonPointItem(**properties)


Test patch:
Repository: alltheplaces/alltheplaces

Issue:
ADEG
https://www.adeg.at/Marktsuche/


Discussion:

Resolving patch:
diff --git a/locations/spiders/adeg.py b/locations/spiders/adeg.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/adeg.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+import json
+import re
+
+import scrapy
+
+from locations.items import GeojsonPointItem
+from locations.hours import OpeningHours
+
+
+class AdegSpider(scrapy.Spider):
+    name = "adeg"
+    item_attributes = {'brand': 'ADEG Österreich', 'brand_wikidata': 'Q290211'}
+    allowed_domains = ['adeg.at']
+    start_urls = [
+        'https://www.adeg.at/stores/data/',
+    ]
+
+    def parse_hours(self, hours):
+        opening_hours = OpeningHours()
+
+        for item in hours:
+            opening_hours.add_range(day=item["dayOfWeek"][:2],
+                                    open_time=item["opens"],
+                                    close_time=item["closes"])
+
+        return opening_hours.as_opening_hours()
+
+
+    def parse(self, response):
+        stores = json.loads(response.body_as_unicode())
+
+        for store in stores:
+            properties = {
+                'name': store["displayName"],
+                'ref': store["storeId"],
+                'addr_full': store["street"],
+                'city': store["city"],
+                'state': store['province']['provinceName'],
+                'postcode': store["zip"],
+                'country': "AT",
+                'phone': (store["telephoneAreaCode"] or '') + " " + (store["telephoneNumber"] or ''),
+                'website': store.get("url") or None,
+                'lat': float(store["yCoordinates"]),
+                'lon': float(store["xCoordinates"]),
+            }
+
+            hours = self.parse_hours(store["openingTimesStructured"])
+            if hours:
+                properties["opening_hours"] = hours
+
+            yield GeojsonPointItem(**properties)


Test patch: