From 5356f32f540542f5d62d3e93ea4692613a90ee42 Mon Sep 17 00:00:00 2001 From: Sebastian Golasch Date: Thu, 9 Mar 2017 14:51:14 +0100 Subject: [PATCH] chore(docs): Added documentation to the netflix service methods --- addon.xml | 2 +- resources/language/English/strings.po | 2 +- resources/language/German/strings.po | 2 +- resources/lib/NetflixHttpRequestHandler.py | 2 + .../lib/NetflixHttpSubRessourceHandler.py | 213 +++++++++++++++++- service.py | 8 + 6 files changed, 220 insertions(+), 9 deletions(-) diff --git a/addon.xml b/addon.xml index 230f92b..973551c 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index 6e4dbe2..37448b0 100644 --- a/resources/language/English/strings.po +++ b/resources/language/English/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.10.5 +# Addon version: 0.10.6 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/German/strings.po b/resources/language/German/strings.po index 57cedb2..8f6e5da 100644 --- a/resources/language/German/strings.po +++ b/resources/language/German/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.10.5 +# Addon version: 0.10.6 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/lib/NetflixHttpRequestHandler.py b/resources/lib/NetflixHttpRequestHandler.py index b42b50c..3c2344f 100644 --- a/resources/lib/NetflixHttpRequestHandler.py +++ b/resources/lib/NetflixHttpRequestHandler.py @@ -25,8 +25,10 @@ methods = [x for x, y in NetflixHttpSubRessourceHandler.__dict__.items() if type sub_res_handler = NetflixHttpSubRessourceHandler(kodi_helper=kodi_helper, netflix_session=netflix_session) class NetflixHttpRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + """ Represents the callable internal server that dispatches requests to Netflix""" def do_GET(self): + """GET request handler (we only need this, as we only do GET requests internally)""" url = urlparse(self.path) params = parse_qs(url.query) method = params.get('method', [None])[0] diff --git a/resources/lib/NetflixHttpSubRessourceHandler.py b/resources/lib/NetflixHttpSubRessourceHandler.py index 598f2b2..1c6d29e 100644 --- a/resources/lib/NetflixHttpSubRessourceHandler.py +++ b/resources/lib/NetflixHttpSubRessourceHandler.py @@ -4,39 +4,84 @@ # Created on: 07.03.2017 class NetflixHttpSubRessourceHandler: + """ Represents the callable internal server routes & translates/executes them to requests for Netflix""" def __init__ (self, kodi_helper, netflix_session): + """Sets up credentials & video_list_cache cache + Assigns the netflix_session/kodi_helper instacnes + Does the initial login if we have user data + + Parameters + ---------- + kodi_helper : :obj:`KodiHelper` + instance of the KodiHelper class + + netflix_session : :obj:`NetflixSession` + instance of the NetflixSession class + """ self.kodi_helper = kodi_helper self.netflix_session = netflix_session self.credentials = self.kodi_helper.get_credentials() self.video_list_cache = {} + # check if we have stored credentials, if so, do the login before the user requests it + # if that is done, we cache the profiles if self.credentials['email'] != '' and self.credentials['password'] != '': if self.netflix_session.is_logged_in(account=self.credentials): self.netflix_session.refresh_session_data(account=self.credentials) else: self.netflix_session.login(account=self.credentials) self.profiles = self.netflix_session.profiles - #self._prefetch_user_video_lists() else: self.profiles = [] - def _prefetch_user_video_lists (self): - for profile_id in self.profiles: - self.switch_profile({'profile_id': [profile_id]}) - self.video_list_cache[profile_id] = self.fetch_video_list_ids({}) - def is_logged_in (self, params): + """Existing login proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ if self.credentials['email'] == '' or self.credentials['password'] == '': return False return self.netflix_session.is_logged_in(account=self.credentials) def logout (self, params): + """Logout proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ self.profiles = [] self.credentials = {'email': '', 'password': ''} return self.netflix_session.logout() def login (self, params): + """Logout proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ email = params.get('email', [''])[0] password = params.get('password', [''])[0] if email != '' and password != '': @@ -47,12 +92,48 @@ class NetflixHttpSubRessourceHandler: return None def list_profiles (self, params): + """Returns the cached list of profiles + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`dict` of :obj:`str` + List of profiles + """ return self.profiles def get_esn (self, params): + """ESN getter function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`str` + Exracted ESN + """ return self.netflix_session.esn def fetch_video_list_ids (self, params): + """Video list ids proxy function (caches video lists) + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`list` + Transformed response of the remote call + """ cached_list = self.video_list_cache.get(self.netflix_session.user_data['guid'], None) if cached_list != None: self.kodi_helper.log('Serving cached list for user: ' + self.netflix_session.user_data['guid']) @@ -63,6 +144,18 @@ class NetflixHttpSubRessourceHandler: return self.netflix_session.parse_video_list_ids(response_data=video_list_ids_raw) def fetch_video_list (self, params): + """Video list proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`list` + Transformed response of the remote call + """ list_id = params.get('list_id', [''])[0] raw_video_list = self.netflix_session.fetch_video_list(list_id=list_id) if 'error' in raw_video_list: @@ -73,12 +166,36 @@ class NetflixHttpSubRessourceHandler: return [] def fetch_episodes_by_season (self, params): + """Episodes for season proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`list` + Transformed response of the remote call + """ raw_episode_list = self.netflix_session.fetch_episodes_by_season(season_id=params.get('season_id')[0]) if 'error' in raw_episode_list: return raw_episode_list return self.netflix_session.parse_episodes_by_season(response_data=raw_episode_list) def fetch_seasons_for_show (self, params): + """Season for show proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`list` + Transformed response of the remote call + """ show_id = params.get('show_id', [''])[0] raw_season_list = self.netflix_session.fetch_seasons_for_show(id=show_id) if 'error' in raw_season_list: @@ -89,30 +206,114 @@ class NetflixHttpSubRessourceHandler: return self.netflix_session.parse_seasons(id=show_id, response_data=raw_season_list) def rate_video (self, params): + """Video rating proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ video_id = params.get('video_id', [''])[0] rating = params.get('rating', [''])[0] return self.netflix_session.rate_video(video_id=video_id, rating=rating) def remove_from_list (self, params): + """Remove from my list proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ video_id = params.get('video_id', [''])[0] return self.netflix_session.remove_from_list(video_id=video_id) def add_to_list (self, params): + """Add to my list proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ video_id = params.get('video_id', [''])[0] return self.netflix_session.add_to_list(video_id=video_id) def fetch_metadata (self, params): + """Metadata proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ video_id = params.get('video_id', [''])[0] return self.netflix_session.fetch_metadata(id=video_id) def switch_profile (self, params): + """Switch profile proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`Requests.Response` + Response of the remote call + """ profile_id = params.get('profile_id', [''])[0] return self.netflix_session.switch_profile(profile_id=profile_id, account=self.credentials) def get_user_data (self, params): + """User data getter function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`str` + Exracted User Data + """ return self.netflix_session.user_data def search (self, params): + """Search proxy function + + Parameters + ---------- + params : :obj:`dict` of :obj:`str` + Request params + + Returns + ------- + :obj:`list` + Transformed response of the remote call + """ term = params.get('term', [''])[0] has_search_results = False raw_search_results = self.netflix_session.fetch_search_results(search_str=term) diff --git a/service.py b/service.py index 212b03a..5843601 100644 --- a/service.py +++ b/service.py @@ -12,6 +12,7 @@ from resources.lib.KodiHelper import KodiHelper from resources.lib.MSLHttpRequestHandler import MSLHttpRequestHandler from resources.lib.NetflixHttpRequestHandler import NetflixHttpRequestHandler +# helper function to select an unused port on the host machine def select_unused_port(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 0)) @@ -22,10 +23,12 @@ def select_unused_port(): addon = Addon() kodi_helper = KodiHelper() +# pick & store a port for the MSL service msl_port = select_unused_port() addon.setSetting('msl_service_port', str(msl_port)) kodi_helper.log(msg='[MSL] Picked Port: ' + str(msl_port)) +# pick & store a port for the internal Netflix HTTP proxy service ns_port = select_unused_port() addon.setSetting('netflix_service_port', str(ns_port)) kodi_helper.log(msg='[NS] Picked Port: ' + str(ns_port)) @@ -46,25 +49,30 @@ nd_server.timeout = 1 if __name__ == '__main__': monitor = xbmc.Monitor() + # start thread for MLS servie msl_thread = threading.Thread(target=msl_server.serve_forever) msl_thread.daemon = True msl_thread.start() + # start thread for Netflix HTTP service nd_thread = threading.Thread(target=nd_server.serve_forever) nd_thread.daemon = True nd_thread.start() + # kill the services if kodi monitor tells us to while not monitor.abortRequested(): if monitor.waitForAbort(5): msl_server.shutdown() nd_server.shutdown() break + # MSL service shutdown sequence msl_server.server_close() msl_server.socket.close() msl_server.shutdown() kodi_helper.log(msg='Stopped MSL Service') + # Netflix service shutdown sequence nd_server.server_close() nd_server.socket.close() nd_server.shutdown() -- 2.30.2