From c548a789a8320025101b72f1d9ad4de4670cd510 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 28 Oct 2019 22:13:13 +0100 Subject: [PATCH 1/2] Add support of socket --- georideapilib/api.py | 43 ++++++++++--- georideapilib/exception.py | 23 +++++++ georideapilib/socket.py | 120 +++++++++++++++++++++++++++++++++++++ setup.py | 4 +- 4 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 georideapilib/exception.py create mode 100644 georideapilib/socket.py diff --git a/georideapilib/api.py b/georideapilib/api.py index f8aa3ec..289682a 100644 --- a/georideapilib/api.py +++ b/georideapilib/api.py @@ -16,6 +16,12 @@ from georideapilib.objects import ( GeorideSharedTrip ) +from georideapilib.exception import ( + LoginException, + SeverException, + UnauthorizedException +) + GEORIDE_API_HOST = "https://api.georide.fr" GEORIDE_API_ENDPOINT_LOGIN = "/user/login" GEORIDE_API_ENDPOINT_NEW_TOKEN = "/user/new-token" @@ -33,16 +39,25 @@ _SESSION = requests.Session() _LOGGER = logging.getLogger(__name__) def get_authorisation_token(email, password): - """ return an authorization token """ + """ return an authorization token or no""" data = {"email": email, "password": password} encoded_data = json.dumps(data).encode('utf-8') + response = _SESSION.post( GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_LOGIN, data=encoded_data, headers={'Content-Type': 'application/json'}) - response_data = response.json() - _LOGGER.debug(response_data) - account = GeorideAccount.from_json(response_data) + + if response.status_code == 200: + _LOGGER.debug("Login success") + response_data = response.json() + account = GeorideAccount.from_json(response_data) + elif response.status_code == 403: + _LOGGER.warnning("Login failed") + raise LoginException("Login failed") + else: + _LOGGER.error("Georide login, http error code: %s", response.status_code) + raise SeverException("Georide login, http error code: {}".format(response.status_code)) return account @@ -52,19 +67,29 @@ def renew_token(token): response = _SESSION.get( GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_NEW_TOKEN, headers=headers) - response_data = response.json() - _LOGGER.debug(response_data) - new_token = response_data['authToken'] + if response.status_code == 200: + _LOGGER.debug("Token updated") + response_data = response.json() + new_token = response_data['authToken'] + elif response.status_code == 401: + _LOGGER.warnning("Renew token refused") + raise UnauthorizedException("Renew token refused") + else: + _LOGGER.error("Georide login, http error code: %s", response.status_code) + raise SeverException("Georide login, http error code: {}".format(response.status_code)) return new_token - def revoke_token(token): """ invalidate the authorization token """ headers = {"Authorization": "Bearer " + token} response = _SESSION.post( GEORIDE_API_HOST + GEORIDE_API_ENDPOINT_LOGOUT, headers=headers) - if response.status_code != 204: + if response.status_code == 401: + _LOGGER.warnning("Token allready revoked") + raise UnauthorizedException("Token allready revoked") + if response.status_code == 401: + _LOGGER.warnning("Token allready revoked") return False return True diff --git a/georideapilib/exception.py b/georideapilib/exception.py new file mode 100644 index 0000000..07c58b4 --- /dev/null +++ b/georideapilib/exception.py @@ -0,0 +1,23 @@ +""" all geroide exception """ + +class Error(Exception): + """Base class for exceptions in this module.""" + pass + +class LoginException(Error): + """loggin exception""" + def __init__(self, expression, message): + self.expression = expression + self.message = message + +class UnauthorizedException(Error): + """loggin exception""" + def __init__(self, expression, message): + self.expression = expression + self.message = message + +class SeverException(Error): + """loggin exception""" + def __init__(self, expression, message): + self.expression = expression + self.message = message diff --git a/georideapilib/socket.py b/georideapilib/socket.py new file mode 100644 index 0000000..d8c0085 --- /dev/null +++ b/georideapilib/socket.py @@ -0,0 +1,120 @@ +""" Georide socket-io implementation """ +import logging +import socketio + +from georideapilib.api import GEORIDE_API_HOST + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.DEBUG) +# create console handler and set level to debug +CH = logging.StreamHandler() +CH.setLevel(logging.DEBUG) + +sio = socketio.Client(reconnection=True) + +@sio.on('connect') +def on_connect(): + """ event: connected """ + _LOGGER.debug('GeoRide socket connected') + +@sio.on('disconnect') +def on_disconnect(): + """ event: disconnected """ + _LOGGER.debug('GeoRide socket disconnected') + + +class GeorideSocket(): + """docstring for GeorideSocket""" + def __init__(self): + self._on_message_callback = None + self._on_device_callback = None + self._on_position_callback = None + self._on_alarm_callback = None + self._on_refresh_tracker_callback = None + self._on_locked_callback = None + self._initialised = False + + + def subscribe_on_message(self, callback_function): + """event: tells you authentication informations.""" + self._on_message_callback = callback_function + + def subscribe_device(self, callback_function): + """event: tells you when a device is added to the account.""" + self._on_device_callback = callback_function + + def subscribe_position(self, callback_function): + """event: tells you when a device sent a position.""" + self._on_position_callback = callback_function + + def subscribe_alarm(self, callback_function): + """event: tells you when a device trigger an alarm.""" + self._on_alarm_callback = callback_function + + def subscribe_refresh_tracker(self, callback_function): + """event: tells you when you need to refresh your list of trackers""" + self._on_refresh_tracker_callback = callback_function + + def subscribe_locked(self, callback_function): + """event: tells you when a device has been locked or unlocked.""" + self._on_locked_callback = callback_function + + + def init(self): + """init the context""" + @sio.on('message') + def on_message(data): + """ on_message """ + _LOGGER.debug('Message recieved: %s', data) + if self._on_message_callback is not None: + self._on_message_callback() + + @sio.on('device') + def on_device(data): + """ on_device """ + _LOGGER.debug('Device recieved: %s', data) + if self._on_device_callback is not None: + self._on_device_callback() + + @sio.on('position') + def on_position(data): + """ on_position """ + _LOGGER.debug('Position recieved:%s', data) + if self._on_position_callback is not None: + self._on_position_callback() + + @sio.on('alarm') + def on_alarm(data): + """ on_alarm """ + _LOGGER.debug('Alarm recieved: %s', data) + if self._on_alarm_callback is not None: + self._on_alarm_callback(data) + + @sio.on('refreshTrackersInstruction') + def on_refresh_tracker(): + """ on_refresh_tracker """ + _LOGGER.debug('Refresh tracker recieved') + if self._on_refresh_tracker_callback is not None: + self._on_refresh_tracker_callback() + + @sio.on('lockedPosition') + def on_locked(data): + """ on_locked """ + _LOGGER.debug('Locked recieved: %s', data) + if self._on_locked_callback is not None: + self._on_locked_callback() + + self._initialised = True + + def connect(self, auth_token): + """ connect to the georide socket""" + _LOGGER.info("Start conection") + if self._initialised is not False: + sio.connect(GEORIDE_API_HOST, headers={'token': auth_token}) + sio.wait() + else: + _LOGGER.error("Please call init() before") + + def disconnect(self): + """disconnect from the georide socket""" + sio.disconnect() diff --git a/setup.py b/setup.py index 7894696..af1d5a2 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ CURRENT_DIR = os.path.dirname(__file__) setup( name='georideapilib', packages=['georideapilib'], # this must be the same as the name above - version='0.2.0', + version='0.3.0', description='Lib to control georide tracker devices with their rest api', author='Matthieu DUVAL', author_email='georideapilib@duval-dev.fr', @@ -28,7 +28,7 @@ setup( download_url='https://codeload.github.com/ptimatth/pyGeoride/tar.gz/0.1.0', keywords=['rest', 'georide', 'api', 'grutier'], # arbitrary keywords classifiers=[], - install_requires=[], + install_requires=["python-socketio[client]"], tests_require=[ 'pytest>=3.7', 'pytest-pep8', From 3e53a339ba45236982bc3c2fb36d202f4179234d Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 29 Oct 2019 21:51:41 +0100 Subject: [PATCH 2/2] Update example and some tweak --- examples/example.py | 46 ++++++++++++++++++++++++++--------------- georideapilib/socket.py | 19 +++++++---------- logging.conf | 29 ++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 logging.conf diff --git a/examples/example.py b/examples/example.py index 78fc205..d024823 100644 --- a/examples/example.py +++ b/examples/example.py @@ -4,69 +4,81 @@ import time import datetime +logging.config.fileConfig('logging.conf') from georideapilib.objects import GeorideAccount import georideapilib.api as GeorideApi +from georideapilib.socket import GeorideSocket + +_LOGGER = logging.getLogger('example') def example(): """ simple example function """ - token = ""# pylint: disable=C0301 - """account = GeorideAccount(0, "", False, token)""" + # token = ""# pylint: disable=C0301 + # account = GeorideAccount(0, "", False, token) account = GeorideApi.get_authorisation_token("", "") print("token 1: ", account.auth_token) + _LOGGER.info("token 1: %s", account.auth_token) # pylint: disable=W0105 - - + + # socket = GeorideSocket() + # socket.init() + # socket.connect(account.auth_token) + # time.sleep(10) + # socket.disconnect() + """ - account.auth_token = GeorideApi.renew_token(account.auth_token) + account.auth_token = GeorideApi.renewToken(account.auth_token) print("token 2: ", account.auth_token) """ # pylint: disable=W0105 user = GeorideApi.get_user(account.auth_token) - print("User: ", user.first_name) + _LOGGER.info("User: %s", user.first_name) trackers = GeorideApi.get_trackers(account.auth_token) tracker = trackers[0] - print("Tracker name: ", tracker.tracker_name) + _LOGGER.info("Tracker name: %s", tracker.tracker_name) trips = GeorideApi.get_trips(account.auth_token, tracker.tracker_id, "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.nice_start_address, - trip.nice_end_address)) + _LOGGER.info("Trip date: %s, from: %s, to: %s", trip_date, trip.nice_start_address, + trip.nice_end_address) positions = GeorideApi.get_positions(account.auth_token, tracker.tracker_id, "2019-10-10", "2019-10-24") position = positions[0] - print("Position speed: {}, lon: {}, lat: {}".format(position.speed, position.longitude, - position.latitude)) + _LOGGER.info("Position speed: %s, lon: %s, lat: %s", position.speed, position.longitude, + position.latitude) trip_shared = GeorideApi.share_a_trip_by_date(account.auth_token, tracker.tracker_id, "2019-10-10", "2019-10-24") - print("tripShared url: {}, id: {}".format(trip_shared.url, trip_shared.share_id)) + _LOGGER.info("tripShared url: %s, id: %s", trip_shared.url, trip_shared.share_id) time.sleep(10) have_been_locked = GeorideApi.lock_tracker(account.auth_token, tracker.tracker_id) - print("Tracker have been locked: ", have_been_locked) + _LOGGER.info("Tracker have been locked: %s", have_been_locked) time.sleep(10) have_been_unlocked = GeorideApi.unlock_tracker(account.auth_token, tracker.tracker_id) - print("Tracker have been unlocked: ", have_been_unlocked) + _LOGGER.info("Tracker have been unlocked: %s", have_been_unlocked) time.sleep(10) is_locked = GeorideApi.toogle_lock_tracker(account.auth_token, tracker.tracker_id) - print("Tracker is locked: ", is_locked) + _LOGGER.info("Tracker is locked: %s", is_locked) time.sleep(10) trackers = GeorideApi.get_trackers(account.auth_token) tracker = trackers[0] - print("Tracker name: ", tracker.tracker_name, " is locked: ", tracker.is_locked) + _LOGGER.info("Tracker name: %s is locked: %s", tracker.tracker_name, tracker.is_locked) + + + """ GeorideApi.revokeToken(account.auth_token) """ # pylint: disable=W0105 - example() diff --git a/georideapilib/socket.py b/georideapilib/socket.py index d8c0085..9746d52 100644 --- a/georideapilib/socket.py +++ b/georideapilib/socket.py @@ -5,12 +5,8 @@ import socketio from georideapilib.api import GEORIDE_API_HOST _LOGGER = logging.getLogger(__name__) -_LOGGER.setLevel(logging.DEBUG) -# create console handler and set level to debug -CH = logging.StreamHandler() -CH.setLevel(logging.DEBUG) -sio = socketio.Client(reconnection=True) +sio = socketio.Client(reconnection=True) # pylint: disable=C0103 @sio.on('connect') def on_connect(): @@ -65,42 +61,42 @@ class GeorideSocket(): @sio.on('message') def on_message(data): """ on_message """ - _LOGGER.debug('Message recieved: %s', data) + _LOGGER.debug('Message received: %s', data) if self._on_message_callback is not None: self._on_message_callback() @sio.on('device') def on_device(data): """ on_device """ - _LOGGER.debug('Device recieved: %s', data) + _LOGGER.debug('Device received: %s', data) if self._on_device_callback is not None: self._on_device_callback() @sio.on('position') def on_position(data): """ on_position """ - _LOGGER.debug('Position recieved:%s', data) + _LOGGER.debug('Position received:%s', data) if self._on_position_callback is not None: self._on_position_callback() @sio.on('alarm') def on_alarm(data): """ on_alarm """ - _LOGGER.debug('Alarm recieved: %s', data) + _LOGGER.debug('Alarm received: %s', data) if self._on_alarm_callback is not None: self._on_alarm_callback(data) @sio.on('refreshTrackersInstruction') def on_refresh_tracker(): """ on_refresh_tracker """ - _LOGGER.debug('Refresh tracker recieved') + _LOGGER.debug('Refresh tracker received') if self._on_refresh_tracker_callback is not None: self._on_refresh_tracker_callback() @sio.on('lockedPosition') def on_locked(data): """ on_locked """ - _LOGGER.debug('Locked recieved: %s', data) + _LOGGER.debug('Locked received: %s', data) if self._on_locked_callback is not None: self._on_locked_callback() @@ -108,7 +104,6 @@ class GeorideSocket(): def connect(self, auth_token): """ connect to the georide socket""" - _LOGGER.info("Start conection") if self._initialised is not False: sio.connect(GEORIDE_API_HOST, headers={'token': auth_token}) sio.wait() diff --git a/logging.conf b/logging.conf new file mode 100644 index 0000000..da3b459 --- /dev/null +++ b/logging.conf @@ -0,0 +1,29 @@ +[loggers] +keys=root,example + +[handlers] +keys=consoleHandler + +[formatters] +keys=simpleFormatter + +[logger_root] +level=DEBUG +handlers=consoleHandler + +[logger_example] +level=DEBUG +handlers=consoleHandler +qualname=simpleExample +propagate=0 + + +[handler_consoleHandler] +class=StreamHandler +level=DEBUG +formatter=simpleFormatter +args=(sys.stdout,) + +[formatter_simpleFormatter] +format=%(asctime)s - %(name)s - %(levelname)s - %(message)s +datefmt= \ No newline at end of file