Version 0.5.20
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.5.14"
|
version="0.5.20"
|
||||||
provider-name="Paco8">
|
provider-name="Paco8">
|
||||||
<requires>
|
<requires>
|
||||||
<!--- <import addon="xbmc.python" version="2.25.0"/> -->
|
<!--- <import addon="xbmc.python" version="2.25.0"/> -->
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
<screenshot>resources/screen1.jpg</screenshot>
|
<screenshot>resources/screen1.jpg</screenshot>
|
||||||
<screenshot>resources/screen2.jpg</screenshot>
|
<screenshot>resources/screen2.jpg</screenshot>
|
||||||
<screenshot>resources/screen3.jpg</screenshot>
|
<screenshot>resources/screen3.jpg</screenshot>
|
||||||
|
<screenshot>resources/screen4.jpg</screenshot>
|
||||||
|
<screenshot>resources/screen5.jpg</screenshot>
|
||||||
</assets>
|
</assets>
|
||||||
</extension>
|
</extension>
|
||||||
</addon>
|
</addon>
|
||||||
@@ -272,3 +272,19 @@ msgstr ""
|
|||||||
msgctxt "#30204"
|
msgctxt "#30204"
|
||||||
msgid "Video not available"
|
msgid "Video not available"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#30300"
|
||||||
|
msgid "IPTV Manager"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#30301"
|
||||||
|
msgid "Install IPTV Manager add-on"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#30302"
|
||||||
|
msgid "Enable IPTV Manager integration"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgctxt "#30303"
|
||||||
|
msgid "IPTV Manager settings"
|
||||||
|
msgstr ""
|
||||||
@@ -272,3 +272,19 @@ msgstr "Formato no soportado"
|
|||||||
msgctxt "#30204"
|
msgctxt "#30204"
|
||||||
msgid "Video not available"
|
msgid "Video not available"
|
||||||
msgstr "Vídeo no disponible"
|
msgstr "Vídeo no disponible"
|
||||||
|
|
||||||
|
msgctxt "#30300"
|
||||||
|
msgid "IPTV Manager"
|
||||||
|
msgstr "IPTV Manager"
|
||||||
|
|
||||||
|
msgctxt "#30301"
|
||||||
|
msgid "Install IPTV Manager add-on"
|
||||||
|
msgstr "Instalar IPTV Manager"
|
||||||
|
|
||||||
|
msgctxt "#30302"
|
||||||
|
msgid "Enable IPTV Manager integration"
|
||||||
|
msgstr "Habilitar integración con IPTV Manager"
|
||||||
|
|
||||||
|
msgctxt "#30303"
|
||||||
|
msgid "IPTV Manager settings"
|
||||||
|
msgstr "Opciones de IPTV Manager"
|
||||||
@@ -48,3 +48,16 @@ class Cache(object):
|
|||||||
files.extend(glob.glob(self.config_directory + ext))
|
files.extend(glob.glob(self.config_directory + ext))
|
||||||
for filename in files:
|
for filename in files:
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
|
def clear_cache(self, days=10):
|
||||||
|
from datetime import datetime
|
||||||
|
deleted = 0
|
||||||
|
files = glob.glob(os.path.join(self.config_directory + 'cache', '*.json'))
|
||||||
|
now = datetime.now()
|
||||||
|
for filename in files:
|
||||||
|
modified_time = datetime.fromtimestamp(os.path.getmtime(filename))
|
||||||
|
time_diff = now - modified_time
|
||||||
|
if time_diff.days > days:
|
||||||
|
os.remove(filename)
|
||||||
|
deleted += 1
|
||||||
|
return deleted
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""IPTV Manager Integration module"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
from .movistar import Movistar
|
||||||
|
|
||||||
|
class IPTVManager:
|
||||||
|
"""Interface to IPTV Manager"""
|
||||||
|
|
||||||
|
def __init__(self, port):
|
||||||
|
"""Initialize IPTV Manager object"""
|
||||||
|
self.port = port
|
||||||
|
|
||||||
|
def via_socket(func):
|
||||||
|
"""Send the output of the wrapped function to socket"""
|
||||||
|
|
||||||
|
def send(self, m):
|
||||||
|
"""Decorator to send over a socket"""
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.connect(('127.0.0.1', self.port))
|
||||||
|
try:
|
||||||
|
sock.sendall(json.dumps(func(self, m)).encode())
|
||||||
|
finally:
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
return send
|
||||||
|
|
||||||
|
@via_socket
|
||||||
|
def send_channels(self, m):
|
||||||
|
"""Return JSON-STREAMS formatted python datastructure to IPTV Manager"""
|
||||||
|
return dict(version=1, streams=m.export_channels())
|
||||||
|
|
||||||
|
@via_socket
|
||||||
|
def send_epg(self, m):
|
||||||
|
"""Return JSON-EPG formatted python data structure to IPTV Manager"""
|
||||||
|
return dict(version=1, epg=m.export_epg())
|
||||||
@@ -11,6 +11,7 @@ import io
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from .log import LOG, print_json
|
from .log import LOG, print_json
|
||||||
from .network import Network
|
from .network import Network
|
||||||
@@ -48,6 +49,8 @@ class Movistar(object):
|
|||||||
|
|
||||||
# Cache
|
# Cache
|
||||||
self.cache = Cache(config_directory)
|
self.cache = Cache(config_directory)
|
||||||
|
if not os.path.exists(config_directory + 'cache'):
|
||||||
|
os.makedirs(config_directory + 'cache')
|
||||||
|
|
||||||
# Endpoints
|
# Endpoints
|
||||||
self.endpoints = self.get_endpoints()
|
self.endpoints = self.get_endpoints()
|
||||||
@@ -297,9 +300,10 @@ class Movistar(object):
|
|||||||
data = self.net.load_data(url, headers)
|
data = self.net.load_data(url, headers)
|
||||||
self.cache.save_file('devices.json', json.dumps(data, ensure_ascii=False))
|
self.cache.save_file('devices.json', json.dumps(data, ensure_ascii=False))
|
||||||
#print_json(data)
|
#print_json(data)
|
||||||
|
if not isinstance(data, list): return []
|
||||||
res = []
|
res = []
|
||||||
for d in data:
|
for d in data:
|
||||||
if d['Id'] != '-':
|
if d.get('Id') != '-':
|
||||||
dev = {}
|
dev = {}
|
||||||
dev['id'] = d['Id']
|
dev['id'] = d['Id']
|
||||||
dev['name'] = d['Name']
|
dev['name'] = d['Name']
|
||||||
@@ -436,7 +440,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 'links' in p: pr['links'] = p['links']
|
pr['id'] = p['Id']
|
||||||
|
#if 'links' in p: pr['links'] = p['links']
|
||||||
epg[id].append(pr)
|
epg[id].append(pr)
|
||||||
|
|
||||||
return epg
|
return epg
|
||||||
@@ -497,8 +502,9 @@ class Movistar(object):
|
|||||||
ch['desc2'] = desc2
|
ch['desc2'] = desc2
|
||||||
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:
|
if self.add_extra_info:
|
||||||
ch['art'] = {'poster': None, 'fanart': None}
|
ch['art']['poster'] = ch['art']['fanart'] = None
|
||||||
self.add_video_extra_info(programs[i]['show_id'], ch, catalog='events')
|
ch['show_id'] = programs[i]['show_id']
|
||||||
|
self.add_video_extra_info(ch)
|
||||||
if 'plot' in ch['info']:
|
if 'plot' in ch['info']:
|
||||||
plot = plot + ch['info']['plot']
|
plot = plot + ch['info']['plot']
|
||||||
break
|
break
|
||||||
@@ -541,6 +547,7 @@ class Movistar(object):
|
|||||||
t['stream_type'] = 'tv'
|
t['stream_type'] = 'tv'
|
||||||
t['info']['mediatype'] = 'movie'
|
t['info']['mediatype'] = 'movie'
|
||||||
t['info']['title'] = str(c['Dial']) +'. ' + c['Nombre']
|
t['info']['title'] = str(c['Dial']) +'. ' + c['Nombre']
|
||||||
|
t['channel_name'] = c['Nombre']
|
||||||
t['id'] = c['CodCadenaTv']
|
t['id'] = c['CodCadenaTv']
|
||||||
if add_epg_info:
|
if add_epg_info:
|
||||||
t['desc1'] = c['Nombre']
|
t['desc1'] = c['Nombre']
|
||||||
@@ -650,8 +657,9 @@ class Movistar(object):
|
|||||||
elif video['AssetType'] == 'NPVR':
|
elif video['AssetType'] == 'NPVR':
|
||||||
t['stream_type'] = 'rec'
|
t['stream_type'] = 'rec'
|
||||||
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"NPVR"}'
|
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"NPVR"}'
|
||||||
|
if 'ShowId' in video: t['show_id'] = video['ShowId']
|
||||||
if self.add_extra_info:
|
if self.add_extra_info:
|
||||||
self.add_video_extra_info(t['id'], t)
|
self.add_video_extra_info(t)
|
||||||
if 'Recording' in data:
|
if 'Recording' in data:
|
||||||
t['stream_type'] = 'rec'
|
t['stream_type'] = 'rec'
|
||||||
t['rec'] = {'id': data['Recording']['id'],
|
t['rec'] = {'id': data['Recording']['id'],
|
||||||
@@ -680,11 +688,49 @@ class Movistar(object):
|
|||||||
res.append(t)
|
res.append(t)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def add_video_extra_info(self, id, t, catalog=''):
|
def add_video_extra_info(self, t):
|
||||||
|
#LOG('add_video_extra_info: t: {}'.format(t))
|
||||||
try:
|
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='')
|
if 'show_id' in t:
|
||||||
#print(url)
|
catalog = 'events'
|
||||||
data = self.net.load_data(url)
|
id = t['show_id']
|
||||||
|
elif 'id' in t:
|
||||||
|
catalog = ''
|
||||||
|
id = t['id']
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
#LOG('id: {} catalog: {}'.format(id, catalog))
|
||||||
|
|
||||||
|
prefix = 'event' if catalog=='events' else 'info'
|
||||||
|
cache_filename = 'cache/{}_{}.json'.format(prefix, id)
|
||||||
|
content = self.cache.load(cache_filename, 30*24*60)
|
||||||
|
if content:
|
||||||
|
data = json.loads(content)
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
self.cache.save_file(cache_filename, json.dumps(data, ensure_ascii=False))
|
||||||
|
|
||||||
|
if not 'info' in t: t['info'] = {}
|
||||||
|
if not 'art' in t: t['art'] = {}
|
||||||
|
|
||||||
|
if not t['info'].get('title'):
|
||||||
|
if 'TituloEpisodio' in data:
|
||||||
|
t['info']['title'] = data['TituloEpisodio']
|
||||||
|
else:
|
||||||
|
t['info']['title'] = data['Titulo']
|
||||||
|
|
||||||
|
if 'Serie' in data:
|
||||||
|
if not t['info'].get('episode'): t['info']['episode'] = data['NumeroEpisodio']
|
||||||
|
if not t['info'].get('tvshowtitle'): t['info']['tvshowtitle'] = data['Serie']['TituloSerie']
|
||||||
|
if not t['info'].get('season') and data['Serie'].get('Temporada'):
|
||||||
|
m = re.search(r'T(\d+)', data['Serie']['Temporada'])
|
||||||
|
if m: t['info']['season'] = m.group(1)
|
||||||
|
|
||||||
|
if not 'duration' in t['info']:
|
||||||
|
t['info']['duration'] = data.get('Duracion', 0) * 60
|
||||||
|
|
||||||
if data.get('Sinopsis'):
|
if data.get('Sinopsis'):
|
||||||
t['info']['plot'] = data['Sinopsis']
|
t['info']['plot'] = data['Sinopsis']
|
||||||
if data.get('Actores'):
|
if data.get('Actores'):
|
||||||
@@ -774,7 +820,7 @@ class Movistar(object):
|
|||||||
t['stream_type'] = 'u7d'
|
t['stream_type'] = 'u7d'
|
||||||
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"CUTV"}'
|
t['session_request'] = '{"contentID":' + str(t['id']) + ', "streamType":"CUTV"}'
|
||||||
if self.add_extra_info:
|
if self.add_extra_info:
|
||||||
self.add_video_extra_info(t['id'], t)
|
self.add_video_extra_info(t)
|
||||||
res.append(t)
|
res.append(t)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@@ -829,19 +875,23 @@ class Movistar(object):
|
|||||||
t['stream_type'] = 'u7d'
|
t['stream_type'] = 'u7d'
|
||||||
t['info']['mediatype'] = 'movie'
|
t['info']['mediatype'] = 'movie'
|
||||||
t['url'] = ''
|
t['url'] = ''
|
||||||
t['id'] = p['show_id']
|
t['id'] = p['id']
|
||||||
|
t['show_id'] = p['show_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']
|
||||||
t['end'] = p['end']
|
t['end'] = p['end']
|
||||||
t['aired'] = (p['end'] <= (time.time() * 1000))
|
t['aired'] = (p['end'] <= (time.time() * 1000))
|
||||||
t['subscribed'] = True # Fix me
|
t['subscribed'] = True # Fix me
|
||||||
|
"""
|
||||||
if 'links' in p:
|
if 'links' in p:
|
||||||
for link in p['links']:
|
for link in p['links']:
|
||||||
if link['rel'] == 'start-over':
|
if link['rel'] == 'start-over':
|
||||||
t['url'] = link['href']
|
t['url'] = link['href']
|
||||||
|
"""
|
||||||
|
t['url'] = 'https://grmovistar.imagenio.telefonica.net/asfe/rest/tvMediaURLs?tvProgram.id='+ str(t['show_id']) +'&svc=startover'
|
||||||
if self.add_extra_info:
|
if self.add_extra_info:
|
||||||
self.add_video_extra_info(t['id'], t, catalog='events')
|
self.add_video_extra_info(t)
|
||||||
res.append(t)
|
res.append(t)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -935,3 +985,111 @@ class Movistar(object):
|
|||||||
if link['sizes'] == '512x512':
|
if link['sizes'] == '512x512':
|
||||||
return link['href']
|
return link['href']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def export_channels(self):
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
else:
|
||||||
|
from urllib import urlencode
|
||||||
|
channels = self.get_channels(False)
|
||||||
|
res = []
|
||||||
|
for c in channels:
|
||||||
|
if not c['subscribed']: continue
|
||||||
|
t = {}
|
||||||
|
t['name'] = c['channel_name']
|
||||||
|
t['id'] = c['id']
|
||||||
|
t['logo'] = c['art']['icon']
|
||||||
|
t['preset'] = c['dial']
|
||||||
|
args = urlencode({'action': 'play', 'stype': 'tv', 'id': c['id'], 'url': c['url'], 'session_request': c['session_request']})
|
||||||
|
t['stream'] = 'plugin://plugin.video.movistarplus/?' + args
|
||||||
|
res.append(t)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def export_channels_to_m3u8(self, filename):
|
||||||
|
channels = self.export_channels()
|
||||||
|
items = []
|
||||||
|
for t in channels:
|
||||||
|
item = '#EXTINF:-1 tvg-name="{name}" tvg-id="{id}" tvg-logo="{logo}" tvg-chno="{preset}" group-title="Movistar+" catchup="vod",{name}\n{stream}\n\n'.format(
|
||||||
|
name=t['name'], id=t['id'], logo=t['logo'], preset=t['preset'], stream=t['stream'])
|
||||||
|
items.append(item)
|
||||||
|
res = '#EXTM3U\n## Movistar+\n{}'.format(''.join(items))
|
||||||
|
with io.open(filename, 'w', encoding='utf-8', newline='') as handle:
|
||||||
|
handle.write(res)
|
||||||
|
|
||||||
|
def export_epg(self):
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
else:
|
||||||
|
from urllib import urlencode
|
||||||
|
now = time.time()*1000
|
||||||
|
res = {}
|
||||||
|
epg = self.get_epg()
|
||||||
|
channels = self.get_channels(False)
|
||||||
|
for channel in channels:
|
||||||
|
if not channel['subscribed']: continue
|
||||||
|
id = channel['id']
|
||||||
|
res[id] = []
|
||||||
|
for e in epg[id]:
|
||||||
|
t = {}
|
||||||
|
t['title'] = e['desc1']
|
||||||
|
t['subtitle'] = e['desc2']
|
||||||
|
t['start'] = datetime.utcfromtimestamp(e['start']/1000).strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
t['stop'] = datetime.utcfromtimestamp(e['end']/1000).strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
|
||||||
|
aired = (e['end'] <= now)
|
||||||
|
if aired:
|
||||||
|
program_id = str(e['show_id'])
|
||||||
|
url = 'https://grmovistar.imagenio.telefonica.net/asfe/rest/tvMediaURLs?tvProgram.id='+ program_id +'&svc=startover'
|
||||||
|
session_request = '{"contentID":' + program_id +',"streamType":"CUTV"}'
|
||||||
|
args = urlencode({'action': 'play', 'stype': 'u7d', 'id': program_id, 'url': url, 'session_request': session_request})
|
||||||
|
t['stream'] = 'plugin://plugin.video.movistarplus/?' + args
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self.add_extra_info and id in ['HOLLYW', 'TCM', 'AMC', 'MV3', 'MV2', 'CPSER', 'FOXGE', 'TNT']:
|
||||||
|
i = {'id': e['id'], 'show_id': e['show_id']}
|
||||||
|
self.add_video_extra_info(i)
|
||||||
|
#print(i)
|
||||||
|
t['description'] = i['info'].get('plot')
|
||||||
|
t['image'] = i['art'].get('poster')
|
||||||
|
t['credits'] = []
|
||||||
|
for text in i['info'].get('director', []):
|
||||||
|
t['credits'].append({'type': 'director', 'name': text})
|
||||||
|
for text in i['info'].get('cast', []):
|
||||||
|
t['credits'].append({'type': 'actor', 'name': text})
|
||||||
|
"""
|
||||||
|
|
||||||
|
res[id].append(t)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def export_epg_to_xml(self, filename):
|
||||||
|
channels = self.export_channels()
|
||||||
|
res = []
|
||||||
|
res.append('<?xml version="1.0" encoding="UTF-8"?>\n' +
|
||||||
|
'<!DOCTYPE tv SYSTEM "xmltv.dtd">\n' +
|
||||||
|
'<tv>\n')
|
||||||
|
|
||||||
|
for t in channels:
|
||||||
|
res.append('<channel id="{}">\n'.format(t['id']) +
|
||||||
|
' <display-name>{}</display-name>\n'.format(t['name']) +
|
||||||
|
' <icon src="{}"/>\n'.format(t['logo']) +
|
||||||
|
'</channel>\n')
|
||||||
|
|
||||||
|
epg = self.export_epg()
|
||||||
|
for ch in channels:
|
||||||
|
for e in epg[ch['id']]:
|
||||||
|
start = datetime.strptime(e['start'], "%Y-%m-%dT%H:%M:%SZ").strftime("%Y%m%d%H%M%S +0000")
|
||||||
|
stop = datetime.strptime(e['stop'], "%Y-%m-%dT%H:%M:%SZ").strftime("%Y%m%d%H%M%S +0000")
|
||||||
|
url = e.get('stream', None)
|
||||||
|
if url:
|
||||||
|
url = url.replace('&', '&')
|
||||||
|
res.append('<programme start="{}" stop="{}" channel="{}"'.format(start, stop, ch['id']) +
|
||||||
|
(' catchup-id="{}"'.format(url) if url else "") +
|
||||||
|
'>\n' +
|
||||||
|
' <title>{}</title>\n'.format(e['title']) +
|
||||||
|
' <sub-title>{}</sub-title>'.format(e['subtitle']) +
|
||||||
|
'</programme>\n')
|
||||||
|
|
||||||
|
res.append('</tv>\n')
|
||||||
|
with io.open(filename, 'w', encoding='utf-8', newline='') as handle:
|
||||||
|
handle.write(''.join(res))
|
||||||
|
|
||||||
@@ -148,6 +148,14 @@ def play(params):
|
|||||||
play_item.setMimeType('application/dash+xml')
|
play_item.setMimeType('application/dash+xml')
|
||||||
play_item.setContentLookup(False)
|
play_item.setContentLookup(False)
|
||||||
|
|
||||||
|
# Add info
|
||||||
|
if addon.getSettingBool('add_extra_info') and stype in ['vod', 'u7d', 'rec']:
|
||||||
|
t = {'id': params['id']}
|
||||||
|
if 'show_id' in params: t['show_id'] = params['show_id']
|
||||||
|
m.add_video_extra_info(t)
|
||||||
|
play_item.setInfo('video', t['info'])
|
||||||
|
play_item.setArt(t['art'])
|
||||||
|
|
||||||
# Subtitles
|
# Subtitles
|
||||||
if stype == 'vod' and addon.getSettingBool('use_ttml2ssa'):
|
if stype == 'vod' and addon.getSettingBool('use_ttml2ssa'):
|
||||||
# Convert subtitles
|
# Convert subtitles
|
||||||
@@ -238,6 +246,7 @@ def add_videos(category, ctype, videos, ref=None, url_next=None, url_prev=None):
|
|||||||
list_item.addContextMenuItems([(addon.getLocalizedString(30173), "RunPlugin(" + action + ")")])
|
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'])
|
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'])
|
||||||
xbmcplugin.addDirectoryItem(_handle, url, list_item, False)
|
xbmcplugin.addDirectoryItem(_handle, url, list_item, False)
|
||||||
elif t['type'] == 'series':
|
elif t['type'] == 'series':
|
||||||
list_item = xbmcgui.ListItem(label = title_name)
|
list_item = xbmcgui.ListItem(label = title_name)
|
||||||
@@ -466,6 +475,19 @@ def list_users():
|
|||||||
add_menu_option(addon.getLocalizedString(30150), get_url(action='logout')) # Close session
|
add_menu_option(addon.getLocalizedString(30150), get_url(action='logout')) # Close session
|
||||||
close_folder()
|
close_folder()
|
||||||
|
|
||||||
|
def iptv(params):
|
||||||
|
LOG('iptv: params: {}'.format(params))
|
||||||
|
if m.logged:
|
||||||
|
try:
|
||||||
|
from .iptvmanager import IPTVManager
|
||||||
|
port = int(params['port'])
|
||||||
|
if params['action'] == 'iptv-channels':
|
||||||
|
IPTVManager(port).send_channels(m)
|
||||||
|
elif params['action'] == 'iptv-epg':
|
||||||
|
IPTVManager(port).send_epg(m)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def router(paramstring):
|
def router(paramstring):
|
||||||
"""
|
"""
|
||||||
Router function that calls other functions
|
Router function that calls other functions
|
||||||
@@ -523,6 +545,8 @@ def router(paramstring):
|
|||||||
list_vod()
|
list_vod()
|
||||||
elif params['action'] == 'search':
|
elif params['action'] == 'search':
|
||||||
search(params)
|
search(params)
|
||||||
|
elif 'iptv' in params['action']:
|
||||||
|
iptv(params)
|
||||||
else:
|
else:
|
||||||
# Main
|
# Main
|
||||||
open_folder(addon.getLocalizedString(30101)) # Menu
|
open_folder(addon.getLocalizedString(30101)) # Menu
|
||||||
@@ -582,9 +606,15 @@ def run():
|
|||||||
if profile_id in ['OTT', 'NODTH']:
|
if profile_id in ['OTT', 'NODTH']:
|
||||||
m.account['platform'] = addon.getSetting('profile_id')
|
m.account['platform'] = addon.getSetting('profile_id')
|
||||||
|
|
||||||
|
# Clear cache
|
||||||
|
LOG('Cleaning cache. {} files removed.'.format(m.cache.clear_cache()))
|
||||||
|
|
||||||
global player
|
global player
|
||||||
player = Player()
|
player = Player()
|
||||||
|
|
||||||
# Call the router function and pass the plugin call parameters to it.
|
# Call the router function and pass the plugin call parameters to it.
|
||||||
# We use string slicing to trim the leading '?' from the plugin call paramstring
|
# We use string slicing to trim the leading '?' from the plugin call paramstring
|
||||||
router(sys.argv[2][1:])
|
params = sys.argv[2][1:]
|
||||||
|
if '/iptv/channels' in sys.argv[0]: params += '&action=iptv-channels'
|
||||||
|
elif '/iptv/epg' in sys.argv[0]: params += '&action=iptv-epg'
|
||||||
|
router(params)
|
||||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 148 KiB |
@@ -4,7 +4,7 @@
|
|||||||
<setting label="30020" type="bool" id="channels_with_epg" 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="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 id="ssa_settings" type="action" label="$ADDON[script.module.ttml2ssa 32201]" option="close" action="Addon.OpenSettings(script.module.ttml2ssa)" enable="eq(-1,true)" subsetting="true"/>
|
||||||
<setting label="30019" type="action" id="is_settings" action="Addon.OpenSettings(inputstream.adaptive)" enable="System.HasAddon(inputstream.adaptive)" option="close"/>
|
<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="true"/>
|
<setting id="reuse_devices" type="bool" label="30023" default="false" visible="true"/>
|
||||||
<setting id="open_session" type="bool" label="30022" default="true" visible="true"/>
|
<setting id="open_session" type="bool" label="30022" default="true" visible="true"/>
|
||||||
@@ -14,12 +14,19 @@
|
|||||||
<category label="30002">
|
<category label="30002">
|
||||||
<setting label="30011" type="bool" id="manifest_modification" default="true"/>
|
<setting label="30011" type="bool" id="manifest_modification" default="true"/>
|
||||||
<setting label="30012" type="bool" id="use_proxy_for_license" default="true"/>
|
<setting label="30012" type="bool" id="use_proxy_for_license" default="true"/>
|
||||||
<setting id="reregister" type="bool" label="30024" default="true" enable="eq(-1,true)"/>
|
<setting id="reregister" type="bool" label="30024" default="true" enable="eq(-1,true)" subsetting="true"/>
|
||||||
</category>
|
</category>
|
||||||
<!--
|
<!--
|
||||||
<category label="30003">
|
<category label="30003">
|
||||||
<setting label="30010" type="labelenum" id="drm_type" values="Widevine|Playready"/>
|
<setting label="30010" type="labelenum" id="drm_type" values="Widevine|Playready"/>
|
||||||
</category>
|
</category>
|
||||||
-->
|
-->
|
||||||
|
<category label="30300">
|
||||||
|
<setting label="30301" type="action" action="InstallAddon(service.iptv.manager)" option="close" visible="!System.HasAddon(service.iptv.manager)"/>
|
||||||
|
<setting label="30302" type="bool" id="iptv.enabled" default="true" visible="System.HasAddon(service.iptv.manager)" />
|
||||||
|
<setting label="30303" type="action" action="Addon.OpenSettings(service.iptv.manager)" enable="eq(-1,true)" option="close" visible="System.HasAddon(service.iptv.manager)" subsetting="true"/>
|
||||||
|
<setting id="iptv.channels_uri" default="plugin://plugin.video.movistarplus/iptv/channels" visible="false"/>
|
||||||
|
<setting id="iptv.epg_uri" default="plugin://plugin.video.movistarplus/iptv/epg" visible="false"/>
|
||||||
|
</category>
|
||||||
</settings>
|
</settings>
|
||||||
|
|
||||||