Merge branch 'patch-1'; Adds functionality which should limit the number of e-mail notices from Apple.

This commit is contained in:
Adam Coddington 2015-05-17 23:15:23 -07:00
commit e849b5954e

View file

@ -1,8 +1,13 @@
import uuid import uuid
import hashlib import hashlib
import json import json
import logging
import pickle
import requests import requests
import sys import sys
import tempfile
import os
from re import match
from pyicloud.exceptions import PyiCloudFailedLoginException from pyicloud.exceptions import PyiCloudFailedLoginException
from pyicloud.services import ( from pyicloud.services import (
@ -13,6 +18,9 @@ from pyicloud.services import (
) )
logger = logging.getLogger(__name__)
class PyiCloudService(object): class PyiCloudService(object):
""" """
A base authentication class for the iCloud service. Handles the A base authentication class for the iCloud service. Handles the
@ -23,7 +31,7 @@ class PyiCloudService(object):
pyicloud = PyiCloudService('username@apple.com', 'password') pyicloud = PyiCloudService('username@apple.com', 'password')
pyicloud.iphone.location() pyicloud.iphone.location()
""" """
def __init__(self, apple_id, password): def __init__(self, apple_id, password, cookie_directory=None):
self.discovery = None self.discovery = None
self.client_id = str(uuid.uuid1()).upper() self.client_id = str(uuid.uuid1()).upper()
self.user = {'apple_id': apple_id, 'password': password} self.user = {'apple_id': apple_id, 'password': password}
@ -37,6 +45,16 @@ class PyiCloudService(object):
self._base_system_url = '%s/system/version.json' % self._home_endpoint self._base_system_url = '%s/system/version.json' % self._home_endpoint
self._base_webauth_url = '%s/refreshWebAuth' % self._push_endpoint self._base_webauth_url = '%s/refreshWebAuth' % self._push_endpoint
if cookie_directory:
self._cookie_directory = os.path.expanduser(
os.path.normpath(cookie_directory)
)
else:
self._cookie_directory = os.path.join(
tempfile.gettempdir(),
'pyicloud',
)
self.session = requests.Session() self.session = requests.Session()
self.session.verify = False self.session.verify = False
self.session.headers.update({ self.session.headers.update({
@ -86,6 +104,15 @@ class PyiCloudService(object):
""" """
self.refresh_validate() self.refresh_validate()
# Check if cookies directory exists
if not os.path.exists(self._cookie_directory):
# If not, create it
os.mkdir(self._cookie_directory)
cookie = self._get_cookie()
if cookie:
self.session.cookies = cookie
data = dict(self.user) data = dict(self.user)
data.update({'id': self.params['id'], 'extended_login': False}) data.update({'id': self.params['id'], 'extended_login': False})
req = self.session.post( req = self.session.post(
@ -98,11 +125,50 @@ class PyiCloudService(object):
msg = 'Invalid email/password combination.' msg = 'Invalid email/password combination.'
raise PyiCloudFailedLoginException(msg) raise PyiCloudFailedLoginException(msg)
self._update_cookie(req)
self.refresh_validate() self.refresh_validate()
self.discovery = req.json() self.discovery = req.json()
self.webservices = self.discovery['webservices'] self.webservices = self.discovery['webservices']
def _get_cookie_path(self):
# Set path for cookie file
return os.path.join(
self._cookie_directory,
''.join([c for c in self.user.get('apple_id') if match(r'\w', c)])
)
def _get_cookie(self):
if hasattr(self, '_cookies'):
return self._cookies
cookiefile = self._get_cookie_path()
# Check if cookie file already exists
try:
# Get cookie data from file
with open(cookiefile, 'rb') as f:
return pickle.load(f)
except IOError:
# This just means that the file doesn't exist; that's OK!
pass
except Exception as e:
logger.exception(
"Unexpected error occurred while loading cookies: %s" % (e, )
)
return None
def _update_cookie(self, request):
cookiefile = self._get_cookie_path()
# Save the cookie in a pickle file
with open(cookiefile, 'wb') as f:
pickle.dump(request.cookies, f)
self._cookies = request.cookies
@property @property
def devices(self): def devices(self):
""" Return all devices.""" """ Return all devices."""