Merge pull request #11 from latestrevision/python-3-support
Add Python3 Support!
This commit is contained in:
commit
79751fbbd1
7 changed files with 86 additions and 36 deletions
|
@ -1 +1 @@
|
||||||
from base import PyiCloudService
|
from pyicloud.base import PyiCloudService
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import time
|
|
||||||
import uuid
|
import uuid
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
from exceptions import PyiCloudFailedLoginException
|
from pyicloud.exceptions import PyiCloudFailedLoginException
|
||||||
from services import (
|
from pyicloud.services import (
|
||||||
FindMyiPhoneServiceManager,
|
FindMyiPhoneServiceManager,
|
||||||
CalendarService,
|
CalendarService,
|
||||||
UbiquityService
|
UbiquityService
|
||||||
|
@ -63,8 +63,13 @@ class PyiCloudService(object):
|
||||||
if 'dsInfo' in resp:
|
if 'dsInfo' in resp:
|
||||||
dsid = resp['dsInfo']['dsid']
|
dsid = resp['dsInfo']['dsid']
|
||||||
self.params.update({'dsid': dsid})
|
self.params.update({'dsid': dsid})
|
||||||
instance = resp.get('instance', uuid.uuid4().hex)
|
instance = resp.get(
|
||||||
sha = hashlib.sha1(self.user.get('apple_id') + instance)
|
'instance',
|
||||||
|
uuid.uuid4().hex.encode('utf-8')
|
||||||
|
)
|
||||||
|
sha = hashlib.sha1(
|
||||||
|
self.user.get('apple_id').encode('utf-8') + instance
|
||||||
|
)
|
||||||
self.params.update({'id': sha.hexdigest().upper()})
|
self.params.update({'id': sha.hexdigest().upper()})
|
||||||
|
|
||||||
def authenticate(self):
|
def authenticate(self):
|
||||||
|
@ -109,7 +114,11 @@ class PyiCloudService(object):
|
||||||
def files(self):
|
def files(self):
|
||||||
if not hasattr(self, '_files'):
|
if not hasattr(self, '_files'):
|
||||||
service_root = self.webservices['ubiquity']['url']
|
service_root = self.webservices['ubiquity']['url']
|
||||||
self._files = UbiquityService(service_root, self.session, self.params)
|
self._files = UbiquityService(
|
||||||
|
service_root,
|
||||||
|
self.session,
|
||||||
|
self.params
|
||||||
|
)
|
||||||
return self._files
|
return self._files
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -118,10 +127,14 @@ class PyiCloudService(object):
|
||||||
return CalendarService(service_root, self.session, self.params)
|
return CalendarService(service_root, self.session, self.params)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'iCloud API: %s' % self.user.get('apple_id')
|
return 'iCloud API: %s' % self.user.get('apple_id')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return unicode(self).encode('ascii', 'ignore')
|
as_unicode = self.__unicode__()
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
return as_unicode
|
||||||
|
else:
|
||||||
|
return as_unicode.encode('ascii', 'ignore')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s>' % str(self)
|
return '<%s>' % str(self)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
from calendar import CalendarService
|
from pyicloud.services.calendar import CalendarService
|
||||||
from findmyiphone import FindMyiPhoneServiceManager
|
from pyicloud.services.findmyiphone import FindMyiPhoneServiceManager
|
||||||
from ubiquity import UbiquityService
|
from pyicloud.services.ubiquity import UbiquityService
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
from pyicloud.exceptions import PyiCloudNoDevicesException
|
from pyicloud.exceptions import PyiCloudNoDevicesException
|
||||||
|
|
||||||
|
@ -51,7 +54,7 @@ class FindMyiPhoneServiceManager(object):
|
||||||
self._devices[device_id].update(device_info)
|
self._devices[device_id].update(device_info)
|
||||||
|
|
||||||
if not self._devices:
|
if not self._devices:
|
||||||
raise PyiCloudNoDevicesException(message)
|
raise PyiCloudNoDevicesException()
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if isinstance(key, int):
|
if isinstance(key, int):
|
||||||
|
@ -62,18 +65,24 @@ class FindMyiPhoneServiceManager(object):
|
||||||
return getattr(self._devices, attr)
|
return getattr(self._devices, attr)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self._devices)
|
return six.text_type(self._devices)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return unicode(self).encode('ascii', 'ignore')
|
as_unicode = self.__unicode__()
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
return as_unicode
|
||||||
|
else:
|
||||||
|
return as_unicode.encode('ascii', 'ignore')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return str(self)
|
return six.text_type(self)
|
||||||
|
|
||||||
|
|
||||||
class AppleDevice(object):
|
class AppleDevice(object):
|
||||||
def __init__(self, content, session, params, manager,
|
def __init__(
|
||||||
sound_url=None, lost_url=None, message_url=None):
|
self, content, session, params, manager,
|
||||||
|
sound_url=None, lost_url=None, message_url=None
|
||||||
|
):
|
||||||
self.content = content
|
self.content = content
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
self.session = session
|
self.session = session
|
||||||
|
@ -115,26 +124,34 @@ class AppleDevice(object):
|
||||||
data=data
|
data=data
|
||||||
)
|
)
|
||||||
|
|
||||||
def display_message (self, subject='Find My iPhone Alert', message="This is a note", sounds=False):
|
def display_message(
|
||||||
|
self, subject='Find My iPhone Alert', message="This is a note",
|
||||||
|
sounds=False
|
||||||
|
):
|
||||||
""" Send a request to the device to play a sound.
|
""" Send a request to the device to play a sound.
|
||||||
|
|
||||||
It's possible to pass a custom message by changing the `subject`.
|
It's possible to pass a custom message by changing the `subject`.
|
||||||
"""
|
"""
|
||||||
data = json.dumps({'device': self.content['id'],
|
data = json.dumps(
|
||||||
'subject': subject,
|
{
|
||||||
'sound':sounds,
|
'device': self.content['id'],
|
||||||
'userText':True,
|
'subject': subject,
|
||||||
'text':message
|
'sound': sounds,
|
||||||
})
|
'userText': True,
|
||||||
|
'text': message
|
||||||
|
}
|
||||||
|
)
|
||||||
self.session.post(
|
self.session.post(
|
||||||
self.message_url,
|
self.message_url,
|
||||||
params=self.params,
|
params=self.params,
|
||||||
data=data
|
data=data
|
||||||
)
|
)
|
||||||
|
|
||||||
def lost_device(self, number,
|
def lost_device(
|
||||||
text='This iPhone has been lost. Please call me.',
|
self, number,
|
||||||
newpasscode=""):
|
text='This iPhone has been lost. Please call me.',
|
||||||
|
newpasscode=""
|
||||||
|
):
|
||||||
""" Send a request to the device to trigger 'lost mode'.
|
""" Send a request to the device to trigger 'lost mode'.
|
||||||
|
|
||||||
The device will show the message in `text`, and if a number has
|
The device will show the message in `text`, and if a number has
|
||||||
|
@ -169,13 +186,17 @@ class AppleDevice(object):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
display_name = self['deviceDisplayName']
|
display_name = self['deviceDisplayName']
|
||||||
name = self['name']
|
name = self['name']
|
||||||
return u'%s: %s' % (
|
return '%s: %s' % (
|
||||||
display_name,
|
display_name,
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return unicode(self).encode('ascii', 'ignore')
|
as_unicode = self.__unicode__()
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
return as_unicode
|
||||||
|
else:
|
||||||
|
return as_unicode.encode('ascii', 'ignore')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<AppleDevice(%s)>' % str(self)
|
return '<AppleDevice(%s)>' % str(self)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class UbiquityService(object):
|
class UbiquityService(object):
|
||||||
|
@ -96,7 +97,9 @@ class UbiquityNode(object):
|
||||||
return self.connection.get_file(self.item_id, **kwargs)
|
return self.connection.get_file(self.item_id, **kwargs)
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
return [child for child in self.get_children() if child.name == name][0]
|
return [
|
||||||
|
child for child in self.get_children() if child.name == name
|
||||||
|
][0]
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
try:
|
try:
|
||||||
|
@ -108,10 +111,14 @@ class UbiquityNode(object):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name.encode('unicode-escape')
|
as_unicode = self.__unicode__()
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
return as_unicode
|
||||||
|
else:
|
||||||
|
return as_unicode.encode('ascii', 'ignore')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s: u'%s'>" % (
|
return "<%s: '%s'>" % (
|
||||||
self.type.capitalize(),
|
self.type.capitalize(),
|
||||||
str(self)
|
self
|
||||||
)
|
)
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
requests>=1.2
|
requests>=1.2
|
||||||
|
six
|
||||||
|
|
12
setup.py
12
setup.py
|
@ -7,7 +7,7 @@ with open('requirements.txt') as f:
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pyicloud',
|
name='pyicloud',
|
||||||
version='0.2.1',
|
version='0.3.0',
|
||||||
url='https://github.com/picklepete/pyicloud',
|
url='https://github.com/picklepete/pyicloud',
|
||||||
description=(
|
description=(
|
||||||
'PyiCloud is a module which allows pythonistas to '
|
'PyiCloud is a module which allows pythonistas to '
|
||||||
|
@ -16,5 +16,13 @@ setup(
|
||||||
author='Peter Evans',
|
author='Peter Evans',
|
||||||
author_email='evans.peter@gmail.com',
|
author_email='evans.peter@gmail.com',
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
install_requires=required
|
install_requires=required,
|
||||||
|
classifiers=[
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Programming Language :: Python :: 2.6',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue