- The TV guide setup always wrote instance-settings-91.xml, so on a box already set up with another instance (from the original add-on) both read channels.m3u8 and every channel showed twice. The setup now rewrites the instance that already reads the list, and the service deletes extra ones at start (keeps the one that isn't 91, which holds what was watched) and restarts IPTV Simple when nothing plays. - The web player registration for the new servers got one 401 error page and gave up, and the TV guide list then lacked LALIGA, DAZN LALIGA and Liga de Campeones until the next export 6 hours later. The registration is tried 3 times, and after a failure the service exports the list again every half hour, up to 6 times. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1007 lines
39 KiB
Python
1007 lines
39 KiB
Python
# encoding: utf-8
|
|
#
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
from __future__ import unicode_literals, absolute_import, division
|
|
|
|
import sys
|
|
import json
|
|
import io
|
|
import os.path
|
|
from datetime import datetime, timedelta
|
|
from .timeconv import isodate2date
|
|
|
|
import xbmc
|
|
import xbmcgui
|
|
import xbmcplugin
|
|
import xbmcaddon
|
|
|
|
if sys.version_info[0] >= 3:
|
|
import urllib.request as urllib2
|
|
from urllib.parse import urlencode, parse_qsl, quote_plus
|
|
unicode = str
|
|
else:
|
|
import urllib2
|
|
from urllib import urlencode, quote_plus
|
|
from urlparse import parse_qsl
|
|
|
|
from .log import LOG
|
|
from .movistar import *
|
|
from .addon import *
|
|
from .gui import *
|
|
from .useragent import useragent
|
|
|
|
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.
|
|
_handle = int(sys.argv[1])
|
|
|
|
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:
|
|
show_notification(addon.getLocalizedString(30204))
|
|
return
|
|
|
|
url = params['url']
|
|
channel_id = params['id']
|
|
stype = params['stype']
|
|
|
|
token = m.account['ssp_token']
|
|
|
|
import inputstreamhelper
|
|
is_helper = inputstreamhelper.Helper('mpd', drm='com.widevine.alpha')
|
|
if not is_helper.check_inputstream():
|
|
show_notification(addon.getLocalizedString(30202))
|
|
return
|
|
|
|
"""
|
|
if addon.getSettingBool('reregister'):
|
|
m.unregister_device()
|
|
m.register_device()
|
|
"""
|
|
|
|
session_opened = False
|
|
if addon.getSettingBool('open_session') or stype == 'vod':
|
|
d = m.open_session(params['session_request'])
|
|
session_opened = True
|
|
LOG('Open session: d: {}'.format(d))
|
|
if d['resultCode'] != 0:
|
|
show_notification(d['resultText'])
|
|
return
|
|
if 'resultData' in d and 'cToken' in d['resultData']:
|
|
token = d['resultData']['cToken']
|
|
|
|
if stype == 'vod':
|
|
d = m.delete_session()
|
|
session_opened = False
|
|
LOG('Delete session: d: {}'.format(d))
|
|
|
|
LOG("token: {}".format(token))
|
|
|
|
if stype in ['u7d', 'rec']:
|
|
d = m.get_u7d_url(url)
|
|
if 'resultText' in d:
|
|
show_notification(d['resultText'])
|
|
return
|
|
else:
|
|
url = d['url']
|
|
#if True:
|
|
# url = url.replace('DASH_WPC_WIDEVINE', 'DASH_TV_WIDEVINE')
|
|
|
|
# U7D from start and end times
|
|
#if stype == 'tv' and all(param in params for param in ['cas_id', 'start_time', 'end_time']):
|
|
# start = datetime.utcfromtimestamp(int(params['start_time']))
|
|
# end = datetime.utcfromtimestamp(int(params['end_time']))
|
|
# catchup_url = 'https://stover-wp0.cdn.telefonica.com/{cas_id}/vxfmt=dp/Manifest.mpd?device_profile=DASH_TV_WIDEVINE&start_time={start_time}&end_time={end_time}'
|
|
# url = catchup_url.format(cas_id=params['cas_id'], start_time=start.strftime('%Y-%m-%dT%H:%M:%SZ'), end_time=end.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
# LOG('url from capchup: {}'.format(url))
|
|
|
|
|
|
# Read the proxy address
|
|
proxy = addon.getSetting('proxy_address')
|
|
LOG('proxy address: {}'.format(proxy))
|
|
|
|
if addon.getSettingBool('manifest_modification') and proxy:
|
|
url = '{}/?manifest={}'.format(proxy, url)
|
|
|
|
LOG("url: {}".format(url))
|
|
|
|
headers = 'Content-Type=application/octet-stream'
|
|
headers += '&User-Agent=' + useragent
|
|
headers += '&Accept=*/*&Accept-Language=es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3'
|
|
headers += '&Referer=https://ver.movistarplus.es/'
|
|
headers += '&Origin=https://ver.movistarplus.es'
|
|
#headers += '&Host=wv-ottlic-f3.imagenio.telefonica.net'
|
|
manifest_headers = 'User-Agent=' + useragent
|
|
|
|
if params.get('new_api') == '1':
|
|
# LALIGA, DAZN LALIGA, Liga de Campeones: their streams only open with a
|
|
# CDN token from the new servers. The player keeps the token it starts
|
|
# with, so it must have hours left.
|
|
from . import kodimov
|
|
try:
|
|
cdn_token = kodimov.new_api_cdn_token(m, min_life=3 * 3600)
|
|
except Exception as e:
|
|
LOG('new_api_cdn_token failed: {}'.format(e))
|
|
show_notification(addon.getLocalizedString(30510).format(e))
|
|
return
|
|
manifest_headers += '&x-tcdn-token=' + cdn_token
|
|
elif True: #stype in ['tv', 'u7d', 'rec']:
|
|
cdn_token = m.cache.load('cdn.conf', 60)
|
|
if not cdn_token:
|
|
cdn_token = m.get_cdntoken()
|
|
if not cdn_token:
|
|
time.sleep(2)
|
|
cdn_token = m.get_cdntoken()
|
|
if cdn_token:
|
|
m.cache.save_file('cdn.conf', cdn_token)
|
|
else:
|
|
show_notification('Ha pasado algo')
|
|
return
|
|
#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'
|
|
certificate = (
|
|
'CsECCAMSEBcFuRfMEgSGiwYzOi93KowYgrSCkgUijgIwggEKAoIBAQCZ7Vs7Mn2rXiTvw7YqlbWY'
|
|
'UgrVvMs3UD4GRbgU2Ha430BRBEGtjOOtsRu4jE5yWl5KngeVKR1YWEAjp+GvDjipEnk5MAhhC28V'
|
|
'jIeMfiG/+/7qd+EBnh5XgeikX0YmPRTmDoBYqGB63OBPrIRXsTeo1nzN6zNwXZg6IftO7L1KEMpH'
|
|
'SQykfqpdQ4IY3brxyt4zkvE9b/tkQv0x4b9AsMYE0cS6TJUgpL+X7r1gkpr87vVbuvVk4tDnbNfF'
|
|
'XHOggrmWEguDWe3OJHBwgmgNb2fG2CxKxfMTRJCnTuw3r0svAQxZ6ChD4lgvC2ufXbD8Xm7fZPvT'
|
|
'CLRxG88SUAGcn1oJAgMBAAE6FGxpY2Vuc2Uud2lkZXZpbmUuY29tEoADrjRzFLWoNSl/JxOI+3u4'
|
|
'y1J30kmCPN3R2jC5MzlRHrPMveoEuUS5J8EhNG79verJ1BORfm7BdqEEOEYKUDvBlSubpOTOD8S/'
|
|
'wgqYCKqvS/zRnB3PzfV0zKwo0bQQQWz53ogEMBy9szTK/NDUCXhCOmQuVGE98K/PlspKkknYVeQr'
|
|
'OnA+8XZ/apvTbWv4K+drvwy6T95Z0qvMdv62Qke4XEMfvKUiZrYZ/DaXlUP8qcu9u/r6DhpV51Wj'
|
|
'x7zmVflkb1gquc9wqgi5efhn9joLK3/bNixbxOzVVdhbyqnFk8ODyFfUnaq3fkC3hR3f0kmYgI41'
|
|
'sljnXXjqwMoW9wRzBMINk+3k6P8cbxfmJD4/Paj8FwmHDsRfuoI6Jj8M76H3CTsZCZKDJjM3BQQ6'
|
|
'Kb2m+bQ0LMjfVDyxoRgvfF//M/EEkPrKWyU2C3YBXpxaBquO4C8A0ujVmGEEqsxN1HX9lu6c5OMm'
|
|
'8huDxwWFd7OHMs3avGpr7RP7DUnTikXrh6X0')
|
|
|
|
play_item = xbmcgui.ListItem(path= url)
|
|
license_type = 'com.widevine.alpha'
|
|
license_key = ''
|
|
|
|
if format(addon.getSetting('drm_type')) == 'Playready':
|
|
license_type = 'com.microsoft.playready'
|
|
|
|
if addon.getSettingBool('use_proxy_for_license') and proxy:
|
|
request_id = str(int(time.time()*1000))
|
|
license_key = '{}/license?token={}&stype={}&session_request={}&request_id={}'.format(proxy, quote_plus(token), stype, quote_plus(params['session_request']), request_id)
|
|
LOG('license_key: {}'.format(license_key))
|
|
else:
|
|
license_key = license_url
|
|
headers += '&nv-authorizations={}'.format(token)
|
|
|
|
if kodi_version > 20:
|
|
play_item.setProperty('inputstream.adaptive.drm_legacy', '{}|{}|{}'.format(license_type, license_key, headers))
|
|
else:
|
|
play_item.setProperty('inputstream.adaptive.license_type', license_type)
|
|
play_item.setProperty('inputstream.adaptive.license_key', '{}|{}|R{{SSM}}|'.format(license_key, headers))
|
|
play_item.setProperty('inputstream.adaptive.manifest_type', 'mpd')
|
|
#play_item.setProperty('inputstream.adaptive.manifest_type', 'hls')
|
|
|
|
if addon.getSettingBool('best_quality'):
|
|
# Left to itself, InputStream Adaptive starts these streams at 576p and
|
|
# never gets to the 720p/1080p versions (they use a different key)
|
|
best = '4K' if addon.getSettingBool('uhd') else '1080p'
|
|
play_item.setProperty('inputstream.adaptive.stream_selection_type', 'fixed-res')
|
|
play_item.setProperty('inputstream.adaptive.chooser_resolution_max', best)
|
|
play_item.setProperty('inputstream.adaptive.chooser_resolution_secure_max', best)
|
|
|
|
play_item.setProperty('inputstream.adaptive.stream_headers', manifest_headers)
|
|
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')
|
|
|
|
if stype == 'u7d':
|
|
play_item.setProperty('inputstream.adaptive.play_timeshift_buffer', 'true')
|
|
|
|
if kodi_version < 19:
|
|
play_item.setProperty('inputstreamaddon', 'inputstream.adaptive')
|
|
else:
|
|
play_item.setProperty('inputstream', 'inputstream.adaptive')
|
|
|
|
play_item.setMimeType('application/dash+xml')
|
|
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
|
|
if stype == 'vod' and addon.getSettingBool('use_ttml2ssa'):
|
|
# Convert subtitles
|
|
from ttml2ssa import Ttml2SsaAddon
|
|
ttml = Ttml2SsaAddon()
|
|
#ttml.use_language_filter = False
|
|
subtype = ttml.subtitle_type()
|
|
|
|
subfolder = os.path.join(profile_dir, 'subtitles')
|
|
if not os.path.exists(subfolder):
|
|
os.makedirs(subfolder)
|
|
|
|
sublist = m.get_subtitles(params['url'])
|
|
LOG('sublist: {}'.format(sublist))
|
|
subpaths = []
|
|
for sub in sublist:
|
|
filename = os.path.join(subfolder, sub['lang'])
|
|
LOG('Converting {}'.format(sub['filename']))
|
|
subheaders = m.net.headers.copy()
|
|
subheaders['x-tcdn-token'] = cdn_token
|
|
response = m.net.session.get(sub['url'], allow_redirects=True, headers=subheaders)
|
|
content = response.content
|
|
with io.open(filename + '.ttml', 'w', encoding='utf-8', newline='') as handle:
|
|
handle.write(content.decode('utf-8'))
|
|
ttml.parse_ttml_from_string(content)
|
|
if subtype != 'srt':
|
|
filename_ssa = filename + '.ssa'
|
|
ttml.write2file(filename_ssa)
|
|
subpaths.append(filename_ssa)
|
|
if subtype != 'ssa':
|
|
filename_srt = filename
|
|
if (subtype == 'both'): filename_srt += '.SRT'
|
|
filename_srt += '.srt'
|
|
ttml.write2file(filename_srt)
|
|
subpaths.append(filename_srt)
|
|
play_item.setSubtitles(subpaths)
|
|
|
|
#if True:
|
|
# m.unregister_device()
|
|
# m.register_device()
|
|
|
|
xbmcplugin.setResolvedUrl(_handle, True, listitem=play_item)
|
|
|
|
LOG('**** session_opened: {}'.format(session_opened))
|
|
watermarks = []
|
|
if stype == 'tv' and 'uid' in params:
|
|
watermarks = m.get_watermarks(params['uid'])
|
|
LOG('watermarks: {}'.format(watermarks))
|
|
|
|
if session_opened or watermarks:
|
|
window = xbmcgui.Window(12005)
|
|
label = xbmcgui.ControlLabel(0, 0, 400, 20, m.account['id'], textColor='0xFFFFFFFF', alignment=6)
|
|
from .player import MyPlayer
|
|
player = MyPlayer()
|
|
monitor = xbmc.Monitor()
|
|
while not monitor.abortRequested() and player.running:
|
|
monitor.waitForAbort(10)
|
|
#LOG('**** waiting')
|
|
if player.isPlaying() and watermarks:
|
|
now = isodate2date(datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
for wm in list(watermarks):
|
|
start = isodate2date(wm['start'])
|
|
stop = isodate2date(wm['stop'])
|
|
if now >= start:
|
|
watermarks.remove(wm)
|
|
if now < stop:
|
|
duration = (stop - start).total_seconds()
|
|
#show_notification(m.account['id'], xbmcgui.NOTIFICATION_INFO)
|
|
w = window.getWidth()
|
|
h = window.getHeight()
|
|
#LOG('window h: {} w: {}'.format(h, w))
|
|
pos_x = w-label.getWidth()-60
|
|
pos_y = h-200
|
|
label.setPosition(pos_x, pos_y)
|
|
window.addControl(label)
|
|
time.sleep(duration)
|
|
window.removeControl(label)
|
|
if session_opened:
|
|
d = m.delete_session()
|
|
LOG('Delete session: d: {}'.format(d))
|
|
LOG('Playback finished')
|
|
|
|
|
|
def add_videos(category, ctype, videos, ref=None, url_next=None, url_prev=None, from_wishlist=False):
|
|
#LOG("category: {} ctype: {}".format(category, ctype))
|
|
xbmcplugin.setPluginCategory(_handle, category)
|
|
xbmcplugin.setContent(_handle, ctype)
|
|
|
|
if ctype == 'movies' or ctype == 'seasons':
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_UNSORTED)
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_LABEL)
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_TITLE)
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_VIDEO_YEAR)
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_GENRE)
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_LASTPLAYED)
|
|
if ctype == 'episodes':
|
|
xbmcplugin.addSortMethod(_handle, xbmcplugin.SORT_METHOD_EPISODE)
|
|
|
|
"""
|
|
if url_prev:
|
|
list_item = xbmcgui.ListItem(label = addon.getLocalizedString(30110)) # Previous page
|
|
xbmcplugin.addDirectoryItem(_handle, get_url(action=ref, url=url_prev, name=category), list_item, True)
|
|
"""
|
|
|
|
for t in videos:
|
|
#LOG("t: {}".format(t))
|
|
if 'subscribed' in t:
|
|
if addon.getSettingBool('only_subscribed') and t['subscribed'] == False: continue
|
|
t['info']['title'] = m.colorize_title(t)
|
|
|
|
if 'availability' in t:
|
|
ends = int(t['availability'].get('end', '0'))
|
|
if ends > 0:
|
|
now = int(time.time()*1000)
|
|
n_hours = int((ends - now) / (1000 * 60 * 60))
|
|
n_days = int(n_hours / 24)
|
|
if (n_days <= addon.getSettingInt('expdays')):
|
|
if n_days < 1:
|
|
t['info']['title'] += ' [COLOR red](' + addon.getLocalizedString(30401).format(n_hours) + ')[/COLOR]'
|
|
else:
|
|
t['info']['title'] += ' [COLOR red](' + addon.getLocalizedString(30400).format(n_days) + ')[/COLOR]'
|
|
|
|
title_name = t['info']['title']
|
|
if not 'type' in t: continue
|
|
|
|
wishlist_action = None
|
|
if t['type'] in ['movie', 'series', 'season']:
|
|
id = t['id']
|
|
stype = 'vod'
|
|
possible_to_add = False
|
|
|
|
if from_wishlist:
|
|
# Remove from wishlist
|
|
if 'favorite_data' in t:
|
|
if 'favorites2' in t['favorite_data']:
|
|
id = t['favorite_data']['favorites2']['id']
|
|
stype = t['favorite_data']['favorites2']['family']
|
|
possible_to_add = True
|
|
elif t['type'] == 'season' and 'favorites2.season' in t['favorite_data']:
|
|
id = t['favorite_data']['favorites2.season']['id']
|
|
stype = t['favorite_data']['favorites2.season']['family']
|
|
possible_to_add = True
|
|
else:
|
|
# Add to wishlist
|
|
if t['type'] in ['series', 'season']:
|
|
possible_to_add = t.get('seguible', False)
|
|
|
|
if t['type'] == 'movie':
|
|
if t.get('stream_type') == 'vod':
|
|
possible_to_add = t['url'] != ''
|
|
if 'show_id' in t:
|
|
possible_to_add = t['url'] != ''
|
|
stype = 'tv'
|
|
id = t['show_id']
|
|
|
|
if possible_to_add:
|
|
if not from_wishlist:
|
|
op = 'add'
|
|
message = 30175
|
|
else:
|
|
op = 'delete'
|
|
message = 30176
|
|
wishlist_action = (addon.getLocalizedString(message), "RunPlugin(" + get_url(action='to_wishlist', id=id, op=op, stype=stype) + ")")
|
|
|
|
if t['type'] == 'movie':
|
|
list_item = xbmcgui.ListItem(label = title_name)
|
|
#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'])
|
|
|
|
actions = []
|
|
if t.get('stream_type') == 'u7d':
|
|
#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:
|
|
action = get_url(action='delete_recording', id=t['rec']['id'], name=t['rec']['name'])
|
|
actions.append((addon.getLocalizedString(30173), "RunPlugin(" + action + ")"))
|
|
|
|
if 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'])
|
|
if t.get('new_api'): url += '&new_api=1'
|
|
if 'show_id' in t: url += '&show_id={}'.format(t['show_id'])
|
|
if 'uid' in t: url += '&uid={}'.format(t['uid'])
|
|
xbmcplugin.addDirectoryItem(_handle, url, list_item, False)
|
|
elif t['type'] == 'series':
|
|
list_item = xbmcgui.ListItem(label = title_name)
|
|
list_item.setInfo('video', t['info'])
|
|
list_item.setArt(t['art'])
|
|
if wishlist_action:
|
|
list_item.addContextMenuItems([wishlist_action])
|
|
xbmcplugin.addDirectoryItem(_handle, get_url(action='series', id=t['id'], name=title_name), list_item, True)
|
|
elif t['type'] == 'season':
|
|
list_item = xbmcgui.ListItem(label = title_name)
|
|
list_item.setInfo('video', t['info'])
|
|
list_item.setArt(t['art'])
|
|
if wishlist_action:
|
|
list_item.addContextMenuItems([wishlist_action])
|
|
xbmcplugin.addDirectoryItem(_handle, get_url(action='season', id=t['id'], name=title_name), list_item, True)
|
|
elif t['type'] == 'category':
|
|
list_item = xbmcgui.ListItem(label = title_name)
|
|
#list_item.setInfo('video', t['info'])
|
|
#list_item.setArt(t['art'])
|
|
xbmcplugin.addDirectoryItem(_handle, get_url(action='category', id=t['id'], name=title_name), list_item, True)
|
|
|
|
if url_next:
|
|
list_item = xbmcgui.ListItem(label = addon.getLocalizedString(30109)) # Next page
|
|
xbmcplugin.addDirectoryItem(_handle, get_url(action=ref, url=url_next, from_wishlist=from_wishlist, name=category), list_item, True)
|
|
|
|
xbmcplugin.endOfDirectory(_handle)
|
|
|
|
def list_devices(params):
|
|
LOG('list_devices: params: {}'.format(params))
|
|
|
|
devices = m.get_devices()
|
|
|
|
if 'id' in params:
|
|
if params['name'] == 'select':
|
|
LOG('Selecting device {}'.format(params['id']))
|
|
m.change_device(params['id'])
|
|
elif params['name'] == 'close':
|
|
LOG('Closing session {}'.format(params['id']))
|
|
m.delete_session(params['id'])
|
|
elif params['name'] == 'delete':
|
|
LOG('Removing device {}'.format(params['id']))
|
|
m.delete_device(params['id'])
|
|
if params['id'] == m.account['device_id']:
|
|
LOG('Registering device')
|
|
m.register_device()
|
|
|
|
xbmc.executebuiltin("Container.Refresh")
|
|
return
|
|
|
|
open_folder(addon.getLocalizedString(30108)) # Devices
|
|
|
|
for d in devices:
|
|
name = d['name'] +' - '+ d['type'] + ' (' + d['reg_date'] + ')'
|
|
if d['playing']: name += ' [' + d['playing'] + ']'
|
|
name += ' ['+ d['id'][:5] +']'
|
|
if d['id'] == m.account['device_id']:
|
|
name = '[B][COLOR blue]' + name + '[/COLOR][/B]'
|
|
|
|
select_action = get_url(action='devices', id=d['id'], name='select')
|
|
close_action = get_url(action='devices', id=d['id'], name='close')
|
|
remove_action = get_url(action='devices', id=d['id'], name='delete')
|
|
cm = [(addon.getLocalizedString(30150), "RunPlugin(" + close_action + ")"),
|
|
(addon.getLocalizedString(30151), "RunPlugin(" + remove_action + ")")]
|
|
if d['type_code'] == 'WP':
|
|
cm.insert(0, (addon.getLocalizedString(30152), "RunPlugin(" + select_action + ")"))
|
|
default_action = select_action
|
|
else:
|
|
default_action = close_action
|
|
add_menu_option(name, default_action, cm)
|
|
|
|
close_folder(cacheToDisc=False)
|
|
|
|
def list_profiles(params):
|
|
LOG('list_profiles: params: {}'.format(params))
|
|
|
|
profiles = m.get_profiles()
|
|
|
|
if 'id' in params:
|
|
if params['name'] == 'select':
|
|
LOG('Selecting profile {}'.format(params['id']))
|
|
m.change_profile(params['id'])
|
|
xbmc.executebuiltin("Container.Refresh")
|
|
return
|
|
|
|
open_folder(addon.getLocalizedString(30180)) # Profiles
|
|
for p in profiles:
|
|
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, art=art)
|
|
close_folder(cacheToDisc=False)
|
|
|
|
def list_epg(params):
|
|
LOG('list_epg: {}'.format(params))
|
|
from .timeconv import my_strftime
|
|
if 'id' in params:
|
|
if not 'date' in params:
|
|
today = datetime.today()
|
|
for i in range(6, 0, -1):
|
|
past_date = today - timedelta(days=i)
|
|
date = past_date.strftime('%Y-%m-%dT00:00:00')
|
|
display_str = my_strftime(past_date, '%a %d')
|
|
add_menu_option(display_str, get_url(action='epg', id=params['id'], name=params['name'], date=date))
|
|
add_videos(params['name'], 'movies', m.epg_to_movies(params['id'], params.get('date'), duration=1))
|
|
else:
|
|
channels = m.get_channels()
|
|
open_folder(addon.getLocalizedString(30107)) # EPG
|
|
for t in channels:
|
|
name = t['info']['title']
|
|
add_menu_option(name, get_url(action='epg', id=t['id'], name=name.encode('utf-8')), art=t['art'])
|
|
close_folder()
|
|
|
|
def listing(name, url):
|
|
data = m.download_list(url, use_hz=False)
|
|
l = []
|
|
url_next = None
|
|
url_prev = None
|
|
if 'Contenidos' in data:
|
|
l = m.get_list(data['Contenidos'])
|
|
url_next = data['next']['href'] if isinstance(data['next'], dict) and 'href' 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')
|
|
|
|
def listing_hz(name, url, from_wishlist=False):
|
|
data = m.download_list(url, use_hz=True)
|
|
l = []
|
|
url_next = None
|
|
url_prev = None
|
|
if 'Contenidos' in data:
|
|
l = m.get_list(data['Contenidos'])
|
|
url_next = data['next']['href'] if isinstance(data['next'], dict) and 'href' 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)
|
|
|
|
def list_vod0():
|
|
open_folder(addon.getLocalizedString(30111)) # VOD
|
|
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
|
|
|
|
name = addon.getLocalizedString(30106).encode('utf-8')
|
|
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='tvshows'))) # TV Shows
|
|
|
|
name = addon.getLocalizedString(30120).encode('utf-8')
|
|
add_menu_option(name, get_url(action='listing', name=name, url=m.get_vod_list_url(cat='documentaries'))) # Documentaries
|
|
|
|
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
|
|
|
|
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()
|
|
|
|
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 reversed(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 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):
|
|
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.delete_session_files()
|
|
|
|
def logout():
|
|
clear_session()
|
|
m.cache.remove_file('auth.key')
|
|
|
|
def login():
|
|
def ask_credentials(username='', password=''):
|
|
username = input_window(addon.getLocalizedString(30163), username) # Username
|
|
if username:
|
|
password = input_window(addon.getLocalizedString(30164), password, hidden=True) # Password
|
|
if password:
|
|
return username, password
|
|
return None, None
|
|
|
|
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 store_credentials:
|
|
m.save_credentials(username, password)
|
|
success, _ = m.login(username, password)
|
|
if success:
|
|
clear_session()
|
|
else:
|
|
show_notification(addon.getLocalizedString(30166)) # Failed
|
|
|
|
def network_login():
|
|
# The account number and the device are found/registered automatically.
|
|
account_number = addon.getSetting('account_number')
|
|
# Keeps device_id.conf: clearing the session would register a new device.
|
|
if m.try_network_login(account_number, force=True):
|
|
show_notification(addon.getLocalizedString(30503), xbmcgui.NOTIFICATION_INFO) # Logged in
|
|
xbmc.executebuiltin('Container.Refresh')
|
|
else:
|
|
reason = (m.network_login_result or (False, ''))[1]
|
|
show_notification(addon.getLocalizedString(30504).format(reason)) # Failed
|
|
|
|
def login_with_key():
|
|
filename = xbmcgui.Dialog().browseSingle(1, addon.getLocalizedString(30182), '', '.key')
|
|
if filename:
|
|
m.install_key_file(filename)
|
|
clear_session()
|
|
|
|
def export_key():
|
|
directory = xbmcgui.Dialog().browseSingle(0, addon.getLocalizedString(30185), '')
|
|
if directory:
|
|
m.export_key_file(directory + 'movistarplus.key')
|
|
|
|
def import_credentials():
|
|
filename = xbmcgui.Dialog().browseSingle(1, addon.getLocalizedString(30193), '', '.json')
|
|
if filename:
|
|
m.import_credentials(filename)
|
|
|
|
def export_credentials():
|
|
directory = xbmcgui.Dialog().browseSingle(0, addon.getLocalizedString(30194), '')
|
|
if directory:
|
|
m.export_credentials(os.path.join(directory, 'credenciales.json'))
|
|
|
|
def select_account(id, name):
|
|
m.switch_account(id)
|
|
open_folder(name)
|
|
add_menu_option(addon.getLocalizedString(30501), get_url(action='network_login')) # Login from home network
|
|
add_menu_option(addon.getLocalizedString(30183), get_url(action='login')) # Login with username
|
|
if addon.getSettingBool('enable_key_login'):
|
|
add_menu_option(addon.getLocalizedString(30181), get_url(action='login_with_key')) # Login with key
|
|
if os.path.exists(os.path.join(m.cache.config_directory, 'auth.key')):
|
|
add_menu_option(addon.getLocalizedString(30184), get_url(action='export_key')) # Export key
|
|
add_menu_option(addon.getLocalizedString(30150), get_url(action='logout')) # Close session
|
|
add_menu_option(addon.getLocalizedString(30196), get_url(action='import_credentials'))
|
|
if os.path.exists(os.path.join(m.cache.config_directory, 'credentials.json')):
|
|
add_menu_option(addon.getLocalizedString(30195), get_url(action='export_credentials'))
|
|
close_folder(cacheToDisc=False)
|
|
|
|
def list_accounts(params):
|
|
LOG('list_accounts: {}'.format(params))
|
|
|
|
if params.get('name') == 'new_account':
|
|
m.create_new_account()
|
|
|
|
accounts = m.get_accounts()
|
|
open_folder(addon.getLocalizedString(30160)) # Accounts
|
|
for account in accounts:
|
|
name = account['name']
|
|
login = account.get('login')
|
|
if login:
|
|
name += ' ({})'.format(login)
|
|
if account['id'] == m.account_dir:
|
|
display_name = '[B][COLOR blue]' + name + '[/COLOR][/B]'
|
|
else:
|
|
display_name = name
|
|
add_menu_option(display_name, get_url(action='select_account', id=account['id'], name=name))
|
|
add_menu_option(addon.getLocalizedString(30161), get_url(action='accounts', name='new_account')) # Add new
|
|
close_folder(cacheToDisc=False)
|
|
|
|
if params.get('name') == 'new_account':
|
|
xbmc.executebuiltin('Container.Update({},replace)'.format(xbmc.getInfoLabel('Container.FolderPath')))
|
|
|
|
def iptv(params):
|
|
LOG('iptv: params: {}'.format(params))
|
|
if m.logged:
|
|
#try:
|
|
if True:
|
|
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 create_iptv_settings():
|
|
from .iptv import save_iptv_settings
|
|
from . import kodimov
|
|
show_notification(addon.getLocalizedString(30319), xbmcgui.NOTIFICATION_INFO)
|
|
output_file = 'instance-settings-91.xml' if kodi_version > 19 else 'settings.xml'
|
|
epg_url = None
|
|
if False: #addon.getSettingBool('use_external_epg'):
|
|
epg_url = addon.getSetting('epg_url')
|
|
try:
|
|
pvr_addon = xbmcaddon.Addon('pvr.iptvsimple')
|
|
pvr_dir = translatePath(pvr_addon.getAddonInfo('profile'))
|
|
LOG('pvr_dir: {}'.format(pvr_dir))
|
|
filename = os.path.join(pvr_dir, output_file)
|
|
if kodi_version > 19:
|
|
# Rewrite the instance that already reads this add-on's list, if any:
|
|
# a second one would show every channel twice
|
|
existing = kodimov.iptv_instance_files(pvr_dir, 'kodimovplus')
|
|
if existing: filename = existing[0]
|
|
if os.path.exists(filename):
|
|
res = xbmcgui.Dialog().yesno(addon.getLocalizedString(30322), addon.getLocalizedString(30323))
|
|
if res == False: return
|
|
# Write the channel list and the programme guide first: if IPTV Simple
|
|
# starts before epg.xml exists, Kodi stores an empty guide for every
|
|
# channel and doesn't ask again for hours.
|
|
export_epg_now()
|
|
if not os.path.exists(os.path.join(profile_dir, 'epg.xml')):
|
|
show_notification(addon.getLocalizedString(30509)) # Log in first
|
|
return
|
|
save_iptv_settings(filename, 'KodiMov+', 'kodimovplus', epg_url)
|
|
# IPTV Simple now reads epg.xml, so the service must keep it up to date.
|
|
addon.setSettingBool('auto_export_epg', True)
|
|
# Restart IPTV Simple so it loads the new instance and channel list.
|
|
kodimov.restart_iptv_simple()
|
|
# Show Movistar's own channel numbers instead of 1, 2, 3... Kodi only
|
|
# accepts it once IPTV Simple is back; the service keeps trying otherwise.
|
|
numbers_set = os.path.join(profile_dir, 'numbers-set')
|
|
if os.path.exists(numbers_set): os.remove(numbers_set)
|
|
for _ in range(5):
|
|
if kodimov.ensure_channel_numbers(numbers_set): break
|
|
xbmc.sleep(2000)
|
|
except:
|
|
show_notification(addon.getLocalizedString(30324))
|
|
|
|
def export_channels_now():
|
|
if not m.logged: return
|
|
channels_filename = os.path.join(profile_dir, 'channels.m3u8')
|
|
if m.export_channels_to_m3u8(channels_filename, addon.getSettingBool('only_subscribed')):
|
|
LOG('export_channels_now: channel list changed')
|
|
|
|
def export_epg_now(quiet=False, reload_guide=False):
|
|
# quiet: background refresh from the service, no pop-ups while watching TV
|
|
def notify(message):
|
|
if not quiet: show_notification(message, xbmcgui.NOTIFICATION_INFO)
|
|
def report_progress(message):
|
|
notify(addon.getLocalizedString(30314).format(message))
|
|
|
|
if not m.logged: return
|
|
|
|
only_subscribed = addon.getSettingBool('only_subscribed')
|
|
channels_filename = os.path.join(profile_dir, 'channels.m3u8')
|
|
epg_filename = os.path.join(profile_dir, 'epg.xml')
|
|
notify(addon.getLocalizedString(30310))
|
|
m.export_channels_to_m3u8(channels_filename, only_subscribed)
|
|
|
|
if True: #not addon.getSettingBool('use_external_epg'):
|
|
notify(addon.getLocalizedString(30311))
|
|
changed = m.export_epg_to_xml(epg_filename, addon.getSettingInt('export_days'), report_progress, only_subscribed)
|
|
if changed and reload_guide:
|
|
from . import kodimov
|
|
try:
|
|
pvr_dir = translatePath(xbmcaddon.Addon('pvr.iptvsimple').getAddonInfo('profile'))
|
|
except RuntimeError: # IPTV Simple not installed or disabled
|
|
pvr_dir = None
|
|
if pvr_dir: kodimov.reload_iptv_guide(pvr_dir, 'kodimovplus')
|
|
|
|
notify(addon.getLocalizedString(30313))
|
|
|
|
|
|
def to_wishlist(params):
|
|
stype = params['stype']
|
|
if params['op'] == 'add':
|
|
retcode, message = m.add_to_wishlist(params['id'], stype)
|
|
else:
|
|
retcode, message = m.delete_from_wishlist(params['id'], stype)
|
|
if retcode in [201, 204]:
|
|
message = 30177 if params['op'] == 'add' else 30178
|
|
show_notification(addon.getLocalizedString(message), xbmcgui.NOTIFICATION_INFO)
|
|
if params['op'] == 'delete':
|
|
xbmc.executebuiltin("Container.Refresh")
|
|
else:
|
|
show_notification(str(retcode) +': '+ message)
|
|
|
|
|
|
def router(paramstring):
|
|
"""
|
|
Router function that calls other functions
|
|
depending on the provided paramstring
|
|
:param paramstring: URL encoded plugin paramstring
|
|
:type paramstring: str
|
|
"""
|
|
|
|
params = dict(parse_qsl(paramstring))
|
|
LOG('params: {}'.format(params))
|
|
if params:
|
|
if params['action'] == 'play':
|
|
play(params)
|
|
elif params['action'] == 'tv':
|
|
if addon.getSettingBool('channels_with_epg'):
|
|
channels = m.get_channels_with_epg()
|
|
else:
|
|
channels = m.get_channels()
|
|
add_videos(addon.getLocalizedString(30104), 'movies', channels)
|
|
elif params['action'] == 'devices':
|
|
list_devices(params)
|
|
elif params['action'] == 'profiles':
|
|
list_profiles(params)
|
|
elif params['action'] == 'login_with_key':
|
|
login_with_key()
|
|
elif params['action'] == 'login':
|
|
login()
|
|
elif params['action'] == 'network_login':
|
|
network_login()
|
|
elif params['action'] == 'export_channels_now':
|
|
export_channels_now()
|
|
elif params['action'] == 'new_api_keep_warm':
|
|
if m.logged:
|
|
from . import kodimov
|
|
kodimov.new_api_keep_warm(m)
|
|
elif params['action'] == 'export_key':
|
|
export_key()
|
|
elif params['action'] == 'export_credentials':
|
|
export_credentials()
|
|
elif params['action'] == 'import_credentials':
|
|
import_credentials()
|
|
elif params['action'] == 'select_account':
|
|
select_account(params['id'], params['name'])
|
|
elif params['action'] == 'accounts':
|
|
list_accounts(params)
|
|
elif params['action'] == 'logout':
|
|
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'] == 'add_recording_season':
|
|
order_recording_season(params['id'])
|
|
elif params['action'] == 'wishlist':
|
|
# Wishlist
|
|
listing_hz(addon.getLocalizedString(30102), m.get_wishlist_url(), from_wishlist=True)
|
|
elif params['action'] == 'continue-watching':
|
|
listing_hz(addon.getLocalizedString(30102), m.get_viewings_url())
|
|
elif params['action'] == 'recordings':
|
|
# Recordings
|
|
listing_hz(addon.getLocalizedString(30103), m.get_recordings_url())
|
|
elif params['action'] == 'listing':
|
|
listing(params['name'], params['url'])
|
|
elif params['action'] == 'listing_hz':
|
|
listing_hz(params['name'], params['url'], params.get('from_wishlist'))
|
|
elif params['action'] == 'series':
|
|
add_videos(params['name'], 'seasons', m.get_seasons(params['id']))
|
|
elif params['action'] == 'season':
|
|
add_videos(params['name'], 'episodes', m.get_episodes(params['id']))
|
|
elif params['action'] == 'vod':
|
|
list_vod()
|
|
elif params['action'] == 'list_section':
|
|
list_section(params['key'])
|
|
elif params['action'] == 'search':
|
|
search(params)
|
|
elif params['action'] == 'create_iptv_settings':
|
|
create_iptv_settings()
|
|
elif params['action'] == 'export_epg_now':
|
|
export_epg_now(quiet=params.get('quiet') == '1', reload_guide=params.get('reload_guide') == '1')
|
|
elif params['action'] == 'to_wishlist':
|
|
to_wishlist(params)
|
|
elif 'iptv' in params['action']:
|
|
iptv(params)
|
|
else:
|
|
# Main
|
|
open_folder(addon.getLocalizedString(30101)) # Menu
|
|
|
|
if m.logged:
|
|
add_menu_option(addon.getLocalizedString(30104), get_url(action='tv'), icon='tv.png') # TV
|
|
add_menu_option(addon.getLocalizedString(30107), get_url(action='epg'), icon='epg.png') # EGP
|
|
add_menu_option(addon.getLocalizedString(30102), get_url(action='wishlist'), icon='mylist.png') # My list
|
|
add_menu_option(addon.getLocalizedString(30103), get_url(action='recordings'), icon='recording.png') # Recordings
|
|
add_menu_option(addon.getLocalizedString(30122), get_url(action='continue-watching'), icon='continue.png') # Continue
|
|
add_menu_option(addon.getLocalizedString(30111), get_url(action='vod'), icon='vod.png') # VOD
|
|
add_menu_option(addon.getLocalizedString(30112), get_url(action='search'), icon='search.png') # Search
|
|
add_menu_option(addon.getLocalizedString(30180), get_url(action='profiles'), icon='profiles.png') # Profiles
|
|
add_menu_option(addon.getLocalizedString(30108), get_url(action='devices'), icon='devices.png') # Devices
|
|
else:
|
|
if m.expired_access_token:
|
|
show_notification(addon.getLocalizedString(30208))
|
|
add_menu_option(addon.getLocalizedString(30501), get_url(action='network_login'), icon='account.png') # Login from home network
|
|
|
|
add_menu_option(addon.getLocalizedString(30160), get_url(action='accounts'), icon='account.png') # Accounts
|
|
add_menu_option(addon.getLocalizedString(30450), get_url(action='show_donation_dialog'), icon='qr.png') # Donation
|
|
close_folder(cacheToDisc=False)
|
|
|
|
|
|
def run():
|
|
# 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
|
|
params = sys.argv[2][1:]
|
|
|
|
if 'show_donation_dialog' in params:
|
|
from .customdialog import show_donation_dialog
|
|
show_donation_dialog()
|
|
return
|
|
|
|
global m
|
|
reuse_devices = addon.getSettingBool('reuse_devices')
|
|
LOG('profile_dir: {}'.format(profile_dir))
|
|
LOG('reuse_devices: {}'.format(reuse_devices))
|
|
m = Movistar(profile_dir, reuse_devices=reuse_devices,
|
|
network_login=addon.getSettingBool('network_login'),
|
|
account_number=addon.getSetting('account_number'))
|
|
m.add_extra_info = addon.getSettingBool('add_extra_info')
|
|
m.hide_unplayable = addon.getSettingBool('hide_unplayable')
|
|
m.add_extra_channels = addon.getSettingBool('extra_channels')
|
|
if addon.getSettingBool('uhd'):
|
|
m.quality = 'UHD'
|
|
|
|
profile_id = addon.getSetting('profile_id').upper()
|
|
LOG('profile_id: {}'.format(profile_id))
|
|
if profile_id not in ['', 'AUTO']:
|
|
m.account['platform'] = profile_id
|
|
|
|
# Clear cache
|
|
LOG('Cleaning cache. {} files removed.'.format(m.cache.clear_cache()))
|
|
|
|
if '/iptv/channels' in sys.argv[0]: params += '&action=iptv-channels'
|
|
elif '/iptv/epg' in sys.argv[0]: params += '&action=iptv-epg'
|
|
router(params)
|