pyicloud/services/findmyiphone.py
2013-01-01 16:30:35 +00:00

81 lines
3.1 KiB
Python
Executable file

import json
from pyicloud.exceptions import PyiCloudNoDevicesException
class FindMyiPhoneService(object):
"""
The 'Find my iPhone' iCloud service, connects to iCloud and returns
phone data including the near-realtime latitude and longitude.
"""
def __init__(self, service_root, session, params):
self.session = session
self.params = params
self._service_root = service_root
self._fmip_endpoint = '%s/fmipservice/client/web' % self._service_root
self._fmip_refresh_url = '%s/refreshClient' % self._fmip_endpoint
self._fmip_sound_url = '%s/playSound' % self._fmip_endpoint
self._fmip_lost_url = '%s/lostDevice' % self._fmip_endpoint
def refresh_client(self):
"""
Refreshes the FindMyiPhoneService endpoint,
ensuring that the location data is up-to-date.
"""
host = self._service_root.split('//')[1].split(':')[0]
self.session.headers.update({'host': host})
req = self.session.post(self._fmip_refresh_url, params=self.params)
self.response = req.json()
if self.response['content']:
# TODO: Support multiple devices.
self.content = self.response['content'][0]
else:
message = 'You do not have any active devices.'
raise PyiCloudNoDevicesException(message)
self.user_info = self.response['userInfo']
def location(self):
self.refresh_client()
return self.content['location']
def status(self, additional=[]):
"""
The FindMyiPhoneService response is quite bloated, this method
will return a subset of the more useful properties.
"""
self.refresh_client()
fields = ['batteryLevel', 'deviceDisplayName', 'deviceStatus', 'name']
fields += additional
properties = {}
for field in fields:
properties[field] = self.content.get(field, 'Unknown')
return properties
def play_sound(self, subject='Find My iPhone Alert'):
"""
Send a request to the device to play a sound, it's possible to
pass a custom message by changing the `subject`.
"""
self.refresh_client()
data = json.dumps({'device': self.content['id'], 'subject': subject})
self.session.post(self._fmip_sound_url, params=self.params, data=data)
def lost_device(self, number, text=None):
"""
Send a request to the device to trigger 'lost mode'. The
device will show the message in `text`, and if a number has
been passed, then the person holding the device can call
the number without entering the passcode.
"""
self.refresh_client()
if not text:
text = 'This iPhone has been lost. Please call me.'
data = json.dumps({
'text': text,
'userText': True,
'ownerNbr': number,
'lostModeEnabled': True,
'trackingEnabled': True,
'device': self.content['id'],
})
self.session.post(self._fmip_lost_url, params=self.params, data=data)