Dec. 28th, 2016

cjwatson: (Default)
I'm very lazy. Rather than having to keep track of Cambridge bin collection days manually, especially around holidays, I wrote a thing to convert it into an iCalendar file for me so that I could import it into Google Calendar. Here it is in case it's useful to anyone else:
#! /usr/bin/python3

from argparse import ArgumentParser
from datetime import datetime
import os.path
import re

from bs4 import BeautifulSoup
import dateutil.parser
from icalendar import (
    Calendar,
    Event,
    )
import requests


parser = ArgumentParser(
    description="Generate iCalendar file for Cambridge bin collection days.")
parser.add_argument(
    "id",
    help=(
        "Unique identifier for this calendar, normally your host name.  Make "
        "sure that this does not collide with any other calendars."))
parser.add_argument("address", help="Your street address in Cambridge.")
parser.add_argument("postcode", help="Your postcode.")
args = parser.parse_args()

now = datetime.now()
req = requests.get(
    "http://bins.cambridge.gov.uk/bins.php",
    params={"address": args.address, "postcode": args.postcode})
soup = BeautifulSoup(req.text)
cal = Calendar()
cal.add("prodid", "-//riva.pelham.vpn.ucam.org//bin-days//EN")
cal.add("version", "2.0")
cal.add("calscale", "GREGORIAN")
cal.add("x-wr-calname", "Bin days")
cal.add("x-wr-timezone", "Europe/London")
for div in soup.find_all("div", style=re.compile(r"^text-align:center")):
    desc = div.contents[0]
    when = dateutil.parser.parse(div.b.get_text(" ").rstrip("*"))
    while when < now:
        when = when.replace(year=when.year + 1)
    event = Event()
    event.add("uid", "bin-days/{:%Y%m%d}@{}".format(when, args.id))
    event.add("dtstart", when.date())
    event.add("summary", desc.capitalize())
    event.add("transp", "TRANSPARENT")
    cal.add_component(event)
with open(os.path.expanduser("~/public_html/bin-days.ics"), "wb") as out:
    out.write(cal.to_ical())
On Debian, this requires the python3-bs4, python3-dateutil, python3-icalendar, and python3-requests packages. You'll probably want to change the output path to somewhere that your calendar software can see (so if it's a web service such as Google Calendar then it needs to be something that corresponds to an accessible URL). The web-scraping is pretty gross, but it's the best I can do given the council's published data. Ideally this would itself be a web service that could generate calendars on demand for a given address and postcode, but like I say I'm lazy.

September 2024

S M T W T F S
12345 67
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags