Fix Discovery +
This commit is contained in:
+154
-131
@@ -4,198 +4,221 @@
|
|||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
import requests
|
import requests, uuid
|
||||||
from core import support, httptools
|
from core import jsontools, support, httptools
|
||||||
from platformcode import logger, config
|
from platformcode import logger
|
||||||
|
|
||||||
|
|
||||||
typo = support.typo
|
typo = support.typo
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.request = functools.partial(session.request, timeout=httptools.HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT)
|
session.request = functools.partial(session.request, timeout=httptools.HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT)
|
||||||
host = support.config.get_channel_url()
|
host = support.config.get_channel_url()
|
||||||
|
deviceId = uuid.uuid4().hex
|
||||||
|
|
||||||
token = session.get('https://disco-api.discoveryplus.it/token?realm=dplayit').json()['data']['attributes']['token']
|
domain = 'https://eu1-prod-direct.discoveryplus.com'
|
||||||
|
token = session.get(f'{domain}/token?deviceId={deviceId}&realm=dplay&shortlived=true').json()['data']['attributes']['token']
|
||||||
api = "https://disco-api.discoveryplus.it"
|
session.headers = {'User-Agent': 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0',
|
||||||
headers = {'User-Agent': 'Mozilla/50.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0',
|
|
||||||
'Referer': host,
|
'Referer': host,
|
||||||
'Cookie' : 'st=' + token}
|
'Origin': host,
|
||||||
|
'Cookie': f'st={token}',
|
||||||
def Dict(item):
|
'content-type': 'application/json',
|
||||||
global pdict
|
'x-disco-params': 'realm=dplay,siteLookupKey=dplus_it'}
|
||||||
pdict = session.get(api + '/cms/routes/{}?decorators=viewingHistory&include=default'.format(item.args), headers=headers).json()['included']
|
|
||||||
|
|
||||||
|
|
||||||
@support.menu
|
@support.menu
|
||||||
def mainlist(item):
|
def mainlist(item):
|
||||||
top = [('Dirette {bold}', ['', 'live']),
|
top = [('Dirette {bold}', ['', 'live']),
|
||||||
('Programmi {bullet bold tv}', ['', 'peliculas', 'programmi']),
|
('Programmi {bullet bold tv}', ['', 'programs', 'programmi'])]
|
||||||
('Generi {bullet bold tv}', ['', 'genres'])]
|
|
||||||
|
|
||||||
search = ''
|
search = ''
|
||||||
|
|
||||||
return locals()
|
return locals()
|
||||||
|
|
||||||
|
|
||||||
def liveDict():
|
|
||||||
livedict = {}
|
|
||||||
|
|
||||||
for key in session.get(api + '/cms/routes/canali?decorators=viewingHistory&include=default', headers=headers).json()['included']:
|
|
||||||
|
|
||||||
if key['type'] == 'channel' and key.get('attributes',{}).get('hasLiveStream', '') and 'Free' in key.get('attributes',{}).get('packages', []):
|
|
||||||
title = key['attributes']['name']
|
|
||||||
livedict[title] = {}
|
|
||||||
livedict[title]['plot'] = key['attributes']['description']
|
|
||||||
livedict[title]['url'] = '{}/canali/{}'.format(host, key['attributes']['alternateId'])
|
|
||||||
livedict[title]['id'] = key['id']
|
|
||||||
return livedict
|
|
||||||
|
|
||||||
|
|
||||||
def search(item, text):
|
def search(item, text):
|
||||||
itemlist = []
|
itemlist = []
|
||||||
item.args = 'search'
|
|
||||||
item.text = text
|
item.text = text
|
||||||
|
|
||||||
try:
|
try:
|
||||||
itemlist = peliculas(item)
|
itemlist = peliculas(item)
|
||||||
except:
|
except:
|
||||||
import sys
|
import sys
|
||||||
for line in sys.exc_info():
|
for line in sys.exc_info():
|
||||||
support.logger.error("%s" % line)
|
logger.error(line)
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def live(item):
|
def live(item):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
|
|
||||||
itemlist =[]
|
itemlist =[]
|
||||||
for name, values in liveDict().items():
|
data = session.get(f'{domain}/cms/routes/epg?include=default').json()['included']
|
||||||
itemlist.append(item.clone(title=typo(name,'bold'), fulltitle=name, plot=values['plot'], url=values['url'], id=values['id'], action='findvideos', forcethumb=True, no_return=True))
|
|
||||||
|
for key in data:
|
||||||
|
|
||||||
|
if key['type'] == 'channel' and key.get('attributes',{}).get('hasLiveStream', '') and 'Free' in key.get('attributes',{}).get('packages', []):
|
||||||
|
itemlist.append(item.clone(title = typo(key['attributes']['name'], 'bold'),
|
||||||
|
fulltitle = key['attributes']['name'],
|
||||||
|
plot = key['attributes'].get('description', ''),
|
||||||
|
url = f"{host}/canali/{key['attributes']['alternateId']}",
|
||||||
|
id = key['id'],
|
||||||
|
action = 'findvideos'))
|
||||||
return support.thumb(itemlist, live=True)
|
return support.thumb(itemlist, live=True)
|
||||||
|
|
||||||
|
|
||||||
|
def programs(item):
|
||||||
|
logger.debug()
|
||||||
|
|
||||||
|
itemlist = []
|
||||||
|
data = session.get(f'{domain}/cms/routes/browse?include=default').json()['included']
|
||||||
|
images = {key['id'] : key['attributes']['src'] for key in data if key['type'] == 'image'}
|
||||||
|
|
||||||
|
channels = {}
|
||||||
|
for key in data:
|
||||||
|
if key['type'] == 'link' and 'Free' in key['attributes']['packages']:
|
||||||
|
logger.debug(jsontools.dump(key))
|
||||||
|
_title = key['attributes'].get('title', key['attributes'].get('name',''))
|
||||||
|
_id = key['relationships']['linkedContent']['data']['id']
|
||||||
|
_thumb = images.get(key['relationships'].get('images', {}).get('data',[{}])[0].get('id'))
|
||||||
|
channels[_title] ={'id':_id, 'thumb':_thumb}
|
||||||
|
|
||||||
|
itemlist = [item.clone(title='Tutti', id=channels['Tutti']['id'], action='peliculas'),
|
||||||
|
item.clone(title='Generi', id=channels['Tutti']['id'], action='genres'),
|
||||||
|
item.clone(title='Per canale', channels=channels, action='channels')]
|
||||||
|
|
||||||
|
return support.thumb(itemlist)
|
||||||
|
|
||||||
|
|
||||||
def genres(item):
|
def genres(item):
|
||||||
item.action = 'peliculas'
|
logger.debug()
|
||||||
itemlist = [
|
|
||||||
item.clone(title='Attualità e inchiesta', args='genere/attualita-e-inchiesta'),
|
itemlist = []
|
||||||
item.clone(title='Beauty and style', args='genere/beauty-and-style'),
|
data = session.get(f'{domain}/cms/collections/{item.id}?include=default').json()['included']
|
||||||
item.clone(title='Serie TV', args='genere/serie-tv'),
|
collection = {k['id']: k['relationships'].get('show', k['relationships'].get('collection'))['data']['id'] for k in data if k['type'] == 'collectionItem'}
|
||||||
item.clone(title='Casa', args='genere/casa'),
|
|
||||||
item.clone(title='Comedy', args='genere/comedy'),
|
included = {}
|
||||||
item.clone(title='Crime', args='genere/crime'),
|
for key in data:
|
||||||
item.clone(title='Documentari', args='genere/documentari'),
|
if key.get('relationships', {}).get('items') and key['type'] == 'collection' and key['attributes']['title'] not in ['A-Z', 'I più visti']:
|
||||||
# item.clone(title='Discovery + Originals', args='genere/discoveryplus-original'),
|
included[key['attributes']['title']] = [k['id'] for k in key['relationships']['items']['data']]
|
||||||
item.clone(title='Food', args='genere/food'),
|
|
||||||
item.clone(title='Medical', args='genere/medical'),
|
for title, values in included.items():
|
||||||
item.clone(title='Motori', args='genere/motori'),
|
itemlist.append(item.clone(title=title, action='peliculas', filter=[collection[k] for k in values]))
|
||||||
item.clone(title='Natura', args='genere/natura'),
|
|
||||||
item.clone(title='Paranormal', args='genere/paranormal'),
|
itemlist.sort(key=lambda it: it.title)
|
||||||
item.clone(title='People', args='genere/people'),
|
|
||||||
item.clone(title='Real Adventure', args='genere/real-adventure'),
|
return support.thumb(itemlist, genre=True)
|
||||||
item.clone(title='Real Life', args='genere/real-life'),
|
|
||||||
item.clone(title='Scienza e Spazio', args='genere/scienza-e-spazio'),
|
|
||||||
item.clone(title='Sex and love', args='genere/sex-and-love'),
|
def channels(item):
|
||||||
item.clone(title='Sport', args='genere/sport'),
|
logger.debug()
|
||||||
item.clone(title='Talent Show', args='genere/talent-show'),
|
|
||||||
]
|
itemlist = [item.clone(title=k, id=v['id'], thumbnail=v['thumb'], action='peliculas') for k, v in item.channels.items() if k !='Tutti']
|
||||||
|
itemlist.sort(key=lambda it: it.title)
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def peliculas(item):
|
def peliculas(item):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
itemlist =[]
|
|
||||||
if 'search' in item.args:
|
|
||||||
pdict = session.get('{}/content/shows?include=genres,images,primaryChannel.images,contentPackages&page[size]=12&query={}'.format(api, item.text), headers=headers).json()['data']
|
|
||||||
else:
|
|
||||||
pdict = session.get('{}/cms/routes/{}?decorators=viewingHistory&include=default'.format(api, item.args), headers=headers).json()['included']
|
|
||||||
images = list(filter(lambda x: x['type'] == 'image', pdict))
|
|
||||||
|
|
||||||
for key in pdict:
|
itemlist =[]
|
||||||
if key['type'] == 'show' and 'Free' in str(key.get('relationships',{}).get('contentPackages',{}).get('data',[])):
|
|
||||||
title = key['attributes']['name']
|
if item.text:
|
||||||
plot = key['attributes'].get('description','')
|
data = session.get(f'{domain}/cms/routes/search/result?include=default&contentFilter[query]={item.text}').json()['included']
|
||||||
url = '{}/programmi/{}'.format(host, key['attributes']['alternateId'])
|
else:
|
||||||
seasons = key['attributes']['seasonNumbers']
|
data = session.get(f'{domain}/cms/collections/{item.id}?include=default').json()['included']
|
||||||
thumbs = [image['attributes']['src'] for image in images if image['id'] == key['relationships']['images']['data'][0]['id']]
|
|
||||||
thumb = thumbs[0] if thumbs else item.thumbnail
|
images = {key['id'] : key['attributes']['src'] for key in data if key['type'] == 'image'}
|
||||||
fanarts = [image['attributes']['src'] for image in images if len(key['relationships']['images']['data']) > 1 and image['id'] == key['relationships']['images']['data'][1]['id']]
|
|
||||||
fanart = fanarts[0] if fanarts else item.fanart
|
for key in data:
|
||||||
|
if key['type'] == 'show' and 'Free' in str(key.get('relationships',{}).get('contentPackages',{}).get('data',[])) and key['attributes']['episodeCount']:
|
||||||
|
|
||||||
|
if item.filter and key['id'] not in item.filter:
|
||||||
|
continue
|
||||||
|
|
||||||
|
thumbId = key['relationships'].get('images',{}).get('data', [{},{},{}])[2].get('id', '')
|
||||||
|
fanartId = key['relationships'].get('images',{}).get('data', [{}])[0].get('id', '')
|
||||||
itemlist.append(
|
itemlist.append(
|
||||||
item.clone(title=typo(title,'bold'),
|
item.clone(title=typo(key['attributes']['name'],'bold'),
|
||||||
fulltitle=title,
|
plot=key['attributes'].get('description',''),
|
||||||
plot=plot,
|
|
||||||
url=url,
|
|
||||||
programid=key['attributes']['alternateId'],
|
programid=key['attributes']['alternateId'],
|
||||||
id=key['id'],
|
seasons=key['attributes']['seasonNumbers'],
|
||||||
seasons=seasons,
|
action='seasons',
|
||||||
action='episodios',
|
thumbnail=images[thumbId] if thumbId else item.thumbnail,
|
||||||
thumbnail=thumb,
|
fanart=images[fanartId] if fanartId else item.fanart,
|
||||||
fanart=fanart,
|
|
||||||
contentType='tvshow'))
|
contentType='tvshow'))
|
||||||
|
|
||||||
|
itemlist.sort(key=lambda it: it.title)
|
||||||
|
|
||||||
|
if not itemlist:
|
||||||
|
from core.item import Item
|
||||||
|
itemlist = [Item(title='Nessun Contenuto Free Disponibile', thumbnail=support.thumb('info'))]
|
||||||
|
|
||||||
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
|
def seasons(item):
|
||||||
|
logger.debug()
|
||||||
|
|
||||||
|
itemlist = []
|
||||||
|
data = session.get(f'{domain}/cms/routes/show/{item.programid}?include=default').json()['included']
|
||||||
|
|
||||||
|
for key in data:
|
||||||
|
if key['type'] == 'collection':
|
||||||
|
for option in key['attributes']['component']['filters'][0]['options']:
|
||||||
|
itemlist.append(item.clone(title=f"Stagione {option['value']}",
|
||||||
|
season=int(option['value']),
|
||||||
|
seasonparams=option['parameter'],
|
||||||
|
showparams=key['attributes']['component']['mandatoryParams'],
|
||||||
|
id=key['id'],
|
||||||
|
contentType='season',
|
||||||
|
action='episodios'))
|
||||||
|
break
|
||||||
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def episodios(item):
|
def episodios(item):
|
||||||
logger.debug()
|
logger.debug()
|
||||||
|
|
||||||
itemlist =[]
|
itemlist =[]
|
||||||
pdict = session.get(api + '/cms/routes/programmi/{}?decorators=viewingHistory&include=default'.format(item.programid), headers=headers).json()['included']
|
data = session.get(f'{domain}/cms/collections/{item.id}?include=default&{item.seasonparams}&{item.showparams}').json()['included']
|
||||||
|
images = {key['id'] : key['attributes']['src'] for key in data if key['type'] == 'image'}
|
||||||
|
|
||||||
for key in pdict:
|
for key in data:
|
||||||
if key['type'] == 'collection' and key.get('attributes',{}).get('component',{}).get('id', '') == 'tabbed-content':
|
if key['type'] == 'video' and 'Free' in str(key.get('relationships',{}).get('contentPackages',{}).get('data',[])):
|
||||||
mandatory = key['attributes']['component'].get('mandatoryParams','')
|
itemlist.append(item.clone(title = f"{item.season}x{key['attributes']['episodeNumber']:02d} - {key['attributes']['name']}",
|
||||||
if not mandatory: return [support.Item(title='CONTENUTO PLUS')]
|
plot = key['attributes']['description'],
|
||||||
for option in key['attributes']['component']['filters'][0]['options']:
|
episode = key['attributes']['episodeNumber'],
|
||||||
url = '{}/cms/collections/{}?decorators=viewingHistory&include=default&{}&{}'.format(api, key['id'], mandatory, option['parameter'])
|
|
||||||
seasons = []
|
|
||||||
season = {}
|
|
||||||
try:
|
|
||||||
season = session.get(url, headers=headers).json()
|
|
||||||
seasons.append(season['included'])
|
|
||||||
pages = season['data'].get('meta',{}).get('itemsTotalPages', 0)
|
|
||||||
if pages:
|
|
||||||
for page in range(2,pages + 1):
|
|
||||||
url = '{}/cms/collections/{}?decorators=viewingHistory&include=default&{}&{}&page[items.number]={}'.format(api, key['id'], mandatory, option['parameter'], page)
|
|
||||||
logger.debug(url)
|
|
||||||
season = session.get(url, headers=headers).json()['included']
|
|
||||||
seasons.append(season)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
for season in seasons:
|
|
||||||
for episode in season:
|
|
||||||
if episode['type'] == 'video':
|
|
||||||
logger.debug('{}x{:02d} - {}'.format(option['id'], episode['attributes']['episodeNumber'], episode['attributes']['name']), episode['attributes']['packages'])
|
|
||||||
if episode['type'] == 'video' and 'Free' in episode['attributes']['packages']:
|
|
||||||
title = '{}x{:02d} - {}'.format(option['id'], episode['attributes']['episodeNumber'], episode['attributes']['name'])
|
|
||||||
plot = episode['attributes']['description']
|
|
||||||
itemlist.append(
|
|
||||||
item.clone(title=typo(title,'bold'),
|
|
||||||
fulltitle=title,
|
|
||||||
plot=plot,
|
|
||||||
id=episode['id'],
|
|
||||||
action='findvideos',
|
|
||||||
contentType = 'episode',
|
contentType = 'episode',
|
||||||
season=option['id'],
|
action = 'findvideos',
|
||||||
episode=episode['attributes']['episodeNumber'],
|
thumbnail = images[key['relationships']['images']['data'][0]['id']],
|
||||||
forcethumb=True,
|
id=key['id']))
|
||||||
no_return=True))
|
|
||||||
|
itemlist.sort(key=lambda it: it.episode)
|
||||||
|
|
||||||
|
if not itemlist:
|
||||||
|
from core.item import Item
|
||||||
|
itemlist = [Item(title='Nessun Episodio Free Disponibile', thumbnail=support.thumb('info'))]
|
||||||
|
|
||||||
if itemlist: itemlist.sort(key=lambda it: (int(it.season), int(it.episode)))
|
|
||||||
return itemlist
|
return itemlist
|
||||||
|
|
||||||
|
|
||||||
def findvideos(item):
|
def findvideos(item):
|
||||||
if item.livefilter:
|
logger.debug()
|
||||||
item.id = liveDict()[item.livefilter]['id']
|
|
||||||
item.fulltitle = item.livefilter
|
content = 'video' if item.contentType == 'episode' else 'channel'
|
||||||
item.forcethumb = True
|
post = {f'{content}Id': item.id, 'deviceInfo': {'adBlocker': False,'drmSupported': True}}
|
||||||
item.no_return = True
|
|
||||||
support.thumb(item, live=True)
|
data = session.post(f'{domain}/playback/v3/{content}PlaybackInfo', json=post).json().get('data',{}).get('attributes',{})
|
||||||
if item.contentType == 'episode': data = session.get('{}/playback/v2/videoPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
|
||||||
else: data = session.get('{}/playback/v2/channelPlaybackInfo/{}?usePreAuth=true'.format(api, item.id), headers=headers).json().get('data',{}).get('attributes',{})
|
|
||||||
if data.get('protection', {}).get('drmEnabled',False):
|
if data.get('protection', {}).get('drmEnabled',False):
|
||||||
item.url = data['streaming']['dash']['url']
|
item.url = data['streaming']['dash']['url']
|
||||||
item.drm = 'com.widevine.alpha'
|
item.drm = 'com.widevine.alpha'
|
||||||
item.license = data['protection']['schemes']['widevine']['licenseUrl'] + '|PreAuthorization=' + data['protection']['drmToken'] + '|R{SSM}|'
|
item.license =f"{data['protection']['schemes']['widevine']['licenseUrl']}|PreAuthorization={data['protection']['drmToken']}|R{{SSM}}|"
|
||||||
else:
|
else:
|
||||||
item.url = data['streaming']['hls']['url']
|
item.url = data['streaming'][0]['url']
|
||||||
item.manifest = 'hls'
|
item.manifest = 'hls'
|
||||||
|
|
||||||
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
return support.server(item, itemlist=[item], Download=False, Videolibrary=False)
|
||||||
@@ -497,7 +497,7 @@ def getCurrentView(item=None, parent_item=None):
|
|||||||
elif parent_item.action in ['episodios', 'get_episodes'] or item.contentType == 'episode':
|
elif parent_item.action in ['episodios', 'get_episodes'] or item.contentType == 'episode':
|
||||||
return 'episode', 'tvshows'
|
return 'episode', 'tvshows'
|
||||||
|
|
||||||
elif parent_item.action in ['get_seasons']:
|
elif parent_item.action in ['get_seasons', 'seasons']:
|
||||||
return 'season', 'tvshows'
|
return 'season', 'tvshows'
|
||||||
|
|
||||||
elif parent_item.action in ['getmainlist', '', 'getchanneltypes']:
|
elif parent_item.action in ['getmainlist', '', 'getchanneltypes']:
|
||||||
|
|||||||
Reference in New Issue
Block a user