Version 0.8.0
This commit is contained in:
1 parent
2ece393522
commit
983c80965a
4 files changed
+175
-14
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.movistarplus"
|
<addon id="plugin.video.movistarplus"
|
||||||
name="Movistar+"
|
name="Movistar+"
|
||||||
version="0.7.16"
|
version="0.8.0"
|
||||||
provider-name="Paco8">
|
provider-name="Paco8">
|
||||||
<requires>
|
<requires>
|
||||||
<!--- <import addon="xbmc.python" version="2.25.0"/> -->
|
<!--- <import addon="xbmc.python" version="2.25.0"/> -->
|
||||||
|
|||||||
+110
-4
@@ -454,6 +454,8 @@ class Movistar(object):
|
|||||||
if 'TituloHorLinea2' in p:
|
if 'TituloHorLinea2' in p:
|
||||||
pr['desc2'] = p['TituloHorLinea2']
|
pr['desc2'] = p['TituloHorLinea2']
|
||||||
pr['show_id'] = p['ShowId']
|
pr['show_id'] = p['ShowId']
|
||||||
|
if 'SerialId' in p:
|
||||||
|
pr['serie_id'] = p['SerialId']
|
||||||
pr['id'] = p['Id']
|
pr['id'] = p['Id']
|
||||||
#if 'links' in p: pr['links'] = p['links']
|
#if 'links' in p: pr['links'] = p['links']
|
||||||
epg[id].append(pr)
|
epg[id].append(pr)
|
||||||
@@ -566,12 +568,12 @@ class Movistar(object):
|
|||||||
t['stream_type'] = 'tv'
|
t['stream_type'] = 'tv'
|
||||||
t['info']['mediatype'] = 'movie'
|
t['info']['mediatype'] = 'movie'
|
||||||
t['channel_name'] = c['Nombre'].strip()
|
t['channel_name'] = c['Nombre'].strip()
|
||||||
t['info']['title'] = str(c['Dial']) +'. ' + t['channel_name']
|
t['info']['title'] = str(c.get('Dial', '0')) +'. ' + t['channel_name']
|
||||||
t['id'] = c['CodCadenaTv']
|
t['id'] = c['CodCadenaTv']
|
||||||
#if add_epg_info:
|
#if add_epg_info:
|
||||||
# t['desc1'] = c['Nombre']
|
# t['desc1'] = c['Nombre']
|
||||||
# t['desc2'] = ''
|
# t['desc2'] = ''
|
||||||
t['dial'] = c['Dial']
|
t['dial'] = c.get('Dial', '0')
|
||||||
t['url'] = c['PuntoReproduccion']
|
t['url'] = c['PuntoReproduccion']
|
||||||
if 'Logo' in c:
|
if 'Logo' in c:
|
||||||
t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logo']
|
t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logo']
|
||||||
@@ -648,6 +650,7 @@ class Movistar(object):
|
|||||||
deviceType='webplayer', DIGITALPLUSUSERIDC=self.account['encoded_user'], PROFILE=self.account['platform'],
|
deviceType='webplayer', DIGITALPLUSUSERIDC=self.account['encoded_user'], PROFILE=self.account['platform'],
|
||||||
ACCOUNTNUMBER=self.account['id'], idsOnly='false', start=1, end=30, mdrm='true', demarcation=self.account['demarcation'])
|
ACCOUNTNUMBER=self.account['id'], idsOnly='false', start=1, end=30, mdrm='true', demarcation=self.account['demarcation'])
|
||||||
#url += '&filter=AD-SINX&topic=CN'
|
#url += '&filter=AD-SINX&topic=CN'
|
||||||
|
if self.quality == 'UHD': url += '&filterQuality=UHD'
|
||||||
url += '&_='+ str(int(time.time()*1000))
|
url += '&_='+ str(int(time.time()*1000))
|
||||||
return url
|
return url
|
||||||
|
|
||||||
@@ -942,6 +945,20 @@ class Movistar(object):
|
|||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def order_recording_season(self, season_id):
|
||||||
|
headers = self.net.headers.copy()
|
||||||
|
headers['Content-Type'] = 'application/json'
|
||||||
|
headers['X-Hzid'] = self.account['session_token']
|
||||||
|
url = self.endpoints['grabartemporada']
|
||||||
|
data = '{"tvSeasonID":"' + str(season_id) +'"}'
|
||||||
|
response = self.net.session.post(url, data=data, headers=headers)
|
||||||
|
content = response.content.decode('utf-8')
|
||||||
|
try:
|
||||||
|
data = json.loads(content)
|
||||||
|
return data
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def delete_recording(self, program_id):
|
def delete_recording(self, program_id):
|
||||||
headers = self.net.headers.copy()
|
headers = self.net.headers.copy()
|
||||||
headers['Content-Type'] = 'application/json'
|
headers['Content-Type'] = 'application/json'
|
||||||
@@ -974,6 +991,8 @@ class Movistar(object):
|
|||||||
t['url'] = ''
|
t['url'] = ''
|
||||||
t['id'] = p['id']
|
t['id'] = p['id']
|
||||||
t['show_id'] = p['show_id']
|
t['show_id'] = p['show_id']
|
||||||
|
if 'serie_id' in p:
|
||||||
|
t['serie_id'] = p['serie_id']
|
||||||
t['session_request'] = '{"contentID":' + str(t['id']) +',"streamType":"CUTV"}'
|
t['session_request'] = '{"contentID":' + str(t['id']) +',"streamType":"CUTV"}'
|
||||||
t['info']['playcount'] = 1 # Set as watched
|
t['info']['playcount'] = 1 # Set as watched
|
||||||
t['start'] = p['start']
|
t['start'] = p['start']
|
||||||
@@ -1024,8 +1043,9 @@ class Movistar(object):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
def get_vod_list_url(self, cat='movies'):
|
def get_vod_list_url(self, cat='movies'):
|
||||||
#sort = 'FD'
|
#sort = 'FE'
|
||||||
sort = 'MA'
|
sort = 'MA'
|
||||||
|
#sort = 'AZ'
|
||||||
url = self.endpoints['consultar'].format(deviceType='webplayer', profile=self.account['platform'], sort=sort, start=1, end=50, mdrm='true', demarcation=self.account['demarcation'])
|
url = self.endpoints['consultar'].format(deviceType='webplayer', profile=self.account['platform'], sort=sort, start=1, end=50, mdrm='true', demarcation=self.account['demarcation'])
|
||||||
filter = '&filter=AC-OM,AC-MA,MA-GBLCICLO59,TD-CUP,RG-SINCAT,AC-PREPUB,' + self.entitlements['suscripcion']
|
filter = '&filter=AC-OM,AC-MA,MA-GBLCICLO59,TD-CUP,RG-SINCAT,AC-PREPUB,' + self.entitlements['suscripcion']
|
||||||
#filter = '&filter=AC-OM,AC-MA,MA-GBLCICLO59,TD-CUP,RG-SINCAT,AC-PREPUB'
|
#filter = '&filter=AC-OM,AC-MA,MA-GBLCICLO59,TD-CUP,RG-SINCAT,AC-PREPUB'
|
||||||
@@ -1042,6 +1062,79 @@ class Movistar(object):
|
|||||||
#LOG('vod url: {}'.format(url))
|
#LOG('vod url: {}'.format(url))
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
def get_vod_sections(self):
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
profile = self.account['platform']
|
||||||
|
#profile = 'OTT'
|
||||||
|
#profile = 'LITE'
|
||||||
|
|
||||||
|
content = self.cache.load('vod_sections.json')
|
||||||
|
if content:
|
||||||
|
data = json.loads(content)
|
||||||
|
else:
|
||||||
|
url = 'https://apps.dof6.com/feed/conf.php?id=justconfig&id_perfil={}&dispositivo=cell'.format(profile)
|
||||||
|
data = self.net.load_data(url)
|
||||||
|
self.cache.save_file('vod_sections.json', json.dumps(data, ensure_ascii=False))
|
||||||
|
|
||||||
|
submenu = data.get('YOMVIANDROID', {}).get('Menu', {}).get('Submenu', [])
|
||||||
|
res = OrderedDict()
|
||||||
|
for o in submenu:
|
||||||
|
#print_json(o)
|
||||||
|
menu = {}
|
||||||
|
menu['visible'] = (o.get('@visible') != 'false')
|
||||||
|
menu['id'] = o.get('@id')
|
||||||
|
|
||||||
|
if 'Modulo' in o:
|
||||||
|
section_name = o['@nombre'] if '@nombre' in o else o['@P']
|
||||||
|
modulo = o['Modulo']
|
||||||
|
|
||||||
|
section = []
|
||||||
|
|
||||||
|
if isinstance(modulo, dict):
|
||||||
|
modulo = [modulo]
|
||||||
|
|
||||||
|
if isinstance(modulo, list):
|
||||||
|
for m in modulo:
|
||||||
|
if 'consulta' in m and m['consulta'].get('@endpoint_ref', '') == 'consultar':
|
||||||
|
if not '@nombre' in m: continue
|
||||||
|
#print (menu['id'], m['@nombre'])
|
||||||
|
c = {}
|
||||||
|
c['name'] = m['@nombre']
|
||||||
|
pars = ''
|
||||||
|
sort = ''
|
||||||
|
|
||||||
|
parametros = m['consulta']['parametro']
|
||||||
|
if isinstance(parametros, dict):
|
||||||
|
parametros = [parametros]
|
||||||
|
|
||||||
|
for par in parametros:
|
||||||
|
#print_json(par)
|
||||||
|
if par.get('@incluir', '') == 'true':
|
||||||
|
pars += '&{}={}'.format(par['@id'], par['@value'])
|
||||||
|
if par['@id'] == 'sort':
|
||||||
|
sort = par['@value']
|
||||||
|
|
||||||
|
pars = pars.replace('{suscripcion}', self.entitlements['suscripcion'])
|
||||||
|
c['url'] = self.endpoints['consultar'].format(deviceType='webplayer', profile=profile, sort=sort, start=1, end=50, mdrm='true', demarcation=self.account['demarcation'])
|
||||||
|
c['url'] += pars
|
||||||
|
if self.quality == 'UHD': c['url'] += '&filterQuality=UHD'
|
||||||
|
section.append(c)
|
||||||
|
if len(section) > 0:
|
||||||
|
menu['name'] = section_name
|
||||||
|
menu['data'] = section
|
||||||
|
res[menu['id']] = menu
|
||||||
|
|
||||||
|
if 'portada_cine_destacados' in res:
|
||||||
|
res['portada_cine_destacados']['visible'] = True
|
||||||
|
res['portada_cine_destacados']['name'] = 'Cine - Géneros'
|
||||||
|
|
||||||
|
if 'portada_series_destacados' in res:
|
||||||
|
res['portada_series_destacados']['visible'] = True
|
||||||
|
res['portada_series_destacados']['name'] = 'Series - Géneros'
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
def install_key_file(self, filename):
|
def install_key_file(self, filename):
|
||||||
import shutil
|
import shutil
|
||||||
if sys.version_info[0] > 2:
|
if sys.version_info[0] > 2:
|
||||||
@@ -1069,7 +1162,7 @@ class Movistar(object):
|
|||||||
self.cache.save_file('auth.key', json.dumps(data, ensure_ascii=False))
|
self.cache.save_file('auth.key', json.dumps(data, ensure_ascii=False))
|
||||||
|
|
||||||
def delete_session_files(self):
|
def delete_session_files(self):
|
||||||
for f in ['access_token.conf', 'account.json', 'device_id.conf', 'devices.json', 'profile_id.conf', 'tokens.json', 'channels2.json', 'epg2.json']:
|
for f in ['access_token.conf', 'account.json', 'device_id.conf', 'devices.json', 'profile_id.conf', 'tokens.json', 'channels2.json', 'channels_UHD.json', 'channels_HD.json', 'epg2.json', 'epg_UHD.json', 'epg_HD.json']:
|
||||||
self.cache.remove_file(f)
|
self.cache.remove_file(f)
|
||||||
|
|
||||||
def get_profile_image_url(self, img_id):
|
def get_profile_image_url(self, img_id):
|
||||||
@@ -1215,3 +1308,16 @@ class Movistar(object):
|
|||||||
with io.open(filename, 'w', encoding='utf-8', newline='') as handle:
|
with io.open(filename, 'w', encoding='utf-8', newline='') as handle:
|
||||||
handle.write(''.join(res))
|
handle.write(''.join(res))
|
||||||
|
|
||||||
|
def save_credentials(self, username, password):
|
||||||
|
from .b64 import encode_base64
|
||||||
|
data = {'username': username, 'password': encode_base64(password)}
|
||||||
|
self.cache.save_file('credentials.json', json.dumps(data, ensure_ascii=False))
|
||||||
|
|
||||||
|
def load_credentials(self):
|
||||||
|
from .b64 import decode_base64
|
||||||
|
content = self.cache.load_file('credentials.json')
|
||||||
|
if content:
|
||||||
|
data = json.loads(content)
|
||||||
|
return data['username'], decode_base64(data['password'])
|
||||||
|
else:
|
||||||
|
return '', ''
|
||||||
+63
-9
@@ -298,16 +298,26 @@ def add_videos(category, ctype, videos, ref=None, url_next=None, url_prev=None,
|
|||||||
list_item.setInfo('video', t['info'])
|
list_item.setInfo('video', t['info'])
|
||||||
list_item.setArt(t['art'])
|
list_item.setArt(t['art'])
|
||||||
|
|
||||||
if t.get('stream_type') == 'u7d' and 'show_id' in t and not t.get('aired', False):
|
actions = []
|
||||||
record_program_action = (addon.getLocalizedString(30171), "RunPlugin(" + get_url(action='add_recording', id=t['show_id']) + ")")
|
if t.get('stream_type') == 'u7d':
|
||||||
list_item.addContextMenuItems([record_program_action])
|
LOG(t)
|
||||||
|
if 'show_id' in t and not t.get('aired', False):
|
||||||
|
record_program_action = (addon.getLocalizedString(30171), "RunPlugin(" + get_url(action='add_recording', id=t['show_id']) + ")")
|
||||||
|
actions.append(record_program_action)
|
||||||
|
if 'serie_id' in t:
|
||||||
|
record_season_action = (addon.getLocalizedString(30169), "RunPlugin(" + get_url(action='add_recording_season', id=t['serie_id']) + ")")
|
||||||
|
actions.append(record_season_action)
|
||||||
|
|
||||||
if 'rec' in t:
|
if 'rec' in t:
|
||||||
action = get_url(action='delete_recording', id=t['rec']['id'], name=t['rec']['name'])
|
action = get_url(action='delete_recording', id=t['rec']['id'], name=t['rec']['name'])
|
||||||
list_item.addContextMenuItems([(addon.getLocalizedString(30173), "RunPlugin(" + action + ")")])
|
actions.append((addon.getLocalizedString(30173), "RunPlugin(" + action + ")"))
|
||||||
|
|
||||||
if wishlist_action:
|
if wishlist_action:
|
||||||
list_item.addContextMenuItems([wishlist_action])
|
actions.append(wishlist_action)
|
||||||
|
|
||||||
|
if len(actions) > 0:
|
||||||
|
LOG(actions)
|
||||||
|
list_item.addContextMenuItems(actions)
|
||||||
|
|
||||||
url = get_url(action='play', id=t['id'], url=t['url'], session_request=t['session_request'], stype=t['stream_type'])
|
url = get_url(action='play', id=t['id'], url=t['url'], session_request=t['session_request'], stype=t['stream_type'])
|
||||||
if 'show_id' in t: url += '&show_id={}'.format(t['show_id'])
|
if 'show_id' in t: url += '&show_id={}'.format(t['show_id'])
|
||||||
@@ -440,7 +450,7 @@ def listing_hz(name, url, from_wishlist=False):
|
|||||||
url_prev = data['prev']['href'] if isinstance(data['next'], dict) and 'prev' in data['next'] else None
|
url_prev = data['prev']['href'] if isinstance(data['next'], dict) and 'prev' in data['next'] else None
|
||||||
add_videos(name, 'movies', l, url_next=url_next, url_prev=url_prev, ref='listing_hz', from_wishlist=from_wishlist)
|
add_videos(name, 'movies', l, url_next=url_next, url_prev=url_prev, ref='listing_hz', from_wishlist=from_wishlist)
|
||||||
|
|
||||||
def list_vod():
|
def list_vod0():
|
||||||
open_folder(addon.getLocalizedString(30111)) # VOD
|
open_folder(addon.getLocalizedString(30111)) # VOD
|
||||||
name = addon.getLocalizedString(30105).encode('utf-8')
|
name = addon.getLocalizedString(30105).encode('utf-8')
|
||||||
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='movies'))) # Movies
|
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='movies'))) # Movies
|
||||||
@@ -453,6 +463,31 @@ def list_vod():
|
|||||||
|
|
||||||
name = addon.getLocalizedString(30121).encode('utf-8')
|
name = addon.getLocalizedString(30121).encode('utf-8')
|
||||||
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='kids'))) # Kids
|
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='kids'))) # Kids
|
||||||
|
|
||||||
|
sections = m.get_vod_sections()
|
||||||
|
|
||||||
|
close_folder()
|
||||||
|
|
||||||
|
def list_vod():
|
||||||
|
open_folder(addon.getLocalizedString(30111)) # VOD
|
||||||
|
|
||||||
|
sections = m.get_vod_sections()
|
||||||
|
for key, s in sections.items():
|
||||||
|
if not s['visible']: continue
|
||||||
|
name = s['name'].encode('utf-8')
|
||||||
|
add_menu_option(name, get_url(action='list_section', name=name, key=key))
|
||||||
|
|
||||||
|
close_folder()
|
||||||
|
|
||||||
|
def list_section(key):
|
||||||
|
open_folder(addon.getLocalizedString(30111)) # VOD
|
||||||
|
|
||||||
|
sections = m.get_vod_sections()
|
||||||
|
items = sections[key]['data']
|
||||||
|
for item in items:
|
||||||
|
name = item['name'].encode('utf-8')
|
||||||
|
add_menu_option(name, get_url(action='listing', name=name, url=item['url']))
|
||||||
|
|
||||||
close_folder()
|
close_folder()
|
||||||
|
|
||||||
def search(params):
|
def search(params):
|
||||||
@@ -494,6 +529,13 @@ def order_recording(program_id):
|
|||||||
else:
|
else:
|
||||||
show_notification(addon.getLocalizedString(30172), xbmcgui.NOTIFICATION_INFO)
|
show_notification(addon.getLocalizedString(30172), xbmcgui.NOTIFICATION_INFO)
|
||||||
|
|
||||||
|
def order_recording_season(season_id):
|
||||||
|
data = m.order_recording_season(season_id)
|
||||||
|
if data and 'resultText' in data:
|
||||||
|
show_notification(data['resultText'])
|
||||||
|
else:
|
||||||
|
show_notification(addon.getLocalizedString(30172), xbmcgui.NOTIFICATION_INFO)
|
||||||
|
|
||||||
def delete_recording(id, name):
|
def delete_recording(id, name):
|
||||||
if sys.version_info[0] < 3:
|
if sys.version_info[0] < 3:
|
||||||
name = name.decode('utf-8')
|
name = name.decode('utf-8')
|
||||||
@@ -510,16 +552,24 @@ def logout():
|
|||||||
m.cache.remove_file('auth.key')
|
m.cache.remove_file('auth.key')
|
||||||
|
|
||||||
def login():
|
def login():
|
||||||
def ask_credentials(username=''):
|
def ask_credentials(username='', password=''):
|
||||||
username = input_window(addon.getLocalizedString(30163), username) # Username
|
username = input_window(addon.getLocalizedString(30163), username) # Username
|
||||||
if username:
|
if username:
|
||||||
password = input_window(addon.getLocalizedString(30164), hidden=True) # Password
|
password = input_window(addon.getLocalizedString(30164), password, hidden=True) # Password
|
||||||
if password:
|
if password:
|
||||||
return username, password
|
return username, password
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
username, password = ask_credentials()
|
store_credentials = addon.getSettingBool('store_credentials')
|
||||||
|
if store_credentials:
|
||||||
|
username, password = m.load_credentials()
|
||||||
|
else:
|
||||||
|
username, password = ('', '')
|
||||||
|
|
||||||
|
username, password = ask_credentials(username, password)
|
||||||
if username:
|
if username:
|
||||||
|
if store_credentials:
|
||||||
|
m.save_credentials(username, password)
|
||||||
success, _ = m.login(username, password)
|
success, _ = m.login(username, password)
|
||||||
if success:
|
if success:
|
||||||
clear_session()
|
clear_session()
|
||||||
@@ -627,6 +677,8 @@ def router(paramstring):
|
|||||||
order_recording(params['id'])
|
order_recording(params['id'])
|
||||||
elif params['action'] == 'delete_recording':
|
elif params['action'] == 'delete_recording':
|
||||||
delete_recording(params['id'], params['name'])
|
delete_recording(params['id'], params['name'])
|
||||||
|
elif params['action'] == 'add_recording_season':
|
||||||
|
order_recording_season(params['id'])
|
||||||
elif params['action'] == 'wishlist':
|
elif params['action'] == 'wishlist':
|
||||||
# Wishlist
|
# Wishlist
|
||||||
listing_hz(addon.getLocalizedString(30102), m.get_wishlist_url(), from_wishlist=True)
|
listing_hz(addon.getLocalizedString(30102), m.get_wishlist_url(), from_wishlist=True)
|
||||||
@@ -643,6 +695,8 @@ def router(paramstring):
|
|||||||
add_videos(params['name'], 'episodes', m.get_episodes(params['id']))
|
add_videos(params['name'], 'episodes', m.get_episodes(params['id']))
|
||||||
elif params['action'] == 'vod':
|
elif params['action'] == 'vod':
|
||||||
list_vod()
|
list_vod()
|
||||||
|
elif params['action'] == 'list_section':
|
||||||
|
list_section(params['key'])
|
||||||
elif params['action'] == 'search':
|
elif params['action'] == 'search':
|
||||||
search(params)
|
search(params)
|
||||||
elif params['action'] == 'export_epg_now':
|
elif params['action'] == 'export_epg_now':
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<settings>
|
<settings>
|
||||||
<category label="30001">
|
<category label="30001">
|
||||||
|
<setting id="store_credentials" type="bool" label="30050" default="false"/>
|
||||||
<setting label="30017" type="bool" id="only_subscribed" default="true"/>
|
<setting label="30017" type="bool" id="only_subscribed" default="true"/>
|
||||||
<setting label="30020" type="bool" id="channels_with_epg" default="false"/>
|
<setting label="30020" type="bool" id="channels_with_epg" default="false"/>
|
||||||
<setting label="30021" type="bool" id="add_extra_info" default="false"/>
|
<setting label="30021" type="bool" id="add_extra_info" default="false"/>
|
||||||
|
|||||||
Reference in new issue
Block a user