diff options
author | Sylvain CECCHETTO <cecchetto.sylvain@me.com> | 2017-12-10 18:35:44 +0100 |
---|---|---|
committer | enen92 <enen92@users.noreply.github.com> | 2017-12-10 17:35:44 +0000 |
commit | 829765ddb449618af47ce6743ebb3c58ee52dac8 (patch) | |
tree | c82b84d161a4cc6f0dbb4411b2cbefd69afe0b83 /plugin.video.catchuptvandmore/resources | |
parent | 198b996ec5bfc0df3980f56116d1a8ad962d6f92 (diff) |
[plugin.video.catchuptvandmore] 0.1.4 (#1476)
Diffstat (limited to 'plugin.video.catchuptvandmore/resources')
144 files changed, 3840 insertions, 686 deletions
diff --git a/plugin.video.catchuptvandmore/resources/__init__.py b/plugin.video.catchuptvandmore/resources/__init__.py index e69de29..e69de29 100755..100644 --- a/plugin.video.catchuptvandmore/resources/__init__.py +++ b/plugin.video.catchuptvandmore/resources/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/language/resource.language.en_gb/strings.po b/plugin.video.catchuptvandmore/resources/language/resource.language.en_gb/strings.po index 0fb703f..cff1272 100755..100644 --- a/plugin.video.catchuptvandmore/resources/language/resource.language.en_gb/strings.po +++ b/plugin.video.catchuptvandmore/resources/language/resource.language.en_gb/strings.po @@ -75,6 +75,10 @@ msgctxt "#30025" msgid "United States channels" msgstr "" +msgctxt "#30026" +msgid "Websites" +msgstr "" + # Context menu (from 30040 to 30049) msgctxt "#30040" msgid "Move down" @@ -92,6 +96,7 @@ msgctxt "#30043" msgid "Download" msgstr "" + # Dialog boxes (from 30050 to 30069) msgctxt "#30050" msgid "Information" @@ -116,7 +121,7 @@ msgid "Arte: Choose Channel" msgstr "" msgctxt "#30081" -msgid "France24: Choose Channel" +msgid "France 24: Choose Channel" msgstr "" msgctxt "#30082" @@ -173,6 +178,14 @@ msgctxt "#30110" msgid "Choose video quality" msgstr "" +msgctxt "#30111" +msgid "Video stream no longer exists" +msgstr "" + +msgctxt "#30112" +msgid "Video with an account needed" +msgstr "" + # Download (from 30200 to 30240) msgctxt "#30200" diff --git a/plugin.video.catchuptvandmore/resources/language/resource.language.fr_fr/strings.po b/plugin.video.catchuptvandmore/resources/language/resource.language.fr_fr/strings.po index ee2e81c..de0143c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/language/resource.language.fr_fr/strings.po +++ b/plugin.video.catchuptvandmore/resources/language/resource.language.fr_fr/strings.po @@ -75,6 +75,10 @@ msgctxt "#30025" msgid "United States channels" msgstr "Chaînes américaines" +msgctxt "#30026" +msgid "Websites" +msgstr "Sites Web" + # Context menu (from 30040 to 30049) msgctxt "#30040" msgid "Move down" @@ -114,15 +118,15 @@ msgstr "Contenus" msgctxt "#30080" msgid "Arte: Choose Channel" -msgstr "Arte : Choix de la chaîne" +msgstr "Arte: Choix de la chaîne" msgctxt "#30081" -msgid "France24: Choose Channel" -msgstr "France24 : Choix de la chaîne" +msgid "France 24: Choose Channel" +msgstr "France 24: Choix de la chaîne" msgctxt "#30082" msgid "Euronews: Choose Channel" -msgstr "Euronews : Choix de la chaîne" +msgstr "Euronews: Choix de la chaîne" msgctxt "#30087" msgid "Video quality (BEST|DEFAULT|DIALOG)" @@ -173,6 +177,14 @@ msgctxt "#30110" msgid "Choose video quality" msgstr "Choisir la qualité vidéo" +msgctxt "#30111" +msgid "Video stream no longer exists" +msgstr "Le flux vidéo n'existe plus" + +msgctxt "#30112" +msgid "Video with an account needed" +msgstr "Vidéo avec un compte requis" + # Download (from 30200 to 30240) msgctxt "#30200" diff --git a/plugin.video.catchuptvandmore/resources/language/resource.language.he.il/strings.po b/plugin.video.catchuptvandmore/resources/language/resource.language.he.il/strings.po index 4133130..0c4c4cd 100755..100644 --- a/plugin.video.catchuptvandmore/resources/language/resource.language.he.il/strings.po +++ b/plugin.video.catchuptvandmore/resources/language/resource.language.he.il/strings.po @@ -75,6 +75,10 @@ msgctxt "#30025" msgid "United States channels" msgstr "ערוצים אמריקאיים" +msgctxt "#30026" +msgid "Websites" +msgstr "אתרי רשת" + # Context menu (from 30040 to 30049) msgctxt "#30040" msgid "Move down" @@ -99,7 +103,7 @@ msgstr "מידע" msgctxt "#30051" msgid "To re-enable hidden items go to the plugin settings" -msgstr "כדי להפעיל מחדש את הפריטים המוסתרים, עבור אל ההגדרות של תוסף" +msgstr "כדי להפעיל מחדש את הפריטים המוסתרים, עבור אל ההגדרות של ההרחבה" # Settings quality and content (from 30070 to 30099) @@ -116,8 +120,8 @@ msgid "Arte: Choose Channel" msgstr "Arte: בחר ערוץ" msgctxt "#30081" -msgid "France24: Choose Channel" -msgstr "France24: בחר ערוץ" +msgid "France 24: Choose Channel" +msgstr "France 24: בחר ערוץ" msgctxt "#30082" msgid "Euronews: Choose Channel" @@ -173,6 +177,14 @@ msgctxt "#30110" msgid "Choose video quality" msgstr "בחר איכות וידאו" +msgctxt "#30111" +msgid "Video stream no longer exists" +msgstr "הזרמת הווידאו כבר לא קיימת" + +msgctxt "#30112" +msgid "Video with an account needed" +msgstr "נדרש וידאו שמקושר לחשבון" + # Download (from 30200 to 30240) msgctxt "#30200" msgid "Folder to Download" diff --git a/plugin.video.catchuptvandmore/resources/language/resource.language.he_il/strings.po b/plugin.video.catchuptvandmore/resources/language/resource.language.he_il/strings.po new file mode 100644 index 0000000..0c7932d --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/language/resource.language.he_il/strings.po @@ -0,0 +1,177 @@ +# Kodi Media Center language file +# Addon Name: Catch-up TV & More +# Addon id: plugin.video.catchuptvandmore +# Addon Provider: SylvainCecchetto +msgid "" +msgstr "" +"Project-Id-Version: Kodi Addons\n" +"Report-Msgid-Bugs-To: alanwww1@kodi.org\n" +"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" +"PO-Revision-Date: 2017-10-22 09:08+0300\n" +"Last-Translator: A. Dambledore\n" +"Language-Team: Eng2Heb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: he_IL\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +# Settings categories (from 30000 to 30009) +msgctxt "#30000" +msgid "Main menu" +msgstr "תפריט ראשי" + +msgctxt "#30001" +msgid "Channels" +msgstr "סרטים מערוצים" + +msgctxt "#30002" +msgid "Quality and Content" +msgstr "איכות ותוכן" + +msgctxt "#30003" +msgid "Download" +msgstr "הורדה" + +msgctxt "#30004" +msgid "Accounts" +msgstr "חשבון" + +# Settings line separators (from 30010 to 30019) +msgctxt "#30010" +msgid "Hide main menu categories" +msgstr "הסתר קטגוריות בתפריט הראשי" + +msgctxt "#30011" +msgid "Hide channels from categories" +msgstr "הסתר ערוצים מכל הקטגוריות" + +msgctxt "#30012" +msgid "To configure YTDL go settings of script.module.youtube.dl" +msgstr "כדי לקבוע את התצורה של YTDL עבור אל ההגדרות של script.module.youtube.dl" + +# Main categories (from 30020 to 30039) +msgctxt "#30020" +msgid "French channels" +msgstr "ערוצים צרפתיים" + +msgctxt "#30021" +msgid "Belgian channels" +msgstr "ערוצים בלגיים" + +msgctxt "#30022" +msgid "Japanese channels" +msgstr "ערוצים יפניים" + +msgctxt "#30023" +msgid "European channels" +msgstr "ערוצים אירופיים" + +msgctxt "#30024" +msgid "United Kingdom channels" +msgstr "ערוצים אנגליים" + +msgctxt "#30025" +msgid "United States channels" +msgstr "ערוצים אמריקאיים" + +# Context menu (from 30040 to 30049) +msgctxt "#30040" +msgid "Move down" +msgstr "הזזה מטה" + +msgctxt "#30041" +msgid "Move up" +msgstr "הזזה מעלה" + +msgctxt "#30042" +msgid "Hide" +msgstr "הסתר" + +msgctxt "#30043" +msgid "Download" +msgstr "הורדה" + +# Dialog boxes (from 30050 to 30069) +msgctxt "#30050" +msgid "Information" +msgstr "מידע" + +msgctxt "#30051" +msgid "To re-enable hidden items go to the plugin settings" +msgstr "כדי להפעיל מחדש את הפריטים המוסתרים, עבור אל ההגדרות של תוסף" + +# Settings quality and content (from 30070 to 30099) +msgctxt "#30070" +msgid "Video quality" +msgstr "איכות וידאו מיו-טיוב" + +msgctxt "#30071" +msgid "Contents" +msgstr "תוכן העניינים" + +msgctxt "#30080" +msgid "Arte: Choose Channel" +msgstr "Arte: בחר ערוץ" + +msgctxt "#30081" +msgid "France24: Choose Channel" +msgstr "France24: בחר ערוץ" + +msgctxt "#30082" +msgid "Euronews: Choose Channel" +msgstr "Euronews: בחר ערוץ" + +msgctxt "#30087" +msgid "Video quality (BEST|DEFAULT|DIALOG)" +msgstr "איכות וידאו (הטוב ביותר|ברירת מחדל|תיבת דו-שיח)" + +# Others (from 30100 to 30140) +msgctxt "#30100" +msgid "More videos..." +msgstr "קטעי וידאו נוספים..." + +msgctxt "#30101" +msgid "All videos" +msgstr "כל וידאו" + +msgctxt "#30102" +msgid "DRM protected video" +msgstr "וידאו מוגן DRM" + +msgctxt "#30103" +msgid "Search" +msgstr "חיפוש" + +msgctxt "#30104" +msgid "Last videos" +msgstr "קטעי וידאו האחרונים" + +msgctxt "#30105" +msgid "From A to Z" +msgstr "מ-א עד ת" + +msgctxt "#30106" +msgid "Ascending" +msgstr "עולה" + +msgctxt "#30107" +msgid "Descending" +msgstr "יורד" + +msgctxt "#30108" +msgid "More programs..." +msgstr "עוד תוכניות..." + +msgctxt "#30109" +msgid "Live TV" +msgstr "טלוויזיה" + +msgctxt "#30110" +msgid "Choose video quality" +msgstr "בחר איכות וידאו" + +# Download (from 30200 to 30240) +msgctxt "#30200" +msgid "Folder to Download" +msgstr "תיקיה להורדה" diff --git a/plugin.video.catchuptvandmore/resources/lib/__init__.py b/plugin.video.catchuptvandmore/resources/lib/__init__.py index e69de29..e69de29 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/__init__.py +++ b/plugin.video.catchuptvandmore/resources/lib/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/__init__.py index e69de29..e69de29 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/__init__.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/be/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/be/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/be/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/be/rtbf.py b/plugin.video.catchuptvandmore/resources/lib/channels/be/rtbf.py new file mode 100644 index 0000000..91fb046 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/be/rtbf.py @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- +""" + Catch-up TV & More + Copyright (C) 2017 SylvainCecchetto + + This file is part of Catch-up TV & More. + + Catch-up TV & More is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Catch-up TV & More is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Catch-up TV & More; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" + +import json +import re +import time +from bs4 import BeautifulSoup as bs +from resources.lib import utils +from resources.lib import common + +# TO DO +# Add geoblock (info in JSON) +# Add Quality Mode + +# Initialize GNU gettext emulation in addon +# This allows to use UI strings from addon’s English +# strings.po file instead of numeric codes +_ = common.ADDON.initialize_gettext() + +URL_EMISSIONS_AUVIO = 'https://www.rtbf.be/auvio/emissions' + +URL_JSON_EMISSION_BY_ID = 'https://www.rtbf.be/api/media/video?' \ + 'method=getVideoListByEmissionOrdered&args[]=%s' +# emission_id + +URL_ROOT_IMAGE_RTBF = 'https://ds1.static.rtbf.be' + +URL_JSON_LIVE = 'https://www.rtbf.be/api/partner/generic/live/' \ + 'planninglist?target_site=media&partner_key=%s' +# partener_key + +URL_ROOT_LIVE = 'https://www.rtbf.be/auvio/direct#/' + + +def channel_entry(params): + """Entry function of the module""" + if 'root' in params.next: + return root(params) + elif 'list_shows' in params.next: + return list_shows(params) + elif 'list_videos' in params.next: + return list_videos(params) + elif 'live' in params.next: + return list_live(params) + elif 'play' in params.next: + return get_video_url(params) + else: + return None + + +def get_partener_key(params): + + file_path_root_live = utils.download_catalog( + URL_ROOT_LIVE, + '%s_root_live.html' % params.channel_name, + ) + html_root_live = open(file_path_root_live).read() + + list_js_files = re.compile( + r'<script type="text\/javascript" src="(.*?)">' + ).findall(html_root_live) + + partener_key_value = '' + i = 0 + + for js_file in list_js_files: + # Get partener key + file_path_js = utils.download_catalog( + js_file, + '%s_partener_key_%s.js' % (params.channel_name, str(i)), + ) + partener_key_js = open(file_path_js).read() + + partener_key = re.compile( + 'partner_key: \'(.+?)\'').findall(partener_key_js) + if len(partener_key) > 0: + partener_key_value = partener_key[0] + i = i + 1 + + return partener_key_value + + +def format_hours(date): + date_list = date.split('T') + date_hour = date_list[1][:5] + return date_hour + + +def format_day(date): + date_list = date.split('T') + date_dmy = date_list[0].replace('-', '/') + return date_dmy + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def root(params): + modes = [] + + # Add Replay + modes.append({ + 'label': 'Replay', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_1', + category='%s Replay' % params.channel_name.upper(), + window_title='%s Replay' % params.channel_name.upper() + ), + }) + + # Add Live + modes.append({ + 'label': 'Live TV', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='live_cat', + category='%s Live TV' % params.channel_name.upper(), + window_title='%s Live TV' % params.channel_name.upper() + ), + }) + + return common.PLUGIN.create_listing( + modes, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_shows(params): + shows = [] + + if params.next == 'list_shows_1': + + file_path = utils.download_catalog( + URL_EMISSIONS_AUVIO, + 'url_emissions_auvio.html') + emissions_html = open(file_path).read() + emissions_soup = bs(emissions_html, 'html.parser') + list_emissions = emissions_soup.find_all( + 'article', class_="rtbf-media-item col-xxs-12 ") + + for emission in list_emissions: + + emission_id = emission.get('data-id') + emission_title = emission.find('h4').get_text().encode('utf-8') + + shows.append({ + 'label': emission_title, + 'url': common.PLUGIN.get_url( + emission_title=emission_title, + action='channel_entry', + emission_id=emission_id, + next='list_videos_1', + window_title=emission_title + ) + }) + + return common.PLUGIN.create_listing( + shows, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ) + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_videos(params): + videos = [] + + if params.next == 'list_videos_1': + + file_path = utils.download_catalog( + URL_JSON_EMISSION_BY_ID % params.emission_id, + 'url_videos_emission_%s.html' % params.emission_id) + videos_json = open(file_path).read() + videos_jsonparser = json.loads(videos_json) + + for video in videos_jsonparser['data']: + + if video["subtitle"]: + title = video["title"].encode('utf-8') + \ + ' - ' + video["subtitle"].encode('utf-8') + else: + title = video["title"].encode('utf-8') + img = URL_ROOT_IMAGE_RTBF + video["thumbnail"]["full_medium"] + url_video = video["urlHls"] + plot = '' + if video["description"]: + plot = video["description"].encode('utf-8') + duration = 0 + duration = video["durations"] + + value_date = time.strftime( + '%d %m %Y', time.localtime(video["liveFrom"])) + date = str(value_date).split(' ') + day = date[0] + mounth = date[1] + year = date[2] + + date = '.'.join((day, mounth, year)) + aired = '-'.join((year, mounth, day)) + + info = { + 'video': { + 'title': title, + 'plot': plot, + # 'episode': episode_number, + # 'season': season_number, + # 'rating': note, + 'aired': aired, + 'date': date, + 'duration': duration, + 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + url_video=url_video) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': title, + 'thumb': img, + 'fanart': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + url_video=url_video + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) + + return common.PLUGIN.create_listing( + videos, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_DATE + ), + content='tvshows', + update_listing='update_listing' in params) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_live(params): + + lives = [] + + title = '' + # subtitle = ' - ' + plot = '' + duration = 0 + img = '' + url_live = '' + + file_path = utils.download_catalog( + URL_JSON_LIVE % (get_partener_key(params)), + '%s_live.json' % (params.channel_name)) + live_json = open(file_path).read() + live_jsonparser = json.loads(live_json) + + # channel_live_in_process = False + + for live in live_jsonparser: + + if type(live["channel"]) is dict: + live_channel = live["channel"]["label"] + else: + live_channel = 'Exclu Auvio' + + start_date_value = format_hours(live["start_date"]) + end_date_value = format_hours(live["end_date"]) + day_value = format_day(live["start_date"]) + + title = live_channel + ' : ' + live["title"] + \ + ' - ' + day_value + ' - ' + start_date_value + '-' + end_date_value + + url_live = '' + if live["url_streaming"]: + url_live = live["url_streaming"]["url_hls"] + plot = live["description"].encode('utf-8') + img = live["images"]["illustration"]["16x9"]["1248x702"] + + info = { + 'video': { + 'title': title, + 'plot': plot, + 'duration': duration + } + } + + lives.append({ + 'label': title, + 'fanart': img, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_l', + url_live=url_live, + ), + 'is_playable': True, + 'info': info + }) + + return common.PLUGIN.create_listing( + lives, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ) + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_video_url(params): + if params.next == 'play_l': + return params.url_live + elif params.next == 'play_r': + return params.url_video diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/eu/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/eu/__init__.py index e69de29..e69de29 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/eu/__init__.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/eu/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/eu/arte.py b/plugin.video.catchuptvandmore/resources/lib/channels/eu/arte.py index 9fe6d0b..9957f8a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/eu/arte.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/eu/arte.py @@ -41,6 +41,7 @@ URL_REPLAY = 'https://www.arte.tv/papi/tvguide/videos/' \ URL_LIVE_ARTE = 'https://api.arte.tv/api/player/v1/livestream/%s' # Langue, ... + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -55,14 +56,15 @@ def channel_entry(params): return get_video_url(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -72,7 +74,7 @@ def root(params): }) modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -89,7 +91,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -118,17 +121,17 @@ def list_shows(params): emission_dict['image'] = emission['programImage'].encode('utf-8') try: emission_dict['genre'] = emission['genre'].encode('utf-8') - except: + except Exception: emission_dict['genre'] = 'Unknown' try: emission_dict['director'] = emission['director'].encode('utf-8') - except: + except Exception: emission_dict['director'] = '' emission_dict['production_year'] = emission['productionYear'] emission_dict['program_title'] = emission['VTI'].encode('utf-8') try: emission_dict['emission_title'] = emission['VSU'].encode('utf-8') - except: + except Exception: emission_dict['emission_title'] = '' emission_dict['category'] = emission['VCH'][0]['label'].encode('utf-8') @@ -138,7 +141,7 @@ def list_shows(params): try: emission_dict['desc'] = emission['VDE'].encode('utf-8') - except: + except Exception: emission_dict['desc'] = '' emissions_list.append(emission_dict) @@ -167,7 +170,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -227,7 +230,7 @@ def list_videos(params): ), 'is_playable': True, 'info': info, - 'context_menu': context_menu # A ne pas oublier pour ajouter le bouton "Download" à chaque vidéo + 'context_menu': context_menu }) return common.PLUGIN.create_listing( @@ -242,7 +245,8 @@ def list_videos(params): ), content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -287,7 +291,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -304,7 +308,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': @@ -324,20 +329,24 @@ def get_video_url(params): if not video.find("HLS"): datas = json_parser['videoJsonPlayer']['VSR'][video] new_list_item = common.sp.xbmcgui.ListItem() - new_list_item.setLabel(datas['mediaType'] + " (" + datas['versionLibelle'] + ")") + new_list_item.setLabel( + datas['mediaType'] + " (" + + datas['versionLibelle'] + ")") new_list_item.setPath(datas['url']) all_datas_videos.append(new_list_item) - seleted_item = common.sp.xbmcgui.Dialog().select("Choose Stream", all_datas_videos) + seleted_item = common.sp.xbmcgui.Dialog().select( + "Choose Stream", all_datas_videos) - url_selected = all_datas_videos[seleted_item].getPath().encode('utf-8') + url_selected = all_datas_videos[seleted_item] + url_selected = url_selected.getPath().encode('utf-8') elif desired_quality == "BEST": - url_selected = video_streams['HTTP_MP4_SQ_1']['url'].encode('utf-8') + url_selected = video_streams['HTTP_MP4_SQ_1']['url'] + url_selected = url_selected.encode('utf-8') else: url_selected = video_streams['HLS_SQ_1']['url'].encode('utf-8') return url_selected elif params.next == 'play_l': return params.url - diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/eu/euronews.py b/plugin.video.catchuptvandmore/resources/lib/channels/eu/euronews.py index be0edad..ef4b57d 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/eu/euronews.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/eu/euronews.py @@ -37,6 +37,7 @@ _ = common.ADDON.initialize_gettext() URL_LIVE_API = 'http://%s.euronews.com/api/watchlive.json' # Language + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -51,14 +52,16 @@ def channel_entry(params): return get_video_url(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): modes = [] + """ # Add Replay Desactiver if params.channel_name != 'euronews': modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -69,7 +72,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -85,16 +88,24 @@ def root(params): common.sp.xbmcplugin.SORT_METHOD_LABEL ), ) + """ + + params.next = "list_live" + return channel_entry(params) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): + return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): lives = [] @@ -142,7 +153,8 @@ def list_live(params): file_path = utils.download_catalog( url_live_json, - '%s_%s_live.json' % (params.channel_name,desired_language.lower()) + '%s_%s_live.json' % ( + params.channel_name, desired_language.lower()) ) json_live = open(file_path).read() json_parser = json.loads(json_live) @@ -150,7 +162,8 @@ def list_live(params): file_path_2 = utils.download_catalog( url_2nd_json, - '%s_%s_live_2.json' % (params.channel_name,desired_language.lower()) + '%s_%s_live_2.json' % ( + params.channel_name, desired_language.lower()) ) json_live_2 = open(file_path_2).read() json_parser_2 = json.loads(json_live_2) @@ -169,7 +182,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -186,7 +199,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): if params.next == 'play_l': diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py index b779d94..2f4d2b1 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py @@ -29,6 +29,15 @@ from resources.lib import common # TO DO # LIVE TV protected by #EXT-X-FAXS-CM # https://helpx.adobe.com/adobe-media-server/dev/configuring-content-protection-hls.html +# Clip and Playlist (cas les blagues de TOTO) +# Case MP4: +# https://pc.middleware.6play.fr/6play/v2/platforms/m6group_web/services/6play/videos/playlist_2248?csa=6&with=clips,freemiumpacks,program_images,service_display_images +# Case without ISM (One flux m3u8) : +# https://pc.middleware.6play.fr/6play/v2/platforms/m6group_web/services/6play/videos/clip_11740712?csa=6&with=clips,freemiumpacks,program_images,service_display_images +# Case Video Protected : +# https://pc.middleware.6play.fr/6play/v2/platforms/m6group_web/services/6play/videos/clip_11288922?csa=6&with=clips,freemiumpacks,program_images,service_display_images +# Rework Quality Video +# Get vtt subtitle # Initialize GNU gettext emulation in addon # This allows to use UI strings from addon’s English @@ -46,7 +55,7 @@ URL_ROOT = 'http://pc.middleware.6play.fr/6play/v2/platforms/' \ # We get an id by program URL_CATEGORY = 'http://pc.middleware.6play.fr/6play/v2/platforms/' \ 'm6group_web/services/6play/folders/%s/programs' \ - '?limit=999&offset=0&csa=9&with=parentcontext' + '?limit=999&offset=0&csa=6&with=parentcontext' # Url to get program's subfolders # e.g. Saison 5, Les meilleurs moments, les recettes pas à pas, ... @@ -70,7 +79,7 @@ URL_VIDEOS2 = 'https://pc.middleware.6play.fr/6play/v2/platforms/' \ URL_JSON_VIDEO = 'https://pc.middleware.6play.fr/6play/v2/platforms/' \ 'm6group_web/services/6play/videos/%s'\ - '?csa=9&with=clips,freemiumpacks' + '?csa=6&with=clips,freemiumpacks' URL_IMG = 'https://images.6play.fr/v1/images/%s/raw' @@ -85,20 +94,21 @@ def channel_entry(params): elif 'list_videos' in params.next: return list_videos(params) elif 'live' in params.next: - return list_live(params) + return None elif 'play' in params.next: return get_video_url(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" + """ modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -114,8 +124,12 @@ def root(params): common.sp.xbmcplugin.SORT_METHOD_LABEL ), ) + """ + params.next = "list_shows_1" + return channel_entry(params) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -123,9 +137,12 @@ def list_shows(params): if params.next == 'list_shows_1': url_root_site = '' - if params.channel_name == 'stories' or params.channel_name == 'bruce' \ - or params.channel_name == 'crazy_kitchen' or params.channel_name == 'home' \ - or params.channel_name == 'styles' or params.channel_name == 'comedy': + if params.channel_name == 'stories' or \ + params.channel_name == 'bruce' or \ + params.channel_name == 'crazy_kitchen' or \ + params.channel_name == 'home' or \ + params.channel_name == 'styles' or \ + params.channel_name == 'comedy': url_root_site = URL_ROOT % params.channel_name else: url_root_site = URL_ROOT % (params.channel_name + 'replay') @@ -228,7 +245,7 @@ def list_shows(params): try: program_fanart = params.program_fanart - except: + except Exception: program_fanart = '' for sub_category in json_parser['program_subcats']: @@ -288,7 +305,7 @@ def list_shows(params): return shows -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -320,7 +337,7 @@ def list_videos(params): year = aired.split('-')[0] date = '.'.join((day, mounth, year)) - except: + except Exception: aired = '' year = '' date = '' @@ -378,7 +395,7 @@ def list_videos(params): content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" video_json = utils.get_webcontent( @@ -387,6 +404,9 @@ def get_video_url(params): json_parser = json.loads(video_json) video_assets = json_parser['clips'][0]['assets'] + if video_assets is None: + utils.send_notification(common.ADDON.get_localized_string(30112)) + return '' url = '' url2 = '' url3 = '' @@ -405,41 +425,10 @@ def get_video_url(params): manifest_url = url2 else: manifest_url = url3 - - manifest = utils.get_webcontent( - manifest_url, - random_ua=True) - if 'drm' in manifest: - utils.send_notification(common.ADDON.get_localized_string(30102)) - return '' - - desired_quality = common.PLUGIN.get_setting( - params.channel_id + '.quality') - - if desired_quality == 'Auto': - return manifest_url - - root = common.os.path.dirname(manifest_url) - - url_sd = '' - url_hd = '' - url_ultra_sd = '' - url_ultra_hd = '' - - lines = manifest.splitlines() - for k in range(0, len(lines) - 1): - if 'RESOLUTION=400' in lines[k]: - url_ultra_sd = root + '/' + lines[k + 1] - elif 'RESOLUTION=640' in lines[k]: - url_sd = root + '/' + lines[k + 1] - elif 'RESOLUTION=720' in lines[k]: - url_hd = root + '/' + lines[k + 1] - elif 'RESOLUTION=1080' in lines[k]: - url_ultra_hd = root + '/' + lines[k + 1] - - desired_quality = common.PLUGIN.get_setting('quality') - - if (desired_quality == 'BEST' or desired_quality == 'DIALOG') and url_ultra_hd: - return url_ultra_hd - else: - return manifest_url + manifest = utils.get_webcontent( + manifest_url, + random_ua=True) + if 'drm' in manifest: + utils.send_notification(common.ADDON.get_localized_string(30102)) + return '' + return manifest_url diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py index e69de29..e69de29 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py index e52cbf4..2059fbd 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py @@ -33,7 +33,7 @@ from resources.lib import common # BFMTV, RMC, ONENET, etc ... URL_TOKEN = 'http://api.nextradiotv.com/%s-applications/' -#channel +# channel URL_MENU = 'http://www.bfmtv.com/static/static-mobile/bfmtv/' \ 'ios-smartphone/v0/configuration.json' @@ -68,7 +68,8 @@ URL_LIVE_BFM_SPORT = 'http://rmcsport.bfmtv.com/mediaplayer/live-bfm-sport/' # RMC Decouverte URL_REPLAY_RMCDECOUVERTE = 'http://rmcdecouverte.bfmtv.com/mediaplayer-replay/' -URL_VIDEO_HTML_RMCDECOUVERTE = 'http://rmcdecouverte.bfmtv.com/mediaplayer-replay/?id=%s' +URL_VIDEO_HTML_RMCDECOUVERTE = 'http://rmcdecouverte.bfmtv.com/'\ + 'mediaplayer-replay/?id=%s' # VideoId_html URL_LIVE_RMCDECOUVERTE = 'http://rmcdecouverte.bfmtv.com/mediaplayer-direct/' @@ -76,7 +77,8 @@ URL_LIVE_RMCDECOUVERTE = 'http://rmcdecouverte.bfmtv.com/mediaplayer-direct/' URL_JS_POLICY_KEY = 'http://players.brightcove.net/%s/%s_default/index.min.js' # AccountId, PlayerId -URL_VIDEO_JSON_BRIGHTCOVE = 'https://edge.api.brightcove.com/playback/v1/accounts/%s/videos/%s' +URL_VIDEO_JSON_BRIGHTCOVE = 'https://edge.api.brightcove.com/'\ + 'playback/v1/accounts/%s/videos/%s' # AccountId, VideoId # Initialize GNU gettext emulation in addon @@ -84,7 +86,8 @@ URL_VIDEO_JSON_BRIGHTCOVE = 'https://edge.api.brightcove.com/playback/v1/account # strings.po file instead of numeric codes _ = common.ADDON.initialize_gettext() -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_token(channel_name): """Get session token""" file_token = utils.get_webcontent(URL_TOKEN % (channel_name)) @@ -92,10 +95,11 @@ def get_token(channel_name): return token_json['session']['token'].encode('utf-8') -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_policy_key(data_account, data_player): """Get policy key""" - file_js = utils.get_webcontent(URL_JS_POLICY_KEY % (data_account, data_player)) + file_js = utils.get_webcontent( + URL_JS_POLICY_KEY % (data_account, data_player)) return re.compile('policyKey:"(.+?)"').findall(file_js)[0] @@ -113,14 +117,15 @@ def channel_entry(params): return get_video_url(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay Desactiver modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -132,7 +137,7 @@ def root(params): # Add Live if params.channel_name != '01net': modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -149,7 +154,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -166,8 +172,12 @@ def list_shows(params): 'article', class_='art-c modulx2-5 bg-color-rub0-1 box-shadow relative') for video in videos_soup: - video_id = video.find('figure').find('a')['href'].split('&', 1)[0].rsplit('=', 1)[1] - video_img = video.find('figure').find('a').find('img')['data-original'] + video_id = video.find( + 'figure').find( + 'a')['href'].split('&', 1)[0].rsplit('=', 1)[1] + video_img = video.find( + 'figure').find( + 'a').find('img')['data-original'] video_titles = video.find( 'div', class_="art-body" ).find('a').find('h2').get_text().encode( @@ -193,7 +203,8 @@ def list_shows(params): else: if params.next == 'list_shows_1': file_path = utils.download_catalog( - URL_REPLAY % (params.channel_name, get_token(params.channel_name)), + URL_REPLAY % ( + params.channel_name, get_token(params.channel_name)), '%s.json' % (params.channel_name)) file_categories = open(file_path).read() json_categories = json.loads(file_categories) @@ -227,7 +238,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -259,12 +270,12 @@ def list_videos(params): video_json = open(file_json).read() json_parser = json.loads(video_json) - video_title = '' program_title = '' for program in json_parser["tags"]: program_title = program.upper() + ' - ' - video_title = program_title + json_parser["name"].encode('utf-8').lower() + video_title = program_title + \ + json_parser["name"].encode('utf-8').lower() video_img = '' for poster in json_parser["poster_sources"]: video_img = poster["src"] @@ -344,11 +355,12 @@ def list_videos(params): category = video['category'].encode('utf-8') title = video['title'].encode('utf-8') description = video['description'].encode('utf-8') - begin_date = video['begin_date'] # 1486725600, + # begin_date = video['begin_date'] # 1486725600, image = video['image'].encode('utf-8') duration = video['video_duration_ms'] / 1000 - value_date = time.strftime('%d %m %Y', time.localtime(video["begin_date"])) + value_date = time.strftime( + '%d %m %Y', time.localtime(video["begin_date"])) date = str(value_date).split(' ') day = date[0] mounth = date[1] @@ -423,7 +435,7 @@ def list_videos(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -480,7 +492,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -515,7 +527,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -524,22 +536,27 @@ def list_live(params): 'info': info }) - #BFM PARIS + # BFM PARIS file_paris_path = utils.download_catalog( URL_LIVE_BFM_PARIS, 'bfm_paris_live.html') live_paris_html = open(file_paris_path).read() live_paris_soup = bs(live_paris_html, 'html.parser') - data_live_paris_soup = live_paris_soup.find('div', class_='BCLvideoWrapper') + data_live_paris_soup = live_paris_soup.find( + 'div', class_='BCLvideoWrapper') - data_account_paris = data_live_paris_soup.find('script')['data-account'] - data_video_id_paris = data_live_paris_soup.find('script')['data-video-id'] - data_player_paris = data_live_paris_soup.find('script')['data-player'] + data_account_paris = data_live_paris_soup.find( + 'script')['data-account'] + data_video_id_paris = data_live_paris_soup.find( + 'script')['data-video-id'] + data_player_paris = data_live_paris_soup.find( + 'script')['data-player'] # Method to get JSON from 'edge.api.brightcove.com' file_json_paris = utils.download_catalog( - URL_VIDEO_JSON_BRIGHTCOVE % (data_account_paris, data_video_id_paris), + URL_VIDEO_JSON_BRIGHTCOVE % ( + data_account_paris, data_video_id_paris), '%s_%s_live.json' % (data_account_paris, data_video_id_paris), force_dl=False, request_type='get', @@ -554,7 +571,8 @@ def list_live(params): title_paris = json_parser_paris["name"] plot_paris = '' if json_parser_paris["long_description"]: - plot_paris = json_parser_paris["long_description"].encode('utf-8') + plot_paris = json_parser_paris["long_description"] + plot_paris = plot_paris.encode('utf-8') for url_paris in json_parser_paris["sources"]: url_live_paris = url_paris["src"].encode('utf-8') @@ -571,7 +589,7 @@ def list_live(params): 'label': title_paris, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live_paris, @@ -582,7 +600,7 @@ def list_live(params): elif params.channel_name == 'bfmbusiness': - #BFM BUSINESS + # BFM BUSINESS file_path = utils.download_catalog( URL_LIVE_BFMBUSINESS, '%s_live.html' % (params.channel_name)) @@ -630,7 +648,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -641,7 +659,7 @@ def list_live(params): elif params.channel_name == 'rmc': - #BFM SPORT + # BFM SPORT file_path = utils.download_catalog( URL_LIVE_BFM_SPORT, 'bfm_sport_live.html') @@ -690,7 +708,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -713,18 +731,23 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_l': return params.url_live elif params.channel_name == 'rmcdecouverte' and params.next == 'play_r': return params.video_url - elif params.channel_name == 'rmcdecouverte' and params.next == 'download_video': + elif params.channel_name == 'rmcdecouverte' and \ + params.next == 'download_video': return URL_VIDEO_HTML_RMCDECOUVERTE % (params.video_id) - elif params.channel_name != 'rmcdecouverte' and (params.next == 'play_r' or params.next == 'download_video'): + elif params.channel_name != 'rmcdecouverte' and \ + (params.next == 'play_r' or params.next == 'download_video'): file_medias = utils.get_webcontent( - URL_VIDEO % (params.channel_name, get_token(params.channel_name), params.video_id)) + URL_VIDEO % ( + params.channel_name, + get_token(params.channel_name), params.video_id)) json_parser = json.loads(file_medias) if params.next == 'download_video': @@ -739,22 +762,23 @@ def get_video_url(params): for datas in video_streams: new_list_item = common.sp.xbmcgui.ListItem() new_list_item.setLabel( - "Video Height : " + str(datas['frame_height']) + \ + "Video Height : " + str(datas['frame_height']) + " (Encoding : " + str(datas['encoding_rate']) + ")" ) new_list_item.setPath(datas['video_url']) all_datas_videos.append(new_list_item) - seleted_item = common.sp.xbmcgui.Dialog().select("Choose Stream", all_datas_videos) + seleted_item = common.sp.xbmcgui.Dialog().select( + "Choose Stream", all_datas_videos) return all_datas_videos[seleted_item].getPath().encode('utf-8') elif desired_quality == 'BEST': - #GET LAST NODE (VIDEO BEST QUALITY) + # GET LAST NODE (VIDEO BEST QUALITY) url_best_quality = '' for datas in video_streams: url_best_quality = datas['video_url'].encode('utf-8') return url_best_quality else: - #DEFAULT VIDEO + # DEFAULT VIDEO return json_parser['video']['video_url'].encode('utf-8') diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/france24.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/france24.py index 6d61ec9..a7a65c5 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/france24.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/france24.py @@ -25,14 +25,14 @@ import time import re import json from bs4 import BeautifulSoup as bs +from youtube_dl import YoutubeDL from resources.lib import utils from resources.lib import common # TO DO -# Replay (emission) | (just 5 first episodes) Add More Button (with api) to download just some part ? (More Work TO DO) +# Replay (emission) | (just 5 first episodes) +# Add More Button (with api) to download just some part ? (More Work TO DO) # Add info LIVE TV (picture, plot) -# Add Video, Last JT, Last ECO, Last Meteo -# Select Language settings not show # Initialize GNU gettext emulation in addon # This allows to use UI strings from addon’s English @@ -45,10 +45,12 @@ URL_LIVE_SITE = 'http://www.france24.com/%s/' URL_INFO_LIVE = 'http://www.france24.com/%s/_fragment/player/nowplaying/' # Language -URL_API_VOD = 'http://api.france24.com/%s/services/json-rpc/emission_list?databases=f24%s&key=XXX' \ +URL_API_VOD = 'http://api.france24.com/%s/services/json-rpc/' \ + 'emission_list?databases=f24%s&key=XXX' \ '&start=0&limit=50&edition_start=0&edition_limit=5' # language + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -61,32 +63,52 @@ def channel_entry(params): return list_live(params) elif 'play' in params.next: return get_video_url(params) + elif 'list_nwb' in params.next: + return list_nwb(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] + desired_language = common.PLUGIN.get_setting( + params.channel_id + '.language') + # Add Replay - modes.append({ - 'label' : 'Replay', - 'url': common.PLUGIN.get_url( - action='channel_entry', - next='list_shows_1', - category='%s Replay' % params.channel_name.upper(), - window_title='%s Replay' % params.channel_name.upper() - ), - }) + if desired_language != 'ES': + modes.append({ + 'label': 'Replay', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_1', + category='%s Replay' % params.channel_name.upper(), + window_title='%s Replay' % params.channel_name.upper() + ), + }) # Add Live + if desired_language != 'ES': + modes.append({ + 'label': 'Live TV', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='live_cat', + category='%s Live TV' % params.channel_name.upper(), + window_title='%s Live TV' % params.channel_name.upper() + ), + }) + modes.append({ - 'label' : 'Live TV', + 'label': 'News - Weather - Business', 'url': common.PLUGIN.get_url( action='channel_entry', - next='live_cat', - category='%s Live TV' % params.channel_name.upper(), - window_title='%s Live TV' % params.channel_name.upper() + next='list_nwb_1', + category='%s News - Weather - Business' % ( + params.channel_name.upper()), + window_title='%s News - Weather - Business' % ( + params.channel_name.upper()) ), }) @@ -98,7 +120,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -108,13 +131,17 @@ def list_shows(params): if params.next == 'list_shows_1': file_path = utils.download_catalog( - URL_API_VOD % (desired_language.lower(),desired_language.lower()), - '%s_%s_vod.json' % (params.channel_name,desired_language.lower()) + URL_API_VOD % ( + desired_language.lower(), desired_language.lower()), + '%s_%s_vod.json' % ( + params.channel_name, desired_language.lower()) ) json_vod = open(file_path).read() json_parser = json.loads(json_vod) - list_caterories = json_parser["result"]["f24%s" % desired_language.lower()]["list"] + list_caterories = json_parser["result"] + list_caterories = list_caterories["f24%s" % desired_language.lower()] + list_caterories = list_caterories["list"] for category in list_caterories: category_name = category["title"].encode('utf-8') @@ -144,7 +171,8 @@ def list_shows(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -159,7 +187,9 @@ def list_videos(params): json_vod = open(file_path).read() json_parser = json.loads(json_vod) - list_caterories = json_parser["result"]["f24%s" % desired_language.lower()]["list"] + list_caterories = json_parser["result"] + list_caterories = list_caterories["f24%s" % desired_language.lower()] + list_caterories = list_caterories["list"] for category in list_caterories: if str(params.nid) == str(category["nid"]): for video in category["editions"]["list"]: @@ -169,7 +199,8 @@ def list_videos(params): img = video["image"][0]["original"].encode('utf-8') url = video["video"][0]["mp4-mbr"].encode('utf-8') - value_date = time.strftime('%d %m %Y', time.localtime(int(video["created"]))) + value_date = time.strftime( + '%d %m %Y', time.localtime(int(video["created"]))) date = str(value_date).split(' ') day = date[0] mounth = date[1] @@ -182,9 +213,9 @@ def list_videos(params): 'title': title, 'aired': aired, 'date': date, - #'duration': video_duration, + # 'duration': video_duration, 'year': year, - 'plot' : plot, + 'plot': plot, 'mediatype': 'tvshow' } } @@ -212,7 +243,6 @@ def list_videos(params): 'context_menu': context_menu }) - # TO DO add More button Video return common.PLUGIN.create_listing( @@ -223,7 +253,8 @@ def list_videos(params): ), content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -246,14 +277,18 @@ def list_live(params): html_live = open(file_path).read() root_soup = bs(html_live, 'html.parser') - json_parser = json.loads(root_soup.select_one("script[type=application/json]").text) - media_datas_list = json_parser['medias']['media']['media_sources']['media_source'] + json_parser = json.loads( + root_soup.select_one("script[type=application/json]").text) + media_datas_list = json_parser['medias']['media'] + media_datas_list = media_datas_list['media_sources']['media_source'] for datas in media_datas_list: if datas['source']: url_live = datas['source'] - live_info = utils.get_webcontent(URL_INFO_LIVE % (desired_language.lower())) - title = re.compile('id="main-player-playing-value">(.+?)<').findall(live_info)[0] + live_info = utils.get_webcontent( + URL_INFO_LIVE % (desired_language.lower())) + title = re.compile( + 'id="main-player-playing-value">(.+?)<').findall(live_info)[0] info = { 'video': { @@ -267,7 +302,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -284,11 +319,100 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_nwb(params): + """Build News - Weather - Business listing""" + nbe = [] + + desired_language = common.PLUGIN.get_setting( + params.channel_id + '.language') + + url_news = '' + url_weather = '' + url_business = '' + + if 'FR' == desired_language: + url_news = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/journal-info' + url_weather = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/meteo-internationale' + url_business = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/journal-economie' + elif 'ES' == desired_language: + url_news = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/ultimo-noticiero' + url_weather = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/el-tiempo' + url_business = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/economia' + elif 'EN' == desired_language or 'AR' == desired_language: + url_news = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/latest-news' + url_weather = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/international-weather-forecast' + url_business = URL_LIVE_SITE % desired_language.lower() + \ + 'vod/business-news' + + url_nbe_list = [] + url_nbe_list.append(url_news) + url_nbe_list.append(url_weather) + url_nbe_list.append(url_business) + + ydl = YoutubeDL() + + for url_nbe in url_nbe_list: + url_nbe_html = utils.get_webcontent(url_nbe) + root_soup = bs(url_nbe_html, 'html.parser') + url_nbe_yt_html = utils.get_webcontent( + root_soup.find( + 'div', class_='yt-vod-container').find('iframe').get('src')) + url_yt = re.compile( + '<link rel="canonical" href="(.*?)"').findall(url_nbe_yt_html)[0] + ydl.add_default_info_extractors() + with ydl: + result = ydl.extract_info(url_yt, download=False) + for format_video in result['formats']: + url_nbe_stream = format_video['url'] + title = result['title'] + plot = '' + duration = 0 + img = result['thumbnail'] + + info = { + 'video': { + 'title': title, + 'plot': plot, + 'duration': duration + } + } + + nbe.append({ + 'label': title, + 'fanart': img, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + url=url_nbe_stream, + ), + 'is_playable': True, + 'info': info + }) + + return common.PLUGIN.create_listing( + nbe, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ) + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_l': return params.url elif params.next == 'play_r' or params.next == 'download_video': return params.url - diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/groupecanal.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/groupecanal.py index f2e5f84..ecedfdb 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/groupecanal.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/groupecanal.py @@ -30,7 +30,8 @@ from resources.lib import common # TO DO -# Replay (More Refactoring todo) / Find API for all channel (JSON) get Replay/Live ? +# Replay (More Refactoring todo) / +# Find API for all channel (JSON) get Replay/Live ? # Get URL Live FROM SITE # QUALITY # Add Button "More Videos" @@ -49,14 +50,17 @@ URL_LIVE_CNEWS = 'http://www.cnews.fr/direct' # Replay Cplus : URL_ROOT_CPLUS = 'http://www.canalplus.fr' -URL_LIST_EMISSIONS_CPLUS = 'http://www.canalplus.fr/pid8034-les-emissions-de-canal.html' +URL_LIST_EMISSIONS_CPLUS = 'http://www.canalplus.fr/' \ + 'pid8034-les-emissions-de-canal.html' # Replay C8 & CStar -URL_REPLAY_C8__CSTAR_ROOT = 'http://lab.canal-plus.pro/web/app_prod.php/api/replay/%s' +URL_REPLAY_C8__CSTAR_ROOT = 'http://lab.canal-plus.pro/' \ + 'web/app_prod.php/api/replay/%s' # Channel id : # c8 : 1 # cstar : 2 -URL_REPLAY_C8__CSTAR_SHOWS = 'http://lab.canal-plus.pro/web/app_prod.php/api/pfv/list/%s/%s' +URL_REPLAY_C8__CSTAR_SHOWS = 'http://lab.canal-plus.pro/' \ + 'web/app_prod.php/api/pfv/list/%s/%s' # channel_id/show_id # Replay CNews @@ -65,7 +69,8 @@ URL_VIDEOS_CNEWS = URL_ROOT_SITE + '/videos/' URL_EMISSIONS_CNEWS = URL_ROOT_SITE + '/emissions' # Replay/Live => Parameters Channel, VideoId -URL_INFO_CONTENT = 'http://service.canal-plus.com/video/rest/getvideos/%s/%s?format=json' +URL_INFO_CONTENT = 'http://service.canal-plus.com/' \ + 'video/rest/getvideos/%s/%s?format=json' CHANNEL_NAME_CATALOG = { 'cplus': 'cplus', @@ -79,6 +84,7 @@ CHANNEL_NAME_CATALOG = { # strings.po file instead of numeric codes _ = common.ADDON.initialize_gettext() + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -93,14 +99,17 @@ def channel_entry(params): return get_video_url(params) return None + +""" Unused def get_token(): - """Get session token""" token_json = utils.get_webcontent(URL_REPLAY_CPLUS_AUTH) token_json = json.loads(token_json) token = token_json['token'] return token +""" -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_channel_id(params): """Get channel id by name""" if params.channel_name == 'c8': @@ -108,14 +117,15 @@ def get_channel_id(params): elif params.channel_name == 'cstar': return '2' -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -126,7 +136,7 @@ def root(params): # Add Live modes.append({ - 'label' : _('Live TV'), + 'label': _('Live TV'), 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -143,12 +153,13 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Create categories list""" shows = [] - ################### BEGIN CNEWS ########################### + # ################## BEGIN CNEWS ########################### if params.next == 'list_shows_1' and params.channel_name == 'cnews': file_path = utils.download_catalog( @@ -165,7 +176,8 @@ def list_shows(params): for category in categories_soup: category_name = category.get_text().encode('utf-8') - category_url = (URL_ROOT_SITE % params.channel_name) + category.get('href') + category_url = ( + URL_ROOT_SITE % params.channel_name) + category.get('href') if category_name != 'Les tops': shows.append({ @@ -186,7 +198,7 @@ def list_shows(params): file_path = utils.download_catalog( params.category_url, '%s_%s.html' % ( - params.channel_name,params.category_name)) + params.channel_name, params.category_name)) root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') categories_soup = root_soup.find_all('a', class_="checkbox") @@ -194,7 +206,8 @@ def list_shows(params): for category in categories_soup: category_name = category.get_text().encode('utf-8') - category_url = (URL_ROOT_SITE % params.channel_name) + category.get('href') + category_url = ( + URL_ROOT_SITE % params.channel_name) + category.get('href') shows.append({ 'label': category_name, @@ -221,7 +234,10 @@ def list_shows(params): for category in categories_soup: category_name = category.find('h3').get_text().encode('utf-8') - category_url = (URL_VIDEOS_CNEWS % params.channel_name) + '/emissions' + category.find('a').get('href').split('.fr')[1] + category_url = ( + URL_VIDEOS_CNEWS % params.channel_name) + \ + '/emissions' + \ + category.find('a').get('href').split('.fr')[1] category_img = category.find('img').get('src').encode('utf-8') shows.append({ @@ -238,12 +254,12 @@ def list_shows(params): ) }) + # ################## END CNEWS ########################### - ################### END CNEWS ########################### - - ################### BEGIN C8 and CStar ################## - elif params.next == 'list_shows_1' and (params.channel_name == 'c8' or \ - params.channel_name == 'cstar'): + # ################## BEGIN C8 and CStar ################## + elif params.next == 'list_shows_1' and \ + (params.channel_name == 'c8' or + params.channel_name == 'cstar'): file_path = utils.download_catalog( URL_REPLAY_C8__CSTAR_ROOT % get_channel_id(params), '%s.json' % (params.channel_name)) @@ -265,8 +281,9 @@ def list_shows(params): ) }) - elif params.next == 'list_shows_2' and (params.channel_name == 'c8' or \ - params.channel_name == 'cstar'): + elif params.next == 'list_shows_2' and \ + (params.channel_name == 'c8' or + params.channel_name == 'cstar'): # Create category's programs list file_path = utils.download_catalog( URL_REPLAY_C8__CSTAR_ROOT % get_channel_id(params), @@ -294,9 +311,9 @@ def list_shows(params): window_title=title ) }) - ################### END C8 and CStar ################## + # ################## END C8 and CStar ################## - ################### BEGIN CANAL + ################## + # ################## BEGIN CANAL + ################## elif params.next == 'list_shows_1' and params.channel_name == 'cplus': file_path = utils.download_catalog( @@ -333,7 +350,7 @@ def list_shows(params): file_path = utils.download_catalog( params.category_url, '%s_%s.html' % ( - params.channel_name,params.category_name)) + params.channel_name, params.category_name)) root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') @@ -355,7 +372,7 @@ def list_shows(params): ) }) - ################### END CANAL + ################## + # ################## END CANAL + ################## return common.PLUGIN.create_listing( shows, @@ -365,21 +382,23 @@ def list_shows(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] if 'previous_listing' in params: videos = ast.literal_eval(params['previous_listing']) - ################### BEGIN CNEWS ########################### + # ################## BEGIN CNEWS ########################### if params.channel_name == 'cnews': url_page = params.category_url + '/page/%s' % params.page file_path = utils.download_catalog( url_page, - '%s_%s_%s.html' % (params.channel_name, params.category_name, params.page)) + '%s_%s_%s.html' % ( + params.channel_name, params.category_name, params.page)) root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') @@ -388,15 +407,19 @@ def list_videos(params): for program in programs: title = program.find('h3').get_text().encode('utf-8') thumb = program.find('img').get('src').encode('utf-8') - #Get Video_ID - video_html = utils.get_webcontent(program.find('a').get('href').encode('utf-8')) + # Get Video_ID + video_html = utils.get_webcontent( + program.find('a').get('href').encode('utf-8')) id = re.compile(r'videoId=(.*?)"').findall(video_html)[0] - #Get Description + # Get Description datas_video = bs(video_html, 'html.parser') - description = datas_video.find('article', class_='entry-body').get_text().encode('utf-8') + description = datas_video.find( + 'article', class_='entry-body').get_text().encode('utf-8') duration = 0 - date = re.compile(r'property="video:release_date" content="(.*?)"').findall(video_html)[0].split('T')[0].split('-') + date = re.compile( + r'property="video:release_date" content="(.*?)"' + ).findall(video_html)[0].split('T')[0].split('-') day = date[2] mounth = date[1] year = date[0] @@ -412,14 +435,14 @@ def list_videos(params): 'date': date, 'duration': duration, 'year': year, - #'genre': category, + # 'genre': category, 'mediatype': 'tvshow' } } context_menu = [] download_video = ( - _('Download'), + _('Download'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url( action='download_video', id=id) + ')' @@ -453,12 +476,13 @@ def list_videos(params): previous_listing=str(videos) ), }) - ################### END CNEWS ########################### + # ################## END CNEWS ########################### - ################### BEGIN C8 and CStar ################## + # ################## BEGIN C8 and CStar ################## elif params.channel_name == 'c8' or params.channel_name == 'cstar': file_path = utils.download_catalog( - URL_REPLAY_C8__CSTAR_SHOWS % (get_channel_id(params), params.videos_recent), + URL_REPLAY_C8__CSTAR_SHOWS % ( + get_channel_id(params), params.videos_recent), '%s_%s.json' % (params.channel_name, params.videos_recent)) file_videos = open(file_path).read() videos_json = json.loads(file_videos) @@ -467,13 +491,15 @@ def list_videos(params): id = video['ID'].encode('utf-8') try: duration = int(video['DURATION'].encode('utf-8')) - except: + except Exception: duration = 0 description = video['INFOS']['DESCRIPTION'].encode('utf-8') views = int(video['INFOS']['NB_VUES'].encode('utf-8')) try: - date_video = video['INFOS']['DIFFUSION']['DATE'].encode('utf-8') # 31/12/2017 - except: + date_video = video['INFOS'] # 31/12/2017 + date_video = date_video['DIFFUSION']['DATE'] + date_video = date_video.encode('utf-8') + except Exception: date_video = "00/00/0000" day = date_video.split('/')[0] mounth = date_video.split('/')[1] @@ -523,14 +549,17 @@ def list_videos(params): 'info': info, 'context_menu': context_menu }) - ################### END C8 and CStar ################## + # ################## END C8 and CStar ################## - ################### BEGIN Canal + ################## + # ################## BEGIN Canal + ################## elif params.channel_name == 'cplus': file_path = utils.download_catalog( params.category_url, - '%s_%s_%s.html' % (params.channel_name, params.category_name, params.category_section)) + '%s_%s_%s.html' % ( + params.channel_name, + params.category_name, + params.category_section)) root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') @@ -544,7 +573,10 @@ def list_videos(params): if section.get_text().encode('utf-8') == params.category_section: break - videos_sections_soup = sections_soup.find_all('ul', class_="features features-alt features-alt-videov3-4x3 features-alt-videov3-4x3-noMarge") + videos_sections_soup = sections_soup.find_all( + 'ul', + class_="features features-alt features-alt-videov3-4x3" + " features-alt-videov3-4x3-noMarge") for videos_section in videos_sections_soup: j = j + 1 if i == j: @@ -553,7 +585,8 @@ def list_videos(params): for data_video in data_videos: title = data_video.find('h4').get('title').encode('utf-8') - description = data_video.find('p').find('a').get_text().strip().encode('utf-8') + description = data_video.find( + 'p').find('a').get_text().strip().encode('utf-8') duration = 0 thumb = data_video.find('img').get('src').encode('utf-8') id = data_video.get('id').split('_')[1] @@ -562,18 +595,18 @@ def list_videos(params): 'video': { 'title': title, 'plot': description, - #'aired': aired, - #'date': date, + # 'aired': aired, + # 'date': date, 'duration': duration, - #'year': year, - #'genre': category, + # 'year': year, + # 'genre': category, 'mediatype': 'tvshow' } } context_menu = [] download_video = ( - _('Download'), + _('Download'), 'XBMC.RunPlugin(' + common.PLUGIN.get_url( action='download_video', id=id) + ')' @@ -594,7 +627,7 @@ def list_videos(params): 'context_menu': context_menu }) - ################### END Canal + ################## + # ################## END Canal + ################## return common.PLUGIN.create_listing( videos, @@ -610,7 +643,8 @@ def list_videos(params): update_listing='update_listing' in params, ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -641,12 +675,15 @@ def list_live(params): if params.channel_name == 'cnews': video_id_re = re.compile(r'content: \'(.*?)\'').findall(html_live) - else : - video_id_re = re.compile(r'\bdata-video="(?P<video_id>[0-9]+)"').findall(html_live) + else: + video_id_re = re.compile( + r'\bdata-video="(?P<video_id>[0-9]+)"').findall(html_live) file_path_json = utils.download_catalog( - URL_INFO_CONTENT % (CHANNEL_NAME_CATALOG[params.channel_name], video_id_re[0]), - '%s_%s_live.json' % (CHANNEL_NAME_CATALOG[params.channel_name], video_id_re[0]) + URL_INFO_CONTENT % ( + CHANNEL_NAME_CATALOG[params.channel_name], video_id_re[0]), + '%s_%s_live.json' % ( + CHANNEL_NAME_CATALOG[params.channel_name], video_id_re[0]) ) file_live_json = open(file_path_json).read() json_parser = json.loads(file_live_json) @@ -668,7 +705,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -685,12 +722,14 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': file_video = utils.get_webcontent( - URL_INFO_CONTENT % (CHANNEL_NAME_CATALOG[params.channel_name],params.id) + URL_INFO_CONTENT % ( + CHANNEL_NAME_CATALOG[params.channel_name], params.id) ) media_json = json.loads(file_video) return media_json['MEDIA']['VIDEOS']['HLS'].encode('utf-8') diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py index 79dedad..ac14879 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py @@ -40,11 +40,11 @@ SECRET_KEY = '19nBVBxv791Xs' CATEGORIES = {} CATEGORIES['Dessins animés'] = 'http://sslreplay.gulli.fr/replay/api?' \ - 'call=%%7B%%22api_key%%22:%%22%s%%22,%%22method' \ - '%%22:%%22programme.getLatestEpisodes%%22,%%' \ - '22params%%22:%%7B%%22program_image_thumb%%' \ - '22:%%5B310,230%%5D,%%22category_id%%22:%%22' \ - 'dessins-animes%%22%%7D%%7D' + 'call=%%7B%%22api_key%%22:%%22%s%%22,%%22' \ + 'method%%22:%%22programme.getLatest' \ + 'Episodes%%22,%%22params%%22:%%7B%%22' \ + 'program_image_thumb%%22:%%5B310,230%%5D,%%22' \ + 'category_id%%22:%%22dessins-animes%%22%%7D%%7D' CATEGORIES['Émissions'] = 'https://sslreplay.gulli.fr/replay/api?' \ 'call=%%7B%%22api_key%%22:%%22%s%%22,%%22method' \ @@ -54,11 +54,11 @@ CATEGORIES['Émissions'] = 'https://sslreplay.gulli.fr/replay/api?' \ 'emissions%%22%%7D%%7D' CATEGORIES['Séries & films'] = 'https://sslreplay.gulli.fr/replay/api?' \ - 'call=%%7B%%22api_key%%22:%%22%s%%22,%%22method' \ - '%%22:%%22programme.getLatestEpisodes%%22,%%' \ - '22params%%22:%%7B%%22program_image_thumb%%' \ - '22:%%5B310,230%%5D,%%22category_id%%22:%%22' \ - 'series%%22%%7D%%7D' + 'call=%%7B%%22api_key%%22:%%22%s%%22,%%2' \ + '2method%%22:%%22programme.getLatest' \ + 'Episodes%%22,%%22params%%22:%%7B%%22program_' \ + 'image_thumb%%22:%%5B310,230%%5D,%%22category' \ + '_id%%22:%%22series%%22%%7D%%7D' URL_LIST_SHOW = 'https://sslreplay.gulli.fr/replay/api?call=%%7B%%22api_key' \ '%%22:%%22%s%%22,%%22' \ @@ -70,6 +70,7 @@ URL_LIVE_TV = 'http://replay.gulli.fr/Direct' # program_id + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -85,7 +86,7 @@ def channel_entry(params): return None -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_api_key(): """Compute the API key""" date = time.strftime("%Y%m%d") @@ -94,14 +95,14 @@ def get_api_key(): return 'iphoner_' + key -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -112,7 +113,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -129,7 +130,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -190,7 +192,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -272,7 +274,7 @@ def list_videos(params): content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -303,7 +305,8 @@ def list_live(params): params.channel_name + '_live_embeded.html') root_live_embeded_html = open(file_path_2).read() - all_url_video = re.compile(r'file: \'(.*?)\'').findall(root_live_embeded_html) + all_url_video = re.compile( + r'file: \'(.*?)\'').findall(root_live_embeded_html) for url_video in all_url_video: if url_video.count('m3u8') > 0: @@ -323,7 +326,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -340,7 +343,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/lcp.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/lcp.py index e1065d9..60de692 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/lcp.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/lcp.py @@ -47,8 +47,10 @@ URL_LIVE_SITE = 'http://www.lcp.fr/le-direct' URL_DAILYMOTION_EMBED = 'http://www.dailymotion.com/embed/video/%s' -URL_VIDEO_REPLAY = 'http://play1.qbrick.com/config/avp/v1/player/media/%s/darkmatter/%s/' -#VideoID, AccountId +URL_VIDEO_REPLAY = 'http://play1.qbrick.com/config/avp/v1/player/' \ + 'media/%s/darkmatter/%s/' +# VideoID, AccountId + def channel_entry(params): """Entry function of the module""" @@ -63,35 +65,37 @@ def channel_entry(params): elif 'play' in params.next: return get_video_url(params) + CATEGORIES = { - 'http://www.lcp.fr/actualites' : 'Actualités', - 'http://www.lcp.fr/emissions' : 'Émissions', - 'http://www.lcp.fr/documentaires' : 'Documentaires' + 'http://www.lcp.fr/actualites': 'Actualités', + 'http://www.lcp.fr/emissions': 'Émissions', + 'http://www.lcp.fr/documentaires': 'Documentaires' } CORRECT_MOUNTH = { - 'janvier' : '01', - 'février' : '02', - 'mars' : '03', - 'avril' : '04', - 'mai' : '05', - 'juin' : '06', - 'juillet' : '07', - 'août' : '08', - 'septembre' : '09', - 'octobre' : '10', - 'novembre' : '11', - 'décembre' : '12' + 'janvier': '01', + 'février': '02', + 'mars': '03', + 'avril': '04', + 'mai': '05', + 'juin': '06', + 'juillet': '07', + 'août': '08', + 'septembre': '09', + 'octobre': '10', + 'novembre': '11', + 'décembre': '12' } -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay Desactiver modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -102,7 +106,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -119,7 +123,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -174,26 +179,27 @@ def list_shows(params): root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') - emissions_soup = root_soup.find_all('div',class_='content') + emissions_soup = root_soup.find_all('div', class_='content') for emission in emissions_soup: emission_name = emission.find('h2').get_text().encode('utf-8') emission_img = emission.find('img')['src'].encode('utf-8') - emission_url = URL_ROOT + emission.find('a')['href'].encode('utf-8') + emission_url = URL_ROOT + emission.find( + 'a')['href'].encode('utf-8') shows.append({ - 'label': emission_name, - 'thumb': emission_img, - 'url': common.PLUGIN.get_url( - action='channel_entry', - emission_url=emission_url, - emission_name=emission_name, - page='0', - next='list_videos_emissions', - window_title=emission_name - ) - }) + 'label': emission_name, + 'thumb': emission_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + emission_url=emission_url, + emission_name=emission_name, + page='0', + next='list_videos_emissions', + window_title=emission_name + ) + }) return common.PLUGIN.create_listing( shows, @@ -203,7 +209,8 @@ def list_shows(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -227,28 +234,34 @@ def list_videos(params): root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') - video_soup = root_soup.find_all('div', class_="node node-lcp-tv-episode node-teaser clearfix") + video_soup = root_soup.find_all( + 'div', class_="node node-lcp-tv-episode node-teaser clearfix") for video in video_soup: title = video.find('h2').find('a').get_text().encode('utf-8') - value_date = video.find('div', class_="content").find('span', class_="date").get_text().encode('utf-8') + value_date = video.find( + 'div', class_="content").find( + 'span', class_="date").get_text().encode('utf-8') date = value_date.split(' ') day = date[0] try: mounth = CORRECT_MOUNTH[date[1]] - except: + except Exception: mounth = '00' year = date[2] date = '.'.join((day, mounth, year)) aired = '-'.join((year, mounth, day)) duration = 0 - duration = int(video.find('div', class_="content").find('div', class_="duration").find('div').find('span').get_text()) * 60 + duration = int( + video.find( + 'div', class_="content").find( + 'div', class_="duration").find( + 'div').find('span').get_text()) * 60 img = video.find('a').find('img')['src'].encode('utf-8') url_video = URL_ROOT + video['about'].encode('utf-8') - info = { 'video': { 'title': title, @@ -282,7 +295,7 @@ def list_videos(params): ), 'is_playable': True, 'info': info, - 'context_menu': context_menu # A ne pas oublier pour ajouter le bouton "Download" à chaque vidéo + 'context_menu': context_menu }) # More videos... @@ -315,20 +328,24 @@ def list_videos(params): root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') - video_soup = root_soup.find_all('div', class_="node node-lcp-reportage node-promoted node-teaser actu-teaser clearfix") + video_soup = root_soup.find_all( + 'div', + class_="node node-lcp-reportage " + "node-promoted node-teaser actu-teaser clearfix") for video in video_soup: title = video.find('h2').find('a').get_text().encode('utf-8') - aired = video.find('div', class_="content").find('div', class_="field field_submitted").get_text() + aired = video.find( + 'div', class_="content").find( + 'div', class_="field field_submitted").get_text() date = '' duration = 0 - year = int(aired.split('/',-1)[2]) + year = int(aired.split('/', -1)[2]) img = video.find('a').find('img')['src'].encode('utf-8') url_video = URL_ROOT + video['about'].encode('utf-8') - info = { 'video': { 'title': title, @@ -362,7 +379,7 @@ def list_videos(params): ), 'is_playable': True, 'info': info, - 'context_menu': context_menu # A ne pas oublier pour ajouter le bouton "Download" à chaque vidéo + 'context_menu': context_menu }) # More videos... @@ -382,11 +399,14 @@ def list_videos(params): elif params.next == 'list_videos_emissions': # Cas emission (2 cas) (-0) ou (sans -0) - # 1ère page http://www.lcp.fr/emissions/evenements/replay-0 (url départ => http://www.lcp.fr/emissions/evenements-0) + # 1ère page http://www.lcp.fr/emissions/evenements/replay-0 + # (url départ => http://www.lcp.fr/emissions/evenements-0) # 1ère page http://www.lcp.fr/emissions/evenements/replay-0?page=1 # ainsi de suite - # 1ère page : http://www.lcp.fr/emissions/en-voiture-citoyens/replay (url départ => http://www.lcp.fr/emissions/en-voiture-citoyens) - # 2ème page : http://www.lcp.fr/emissions/en-voiture-citoyens/replay?page=1 + # 1ère page : http://www.lcp.fr/emissions/en-voiture-citoyens/replay + # (url départ => http://www.lcp.fr/emissions/en-voiture-citoyens) + # 2ème page : + # http://www.lcp.fr/emissions/en-voiture-citoyens/replay?page=1 # ainsi de suite if params.page == 0 and '-0' not in params.emission_url: @@ -396,7 +416,8 @@ def list_videos(params): elif params.page == 0 and '-0' in params.emission_url: url = params.emission_url[:-2] + '/replay-0' elif params.page > 0 and '-0' in params.emission_url: - url = params.emission_url[:-2] + '/replay-0?page=' + str(params.page) + url = params.emission_url[:-2] + \ + '/replay-0?page=' + str(params.page) file_path = utils.download_catalog( url, @@ -407,29 +428,36 @@ def list_videos(params): root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') - video_soup = root_soup.find_all('div', class_="node node-lcp-tv-episode node-teaser clearfix") + video_soup = root_soup.find_all( + 'div', class_="node node-lcp-tv-episode node-teaser clearfix") for video in video_soup: - title = video.find('h2').find('a').get_text().encode('utf-8') + ' - ' + video.find('h4').find('a').get_text().encode('utf-8') - value_date = video.find('div', class_="content").find('span', class_="date").get_text().encode('utf-8') + title = video.find( + 'h2').find('a').get_text().encode( + 'utf-8') + ' - ' + video.find( + 'h4').find('a').get_text().encode('utf-8') + value_date = video.find( + 'div', class_="content").find( + 'span', class_="date").get_text().encode('utf-8') date = value_date.split(' ') day = date[0] try: mounth = CORRECT_MOUNTH[date[1]] - except: + except Exception: mounth = '00' year = date[2] date = '.'.join((day, mounth, year)) aired = '-'.join((year, mounth, day)) duration = 0 - duration = int(video.find('div', class_="content").find('div', class_="duration").find('div').find('span').get_text()) * 60 + duration = int(video.find('div', class_="content").find( + 'div', class_="duration").find( + 'div').find('span').get_text()) * 60 img = video.find('a').find('img')['src'].encode('utf-8') url_video = URL_ROOT + video['about'].encode('utf-8') - info = { 'video': { 'title': title, @@ -463,7 +491,7 @@ def list_videos(params): ), 'is_playable': True, 'info': info, - 'context_menu': context_menu # A ne pas oublier pour ajouter le bouton "Download" à chaque vidéo + 'context_menu': context_menu }) # More videos... @@ -494,7 +522,7 @@ def list_videos(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -512,7 +540,7 @@ def list_live(params): class_='embed-responsive-item') url_live_embeded = live_soup.get('src') - url_live = 'http:%s' % url_live_embeded + url_live = 'http:%s' % url_live_embeded title = '%s Live' % params.channel_name.upper() @@ -528,7 +556,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -545,7 +573,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': @@ -553,24 +582,28 @@ def get_video_url(params): url = '' html_video = utils.get_webcontent(params.url_video) - url_video_embed = re.compile(r'<iframe src="(.*?)"').findall(html_video)[0] + url_video_embed = re.compile( + r'<iframe src="(.*?)"').findall(html_video)[0] if 'dailymotion' in url_video_embed: - url_video_embed_http = 'http:%s' % url_video_embed + url_video_embed_http = 'http:%s' % url_video_embed if params.next == 'download_video': return url_video_embed_http html_video = utils.get_webcontent(url_video_embed_http) html_video = html_video.replace('\\', '') - all_url_video = re.compile(r'"type":"video/mp4","url":"(.*?)"').findall(html_video) + all_url_video = re.compile( + r'"type":"video/mp4","url":"(.*?)"').findall(html_video) for datas in all_url_video: url = datas else: # get videoId and accountId - videoId, accountId = re.compile(r'embed/(.*?)/(.*?)/').findall(url_video_embed)[0] + videoId, accountId = re.compile( + r'embed/(.*?)/(.*?)/').findall(url_video_embed)[0] - html_json = utils.get_webcontent(URL_VIDEO_REPLAY % (videoId, accountId)) + html_json = utils.get_webcontent( + URL_VIDEO_REPLAY % (videoId, accountId)) html_json_2 = re.compile(r'\((.*?)\);').findall(html_json)[0] json_parser = json.loads(html_json_2) @@ -587,8 +620,9 @@ def get_video_url(params): html_live = utils.get_webcontent(params.url) html_live = html_live.replace('\\', '') - url_live = re.compile(r'{"type":"application/x-mpegURL","url":"(.*?)"}]}').findall(html_live) + url_live = re.compile( + r'{"type":"application/x-mpegURL","url":"(.*?)"}]}' + ).findall(html_live) # Just one flux no quality to choose return url_live[0] - diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/lequipe.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/lequipe.py index 3201586..b40af4a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/lequipe.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/lequipe.py @@ -40,12 +40,14 @@ URL_ROOT = 'https://www.lequipe.fr' URL_ROOT_VIDEO_LEQUIPE = 'https://www.lequipe.fr/lachainelequipe/' -URL_REPLAY_VIDEO_LEQUIPE = 'https://www.lequipe.fr/lachainelequipe/morevideos/%s' +URL_REPLAY_VIDEO_LEQUIPE = 'https://www.lequipe.fr/' \ + 'lachainelequipe/morevideos/%s' # Category_id URL_DAILYMOTION_EMBED = 'http://www.dailymotion.com/embed/video/%s' # Video_id + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -61,14 +63,15 @@ def channel_entry(params): else: return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -79,7 +82,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -96,7 +99,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -109,12 +113,14 @@ def list_shows(params): root_html = open(file_path).read() root_soup = bs(root_html, 'html.parser') - categories_soup = root_soup.find_all('a', class_="navtab__item js-tabs-item") + categories_soup = root_soup.find_all( + 'a', class_="navtab__item js-tabs-item") for category in categories_soup: category_name = category.get_text().encode('utf-8') - category_url = URL_REPLAY_VIDEO_LEQUIPE % category.get('data-program-id') + category_url = URL_REPLAY_VIDEO_LEQUIPE % \ + category.get('data-program-id') shows.append({ 'label': category_name, @@ -135,14 +141,13 @@ def list_shows(params): common.sp.xbmcplugin.SORT_METHOD_LABEL)) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] if 'previous_listing' in params: videos = ast.literal_eval(params['previous_listing']) - url = params.category_url + '/' + params.page file_path = utils.download_catalog( url, @@ -163,7 +168,8 @@ def list_videos(params): url = URL_ROOT + program['href'].encode('utf-8') html_video_equipe = utils.get_webcontent(url) video_id = re.compile( - r'<iframe src="//www.dailymotion.com/embed/video/(.*?)\?', re.DOTALL).findall(html_video_equipe)[0] + r'<iframe src="//www.dailymotion.com/embed/video/(.*?)\?', + re.DOTALL).findall(html_video_equipe)[0] title = program.find( 'h2').get_text().encode('utf-8') @@ -253,7 +259,8 @@ def list_videos(params): update_listing='update_listing' in params, ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -262,13 +269,12 @@ def list_live(params): plot = '' duration = 0 img = '' - url_live = '' video_id = '' - url_live = '' html_live_equipe = utils.get_webcontent(URL_ROOT_VIDEO_LEQUIPE) video_id = re.compile( - r'<iframe src="//www.dailymotion.com/embed/video/(.*?)\?', re.DOTALL).findall(html_live_equipe)[0] + r'<iframe src="//www.dailymotion.com/embed/video/(.*?)\?', + re.DOTALL).findall(html_live_equipe)[0] title = '%s Live' % params.channel_name.upper() @@ -284,7 +290,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', video_id=video_id, @@ -302,8 +308,7 @@ def list_live(params): ) - -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" url_video = URL_DAILYMOTION_EMBED % params.video_id @@ -317,11 +322,14 @@ def get_video_url(params): html_video = html_video.replace('\\', '') if params.next == 'play_l': - all_url_video = re.compile(r'{"type":"application/x-mpegURL","url":"(.*?)"').findall(html_video) + all_url_video = re.compile( + r'{"type":"application/x-mpegURL","url":"(.*?)"' + ).findall(html_video) # Just One Quality return all_url_video[0] - elif params.next == 'play_r': - all_url_video = re.compile(r'{"type":"video/mp4","url":"(.*?)"').findall(html_video) + elif params.next == 'play_r': + all_url_video = re.compile( + r'{"type":"video/mp4","url":"(.*?)"').findall(html_video) if desired_quality == "DIALOG": all_datas_videos = [] for datas in all_url_video: @@ -331,7 +339,8 @@ def get_video_url(params): new_list_item.setPath(datas) all_datas_videos.append(new_list_item) - seleted_item = common.sp.xbmcgui.Dialog().select("Choose Stream", all_datas_videos) + seleted_item = common.sp.xbmcgui.Dialog().select( + "Choose Stream", all_datas_videos) return all_datas_videos[seleted_item].getPath().encode('utf-8') elif desired_quality == 'BEST': diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/nrj.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/nrj.py index a313210..9e325d3 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/nrj.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/nrj.py @@ -58,7 +58,9 @@ URL_COMPTE_LOGIN = 'https://www.nrj-play.fr/compte/login' # TO DO add account for using Live Direct URL_LIVE_WITH_TOKEN = 'http://www.nrj-play.fr/compte/live?channel=%s' -# channel (nrj12, ...) - call this url after get session (url live with token inside this page) +# channel (nrj12, ...) - +# call this url after get session (url live with token inside this page) + def channel_entry(params): """Entry function of the module""" @@ -76,14 +78,14 @@ def channel_entry(params): return None -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay with Categories modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -94,7 +96,7 @@ def root(params): # Add Replay modes.append({ - 'label' : 'Replay sans categorie', + 'label': 'Replay sans categorie', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_without_categories', @@ -105,7 +107,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -122,7 +124,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -138,7 +141,7 @@ def list_shows(params): action='channel_entry', state_video=state_video, next='list_videos_1', - #title_category=category_name, + # title_category=category_name, window_title=state_video ) }) @@ -168,7 +171,7 @@ def list_shows(params): action='channel_entry', state_video=state_video, next='list_videos_1', - #title_category=category_name, + # title_category=category_name, window_title=state_video ) }) @@ -186,7 +189,7 @@ def list_shows(params): action='channel_entry', category_name=category_name, next='list_shows_programs', - #title_category=category_name, + # title_category=category_name, window_title=category_name ) }) @@ -198,9 +201,10 @@ def list_shows(params): state_video = 'VIDEOS_BY_CATEGORY' for collection in collections: - if params.category_name == collection.findtext("category").encode('utf-8') \ - or (params.category_name == 'NO_CATEGORY' and \ - collection.findtext("category").encode('utf-8') == ''): + if params.category_name == collection.findtext( + "category").encode('utf-8') \ + or (params.category_name == 'NO_CATEGORY' and + collection.findtext("category").encode('utf-8') == ''): name_program = collection.findtext("name").encode('utf-8') img_program = collection.findtext("picture") id_program = collection.get("id") @@ -213,7 +217,7 @@ def list_shows(params): next='list_videos_1', state_video=state_video, id_program=id_program, - #title_program=name_program, + # title_program=name_program, window_title=name_program ) }) @@ -226,7 +230,8 @@ def list_shows(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -241,12 +246,14 @@ def list_videos(params): xml_elements = ET.XML(replay_xml) - programs = xml_elements.findall("{http://www.sitemaps.org/schemas/sitemap/0.9}url") + programs = xml_elements.findall( + "{http://www.sitemaps.org/schemas/sitemap/0.9}url") for program in programs: url_site = program.findtext( - "{http://www.sitemaps.org/schemas/sitemap/0.9}loc").encode('utf-8') + "{http://www.sitemaps.org/schemas/sitemap/0.9}loc" + ).encode('utf-8') check_string = '%s/replay/' % params.channel_name if url_site.count(check_string) > 0: @@ -355,7 +362,8 @@ def list_videos(params): img = program.find("photos").findtext("photo") # Url Video - url = '' #program.find("offres").find("offre").find("videos").findtext("video) + url = '' + # program.find("offres").find("offre").find("videos").findtext("video) for i in program.find("offres").findall("offre"): date_value = i.get("startdate") @@ -429,7 +437,8 @@ def list_videos(params): img = program.find("photos").findtext("photo") # Url Video - url = '' #program.find("offres").find("offre").find("videos").findtext("video) + url = '' + # program.find("offres").find("offre").find("videos").findtext("video) for i in program.find("offres").findall("offre"): date_value = i.get("startdate") @@ -497,7 +506,8 @@ def list_videos(params): ), content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -512,7 +522,8 @@ def list_live(params): result = session_requests.get(URL_COMPTE_LOGIN) token_form_login = re.compile( - r'name=\"login_form\[_token\]\" value=\"(.*?)\"').findall(result.text)[0] + r'name=\"login_form\[_token\]\" value=\"(.*?)\"' + ).findall(result.text)[0] # Build PAYLOAD payload = { @@ -525,7 +536,7 @@ def list_live(params): # LOGIN result_2 = session_requests.post( - URL_COMPTE_LOGIN, data = payload, headers = dict(referer = URL_COMPTE_LOGIN)) + URL_COMPTE_LOGIN, data=payload, headers=dict(referer=URL_COMPTE_LOGIN)) # GET page with url_live with the session logged result_3 = session_requests.get( @@ -555,7 +566,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url_live=url_live, @@ -572,7 +583,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/numero23.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/numero23.py index 1beab9d..85996d4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/numero23.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/numero23.py @@ -43,6 +43,7 @@ URL_INFO_LIVE_JSON = 'http://www.numero23.fr/wp-content/cache/n23-direct.json' URL_DAILYMOTION_EMBED = 'http://www.dailymotion.com/embed/video/%s' # Video_id + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -58,29 +59,31 @@ def channel_entry(params): else: return None + CORRECT_MONTH = { - 'janvier' : '01', - 'février' : '02', - 'mars' : '03', - 'avril' : '04', - 'mai' : '05', - 'juin' : '06', - 'juillet' : '07', - 'août' : '08', - 'septembre' : '09', - 'octobre' : '10', - 'novembre' : '11', - 'décembre' : '12' + 'janvier': '01', + 'février': '02', + 'mars': '03', + 'avril': '04', + 'mai': '05', + 'juin': '06', + 'juillet': '07', + 'août': '08', + 'septembre': '09', + 'octobre': '10', + 'novembre': '11', + 'décembre': '12' } -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -91,7 +94,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -108,7 +111,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -125,7 +129,8 @@ def list_shows(params): ) for category in categories_soup.find_all('a'): - category_name = category.find('span').get_text().encode('utf-8').replace( + category_name = category.find( + 'span').get_text().encode('utf-8').replace( '\n', ' ').replace('\r', ' ').rstrip('\r\n') category_hash = common.sp.md5(category_name).hexdigest() @@ -152,7 +157,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -162,7 +167,8 @@ def list_videos(params): file_path = utils.download_catalog( url_replay_paged, - '%s_%s_%s.html' % (params.channel_name, params.category_name, str(paged)) + '%s_%s_%s.html' % ( + params.channel_name, params.category_name, str(paged)) ) program_html = open(file_path).read() program_soup = bs(program_html, 'html.parser') @@ -174,30 +180,40 @@ def list_videos(params): info_video = video.find_all('p') - video_title = video.find('h3').find('a').get_text().encode('utf-8').replace( - '\n', ' ').replace('\r', ' ').rstrip('\r\n') + ' - ' + video.find( - 'p', class_="red").get_text().encode( - 'utf-8').replace('\n', ' ').replace('\r', ' ').rstrip('\r\n') - video_img = video.find('img')['src'].encode('utf-8') - video_id = video.find('div', class_="player")['data-id-video'].encode('utf-8') + video_title = video.find('h3').find( + 'a').get_text().encode('utf-8').replace( + '\n', ' ').replace('\r', ' ').rstrip( + '\r\n') + ' - ' + video.find( + 'p', class_="red").get_text().encode( + 'utf-8').replace('\n', ' ').replace('\r', ' ').rstrip('\r\n') + video_img = video.find( + 'img')['src'].encode('utf-8') + video_id = video.find( + 'div', class_="player")['data-id-video'].encode('utf-8') video_duration = 0 video_duration_list = str(info_video[3]).replace( "<p><strong>", '').replace("</strong></p>", '').split(':') if len(video_duration_list) > 2: - video_duration = int(video_duration_list[0]) * 3600 + int(video_duration_list[1]) \ - * 60 + int(video_duration_list[2]) + video_duration = int(video_duration_list[0]) * 3600 + \ + int(video_duration_list[1]) * 60 + \ + int(video_duration_list[2]) else: - video_duration = int(video_duration_list[0]) * 60 + int(video_duration_list[1]) + video_duration = int(video_duration_list[0]) * 60 + \ + int(video_duration_list[1]) # get month and day on the page - date_list = str(info_video[2]).replace("<p>", '').replace("</p>", '').split(' ') - day = date_list[2] - try: - mounth = CORRECT_MONTH[date_list[3]] - except: - mounth = '00' - # get year ? + date_list = str(info_video[2]).replace( + "<p>", '').replace("</p>", '').split(' ') + day = '00' + mounth = '00' year = '2017' + if len(date_list) > 3: + day = date_list[2] + try: + mounth = CORRECT_MONTH[date_list[3]] + except Exception: + mounth = '00' + # get year ? date = '.'.join((day, mounth, year)) aired = '-'.join((year, mounth, day)) @@ -241,12 +257,14 @@ def list_videos(params): file_path = utils.download_catalog( url_replay_paged, - '%s_%s_%s.html' % (params.channel_name, params.category_name, str(paged)) + '%s_%s_%s.html' % ( + params.channel_name, params.category_name, str(paged)) ) program_html = open(file_path).read() program_soup = bs(program_html, 'html.parser') - videos_soup = program_soup.find_all('div', class_='program sticky video') + videos_soup = program_soup.find_all( + 'div', class_='program sticky video') return common.PLUGIN.create_listing( videos, @@ -256,7 +274,8 @@ def list_videos(params): ), content='tvshows') -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -265,7 +284,6 @@ def list_live(params): plot = '' duration = 0 img = '' - url_live = '' file_path = utils.download_catalog( URL_INFO_LIVE_JSON, @@ -278,7 +296,7 @@ def list_live(params): video_id = json_parser["video"].encode('utf-8') - #url_live = url_dailymotion_embed % video_id + # url_live = url_dailymotion_embed % video_id info = { 'video': { @@ -292,7 +310,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', video_id=video_id, @@ -309,7 +327,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" url_video = URL_DAILYMOTION_EMBED % params.video_id @@ -324,11 +343,13 @@ def get_video_url(params): if params.next == 'play_l': all_url_video = re.compile( - r'{"type":"application/x-mpegURL","url":"(.*?)"').findall(html_video) + r'{"type":"application/x-mpegURL","url":"(.*?)"' + ).findall(html_video) # Just One Quality return all_url_video[0] - elif params.next == 'play_r': - all_url_video = re.compile(r'{"type":"video/mp4","url":"(.*?)"').findall(html_video) + elif params.next == 'play_r': + all_url_video = re.compile( + r'{"type":"video/mp4","url":"(.*?)"').findall(html_video) if desired_quality == "DIALOG": all_datas_videos = [] for datas in all_url_video: @@ -338,11 +359,12 @@ def get_video_url(params): new_list_item.setPath(datas) all_datas_videos.append(new_list_item) - seleted_item = common.sp.xbmcgui.Dialog().select("Choose Stream", all_datas_videos) + seleted_item = common.sp.xbmcgui.Dialog().select( + "Choose Stream", all_datas_videos) return all_datas_videos[seleted_item].getPath().encode('utf-8') elif desired_quality == 'BEST': - #Last video in the Best + # Last video in the Best for datas in all_url_video: url = datas return url diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py index 156edd2..7a83e3e 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py @@ -97,9 +97,11 @@ CATEGORIES = { 'Info': 'https://pluzz.webservices.francetelevisions.fr/' 'mobile/liste/type/replay/rubrique/info/nb/20/debut/%s', 'Documentaire': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/type/replay/rubrique/documentaire/nb/20/debut/%s', + 'mobile/liste/type/replay/rubrique/documentaire/' + 'nb/20/debut/%s', 'Série & Fiction': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/type/replay/rubrique/seriefiction/nb/20/debut/%s', + 'mobile/liste/type/replay/rubrique/seriefiction/nb/' + '20/debut/%s', 'Magazine': 'https://pluzz.webservices.francetelevisions.fr/' 'mobile/liste/type/replay/rubrique/magazine/nb/20/debut/%s', 'Culture': 'https://pluzz.webservices.francetelevisions.fr/' @@ -107,19 +109,25 @@ CATEGORIES = { 'Jeunesse': 'https://pluzz.webservices.francetelevisions.fr/' 'mobile/liste/type/replay/rubrique/jeunesse/nb/20/debut/%s', 'Divertissement': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/type/replay/rubrique/divertissement/nb/20/debut/%s', + 'mobile/liste/type/replay/rubrique/divertissement/nb/' + '20/debut/%s', 'Sport': 'https://pluzz.webservices.francetelevisions.fr/' 'mobile/liste/type/replay/rubrique/sport/nb/20/debut/%s', 'Jeu': 'https://pluzz.webservices.francetelevisions.fr/' 'mobile/liste/type/replay/rubrique/jeu/nb/20/debut/%s', - 'Version multilingue (VM)': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/filtre/multilingue/type/replay/nb/20/debut/%s', + 'Version multilingue (VM)': 'https://pluzz.webservices.' + 'francetelevisions.fr/' + 'mobile/liste/filtre/multilingue/type/' + 'replay/nb/20/debut/%s', 'Sous-titrés': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/filtre/soustitrage/type/replay/nb/20/debut/%s', + 'mobile/liste/filtre/soustitrage/type/replay/nb/' + '20/debut/%s', 'Audiodescription (AD)': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/filtre/audiodescription/type/replay/nb/20/debut/%s', + 'mobile/liste/filtre/audiodescription/type/replay' + '/nb/20/debut/%s', 'Tous publics': 'https://pluzz.webservices.francetelevisions.fr/' - 'mobile/liste/type/replay/filtre/touspublics/nb/20/debut/%s' + 'mobile/liste/type/replay/filtre/touspublics' + '/nb/20/debut/%s' } @@ -140,7 +148,7 @@ def channel_entry(params): return None -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def change_to_nicer_name(original_name): """Convert id name to label name""" if original_name in CATEGORIES_DISPLAY: @@ -148,7 +156,7 @@ def change_to_nicer_name(original_name): return original_name -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] @@ -156,7 +164,7 @@ def root(params): # Add Replay if params.channel_name != 'franceinfo': modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -168,7 +176,7 @@ def root(params): # Add Live if params.channel_name != 'la_1ere': modes.append({ - 'label' : _('Live TV'), + 'label': _('Live TV'), 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -185,7 +193,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -394,7 +403,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -556,7 +565,7 @@ def list_videos(params): ), 'is_playable': True, 'info': info, - 'context_menu': context_menu # A ne pas oublier pour ajouter le bouton "Download" à chaque vidéo + 'context_menu': context_menu }) if 'search' in params.next: @@ -606,7 +615,8 @@ def list_videos(params): update_listing='update_listing' in params, ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -634,14 +644,17 @@ def list_live(params): if id_programme == '': id_programme = emission['id_emission'].encode('utf-8') id_diffusion = emission['id_diffusion'] - chaine_id = emission['chaine_id'].encode('utf-8') + # chaine_id = emission['chaine_id'].encode('utf-8') - start_time_emission = 'Début : ' + emission['date_diffusion'].split('T')[1].encode('utf-8') + start_time_emission = 'Début : ' + \ + emission['date_diffusion'].split('T')[1].encode('utf-8') if emission['accroche']: - plot = start_time_emission + '\n ' + emission['accroche'].encode('utf-8') + plot = start_time_emission + '\n ' + \ + emission['accroche'].encode('utf-8') elif emission['accroche_programme']: - plot = start_time_emission + '\n ' + emission['accroche_programme'].encode('utf-8') + plot = start_time_emission + '\n ' + \ + emission['accroche_programme'].encode('utf-8') if emission['date_diffusion']: date = emission['date_diffusion'] date = date.encode('utf-8') @@ -674,7 +687,6 @@ def list_live(params): day = int(date[8:10]) aired = '-'.join((str(year), str(month), str(day))) - image = URL_IMG % (emission['image_large']) info = { @@ -684,7 +696,7 @@ def list_live(params): 'aired': aired, 'date': date, 'duration': duration, - #year': year, + # year': year, 'genre': genre, 'mediatype': 'tvshow', 'season': season, @@ -729,7 +741,6 @@ def list_live(params): 'info': info }) - return common.PLUGIN.create_listing( lives, sort_methods=( @@ -738,7 +749,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" @@ -754,7 +766,8 @@ def get_video_url(params): all_datas_videos = [] for video in json_parser['videos']: - if video['format'] == 'hls_v5_os' or video['format'] == 'm3u8-download': + if video['format'] == 'hls_v5_os' or \ + video['format'] == 'm3u8-download': new_list_item = common.sp.xbmcgui.ListItem() if video['format'] == 'hls_v5_os': new_list_item.setLabel("HD") diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/publicsenat.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/publicsenat.py index 33d18d6..8f8cf6a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/publicsenat.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/publicsenat.py @@ -41,6 +41,7 @@ URL_LIVE_SITE = 'https://www.publicsenat.fr/direct' URL_DAILYMOTION_EMBED = 'http://www.dailymotion.com/embed/video/%s' + def channel_entry(params): """Entry function of the module""" if 'root' in params.next: @@ -54,38 +55,41 @@ def channel_entry(params): elif 'play' in params.next: return get_video_url(params) + CATEGORIES = { - 'https://www.publicsenat.fr/recherche/type/episode/' \ - 'field_theme/politique-4127?sort_by=pse_search_date_publication' : 'Politique', - 'https://www.publicsenat.fr/recherche/type/episode/' \ - 'field_theme/societe-4126?sort_by=pse_search_date_publication' : 'Société', - 'https://www.publicsenat.fr/recherche/type/episode/' \ - 'field_theme/debat-4128?sort_by=pse_search_date_publication' : 'Débat' + 'https://www.publicsenat.fr/recherche/type/episode/' + 'field_theme/politique-4127?' + 'sort_by=pse_search_date_publication': 'Politique', + 'https://www.publicsenat.fr/recherche/type/episode/' + 'field_theme/societe-4126?sort_by=pse_search_date_publication': 'Société', + 'https://www.publicsenat.fr/recherche/type/episode/' + 'field_theme/debat-4128?sort_by=pse_search_date_publication': 'Débat' } CORRECT_MONTH = { - 'janvier' : '01', - 'février' : '02', - 'mars' : '03', - 'avril' : '04', - 'mai' : '05', - 'juin' : '06', - 'juillet' : '07', - 'août' : '08', - 'septembre' : '09', - 'octobre' : '10', - 'novembre' : '11', - 'décembre' : '12' + 'janvier': '01', + 'février': '02', + 'mars': '03', + 'avril': '04', + 'mai': '05', + 'juin': '06', + 'juillet': '07', + 'août': '08', + 'septembre': '09', + 'octobre': '10', + 'novembre': '11', + 'décembre': '12' } -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -96,7 +100,7 @@ def root(params): # Add Live modes.append({ - 'label' : 'Live TV', + 'label': 'Live TV', 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -113,7 +117,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build shows listing""" shows = [] @@ -142,7 +147,8 @@ def list_shows(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] @@ -164,32 +170,38 @@ def list_videos(params): if params.category_name == 'Politique': video_soup = root_soup.find_all( 'article', - class_="node node-episode node-episode-pse-search-result theme-4127 clearfix") + class_="node node-episode node-episode-pse-search-result" + " theme-4127 clearfix") elif params.category_name == 'Société': video_soup = root_soup.find_all( 'article', - class_="node node-episode node-episode-pse-search-result theme-4126 clearfix") + class_="node node-episode node-episode-pse-search-result " + "theme-4126 clearfix") elif params.category_name == 'Débat': video_soup = root_soup.find_all( 'article', - class_="node node-episode node-episode-pse-search-result theme-4128 clearfix") + class_="node node-episode node-episode-pse-search-result " + "theme-4128 clearfix") for video in video_soup: # Test Existing Video - if video.find('div', class_="content").find( \ + if video.find('div', class_="content").find( 'div', class_="right").find('div', class_="wrapper-duree"): title = '' - if video.find('div', class_="content").find( \ + if video.find('div', class_="content").find( 'div', - class_="field field-name-title-field field-type-text field-label-hidden"): + class_="field field-name-title-field field-type-text " + "field-label-hidden"): title = video.find( 'div', class_="content" ).find( 'div', - class_="field field-name-field-ref-emission field-type-entityreference field-label-hidden" + class_="field field-name-field-ref-emission" + " field-type-entityreference " + "field-label-hidden" ).find( 'div', class_="field-items" @@ -199,25 +211,22 @@ def list_videos(params): ).get_text().encode('utf-8') + ' - ' \ + video.find( 'div', - class_="content" - ).find( - 'div', - class_="field field-name-title-field field-type-text field-label-hidden" - ).find( + class_="content").find( + 'div', + class_="field field-name-title-field " + "field-type-text field-label-hidden").find( 'div', - class_="field-items" - ).find( + class_="field-items").find( 'div', - class_="field-item even" - ).get_text().encode('utf-8') + class_="field-item even").get_text().encode('utf-8') else: title = video.find( 'div', - class_="content" - ).find( + class_="content").find( 'div', - class_="field field-name-field-ref-emission field-type-entityreference field-label-hidden" - ).find( + class_="field field-name-field-ref-emission" + " field-type-entityreference " + "field-label-hidden").find( 'div', class_="field-items" ).find( @@ -226,9 +235,12 @@ def list_videos(params): ).get_text().encode('utf-8') img = '' - if video.find('div', class_="content").find('div', class_="wrapper-visuel" \ - ).find('div', class_="scald-atom video").find('div', \ - class_="field field-name-scald-thumbnail field-type-image field-label-hidden"): + if video.find( + 'div', class_="content").find( + 'div', class_="wrapper-visuel").find( + 'div', class_="scald-atom video").find( + 'div', class_="field field-name-scald-thumbnail" + " field-type-image field-label-hidden"): img = video.find( 'div', class_="content" @@ -240,7 +252,8 @@ def list_videos(params): class_="scald-atom video" ).find( 'div', - class_="field field-name-scald-thumbnail field-type-image field-label-hidden" + class_="field field-name-scald-thumbnail" + " field-type-image field-label-hidden" ).find( 'div', class_="field-items" @@ -250,14 +263,17 @@ def list_videos(params): ).find('img').get('src') plot = '' - if video.find('div', class_="content").find('div', \ - class_="field field-name-field-contenu field-type-text-long field-label-hidden"): + if video.find( + 'div', class_="content").find( + 'div', class_="field field-name-field-contenu" + " field-type-text-long field-label-hidden"): plot = video.find( 'div', class_="content" ).find( 'div', - class_="field field-name-field-contenu field-type-text-long field-label-hidden" + class_="field field-name-field-contenu " + "field-type-text-long field-label-hidden" ).find( 'div', class_="field-items" @@ -266,7 +282,6 @@ def list_videos(params): class_="field-item even" ).get_text().encode('utf-8') - value_date = video.find( 'div', class_="content" @@ -275,7 +290,7 @@ def list_videos(params): day = date[2] try: mounth = CORRECT_MONTH[date[3]] - except: + except Exception: mounth = '00' year = date[4] @@ -286,8 +301,8 @@ def list_videos(params): duration = int(video.find('div', class_="content").find( 'div', class_="right").find( 'div', - class_="wrapper-duree").get_text().encode('utf-8')[:-3]) * 60 - + class_="wrapper-duree").get_text().encode( + 'utf-8')[:-3]) * 60 url_video = URL_ROOT + video.find( 'div', class_="content").find('a').get('href').encode('utf-8') @@ -299,7 +314,7 @@ def list_videos(params): 'date': date, 'duration': duration, 'year': year, - 'plot' : plot, + 'plot': plot, 'mediatype': 'tvshow' } } @@ -354,7 +369,8 @@ def list_videos(params): update_listing='update_listing' in params, ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -387,7 +403,7 @@ def list_live(params): 'label': title, 'fanart': img, 'thumb': img, - 'url' : common.PLUGIN.get_url( + 'url': common.PLUGIN.get_url( action='channel_entry', next='play_l', url=url_live, @@ -404,7 +420,8 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': @@ -417,8 +434,7 @@ def get_video_url(params): for url in urlembeded_videos_soup: url_video_embed = url.get('src').encode('utf-8') - break # get first video hard to find by another method - + break # get first video hard to find by another method url_video_embed_http = url_video_embed if params.next == 'download_video': @@ -426,7 +442,8 @@ def get_video_url(params): html_video = utils.get_webcontent(url_video_embed_http) html_video = html_video.replace('\\', '') - all_url_video = re.compile(r'"type":"video/mp4","url":"(.*?)"').findall(html_video) + all_url_video = re.compile( + r'"type":"video/mp4","url":"(.*?)"').findall(html_video) for datas in all_url_video: url = datas @@ -438,7 +455,8 @@ def get_video_url(params): html_live = html_live.replace('\\', '') url_live = re.compile( - r'{"type":"application/x-mpegURL","url":"(.*?)"}]}').findall(html_live) + r'{"type":"application/x-mpegURL","url":"(.*?)"}]}' + ).findall(html_live) # Just one flux no quality to choose return url_live[0] diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py index 79c524c..2bc277b 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py +++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py @@ -21,7 +21,9 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ +import ast import json +import re from bs4 import BeautifulSoup as bs from resources.lib import utils from resources.lib import common @@ -70,14 +72,15 @@ def channel_entry(params): return get_video_url(params) return None -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def root(params): """Add Replay and Live in the listing""" modes = [] # Add Replay modes.append({ - 'label' : 'Replay', + 'label': 'Replay', 'url': common.PLUGIN.get_url( action='channel_entry', next='list_shows_1', @@ -89,7 +92,7 @@ def root(params): # Add Live if params.channel_name != 'tfou' and params.channel_name != 'xtra': modes.append({ - 'label' : _('Live TV'), + 'label': _('Live TV'), 'url': common.PLUGIN.get_url( action='channel_entry', next='live_cat', @@ -106,7 +109,8 @@ def root(params): ), ) -@common.PLUGIN.cached(common.CACHE_TIME) + +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_shows(params): """Build categories listing""" shows = [] @@ -124,14 +128,15 @@ def list_shows(params): 'ul', attrs={'class': 'topic-chronology-milestone-component'}) for program in programs_soup.find_all('li'): - program_url = URL_LCI_ROOT + program.find('a')['href'].encode('utf-8') + program_url = URL_LCI_ROOT + program.find( + 'a')['href'].encode('utf-8') program_name = program.find( 'h2', class_='text-block').get_text().encode('utf-8') img = program.find_all('source')[0] try: img = img['data-srcset'].encode('utf-8') - except: + except Exception: img = img['srcset'].encode('utf-8') img = img.split(',')[0].split(' ')[0] @@ -192,21 +197,33 @@ def list_shows(params): img = program.find('img') try: img = img['data-srcset'].encode('utf-8') - except: + except Exception: img = img['srcset'].encode('utf-8') img = 'http:' + img.split(',')[-1].split(' ')[0] - shows.append({ - 'label': program_name, - 'thumb': img, - 'url': common.PLUGIN.get_url( - action='channel_entry', - program_url=program_url, - next='list_videos_categories', - window_title=program_name - ) - }) + if 'meteo.tf1.fr/meteo-france' in program_url: + shows.append({ + 'label': program_name, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + program_url=program_url, + next='list_videos', + window_title=program_name + ) + }) + else: + shows.append({ + 'label': program_name, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + program_url=program_url, + next='list_videos_categories', + window_title=program_name + ) + }) return common.PLUGIN.create_listing( shows, @@ -217,7 +234,7 @@ def list_shows(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos_categories(params): """Build videos categories listing""" videos_categories = [] @@ -230,19 +247,38 @@ def list_videos_categories(params): filters_1_soup = program_soup.find( 'ul', class_='filters_1') - for li in filters_1_soup.find_all('li'): - category_title = li.get_text().encode('utf-8') - category_id = li.find('a')['data-filter'].encode('utf-8') - videos_categories.append({ - 'label': category_title, - 'url': common.PLUGIN.get_url( - action='channel_entry', - program_url=params.program_url, - next='list_videos', - window_title=category_title, - category_id=category_id - ) - }) + if filters_1_soup is not None: + for li in filters_1_soup.find_all('li'): + category_title = li.get_text().encode('utf-8') + category_id = li.find('a')['data-filter'].encode('utf-8') + + # Get Last Page of each categorie + # Get First page : + url_first_page = ''.join(( + params.program_url, + '/videos', + '?filter=', + category_id)) + program_first_page_html = utils.get_webcontent(url_first_page) + program_first_page_soup = bs( + program_first_page_html, 'html.parser') + # Get Last page : + last_page = '0' + if program_first_page_soup.find('a', class_='icon i-chevron-right-double trackXiti') is not None: + last_page = program_first_page_soup.find('a', class_='icon i-chevron-right-double trackXiti').get('href').rsplit('/')[-1].split('?')[0] + + videos_categories.append({ + 'label': category_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + program_url=params.program_url, + page='1', + last_page=last_page, + next='list_videos', + window_title=category_title, + category_id=category_id + ) + }) return common.PLUGIN.create_listing( videos_categories, sort_methods=( @@ -252,10 +288,12 @@ def list_videos_categories(params): ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_videos(params): """Build videos listing""" videos = [] + if 'previous_listing' in params: + videos = ast.literal_eval(params['previous_listing']) if params.channel_name == 'lci': program_html = utils.get_webcontent(params.program_url) @@ -263,7 +301,7 @@ def list_videos(params): list_replay = program_soup.find_all( 'a', - class_='topic-emission-extract-block-image trackXiti') + class_='medium-3col-article-block-article-link') for replay in list_replay: @@ -312,12 +350,64 @@ def list_videos(params): 'context_menu': context_menu }) + elif 'meteo.tf1.fr/meteo-france' in params.program_url: + program_html = utils.get_webcontent(params.program_url) + program_soup = bs(program_html, 'html.parser') + + wat_info = program_soup.find( + 'td', + class_='textbase') + + title = wat_info.find('h3').get_text() + + program_id = re.compile('; src = \'(.*?)\?').findall(program_html)[0] + + info = { + 'video': { + 'title': title, + #'plot': stitle, + #'aired': aired, + #'date': date, + #'duration': duration, + #'year': int(aired[:4]), + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + ('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + program_id=program_id) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': title, + #'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + program_id=program_id, + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) else: - url = ''.join(( - params.program_url, - '/videos/', - '?filter=', - params.category_id)) + if params.page == '1': + url = ''.join(( + params.program_url, + '/videos', + '?filter=', + params.category_id)) + else: + url = ''.join(( + params.program_url, + '/videos/%s' % params.page, + '?filter=', + params.category_id)) program_html = utils.get_webcontent(url) program_soup = bs(program_html, 'html.parser') @@ -325,96 +415,113 @@ def list_videos(params): 'ul', class_='grid') - for li in grid.find_all('li'): - video_type_string = li.find( - 'div', class_='description').find('a')['data-xiti-libelle'].encode('utf-8') - video_type_string = video_type_string.split('-')[0] - - if 'Playlist' not in video_type_string: - title = li.find( - 'p', - class_='title').get_text().encode('utf-8') - - try: - stitle = li.find( - 'p', - class_='stitle').get_text().encode('utf-8') - except: - stitle = '' + if grid is not None: + for li in grid.find_all('li'): + video_type_string = li.find( + 'div', class_='description').find('a')['data-xiti-libelle'].encode('utf-8') + video_type_string = video_type_string.split('-')[0] - try: - duration_soup = li.find( + if 'Playlist' not in video_type_string: + title = li.find( 'p', - class_='uptitle').find( - 'span', - class_='momentDate') - duration = int(duration_soup.get_text().encode('utf-8')) - except: - duration = 0 - - img = li.find('img') - try: - img = img['data-srcset'].encode('utf-8') - except: - img = img['srcset'].encode('utf-8') + class_='title').get_text().encode('utf-8') - img = 'http:' + img.split(',')[-1].split(' ')[0] + try: + stitle = li.find( + 'p', + class_='stitle').get_text().encode('utf-8') + except: + stitle = '' - try: - date_soup = li.find( - 'div', - class_='text').find( + try: + duration_soup = li.find( 'p', - class_='uptitle').find('span') - - aired = date_soup['data-date'].encode('utf-8').split('T')[0] - day = aired.split('-')[2] - mounth = aired.split('-')[1] - year = aired.split('-')[0] - date = '.'.join((day, mounth, year)) - # date : string (%d.%m.%Y / 01.01.2009) - # aired : string (2008-12-07) - - except: - date = '' - aired = '' - year = 0 - - program_id = li.find('a')['href'].encode('utf-8') - - info = { - 'video': { - 'title': title, - 'plot': stitle, - 'aired': aired, - 'date': date, - 'duration': duration, - 'year': int(aired[:4]), - 'mediatype': 'tvshow' + class_='uptitle').find( + 'span', + class_='momentDate') + duration = int(duration_soup.get_text().encode('utf-8')) + except: + duration = 0 + + img = li.find('img') + try: + img = img['data-srcset'].encode('utf-8') + except: + img = img['srcset'].encode('utf-8') + + img = 'http:' + img.split(',')[-1].split(' ')[0] + + try: + date_soup = li.find( + 'div', + class_='text').find( + 'p', + class_='uptitle').find('span') + + aired = date_soup['data-date'].encode('utf-8').split('T')[0] + day = aired.split('-')[2] + mounth = aired.split('-')[1] + year = aired.split('-')[0] + date = '.'.join((day, mounth, year)) + # date : string (%d.%m.%Y / 01.01.2009) + # aired : string (2008-12-07) + + except: + date = '' + aired = '' + year = 0 + + program_id = li.find('a')['href'].encode('utf-8') + + info = { + 'video': { + 'title': title, + 'plot': stitle, + 'aired': aired, + 'date': date, + 'duration': duration, + 'year': int(aired[:4]), + 'mediatype': 'tvshow' + } } - } - context_menu = [] - download_video = ( - _('Download'), - 'XBMC.RunPlugin(' + common.PLUGIN.get_url( - action='download_video', - program_id=program_id) + ')' - ) - context_menu.append(download_video) + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + program_id=program_id) + ')' + ) + context_menu.append(download_video) - videos.append({ - 'label': title, - 'thumb': img, - 'url': common.PLUGIN.get_url( - action='channel_entry', - next='play_r', - program_id=program_id, - ), - 'is_playable': True, - 'info': info, - 'context_menu': context_menu - }) + videos.append({ + 'label': title, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + program_id=program_id, + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) + + if int(params.page) < int(params.last_page): + # More videos... + videos.append({ + 'label': common.ADDON.get_localized_string(30100), + 'url': common.PLUGIN.get_url( + action='channel_entry', + program_url=params.program_url, + category_id=params.category_id, + last_page=params.last_page, + next='list_videos', + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(videos) + ), + }) return common.PLUGIN.create_listing( videos, @@ -424,9 +531,11 @@ def list_videos(params): common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE, common.sp.xbmcplugin.SORT_METHOD_UNSORTED ), - content='tvshows') + content='tvshows', + update_listing='update_listing' in params, + ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def list_live(params): """Build live listing""" lives = [] @@ -491,29 +600,34 @@ def list_live(params): ) ) -@common.PLUGIN.cached(common.CACHE_TIME) +@common.PLUGIN.mem_cached(common.CACHE_TIME) def get_video_url(params): """Get video URL and start video player""" if params.next == 'play_r' or params.next == 'download_video': - if "http" not in params.program_id: + if 'www.wat.tv/embedframe' in params.program_id: + url = 'http:' + params.program_id + elif "http" not in params.program_id: if params.program_id[0] == '/': params.program_id = params.program_id[1:] url = URL_ROOT + params.program_id else: url = params.program_id video_html = utils.get_webcontent(url) - video_html_soup = bs(video_html, 'html.parser') - - iframe_player_soup = video_html_soup.find( - 'div', - class_='iframe_player') - if params.channel_name == 'lci': - video_id = iframe_player_soup['data-watid'].encode('utf-8') + if 'www.wat.tv/embedframe' in params.program_id: + video_id = re.compile('UVID=(.*?)&').findall(video_html)[0] else: - data_src = iframe_player_soup['data-src'].encode('utf-8') - video_id = data_src[-8:] + video_html_soup = bs(video_html, 'html.parser') + iframe_player_soup = video_html_soup.find( + 'div', + class_='iframe_player') + + if params.channel_name == 'lci': + video_id = iframe_player_soup['data-watid'].encode('utf-8') + else: + data_src = iframe_player_soup['data-src'].encode('utf-8') + video_id = data_src[-8:] timeserver = str(utils.get_webcontent(URL_TIME)) @@ -553,6 +667,14 @@ def get_video_url(params): except: pass + # Check DRM in the m3u8 file + manifest = utils.get_webcontent( + url_video, + random_ua=True) + if 'drm' in manifest: + utils.send_notification(common.ADDON.get_localized_string(30102)) + return '' + return url_video elif params.next == 'play_l': diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/uk/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/uk/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/uk/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/uk/blaze.py b/plugin.video.catchuptvandmore/resources/lib/channels/uk/blaze.py new file mode 100644 index 0000000..1aab65b --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/uk/blaze.py @@ -0,0 +1,339 @@ +# -*- coding: utf-8 -*- +""" + Catch-up TV & More + Copyright (C) 2017 SylvainCecchetto + + This file is part of Catch-up TV & More. + + Catch-up TV & More is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Catch-up TV & More is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Catch-up TV & More; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" + +import ast +import re +from bs4 import BeautifulSoup as bs +from resources.lib import utils +from resources.lib import common + +# TO DO +# Fix Download Video + +# Initialize GNU gettext emulation in addon +# This allows to use UI strings from addon’s English +# strings.po file instead of numeric codes +_ = common.ADDON.initialize_gettext() + +# Live +URL_LIVE_JSON = 'http://dbxm993i42r09.cloudfront.net/' \ + 'configs/blaze.json?callback=blaze' + +URL_NOW_PLAYING = 'http://www.blaze.tv/home/index/now-playing' + +# Replay +URL_SHOWS = 'http://www.blaze.tv/series?page=%s' +# pageId + +URL_API_KEY = 'https://dbxm993i42r09.cloudfront.net/configs/config.blaze.js' + +URL_STREAM = 'https://d2q1b32gh59m9o.cloudfront.net/player/config?' \ + 'callback=ssmp&client=blaze&type=vod&apiKey=%s&videoId=%s&' \ + 'format=jsonp&callback=ssmp' +# apiKey, videoId + +URL_ROOT = 'http://www.blaze.tv' + + +def channel_entry(params): + """Entry function of the module""" + if 'root' in params.next: + return root(params) + elif 'list_shows' in params.next: + return list_shows(params) + elif 'list_videos' in params.next: + return list_videos(params) + elif 'live' in params.next: + return list_live(params) + elif 'play' in params.next: + return get_video_url(params) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def root(params): + """Add Replay and Live in the listing""" + modes = [] + + # Add Replay + modes.append({ + 'label': 'Replay', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_1', + page='0', + category='%s Replay' % params.channel_name.upper(), + window_title='%s Replay' % params.channel_name.upper() + ), + }) + + # Add Live + modes.append({ + 'label': 'Live TV', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='live_cat', + category='%s Live TV' % params.channel_name.upper(), + window_title='%s Live TV' % params.channel_name.upper() + ), + }) + + return common.PLUGIN.create_listing( + modes, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_shows(params): + """Build categories listing""" + shows = [] + if 'previous_listing' in params: + shows = ast.literal_eval(params['previous_listing']) + + if params.next == 'list_shows_1': + file_path = utils.download_catalog( + URL_SHOWS % params.page, + '%s_shows_%s.html' % (params.channel_name, params.page) + ) + replay_shows_html = open(file_path).read() + + replay_shows_soup = bs(replay_shows_html, 'html.parser') + replay_shows = replay_shows_soup.find_all('div', class_='item') + + for show in replay_shows: + + show_title = show.find('a').find('img').get('alt') + show_img = show.find('a').find('img').get('src').encode('utf-8') + show_url = URL_ROOT + show.find('a').get('href').encode('utf-8') + + shows.append({ + 'label': show_title, + 'thumb': show_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_2', + title=show_title, + show_url=show_url, + window_title=show_title + ) + }) + + # More programs... + shows.append({ + 'label': common.ADDON.get_localized_string(30108), + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_1', + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(shows) + ), + }) + + elif params.next == 'list_shows_2': + + file_path = utils.download_catalog( + params.show_url, + '%s_show_%s.html' % (params.channel_name, params.title) + ) + replay_show_html = open(file_path).read() + + replay_show_seasons_soup = bs(replay_show_html, 'html.parser') + replay_show_seasons = replay_show_seasons_soup.find( + 'div', class_='pagination') + + get_show_seasons = replay_show_seasons.find_all('a') + + for season in get_show_seasons: + + season_title = 'Series %s' % season.get_text().strip() + show_season_url = URL_ROOT + season.get('href').encode('utf-8') + + shows.append({ + 'label': season_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_1', + title=params.title + '_' + season_title, + show_url=show_season_url, + window_title=season_title + ) + }) + + return common.PLUGIN.create_listing( + shows, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ), + update_listing='update_listing' in params, + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_videos(params): + """Build videos listing""" + videos = [] + + file_path = utils.download_catalog( + params.show_url, + '%s_show_%s.html' % (params.channel_name, params.title) + ) + replay_show_html = open(file_path).read() + episodes_soup = bs(replay_show_html, 'html.parser') + + root_episodes = episodes_soup.find_all('div', class_='carousel-inner')[0] + episodes = root_episodes.find_all( + 'div', class_='col-md-4 wrapper-item season') + + for episode in episodes: + + value_episode = episode.find( + 'span', class_='caption-description' + ).get_text().split(' | ')[1].split(' ')[1] + value_season = episode.find( + 'span', class_='caption-description' + ).get_text().split(' | ')[0].split(' ')[1] + video_title = episode.find( + 'span', class_='caption-title' + ).get_text() + ' S%sE%s' % (value_season, value_episode) + + video_duration = 0 + video_plot = episode.find( + 'span', class_='caption-title').get_text().encode('utf-8') + ' ' + video_plot = video_plot + episode.find( + 'span', class_='caption-description').get_text().encode('utf-8') + video_img = episode.find('a').find('img').get('src') + video_url = URL_ROOT + episode.find('a').get('href').encode('utf-8') + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_url=video_url) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'fanart': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_url=video_url + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + + return common.PLUGIN.create_listing( + videos, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_DURATION, + common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE, + common.sp.xbmcplugin.SORT_METHOD_GENRE, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + content='tvshows', + update_listing='update_listing' in params, + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_live(params): + """Build live listing""" + lives = [] + + title = '' + # subtitle = ' - ' + plot = '' + duration = 0 + img = '' + url_live = '' + + video_html = utils.get_webcontent(URL_NOW_PLAYING) + title_live = bs(video_html, 'html.parser') + title = title_live.get_text() + url_live_html = utils.get_webcontent(URL_LIVE_JSON) + url_live = re.compile('"url": "(.*?)"').findall(url_live_html)[0] + + info = { + 'video': { + 'title': title, + 'plot': plot, + 'duration': duration + } + } + + lives.append({ + 'label': title, + 'fanart': img, + 'thumb': img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_l', + url=url_live, + ), + 'is_playable': True, + 'info': info + }) + + return common.PLUGIN.create_listing( + lives, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ) + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_video_url(params): + """Get video URL and start video player""" + if params.next == 'play_l': + return params.url + elif params.next == 'play_r' or params.next == 'download_video': + video_html = utils.get_webcontent(params.video_url) + videoId = re.compile('data-uvid="(.*?)"').findall(video_html)[0] + apikey_html = utils.get_webcontent(URL_API_KEY) + apikey = re.compile('"apiKey": "(.*?)"').findall(apikey_html)[0] + stream_html = utils.get_webcontent(URL_STREAM % (apikey, videoId)) + return re.compile('"hls":"(.*?)"').findall(stream_html)[0] diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/uk/uktvplay.py b/plugin.video.catchuptvandmore/resources/lib/channels/uk/uktvplay.py new file mode 100644 index 0000000..ba3b89f --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/uk/uktvplay.py @@ -0,0 +1,473 @@ +# -*- coding: utf-8 -*- +""" + Catch-up TV & More + Copyright (C) 2017 SylvainCecchetto + + This file is part of Catch-up TV & More. + + Catch-up TV & More is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Catch-up TV & More is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Catch-up TV & More; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" + +import re +import requests +from bs4 import BeautifulSoup as bs +from resources.lib import utils +from resources.lib import common + +# TO DO +# Live TV ? +# Get IMG from each SHOW (How ? Working on the browser not by wget) + +# Initialize GNU gettext emulation in addon +# This allows to use UI strings from addon’s English +# strings.po file instead of numeric codes +_ = common.ADDON.initialize_gettext() + +URL_ROOT = 'https://uktvplay.uktv.co.uk' + +URL_SHOWS = 'https://uktvplay.uktv.co.uk/shows/channel/%s/' +# channel_name + +URL_AUTHENTICATE = 'https://live.mppglobal.com/api/accounts/authenticate' +# POST Payload {email: "********@*******", password: "*********"} + +URL_BRIGHTCOVE_API = 'https://edge.api.brightcove.com/playback/v1/' \ + 'accounts/%s/videos/%s' +# data-account, data-vidid + +URL_JS_POLICY_KEY = 'https://players.brightcove.net/%s/%s_default/index.min.js' +# data-account, data-player + + +def channel_entry(params): + """Entry function of the module""" + if 'root' in params.next: + return root(params) + elif 'list_shows' in params.next: + return list_shows(params) + elif 'list_videos' in params.next: + return list_videos(params) + elif 'live' in params.next: + return list_live(params) + elif 'play' in params.next: + return get_video_url(params) + + +CORRECT_MOUNTH = { + 'Jan': '01', + 'Feb': '02', + 'Mar': '03', + 'Apr': '04', + 'May': '05', + 'Jun': '06', + 'Jul': '07', + 'Aug': '08', + 'Sep': '09', + 'Oct': '10', + 'Nov': '11', + 'Dec': '12' +} + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_policy_key(data_account, data_player): + """Get policy key""" + file_js = utils.get_webcontent( + URL_JS_POLICY_KEY % (data_account, data_player)) + return re.compile('policyKey:"(.+?)"').findall(file_js)[0] + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def root(params): + """Add Replay and Live in the listing""" + modes = [] + + # Add Replay + modes.append({ + 'label': 'Replay', + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_1', + category='%s Replay' % params.channel_name.upper(), + window_title='%s Replay' % params.channel_name.upper() + ), + }) + + return common.PLUGIN.create_listing( + modes, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_shows(params): + """Build categories listing""" + shows = [] + + if params.next == 'list_shows_1': + + file_path = utils.download_catalog( + URL_SHOWS % (params.channel_name), + '%s_show.html' % (params.channel_name) + ) + replay_shows_html = open(file_path).read() + + replay_shows_soup = bs(replay_shows_html, 'html.parser') + replay_shows = replay_shows_soup.find_all('div', class_='span2') + + for show in replay_shows: + + show_title = show.find('a').find('img').get('alt').encode('utf-8') + show_img = show.find('a').find('img').get('src') + show_url = URL_ROOT + show.find('a').get('href') + + if 'episodes' in show.find('p', class_='series-ep').get_text(): + shows.append({ + 'label': show_title, + 'thumb': show_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_2', + title=show_title, + show_url=show_url, + window_title=show_title + ) + }) + else: + shows.append({ + 'label': show_title, + 'thumb': show_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_1', + title=show_title, + show_url=show_url, + window_title=show_title + ) + }) + + elif params.next == 'list_shows_2': + + file_path = utils.download_catalog( + params.show_url, + '%s_show_%s.html' % (params.channel_name, params.title) + ) + replay_show_html = open(file_path).read() + + replay_show_seasons_soup = bs(replay_show_html, 'html.parser') + replay_show_seasons = replay_show_seasons_soup.find( + 'ul', class_='clearfix tag-nav') + + get_show_seasons = replay_show_seasons.find_all('li') + + for season in get_show_seasons: + + season_title = 'Series %s' % season.get( + 'id').encode('utf-8').split('nav-series-')[1] + + shows.append({ + 'label': season_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_1', + title=params.title + '_' + season_title, + show_url=params.show_url, + window_title=season_title + ) + }) + + return common.PLUGIN.create_listing( + shows, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_LABEL + ) + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_videos(params): + """Build videos listing""" + videos = [] + + file_path = utils.download_catalog( + params.show_url, + '%s_show_%s.html' % ( + params.channel_name, params.title) + ) + replay_show_season_html = open(file_path).read() + seasons_episodes_soup = bs(replay_show_season_html, 'html.parser') + + # Get data-account + data_account = re.compile( + r'data-account="(.*?)"').findall(replay_show_season_html)[0] + data_player = re.compile( + r'data-player="(.*?)"').findall(replay_show_season_html)[0] + + if "Series" in params.title: + # GET VideoId for each episode of season selected + seasons_episodes = seasons_episodes_soup.find_all( + 'div', class_='spanOneThird vod-episode clearfix ') + for episode in seasons_episodes: + if episode.get('data-series') == \ + params.title.split('Series')[1].strip(): + + data_vidid = episode.get('data-vidid') + + video_title = episode.get('data-title') + video_title = video_title + ' S%sE%s' % ( + episode.get('data-series'), episode.get('data-episode')) + video_duration = 0 + + video_plot = 'Expire ' + video_plot = video_plot + episode.get( + 'data-publishend').split('T')[0] + video_plot = video_plot + '\n' + episode.get( + 'data-teaser').encode('utf-8') + + video_img = episode.find('img').get('src') + + date_value = episode.get("data-publishstart") + date_value_list = date_value.split('T')[0].split('-') + day = date_value_list[2] + mounth = date_value_list[1] + year = date_value_list[0] + + date = '.'.join((day, mounth, year)) + aired = '-'.join((year, mounth, day)) + + info = { + 'video': { + 'title': video_title, + 'aired': aired, + 'date': date, + 'duration': video_duration, + 'plot': video_plot, + 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'fanart': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) + + play_episode = seasons_episodes_soup.find( + 'div', class_='spanOneThird vod-episode clearfix playing in') + if play_episode.get('data-series') == \ + params.title.split('Series')[1].strip(): + + data_vidid = play_episode.get('data-vidid') + + video_title = play_episode.get('data-title') + video_title = video_title + ' S%sE%s' % ( + play_episode.get('data-series'), + play_episode.get('data-episode') + ) + video_duration = 0 + video_plot = 'Expire ' + video_plot = video_plot + play_episode.get( + 'data-publishend').split('T')[0] + '\n ' + video_plot = video_plot + play_episode.get( + 'data-teaser').encode('utf-8') + video_img = play_episode.find('img').get('src') + + date_value = play_episode.get("data-publishstart") + date_value_list = date_value.split('T')[0].split('-') + day = date_value_list[2] + mounth = date_value_list[1] + year = date_value_list[0] + + date = '.'.join((day, mounth, year)) + aired = '-'.join((year, mounth, day)) + + info = { + 'video': { + 'title': video_title, + 'aired': aired, + 'date': date, + 'duration': video_duration, + 'plot': video_plot, + 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'fanart': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) + + else: + play_episode = seasons_episodes_soup.find( + 'div', class_='vod-video-container') + + data_vidid = play_episode.find('a').get('data-vidid') + + video_title = play_episode.find('img').get('alt') + video_duration = 0 + video_plot = seasons_episodes_soup.find( + 'p', class_='teaser').get_text().encode('utf-8') + video_img = re.compile( + 'itemprop="image" content="(.*?)"' + ).findall(replay_show_season_html)[0] + + date_value = re.compile( + 'itemprop="uploadDate" content="(.*?)"' + ).findall(replay_show_season_html)[0] + date_value_list = date_value.split(',')[0].split(' ') + if len(date_value_list[0]) == 1: + day = '0' + date_value_list[0] + else: + day = date_value_list[0] + try: + mounth = CORRECT_MOUNTH[date_value_list[1]] + except Exception: + mounth = '00' + year = date_value_list[2] + + date = '.'.join((day, mounth, year)) + aired = '-'.join((year, mounth, day)) + + info = { + 'video': { + 'title': video_title, + 'aired': aired, + 'date': date, + 'duration': video_duration, + 'plot': video_plot, + 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'fanart': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + data_vidid=data_vidid, + data_account=data_account, + data_player=data_player + ), + 'is_playable': True, + 'info': info, + 'context_menu': context_menu + }) + + return common.PLUGIN.create_listing( + videos, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_UNSORTED, + common.sp.xbmcplugin.SORT_METHOD_DURATION, + common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE, + common.sp.xbmcplugin.SORT_METHOD_GENRE, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + content='tvshows', + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_live(params): + """Build live listing""" + return None + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_video_url(params): + """Get video URL and start video player""" + if params.next == 'play_r' or params.next == 'download_video': + + session_requests = requests.session() + + # Build PAYLOAD + """ + payload = { + 'email': common.PLUGIN.get_setting( + params.channel_id.rsplit('.', 1)[0] + '.login'), + 'password': common.PLUGIN.get_setting( + params.channel_id.rsplit('.', 1)[0] + '.password') + } + result = session_requests.post(URL_AUTHENTICATE,payload) + """ + result_2 = session_requests.get( + URL_BRIGHTCOVE_API % (params.data_account, params.data_vidid), + headers={'Accept': 'application/json;pk=%s' % get_policy_key( + params.data_account, params.data_player)} + ) + return re.compile( + '"application/x-mpegURL","src":"(.+?)"').findall(result_2.text)[0] diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/ws/__init__.py b/plugin.video.catchuptvandmore/resources/lib/channels/ws/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/ws/__init__.py diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/ws/allocine.py b/plugin.video.catchuptvandmore/resources/lib/channels/ws/allocine.py new file mode 100644 index 0000000..f3d7bfa --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/ws/allocine.py @@ -0,0 +1,661 @@ +# -*- coding: utf-8 -*- +''' + Catch-up TV & More + Copyright (C) 2017 SylvainCecchetto + + This file is part of Catch-up TV & More. + + Catch-up TV & More is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Catch-up TV & More is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Catch-up TV & More; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +''' + +import ast +import json +import re +import requests +from bs4 import BeautifulSoup as bs +from youtube_dl import YoutubeDL +from resources.lib import utils +from resources.lib import common + +# TO DO +# Vimeo HTTP 503 +# Get Last_Page (for Programs, Videos) +# Get Partner Id ? +# Todo get Aired, Year, Date of the Video + +URL_ROOT = 'http://www.allocine.fr' + +URL_API_MEDIA = 'http://api.allocine.fr/rest/v3/' \ + 'media?code=%s&partner=%s&format=json' +# videoId, PARTENER + +PARTNER = 'YW5kcm9pZC12Mg' + +# Initialize GNU gettext emulation in addon +# This allows to use UI strings from addon’s English +# strings.po file instead of numeric codes +_ = common.ADDON.initialize_gettext() + + +def channel_entry(params): + """Entry function of the module""" + if 'root' in params.next: + return root(params) + if 'list_shows' in params.next: + return list_shows(params) + elif 'list_videos' in params.next: + return list_videos(params) + elif 'play' in params.next: + return get_video_url(params) + return None + + +CATEGORIES = { + 'Les émissions': URL_ROOT + '/video/', + 'Videos Films (Bandes-Annonces, Extraits, ...)': + URL_ROOT + '/video/films/', + 'Videos Séries TV (Bandes-Annonces, Extraits, ...)': + URL_ROOT + '/series/video/' +} + +CATEGORIES_LANGUAGE = { + 'VF': 'version-0/', + 'VO': 'version-1/' +} + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def root(params): + """Add modes in the listing""" + modes = [] + + for category_name, category_url in CATEGORIES.iteritems(): + + if 'series' in category_url or 'films' in category_url: + next_value = 'list_shows_films_series_1' + else: + next_value = 'list_shows_emissions_1' + + modes.append({ + 'label': category_name, + 'url': common.PLUGIN.get_url( + action='channel_entry', + category_url=category_url, + category_name=category_name, + next=next_value, + window_title=category_name + ) + }) + + return common.PLUGIN.create_listing( + modes, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_shows(params): + """Build categories listing""" + shows = [] + if 'previous_listing' in params: + shows = ast.literal_eval(params['previous_listing']) + + if params.next == 'list_shows_emissions_1': + + # Build Categories Emissions + replay_categories_programs_html = utils.get_webcontent( + params.category_url) + replay_categories_programs_soup = bs( + replay_categories_programs_html, 'html.parser') + root_categories_programs = replay_categories_programs_soup.find( + 'li', class_='item_4 is_active ') + replay_categories_programs = root_categories_programs.find_all('a') + + for category_programs in replay_categories_programs: + categorie_programs_title = category_programs.get_text() + categorie_programs_title = categorie_programs_title.strip() + categorie_programs_title = categorie_programs_title.encode('utf-8') + + categorie_programs_url = URL_ROOT + category_programs.get('href') + shows.append({ + 'label': categorie_programs_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_emissions_2', + title=categorie_programs_title, + categorie_programs_url=categorie_programs_url, + window_title=categorie_programs_title + ) + }) + + elif params.next == 'list_shows_emissions_2': + + # Build sub categories if exists / add 'Les Programmes', 'Les Vidéos' + replay_subcategories_programs_html = utils.get_webcontent( + params.categorie_programs_url) + replay_subcategories_programs_soup = bs( + replay_subcategories_programs_html, 'html.parser') + + # Les vidéos + show_title = '# Les videos' + next_value = 'list_videos_emissions_1' + show_url = params.categorie_programs_url + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + page='1', + show_url=show_url, + window_title=show_title + ) + }) + + # Les programmes + programs_title = '# Les programmes' + next_value = 'list_shows_emissions_4' + programs_url = params.categorie_programs_url.replace( + '/cat-', '/prgcat-') + + shows.append({ + 'label': programs_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=programs_title, + page='1', + programs_url=programs_url, + window_title=programs_title + ) + }) + + # Subcategories + subcategories = replay_subcategories_programs_soup.find( + 'div', class_='nav-button-filter').find_all('a') + + for subcategory in subcategories: + subcategorie_programs_title = subcategory.find( + 'span', class_='label').get_text().encode('utf-8') + subcategorie_programs_url = URL_ROOT + subcategory.get('href') + + shows.append({ + 'label': subcategorie_programs_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_emissions_3', + title=subcategorie_programs_title, + subcategorie_programs_url=subcategorie_programs_url, + window_title=subcategorie_programs_title + ) + }) + + elif params.next == 'list_shows_emissions_3': + + # Les vidéos + show_title = '# Les videos' + next_value = 'list_videos_emissions_1' + show_url = params.subcategorie_programs_url + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + page='1', + show_url=show_url, + window_title=show_title + ) + }) + + # Les programmes + programs_title = '# Les programmes' + next_value = 'list_shows_emissions_4' + programs_url = params.subcategorie_programs_url.replace( + '/cat-', '/prgcat-') + + shows.append({ + 'label': programs_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=programs_title, + page='1', + programs_url=programs_url, + window_title=programs_title + ) + }) + + elif params.next == 'list_shows_emissions_4': + + replay_programs_html = utils.get_webcontent( + params.programs_url + '?page=%s' % params.page) + replay_programs_soup = bs(replay_programs_html, 'html.parser') + replay_programs = replay_programs_soup.find_all( + 'figure', class_='media-meta-fig') + + for program in replay_programs: + + program_title = program.find( + 'h2', class_='title ' + ).find('span').find('a').get_text().strip().encode('utf-8') + program_img = program.find('img').get('src') + program_url = URL_ROOT + program.find( + 'h2', class_='title ' + ).find('span').find('a').get('href').encode('utf-8') + + shows.append({ + 'label': program_title, + 'thumb': program_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_emissions_5', + program_title=program_title, + program_url=program_url, + window_title=program_title + ) + }) + + if replay_programs_soup.find('div', class_='pager pager margin_40t') \ + is not None: + # More programs... + shows.append({ + 'label': '# ' + common.ADDON.get_localized_string(30108), + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_shows_emissions_4', + programs_url=params.programs_url, + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(shows) + ), + }) + + elif params.next == 'list_shows_emissions_5': + + replay_seasons_html = utils.get_webcontent( + params.program_url + 'saisons/') + replay_seasons_soup = bs(replay_seasons_html, 'html.parser') + replay_seasons = replay_seasons_soup.find_all( + 'h2', class_='fs18 d_inline_block margin_10r') + + if len(replay_seasons) > 0: + + for season in replay_seasons: + season_title = season.find('a').find('span').get_text().strip() + show_season_url = URL_ROOT + season.find( + 'a', class_='no_underline').get('href').encode('utf-8') + + # Get Last Page + last_page = '0' + info_show_season = utils.get_webcontent(show_season_url) + info_show_season_pages = re.compile( + '<a href="(.*?)"').findall(info_show_season) + for info_show_season_page in info_show_season_pages: + if '?page=' in info_show_season_page: + last_page = info_show_season_page.split('=')[1] + + shows.append({ + 'label': season_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_emissions_1', + title=season_title, + page='1', + last_page=last_page, + show_url=show_season_url, + window_title=season_title + ) + }) + + else: + season_title = replay_seasons_soup.find( + 'div', class_='margin_20t margin_40b' + ).find('a').get_text().strip().encode('utf-8') + show_season_url = URL_ROOT + replay_seasons_soup.find( + 'div', class_='margin_20t margin_40b' + ).find('a').get('href').encode('utf-8') + + # Get Last Page + last_page = '0' + info_show_season = utils.get_webcontent(show_season_url) + info_show_season_pages = re.compile( + '<a href="(.*?)"').findall(info_show_season) + for info_show_season_page in info_show_season_pages: + if '?page=' in info_show_season_page: + last_page = info_show_season_page.split('=')[1] + + shows.append({ + 'label': season_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_emissions_1', + title=season_title, + page='1', + last_page=last_page, + show_url=show_season_url, + window_title=season_title + ) + }) + + elif params.next == 'list_shows_films_series_1': + + # Build All Types + replay_types_films_series_html = utils.get_webcontent( + params.category_url) + replay_types_films_series_soup = bs( + replay_types_films_series_html, 'html.parser') + replay_types_films_series = replay_types_films_series_soup.find_all( + 'div', class_='left_col_menu_item')[0] + + show_title = '# Toutes les videos' + next_value = 'list_videos_films_series_1' + show_url = params.category_url + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + page='1', + show_url=show_url, + window_title=show_title + ) + }) + + for all_types in replay_types_films_series.find_all('a'): + + show_title = all_types.get_text() + next_value = 'list_shows_films_series_2' + show_url = URL_ROOT + all_types.get('href') + + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + show_url=show_url, + window_title=show_title + ) + }) + + elif params.next == 'list_shows_films_series_2': + + # Build All Languages + show_title = '# Toutes les videos' + next_value = 'list_videos_films_series_1' + show_url = params.show_url + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + show_url=show_url, + page='1', + window_title=show_title + ) + }) + + for language, language_url in CATEGORIES_LANGUAGE.iteritems(): + + show_title = language + next_value = 'list_videos_films_series_1' + show_url = params.show_url + language_url + + shows.append({ + 'label': show_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=next_value, + title=show_title, + show_url=show_url, + page='1', + window_title=show_title + ) + }) + + return common.PLUGIN.create_listing( + shows, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + update_listing='update_listing' in params, + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_videos(params): + """Build videos listing""" + videos = [] + if 'previous_listing' in params: + videos = ast.literal_eval(params['previous_listing']) + + if params.next == 'list_videos_films_series_1': + + replay_episodes_html = utils.get_webcontent( + params.show_url + '?page=%s' % params.page) + replay_episodes_soup = bs(replay_episodes_html, 'html.parser') + episodes = replay_episodes_soup.find_all( + 'article', class_="media-meta sidecontent small") + + for episode in episodes: + video_title = episode.find('h2').find( + 'span').find('a').get_text().strip().encode('utf-8') + video_id = re.compile( + 'cmedia=(.*?)&').findall(episode.find('a').get('href'))[0] + video_img = episode.find('img').get('src').encode('utf-8') + video_duration = 0 + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + # 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_id=video_id) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_id=video_id + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + + # More videos... + videos.append({ + 'label': '# ' + common.ADDON.get_localized_string(30100), + 'url': common.PLUGIN.get_url( + action='channel_entry', + show_url=params.show_url, + next='list_videos_films_series_1', + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(videos) + ), + }) + + elif params.next == 'list_videos_emissions_1': + replay_episodes_html = utils.get_webcontent( + params.show_url + '?page=%s' % params.page) + replay_episodes_soup = bs(replay_episodes_html, 'html.parser') + + if replay_episodes_soup.find( + 'section', class_='media-meta-list by2 j_w') is not None: + root_episodes_soup = replay_episodes_soup.find( + 'section', class_='media-meta-list by2 j_w') + episodes = root_episodes_soup.find_all( + 'figure', class_='media-meta-fig') + else: + episodes = replay_episodes_soup.find_all( + 'figure', class_='media-meta-fig') + + for episode in episodes: + if episode.find('h3') is not None: + video_title = episode.find( + 'h3').find('span').find('a').get_text().strip() + else: + video_title = episode.find( + 'h2').find('span').find('a').get_text().strip() + if '?cmedia=' in episode.find('a').get('href'): + video_id = episode.find('a').get('href').split('?cmedia=')[1] + elif 'cfilm=' in episode.find('a').get('href') or \ + 'cserie=' in episode.find('a').get('href'): + video_id = episode.find( + 'h2').find('span').find( + 'a').get('href').split('_cmedia=')[1].split('&')[0] + else: + video_id = episode.find( + 'a').get('href').split('-')[1].replace('/', '') + video_plot = '' + for plot_value in episode.find( + 'div', class_='media-meta-figcaption-inner').find_all('p'): + video_plot = plot_value.get_text().strip() + if episode.find('meta') is not None: + video_img = episode.find('meta').get('content').encode('utf-8') + else: + video_img = episode.find('img').get('src').encode('utf-8') + video_duration = 0 + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_id=video_id) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_id=video_id + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + + # More videos... + videos.append({ + 'label': '# ' + common.ADDON.get_localized_string(30100), + 'url': common.PLUGIN.get_url( + action='channel_entry', + show_url=params.show_url, + # last_page=params.last_page, + next='list_videos_1', + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(videos) + ), + }) + + return common.PLUGIN.create_listing( + videos, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + content='tvshows', + update_listing='update_listing' in params, + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_video_url(params): + """Get video URL and start video player""" + video_json = utils.get_webcontent( + URL_API_MEDIA % (params.video_id, PARTNER)) + video_json_parser = json.loads(video_json) + + url = '' + if 'rendition' in video_json_parser["media"]: + # (Video Hosted By Allocine) + for media in video_json_parser["media"]["rendition"]: + url = media["href"] + if requests.get(url, stream=True).status_code == 404: + utils.send_notification(common.ADDON.get_localized_string(30111)) + return '' + return url + else: + # (Video Not Hosted By Allocine) + url_video_embeded = re.compile( + 'src=\'(.*?)\'' + ).findall(video_json_parser["media"]["trailerEmbed"])[0] + url_video_embeded_html = utils.get_webcontent(url_video_embeded) + url_video_json = re.compile( + 'data-model="(.*?)"' + ).findall(url_video_embeded_html)[0].replace('"', '"') + url_video_json_parser = json.loads(url_video_json) + # Case Facebook, Youtube and Vimeo (Not Working HTTP 503) + if 'facebook' in url_video_json or \ + 'youtube' in url_video_json or 'vimeo' in url_video_json: + url_ytdl = url_video_json_parser["videos"][0]["sources"]["code"] + url_ytdl = re.compile('src=(.*?) ').findall( + url_ytdl + )[0].replace('\\', '').replace('&', '&').replace('"', '') + # Case DailyMotion + else: + url_ytdl = url_video_json_parser["videos"] + url_ytdl = url_ytdl[0]["sources"]["url_provider"] + url_ytdl = 'https:' + url_ytdl.split( + ':')[1].replace( + '\\', '').replace('&', '&').replace('"', '') + ydl = YoutubeDL() + ydl.add_default_info_extractors() + with ydl: + result = ydl.extract_info(url_ytdl, download=False) + for format_video in result['formats']: + url = format_video['url'] + return url diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/ws/tetesaclaques.py b/plugin.video.catchuptvandmore/resources/lib/channels/ws/tetesaclaques.py new file mode 100644 index 0000000..195d19f --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/lib/channels/ws/tetesaclaques.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +''' + Catch-up TV & More + Copyright (C) 2017 SylvainCecchetto + + This file is part of Catch-up TV & More. + + Catch-up TV & More is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Catch-up TV & More is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Catch-up TV & More; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +''' + +import ast +import re +from bs4 import BeautifulSoup as bs +from youtube_dl import YoutubeDL +from resources.lib import utils +from resources.lib import common + +# TO DO +# Play Spanish Videos + +URL_ROOT = 'https://www.tetesaclaques.tv' + +URL_YOUTUBE = 'https://www.youtube.com/embed/%s?&autoplay=0' +# YTid + +# Initialize GNU gettext emulation in addon +# This allows to use UI strings from addon’s English +# strings.po file instead of numeric codes +_ = common.ADDON.initialize_gettext() + + +def channel_entry(params): + """Entry function of the module""" + if 'root' in params.next: + return root(params) + if 'list_shows' in params.next: + return list_shows(params) + elif 'list_videos' in params.next: + return list_videos(params) + elif 'play' in params.next: + return get_video_url(params) + return None + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def root(params): + """Add modes in the listing""" + modes = [] + + list_categories_html = utils.get_webcontent(URL_ROOT) + list_categories_soup = bs(list_categories_html, 'html.parser') + list_categories = list_categories_soup.find( + 'div', class_='jqueryslidemenu').find('ul').find('ul').find_all('li') + + for category in list_categories: + + if 'personnages' in category.find('a').get('href'): + value_next = 'list_shows_1' + else: + value_next = 'list_videos_1' + category_title = category.find('a').get_text() + category_url = URL_ROOT + '/' + category.find('a').get('href') + + modes.append({ + 'label': category_title, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next=value_next, + title=category_title, + page='1', + category_url=category_url, + window_title=category_title + ) + }) + + return common.PLUGIN.create_listing( + modes, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_shows(params): + """Build categories listing""" + shows = [] + + list_shows_html = utils.get_webcontent(params.category_url) + list_shows_soup = bs(list_shows_html, 'html.parser') + list_shows = list_shows_soup.find( + 'div', class_='personnages').find_all('a') + + for personnage in list_shows: + + show_title = personnage.get('title') + show_img = URL_ROOT + personnage.find('img').get('src') + show_url = URL_ROOT + personnage.get('href').encode('utf-8') + + shows.append({ + 'label': show_title, + 'thumb': show_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='list_videos_2', + title=show_title, + category_url=show_url, + window_title=show_title + ) + }) + + return common.PLUGIN.create_listing( + shows, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def list_videos(params): + """Build videos listing""" + videos = [] + if 'previous_listing' in params: + videos = ast.literal_eval(params['previous_listing']) + + if params.next == 'list_videos_1': + + replay_episodes_html = utils.get_webcontent( + params.category_url + '/par_date/%s' % params.page) + replay_episodes_soup = bs(replay_episodes_html, 'html.parser') + + if 'serietele' in params.category_url: + episodes = replay_episodes_soup.find( + 'div', class_='serieTele').find_all('div') + + for episode in episodes: + if episode.find('a') is not None and \ + episode.find('img', class_='thumb') is not None: + video_title = episode.find('a').find( + 'span', class_='saison-episode' + ).get_text().strip() + ' ' + episode.find('img').get('alt') + video_url = URL_ROOT + episode.find('a').get('href') + video_img = URL_ROOT + '/' + episode.find('img').get('src') + video_duration = 0 + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + # 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_url=video_url) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_url=video_url + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + else: + episodes = replay_episodes_soup.find_all( + 'a', class_='lienThumbCollection') + + for episode in episodes: + video_title = episode.find('img').get('alt') + video_url = URL_ROOT + episode.get('href') + video_img = URL_ROOT + '/' + episode.find('img').get('src') + video_duration = 0 + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + # 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_url=video_url) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_url=video_url + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + + # More videos... + videos.append({ + 'label': '# ' + common.ADDON.get_localized_string(30100), + 'url': common.PLUGIN.get_url( + action='channel_entry', + category_url=params.category_url, + next='list_videos_1', + page=str(int(params.page) + 1), + update_listing=True, + previous_listing=str(videos) + ), + }) + + elif 'list_videos_2': + + replay_episodes_html = utils.get_webcontent(params.category_url) + replay_episodes_soup = bs(replay_episodes_html, 'html.parser') + episodes = replay_episodes_soup.find_all( + 'a', class_='lienThumbCollection') + + for episode in episodes: + video_title = episode.find('img').get('alt') + video_url = URL_ROOT + episode.get('href') + video_img = URL_ROOT + '/' + episode.find('img').get('src') + video_duration = 0 + + info = { + 'video': { + 'title': video_title, + # 'aired': aired, + # 'date': date, + 'duration': video_duration, + # 'plot': video_plot, + # 'year': year, + 'mediatype': 'tvshow' + } + } + + context_menu = [] + download_video = ( + _('Download'), + 'XBMC.RunPlugin(' + common.PLUGIN.get_url( + action='download_video', + video_url=video_url) + ')' + ) + context_menu.append(download_video) + + videos.append({ + 'label': video_title, + 'thumb': video_img, + 'url': common.PLUGIN.get_url( + action='channel_entry', + next='play_r', + video_url=video_url + ), + 'is_playable': True, + 'info': info # , + # 'context_menu': context_menu + }) + + return common.PLUGIN.create_listing( + videos, + sort_methods=( + common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE, + common.sp.xbmcplugin.SORT_METHOD_UNSORTED + ), + content='tvshows', + update_listing='update_listing' in params, + ) + + +@common.PLUGIN.mem_cached(common.CACHE_TIME) +def get_video_url(params): + """Get video URL and start video player""" + video_html = utils.get_webcontent(params.video_url) + if re.compile('AtedraVideo.video_id = "(.*?)"').findall(video_html): + url_ytdl = URL_YOUTUBE % re.compile( + 'AtedraVideo.video_id = "(.*?)"').findall(video_html)[0] + else: + # TO DO Espagnol Video + return '' + + ydl = YoutubeDL() + ydl.add_default_info_extractors() + with ydl: + result = ydl.extract_info(url_ytdl, download=False) + for format_video in result['formats']: + url = format_video['url'] + return url diff --git a/plugin.video.catchuptvandmore/resources/lib/common.py b/plugin.video.catchuptvandmore/resources/lib/common.py index f403d7f..5ef8879 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/common.py +++ b/plugin.video.catchuptvandmore/resources/lib/common.py @@ -30,6 +30,7 @@ CACHE_TIME = 10 PLUGIN_NAME = 'Catch-up TV & More' + def get_window_title(): query = sp.sys.argv[2][1:] params = PLUGIN.get_params(query) diff --git a/plugin.video.catchuptvandmore/resources/lib/simpleplugin.py b/plugin.video.catchuptvandmore/resources/lib/simpleplugin.py index f3b6f9d..6b1e90d 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/simpleplugin.py +++ b/plugin.video.catchuptvandmore/resources/lib/simpleplugin.py @@ -11,6 +11,7 @@ SimplePlugin micro-framework for Kodi content plugins import os import sys import re +import inspect from datetime import datetime, timedelta import cPickle as pickle from urlparse import parse_qs @@ -21,15 +22,20 @@ from copy import deepcopy from types import GeneratorType from hashlib import md5 from shutil import move +from contextlib import contextmanager +from pprint import pformat import xbmcaddon import xbmc import xbmcplugin import xbmcgui -__all__ = ['SimplePluginError', 'Storage', 'Addon', 'Plugin', 'Params'] +__all__ = ['SimplePluginError', 'Storage', 'MemStorage', + 'Addon', 'Plugin', 'Params', 'debug_exception'] -ListContext = namedtuple('ListContext', ['listing', 'succeeded', 'update_listing', 'cache_to_disk', - 'sort_methods', 'view_mode', 'content']) +ListContext = namedtuple('ListContext', ['listing', 'succeeded', + 'update_listing', 'cache_to_disk', + 'sort_methods', 'view_mode', + 'content', 'category']) PlayContext = namedtuple('PlayContext', ['path', 'play_item', 'succeeded']) @@ -38,6 +44,71 @@ class SimplePluginError(Exception): pass +def _format_vars(variables): + """ + Format variables dictionary + + :param variables: variables dict + :type variables: dict + :return: formatted string with sorted ``var = val`` pairs + :rtype: str + """ + var_list = [(var, val) for var, val in variables.iteritems()] + lines = [] + for var, val in sorted(var_list, key=lambda i: i[0]): + if not (var.startswith('__') or var.endswith('__')): + lines.append('{0} = {1}'.format(var, pformat(val))) + return '\n'.join(lines) + + +@contextmanager +def debug_exception(logger=None): + """ + Diagnostic helper context manager + + It controls execution within its context and writes extended + diagnostic info to the Kodi log if an unhandled exception + happens within the context. The info includes the following items: + + - Module path. + - Code fragment where the exception has happened. + - Global variables. + - Local variables. + + After logging the diagnostic info the exception is re-raised. + + Example:: + + with debug_exception(): + # Some risky code + raise RuntimeError('Fatal error!') + + :param logger: logger function which must accept a single argument + which is a log message. By default it is :func:`xbmc.log` + with ``ERROR`` level. + """ + try: + yield + except: + if logger is None: + logger = lambda msg: xbmc.log(msg, xbmc.LOGERROR) + logger('Unhandled exception detected!') + logger('*** Start diagnostic info ***') + frame_info = inspect.trace(5)[-1] + logger('File: {0}'.format(frame_info[1])) + context = '' + for i, line in enumerate(frame_info[4], frame_info[2] - frame_info[5]): + if i == frame_info[2]: + context += '{0}:>{1}'.format(str(i).rjust(5), line) + else: + context += '{0}: {1}'.format(str(i).rjust(5), line) + logger('Code context:\n' + context) + logger('Global variables:\n' + _format_vars(frame_info[0].f_globals)) + logger('Local variables:\n' + _format_vars(frame_info[0].f_locals)) + logger('**** End diagnostic info ****') + raise + + class Params(dict): """ Params(**kwargs) @@ -47,6 +118,8 @@ class Params(dict): Parameters can be accessed both through :class:`dict` keys and instance properties. + .. note:: For a missing parameter an instance property returns ``None``. + Example: .. code-block:: python @@ -56,10 +129,8 @@ class Params(dict): foo = params['foo'] # Access by key bar = params.bar # Access through property. Both variants are equal """ - def __getattr__(self, item): - if item not in self: - raise AttributeError('Invalid parameter: "{0}"!'.format(item)) - return self[item] + def __getattr__(self, key): + return self.get(key) def __str__(self): return '<Params {0}>'.format(super(Params, self).__repr__()) @@ -70,6 +141,8 @@ class Params(dict): class Storage(MutableMapping): """ + Storage(storage_dir, filename='storage.pcl') + Persistent storage for arbitrary data with a dictionary-like interface It is designed as a context manager and better be used @@ -107,7 +180,7 @@ class Storage(MutableMapping): def __enter__(self): return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, t, v, tb): self.flush() def __getitem__(self, key): @@ -120,7 +193,7 @@ class Storage(MutableMapping): del self._storage[key] def __iter__(self): - return self._storage.__iter__() + return iter(self._storage) def __len__(self): return len(self._storage) @@ -163,6 +236,106 @@ class Storage(MutableMapping): return deepcopy(self._storage) +class MemStorage(MutableMapping): + """ + MemStorage(storage_id) + + In-memory storage with dict-like interface + + The data is stored in the Kodi core so contents of a MemStorage instance + with the same ID can be shared between different Python processes. + + .. note:: Keys are case-insensitive + + .. warning:: :class:`MemStorage` does not allow to modify mutable objects + in place! You need to assign them to variables first, modify and + store them back to a MemStorage instance. + + Example: + + .. code-block:: python + + storage = MemStorage('foo') + some_list = storage['bar'] + some_list.append('spam') + storage['bar'] = some_list + + :param storage_id: ID of this storage instance + :type storage_id: str + :param window_id: the ID of a Kodi Window object where storage contents + will be stored. + :type window_id: int + """ + def __init__(self, storage_id, window_id=10000): + self._id = storage_id + self._window = xbmcgui.Window(window_id) + try: + self['__keys__'] + except KeyError: + self['__keys__'] = [] + + def _check_key(self, key): + if not isinstance(key, str): + raise TypeError('Storage key must be of str type!') + + def _format_contents(self): + lines = [] + for key, val in self.iteritems(): + lines.append('{0}: {1}'.format(repr(key), repr(val))) + return ', '.join(lines) + + def __str__(self): + return '<MemStorage {{{0}}}>'.format(self._format_contents()) + + def __repr__(self): + return '<simpleplugin.MemStorage object {{{0}}}'.format(self._format_contents()) + + def __getitem__(self, key): + self._check_key(key) + full_key = '{0}__{1}'.format(self._id, key) + raw_item = self._window.getProperty(full_key) + if raw_item: + return pickle.loads(raw_item) + else: + raise KeyError(key) + + def __setitem__(self, key, value): + self._check_key(key) + full_key = '{0}__{1}'.format(self._id, key) + self._window.setProperty(full_key, pickle.dumps(value)) + if key != '__keys__': + keys = self['__keys__'] + keys.append(key) + self['__keys__'] = keys + + def __delitem__(self, key): + self._check_key(key) + full_key = '{0}__{1}'.format(self._id, key) + item = self._window.getProperty(full_key) + if item: + self._window.clearProperty(full_key) + if key != '__keys__': + keys = self['__keys__'] + keys.remove(key) + self['__keys__'] = keys + else: + raise KeyError(key) + + def __contains__(self, key): + self._check_key(key) + full_key = '{0}__{1}'.format(self._id, key) + item = self._window.getProperty(full_key) + if item: + return True + return False + + def __iter__(self): + return iter(self['__keys__']) + + def __len__(self): + return len(self['__keys__']) + + class Addon(object): """ Base addon class @@ -358,7 +531,7 @@ class Addon(object): :param message: message to write to the Kodi log :type message: str """ - self.log(message, xbmc.LOGINFO) + self.log(message, xbmc.LOGNOTICE) def log_warning(self, message): """ @@ -408,6 +581,62 @@ class Addon(object): """ return Storage(self.config_dir, filename) + def get_mem_storage(self, storage_id='', window_id=10000): + """ + Creates an in-memory storage for this addon with :class:`dict`-like + interface + + The storage can store picklable Python objects as long as + Kodi is running and storage contents can be shared between + Python processes. Different addons have separate storages, + so storages with the same names created with this method + do not conflict. + + Example:: + + addon = Addon() + storage = addon.get_mem_storage() + foo = storage['foo'] + storage['bar'] = bar + + :param storage_id: optional storage ID (case-insensitive). + :type storage_id: str + :param window_id: the ID of a Kodi Window object where storage contents + will be stored. + :type window_id: int + :return: in-memory storage for this addon + :rtype: MemStorage + """ + if storage_id: + storage_id = '{0}_{1}'.format(self.id, storage_id) + return MemStorage(storage_id, window_id) + + def _get_cached_data(self, cache, func, duration, *args, **kwargs): + """ + Get data from a cache object + + :param cache: cache object + :param func: function to cache + :param duration: cache duration + :param args: function args + :param kwargs: function kwargs + :return: function return data + """ + if duration <= 0: + raise ValueError('Caching duration cannot be zero or negative!') + current_time = datetime.now() + key = func.__name__ + str(args) + str(kwargs) + try: + data, timestamp = cache[key] + if current_time - timestamp > timedelta(minutes=duration): + raise KeyError + self.log_debug('Cache hit: {0}'.format(key)) + except KeyError: + self.log_debug('Cache miss: {0}'.format(key)) + data = func(*args, **kwargs) + cache[key] = (data, current_time) + return data + def cached(self, duration=10): """ Cached decorator @@ -429,20 +658,30 @@ class Addon(object): @wraps(func) def inner_wrapper(*args, **kwargs): with self.get_storage('__cache__.pcl') as cache: - current_time = datetime.now() - key = func.__name__ + str(args) + str(kwargs) - try: - data, timestamp = cache[key] - if duration > 0 and current_time - timestamp > timedelta(minutes=duration): - raise KeyError - elif duration <= 0: - raise ValueError('Caching duration cannot be zero or negative!') - self.log_debug('Cache hit: {0}'.format(key)) - except KeyError: - self.log_debug('Cache miss: {0}'.format(key)) - data = func(*args, **kwargs) - cache[key] = (data, current_time) - return data + return self._get_cached_data(cache, func, duration, *args, **kwargs) + return inner_wrapper + return outer_wrapper + + def mem_cached(self, duration=10): + """ + In-memory cache decorator + + Usage:: + + @plugin.mem_cached(30) + def my_func(*args, **kwargs): + # Do some stuff + return value + + :param duration: caching duration in min (positive values only) + :type duration: int + :raises ValueError: if duration is zero or negative + """ + def outer_wrapper(func): + @wraps(func) + def inner_wrapper(*args, **kwargs): + cache = self.get_mem_storage('***cache***') + return self._get_cached_data(cache, func, duration, *args, **kwargs) return inner_wrapper return outer_wrapper @@ -462,7 +701,7 @@ class Addon(object): :type ui_string: str :return: a UI string from translated :file:`strings.po`. :rtype: unicode - :raises simpleplugin.SimplePluginError: if :meth:`Addon.initialize_gettext` wasn't called first + :raises SimplePluginError: if :meth:`Addon.initialize_gettext` wasn't called first or if a string is not found in English :file:`strings.po`. """ if self._ui_strings_map is not None: @@ -502,9 +741,11 @@ class Addon(object): with localized versions if these strings are translated. :return: :meth:`Addon.gettext` method object - :raises simpleplugin.SimplePluginError: if the addon's English :file:`strings.po` file is missing + :raises SimplePluginError: if the addon's English :file:`strings.po` file is missing """ strings_po = os.path.join(self.path, 'resources', 'language', 'resource.language.en_gb', 'strings.po') + if not os.path.exists(strings_po): + strings_po = os.path.join(self.path, 'resources', 'language', 'English', 'strings.po') if os.path.exists(strings_po): with open(strings_po, 'rb') as fo: raw_strings = fo.read() @@ -563,20 +804,20 @@ class Plugin(Addon): plugin = Plugin() @plugin.action() - def root(params): # Mandatory item! + def root(): # Mandatory item! return [{'label': 'Foo', - 'url': plugin.get_url(action='some_action', param='Foo')}, + 'url': plugin.get_url(action='some_action', label='Foo')}, {'label': 'Bar', - 'url': plugin.get_url(action='some_action', param='Bar')}] + 'url': plugin.get_url(action='some_action', label='Bar')}] @plugin.action() def some_action(params): - return [{'label': params['param']}] + return [{'label': params.label]}] plugin.run() - An action callable receives 1 parameter -- params. - params is a dict-like object containing plugin call parameters (including action string) + An action callable may receive 1 optional parameter which is + a dict-like object containing plugin call parameters (including action string) The action callable can return either a list/generator of dictionaries representing Kodi virtual directory items or a resolved playable path (:class:`str` or :obj:`unicode`) for Kodi to play. @@ -626,6 +867,21 @@ class Plugin(Addon): except for ``'url'`` and ``'is_folder'``, are ignored. - properties -- a dictionary of list item properties (see :meth:`xbmcgui.ListItem.setProperty`) -- optional. + - cast -- a list of cast info (actors, roles, thumbnails) for the list item + (see :meth:`xbmcgui.ListItem.setCast`) -- optional. + - offscreen -- if ``True`` do not lock GUI (used for Python scrapers and subtitle plugins) -- + optional. + - content_lookup -- if ``False``, do not HEAD requests to get mime type. Optional. + - online_db_ids -- a :class:`dict` of ``{'label': 'value'}`` pairs representing + the item's IDs in popular online databases. Possible labels: 'imdb', 'tvdb', + 'tmdb', 'anidb', see :meth:`xbmcgui.ListItem.setUniqueIDs`. Optional. + - ratings -- a :class:`list` of :class:`dict`s with the following keys: + 'type' (:class:`str`), 'rating' (:class:`float`), + 'votes' (:class:`int`, optional), 'defaultt' (:class:`bool`, optional). + This list sets item's ratings in popular online databases. + Possible types: 'imdb', 'tvdb', tmdb', 'anidb'. + See :meth:`xbmcgui.ListItem.setRating`. Optional. + Example 3:: @@ -743,7 +999,7 @@ class Plugin(Addon): :param name: action's name (optional). :type name: str - :raises simpleplugin.SimplePluginError: if the action with such name is already defined. + :raises SimplePluginError: if the action with such name is already defined. """ def wrap(func, name=name): if name is None: @@ -754,49 +1010,55 @@ class Plugin(Addon): return func return wrap - def run(self, category=''): + def run(self, category=None): """ Run plugin - :param category: str - plugin sub-category, e.g. 'Comedy'. - See :func:`xbmcplugin.setPluginCategory` for more info. - :type category: str - :raises simpleplugin.SimplePluginError: if unknown action string is provided. + :raises SimplePluginError: if unknown action string is provided. """ - self._handle = int(sys.argv[1]) if category: - xbmcplugin.setPluginCategory(self._handle, category) + self.log_warning( + 'Deprecation warning: Plugin category is no longer set via Plugin.run(). ' + 'Use "category" parameter of Plugin.create_listing() instead.' + ) + self._handle = int(sys.argv[1]) params = self.get_params(sys.argv[2][1:]) action = params.get('action', 'root') self.log_debug(str(self)) self.log_debug('Actions: {0}'.format(str(self.actions.keys()))) - self.log_debug('Called action "{0}" with params "{1}"'.format(action, str(params))) + self.log_debug('Called action "{0}" with params "{1}"'.format( + action, str(params)) + ) try: action_callable = self.actions[action] except KeyError: raise SimplePluginError('Invalid action: "{0}"!'.format(action)) else: - result = action_callable(params) + # inspect.isfunction is needed for tests + if inspect.isfunction(action_callable) and not inspect.getargspec(action_callable).args: + result = action_callable() + else: + result = action_callable(params) self.log_debug('Action return value: {0}'.format(str(result))) if isinstance(result, (list, GeneratorType)): self._add_directory_items(self.create_listing(result)) elif isinstance(result, basestring): self._set_resolved_url(self.resolve_url(result)) - elif isinstance(result, tuple) and hasattr(result, 'listing'): + elif isinstance(result, ListContext): self._add_directory_items(result) - elif isinstance(result, tuple) and hasattr(result, 'path'): + elif isinstance(result, PlayContext): self._set_resolved_url(result) else: self.log_debug('The action "{0}" has not returned any valid data to process.'.format(action)) @staticmethod def create_listing(listing, succeeded=True, update_listing=False, cache_to_disk=False, sort_methods=None, - view_mode=None, content=None): + view_mode=None, content=None, category=None): """ Create and return a context dict for a virtual folder listing :param listing: the list of the plugin virtual folder items - :type listing: :class:`list` or :class:`types.GeneratorType` + :type listing: list or types.GeneratorType :param succeeded: if ``False`` Kodi won't open a new listing and stays on the current level. :type succeeded: bool :param update_listing: if ``True``, Kodi won't open a sub-listing but refresh the current one. @@ -811,11 +1073,15 @@ class Plugin(Addon): :param content: string - current plugin content, e.g. 'movies' or 'episodes'. See :func:`xbmcplugin.setContent` for more info. :type content: str + :param category: str - plugin sub-category, e.g. 'Comedy'. + See :func:`xbmcplugin.setPluginCategory` for more info. + :type category: str :return: context object containing necessary parameters to create virtual folder listing in Kodi UI. :rtype: ListContext """ - return ListContext(listing, succeeded, update_listing, cache_to_disk, sort_methods, view_mode, content) + return ListContext(listing, succeeded, update_listing, cache_to_disk, + sort_methods, view_mode, content, category) @staticmethod def resolve_url(path='', play_item=None, succeeded=True): @@ -847,15 +1113,25 @@ class Plugin(Addon): :return: ListItem instance :rtype: xbmcgui.ListItem """ - list_item = xbmcgui.ListItem(label=item.get('label', ''), - label2=item.get('label2', ''), - path=item.get('path', '')) - if int(xbmc.getInfoLabel('System.BuildVersion')[:2]) >= 16: + major_version = xbmc.getInfoLabel('System.BuildVersion')[:2] + if major_version >= '18': + list_item = xbmcgui.ListItem(label=item.get('label', ''), + label2=item.get('label2', ''), + path=item.get('path', ''), + offscreen=item.get('offscreen', False)) + else: + list_item = xbmcgui.ListItem(label=item.get('label', ''), + label2=item.get('label2', ''), + path=item.get('path', '')) + if major_version >= '16': art = item.get('art', {}) art['thumb'] = item.get('thumb', '') art['icon'] = item.get('icon', '') art['fanart'] = item.get('fanart', '') item['art'] = art + cont_look = item.get('content_lookup') + if cont_look is not None: + list_item.setContentLookup(cont_look) else: list_item.setThumbnailImage(item.get('thumb', '')) list_item.setIconImage(item.get('icon', '')) @@ -877,6 +1153,17 @@ class Plugin(Addon): if item.get('properties'): for key, value in item['properties'].iteritems(): list_item.setProperty(key, value) + if major_version >= '17': + cast = item.get('cast') + if cast is not None: + list_item.setCast(cast) + db_ids = item.get('online_db_ids') + if db_ids is not None: + list_item.setUniqueIDs(db_ids) + ratings = item.get('ratings') + if ratings is not None: + for rating in ratings: + list_item.setRating(**rating) return list_item def _add_directory_items(self, context): @@ -885,8 +1172,11 @@ class Plugin(Addon): :param context: context object :type context: ListContext + :raises SimplePluginError: if sort_methods parameter is not int, tuple or list """ self.log_debug('Creating listing from {0}'.format(str(context))) + if context.category is not None: + xbmcplugin.setPluginCategory(self._handle, context.category) if context.content is not None: xbmcplugin.setContent(self._handle, context.content) # This must be at the beginning for item in context.listing: @@ -900,7 +1190,14 @@ class Plugin(Addon): is_folder = False xbmcplugin.addDirectoryItem(self._handle, item['url'], list_item, is_folder) if context.sort_methods is not None: - [xbmcplugin.addSortMethod(self._handle, method) for method in context.sort_methods] + if isinstance(context.sort_methods, int): + xbmcplugin.addSortMethod(self._handle, context.sort_methods) + elif isinstance(context.sort_methods, (tuple, list)): + for method in context.sort_methods: + xbmcplugin.addSortMethod(self._handle, method) + else: + raise TypeError( + 'sort_methods parameter must be of int, tuple or list type!') xbmcplugin.endOfDirectory(self._handle, context.succeeded, context.update_listing, @@ -920,4 +1217,4 @@ class Plugin(Addon): list_item = xbmcgui.ListItem(path=context.path) else: list_item = self.create_list_item(context.play_item) - xbmcplugin.setResolvedUrl(self._handle, context.succeeded, list_item)
\ No newline at end of file + xbmcplugin.setResolvedUrl(self._handle, context.succeeded, list_item) diff --git a/plugin.video.catchuptvandmore/resources/lib/skeleton.py b/plugin.video.catchuptvandmore/resources/lib/skeleton.py index 7d2f9a2..b6f63cd 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/skeleton.py +++ b/plugin.video.catchuptvandmore/resources/lib/skeleton.py @@ -22,11 +22,24 @@ CATEGORIES = { + 'main_menu.be': 'Belgian channels', + 'main_menu.eu': 'European channels', 'main_menu.fr': 'French channels', - 'main_menu.eu': 'European channels' + 'main_menu.uk': 'United Kingdom channels', + 'main_menu.ws': 'Websites' } CHANNELS = { + + 'main_menu.be': { + 'channels.be.rtbf.auvio': 'RTBF Auvio (La Une, La deux, La Trois, ...)' + }, + + 'main_menu.eu': { + 'channels.eu.arte.arte': 'Arte', + 'channels.eu.euronews.euronews': 'Euronews' + }, + 'main_menu.fr': { 'channels.fr.tf1.tf1': 'TF1', 'channels.fr.pluzz.france2': 'France 2', @@ -70,8 +83,16 @@ CHANNELS = { 'channels.fr.publicsenat.publicsenat': 'Public Sénat' }, - 'main_menu.eu': { - 'channels.eu.arte.arte': 'Arte', - 'channels.eu.euronews.euronews': 'Euronews' + 'main_menu.uk': { + 'channels.uk.blaze.blaze': 'Blaze', + 'channels.uk.uktvplay.dave': 'Dave', + 'channels.uk.uktvplay.really': 'Really', + 'channels.uk.uktvplay.yesterday': 'Yesterday', + 'channels.uk.uktvplay.drama': 'Drama' + }, + + 'main_menu.ws': { + 'channels.ws.allocine.allocine': 'Allociné', + 'channels.ws.tetesaclaques.tetesaclaques': 'Au pays des Têtes à claques' } } diff --git a/plugin.video.catchuptvandmore/resources/lib/utils.py b/plugin.video.catchuptvandmore/resources/lib/utils.py index e9206df..e9206df 100755..100644 --- a/plugin.video.catchuptvandmore/resources/lib/utils.py +++ b/plugin.video.catchuptvandmore/resources/lib/utils.py diff --git a/plugin.video.catchuptvandmore/resources/media/categories/be.png b/plugin.video.catchuptvandmore/resources/media/categories/be.png Binary files differnew file mode 100644 index 0000000..80b8037 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/categories/be.png diff --git a/plugin.video.catchuptvandmore/resources/media/categories/eu.png b/plugin.video.catchuptvandmore/resources/media/categories/eu.png Binary files differindex e534746..e534746 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/categories/eu.png +++ b/plugin.video.catchuptvandmore/resources/media/categories/eu.png diff --git a/plugin.video.catchuptvandmore/resources/media/categories/fr.png b/plugin.video.catchuptvandmore/resources/media/categories/fr.png Binary files differindex cb017dc..cb017dc 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/categories/fr.png +++ b/plugin.video.catchuptvandmore/resources/media/categories/fr.png diff --git a/plugin.video.catchuptvandmore/resources/media/categories/uk.png b/plugin.video.catchuptvandmore/resources/media/categories/uk.png Binary files differnew file mode 100644 index 0000000..548cf45 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/categories/uk.png diff --git a/plugin.video.catchuptvandmore/resources/media/categories/ws.png b/plugin.video.catchuptvandmore/resources/media/categories/ws.png Binary files differnew file mode 100644 index 0000000..608b328 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/categories/ws.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/be/auvio.png b/plugin.video.catchuptvandmore/resources/media/channels/be/auvio.png Binary files differnew file mode 100644 index 0000000..fd50c18 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/be/auvio.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/be/auvio_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/be/auvio_fanart.png Binary files differnew file mode 100644 index 0000000..05c443e --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/be/auvio_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/eu/arte.png b/plugin.video.catchuptvandmore/resources/media/channels/eu/arte.png Binary files differindex 3c003a2..3c003a2 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/eu/arte.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/eu/arte.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/eu/arte_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/eu/arte_fanart.png Binary files differindex dd5491b..dd5491b 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/eu/arte_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/eu/arte_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews.png b/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews.png Binary files differindex 0b40147..0b40147 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews_fanart.png Binary files differindex a05737f..a05737f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/eu/euronews_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/01net.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/01net.png Binary files differindex 10e36e0..10e36e0 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/01net.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/01net.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/01net_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/01net_fanart.png Binary files differindex c793db8..c793db8 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/01net_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/01net_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter.png Binary files differindex 320cf16..320cf16 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter_fanart.png Binary files differindex 0fdefb5..0fdefb5 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/6ter_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness.png Binary files differindex 8286439..8286439 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness_fanart.png Binary files differindex a849cda..a849cda 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmbusiness_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv.png Binary files differindex 3ca5f2a..3ca5f2a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv_fanart.png Binary files differindex 226487f..226487f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bfmtv_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce.png Binary files differindex 4d043f5..4d043f5 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce_fanart.png Binary files differindex fd37443..fd37443 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/bruce_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/c8.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/c8.png Binary files differindex e18d86c..e18d86c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/c8.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/c8.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/c8_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/c8_fanart.png Binary files differindex 05a9a6c..05a9a6c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/c8_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/c8_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25.png Binary files differindex f4f9d60..f4f9d60 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25_fanart.png Binary files differindex 6ecbd9e..6ecbd9e 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cherie25_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews.png Binary files differindex a3f5127..a3f5127 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews_fanart.png Binary files differindex a759d39..a759d39 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cnews_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy.png Binary files differindex 279348c..279348c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy_fanart.png Binary files differindex f2a41c1..f2a41c1 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/comedy_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus.png Binary files differindex 6829f23..6829f23 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus_fanart.png Binary files differindex 2a2e3b4..2a2e3b4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cplus_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen.png Binary files differindex 6d8c2d2..6d8c2d2 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen_fanart.png Binary files differindex 1e03344..1e03344 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/crazy_kitchen_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar.png Binary files differindex 4d3a463..4d3a463 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar_fanart.png Binary files differindex f7c45db..f7c45db 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/cstar_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france2.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france2.png Binary files differindex 6f741cd..6f741cd 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france2.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france2.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france24.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france24.png Binary files differindex 9a9db7c..9a9db7c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france24.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france24.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france24_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france24_fanart.png Binary files differindex dadb2fb..dadb2fb 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france24_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france24_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france2_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france2_fanart.png Binary files differindex 8184c2a..8184c2a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france2_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france2_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france3.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france3.png Binary files differindex 3309012..3309012 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france3.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france3.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france3_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france3_fanart.png Binary files differindex dede4f8..dede4f8 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france3_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france3_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france4.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france4.png Binary files differindex a8a1bba..a8a1bba 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france4.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france4.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france4_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france4_fanart.png Binary files differindex d83de13..d83de13 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france4_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france4_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france5.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france5.png Binary files differindex bc1f6ea..bc1f6ea 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france5.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france5.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/france5_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/france5_fanart.png Binary files differindex 96ce7ae..96ce7ae 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/france5_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/france5_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo.png Binary files differindex bdc12e4..bdc12e4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo_fanart.png Binary files differindex edb1cb8..edb1cb8 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceinfo_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo.png Binary files differindex b2de049..b2de049 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo_fanart.png Binary files differindex e05df4c..e05df4c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/franceo_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli.png Binary files differindex b2e1522..b2e1522 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli_fanart.png Binary files differindex 94739ab..94739ab 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/gulli_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1.png Binary files differindex c33450f..c33450f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1_fanart.png Binary files differindex 665dc6c..665dc6c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/hd1_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/home.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/home.png Binary files differindex 3c3f68f..3c3f68f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/home.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/home.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/home_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/home_fanart.png Binary files differindex 1c22df9..1c22df9 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/home_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/home_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere.png Binary files differindex 29de8d2..29de8d2 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere_fanart.png Binary files differindex 1dcc660..1dcc660 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/la_1ere_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lci.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lci.png Binary files differindex c979af1..c979af1 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lci.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lci.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lci_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lci_fanart.png Binary files differindex 565bdee..565bdee 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lci_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lci_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp.png Binary files differindex d33817d..d33817d 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp_fanart.png Binary files differindex d697fdf..d697fdf 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lcp_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe.png Binary files differindex 90b5b46..90b5b46 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe_fanart.png Binary files differindex bfc2dbe..bfc2dbe 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/lequipe_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/m6.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/m6.png Binary files differindex 24852b7..24852b7 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/m6.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/m6.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/m6_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/m6_fanart.png Binary files differindex f5e8e8e..f5e8e8e 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/m6_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/m6_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12.png Binary files differindex 0c4c9f4..0c4c9f4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12_fanart.png Binary files differindex 848d9c6..848d9c6 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/nrj12_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1.png Binary files differindex 59c8e33..59c8e33 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1_fanart.png Binary files differindex bc00729..bc00729 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/nt1_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23.png Binary files differindex cd302c4..cd302c4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23_fanart.png Binary files differindex 35045dd..35045dd 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/numero23_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere.png Binary files differindex 83ad901..83ad901 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere_fanart.png Binary files differindex 823bd90..823bd90 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/parispremiere_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat.png Binary files differindex 8a756d9..8a756d9 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat_fanart.png Binary files differindex 38fc4bb..38fc4bb 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/publicsenat_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc.png Binary files differindex 21bbe7e..21bbe7e 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc_fanart.png Binary files differindex d471802..d471802 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmc_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmcdecouverte.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmcdecouverte.png Binary files differindex 5908627..5908627 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/rmcdecouverte.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/rmcdecouverte.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/stories.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/stories.png Binary files differindex 716f06a..716f06a 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/stories.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/stories.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/stories_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/stories_fanart.png Binary files differindex 4083644..4083644 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/stories_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/stories_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/styles.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/styles.png Binary files differindex 84bb4b5..84bb4b5 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/styles.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/styles.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/styles_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/styles_fanart.png Binary files differindex 120a167..120a167 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/styles_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/styles_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/teva.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/teva.png Binary files differindex e376edf..e376edf 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/teva.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/teva.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/teva_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/teva_fanart.png Binary files differindex b45bff7..b45bff7 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/teva_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/teva_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1.png Binary files differindex 18b7490..18b7490 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1_fanart.png Binary files differindex e23d730..e23d730 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tf1_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou.png Binary files differindex 1b69f8d..1b69f8d 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou_fanart.png Binary files differindex f47d92d..f47d92d 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tfou_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc.png Binary files differindex 2ad9872..2ad9872 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc_fanart.png Binary files differindex de8fef7..de8fef7 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/tmc_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/w9.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/w9.png Binary files differindex a0c27c4..a0c27c4 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/w9.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/w9.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/w9_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/w9_fanart.png Binary files differindex 0fe0102..0fe0102 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/w9_fanart.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/w9_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/fr/xtra.png b/plugin.video.catchuptvandmore/resources/media/channels/fr/xtra.png Binary files differindex dc311d1..dc311d1 100755..100644 --- a/plugin.video.catchuptvandmore/resources/media/channels/fr/xtra.png +++ b/plugin.video.catchuptvandmore/resources/media/channels/fr/xtra.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/blaze.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/blaze.png Binary files differnew file mode 100644 index 0000000..53f0a08 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/blaze.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/dave.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/dave.png Binary files differnew file mode 100644 index 0000000..6a150e4 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/dave.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/drama.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/drama.png Binary files differnew file mode 100644 index 0000000..d29241c --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/drama.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/drama_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/drama_fanart.png Binary files differnew file mode 100644 index 0000000..f42b2eb --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/drama_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/really.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/really.png Binary files differnew file mode 100644 index 0000000..92905e0 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/really.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/uk/yesterday.png b/plugin.video.catchuptvandmore/resources/media/channels/uk/yesterday.png Binary files differnew file mode 100644 index 0000000..941535d --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/uk/yesterday.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine.png b/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine.png Binary files differnew file mode 100644 index 0000000..77aa0dc --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine_fanart.png Binary files differnew file mode 100644 index 0000000..222fec4 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/ws/allocine_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques.png b/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques.png Binary files differnew file mode 100644 index 0000000..0fdfa19 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques.png diff --git a/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques_fanart.png b/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques_fanart.png Binary files differnew file mode 100644 index 0000000..f255005 --- /dev/null +++ b/plugin.video.catchuptvandmore/resources/media/channels/ws/tetesaclaques_fanart.png diff --git a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-01.jpg b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-01.jpg Binary files differindex 11c6c33..11c6c33 100755..100644 --- a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-01.jpg +++ b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-01.jpg diff --git a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-02.jpg b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-02.jpg Binary files differindex da9e325..da9e325 100755..100644 --- a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-02.jpg +++ b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-02.jpg diff --git a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-03.jpg b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-03.jpg Binary files differindex a5c6b9c..a5c6b9c 100755..100644 --- a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-03.jpg +++ b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-03.jpg diff --git a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-04.jpg b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-04.jpg Binary files differindex 05ee326..05ee326 100755..100644 --- a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-04.jpg +++ b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-04.jpg diff --git a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-05.jpg b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-05.jpg Binary files differindex f7d309f..f7d309f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/screenshots/screenshot-05.jpg +++ b/plugin.video.catchuptvandmore/resources/screenshots/screenshot-05.jpg diff --git a/plugin.video.catchuptvandmore/resources/settings.xml b/plugin.video.catchuptvandmore/resources/settings.xml index 5037cbb..0cd040f 100755..100644 --- a/plugin.video.catchuptvandmore/resources/settings.xml +++ b/plugin.video.catchuptvandmore/resources/settings.xml @@ -6,7 +6,10 @@ <!-- Hide main menu categories --> <setting label="30010" type="lsep"/> <setting label="30020" type="bool" id="main_menu.fr" default="true"/> + <setting label="30021" type="bool" id="main_menu.be" default="true"/> <setting label="30023" type="bool" id="main_menu.eu" default="true"/> + <setting label="30024" type="bool" id="main_menu.uk" default="true"/> + <setting label="30026" type="bool" id="main_menu.ws" default="true"/> </category> @@ -144,6 +147,12 @@ <setting label="Paris Première" type="bool" id="channels.fr.6play.parispremiere" default="true" visible="eq(-83,true)"/> <setting label="" type="number" visible="false" id="channels.fr.6play.parispremiere.order" default="42"/>--> + <setting label="30021" type="lsep" subsetting="true" visible="eq(1,true)"/> + <setting label="30021" type="bool" id="main_menu.be" default="true" visible="false"/> + + <setting label="RTBF Auvio (La Une, La deux, La Trois, ...)" type="bool" id="channels.be.rtbf.auvio" default="true" visible="eq(-1,true)"/> + <setting label="" type="number" visible="false" id="channels.be.rtbf.auvio.order" default="1"/> + <setting label="30023" type="lsep" subsetting="true" visible="eq(1,true)"/> <setting label="30023" type="bool" id="main_menu.eu" default="true" visible="false"/> @@ -153,8 +162,34 @@ <setting label="Arte" type="bool" id="channels.eu.arte.arte" default="true" visible="eq(-3,true)"/> <setting label="" type="number" visible="false" id="channels.eu.arte.arte.order" default="2"/> - </category> + <setting label="30024" type="lsep" subsetting="true" visible="eq(1,true)"/> + <setting label="30024" type="bool" id="main_menu.uk" default="true" visible="false"/> + + <setting label="Blaze" type="bool" id="channels.uk.blaze.blaze" default="true" visible="eq(-1,true)"/> + <setting label="" type="number" visible="false" id="channels.uk.blaze.blaze.order" default="1"/> + + <setting label="Dave" type="bool" id="channels.uk.uktvplay.dave" default="true" visible="eq(-3,true)"/> + <setting label="" type="number" visible="false" id="channels.uk.uktvplay.dave.order" default="2"/> + + <setting label="Really" type="bool" id="channels.uk.uktvplay.really" default="true" visible="eq(-5,true)"/> + <setting label="" type="number" visible="false" id="channels.uk.uktvplay.really.order" default="3"/> + + <setting label="Yesterday" type="bool" id="channels.uk.uktvplay.yesterday" default="true" visible="eq(-7,true)"/> + <setting label="" type="number" visible="false" id="channels.uk.uktvplay.yesterday.order" default="4"/> + + <setting label="Drama" type="bool" id="channels.uk.uktvplay.drama" default="true" visible="eq(-9,true)"/> + <setting label="" type="number" visible="false" id="channels.uk.uktvplay.drama.order" default="5"/> + + <setting label="30026" type="lsep" subsetting="true" visible="eq(1,true)"/> + <setting label="30026" type="bool" id="main_menu.ws" default="true" visible="false"/> + <setting label="Allociné" type="bool" id="channels.ws.allocine.allocine" default="true" visible="eq(-1,true)"/> + <setting label="" type="number" visible="false" id="channels.ws.allocine.allocine.order" default="1"/> + + <setting label="Au pays des Têtes à claques" type="bool" id="channels.ws.tetesaclaques.tetesaclaques" default="true" visible="eq(-3,true)"/> + <setting label="" type="number" visible="false" id="channels.ws.tetesaclaques.tetesaclaques.order" default="2"/> + + </category> <!-- Quality and Content (and also hidden settings) --> <category label="30002"> @@ -163,10 +198,11 @@ <setting label="30087" type="labelenum" id="quality" values="BEST|DEFAULT|DIALOG"/> <setting label="30071" type="lsep" /> + <setting label="30020" type="lsep" subsetting="true" visible="eq(1,true)"/> <setting label="30020" type="bool" id="main_menu.fr" default="true" visible="false"/> - <setting label="30081" type="labelenum" id="channels.fr.france24.france24.language" visible="eq(-1,true)" values="FR|EN|AR"/> + <setting label="30081" type="labelenum" id="channels.fr.france24.france24.language" visible="eq(-1,true)" values="FR|EN|AR|ES"/> <setting label="30023" type="lsep" subsetting="true" visible="eq(1,true)"/> <setting label="30023" type="bool" id="main_menu.eu" default="true" visible="false"/> @@ -177,14 +213,12 @@ <setting label="" type="bool" id="show_hidden_items_information" default="true" visible="false"/> </category> - <!-- Download ... --> <category label="30003"> <setting label="30012" type="lsep"/> <setting label="30200" type="folder" id="dlFolder" source="auto" option="writeable"/> </category> - <!-- Account ... --> <category label="30004"> @@ -193,6 +227,13 @@ <setting label="NRJ Login" type="text" id="channels.fr.nrj.login" visible="eq(-1,true)" defaut=""/> <setting label="NRJ Password" type="text" id="channels.fr.nrj.password" option="hidden" visible="eq(-2,true)" defaut=""/> + + <setting label="30024" type="lsep" subsetting="true" visible="eq(1,true)"/> + <setting label="30024" type="bool" id="main_menu.uk" default="true" visible="false"/> + + <setting label="UKTVPlay Login" type="text" id="channels.uk.uktvplay.login" visible="eq(-1,true)" defaut=""/> + <setting label="UKTVPlay Password" type="text" id="channels.uk.uktvplay.password" option="hidden" visible="eq(-2,true)" defaut=""/> + </category> </settings> |