From 83d3c1f2f2239aaf3f27a02a5f206deb513a418c Mon Sep 17 00:00:00 2001 From: Ville Ranki Date: Thu, 12 Dec 2019 21:16:50 +0200 Subject: [PATCH] Added teamup module --- Pipfile | 2 + README.md | 20 ++++++++ modules/teamup.py | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 modules/teamup.py diff --git a/Pipfile b/Pipfile index 4da48af..56b8db5 100644 --- a/Pipfile +++ b/Pipfile @@ -4,6 +4,8 @@ verify_ssl = true name = "pypi" [packages] +pyTeamUp = "*" +pandas = "*" matrix-nio = "*" geopy = "*" google-api-python-client = "*" diff --git a/README.md b/README.md index cfd2610..9d5cd8f 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,26 @@ Aviation weather TAF service access. Prints bot uptime. +### Teamup + +Can access Teamup ( https://teamup.com/ ) calendar. Teamup has nice API and is easier to set up than Google so +prefer it if possible. This bot polls the calendar every 5 minutes and notifies the room of any changes. + +Howto: + +* Create a calendar in Teamup https://teamup.com/ +* Get api key at https://teamup.com/api-keys/request +* !teamup apikey [your api key] +* !teamup add [calendar id] + +Commands: + +* !teamup apikey [apikey] - set api key +* !teamup add [calendar id] - add calendar to this room +* !teamup del [calendar id] - delete calendar from this room +* !teamup list - list calendars in this room +* !teamup poll - poll now for changes + ### Google Calendar Can access a google calendar in a room. This is a bit pain to set up, sorry. diff --git a/modules/teamup.py b/modules/teamup.py new file mode 100644 index 0000000..0ac52c1 --- /dev/null +++ b/modules/teamup.py @@ -0,0 +1,119 @@ +from pyteamup import Calendar, Event +from datetime import datetime +import time +import os + +# +# TeamUp calendar notifications +# +class MatrixModule: + api_key = None + calendar_rooms = dict() # Roomid -> [calid, calid..] + calendars = dict() # calid -> Calendar + + async def matrix_poll(self, bot, pollcount): + if self.api_key: + if pollcount % (6 * 5) == 0: # Poll every 5 min + await self.poll_all_calendars(bot) + + async def matrix_message(self, bot, room, event): + args = event.body.split() + if len(args) == 2: + if args[1] == 'list': + await bot.send_text(room, f'Calendars in this room: {self.calendar_rooms.get(room.room_id) or []}') + elif args[1] == 'poll': + await self.poll_all_calendars(bot) + elif len(args) == 3: + if args[1] == 'add': + calid = args[2] + print(f'Adding calendar {calid} to room id {room.room_id}') + + if self.calendar_rooms.get(room.room_id): + if calid not in self.calendar_rooms[room.room_id]: + self.calendar_rooms[room.room_id].append(calid) + else: + await bot.send_text(room, 'This teamup calendar already added in this room!') + return + else: + self.calendar_rooms[room.room_id] = [calid] + + print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}') + + bot.save_settings() + self.setup_calendars() + await bot.send_text(room, 'Added new teamup calendar to this room') + if args[1] == 'del': + calid = args[2] + print(f'Removing calendar {calid} from room id {room.room_id}') + + if self.calendar_rooms.get(room.room_id): + self.calendar_rooms[room.room_id].remove(calid) + + print(f'Calendars now for this room {self.calendar_rooms.get(room.room_id)}') + + bot.save_settings() + self.setup_calendars() + await bot.send_text(room, 'Removed teamup calendar from this room') + if args[1] == 'apikey': + self.api_key = args[2] + bot.save_settings() + self.setup_calendars() + await bot.send_text(room, 'Api key set') + + def help(self): + return('Polls teamup calendar.') + + async def poll_all_calendars(self, bot): + for roomid in self.calendar_rooms: + calendars = self.calendar_rooms[roomid] + for calendarid in calendars: + events, timestamp = self.poll_server(self.calendars[calendarid]) + self.calendars[calendarid].timestamp = timestamp + for event in events: + await bot.send_text(bot.get_room_by_id(roomid), 'Calendar: ' + self.eventToString(event)) + + def poll_server(self, calendar): + events, timestamp = calendar.get_changed_events(calendar.timestamp) + return events, timestamp + + def to_datetime(self, dts): + try: + return datetime.strptime(dts, '%Y-%m-%dT%H:%M:%S') + except ValueError: + pos = len(dts) - 3 + dts = dts[:pos] + dts[pos+1:] + return datetime.strptime(dts, '%Y-%m-%dT%H:%M:%S%z') + + def eventToString(self, event): + startdt = self.to_datetime(event['start_dt']) + if len(event['title']) == 0: + event['title'] = '(empty name)' + + if(event['delete_dt']): + s = event['title'] + ' deleted.' + else: + s = event['title'] + " " + (event['notes'] or '') + ' ' + str(startdt.day) + '.' + str(startdt.month) + if not event['all_day']: + s = s + ' ' + startdt.strftime("%H:%M") + ' (' + str(event['duration']) + ' min)' + return s + + def setup_calendars(self): + self.calendars = dict() + if self.api_key: + for roomid in self.calendar_rooms: + calendars = self.calendar_rooms[roomid] + for calid in calendars: + self.calendars[calid] = Calendar(calid, self.api_key) + self.calendars[calid].timestamp = int(time.time()) + + def get_settings(self): + return { 'apikey': self.api_key or '', 'calendar_rooms': self.calendar_rooms } + + def set_settings(self, data): + if data.get('calendar_rooms'): + self.calendar_rooms = data['calendar_rooms'] + if data.get('apikey'): + self.api_key = data['apikey'] + if self.api_key and len(self.api_key)==0: + self.api_key = None + self.setup_calendars()