From 8221e0982560b45d7043a4cdd9e2036577840a7c Mon Sep 17 00:00:00 2001 From: Alhaziel01 Date: Tue, 18 Jan 2022 20:22:43 +0100 Subject: [PATCH] Aggiunto Pluto TV --- channels.json | 1 + channels/plutotv.json | 12 ++++ channels/plutotv.py | 137 ++++++++++++++++++++++++++++++++++++++++++ core/support.py | 21 ++++--- 4 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 channels/plutotv.json create mode 100644 channels/plutotv.py diff --git a/channels.json b/channels.json index f50668f5..c44ee6f0 100644 --- a/channels.json +++ b/channels.json @@ -33,6 +33,7 @@ "paramount": "https://www.paramountnetwork.it", "piratestreaming": "https://www.piratestreaming.design", "polpotv": "https://roma.polpo.tv", + "plutotv":"https://pluto.tv", "raiplay": "https://www.raiplay.it", "seriehd": "https://altadefinizionecommunity.casa", "serietvonline": "https://serietvonline.art", diff --git a/channels/plutotv.json b/channels/plutotv.json new file mode 100644 index 00000000..1bcc7c1c --- /dev/null +++ b/channels/plutotv.json @@ -0,0 +1,12 @@ +{ + "id": "plutotv", + "name": "Pluto TV", + "active": true, + "language": ["ita"], + "thumbnail": "plutotv.png", + "banner": "plutotv.png", + "categories": ["movie", "tvshow", "documentary", "live"], + "not_active": ["include_in_newest"], + "default_off": ["include_in_global_search"], + "settings": [] +} diff --git a/channels/plutotv.py b/channels/plutotv.py new file mode 100644 index 00000000..b559c0df --- /dev/null +++ b/channels/plutotv.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------ +# Canale per Pluto TV +# ------------------------------------------------------------ + +import uuid, datetime, requests +from platformcode import logger, config +from core.item import Item +from core import support, httptools + + +host = support.config.get_channel_url() +api = 'https://api.pluto.tv' +UUID = 'sid={}&deviceId={}'.format(uuid.uuid1().hex, uuid.uuid4().hex) + +now = datetime.datetime.now() +start = (now.strftime('%Y-%m-%dT%H:00:00Z')) +stop = (now + datetime.timedelta(hours=2)).strftime('%Y-%m-%dT%H:00:00Z') + + +live_url = '{}/v2/channels.json?{}'.format(api, UUID) +guide_url = '{}/v2/channels?start={}&stop={}&{}'.format(api, start, stop, UUID) +vod_url = '{}/v3/vod/categories?includeItems=true&deviceType=web&'.format(api, UUID) + + +@support.menu +def mainlist(item): + top = [('Dirette {bold}', ['/it/live-tv/', 'live'])] + + menu = sorted([(it['name'], ['/it/on-demand', 'peliculas', it['items']]) for it in httptools.downloadpage(vod_url).json['categories'][1:]]) + + search = '' + + return locals() + +def live(item): + logger.debug() + def calcTime(t): + return datetime.datetime.strftime(datetime.datetime.strptime(t, '%Y-%m-%dT%H:%M:%S.%fZ'), '%H:%M') + + guide = {} + for g in httptools.downloadpage(guide_url).json: + guide[g['number']] = [g['timelines'][0]['title'], + '{}/{}'.format(calcTime(g['timelines'][0]['start']), calcTime(g['timelines'][0]['stop'])), + g['timelines'][1]['title']] + + itemlist = [] + for it in httptools.downloadpage(live_url).json: + itemlist.append(item.clone(title= '[B]{}[/B] | {} | {}'.format(it['name'], guide[it['number']][0], guide[it['number']][1]), + number=it['number'], + contentTitle=it['name'], + action='findvideos', + thumbnail=it['solidLogoPNG']['path'], + fanart=it['featuredImage']['path'], + plot='{}\n\n[B]A seguire:[/B]\n{}'.format(it['summary'], guide[it['number']][2]), + url= it['stitched']['urls'][0]['url'], + forcethumb=True)) + itemlist.sort(key=lambda it: it.number) + return itemlist + +def search(item, text): + logger.debug('Search', text) + try: + item.search = text.lower() + item.args = [] + for it in httptools.downloadpage(vod_url).json['categories'][1:]: + item.args.extend(it['items']) + return peliculas(item) + + except: + import sys + for line in sys.exc_info(): + support.logger.error("%s" % line) + return [] + + +def peliculas(item): + logger.debug() + itemlist = [] + recordlist = [] + for i, it in enumerate(item.args): + if item.search in it['name'].lower(): + itm = Item(channel=item.channel, + title=it['name'], + contentTitle=it['name'], + contentSerieName= it['name'] if it['type'] == 'series' else '', + plot=it['description'], + contentType='tvshow' if it['type'] == 'series' else 'movie', + action='episodios' if it['type'] == 'series' else 'findvideos', + thumbnail= it['covers'][0]['url'], + fanart= it['covers'][2]['url'] if len(it['covers']) > 2 else '', + id= it['_id'], + url= it['stitched']['urls'][0]['url']) + + if i < 20 or item.search: + itemlist.append(itm) + else: + recordlist.append(it) + + support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + if recordlist and not item.search: + itemlist.append(item.clone(title=support.typo(support.config.get_localized_string(30992), 'color kod bold'), thumbnail=support.thumb(), args=recordlist)) + return itemlist + + +def episodios(item): + logger.debug() + itemlist = [] + seasons = httptools.downloadpage('{}/v3/vod/series/{}/seasons?includeItems=true&deviceType=web&{}'.format(api, item.id, UUID)).json['seasons'] + for season in seasons: + for episode in season['episodes']: + itemlist.append(item.clone(title='{}x{:02d} - {}'.format(episode['season'], episode['number'], episode['name']), + contrentTitle=episode['name'], + contentSeason=episode['season'], + contentEpisodeNumber=episode['number'], + plot=episode['description'], + thumbnail=episode['covers'][1]['url'], + url=episode['stitched']['urls'][0]['url'], + action='findvideos')) + + if config.get_setting('episode_info'): + support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) + support.videolibrary(itemlist,item) + return itemlist + + +def findvideos(item): + logger.debug() + item.server = 'directo' + item.manifest='hls' + item.url = item.url.replace('deviceType=&','deviceType=web&') + item.url = item.url.replace('deviceMake=&','deviceMake=firefox&') + item.url = item.url.replace('deviceModel=&','deviceModel=firefox&') + item.url = item.url.replace('appName=&','appName=web&') + item.url = item.url.replace('sid=&','') + item.url = '{}&sid={}'.format(item.url, uuid.uuid1().hex) + return support.server(item, itemlist=[item], Download=False, Videolibrary=False) diff --git a/core/support.py b/core/support.py index b568ef1d..0bab5a65 100755 --- a/core/support.py +++ b/core/support.py @@ -606,7 +606,7 @@ def scrape(func): if action != 'play' and 'patronMenu' not in args and 'patronGenreMenu' not in args \ and not stackCheck(['add_tvshow', 'get_newest']) and (function not in ['episodes', 'mainlist'] \ - or (function in ['episodes'] and config.getSetting('episode_info'))): + or (function in ['episodes'] and config.get_setting('episode_info'))): tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True) if not group and not args.get('groupExplode') and ((pagination and len(matches) <= pag * pagination) or not pagination): # next page with pagination @@ -1493,7 +1493,7 @@ def thumb(item_itemlist_string=None, genre=False, live=False): icon_dict = {'movie':['film', 'movie'], 'tvshow':['serie','tv','episodi','episodio','fiction', 'show'], 'documentary':['documentari','documentario', 'documentary', 'documentaristico'], - 'teenager':['ragazzi','teenager', 'teen'], + 'teenager':['ragazzi','teenager', 'giovani', 'teen'], 'learning':['learning', 'school', 'scuola'], 'all':['tutti', 'all'], 'news':['novità', "novita'", 'aggiornamenti', 'nuovi', 'nuove', 'new', 'newest', 'news', 'ultimi', 'notizie'], @@ -1519,11 +1519,11 @@ def thumb(item_itemlist_string=None, genre=False, live=False): 'noir':['noir'], 'popular':['popolari','popolare', 'più visti', 'raccomandati', 'raccomandazioni' 'recommendations'], 'thriller':['thriller'], - 'top_rated' : ['fortunato', 'votati', 'lucky', 'top'], + 'top_rated' : ['fortunato', 'votati', 'primo', 'lucky', 'top'], 'on_the_air' : ['corso', 'onda', 'diretta', 'dirette'], 'western':['western'], 'vos':['sub','sub-ita'], - 'romance':['romantico','sentimentale', 'romance', 'soap'], + 'romance':['romantico', 'romantici', 'sentimentale', 'romance', 'soap'], 'family':['famiglia','famiglie', 'family'], 'historical':['storico', 'history', 'storia', 'historical'], 'az':['lettera','lista','alfabetico','a-z', 'alphabetical'], @@ -1551,19 +1551,20 @@ def thumb(item_itemlist_string=None, genre=False, live=False): '_tvshow':['serie','tv', 'fiction']} def autoselect_thumb(item, genre): - # logger.debug('SPLIT',re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower())) + searched = re.split(r'\:|\.|\{|\}|\[|\]|\(|\)|/| ', item.title.lower()) + # logger.debug('SPLIT',searched) if genre == False: for thumb, titles in icon_dict.items(): - if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in search): + if any(word in searched for word in search): thumb = 'search' for suffix, titles in search_suffix.items(): - if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ): + if any(word in searched for word in titles ): thumb = thumb + suffix item.thumbnail = get_thumb(thumb + '.png') - elif any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)| ',item.title.lower()) for word in titles ): + elif any(word in searched for word in titles ): if thumb == 'movie' or thumb == 'tvshow': for suffix, titles in suffix_dict.items(): - if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ): + if any(word in searched for word in titles ): thumb = thumb + suffix item.thumbnail = get_thumb(thumb + '.png') else: item.thumbnail = get_thumb(thumb + '.png') @@ -1572,7 +1573,7 @@ def thumb(item_itemlist_string=None, genre=False, live=False): else: for thumb, titles in icon_dict.items(): - if any(word in re.split(r'\.|\{|\}|\[|\]|\(|\)|/| ',item.title.lower()) for word in titles ): + if any(word in searched for word in titles ): item.thumbnail = get_thumb(thumb + '.png') else: thumb = item.thumbnail