tl_icalendar.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import os
  2. import xml.etree.ElementTree as ET
  3. from datetime import datetime
  4. import pytz
  5. import requests
  6. from icalendar import Calendar, Event
  7. from slugify import slugify
  8. CALENDAR_URL = 'http://www.teamliquid.net/calendar/xml/calendar.xml'
  9. TIMEZONE = 'Asia/Seoul' # Must match the timezone used in the XML calendar.
  10. STATIC_ROOT = os.path.join('calendars')
  11. BUCKET_NAME = 'tl-icalendar'
  12. def get_xml_calendar(url):
  13. response = requests.get(url)
  14. return response.content
  15. def parse_xml_calendar(calendar):
  16. events = []
  17. event_types = []
  18. for month in ET.fromstring(calendar):
  19. for day in month:
  20. for event in day:
  21. event_year = month.attrib['year']
  22. event_month = month.attrib['num']
  23. event_day = day.attrib['num']
  24. event_hour = event.attrib['hour']
  25. event_minute = event.attrib['minute']
  26. try:
  27. event_type = event.find('type').text
  28. except AttributeError:
  29. event_type = 'N/A'
  30. if event_type not in event_types:
  31. event_types.append(event_type)
  32. try:
  33. event_title = event.find('title').text
  34. except AttributeError:
  35. event_title = 'N/A'
  36. try:
  37. event_description = event.find('description').text
  38. except AttributeError:
  39. event_description = 'N/A'
  40. try:
  41. event_id = event.find('event-id').text
  42. except AttributeError:
  43. event_id = 'N/A'
  44. try:
  45. event_url = event.find('liquipedia-url').text
  46. except AttributeError:
  47. event_url = 'N/A'
  48. events.append({
  49. 'year': int(event_year),
  50. 'month': int(event_month),
  51. 'day': int(event_day),
  52. 'hour': int(event_hour),
  53. 'minute': int(event_minute),
  54. 'type': event_type,
  55. 'title': event_title,
  56. 'description': event_description,
  57. 'id': event_id,
  58. 'url': event_url
  59. })
  60. return events, event_types
  61. def create_icalendar(events, event_type):
  62. calendar = Calendar()
  63. calendar.add('prodid', '-//TeamLiquid.net//Events Calendar//')
  64. calendar.add('version', '2.0')
  65. for item in events:
  66. if event_type == item['type']:
  67. event = Event()
  68. event.add('summary', '{} ({})'.format(item['title'], item['type']))
  69. event.add('description', '{}\nLiquipedia: {}'.format(
  70. item['description'], item['url']))
  71. event.add('uid', item['id'])
  72. event.add('dtstart', datetime(
  73. item['year'],
  74. item['month'],
  75. item['day'],
  76. item['hour'],
  77. item['minute'],
  78. 0, # Seconds.
  79. tzinfo=pytz.timezone(TIMEZONE))
  80. )
  81. calendar.add_component(event)
  82. return calendar
  83. def write_icalendar_to_file(calendar, event_type):
  84. if not os.path.exists(STATIC_ROOT):
  85. os.makedirs(STATIC_ROOT)
  86. filename = os.path.join(STATIC_ROOT, slugify(event_type) + '.ics')
  87. f = open(filename, 'wb')
  88. f.write(calendar.to_ical())
  89. f.close()
  90. return f.name
  91. def upload_calendars():
  92. import boto3
  93. s3 = boto3.resource('s3')
  94. for filename in os.listdir('calendars/'):
  95. data = open('calendars/' + filename, 'rb')
  96. s3.Bucket(BUCKET_NAME).put_object(Key=filename, Body=data)
  97. def run():
  98. print('Fetching calendar from', CALENDAR_URL, '...')
  99. xml_calendar = get_xml_calendar(CALENDAR_URL)
  100. print('Parsing XML calendar ...')
  101. events, event_types = parse_xml_calendar(xml_calendar)
  102. for event_type in event_types:
  103. print('Creating `{}` iCalendar ...'.format(event_type))
  104. icalendar = create_icalendar(events, event_type)
  105. print('\tWriting iCalendar to file ...')
  106. f = write_icalendar_to_file(icalendar, event_type)
  107. print('\tDone. Check `{}`'.format(f))
  108. print('Uploading to S3 ...')
  109. upload_calendars()
  110. print('GG')
  111. if __name__ == '__main__':
  112. run()