PageRenderTime 80ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/CalendarBuilder.py

https://github.com/levyd/CalendarBuilder
Python | 70 lines | 54 code | 13 blank | 3 comment | 12 complexity | f4b01b2324169abc7b1d9c30da48c7a1 MD5 | raw file
  1. from sys import stderr
  2. from BeautifulSoup import BeautifulSoup
  3. from icalendar import Calendar, Event, vRecur
  4. from datetime import datetime, timedelta
  5. import re
  6. class CalendarBuilder:
  7. def __init__(self):
  8. self.calendar = Calendar()
  9. self.calendar.add("version", "2.0")
  10. self.calendar.add("prodid", "-//levyd//NONSGML CalendarBuilder//EN")
  11. self.enddate = None
  12. def addEvent(self, node, date):
  13. strings = node.findAll(text=True)
  14. event = Event()
  15. event.add("summary", strings[0])
  16. match = re.search("(\d\d?:\d\d [ap]m)-(\d\d?:\d\d [ap]m)", strings[2])
  17. if match is None:
  18. print >> stderr, "Warning: Could not parse time string, %s" % strings[2]
  19. return False
  20. else:
  21. event.add("dtstart", datetime.strptime(date + match.group(1), "%Y-%m-%d %I:%M %p"))
  22. event.add("dtend", datetime.strptime(date + match.group(2), "%Y-%m-%d %I:%M %p"))
  23. if self.enddate is not None:
  24. recur = vRecur(freq="WEEKLY", until=self.enddate)
  25. event.add("rrule", recur, encode=0)
  26. event.add("location", strings[3])
  27. self.calendar.add_component(event)
  28. def setEndDate(self, enddate):
  29. self.enddate = datetime.strptime(enddate, "%b %d %Y")
  30. def parse(self, infile):
  31. """Parses the dalonline HTML into a schedule for one week"""
  32. doc = BeautifulSoup(infile.read())
  33. # Get the base date (Monday) of the webpage's calendar
  34. weekoftag = doc.find(text=re.compile("Week of .*"))
  35. weekofre = re.search("Week of (.*)", weekoftag)
  36. if weekofre is None:
  37. raise Exception("Fatal: Couldn't determine calendar base date")
  38. else:
  39. weekof = datetime.strptime(str(weekofre.group(1)), "%b %d, %Y").strftime("%Y %W")
  40. dow = 1
  41. dowcounter = [0, 0, 0, 0, 0, 0, 0]
  42. # Identify all events in the webpage's calendar
  43. table = doc.find("table", attrs={"class" : "datadisplaytable"})
  44. for row in table.findAll("tr"):
  45. for entry in row.findAll("td"):
  46. if entry["class"] == "ddlabel":
  47. date = datetime.strptime(weekof + " " + str(dow), "%Y %W %w").strftime("%Y-%m-%d ")
  48. self.addEvent(entry, date)
  49. dowcounter[dow] += int(entry["rowspan"]) - 1
  50. dow = (dow + 1) % 7
  51. while dowcounter[dow] > 0:
  52. dowcounter[dow] -= 1
  53. dow = (dow + 1) % 7
  54. if dow != 1:
  55. print >> stderr, "Warning, day-of-week might be misaligned"
  56. def export(self, outfile):
  57. outfile.write(self.calendar.as_string())