From: Sebastian Golasch Date: Sun, 2 Jul 2017 19:25:08 +0000 (+0200) Subject: Merge pull request #74 from asciidisco/fix/esn-loading-inline-data X-Git-Url: http://git.code-monkey.de/?p=plugin.video.netflix.git;a=commitdiff_plain;h=bab3091758a90d4d8dd112d97a9c16377050ed93;hp=96d45f2f67a9452d63414d480fd19e34d3f4f7e3 Merge pull request #74 from asciidisco/fix/esn-loading-inline-data Fix/esn loading inline data --- diff --git a/addon.xml b/addon.xml index d04de3e..8f3b40a 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -28,7 +28,12 @@ MIT http://www.kodinerds.net/index.php/Thread/55607-Inputstream-Agile-Betatest-Netflix/ https://github.com/asciidisco/plugin.video.netflix - v0.11.11 (2017-4-10) + v0.11.12 (2017-07-02) + - Fix missing isFirstUse inline setting + - Fix dynamic ESN loading for widevine + - Fix unicode decoding problems + + v0.11.11 (2017-4-10) - Portugese translations - Swedish translations @@ -40,9 +45,6 @@ - Fix issues with persisted msl manifests v0.11.8 (2017-3-17) - - Fix 1 sec delay per request on windows (see https://github.com/asciidisco/plugin.video.netflix/issues/21 for details) - - v0.11.7 (2017-3-17) - - Remove initial connection check as it´s causing trouble + - Fix 1 sec delay per request on windows (see https://github.com/asciidisco/plugin.video.netflix/issues/21 for details) diff --git a/resources/language/Dutch/strings.po b/resources/language/Dutch/strings.po index 366bd37..3cc76cf 100644 --- a/resources/language/Dutch/strings.po +++ b/resources/language/Dutch/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index 965a0b3..51ad4f5 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.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/German/strings.po b/resources/language/German/strings.po index a20a107..3cf40ad 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.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Polish/strings.po b/resources/language/Polish/strings.po index 0580e17..03e4d51 100644 --- a/resources/language/Polish/strings.po +++ b/resources/language/Polish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Portugese/strings.po b/resources/language/Portugese/strings.po index 63e8ac3..f652897 100644 --- a/resources/language/Portugese/strings.po +++ b/resources/language/Portugese/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Slovak/strings.po b/resources/language/Slovak/strings.po index df75c2c..d8f513f 100644 --- a/resources/language/Slovak/strings.po +++ b/resources/language/Slovak/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Spanish/strings.po b/resources/language/Spanish/strings.po index 16071d8..2deda61 100644 --- a/resources/language/Spanish/strings.po +++ b/resources/language/Spanish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Swedish/strings.po b/resources/language/Swedish/strings.po index c5cf9ae..ffbdeee 100644 --- a/resources/language/Swedish/strings.po +++ b/resources/language/Swedish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/lib/KodiHelper.py b/resources/lib/KodiHelper.py index 100f94e..a75f2e7 100644 --- a/resources/lib/KodiHelper.py +++ b/resources/lib/KodiHelper.py @@ -7,7 +7,9 @@ import xbmcplugin import xbmcgui import xbmc import json -from os.path import join +from MSL import MSL +from os import remove +from os.path import join, isfile from urllib import urlencode from xbmcaddon import Addon from uuid import uuid4 @@ -190,6 +192,34 @@ class KodiHelper: 'password': self.get_addon().getSetting('password') } + def get_esn(self): + """ + Returns the esn from settings + """ + self.log(msg='Is FILE: ' + str(isfile(self.msl_data_path + 'msl_data.json'))) + self.log(msg=self.get_addon().getSetting('esn')) + return self.get_addon().getSetting('esn') + + def set_esn(self, esn): + """ + Returns the esn from settings + """ + stored_esn = self.get_esn() + if not stored_esn and esn: + self.set_setting('esn', esn) + self.delete_manifest_data() + return esn + return stored_esn + + def delete_manifest_data(self): + if isfile(self.msl_data_path + 'msl_data.json'): + remove(self.msl_data_path + 'msl_data.json') + if isfile(self.msl_data_path + 'manifest.json'): + remove(self.msl_data_path + 'manifest.json') + msl = MSL(kodi_helper=self) + msl.perform_key_handshake() + msl.save_msl_data() + def get_dolby_setting(self): """ Returns if the dolby sound is enabled @@ -644,6 +674,7 @@ class KodiHelper: bool List could be build """ + self.set_esn(esn) addon = self.get_addon() inputstream_addon = self.get_inputstream_addon() if inputstream_addon == None: @@ -744,7 +775,9 @@ class KodiHelper: if 'mpaa' in entry_keys: infos.update({'mpaa': entry['mpaa']}) else: - infos.update({'mpaa': str(entry['maturity']['board']) + '-' + str(entry['maturity']['value'])}) + if entry.get('maturity', None) is not None: + if entry['maturity']['board'] is not None and entry['maturity']['value'] is not None: + infos.update({'mpaa': str(entry['maturity']['board'].encode('utf-8')) + '-' + str(entry['maturity']['value'].encode('utf-8'))}) if 'rating' in entry_keys: infos.update({'rating': int(entry['rating']) * 2}) if 'synopsis' in entry_keys: diff --git a/resources/lib/MSL.py b/resources/lib/MSL.py index 5b7381d..d038797 100644 --- a/resources/lib/MSL.py +++ b/resources/lib/MSL.py @@ -42,7 +42,7 @@ class MSL: last_drm_context = '' last_playback_context = '' #esn = "NFCDCH-LX-CQE0NU6PA5714R25VPLXVU2A193T36" - esn = "WWW-BROWSE-D7GW1G4NPXGR1F0X1H3EQGY3V1F5WE" + #esn = "WWW-BROWSE-D7GW1G4NPXGR1F0X1H3EQGY3V1F5WE" #esn = "NFCDIE-02-DCH84Q2EK3N6VFVQJ0NLRQ27498N0F" current_message_id = 0 session = requests.session() @@ -71,13 +71,18 @@ class MSL: elif self.file_exists(self.kodi_helper.msl_data_path, 'rsa_key.bin'): self.kodi_helper.log(msg='RSA Keys do already exist load old ones') self.__load_rsa_keys() - self.__perform_key_handshake() + if self.kodi_helper.get_esn(): + self.__perform_key_handshake() else: self.kodi_helper.log(msg='Create new RSA Keys') # Create new Key Pair and save self.rsa_key = RSA.generate(2048) self.__save_rsa_keys() - self.__perform_key_handshake() + if self.kodi_helper.get_esn(): + self.__perform_key_handshake() + + def perform_key_handshake(self): + self.__perform_key_handshake() def load_manifest(self, viewable_id): """ @@ -406,6 +411,7 @@ class MSL: } def __generate_msl_request_data(self, data): + self.__load_msl_data() header_encryption_envelope = self.__encrypt(self.__generate_msl_header()) header = { 'headerdata': base64.standard_b64encode(header_encryption_envelope), @@ -453,9 +459,10 @@ class MSL: :return: The base64 encoded JSON String of the header """ self.current_message_id = self.rndm.randint(0, pow(2, 52)) + esn = self.kodi_helper.get_esn() header_data = { - 'sender': self.esn, + 'sender': esn, 'handshake': is_handshake, 'nonreplayable': False, 'capabilities': { @@ -507,10 +514,12 @@ class MSL: :param plaintext: :return: Serialized JSON String of the encryption Envelope """ + esn = self.kodi_helper.get_esn() + iv = get_random_bytes(16) encryption_envelope = { 'ciphertext': '', - 'keyid': self.esn + '_' + str(self.sequence_number), + 'keyid': esn + '_' + str(self.sequence_number), 'sha256': 'AA==', 'iv': base64.standard_b64encode(iv) } @@ -535,11 +544,13 @@ class MSL: def __perform_key_handshake(self): header = self.__generate_msl_header(is_key_request=True, is_handshake=True, compressionalgo="", encrypt=False) + esn = self.kodi_helper.get_esn() + request = { 'entityauthdata': { 'scheme': 'NONE', 'authdata': { - 'identity': self.esn + 'identity': esn } }, 'headerdata': base64.standard_b64encode(header), @@ -596,6 +607,10 @@ class MSL: self.encryption_key = base64.standard_b64decode(msl_data['encryption_key']) self.sign_key = base64.standard_b64decode(msl_data['sign_key']) + + def save_msl_data(self): + self.__save_msl_data() + def __save_msl_data(self): """ Saves the keys and tokens in json file diff --git a/resources/lib/NetflixHttpSubRessourceHandler.py b/resources/lib/NetflixHttpSubRessourceHandler.py index a4113a4..55d95ca 100644 --- a/resources/lib/NetflixHttpSubRessourceHandler.py +++ b/resources/lib/NetflixHttpSubRessourceHandler.py @@ -40,6 +40,7 @@ class NetflixHttpSubRessourceHandler: self.profiles = self.netflix_session.profiles else: self.profiles = [] + self.kodi_helper.set_esn(self.netflix_session.esn) def is_logged_in (self, params): """Existing login proxy function diff --git a/resources/lib/NetflixSession.py b/resources/lib/NetflixSession.py index f4c9be3..e5d3219 100644 --- a/resources/lib/NetflixSession.py +++ b/resources/lib/NetflixSession.py @@ -1250,7 +1250,7 @@ class NetflixSession: 'title': episode['info']['title'], 'year': episode['info']['releaseYear'], 'genres': self.parse_genres_for_video(video=episode, genres=genres), - 'mpaa': str(episode['maturity']['rating']['board']) + ' ' + str(episode['maturity']['rating']['value']), + 'mpaa': str(episode['maturity']['rating']['board']).encode('utf-8') + ' ' + str(episode['maturity']['rating']['value']).encode('utf-8'), 'maturity': episode['maturity'], 'playcount': (0, 1)[episode['watched']], 'rating': episode['userRating'].get('average', 0) if episode['userRating'].get('average', None) != None else episode['userRating'].get('predicted', 0), @@ -1884,14 +1884,14 @@ class NetflixSession: User Agent for platform """ import platform - if platform == 'linux' or platform == 'linux2': - return 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' - elif platform == 'darwin': + self.log(msg='Building User Agent for platform: ' + str(platform.system()) + ' - ' + str(platform.machine())) + if platform.system() == 'Darwin': return 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' - elif platform == 'win32': + if platform.system() == 'Windows': return 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' - else: - return 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' + if platform.machine().startswith('arm'): + return 'Mozilla/5.0 (X11; CrOS armv7l 7647.78.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36' + return 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' def _session_post (self, component, type='document', data={}, headers={}, params={}): """Executes a get request using requests for the current session & measures the duration of that request @@ -2207,7 +2207,6 @@ class NetflixSession: important_fields = [ 'profileName', 'isActive', - 'isFirstUse', 'isAccountOwner', 'isKids' ] @@ -2220,7 +2219,7 @@ class NetflixSession: profile.update({important_field: netflix_page_data['profiles'][profile_id]['summary'][important_field]}) avatar_base = netflix_page_data['nf'].get(netflix_page_data['profiles'][profile_id]['summary']['avatarName'], False); avatar = 'https://secure.netflix.com/ffe/profiles/avatars_v2/320x320/PICON_029.png' if avatar_base == False else avatar_base['images']['byWidth']['320']['value'] - profile.update({'avatar': avatar}) + profile.update({'avatar': avatar, 'isFirstUse': False}) profiles.update({profile_id: profile}) return profiles