Repository: alltheplaces/alltheplaces

Issue:
Storcash (NO)
### Brand name

Storcash (NO)

### Wikidata ID

None found

### Store finder url(s)

https://storcash.no/butikker
https://storcash.no/feeds/opening-hours

Part of #7862 's parent group, but not using the common API


Discussion:

Resolving patch:
diff --git a/locations/spiders/storcash_no.py b/locations/spiders/storcash_no.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/storcash_no.py
@@ -0,0 +1,30 @@
+from scrapy.http import JsonRequest
+
+from locations.categories import Categories
+from locations.storefinders.sylinder import SylinderSpider
+
+
+class StorcashNoSpider(SylinderSpider):
+    name = "storcash_no"
+    item_attributes = {"brand": "Storcash", "extras": Categories.SHOP_WHOLESALE.value}
+    base_url = "https://storcash.no/#"  # Note: Doesn't use the same storefinder
+    app_keys = [
+        "5000",  # Bergen Storcash Storcash (NO)
+        "5020",  # Sola Storcash
+        "5030",  # Haugaland Storcash
+        "5040",  # Kjørbekk Storcash
+        "5060",  # Tiller Storcash
+        "5070",  # Sørlandet Storcash
+        "5080",  # Buskerud Storcash
+        "5090",  # Bodø Storcash
+    ]
+
+    def start_requests(self):
+        yield JsonRequest(url="https://api.ngdata.no/sylinder/stores/v1/extended-info")
+
+    def parse(self, response, **kwargs):
+        for location in response.json():
+            if not location["storeDetails"]["chainId"] in self.app_keys:
+                continue
+
+            yield from self.parse_location(location) or []
diff --git a/locations/storefinders/sylinder.py b/locations/storefinders/sylinder.py
--- a/locations/storefinders/sylinder.py
+++ b/locations/storefinders/sylinder.py
@@ -24,40 +24,43 @@ def start_requests(self):
 
     def parse(self, response, **kwargs):
         for location in response.json():
-            item = DictParser.parse(location["storeDetails"])
-            item["ref"] = location["gln"]
+            yield from self.parse_location(location) or []
 
-            # Example:
-            # {'gln': '7080001064310', 'storeDetails': {'storeId': '1020', 'storeName': 'MENY Ski', 'slug': 'meny-ski', 'position': {'lat': 59.713270584310074, 'lng': 10.835573416901537}, 'shopServices': [{'typeCode': 'BHG', 'name': 'Gavekort'}, {'typeCode': 'BAX_NT', 'name': 'Tipping'}, {'typeCode': 'P_PB_U', 'name': 'Posten pakkeboks ute'}, {'typeCode': 'KIB', 'name': 'Kontanttjenester i Butikk'}], 'chainId': '1300', 'organization': {'address': 'Eikeliv 1', 'addressType': 'Delivery', 'postalCode': '1400', 'city': 'SKI', 'phone': '64 878090', 'fax': '64 863312', 'facebookUrl': None, 'email': 'butikksjef.ski@meny.no'}, 'municipality': 'NORDRE FOLLO', 'county': 'AKERSHUS', 'lastChanged': '2024-01-24T14:03:23.0000000+01:00', 'metadata': {'messageReceived': '2024-01-24T14:03:25.8000000+01:00', 'source': 'NGG IntStore'}}, 'openingHours': {'isOpenSunday': False, 'metadata': {'messageReceived': '2024-02-26T15:36:07.9070000+01:00', 'source': 'SAP Retail OSB'}}}
-            # item["city"] = location["storeDetails"]["municipality"]
-            item["state"] = location["storeDetails"]["county"]
-            item["street_address"] = location["storeDetails"]["organization"]["address"]
-            item["city"] = location["storeDetails"]["organization"]["city"]
-            item["postcode"] = location["storeDetails"]["organization"]["postalCode"]
+    def parse_location(self, location):
+        item = DictParser.parse(location["storeDetails"])
+        item["ref"] = location["gln"]
 
-            item["phone"] = location["storeDetails"]["organization"]["phone"]
-            item["email"] = location["storeDetails"]["organization"]["email"]
+        # Example:
+        # {'gln': '7080001064310', 'storeDetails': {'storeId': '1020', 'storeName': 'MENY Ski', 'slug': 'meny-ski', 'position': {'lat': 59.713270584310074, 'lng': 10.835573416901537}, 'shopServices': [{'typeCode': 'BHG', 'name': 'Gavekort'}, {'typeCode': 'BAX_NT', 'name': 'Tipping'}, {'typeCode': 'P_PB_U', 'name': 'Posten pakkeboks ute'}, {'typeCode': 'KIB', 'name': 'Kontanttjenester i Butikk'}], 'chainId': '1300', 'organization': {'address': 'Eikeliv 1', 'addressType': 'Delivery', 'postalCode': '1400', 'city': 'SKI', 'phone': '64 878090', 'fax': '64 863312', 'facebookUrl': None, 'email': 'butikksjef.ski@meny.no'}, 'municipality': 'NORDRE FOLLO', 'county': 'AKERSHUS', 'lastChanged': '2024-01-24T14:03:23.0000000+01:00', 'metadata': {'messageReceived': '2024-01-24T14:03:25.8000000+01:00', 'source': 'NGG IntStore'}}, 'openingHours': {'isOpenSunday': False, 'metadata': {'messageReceived': '2024-02-26T15:36:07.9070000+01:00', 'source': 'SAP Retail OSB'}}}
+        # item["city"] = location["storeDetails"]["municipality"]
+        item["state"] = location["storeDetails"]["county"]
+        item["street_address"] = location["storeDetails"]["organization"]["address"]
+        item["city"] = location["storeDetails"]["organization"]["city"]
+        item["postcode"] = location["storeDetails"]["organization"]["postalCode"]
 
-            item["facebook"] = location["storeDetails"]["organization"]["facebookUrl"]
-            if self.base_url is not None:
-                item["website"] = self.base_url + location["storeDetails"]["slug"]
+        item["phone"] = location["storeDetails"]["organization"]["phone"]
+        item["email"] = location["storeDetails"]["organization"]["email"]
 
-            if location.get("openingHours"):
-                item["opening_hours"] = OpeningHours()
+        item["facebook"] = location["storeDetails"]["organization"]["facebookUrl"]
+        if self.base_url is not None:
+            item["website"] = self.base_url + location["storeDetails"]["slug"]
 
-                # For now, not collecting special opening hours
-                # print(location["openingHours"]["upcomingSpecialOpeningHours"])
+        if location.get("openingHours"):
+            item["opening_hours"] = OpeningHours()
 
-                for day in location["openingHours"]["upcomingOpeningHours"]:
-                    if day["closed"]:
-                        continue
+            # For now, not collecting special opening hours
+            # print(location["openingHours"]["upcomingSpecialOpeningHours"])
 
-                    if day["isSpecial"]:
-                        continue
+            for day in location["openingHours"]["upcomingOpeningHours"]:
+                if day["closed"]:
+                    continue
 
-                    item["opening_hours"].add_range(day["abbreviatedDayOfWeek"], day["opens"], day["closes"])
+                if day["isSpecial"]:
+                    continue
 
-            yield from self.parse_item(item, location) or []
+                item["opening_hours"].add_range(day["abbreviatedDayOfWeek"], day["opens"], day["closes"])
+
+        yield from self.parse_item(item, location) or []
 
     def parse_item(self, item, location, **kwargs):
         yield item


Test patch: