Version 0.5.12

This commit is contained in:
Paco8 committed 2023-02-11 23:46:29 +01:00
1 parent 2f9bc94b73
commit 0cf60f4e54
7 files changed
+306 -67

No files matched your search

+2 -1
View File
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.movistarplus"
name="Movistar+"
version="0.4.6"
version="0.5.12"
provider-name="Paco8">
<requires>
<!--- <import addon="xbmc.python" version="2.25.0"/> -->
<import addon="script.module.requests"/>
<import addon="script.module.inputstreamhelper" version="0.5.2" />
<import addon="script.module.pytz"/>
<import addon="script.module.dateutil"/>
<import addon="script.module.ttml2ssa" version="0.1.16" />
</requires>
<extension point="xbmc.python.pluginsource" library="default.py">
@@ -268,3 +268,7 @@ msgstr ""
msgctxt "#30203"
msgid "Format not supported"
msgstr ""
msgctxt "#30204"
msgid "Video not available"
msgstr ""
@@ -268,3 +268,7 @@ msgstr "Inputstream.adaptive no está disponible"
msgctxt "#30203"
msgid "Format not supported"
msgstr "Formato no soportado"
msgctxt "#30204"
msgid "Video not available"
msgstr "Vídeo no disponible"
+184 -16
View File
@@ -5,7 +5,6 @@
from __future__ import unicode_literals, absolute_import, division
import sys
import base64
import json
import requests
import io
@@ -31,6 +30,8 @@ class Movistar(object):
'ssp_token': '',
'demarcation': 0}
add_extra_info = True
def __init__(self, config_directory, reuse_devices=False):
self.logged = False
@@ -69,9 +70,10 @@ class Movistar(object):
if not data or 'ofertas' not in data: return
self.cache.save_file('account.json', json.dumps(data, ensure_ascii=False))
self.account['id'] = data['ofertas'][0]['accountNumber']
self.account['pid'] = data['ofertas'][0]['cod_persona']
#self.account['pid'] = data['ofertas'][0]['cod_persona']
self.account['encoded_user'] = data['cod_usuario_cifrado']
self.account['platform'] = data['ofertas'][0]['@id_perfil']
#self.account['platform'] = 'OTT'
# Profile ID
content = self.cache.load_file('profile_id.conf')
@@ -145,6 +147,7 @@ class Movistar(object):
self.account['session_token'] = data['token']
self.account['ssp_token'] = data['sspToken']
self.account['demarcation'] = data['demarcation']
self.account['pid'] = data['pid']
self.entitlements['activePurchases'] = data['activePurchases']
self.entitlements['partners'] = data['partners']
@@ -155,6 +158,10 @@ class Movistar(object):
#print_json(self.entitlements)
self.logged = True
# Search
data = self.cache.load_file('searchs.json')
self.search_list = json.loads(data) if data else []
def get_token(self):
data = {"accountNumber": self.account['id'],
"userProfile": self.account['profile_id'],
@@ -197,7 +204,7 @@ class Movistar(object):
headers = self.net.headers.copy()
headers['Content-Type'] = 'application/json'
headers['X-Hzid'] = session_token
url = self.endpoints['setUpStream'].format(PID=self.account['id'], deviceCode='WP_OTT', PLAYREADYID=self.account['device_id'])
url = self.endpoints['setUpStream'].format(PID=self.account['pid'], deviceCode='WP_OTT', PLAYREADYID=self.account['device_id'])
if session_id != None:
url += '/' + session_id
#LOG('open_session: url: {}'.format(url))
@@ -407,8 +414,9 @@ class Movistar(object):
data = json.loads(content)
else:
today = datetime.today()
str_now = today.strftime('%Y-%m-%dT%H:00:00')
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'])
#print(url)
data = self.net.load_data(url)
self.cache.save_file('epg2.json', json.dumps(data, ensure_ascii=False))
@@ -422,10 +430,13 @@ class Movistar(object):
pr['end'] = int(p['FechaHoraFin'])
pr['start_str'] = timestamp2str(pr['start'])
pr['end_str'] = timestamp2str(pr['end'])
pr['date_str'] = timestamp2str(pr['start'], '%a %d %H:%M')
pr['desc1'] = p['Titulo']
pr['desc2'] = ''
if 'TituloHorLinea2' in p:
pr['desc2'] = p['TituloHorLinea2']
pr['show_id'] = p['ShowId']
if 'links' in p: pr['links'] = p['links']
epg[id].append(pr)
return epg
@@ -451,13 +462,23 @@ class Movistar(object):
if stype == 'u7d': s += ' (U7D)'
elif stype == 'rec': s += ' (REC)'
if title['subscribed'] == True:
color1 = 'yellow'
color2 = 'red'
else:
color1 = 'yellow'
color2 = 'red'
available = True
if 'subscribed' in title and title['subscribed'] == False: available = False
if 'url' in title and title['url'] == '': available = False
if not available:
color1 = 'gray'
color2 = 'gray'
s = '[COLOR gray]' + s +'[/COLOR]'
elif 'start' in title:
aired = (title['start'] <= (time.time() * 1000))
if not aired:
color1 = 'blue'
color2 = 'blue'
s = '[COLOR blue]' + s +'[/COLOR]'
if title.get('desc1', '') != '':
s += ' - [COLOR {}]{}[/COLOR]'.format(color1, title['desc1'])
if title.get('desc2', '') != '':
@@ -467,14 +488,21 @@ class Movistar(object):
def add_epg_info(self, channels, epg, timestamp):
for ch in channels:
programs = self.find_program_epg(epg, ch['id'], timestamp)
ch['info']['plot'] = ''
plot = ''
for i in range(len(programs)):
desc1 = programs[i]['desc1']
desc2 = programs[i]['desc2']
if i == 0:
ch['desc1'] = desc1
ch['desc2'] = desc2
ch['info']['plot'] += "[B]{}[/B] {} {}\n".format(programs[i]['start_str'], desc1, desc2)
plot += "[B]{}[/B] {} {}\n".format(programs[i]['start_str'], desc1, desc2)
if self.add_extra_info:
ch['art'] = {'poster': None, 'fanart': None}
self.add_video_extra_info(programs[i]['show_id'], ch, catalog='events')
if 'plot' in ch['info']:
plot = plot + ch['info']['plot']
break
ch['info']['plot'] = plot
def is_subscribed_channel(self, products):
for e in self.entitlements['activePackages']:
@@ -519,9 +547,7 @@ class Movistar(object):
t['desc2'] = ''
t['dial'] = c['Dial']
t['url'] = c['PuntoReproduccion']
t['art']['icon'] = c['Logo']
t['art']['thumb'] = c['Logo']
t['art']['poster'] = c['Logo']
t['art']['icon'] = t['art']['thumb'] = t['art']['poster'] = c['Logo']
t['session_request'] = '{"contentID":"'+ t['id'] +'", "streamType":"CHN"}'
t['subscribed'] = self.is_subscribed_channel(c['Productos'])
t['info']['playcount'] = 1 # Set as watched
@@ -571,9 +597,28 @@ class Movistar(object):
url = self.endpoints['grabaciones'].format(
deviceType='webplayer', DIGITALPLUSUSERIDC=self.account['encoded_user'], PROFILE=self.account['platform'],
idsOnly='false', start=1, end=30, mdrm='true', demarcation=self.account['demarcation'])
url += '&state=Completed&_='+ str(int(time.time()*1000))
#url += '&state=Completed&_='+ str(int(time.time()*1000))
url += '&_='+ str(int(time.time()*1000))
return url
def get_search_url(self, search_term):
url = self.endpoints['buscar_best'].format(
ACCOUNTNUMBER=self.account['id'],
profile=self.account['platform'],
texto=search_term,
linearSubscription=','.join(self.entitlements['linearSubscription']),
vodSubscription=','.join(self.entitlements['vodSubscription']),
mdrm='true', demarcation=self.account['demarcation'])
return url
def add_search(self, search_term):
self.search_list.append(search_term)
self.cache.save_file('searchs.json', json.dumps(self.search_list, ensure_ascii=False))
def delete_search(self, search_term):
self.search_list = [s for s in self.search_list if s != search_term]
self.cache.save_file('searchs.json', json.dumps(self.search_list, ensure_ascii=False))
def get_title(self, data):
t = {}
t['info'] = {}
@@ -584,6 +629,7 @@ class Movistar(object):
t['art']['poster'] = ed['Imagen'].replace('ywcatalogov', 'dispficha')
t['art']['thumb'] = t['art']['poster']
t['info']['genre'] = ed['GeneroComAntena']
if ed.get('TipoComercial') == 'Impulsivo': return None # Alquiler
if ed['TipoContenido'] in ['Individual', 'Episodio']:
t['type'] = 'movie'
t['stream_type'] = 'vod'
@@ -604,6 +650,16 @@ class Movistar(object):
elif video['AssetType'] == 'NPVR':
t['stream_type'] = 'rec'
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"NPVR"}'
if self.add_extra_info:
self.add_video_extra_info(t['id'], t)
if 'Recording' in data:
t['stream_type'] = 'rec'
t['rec'] = {'id': data['Recording']['id'],
'name': data['Recording']['name'],
'start': data['Recording']['beginTime'],
'end': data['Recording']['endTime']}
if t['url'] == '': t['info']['title'] += ' (' + isodate2str(t['rec']['start']) + ')'
if t['url'] == '' and t['stream_type'] == 'vod': t['subscribed'] = False
if ed['TipoContenido'] == 'Serie':
t['type'] = 'series'
t['info']['mediatype'] = 'tvshow'
@@ -624,6 +680,39 @@ class Movistar(object):
res.append(t)
return res
def add_video_extra_info(self, id, t, catalog=''):
try:
url = self.endpoints['ficha'].format(deviceType='webplayer', id=id, profile=self.account['platform'], mediatype='FOTOV', version='7.1', mode='GLOBAL', catalog=catalog, channels='', state='', mdrm='true', demarcation=self.account['demarcation'], legacyBoxOffice='')
#print(url)
data = self.net.load_data(url)
if data.get('Sinopsis'):
t['info']['plot'] = data['Sinopsis']
if data.get('Actores'):
t['info']['cast'] = data['Actores'].split(', ')
if data.get('Directores'):
t['info']['director'] = data['Directores'].split(', ')
if data.get('Anno'):
t['info']['year'] = data['Anno']
if data.get('Nacionalidad'):
t['info']['country'] = data['Nacionalidad']
im_thumb = im_default = im_season = im_fanart = None
for im in data['Imagenes']:
if im['id'] == 'horizontal': im_thumb = im['uri']
elif im['id'] == 'default': im_default = im['uri']
elif im['id'] == 'watch2tgr-end': im_fanart = im['uri']
elif im['id'] == 'temporada': im_season = im['uri']
if im_thumb and not t['art'].get('thumb'): t['art']['thumb'] = im_thumb
if im_season:
if not t['art'].get('poster'): t['art']['poster'] = im_season
if im_fanart:
if not t['art'].get('fanart'): t['art']['fanart'] = im_fanart
if im_default:
if not t['art'].get('poster'): t['art']['poster'] = im_default
if not t['art'].get('icon'): t['art']['icon'] = im_default
if not t['art'].get('fanart'): t['art']['fanart'] = im_default
except:
pass
def get_seasons(self, id):
url = self.endpoints['ficha'].format(deviceType='webplayer', id=id, profile=self.account['platform'], mediatype='FOTOV', version='7.1', mode='GLOBAL', catalog='', channels='', state='', mdrm='true', demarcation=self.account['demarcation'], legacyBoxOffice='')
data = self.net.load_data(url)
@@ -653,6 +742,7 @@ class Movistar(object):
#print(url)
data = self.net.load_data(url)
#print_json(data)
#self.cache.save_file('episodes.json', json.dumps(data, ensure_ascii=False))
res = []
for d in data['Episodios']:
ed = d['DatosEditoriales']
@@ -666,7 +756,8 @@ class Movistar(object):
t['info']['title'] = ed['TituloEpisodio']
t['info']['episode'] = ed['NumeroEpisodio']
t['info']['duration'] = ed['DuracionEnSegundos']
t['art']['thumb'] = ed['Imagen']
t['info']['tvshowtitle'] = data.get('TituloSerie', '')
t['art']['poster'] = data['Imagen']
for im in ed['Imagenes']:
if im['id'] == 'horizontal': t['art']['thumb'] = im['uri']
m = re.search(r'T(\d+)', ed['Temporada'])
@@ -682,7 +773,8 @@ class Movistar(object):
elif video['AssetType'] == 'U7D':
t['stream_type'] = 'u7d'
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"CUTV"}'
if self.add_extra_info:
self.add_video_extra_info(t['id'], t)
res.append(t)
return res
@@ -694,6 +786,65 @@ class Movistar(object):
data = self.net.load_data(url, headers)
return data
def order_recording(self, program_id):
headers = self.net.headers.copy()
headers['Content-Type'] = 'application/json'
headers['X-Hzid'] = self.account['session_token']
url = self.endpoints['grabarprograma']
data = '{"tvProgramID":"' + str(program_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):
headers = self.net.headers.copy()
headers['Content-Type'] = 'application/json'
headers['X-Hzid'] = self.account['session_token']
url = self.endpoints['borrargrabacionindividual'].format(showId=program_id)
response = self.net.session.delete(url, headers=headers)
content = response.content.decode('utf-8')
try:
data = json.loads(content)
return data
except:
return None
def epg_to_movies(self, channel_id):
epg = self.get_epg()
res = []
for p in epg[channel_id]:
if sys.version_info[0] < 3:
p['date_str'] = unicode(p['date_str'], 'utf-8')
name = '[B]' + p['date_str'] + '[/B] ' + p['desc1']
if p['desc2']: name += ' - '+ p['desc2']
plot = name +"\n" + p['desc2']
t = {'info': {}, 'art': {}}
t['info']['title'] = name
t['info']['plot'] = plot
t['type'] = 'movie'
t['stream_type'] = 'u7d'
t['info']['mediatype'] = 'movie'
t['url'] = ''
t['id'] = p['show_id']
t['session_request'] = '{"contentID":' + str(t['id']) +',"streamType":"CUTV"}'
t['info']['playcount'] = 1 # Set as watched
t['start'] = p['start']
t['end'] = p['end']
t['aired'] = (p['end'] <= (time.time() * 1000))
t['subscribed'] = True # Fix me
if 'links' in p:
for link in p['links']:
if link['rel'] == 'start-over':
t['url'] = link['href']
if self.add_extra_info:
self.add_video_extra_info(t['id'], t, catalog='events')
res.append(t)
return res
def get_subtitles(self, manifest_url):
base_url = os.path.dirname(manifest_url)
content = self.net.load_url(manifest_url)
@@ -730,6 +881,7 @@ class Movistar(object):
sort = 'MA'
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'
url += '&mode=VOD' + filter
if cat == 'tvshows':
url += '&topic=SR&showSeries=series'
@@ -767,3 +919,19 @@ class Movistar(object):
def save_key_file(self, d):
data = {'timestamp': int(time.time()*1000), 'response': d}
self.cache.save_file('auth.key', json.dumps(data, ensure_ascii=False))
def get_profile_image_url(self, img_id):
content = self.cache.load_file('avatars.json')
if content:
data = json.loads(content)
else:
url = self.endpoints['avatares']
data = self.net.load_data(url)
self.cache.save_file('avatars.json', json.dumps(data, ensure_ascii=False))
#print_json(data)
for avatar in data:
if avatar['id'] == img_id:
for link in avatar['links']:
if link['sizes'] == '512x512':
return link['href']
return None
+87 -29
View File
@@ -33,19 +33,18 @@ _url = sys.argv[0]
# Get the plugin handle as an integer number.
_handle = int(sys.argv[1])
try: # Kodi >= 19
from xbmcvfs import translatePath
except ImportError: # Kodi 18
from xbmc import translatePath
def get_url(**kwargs):
for key, value in kwargs.items():
if isinstance(value, unicode):
kwargs[key] = value.encode('utf-8')
return '{0}?{1}'.format(_url, urlencode(kwargs))
def play(params):
LOG('play - params: {}'.format(params))
if not 'url' in params: return
if not 'url' in params:
show_notification(addon.getLocalizedString(30204))
return
url = params['url']
channel_id = params['id']
@@ -70,7 +69,7 @@ def play(params):
d = m.open_session(params['session_request'], session_token)
LOG('Open session: d: {}'.format(d))
if d['resultCode'] != 0:
dialog = xbmcgui.Dialog().notification('Error', d['resultText'], xbmcgui.NOTIFICATION_ERROR, 5000)
show_notification(d['resultText'])
return
if 'resultData' in d and 'cToken' in d['resultData']:
token = d['resultData']['cToken']
@@ -85,7 +84,11 @@ def play(params):
if stype in ['u7d', 'rec']:
d = m.get_u7d_url(url)
url = d['url']
if 'resultText' in d:
show_notification(d['resultText'])
return
else:
url = d['url']
proxy = m.cache.load_file('proxy.conf')
if addon.getSettingBool('manifest_modification') and proxy:
@@ -136,6 +139,9 @@ def play(params):
#play_item.setProperty('inputstream.adaptive.license_flags', 'persistent_storage')
#play_item.setProperty('inputstream.adaptive.license_flags', 'force_secure_decoder')
if stype == 'u7d':
play_item.setProperty('inputstream.adaptive.play_timeshift_buffer', 'true')
if sys.version_info[0] < 3:
play_item.setProperty('inputstreamaddon', 'inputstream.adaptive')
else:
@@ -214,20 +220,25 @@ def add_videos(category, ctype, videos, ref=None, url_next=None, url_prev=None):
#LOG("*** TEST t: {}".format(t))
if 'subscribed' in t:
if addon.getSettingBool('only_subscribed') and t['subscribed'] == False: continue
t['info']['title'] = m.colorize_title(t)
title_name = t['info']['title'].encode('utf-8')
t['info']['title'] = m.colorize_title(t)
title_name = t['info']['title']
if not 'type' in t: continue
if t['type'] == 'movie':
list_item = xbmcgui.ListItem(label = title_name)
#if t['stream_type'] == 'tv':
# action = get_url(action='epg', id=t['id'], name=t['name'].encode('utf-8'))
# LOG('action: {}'.format(action))
# list_item.addContextMenuItems([('EPG', "RunPlugin(" + action + ")")])
if t['url'] == '':
t['info']['title'] = '[COLOR gray]' + t['info']['title'] +'[/COLOR]'
#if t['url'] == '':
# t['info']['title'] = '[COLOR gray]' + t['info']['title'] +'[/COLOR]'
list_item.setProperty('IsPlayable', 'true')
list_item.setInfo('video', t['info'])
list_item.setArt(t['art'])
if t.get('stream_type') == 'u7d' and not t.get('aired', False):
record_program_action = (addon.getLocalizedString(30171), "RunPlugin(" + get_url(action='add_recording', id=t['id']) + ")")
list_item.addContextMenuItems([record_program_action])
if 'rec' in t:
action = get_url(action='delete_recording', id=t['rec']['id'], name=t['rec']['name'])
list_item.addContextMenuItems([(addon.getLocalizedString(30173), "RunPlugin(" + action + ")")])
url = get_url(action='play', id=t['id'], url=t['url'], session_request=t['session_request'], stype=t['stream_type'])
xbmcplugin.addDirectoryItem(_handle, url, list_item, False)
elif t['type'] == 'series':
@@ -314,24 +325,16 @@ def list_profiles(params):
name = p['name']
if p['id'] == m.account['profile_id']:
name = '[B][COLOR blue]' + name + '[/COLOR][/B]'
img_url = m.get_profile_image_url(p['image_id'])
art = {'icon': img_url} if img_url else None
select_action = get_url(action='profiles', id=p['id'], name='select')
add_menu_option(name, select_action)
add_menu_option(name, select_action, art=art)
close_folder(cacheToDisc=False)
def list_epg(params):
LOG('list_epg: {}'.format(params))
if 'id' in params:
epg = m.get_epg()
xbmcplugin.setPluginCategory(_handle, params['name'])
xbmcplugin.setContent(_handle, 'files')
for p in epg[params['id']]:
name = '[B]' + p['start_str'] + '[/B] ' + p['desc1']
if p['desc2']: name += ' - '+ p['desc2']
plot = name +"\n" + p['desc2']
list_item = xbmcgui.ListItem(label=name)
list_item.setInfo('video', {'name':name, 'plot':plot})
xbmcplugin.addDirectoryItem(_handle, '', list_item, False)
xbmcplugin.endOfDirectory(_handle)
add_videos(params['name'], 'movies', m.epg_to_movies(params['id']))
else:
channels = m.get_channels()
open_folder(addon.getLocalizedString(30107)) # EPG
@@ -369,6 +372,53 @@ def list_vod():
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='kids'))) # Kids
close_folder()
def search(params):
search_term = params.get('search_term', None)
if search_term:
if sys.version_info[0] < 3:
search_term = search_term.decode('utf-8')
if params.get('name', None) == 'delete':
m.delete_search(search_term)
xbmc.executebuiltin("Container.Refresh")
else:
url = m.get_search_url(search_term)
listing_hz(addon.getLocalizedString(30117), url)
return
if params.get('name', None) == 'new':
search_term = input_window(addon.getLocalizedString(30116)) # Search term
if search_term:
if sys.version_info[0] < 3:
search_term = search_term.decode('utf-8')
m.add_search(search_term)
xbmc.executebuiltin("Container.Refresh")
return
open_folder(addon.getLocalizedString(30113)) # Search
add_menu_option(addon.getLocalizedString(30113), get_url(action='search', name='new')) # New search
for i in m.search_list:
remove_action = get_url(action='search', search_term=i, name='delete')
cm = [(addon.getLocalizedString(30114), "RunPlugin(" + remove_action + ")")]
add_menu_option(i.encode('utf-8'), get_url(action='search', search_term=i), cm)
close_folder(cacheToDisc=False)
def order_recording(program_id):
data = m.order_recording(program_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):
if sys.version_info[0] < 3:
name = name.decode('utf-8')
res = xbmcgui.Dialog().yesno(addon.getLocalizedString(30173), addon.getLocalizedString(30174).format(name))
if res == True:
m.delete_recording(id)
xbmc.executebuiltin("Container.Refresh")
def clear_session():
m.cache.remove_file('access_token.conf')
m.cache.remove_file('account.json')
@@ -453,6 +503,10 @@ def router(paramstring):
logout()
elif params['action'] == 'epg':
list_epg(params)
elif params['action'] == 'add_recording':
order_recording(params['id'])
elif params['action'] == 'delete_recording':
delete_recording(params['id'], params['name'])
elif params['action'] == 'wishlist':
# Wishlist
listing_hz(addon.getLocalizedString(30102), m.get_wishlist_url())
@@ -469,6 +523,8 @@ def router(paramstring):
add_videos(params['name'], 'episodes', m.get_episodes(params['id']))
elif params['action'] == 'vod':
list_vod()
elif params['action'] == 'search':
search(params)
else:
# Main
open_folder(addon.getLocalizedString(30101)) # Menu
@@ -480,6 +536,7 @@ def router(paramstring):
add_menu_option(addon.getLocalizedString(30102), get_url(action='wishlist')) # My list
add_menu_option(addon.getLocalizedString(30103), get_url(action='recordings')) # Recordings
add_menu_option(addon.getLocalizedString(30111), get_url(action='vod')) # VOD
add_menu_option(addon.getLocalizedString(30112), get_url(action='search')) # Search
add_menu_option(addon.getLocalizedString(30180), get_url(action='profiles')) # Profiles
add_menu_option(addon.getLocalizedString(30108), get_url(action='devices')) # Devices
@@ -520,6 +577,7 @@ def run():
LOG('profile_dir: {}'.format(profile_dir))
LOG('reuse_devices: {}'.format(reuse_devices))
m = Movistar(profile_dir, reuse_devices=reuse_devices)
m.add_extra_info = addon.getSettingBool('add_extra_info')
global player
player = Player()
+23 -19
View File
@@ -5,27 +5,31 @@
from __future__ import unicode_literals, absolute_import, division
from datetime import datetime, timedelta
from datetime import datetime
import pytz
from dateutil import parser
def timestamp2str(timestamp):
weekdays = ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab']
def timestamp2str(timestamp, format='%H:%M'):
time = datetime.fromtimestamp(timestamp / 1000)
return time.strftime("%H:%M")
if '%a' in format:
w = int(time.strftime('%w'))
format = format.replace('%a', weekdays[w])
return time.strftime(format).capitalize()
def isodate2str(iso_str):
iso_str = iso_str[0:19]
def isodate2date(date_string):
date_object = parser.parse(date_string)
if date_object.tzinfo is None:
madrid_tz = pytz.timezone("Europe/Madrid")
madrid_time = madrid_tz.localize(date_object)
else:
madrid_time = date_object.astimezone(pytz.timezone("Europe/Madrid"))
return madrid_time
def isodate2str(date_string):
try:
dt = datetime.strptime(iso_str, "%Y-%m-%dT%H:%M:%S")
date_object = isodate2date(date_string)
return date_object.strftime("%d/%m/%Y %H:%M:%S")
except:
return iso_str
try:
import pytz
utc_tz = pytz.timezone('UTC')
dt = utc_tz.localize(dt)
dt = dt.astimezone(pytz.timezone('Europe/Madrid'))
except:
pass
dt = dt.strftime('%d/%m/%Y %H:%M:%S')
return dt
return date_string
+2 -2
View File
@@ -2,11 +2,11 @@
<category label="30001">
<setting label="30017" type="bool" id="only_subscribed" default="true"/>
<setting label="30020" type="bool" id="channels_with_epg" default="true"/>
<!-- <setting label="30021" type="bool" id="add_extra_info" default="true"/> -->
<setting label="30021" type="bool" id="add_extra_info" default="true"/>
<setting id="use_ttml2ssa" type="bool" label="$ADDON[script.module.ttml2ssa 32202]" default="false"/>
<setting id="ssa_settings" type="action" label="$ADDON[script.module.ttml2ssa 32201]" option="close" action="Addon.OpenSettings(script.module.ttml2ssa)" enable="eq(-1,true)"/>
<setting label="30019" type="action" id="is_settings" action="Addon.OpenSettings(inputstream.adaptive)" enable="System.HasAddon(inputstream.adaptive)" option="close"/>
<setting id="reuse_devices" type="bool" label="30023" default="false" visible="false"/>
<setting id="reuse_devices" type="bool" label="30023" default="false" visible="true"/>
<setting id="open_session" type="bool" label="30022" default="true" visible="true"/>
</category>
<category label="30002">