From 2ece3935222dee7cedbf0c86a325354c976a157a Mon Sep 17 00:00:00 2001 From: Paco8 <5084042+Paco8@users.noreply.github.com> Date: Thu, 23 Nov 2023 15:55:53 +0100 Subject: [PATCH] Version 0.7.16 --- addon.xml | 2 +- resources/lib/endpoints.py | 19 +++++----- resources/lib/movistar.py | 72 ++++++++++++++++++++++---------------- resources/lib/plugin.py | 16 ++++++--- resources/settings.xml | 5 +-- 5 files changed, 65 insertions(+), 49 deletions(-) diff --git a/addon.xml b/addon.xml index 82a5388..caee771 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/lib/endpoints.py b/resources/lib/endpoints.py index 254d26d..dc67c76 100644 --- a/resources/lib/endpoints.py +++ b/resources/lib/endpoints.py @@ -20,10 +20,10 @@ endpoints = { "proximamente-por-genero": "https://ottcache.dof6.com/movistarplus/webplayer/{profile}/contents/upcoming?mediaType=FOTOV&sort=FA&maxItems=30&mdrm={mdrm}&tlsstream=true", "token_hz": "https://autologinmovistar.imagenio.telefonica.net/asmgr/ccs/getHZTokenOnHome/WP_OTT/{MEDIAPLAYERID}", "alquilertvodlite": "https://lite.dof6.com/mpluslite/webplayer/accounts/{ACCOUNTNUMBER}/tvod/rent", - "haztecliente": "https://www.movistar.es/particulares/television/movistar-imagenio/?pid=yomvi-menu-boton_contratar", + "haztecliente": "https://www.movistarplus.es/", "cambiopin": "https://clientservices.dof6.com/movistarplus/webplayer/users/{DIGITALPLUSUSERIDC}/purchasePin", "hazteclienteregistro": "https://www.movistar.es/particulares/television/movistar-imagenio/?pid=yomvi-registro-nocliente", - "boton_contrata": "https://ottcache.dof6.com/yomvi/upselling-page/{contents}/{contentId}/landing", + "boton_contrata": "https://www.movistar.es/particulares/tv?pid=yomvi-canalyficha-contratar", "valorar": "https://perso.dof6.com/vod/vod.svc/webplayer/contents/yomvi/{CONTENTID}/ratings/{RATING}?userId={USERID}&accountnumber={ACCOUNTNUMBER}", "setUpStream": "https://alkasvaspub.imagenio.telefonica.net/asvas/ccs/{PID}/{deviceCode}/{PLAYREADYID}/Session", "relacionados": "https://ottcache.dof6.com/movistarplus/{deviceType}/users/webplayer/recommendations?profile={profile}&contentId={contentId}&showSeries=series&start={start}&end={end}&version=8&mdrm={mdrm}&tlsstream=true", @@ -40,12 +40,12 @@ endpoints = { "canales": "https://ottcache.dof6.com/movistarplus/{deviceType}/{profile}/contents/channels?mdrm={mdrm}&tlsstream=true&demarcation={demarcation}&version=8", "initdata": "https://clientservices.dof6.com/movistarplus/{deviceType}/sdp/mediaPlayers/{DEVICEID}/initData?qspVersion=ssp&version=8&status=default", "serverFP": "https://fp-ottlic-f3.imagenio.telefonica.net/TFAESP/fpls/contentlicenseservice/v1/licenses", - "zonacliente_LITE_YOMVI": "https://www.movistar.es/particulares/movistarplus/", + "zonacliente_LITE_YOMVI": "https://contratar.movistarplus.es/cliente-suscripcion/", "obtenercuenta": "https://clientservices.dof6.com/movistarplus/api/devices/webplayer/account", "recomendados2": "https://perso.dof6.com/movistarplus/{deviceType}/users/{ACCOUNTNUMBER}/contents/recommended?profile={PROFILE}&userProfile={PROFILEID}&deviceId={PLAYREADYID}&start={start}&end={end}&mode=VODRU7D&version=8&mdrm={mdrm}&tlsstream=true", "buscar_anonimo": "https://ottcache.dof6.com/movistarplus/webplayer/users/contents/search?term={texto}&mode=VODRU7D&profile=anonimo&version=8&mdrm={mdrm}&tlsstream=true&scope=DAZN", "borrargrabaciontemporada": "https://grmovistar.imagenio.telefonica.net/asfe/rest/users/npvrRecordings/episodesDeletion", - "suscripcion_CASUAL": "https://lite.movistarplus.es/cliente-suscripcion/", + "suscripcion_CASUAL": "https://contratar.movistarplus.es/cliente-suscripcion/", "consultarsala": "https://watchtogether.dof6.com/rooms/{ROOMID}?accountId={ACCOUNTNUMBER}", "en-canales-por-genero": "https://ottcache.dof6.com/movistarplus/webplayer/{profile}/contents/highlighted?mediaType=FOTOH&filter=SVODQ3&pageNumber={pagenumber}&pageLength={pagelength}&mdrm={mdrm}&tlsstream=true&version=8", "serverWV": "https://wv-ottlic-f3.imagenio.telefonica.net/TFAESP/wvls/contentlicenseservice/v1/licenses", @@ -56,10 +56,8 @@ endpoints = { "ultimasreproducciones": "https://perso.dof6.com/movistarplus/{deviceType}/users/{DIGITALPLUSUSERIDC}/viewings?profile={PROFILE}&container=trackedseries&mediaType=FOTOH&idsOnly={idsOnly}&accountNumber={ACCOUNTNUMBER}&version=8&start={start}&end={end}&mdrm={mdrm}&tlsstream=true&demarcation={demarcation}", "sacarusuariosalaoffline": "https://watchtogether.dof6.com/rooms/{ROOMID}/participant/{PARTICIPANTID}/abort?accountId={ACCOUNTNUMBER}", "contrata_producto": "https://clientservices.dof6.com/movistarplus/upselling/{deviceType}/{PLAYREADYID}/user/{ACCOUNTNUMBER}/products/{ProductId}?mdrm={mdrm}", - "suscripcion_NODTH": "https://sitioseguro.movistarplus.es/zonacliente/mi-suscripcion/?view=ac", "guiaTV": "https://ottcache.dof6.com/movistarplus/{deviceType}/{profile}/contents/epg?preOffset={preOffset}&postOffset={postOffset}&mdrm={mdrm}&tlsstream=true&demarcation={demarcation}&version=8", "buscar_best_tag": "https://perso.dof6.com/movistarplus/webplayer/users/contents/search?{POPULATE}&demarcation={demarcation}&scope=DAZN", - "zonacliente_NODTH_YOMVI": "https://sitioseguro.movistarplus.es/zonacliente/tienda/index.html?view=ac&nick={NICK}", "listaperfiles": "https://grmovistar.imagenio.telefonica.net/asfe/rest/users/profiles?state=0&isForKids=0", "zonacliente_SVOD_YOMVI": "https://sitioseguro.movistarplus.es/zonacliente/tienda/index.html", "tracking_series": "https://perso.dof6.com/movistarplus/{deviceType}/user/{DIGITALPLUSUSERIDC}/tracking/series?accountNumber={ACCOUNTNUMBER}&version=8&mdrm={mdrm}&tlsstream=true", @@ -68,16 +66,14 @@ endpoints = { "activacion_dispositivo_cuenta_tk": "https://auth.dof6.com/movistarplus/webplayer/accounts/{ACCOUNTNUMBER}/devices/{DEVICEID}?qspVersion=ssp", "cambiopassword": "https://auth.dof6.com/credmgmt/api/credmgmt/user/{DIGITALPLUSUSERIDC}/changePassword", "recomendados": "https://perso.dof6.com/movistarplus/{deviceType}/users/{ACCOUNTNUMBER}/recommendations?profile={PROFILE}&userProfile={PROFILEID}&deviceId={PLAYREADYID}&showSeries=series&start={start}&end={end}&version=8&mdrm={mdrm}&tlsstream=true", - "zonacliente_NODTHCASUAL_YOMVI": "https://sitioseguro.movistarplus.es/zonacliente/tienda/index.html?view=ac&nick={NICK}", "grabarprograma": "https://grmovistar.imagenio.telefonica.net/asfe/rest/users/npvrRecordings", "consultaestadoalquiler": "https://lite.dof6.com/mpluslite/webplayer/accounts/{ACCOUNTNUMBER}/tvod/rental/{EXTERNALPRODUCTID}", "cerrarsesiones": "https://clientservices.dof6.com/movistarplus/accounts/{ACCOUNTNUMBER}/devices?qspVersion=ssp", - "suscripcion_NODTHCASUAL": "https://sitioseguro.movistarplus.es/zonacliente/misdatospersonales.html?view=ac", "nombrardispositivo": "https://clientservices.dof6.com/movistarplus/accounts/{ACCOUNTNUMBER}/devices/{DEVICEID}/name?qspVersion=ssp", "buscar_best": "https://perso.dof6.com/movistarplus/webplayer/users/contents/search?accountnumber={ACCOUNTNUMBER}&profile={profile}&term={texto}&mode=VODRU7D&showSeries=series&distilledTvRights={distilledTvRights}&version=8&mdrm={mdrm}&tlsstream=true&demarcation={demarcation}&scope=DAZN", "consultarperfil": "https://grmovistar.imagenio.telefonica.net/asfe/rest/users/profiles/{profileID}", "grabaciones": "https://perso.dof6.com/movistarplus/npvr/{deviceType}/users/{DIGITALPLUSUSERIDC}/recordings?profile={PROFILE}&mediaType=FOTOH&version=8&idsOnly={idsOnly}&start={start}&end={end}&mdrm={mdrm}&tlsstream=true&demarcation={demarcation}", - "suscripcion_LITE": "https://lite.movistarplus.es/cliente-suscripcion/", + "suscripcion_LITE": "https://contratar.movistarplus.es/cliente-suscripcion/", "siguiente_episodio": "https://ottcache.dof6.com/movistarplus/{deviceType}/episodes/{contentId}/next?profile={PROFILE}&version=8&mdrm={mdrm}&tlsstream=true", "eliminardipositivo": "https://clientservices.dof6.com/movistarplus/accounts/{ACCOUNTNUMBER}/devices/{DEVICEID}?qspVersion=ssp", "activarpartner": "https://clientservices.dof6.com/oauth2/webplayer/users/{ACCOUNTNUMBER}/partners/{PARTNER}/promo?profile={PROFILE}", @@ -85,16 +81,17 @@ endpoints = { "primerepisodio": "https://ottcache.dof6.com/movistarplus/{deviceType}/series/{id}/first?profile={PROFILE}&version=8&mdrm={mdrm}&tlsstream=true", "ficha": "https://ottcache.dof6.com/movistarplus/{deviceType}/contents/{id}/details?profile={profile}&mediaType={mediatype}&version=8&mode={mode}&catalog={catalog}&channels={channels}&state={state}&mdrm={mdrm}&tlsstream=true&demarcation={demarcation}&legacyBoxOffice={legacyBoxOffice}", "renovacion_hztoken": "https://clientservices.dof6.com/movistarplus/{deviceType}/mediaPlayers/{DEVICEID}/hz-token", + "contratarlite_ANONIMO": "https://contratar.movistarplus.es/", "keepAliveStream": "https://alkasvaspub.imagenio.telefonica.net/asvas/ccs/{PID}/{deviceCode}/{PLAYREADYID}/Session/{SessionID}", + "renovacion_cdntoken2": "https://lite.dof6.com/tcdnidserver/{ACCOUNTNUMBER}/devices/webplayer/cdn/token/refresh", "renovacion_ssptoken": "https://clientservices.dof6.com/movistarplus/{deviceType}/accounts/{ACCOUNTNUMBER}/ssp-token?mediaPlayerId={DEVICEID}", - "renovacion_cdntoken2": "https://lite.dof6.com/tcdnidserver/{ACCOUNTNUMBER}/devices/webplayer/cdn/token/refresh", "config": "https://ottcache.dof6.com/movistarplus/{origin}/webplayer/{profile}/configuration/config?format=json&uisegment={uisegment}", "registro": "https://www.movistar.es/particulares/ver-tv/contenidos/yomvi?origen=activar", "consulta_producto": "https://clientservices.dof6.com/movistarplus/upselling/{deviceType}/{PLAYREADYID}/contents/{contents}/{contentId}/subscription?mdrm={mdrm}", "borradofavoritos": "https://grmovistar.imagenio.telefonica.net/asfe/rest/users/favorites/{family}/{contentId}", "promo_home": "https://ottcache.dof6.com/movistarplus/{origin}/webplayer/{profile}/configuration/promo-home?format=json&promosegment={promosegment}", "crearsala": "https://watchtogether.dof6.com/rooms?accountId={ACCOUNTNUMBER}", - "zonacliente_CASUAL_YOMVI": "https://www.movistar.es/particulares/movistarplus/", + "zonacliente_CASUAL_YOMVI": "https://contratar.movistarplus.es/cliente-suscripcion/", "seguimiento": "https://perso.dof6.com/movistarplus/{deviceType}/user/{DIGITALPLUSUSERIDC}/tracking/series/{SERIESID}?accountNumber={ACCOUNTNUMBER}&profile={PROFILE}&version=8&mdrm={mdrm}&tlsstream=true", "tearDownStream": "https://alkasvaspub.imagenio.telefonica.net/asvas/ccs/{PID}/{deviceCode}/{PLAYREADYID}/Session/{SessionID}", "cerrarsesiondispositivo": "https://clientservices.dof6.com/movistarplus/accounts/{ACCOUNTNUMBER}/devices/{DEVICEID}/sessions?qspVersion=ssp", diff --git a/resources/lib/movistar.py b/resources/lib/movistar.py index 933c558..96546c8 100644 --- a/resources/lib/movistar.py +++ b/resources/lib/movistar.py @@ -48,6 +48,8 @@ class Movistar(object): self.net = Network() self.net.headers = headers + self.quality = 'HD' # or UHD + # Cache self.cache = Cache(config_directory) if not os.path.exists(config_directory + 'cache'): @@ -423,16 +425,18 @@ class Movistar(object): self.cache.remove_file('tokens.json') def get_epg(self): - content = self.cache.load('epg2.json', 6*60) + cache_filename = 'epg_{}.json'.format(self.quality) + content = self.cache.load(cache_filename, 6*60) if content: data = json.loads(content) else: today = datetime.today() str_now = today.strftime('%Y-%m-%dT00:00:00') url = self.endpoints['rejilla'].format(deviceType='webplayer', profile=self.account['platform'], UTCDATETIME=str_now, DURATION=2, CHANNELS='', NETWORK='movistarplus', mdrm='true', demarcation=self.account['demarcation']) + if self.quality == 'UHD': url += '&filterQuality=UHD' #print(url) data = self.net.load_data(url) - self.cache.save_file('epg2.json', json.dumps(data, ensure_ascii=False)) + self.cache.save_file(cache_filename, json.dumps(data, ensure_ascii=False)) epg = {} for ch in data: @@ -477,6 +481,7 @@ class Movistar(object): stype = title.get('stream_type') if stype == 'u7d': s += ' (U7D)' elif stype == 'rec': s += ' (REC)' + if title.get('video_format') == '4K': s += " (4K)" color1 = 'yellow' color2 = 'red' @@ -540,21 +545,17 @@ class Movistar(object): #return False return self.is_subscribed_channel(products) - def get_channels(self, add_epg_info = False): + def get_channels(self): demarcation = self.account['demarcation'] - if add_epg_info: - url = self.endpoints['guiaTV'].format(deviceType='webplayer', profile=self.account['platform'], preOffset=0, postOffset=0, mdrm='true', demarcation=demarcation) - url += '&filterQuality=UHD' - data = self.net.load_data(url) + cache_filename = 'channels_{}.json'.format(self.quality) + content = self.cache.load(cache_filename) + if content: + data = json.loads(content) else: - content = self.cache.load('channels2.json') - if content: - data = json.loads(content) - else: - url = self.endpoints['canales'].format(deviceType='webplayer', profile=self.account['platform'], mdrm='true', demarcation=demarcation) - url += '&filterQuality=UHD' - data = self.net.load_data(url) - self.cache.save_file('channels2.json', json.dumps(data, ensure_ascii=False)) + url = self.endpoints['canales'].format(deviceType='webplayer', profile=self.account['platform'], mdrm='true', demarcation=demarcation) + if self.quality == 'UHD': url += '&filterQuality=UHD' + data = self.net.load_data(url) + self.cache.save_file(cache_filename, json.dumps(data, ensure_ascii=False)) res = [] for c in data: @@ -567,26 +568,29 @@ class Movistar(object): t['channel_name'] = c['Nombre'].strip() t['info']['title'] = str(c['Dial']) +'. ' + t['channel_name'] t['id'] = c['CodCadenaTv'] - if add_epg_info: - t['desc1'] = c['Nombre'] - t['desc2'] = '' + #if add_epg_info: + # t['desc1'] = c['Nombre'] + # t['desc2'] = '' t['dial'] = c['Dial'] t['url'] = c['PuntoReproduccion'] - t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logo'] + if 'Logo' in c: + t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logo'] + elif 'Logos' in c: + t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logos'][0]['uri'] t['session_request'] = '{"contentID":"'+ t['id'] +'", "streamType":"CHN"}' t['subscribed'] = self.is_subscribed_channel(c.get('tvProducts', [])) t['info']['playcount'] = 1 # Set as watched # epg - if add_epg_info: - program = c['Pases'][0] - t['desc1'] = program['Titulo'] - if 'TituloHorLinea2' in program: - t['desc2'] = program['TituloHorLinea2'] - t['start'] = int(program['FechaHoraInicio']) - t['end'] = int(program['FechaHoraFin']) - t['start_str'] = timestamp2str(t['start']) - t['end_str'] = timestamp2str(t['end']) - t['info']['plot'] = '[B]{}-{}[/B] {}\n{}'.format(t['start_str'], t['end_str'], t['desc1'], t['desc2']) + #if add_epg_info: + # program = c['Pases'][0] + # t['desc1'] = program['Titulo'] + # if 'TituloHorLinea2' in program: + # t['desc2'] = program['TituloHorLinea2'] + # t['start'] = int(program['FechaHoraInicio']) + # t['end'] = int(program['FechaHoraFin']) + # t['start_str'] = timestamp2str(t['start']) + # t['end_str'] = timestamp2str(t['end']) + # t['info']['plot'] = '[B]{}-{}[/B] {}\n{}'.format(t['start_str'], t['end_str'], t['desc1'], t['desc2']) res.append(t) @@ -662,6 +666,7 @@ class Movistar(object): texto=search_term, distilledTvRights=','.join(self.entitlements['distilledTvRights']), mdrm='true', demarcation=self.account['demarcation']) + if self.quality == 'UHD': url += '&filterQuality=UHD' return url def add_search(self, search_term): @@ -688,6 +693,7 @@ class Movistar(object): #url = url.replace('state=&', '') e = 'https://ottcache.dof6.com/movistarplus/webplayer/contents/{id}/details?profile={profile}&mediaType=FOTOV&version=8&mode={mode}&catalog={catalog}&mdrm=true&tlsstream=true&demarcation={demarcation}' url = e.format(id=id, profile=self.account['platform'], mode=mode, catalog=catalog, demarcation=self.account['demarcation']) + if self.quality == 'UHD': url += '&filterQuality=UHD' #print(url) return url @@ -747,6 +753,7 @@ class Movistar(object): t['subscribed'] = self.is_subscribed_vod(data.get('tvProducts', [])) if 'DatosAccesoAnonimo' in data: da = data['DatosAccesoAnonimo'] + t['video_format'] = da.get('FormatoVideo') if 'HoraInicio' in da and da['HoraInicio'] != None: t['start'] = int(da['HoraInicio']) t['start_str'] = timestamp2str(t['start']) @@ -855,6 +862,7 @@ class Movistar(object): t['art']['poster'] = t['art']['thumb'] = data['Imagen'] t['subscribed'] = self.is_subscribed_vod(data.get('tvProducts', [])) if 'Seguible' in data: t['seguible'] = data['Seguible'] + #t['video_format'] = data.get('FormatoVideo') c += 1 res.append(t) @@ -901,6 +909,7 @@ class Movistar(object): if 'ShowId' in video: t['show_id'] = video['ShowId'] if 'DatosAccesoAnonimo' in d: da = d['DatosAccesoAnonimo'] + t['video_format'] = da.get('FormatoVideo') if 'HoraInicio' in da and da['HoraInicio'] != None: t['start'] = int(da['HoraInicio']) t['start_str'] = timestamp2str(t['start']) @@ -1029,6 +1038,7 @@ class Movistar(object): url += '&topic=DC' elif cat == 'kids': url += '&topic=IN' + if self.quality == 'UHD': url += '&filterQuality=UHD' #LOG('vod url: {}'.format(url)) return url @@ -1083,7 +1093,7 @@ class Movistar(object): from urllib.parse import urlencode else: from urllib import urlencode - channels = self.get_channels(False) + channels = self.get_channels() res = [] for c in channels: if not c['subscribed']: continue @@ -1116,7 +1126,7 @@ class Movistar(object): #now = time.time()*1000 res = {} epg = self.get_epg() - channels = self.get_channels(False) + channels = self.get_channels() for channel in channels: id = channel['id'] if not channel['subscribed'] or not id in epg: continue diff --git a/resources/lib/plugin.py b/resources/lib/plugin.py index acbf8e3..b58f327 100644 --- a/resources/lib/plugin.py +++ b/resources/lib/plugin.py @@ -28,6 +28,8 @@ from .movistar import * from .addon import * from .gui import * +kodi_version= int(xbmc.getInfoLabel('System.BuildVersion')[:2]) + # Get the plugin url in plugin:// notation. _url = sys.argv[0] # Get the plugin handle as an integer number. @@ -107,7 +109,7 @@ def play(params): manifest_headers = 'User-Agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0' if stype == 'tv': cdn_token = m.get_cdntoken() - LOG('cdn_token: {}'.format(cdn_token)) + #LOG('cdn_token: {}'.format(cdn_token)) manifest_headers += '&x-tcdn-token=' + cdn_token license_url = 'https://wv-ottlic-f3.imagenio.telefonica.net/TFAESP/wvls/contentlicenseservice/v1/licenses' @@ -141,8 +143,12 @@ def play(params): play_item.setProperty('inputstream.adaptive.license_key', license_url) else: play_item.setProperty('inputstream.adaptive.license_key', '{}|{}&nv-authorizations={}|R{{SSM}}|'.format(license_url, headers, token)) - play_item.setProperty('inputstream.adaptive.stream_headers', manifest_headers) - play_item.setProperty('inputstream.adaptive.manifest_headers', manifest_headers) # Kodi 21 + + if kodi_version < 20: + play_item.setProperty('inputstream.adaptive.stream_headers', manifest_headers) + else: + play_item.setProperty('inputstream.adaptive.manifest_headers', manifest_headers) + play_item.setProperty('inputstream.adaptive.server_certificate', certificate) #play_item.setProperty('inputstream.adaptive.license_flags', 'persistent_storage') #play_item.setProperty('inputstream.adaptive.license_flags', 'force_secure_decoder') @@ -150,7 +156,7 @@ def play(params): if stype == 'u7d': play_item.setProperty('inputstream.adaptive.play_timeshift_buffer', 'true') - if sys.version_info[0] < 3: + if kodi_version < 19: play_item.setProperty('inputstreamaddon', 'inputstream.adaptive') else: play_item.setProperty('inputstream', 'inputstream.adaptive') @@ -679,6 +685,8 @@ def run(): LOG('reuse_devices: {}'.format(reuse_devices)) m = Movistar(profile_dir, reuse_devices=reuse_devices) m.add_extra_info = addon.getSettingBool('add_extra_info') + if addon.getSettingBool('uhd'): + m.quality = 'UHD' profile_id = addon.getSetting('profile_id') LOG('profile_id: {}'.format(profile_id)) diff --git a/resources/settings.xml b/resources/settings.xml index ce7f7c3..070f18c 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -3,12 +3,13 @@ + - + - +