From 9982477759ac74b0dee15e7f2bc990014e01734d Mon Sep 17 00:00:00 2001 From: yannickulrich Date: Sun, 17 Jan 2016 20:27:57 +0100 Subject: [PATCH 1/3] 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) From 420c9a783c9229525da26c78ca14513f2d5bf6e1 Mon Sep 17 00:00:00 2001 From: yannickulrich Date: Mon, 18 Jan 2016 09:38:14 +0100 Subject: [PATCH 2/3] PEP8 compatibility --- pyicloud/services/reminders.py | 278 ++++++++++++++++----------------- 1 file changed, 139 insertions(+), 139 deletions(-) diff --git a/pyicloud/services/reminders.py b/pyicloud/services/reminders.py index d8adf1e6..9bbc7d39 100644 --- a/pyicloud/services/reminders.py +++ b/pyicloud/services/reminders.py @@ -1,147 +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) + 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 'dueDate' in reminder: + 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 + if reminder['description']: + desc = reminder['description'] + else: + desc = "" + 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 collection in self.collections: + 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) + return req.ok From cb89d678cf6e1fe2efe15a1612cefbab53dc7f7a Mon Sep 17 00:00:00 2001 From: yannickulrich Date: Mon, 18 Jan 2016 10:09:59 +0100 Subject: [PATCH 3/3] PEP8 for base.py --- pyicloud/base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyicloud/base.py b/pyicloud/base.py index 95ca01f3..d73ab234 100644 --- a/pyicloud/base.py +++ b/pyicloud/base.py @@ -177,13 +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')