From cd5adffbd0b010f806f5d1749f5bf463a9bac8a2 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Fri, 25 Oct 2019 00:40:15 +0200 Subject: [PATCH] First commit with some GeorideApiLib items --- .gitignore | 3 + .travis.yml | 11 + README.md | 24 ++ examples/example.py | 63 +++++ georide-logo.png | Bin 0 -> 12381 bytes georideapilib/api.py | 192 +++++++++++++++ georideapilib/objects.py | 504 +++++++++++++++++++++++++++++++++++++++ manifest.json | 10 + setup.cfg | 2 + setup.py | 40 ++++ test_requirements.txt | 6 + 11 files changed, 855 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 README.md create mode 100644 examples/example.py create mode 100644 georide-logo.png create mode 100644 georideapilib/api.py create mode 100644 georideapilib/objects.py create mode 100644 manifest.json create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 test_requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6f9cb1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +examples/__main__.py +__pycache__ +**/__pycache__ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1bdfb08 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: python +python: + - "3.5" +cache: pip +install: + - pip install -r test_requirements.txt + - pip install . +script: + - py.test tests/*_test.py --cov=georideapilib + - pylint georideapilib + - coveralls \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e667ea --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Georideapilib +![Logo Georide](georide-logo.png) + +⚠️ this is not an official implementation + +Official geroide website: https://georide.fr/ + +This library can control your georide tracker tracker + + +Some code have been taken from @alexmohr https://github.com/alexmohr/sonyapilib + +This library is used as communication interface in a home assistant component to control media players, which can be found here:(Not ready yes ;)) + +At the moment not all functions offered by the api are implemented. If you miss a function feel free to create a pull request or open a feature request. + +# Installation +To install simply run +``` +pip install georideapilib +``` + +This library has been tested with python 3.7 and above, functionality for older python version cannot be guaranteed. + diff --git a/examples/example.py b/examples/example.py new file mode 100644 index 0000000..7f45701 --- /dev/null +++ b/examples/example.py @@ -0,0 +1,63 @@ +import api as GeorideApi +from objects import GeorideAccount + +import datetime +import time + + +""" If ypu out to reuse account """ +""" +account = GeorideAccount(, , , ) +""" + +""" Get an acces token """ +account = GeorideApi.getAuthorisationToken("", "") +print("token 1: ", account.authToken) + + +""" do not abuse, renew when previous token have almost reached time """ +""" +account.authToken = GeorideApi.renewToken(account.authToken) +print("token 2: ", account.authToken) +""" + +user = GeorideApi.getUser(account.authToken) +print("User: ", user.firstName) + +trackers = GeorideApi.getTrackers(account.authToken) +tracker = trackers[0] +print("Tracker name: ", tracker.trackerName) + +trips = GeorideApi.getTrips(account.authToken, tracker.trackerId, "2019-10-10", "2019-10-24") +trip = trips[0]; +trip_date = datetime.datetime.strptime("2019-10-10T06:45:34.000Z", '%Y-%m-%dT%H:%M:%S.%fZ') +print("Trip date: {}, from: {}, to: {}".format(trip_date, trip.niceStartAddress, trip.niceEndAddress)) + +positions = GeorideApi.getPositions(account.authToken, tracker.trackerId, "2019-10-10", "2019-10-24") +position = positions[0]; +print("Position speed: {}, lon: {}, lat: {}".format(position.speed, position.longitude, position.latitude)) + + +tripShared = GeorideApi.shareATripByDate(account.authToken, tracker.trackerId, fromDate="2019-10-10", toDate="2019-10-24") +print("tripShared url: {}, id: {}".format(tripShared.url, tripShared.shareId)) + +time.sleep(30) +haveBeenLocked = GeorideApi.lockTracker(account.authToken, tracker.trackerId) +print("Tracker have been locked: ", haveBeenLocked) + +time.sleep(30) +haveBeenUnlocked = GeorideApi.lockTracker(account.authToken, tracker.trackerId) +print("Tracker have been unlocked: ", haveBeenUnlocked) + +time.sleep(30) +isLocked = GeorideApi.toogleLockTracker(account.authToken, tracker.trackerId) +print("Tracker is locked: ", haveBeenUnlocked) + +time.sleep(30) +trackers = GeorideApi.getTrackers(account.authToken) +tracker = trackers[0] +print("Tracker name: ", tracker.trackerName, " is locked: ", tracker.isLocked) + +""" +GeorideApi.revokeToken(account.authToken) +""" \ No newline at end of file diff --git a/georide-logo.png b/georide-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b70f5632667c4a68d313373b65fc66730ce63083 GIT binary patch literal 12381 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 J6;j4Q{{wpcv_=2` literal 0 HcmV?d00001 diff --git a/georideapilib/api.py b/georideapilib/api.py new file mode 100644 index 0000000..cf04ebc --- /dev/null +++ b/georideapilib/api.py @@ -0,0 +1,192 @@ +""" +Georide api lib +@author Matthieu DUVAL +""" + +import urllib3 +import json + +from objects import GeorideTracker, GeorideAccount, GeorideUser, GeorideTrackerTrip, GeorideTrackerPosition, GeorideSharedTrip + +GEORIDE_API_HOST = "https://api.georide.fr" +GEORIDE_API_ENDPOINT_LOGIN = "/user/login" +GEORIDE_API_ENDPOINT_NEW_TOKEN = "/user/new-token" +GEORIDE_API_ENDPOINT_LOGOUT = "/user/logout" +GEORIDE_API_ENDPOINT_USER = "/user" +GEORIDE_API_ENDPOINT_TRAKERS = "/user/trackers" +GEORIDE_API_ENDPOINT_TRIPS = "/tracker/:trackerId/trips" +GEORIDE_API_ENDPOINT_LOCK = "/tracker/:trackerId/lock" +GEORIDE_API_ENDPOINT_UNLOCK = "/tracker/:trackerId/unlock" +GEORIDE_API_ENDPOINT_TOGGLE_LOCK = "/tracker/:trackerId/toggleLock" +GEORIDE_API_ENDPOINT_POSITIONS = "/tracker/:trackerId/trips/positions" +GEORIDE_API_ENDPOINT_TRIP_SHARE = "/tracker/:trackerId/share/trip" + + +def getAuthorisationToken(email, password): + http = urllib3.PoolManager() + data = {"email": email,"password": password} + encoded_data = json.dumps(data).encode('utf-8') + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_LOGIN, + body=encoded_data, + headers={'Content-Type': 'application/json'}) + response_data = json.loads(response.data.decode('utf-8')) + account = GeorideAccount.fromJson(response_data) + return account + + +def renewToken(token): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'GET', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_NEW_TOKEN, + headers=headers) + response_data = json.loads(response.data.decode('utf-8')) + newToken = response_data['authToken'] + return newToken + + +def revokeToken(token): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_LOGOUT, + headers=headers) + if response.status == 204: + return True + else: + return False + + +def getUser(token): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'GET', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_USER, + headers=headers) + response_data = json.loads(response.data.decode('utf-8')) + account = GeorideUser.fromJson(response_data) + return account + +def getTrackers(token): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'GET', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_TRAKERS, + headers=headers) + + response_data = json.loads(response.data.decode('utf-8')) + trackers = [] + for json_tracker in response_data: + trackers.append(GeorideTracker.fromJson(json_tracker)) + return trackers + + +def getTrips(token, trackerId, fromDate, toDate): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'GET', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_TRIPS.replace(':trackerId', str(trackerId)), + fields={'from': fromDate, 'to': toDate}, + headers=headers) + + response_data = json.loads(response.data.decode('utf-8')) + trips = [] + for json_trip in response_data: + trips.append(GeorideTrackerTrip.fromJson(json_trip)) + return trips + +def getPositions(token, trackerId, fromDate, toDate): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'GET', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_POSITIONS.replace(':trackerId', str(trackerId)), + fields={'from': fromDate, 'to': toDate}, + headers=headers) + + response_data = json.loads(response.data.decode('utf-8')) + positions = [] + for json_position in response_data: + positions.append(GeorideTrackerPosition.fromJson(json_position)) + return positions + +def shareATripByTripId(token, trackerId, tripId): + return _shareATrip(token, trackerId, tripId=tripId) + +def shareATripByDate(token, trackerId, fromDate, toDate): + return _shareATrip(token, trackerId, fromDate=fromDate, toDate=toDate) + +def shareATripByTripMergeId(token, trackerId, tripMergedId): + return _shareATrip(token, trackerId, tripMergedId=tripMergedId) + +def _shareATrip(token, trackerId, tripId=None, fromDate=None, toDate=None, tripMergedId=None): + data = None + if tripId != None: + data = {"tripId": tripId} + elif fromDate != None and toDate != None: + data = {"from": fromDate, "to": toDate} + elif tripMergedId != None: + data = {"tripMergedId": tripMergedId} + + encoded_data = json.dumps(data).encode('utf-8') + print("Trip data: ", encoded_data) + + http = urllib3.PoolManager() + headers = { + "Authorization": "Bearer " + token, + 'Content-Type': 'application/json' + } + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_TRIP_SHARE.replace(':trackerId', str(trackerId)), + body=encoded_data, + headers=headers) + + response_data = json.loads(response.data.decode('utf-8')) + print("Trip data: ", response_data) + return GeorideSharedTrip.fromJson(response_data) + +def lockTracker(token, trackerId): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_LOCK.replace(':trackerId', str(trackerId)), + headers=headers) + if response.status == 204: + return True + else: + return False + +def unlockTracker(token, trackerId): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_UNCLOCK.replace(':trackerId', str(trackerId)), + headers=headers) + if response.status == 204: + return True + else: + return False + +def toogleLockTracker(token, trackerId): + http = urllib3.PoolManager() + headers = {"Authorization": "Bearer " + token} + response = http.request( + 'POST', + GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_TOGGLE_LOCK.replace(':trackerId', str(trackerId)), + headers=headers) + response_data = json.loads(response.data.decode('utf-8')) + return response_data['locked'] + +if __name__ == '__main__': + print("Not a main module") + diff --git a/georideapilib/objects.py b/georideapilib/objects.py new file mode 100644 index 0000000..6b32f04 --- /dev/null +++ b/georideapilib/objects.py @@ -0,0 +1,504 @@ +""" +Georide objects implementation +@author Matthieu DUVAL +""" + +class GeorideSharedTrip: + def __init__(self, url, shareId): + self._url = url + self._shareId = shareId + + @property + def url(self): + return self._url + + @property + def shareId(self): + return self._shareId + + def fromJson(json): + return GeorideSharedTrip( + json['url'], + json['shareId'] + ) + +class GeorideTrackerTrip: + def __init__(self, tripId, trackerId, averageSpeed, maxSpeed, distance, duration, startAddress, niceStartAddress, startLat, + startLon, endAddress, niceEndAddress, endLat, endLon, startTime, endTime): + self._tripId = tripId + self._trackerId = trackerId + self._averageSpeed = averageSpeed + self._maxSpeed = maxSpeed + self._distance = distance + self._duration = duration + self._startAddress = startAddress + self._niceStartAddress = niceStartAddress + self._startLat = startLat + self._startLon = startLon + self._endAddress = endAddress + self._niceEndAddress = niceEndAddress + self._endLat = endLat + self._endLon = endLon + self._startTime = startTime + self._endTime = endTime + + @property + def tripId(self): + return self._tripId + + @property + def trackerId(self): + return self._trackerId + + @property + def averageSpeed(self): + return self._averageSpeed + + @property + def maxSpeed(self): + return self._maxSpeed + + @property + def distance(self): + return self._distance + + @property + def duration(self): + return self._duration + + @property + def startAddress(self): + return self._startAddress + + @property + def niceStartAddress(self): + return self._niceStartAddress + + @property + def startLat(self): + return self._startLat + + @property + def startLon(self): + return self._startLon + + @property + def endAddress(self): + return self._endAddress + + @property + def niceEndAddress(self): + return self._niceEndAddress + + @property + def endLat(self): + return self._endLat + + @property + def endLon(self): + return self._endLon + + @property + def startTime(self): + return self._startTime + + @property + def endTime(self): + return self._endTime + + def fromJson(json): + return GeorideTrackerTrip( + json['id'], + json['trackerId'], + json['averageSpeed'], + json['maxSpeed'], + json['distance'], + json['duration'], + json['startAddress'], + json['niceStartAddress'], + json['startLat'], + json['startLon'], + json['endAddress'], + json['niceEndAddress'], + json['endLat'], + json['endLon'], + json['startTime'], + json['endTime'] + ) + + +class GeorideTrackerPosition: + def __init__(self, fixtime, latitude, longitude, altitude, speed, address): + self._fixtime = fixtime + self._latitude = latitude + self._longitude = longitude + self._altitude = altitude + self._speed = speed + self._address = address + + @property + def fixtime(self): + return self._fixtime + + @property + def latitude(self): + return self._latitude + + @property + def longitude(self): + return self._longitude + + @property + def altitude(self): + return self._altitude + + @property + def speed(self): + return self._speed + + @property + def address(self): + return self._address + + def fromJson(json): + return GeorideTrackerPosition( + json['fixtime'], + json['latitude'], + json['longitude'], + json['altitude'], + json['speed'], + json['address'] + ) + + + + +class GeorideTracker: + def __init__(self, trackerId, trackerName, deviceButtonAction, deviceButtonDelay, vibrationLevel, isOldTracker, autoLockFreezedTo, + fixtime, role, lastPaymentDate, giftCardId, expires, activationDate, odometer, isStolen, isCrashed, crashDetectionDisabled, + speed, moving, positionId, latitude, longitude, altitude, lockedPositionId, lockedLatitude, lockedLongitude, isLocked, + canSeePosition, canLock, canUnlock, canShare, canUnshare, canCheckSpeed, canSeeStatistics, canSendBrokenDownSignal, + canSendStolenSignal, status): + self._trackerId = trackerId + self._trackerName = trackerName + self._deviceButtonAction = deviceButtonAction + self._deviceButtonDelay = deviceButtonDelay + self._vibrationLevel = vibrationLevel + self._isOldTracker = isOldTracker + self._autoLockFreezedTo = autoLockFreezedTo + self._fixtime = fixtime + self._role = role + self._lastPaymentDate = lastPaymentDate + self._giftCardId = giftCardId + self._expires = expires + self._activationDate = activationDate + self._odometer = odometer + self._isStolen = isStolen + self._isCrashed = isCrashed + self._crashDetectionDisabled = crashDetectionDisabled + self._speed = speed + self._moving = moving + self._positionId = positionId + self._latitude = latitude + self._longitude = longitude + self._altitude = altitude + self._lockedPositionId = lockedPositionId + self._lockedLatitude = lockedLatitude + self._lockedLongitude = lockedLongitude + self._isLocked = isLocked + self._canSeePosition = canSeePosition + self._canLock = canLock + self._canUnlock = canUnlock + self._canShare = canShare + self._canUnshare = canUnshare + self._canCheckSpeed = canCheckSpeed + self._canSeeStatistics = canSeeStatistics + self._canSendBrokenDownSignal = canSendBrokenDownSignal + self._canSendStolenSignal = canSendStolenSignal + self._status = status + + @property + def trackerId(self): + return self._trackerId + + @property + def trackerName(self): + return self._trackerName + + @property + def deviceButtonAction(self): + return self._deviceButtonAction + + @property + def deviceButtonDelay(self): + return self._deviceButtonDelay + + @property + def vibrationLevel(self): + return self._vibrationLevel + + @property + def isOldTracker(self): + return self._isOldTracker + + @property + def autoLockFreesedTo(self): + return self._autoLockFreesedTo + + @property + def fixtime(self): + return self._fixtime + + @property + def role(self): + return self._role + + @property + def lastPayementDate(self): + return self._lastPayementDate + + @property + def giftCardId(self): + return self._giftCardId + + @property + def expires(self): + return self._expires + + @property + def activationDate(self): + return self._activationDate + + @property + def odometer(self): + return self._odometer + + @property + def isStolen(self): + return self._isStolen + + @property + def isCrashed(self): + return self._isCrashed + + @property + def crashDetectionDisabled(self): + return self._crashDetectionDisabled + + @property + def speed(self): + return self._speed + + @property + def moving(self): + return self._moving + + @property + def positionId(self): + return self._positionId + + @property + def latitude(self): + return self._latitude + + @property + def longitude(self): + return self._longitude + + @property + def altitude(self): + return self._altitude + + @property + def lockedPositionId(self): + return self._lockedPositionId + + @property + def lockedLatitude(self): + return self._lockedLatitude + + @property + def lockedLongitude(self): + return self._lockedLongitude + + @property + def isLocked(self): + return self._isLocked + + @property + def canSeePosition(self): + return self._canSeePosition + + @property + def canLock(self): + return self._canLock + + @property + def canUnlock(self): + return self._canUnlock + + @property + def canShare(self): + return self._canShare + + @property + def canUnshare(self): + return self._canUnshare + + @property + def canCheckSpeed(self): + return self._canCheckSpeed + + @property + def canSeeStatistics(self): + return self._canSeeStatistics + + @property + def canSendBrokenDownSignal(self): + return self._canSendBrokenDownSignal + + @property + def canSendStolenSignal(self): + return self._canSendStolenSignal + + @property + def status(self): + return self._status + + def fromJson(json): + return GeorideTracker( + json['trackerId'], + json['trackerName'], + json['deviceButtonAction'], + json['deviceButtonDelay'], + json['vibrationLevel'], + json['isOldTracker'], + json['autoLockFreezedTo'], + json['fixtime'], + json['role'], + json['lastPaymentDate'], + json['giftCardId'], + json['expires'], + json['activationDate'], + json['odometer'], + json['isStolen'], + json['isCrashed'], + json['crashDetectionDisabled'], + json['speed'], + json['moving'], + json['positionId'], + json['latitude'], + json['longitude'], + json['altitude'], + json['lockedPositionId'], + json['lockedLatitude'], + json['lockedLongitude'], + json['isLocked'], + json['canSeePosition'], + json['canLock'], + json['canUnlock'], + json['canShare'], + json['canUnshare'], + json['canCheckSpeed'], + json['canSeeStatistics'], + json['canSendBrokenDownSignal'], + json['canSendStolenSignal'], + json['status'] + ) + + +class GeorideAccount: + def __init__(self, account_id, email, isAdmin, authToken): + self._account_id = account_id + self._email = email + self._isAdmin = isAdmin + self._authToken = authToken + + @property + def account_id(self): + return self._account_id + + @property + def email(self): + return self._email + + @property + def isAdmin(self): + return self._isAdmin + + @property + def authToken(self): + return self._authToken + + @authToken.setter + def authToken(self, newToken): + self._authToken = newToken + + def fromJson(json): + return GeorideAccount( + json['id'], + json['email'], + json['isAdmin'], + json['authToken'] + ) + + +class GeorideUser: + def __init__(self, account_id, email, firstName, createdAt, phoneNumberp, pushUserToken, legal, dateOfBirth): + self._account_id = account_id + self._email = email + self._firstName = firstName + self._createdAt = createdAt + self._phoneNumberp = phoneNumberp + self._pushUserToken = pushUserToken + self._legal = legal + self._dateOfBirth = dateOfBirth + + @property + def user_id(self): + return self._user_id + + @property + def email(self): + return self._email + + @property + def firstName(self): + return self._firstName + + @property + def createdAt(self): + return self._createdAt + + @property + def phoneNumber(self): + return self._phoneNumber + + @property + def pushUserToken(self): + return self._pushUserToken + + @property + def legal(self): + return self._legal + + @property + def dateOfBirth(self): + return self._dateOfBirth + + def fromJson(json): + return GeorideUser( + json['id'], + json['email'], + json['firstName'], + json['createdAt'], + json['phoneNumber'], + json['pushUserToken'], + json['legal'], + json['dateOfBirth'] + ) + + + +if __name__ == '__main__': + print("Not a main module") \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..7d10829 --- /dev/null +++ b/manifest.json @@ -0,0 +1,10 @@ +{ + "domain": "georide", + "name": "Georide", + "config_flow": true, + "documentation": "https://georide.fr", + "dependencies": [ + "urllib3" + ], + "codeowners": [] +} \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..224a779 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b3b8152 --- /dev/null +++ b/setup.py @@ -0,0 +1,40 @@ +# pylint: disable=invalid-name, exec-used +"""Setup georideapilib package.""" +from __future__ import absolute_import + +import os +import sys + +from setuptools import setup + +sys.path.insert(0, '.') + +CURRENT_DIR = os.path.dirname(__file__) + +# to deploy to pip, please use +# make pythonpack +# python setup.py register sdist upload +# and be sure to test it firstly using +# "python setup.py register sdist upload -r pypitest" +setup( + name='georideapilib', + packages=['georideapilib'], # this must be the same as the name above + version='0.1.0', + description='Lib to control georide tracker devices with their rest api', + author='Matthieu DUVAL', + author_email='georideapilib@duval-dev.fr', + # use the URL to the github repo + url='https://github.com/ptimatth/pyGeoride', + download_url='https://codeload.github.com/ptimatth/pyGeoride/tar.gz/0.1.0', + keywords=['rest', 'georide', 'api', 'grutier'], # arbitrary keywords + classifiers=[], + install_requires=[], + tests_require=[ + 'pytest>=3.7', + 'pytest-pep8', + 'pytest-cov', + 'python-coveralls', + 'pylint', + 'coverage>=4.4' + ] +) \ No newline at end of file diff --git a/test_requirements.txt b/test_requirements.txt new file mode 100644 index 0000000..6cbcae9 --- /dev/null +++ b/test_requirements.txt @@ -0,0 +1,6 @@ +pytest>=3.7 +pytest-pep8 +pytest-cov +python-coveralls +pylint +coverage>=4.4 \ No newline at end of file