From 9982477759ac74b0dee15e7f2bc990014e01734d Mon Sep 17 00:00:00 2001 From: yannickulrich Date: Sun, 17 Jan 2016 20:27:57 +0100 Subject: [PATCH] Adding Reminder support --- pyicloud/base.py | 9 +- pyicloud/services/__init__.py | 1 + pyicloud/services/reminders.py | 147 +++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 pyicloud/services/reminders.py diff --git a/pyicloud/base.py b/pyicloud/base.py index 1b03a225..95ca01f3 100644 --- a/pyicloud/base.py +++ b/pyicloud/base.py @@ -16,7 +16,8 @@ FindMyiPhoneServiceManager, CalendarService, UbiquityService, - ContactsService + ContactsService, + RemindersService ) @@ -176,6 +177,12 @@ def calendar(self): def contacts(self): service_root = self.webservices['contacts']['url'] return ContactsService(service_root, self.session, self.params) + + @property + def reminders(self): + service_root = self.webservices['reminders']['url'] + return RemindersService(service_root, self.session, self.params) + def __unicode__(self): return 'iCloud API: %s' % self.user.get('apple_id') diff --git a/pyicloud/services/__init__.py b/pyicloud/services/__init__.py index 56c37d0f..fbcf2082 100644 --- a/pyicloud/services/__init__.py +++ b/pyicloud/services/__init__.py @@ -2,3 +2,4 @@ from pyicloud.services.findmyiphone import FindMyiPhoneServiceManager from pyicloud.services.ubiquity import UbiquityService from pyicloud.services.contacts import ContactsService +from pyicloud.services.reminders import RemindersService diff --git a/pyicloud/services/reminders.py b/pyicloud/services/reminders.py new file mode 100644 index 00000000..d8adf1e6 --- /dev/null +++ b/pyicloud/services/reminders.py @@ -0,0 +1,147 @@ +from __future__ import absolute_import +from datetime import datetime, timedelta +from calendar import monthrange +import time +import uuid +import pytz +import json + +class RemindersService(object): + def __init__(self, service_root, session, params): + self.session = session + self.params = params + self._service_root = service_root + self.lists={} + self.collections = {} + + self.refresh() + + def get_all_possible_timezones_of_local_machine(self): + """ + Return all possible timezones in Olson TZ notation + This has been taken from + http://stackoverflow.com/questions/7669938 + """ + local_names = [] + if time.daylight: + local_offset = time.altzone + localtz = time.tzname[1] + else: + local_offset = time.timezone + localtz = time.tzname[0] + + local_offset = timedelta(seconds=-local_offset) + + for name in pytz.all_timezones: + timezone = pytz.timezone(name) + if not hasattr(timezone, '_tzinfos'): + continue + for (utcoffset, daylight, tzname), _ in timezone._tzinfos.items(): + if utcoffset == local_offset and tzname == localtz: + local_names.append(name) + return local_names + + + + def get_system_tz(self): + """ + Retrieves the system's timezone from a list of possible options. + Just take the first one + """ + return self.get_all_possible_timezones_of_local_machine()[0] + + + + def refresh(self): + host = self._service_root.split('//')[1].split(':')[0] + self.session.headers.update({'host': host}) + + params_reminders=dict(self.params) + params_reminders.update({ + 'clientVersion': '4.0', + 'lang': 'en-us', + 'usertz':self.get_system_tz() + }) + + # Open reminders + req = self.session.get( + self._service_root + '/rd/startup', + params=params_reminders + ) + + startup = req.json() + + self.lists={} + self.collections = {} + for collection in startup['Collections']: + temp = [] + self.collections[collection['title']] = { + 'guid': collection['guid'], + 'ctag': collection['ctag'] + } + for reminder in startup['Reminders']: + + if reminder['pGuid'] != collection['guid']: + continue + if reminder.has_key("dueDate"): + if reminder['dueDate']: + due = datetime( + reminder['dueDate'][1], + reminder['dueDate'][2],reminder['dueDate'][3], + reminder['dueDate'][4],reminder['dueDate'][5] + ) + else: + due = None + else: + due = None + desc=reminder['description'] if reminder['description'] else "" + temp.append({ + "title": reminder['title'], + "desc": desc, + "due": due + }) + self.lists[collection['title']] = temp + + def post(self, title, description = "", collection=None): + pguid = 'tasks' + if collection: + if self.collections.has_key(collection): + pguid = self.collections[collection]['guid'] + + host = self._service_root.split('//')[1].split(':')[0] + self.session.headers.update({'host': host}) + + params_reminders=dict(self.params) + params_reminders.update({ + 'clientVersion': '4.0', + 'lang': 'en-us', + 'usertz':self.get_system_tz() + }) + + req = self.session.post( + self._service_root + '/rd/reminders/tasks', + data=json.dumps({ + "Reminders":{ + 'title': title, + "description":description, + "pGuid":pguid, + "etag":None, + "order":None, + "priority":0, + "recurrence":None, + "alarms":[], + "startDate":None, + "startDateTz":None, + "startDateIsAllDay":False, + "completedDate":None, + "dueDate":None, + "dueDateIsAllDay":False, + "lastModifiedDate":None, + "createdDate":None, + "isFamily":None, + "createdDateExtended":int(time.time()*1000), + "guid":str(uuid.uuid4()) + }, + "ClientState": {"Collections": self.collections.values() } + }), + params=params_reminders)