From dd90c2670fc45db013cd7ad4b99a84948f12d31b Mon Sep 17 00:00:00 2001 From: Chandler Swift Date: Sun, 28 Apr 2024 01:05:55 -0500 Subject: [PATCH] Add Michaels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requested-By: Käthe Swift --- layers/chains/index.js | 5 +++ layers/chains/michaels/get_data.py | 57 ++++++++++++++++++++++++++++++ layers/chains/michaels/layer.js | 24 +++++++++++++ layers/chains/michaels/pin.svg | 17 +++++++++ 4 files changed, 103 insertions(+) create mode 100755 layers/chains/michaels/get_data.py create mode 100644 layers/chains/michaels/layer.js create mode 100644 layers/chains/michaels/pin.svg diff --git a/layers/chains/index.js b/layers/chains/index.js index bd89355..7ce2b66 100644 --- a/layers/chains/index.js +++ b/layers/chains/index.js @@ -3,6 +3,7 @@ import culversLayer from './culvers/layer.js'; import krispyKremeLayer from './krispy-kreme/layer.js'; import kwikTripLayer from './kwik-trip/layer.js'; import menardsLayer from './menards/layer.js'; +import michaelsLayer from './michaels/layer.js'; import milwaukeeBurgerCompanyLayer from './milwaukee-burger-company/layer.js'; import punchPizzaLayer from './punch-pizza/layer.js'; import raisingCanesLayer from './raising-canes/layer.js'; @@ -32,6 +33,10 @@ const chains = { name: "Menards", layer: menardsLayer, }, + { + name: "Michaels", + layer: michaelsLayer, + }, { name: "Milwaukee Burger Company", layer: milwaukeeBurgerCompanyLayer, diff --git a/layers/chains/michaels/get_data.py b/layers/chains/michaels/get_data.py new file mode 100755 index 0000000..a6a1a2d --- /dev/null +++ b/layers/chains/michaels/get_data.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import requests +import json +from bs4 import BeautifulSoup + +# Stolen from my machine, appears to work; sufficient and necessary to get +# around their firewall apparently? +UA={ + "User-Agent": 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0' +} + + +locations = [] +response = requests.get('https://locations.michaels.com/', headers=UA) +soup = BeautifulSoup(response.text, 'html.parser') +for state in soup.select('#content ul.state_list li a'): + print(" ", state['href']) + response = requests.get(state['href'], headers=UA) + soup = BeautifulSoup(response.text, 'html.parser') + for city in soup.select('#cities ul.city_list li > a'): + print(" ", city['href']) + response = requests.get(city['href'], headers=UA) + soup = BeautifulSoup(response.text, 'html.parser') + for location in soup.select('#locations > ul > li > a'): + print(" ", location['href']) + response = requests.get(location['href'], headers=UA) + soup = BeautifulSoup(response.text, 'html.parser') + scripts = [scr.text for scr in soup.find_all('script') if 'latitude' in scr.text] # TODO: filter this better?? + + data = json.loads(scripts[0]) + locations.append({ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [data['geo']['longitude'], data['geo']['latitude']], # yes, [lon, lat] since it's [x, y] + }, + "properties": { + 'address': data['address']['streetAddress'], + 'city': data['address']['addressLocality'], + 'state': data['address']['addressRegion'], + 'zip': data['address']['postalCode'], + 'country': data['address']['addressCountry'], + 'url': data['url'], + 'website': location['href'], + }, + }) + +geojson = { + "type": "FeatureCollection", + "features": locations, +} + +print(len(locations), "locations found") + +with open("data.geojson", "w") as f: + f.write(json.dumps(geojson)) diff --git a/layers/chains/michaels/layer.js b/layers/chains/michaels/layer.js new file mode 100644 index 0000000..af140b4 --- /dev/null +++ b/layers/chains/michaels/layer.js @@ -0,0 +1,24 @@ +import VectorLayer from 'ol/layer/Vector'; +import {Vector as VectorSource} from 'ol/source.js'; +import GeoJSON from 'ol/format/GeoJSON.js'; + +import {Style} from 'ol/style.js'; +import Icon from 'ol/style/Icon.js'; + +import url from './data.geojson?url'; // TODO: remove `?url`? +import pin from './pin.svg?url'; // TODO: remove `?url`? + +const vectorLayer = new VectorLayer({ + source: new VectorSource({ + url: url, + format: new GeoJSON, + }), + style: new Style({ + image: new Icon({ + anchor: [0.5, 1], + src: pin, + }), + }), +}); + +export default vectorLayer; diff --git a/layers/chains/michaels/pin.svg b/layers/chains/michaels/pin.svg new file mode 100644 index 0000000..e7d2e0a --- /dev/null +++ b/layers/chains/michaels/pin.svg @@ -0,0 +1,17 @@ + + + + + +