diff --git a/Makefile b/Makefile index 1f87120e..fe23bd20 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,9 @@ out/lavonne.json: out/bngbirds.json: python src/bngbirds.py || $(call restore-file,$@) +out/paintbar.json: + python src/paintbar.py || $(call restore-file,$@) + fetch: out/allevents.txt \ out/highape.txt \ out/mapindia.json \ @@ -216,7 +219,8 @@ fetch: out/allevents.txt \ out/thewhitebox.json \ out/timeandspace.json \ out/lavonne.json \ - out/bngbirds.json + out/bngbirds.json \ + out/paintbar.json @echo "Done" clean: diff --git a/out/paintbar.json b/out/paintbar.json new file mode 100644 index 00000000..c5b0c804 --- /dev/null +++ b/out/paintbar.json @@ -0,0 +1,58 @@ +[ + { + "name": "Sunflower Sky 🌻 | 12th Jan, Sun | 4-6pm", + "description": "🌻Get ready to paint sunflowers with us! \nP.S - you can choose to paint this on a tote bag / on canvas when you reach! \n\n> Step by step guidance by an artist \n> 12 by 16 inch canvas OR tote bag \n> Beginner friendly \n> Children are welcome for all workshops \n> Includes a non alcoholic beverage & Brik Oven Pizza's to share\nLocation : Paint Bar, Sadashivnagar, Bangalore \nFind directions to our studio here ->\n\n", + "url": "https://www.paintbar.in/products/sunflower-sky-🌻-12th-jan-sun-4-6pm", + "offers": [ + { + "@type": "Offer", + "priceCurrency": "INR", + "price": "2650.00" + } + ], + "startDate": "2025-01-12T16:00:00+05:30", + "endDate": "2025-01-12T18:00:00+05:30" + }, + { + "name": "Set of 3 | 18th Jan, Sat | 4-6pm", + "description": "You've asked us many times to bring workshops where you can create a set of 3\npaintings, and we are finallyyyy bringing it to you! \nIf you're looking at filling up that one wall in your house with paintings but\ndon't know where to start, then this one is for you! \nCreate a set of 3 paintings, with patterns that are minimal, yet fun! \n**If you don't like the reference picture, get one of your own and our artist\nwill help you out with that too! \n** \n> Step by step guidance by an artist \n> 12 by 16 inch set of 3 canvas' \n> Beginner friendly \n> Children are welcome for all workshops. \n> Includes a non alcoholic beverage & Pizza's to share\nLocation : Paint Bar, Sadashivnagar, Bangalore \nFind directions to our studio here ->\n\n", + "url": "https://www.paintbar.in/products/set-of-3-13th-december", + "offers": [ + { + "@type": "Offer", + "priceCurrency": "INR", + "price": "3600.00" + } + ], + "startDate": "2025-01-18T16:00:00+05:30", + "endDate": "2025-01-18T18:00:00+05:30" + }, + { + "name": "Toast & Tonic X Paint Bar | 19th Jan, Sun | 4-6pm", + "description": "Toast & Tonic X Paint Bar bring you a Sip n' Paint to remember! \n \nWe've tied up with **Toast & Tonic **to bring you a special Paint Bar! Try\nsomething new, while you sip on cocktails from Toast & Tonic. \n> Step by step guidance by an artist \n> 12 by 16 inch canvas \n> Beginner friendly \n> Children are welcome for all workshops \n> Includes an alcoholic beverage.\nLocation : Toast & Tonic, Ashok Nagar, Bangalore \nFind directions to Toast & Tonic here ->\n\n", + "url": "https://www.paintbar.in/products/toast-tonic-x-paint-bar-19th-jan", + "offers": [ + { + "@type": "Offer", + "priceCurrency": "INR", + "price": "2600.00" + } + ], + "startDate": "2025-01-19T16:00:00+05:30", + "endDate": "2025-01-19T18:00:00+05:30" + }, + { + "name": "Humming Bird 🌺 | 26th Jan, Sun | 4-6pm", + "description": "We're back with another bright and funky workshop! With step by step guidance\nby an artist, and all materials provided we make painting easy for you. \n \n> Step by step guidance by an artist \n> 12 by 16 inch canvas \n> Beginner friendly \n> Children are welcome for all workshops \n> Includes a non alcoholic beverage & Brik Oven Pizza's to share\nLocation : Paint Bar, Sadashivnagar, Bangalore \nFind directions to our studio here ->\n\n", + "url": "https://www.paintbar.in/products/boat-ride-🚣-️-26th-jan-sun-4-6pm", + "offers": [ + { + "@type": "Offer", + "priceCurrency": "INR", + "price": "2650.00" + } + ], + "startDate": "2025-01-26T16:00:00+05:30", + "endDate": "2025-01-26T18:00:00+05:30" + } +] \ No newline at end of file diff --git a/patch/paintbar.json b/patch/paintbar.json new file mode 100644 index 00000000..8e607bb6 --- /dev/null +++ b/patch/paintbar.json @@ -0,0 +1,12 @@ +{ + "@context": "https://schema.org", + "@type": "SocialEvent", + "inLanguage": "en", + "eventStatus": "EventScheduled", + "organizer": { + "@type": "Organization", + "name": "Paint Bar", + "url": "https://www.paintbar.in/" + }, + "keywords": ["PAINTBAR"] +} diff --git a/src/event-fetcher.py b/src/event-fetcher.py index 3921475a..8ae0a973 100644 --- a/src/event-fetcher.py +++ b/src/event-fetcher.py @@ -59,7 +59,8 @@ "out/thewhitebox.json", "out/timeandspace.json", "out/lavonne.json", - "out/bngbirds.json" + "out/bngbirds.json", + "out/paintbar.json" ] KNOWN_EVENT_TYPES = [ diff --git a/src/paintbar.py b/src/paintbar.py new file mode 100644 index 00000000..7a03a70d --- /dev/null +++ b/src/paintbar.py @@ -0,0 +1,78 @@ +import datefinder +import json +from datetime import datetime +from common.tz import IST +from common.shopify import Shopify, ShopifyProduct + +DOMAIN = 'www.paintbar.in' +COLLECTION = 'paint-bar-bangalore' + +# Convert variants to Schema.org/Offer +def make_offers(product: ShopifyProduct): + return [ + { + "@type": "Offer", + "priceCurrency": "INR", + "price": variant.price, + } + for variant in product.variants + ] + +# Fetch timings from the variant.title. It returns start_date and end_date timestamps +def fetch_timings(date_str: str): + (_, date_part, time_part) = date_str.split(" | ") + + event_date = list(datefinder.find_dates(date_part))[0] + + for splitter in ["to", "-"]: + if splitter in time_part: + l = [x.strip() for x in time_part.split(splitter)] + + if l == None: + raise ValueError("Could not find time in" + date_str) + + known_twelveness = [ + twelveness for twelveness in ["am", "pm"] for i in l if twelveness in i + ] + + timestamps = [] + + for time_str in l: + # check if time_str contains AM or PM + if not ("am" in time_str or "pm" in time_str): + time_str += known_twelveness[0] + timestamps.append( + list(datefinder.find_dates(time_str, base_date=event_date))[0].replace( + tzinfo=IST + ) + ) + + if len(timestamps) != 2: + raise ValueError("Could not find time in" + date_str) + + return timestamps + + +def make_event(product, sp: Shopify): + start_date, end_date = fetch_timings(product.title) + # URL may sometimes contain emojis, make sure they are encoded as EMOJI + print(product.url) + + return { + "name": product.title, + "description": product.description, + "url": product.url, + "offers": make_offers(product), + "startDate": start_date.isoformat(), + "endDate": end_date.isoformat(), + } + +if __name__ == "__main__": + from common.session import get_cached_session + session = get_cached_session() + paint_bar = Shopify(DOMAIN, session, COLLECTION) + events = [make_event(p, paint_bar) for p in paint_bar.products()] + + with open("out/paintbar.json", "w") as f: + json.dump(events, f, indent=2, ensure_ascii=False) + print(f"[PAINTBAR] {len(events)} events")