2012-12-31 15:51:40 +01:00
|
|
|
import json
|
|
|
|
|
2012-12-30 20:29:13 +01:00
|
|
|
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, session, params):
|
|
|
|
self.session = session
|
|
|
|
self.params = params
|
|
|
|
self._fmip_root = 'https://p12-fmipweb.icloud.com'
|
|
|
|
self._fmip_endpoint = '%s/fmipservice/client/web' % self._fmip_root
|
|
|
|
self._fmip_refresh_url = '%s/refreshClient' % self._fmip_endpoint
|
2012-12-31 15:51:40 +01:00
|
|
|
self._fmip_sound_url = '%s/playSound' % self._fmip_endpoint
|
2012-12-30 20:29:13 +01:00
|
|
|
|
|
|
|
def refresh_client(self):
|
|
|
|
"""
|
|
|
|
Refreshes the FindMyiPhoneService endpoint,
|
|
|
|
ensuring that the location data is up-to-date.
|
|
|
|
"""
|
|
|
|
self.session.headers.update({'host': 'p12-fmipweb.icloud.com'})
|
|
|
|
req = self.session.post(self._fmip_refresh_url, params=self.params)
|
|
|
|
self.response = req.json()
|
|
|
|
if self.response['content']:
|
2012-12-31 15:52:57 +01:00
|
|
|
# TODO: Support multiple devices.
|
|
|
|
self.content = self.response['content'][0]
|
2012-12-30 20:29:13 +01:00
|
|
|
else:
|
2012-12-31 15:52:57 +01:00
|
|
|
message = 'You do not have any active devices.'
|
|
|
|
raise PyiCloudNoDevicesException(message)
|
2012-12-30 20:29:13 +01:00
|
|
|
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
|
2012-12-31 15:51:40 +01:00
|
|
|
|
|
|
|
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`.
|
2012-12-31 15:52:57 +01:00
|
|
|
"""
|
2012-12-31 15:51:40 +01:00
|
|
|
self.refresh_client()
|
|
|
|
data = json.dumps({'device': self.content['id'], 'subject': subject})
|
|
|
|
self.session.post(self._fmip_sound_url, params=self.params, data=data)
|