summaryrefslogtreecommitdiff
path: root/plugin.video.catchuptvandmore/resources/lib/channels/fr
diff options
context:
space:
mode:
authorSylvain CECCHETTO <cecchetto.sylvain@me.com>2017-03-22 03:24:43 +0100
committerenen92 <enen92@users.noreply.github.com>2017-03-22 02:24:43 +0000
commitaefa7d3d72e3a461ec6db79fe305023395118cf1 (patch)
treed18fbbd269e5372590c3bed3414240adeb48c155 /plugin.video.catchuptvandmore/resources/lib/channels/fr
parent4802b7e3b5cea3b306712e756226ce37b3e743e9 (diff)
[plugin.video.catchuptvandmore] 0.1.0 (#989)
Diffstat (limited to 'plugin.video.catchuptvandmore/resources/lib/channels/fr')
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py381
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py0
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/arte.py260
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py224
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/c.py210
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/canalplus.py318
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py203
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/itele.py192
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py282
-rwxr-xr-xplugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py238
10 files changed, 2308 insertions, 0 deletions
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py
new file mode 100755
index 0000000..d60ebd0
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/6play.py
@@ -0,0 +1,381 @@
+# -*- coding: utf-8 -*-
+"""
+ Catch-up TV & More
+ Original work (C) JUL1EN094, SPM, SylvainCecchetto
+ Copyright (C) 2016 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
+from resources.lib import utils
+from resources.lib import common
+
+
+# Url to get channel's categories
+# e.g. Info, Divertissement, Séries, ...
+# We get an id by category
+url_root = 'http://pc.middleware.6play.fr/6play/v2/platforms/' \
+ 'm6group_web/services/%sreplay/folders?limit=999&offset=0'
+
+# Url to get catgory's programs
+# e.g. Le meilleur patissier, La france à un incroyable talent, ...
+# 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'
+
+# Url to get program's subfolders
+# e.g. Saison 5, Les meilleurs moments, les recettes pas à pas, ...
+# We get an id by subfolder
+url_subcategory = 'http://pc.middleware.6play.fr/6play/v2/platforms/' \
+ 'm6group_web/services/6play/programs/%s' \
+ '?with=links,subcats,rights'
+
+
+# Url to get shows list
+# e.g. Episode 1, Episode 2, ...
+url_videos = 'http://pc.middleware.6play.fr/6play/v2/platforms/' \
+ 'm6group_web/services/6play/programs/%s/videos?' \
+ 'csa=6&with=clips,freemiumpacks&type=vi,vc,playlist&limit=999'\
+ '&offset=0&subcat=%s&sort=subcat'
+
+url_videos2 = 'https://pc.middleware.6play.fr/6play/v2/platforms/' \
+ 'm6group_web/services/6play/programs/%s/videos?' \
+ 'csa=6&with=clips,freemiumpacks&type=vi&limit=999&offset=0'
+
+
+url_json_video = 'https://pc.middleware.6play.fr/6play/v2/platforms/' \
+ 'm6group_web/services/6play/videos/%s'\
+ '?csa=9&with=clips,freemiumpacks'
+
+
+url_img = 'https://images.6play.fr/v1/images/%s/raw'
+
+
+def channel_entry(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)
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ shows = []
+
+ if params.next == 'list_shows_1':
+ file_path = utils.download_catalog(
+ url_root % (params.channel_name),
+ '%s.json' % (params.channel_name),
+ random_ua=True)
+ file_prgm = open(file_path).read()
+ json_parser = json.loads(file_prgm)
+
+ # do not cache failed catalog fetch
+ # the error format is:
+ # {"error":{"code":403,"message":"Forbidden"}}
+ if isinstance(json_parser, dict) and \
+ 'error' in json_parser.keys():
+ utils.os.remove(file_path)
+ raise Exception('Failed to fetch the 6play catalog')
+
+ for array in json_parser:
+ category_id = str(array['id'])
+ category_name = array['name'].encode('utf-8')
+ shows.append({
+ 'label': category_name,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_id=category_id,
+ next='list_shows_2',
+ title=category_name
+ )
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_2':
+ file_prgm = utils.get_webcontent(
+ url_category % (params.category_id),
+ random_ua=True)
+ json_parser = json.loads(file_prgm)
+
+ for array in json_parser:
+ program_title = array['title'].encode('utf-8')
+ program_id = str(array['id'])
+ program_desc = array['description'].encode('utf-8')
+ program_imgs = array['images']
+ program_img = ''
+ for img in program_imgs:
+ if img['role'].encode('utf-8') == 'vignette':
+ external_key = img['external_key'].encode('utf-8')
+ program_img = url_img % (external_key)
+ elif img['role'].encode('utf-8') == 'carousel':
+ external_key = img['external_key'].encode('utf-8')
+ program_fanart = url_img % (external_key)
+
+ info = {
+ 'video': {
+ 'title': program_title,
+ 'plot': program_desc
+ }
+ }
+ shows.append({
+ 'label': program_title,
+ 'thumb': program_img,
+ 'fanart': program_fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_shows_3',
+ program_id=program_id,
+ program_img=program_img,
+ program_fanart=program_fanart,
+ program_desc=program_desc,
+ title=program_title
+ ),
+ 'info': info
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_3':
+ program_json = utils.get_webcontent(
+ url_subcategory % (params.program_id),
+ random_ua=True)
+
+ json_parser = json.loads(program_json)
+ for sub_category in json_parser['program_subcats']:
+ sub_category_id = str(sub_category['id'])
+ sub_category_title = sub_category['title'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': sub_category_title,
+ 'plot': params.program_desc
+ }
+ }
+
+ shows.append({
+ 'label': sub_category_title,
+ 'thumb': params.program_img,
+ 'fanart': params.program_fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos',
+ program_id=params.program_id,
+ sub_category_id=sub_category_id
+ ),
+ 'info': info
+ })
+
+ info = {
+ 'video': {
+ 'title': common.addon.get_localized_string(30101),
+ 'plot': params.program_desc
+ }
+ }
+ shows.append({
+ 'label': common.addon.get_localized_string(30101),
+ 'thumb': params.program_img,
+ 'fanart': params.program_fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos',
+ program_id=params.program_id,
+ sub_category_id='null'
+
+ ),
+ 'info': info
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ return shows
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+
+ if params.sub_category_id == 'null':
+ url = url_videos2 % params.program_id
+ else:
+ url = url_videos % (params.program_id, params.sub_category_id)
+ program_json = utils.get_webcontent(
+ url,
+ random_ua=True)
+ json_parser = json.loads(program_json)
+
+ for video in json_parser:
+ video_id = str(video['id'])
+
+ title = video['title'].encode('utf-8')
+ duration = video['clips'][0]['duration']
+ description = video['description'].encode('utf-8')
+ try:
+ aired = video['clips'][0]['product']['last_diffusion']
+ aired = aired.encode('utf-8')
+ aired = aired[:10]
+ year = aired[:4]
+ # date : string (%d.%m.%Y / 01.01.2009)
+ # aired : string (2008-12-07)
+ day = aired.split('-')[2]
+ mounth = aired.split('-')[1]
+ year = aired.split('-')[0]
+ date = '.'.join((day, mounth, year))
+
+ except:
+ aired = ''
+ year = ''
+ date = ''
+ img = ''
+
+ program_imgs = video['clips'][0]['images']
+ program_img = ''
+ for img in program_imgs:
+ if img['role'].encode('utf-8') == 'vignette':
+ external_key = img['external_key'].encode('utf-8')
+ program_img = url_img % (external_key)
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': description,
+ 'aired': aired,
+ 'date': date,
+ 'duration': duration,
+ 'year': year,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': program_img,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ video_id=video_id,
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ common.sp.xbmcplugin.SORT_METHOD_DURATION,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ ),
+ content='tvshows')
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ video_json = utils.get_webcontent(
+ url_json_video % (params.video_id),
+ random_ua=True)
+ json_parser = json.loads(video_json)
+
+ video_assets = json_parser['clips'][0]['assets']
+ url = ''
+ url2 = ''
+ url3 = ''
+ for asset in video_assets:
+ if 'ism' in asset['video_container'].encode('utf-8'):
+ url = asset['full_physical_path'].encode('utf-8')
+ if 'mp4' in asset['video_container'].encode('utf-8'):
+ if 'hd' in asset['video_quality'].encode('utf-8'):
+ url2 = asset['full_physical_path'].encode('utf-8')
+ else:
+ url3 = asset['full_physical_path'].encode('utf-8')
+ manifest_url = ''
+ if url:
+ manifest_url = url
+ elif url2:
+ 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]
+
+ if desired_quality == 'Force HD':
+ if url_ultra_hd:
+ return url_ultra_hd
+ elif url_hd:
+ return url_hd
+ return manifest_url
+
+ elif desired_quality == 'Force SD':
+ if url_ultra_sd:
+ return url_ultra_sd
+ elif url_sd:
+ return url_sd
+ 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
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/__init__.py
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/arte.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/arte.py
new file mode 100755
index 0000000..f2b7a2b
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/arte.py
@@ -0,0 +1,260 @@
+# -*- coding: utf-8 -*-
+"""
+ Catch-up TV & More
+ Copyright (C) 2016 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
+from resources.lib import utils
+from resources.lib import common
+
+authorization_key = 'Bearer OTE3NjJhOTYwNzQzNWY0MGE0OGI5MGQ0YmVm' \
+ 'MWY2Y2JiYzc5NDQzY2IxMmYxYjQ0NDVlYmEyOTBmYjVkMDg3OQ'
+
+headers = {'Authorization': authorization_key}
+
+url_categories = 'https://api-cdn.arte.tv/api/opa/v2/categories?' \
+ 'language=%s&limit=100&sort=order'
+# Valid languages list : fr|de|en|es|pl
+
+
+def channel_entry(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)
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ shows = []
+
+ disered_language = common.plugin.get_setting(
+ params.channel_id + '.language')
+
+ if disered_language == 'Auto':
+ disered_language = params.channel_country
+
+ file_path = utils.download_catalog(
+ url_categories % disered_language,
+ '%s.json' % params.channel_name,
+ specific_headers=headers)
+ file_categories = open(file_path).read()
+ json_parser = json.loads(file_categories)
+
+ for category in json_parser['categories']:
+ label = category['label'].encode('utf-8')
+ desc = category['description'].encode('utf-8')
+ href = category['links']['videos']['href'].encode('utf-8')
+ code = category['code'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': label,
+ 'plot': desc
+ }
+ }
+
+ shows.append({
+ 'label': label,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ code=code,
+ href=href,
+ next='list_videos',
+ title=label
+ ),
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+
+ params_url = {
+ 'geoblockingZone': 'EUR_DE_FR,ALL,SAT,DE_FR',
+ 'imageSize': '1920x1080,625x224,940x530,720x406,400x225',
+ 'kind': 'SHOW',
+ 'limit': '100',
+ 'platform': 'ARTEPLUS7',
+ 'sort': '-broadcastBegin',
+ 'videoLibrary': 'true'
+ }
+ file_path = utils.download_catalog(
+ params.href,
+ '%s.json' % (params.channel_name + params.code),
+ specific_headers=headers,
+ params=params_url)
+ file_shows = open(file_path).read()
+ json_parser = json.loads(file_shows)
+
+ for video in json_parser['videos']:
+ title = video['title'].encode('utf-8')
+ subtitle = ''
+ if video['subtitle'] is not None:
+ subtitle = video['subtitle'].encode('utf-8')
+
+ original_title = video['originalTitle'].encode('utf-8')
+ plotoutline = ''
+ if video['shortDescription'] is not None:
+ plotoutline = video['shortDescription'].encode('utf-8')
+ plot = ''
+ if video['fullDescription'] is not None:
+ plot = video['fullDescription'].encode('utf-8')
+ duration = video['durationSeconds']
+ year_prod = video['productionYear']
+ genre = video['genrePresse'].encode('utf-8')
+ season = video['season']
+ episode = video['episode']
+ total_episodes = video['totalEpisodes']
+ href = video['links']['videoStreams']['href'].encode('utf-8')
+ views = video['views']
+ director = video['director']
+ aired = video['arteSchedulingDay'] # year-mounth-day
+ day = aired.split('-')[2]
+ mounth = aired.split('-')[1]
+ year = aired.split('-')[0]
+ date = '.'.join((day, mounth, year))
+ fanart = video['mainImage']['url'].encode('utf-8')
+ thumb = video['mainImage']['alternateResolutions'][1]['url'].encode('utf-8')
+
+ if subtitle:
+ title = title + ' - [I]' + subtitle + '[/I]'
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'originaltitle': original_title,
+ 'plot': plot,
+ 'plotoutline': plotoutline,
+ 'aired': aired,
+ 'date': date,
+ 'duration': duration,
+ 'year': year_prod,
+ 'genre': genre,
+ 'season': season,
+ 'episode': episode,
+ 'playcount': views,
+ 'director': director,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'fanart': fanart,
+ 'thumb': thumb,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ href=href,
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ 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_PLAYCOUNT,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ ),
+ content='tvshows')
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ file_medias = utils.get_webcontent(
+ params.href,
+ specific_headers=headers)
+ json_parser = json.loads(file_medias)
+
+ url_auto = ''
+ url_hd_plus = ''
+ url_hd = ''
+ url_sd = ''
+ url_sd_minus = ''
+ for video_stream in json_parser['videoStreams']:
+ if video_stream['audioSlot'] == 1:
+ if video_stream['quality'] == 'AQ' or \
+ video_stream['quality'] == 'XQ':
+ url_auto = video_stream['url'].encode('utf-8')
+
+ elif video_stream['quality'] == 'SQ' and \
+ video_stream['mediaType'] == 'mp4' and \
+ video_stream['protocol'] == 'HTTP':
+ url_hd_plus = video_stream['url'].encode('utf-8')
+
+ elif video_stream['quality'] == 'EQ' and \
+ video_stream['mediaType'] == 'mp4' and \
+ video_stream['protocol'] == 'HTTP':
+ url_hd = video_stream['url'].encode('utf-8')
+
+ elif video_stream['quality'] == 'HQ' and \
+ video_stream['mediaType'] == 'mp4' and \
+ video_stream['protocol'] == 'HTTP':
+ url_sd = video_stream['url'].encode('utf-8')
+
+ elif video_stream['quality'] == 'MQ' and \
+ video_stream['mediaType'] == 'mp4' and \
+ video_stream['protocol'] == 'HTTP':
+ url_sd_minus = video_stream['url'].encode('utf-8')
+
+ desired_quality = common.plugin.get_setting(
+ params.channel_id + '.quality')
+
+ if desired_quality == 'Auto' and url_auto:
+ return url_auto
+
+ if desired_quality == 'HD+' and url_hd_plus:
+ return url_hd_plus
+ elif url_hd:
+ return url_hd
+
+ if desired_quality == 'HD' and url_hd:
+ return url_hd
+ elif url_hd_plus:
+ return url_hd_plus
+
+ if desired_quality == 'SD' and url_sd:
+ return url_sd
+ elif url_sd_minus:
+ return url_sd_minus
+
+ if desired_quality == 'SD-' and url_sd_minus:
+ return url_sd_minus
+ elif url_sd:
+ return url_sd
+
+ return url_auto
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py
new file mode 100755
index 0000000..f88615b
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/bfmtv.py
@@ -0,0 +1,224 @@
+# -*- 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
+from resources.lib import utils
+from resources.lib import common
+
+url_token = 'http://api.nextradiotv.com/bfmtv-applications/'
+
+url_menu = 'http://www.bfmtv.com/static/static-mobile/bfmtv/' \
+ 'ios-smartphone/v0/configuration.json'
+
+url_replay = 'http://api.nextradiotv.com/bfmtv-applications/%s/' \
+ 'getPage?pagename=replay'
+# token
+
+url_show = 'http://api.nextradiotv.com/bfmtv-applications/%s/' \
+ 'getVideosList?category=%s&count=100&page=%s'
+# token, category, page_number
+
+url_video = 'http://api.nextradiotv.com/bfmtv-applications/%s/' \
+ 'getVideo?idVideo=%s'
+# token, video_id
+
+
+@common.plugin.cached(common.cache_time)
+def get_token():
+ file_token = utils.get_webcontent(url_token)
+ token_json = json.loads(file_token)
+ return token_json['session']['token'].encode('utf-8')
+
+
+def channel_entry(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)
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ # Create categories list
+ shows = []
+
+ if params.next == 'list_shows_1':
+ file_path = utils.download_catalog(
+ url_replay % get_token(),
+ '%s.json' % (params.channel_name))
+ file_categories = open(file_path).read()
+ json_categories = json.loads(file_categories)
+ json_categories = json_categories['page']['contents'][0]
+ json_categories = json_categories['elements'][0]['items']
+
+ for categories in json_categories:
+ title = categories['title'].encode('utf-8')
+ image_url = categories['image_url'].encode('utf-8')
+ category = categories['categories'].encode('utf-8')
+
+ shows.append({
+ 'label': title,
+ 'thumb': image_url,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category=category,
+ next='list_videos_1',
+ title=title,
+ page='1'
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+ if params.next == 'list_videos_1':
+ file_path = utils.download_catalog(
+ url_show % (
+ get_token(),
+ params.category,
+ params.page),
+ '%s_%s_%s.json' % (
+ params.channel_name,
+ params.category,
+ params.page))
+ file_show = open(file_path).read()
+ json_show = json.loads(file_show)
+
+ for video in json_show['videos']:
+ video_id = video['video'].encode('utf-8')
+ video_id_ext = video['id_ext'].encode('utf-8')
+ category = video['category'].encode('utf-8')
+ title = video['title'].encode('utf-8')
+ description = video['description'].encode('utf-8')
+ begin_date = video['begin_date'] # 1486725600,
+ image = video['image'].encode('utf-8')
+ duration = video['video_duration_ms'] / 1000
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': description,
+ #'aired': aired,
+ #'date': date,
+ 'duration': duration,
+ #'year': year,
+ 'genre': category,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': image,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ video_id=video_id,
+ video_id_ext=video_id_ext
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ # More videos...
+ videos.append({
+ 'label': common.addon.get_localized_string(30100),
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category=params.category,
+ next='list_videos_1',
+ title=title,
+ page=str(int(params.page) + 1)
+ )
+
+ })
+
+ 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.cached(common.cache_time)
+def get_video_URL(params):
+ file_medias = utils.get_webcontent(
+ url_video % (get_token(), params.video_id))
+ json_parser = json.loads(file_medias)
+
+ url_hd_plus = ''
+ url_hd = ''
+ url_sd = ''
+ url_sd_minus = ''
+ url_default = ''
+
+ for media in json_parser['video']['medias']:
+ if media['frame_height'] == 270:
+ url_sd_minus = media['video_url'].encode('utf-8')
+ elif media['frame_height'] == 360:
+ url_sd = media['video_url'].encode('utf-8')
+ elif media['frame_height'] == 720:
+ url_hd = media['video_url'].encode('utf-8')
+ elif media['frame_height'] == 1080:
+ url_hd_plus = media['video_url'].encode('utf-8')
+ url_default = media['video_url'].encode('utf-8')
+
+ desired_quality = common.plugin.get_setting(
+ params.channel_id + '.quality')
+
+ if desired_quality == 'HD+' and url_hd_plus:
+ return url_hd_plus
+ elif url_hd:
+ return url_hd
+
+ if desired_quality == 'HD' and url_hd:
+ return url_hd
+ elif url_hd_plus:
+ return url_hd_plus
+
+ if desired_quality == 'SD' and url_sd:
+ return url_sd
+ elif url_sd_minus:
+ return url_sd_minus
+
+ if desired_quality == 'SD-' and url_sd_minus:
+ return url_sd_minus
+ elif url_sd:
+ return url_sd
+
+ return url_default
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/c.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/c.py
new file mode 100755
index 0000000..84d3b2d
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/c.py
@@ -0,0 +1,210 @@
+# -*- 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
+from resources.lib import utils
+from resources.lib import common
+
+
+url_root = 'http://lab.canal-plus.pro/web/app_prod.php/api/replay/%s'
+# Channel id :
+# c8 : 1
+# cstar : 2
+
+url_shows = 'http://lab.canal-plus.pro/web/app_prod.php/api/pfv/list/%s/%s'
+# channel_id/show_id
+
+url_video = 'http://lab.canal-plus.pro/web/app_prod.php/api/pfv/video/%s/%s'
+# channel_id/video_id
+
+
+def get_channel_id(params):
+ if params.channel_name == 'c8':
+ return '1'
+ elif params.channel_name == 'cstar':
+ return '2'
+ else:
+ return '1'
+
+
+def channel_entry(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)
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ # Create categories list
+ shows = []
+
+ if params.next == 'list_shows_1':
+ file_path = utils.download_catalog(
+ url_root % get_channel_id(params),
+ '%s.json' % (params.channel_name))
+ file_categories = open(file_path).read()
+ json_categories = json.loads(file_categories)
+
+ for categories in json_categories:
+ title = categories['title'].encode('utf-8')
+ slug = categories['slug'].encode('utf-8')
+
+ shows.append({
+ 'label': title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ slug=slug,
+ next='list_shows_2',
+ title=title
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_2':
+ # Create category's programs list
+ file_path = utils.download_catalog(
+ url_root % get_channel_id(params),
+ '%s_%s.json' % (params.channel_name, params.slug))
+ file_categories = open(file_path).read()
+ json_categories = json.loads(file_categories)
+
+ for categories in json_categories:
+ if categories['slug'].encode('utf-8') == params.slug:
+ for programs in categories['programs']:
+ id = str(programs['id'])
+ title = programs['title'].encode('utf-8')
+ slug = programs['slug'].encode('utf-8')
+ videos_recent = str(programs['videos_recent'])
+
+ shows.append({
+ 'label': title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos',
+ id=id,
+ videos_recent=videos_recent,
+ slug=slug,
+ title=title
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+ file_path = utils.download_catalog(
+ url_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)
+
+ for video in videos_json:
+ id = video['ID'].encode('utf-8')
+ try:
+ duration = int(video['DURATION'].encode('utf-8'))
+ except:
+ 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 = "00/00/0000"
+ day = date_video.split('/')[0]
+ mounth = date_video.split('/')[1]
+ year = date_video.split('/')[2]
+ aired = '-'.join((day, mounth, year))
+ date = date_video.replace('/', '.')
+ title = video['INFOS']['TITRAGE']['TITRE'].encode('utf-8')
+ subtitle = video['INFOS']['TITRAGE']['SOUS_TITRE'].encode('utf-8')
+ thumb = video['MEDIA']['IMAGES']['GRAND'].encode('utf-8')
+ category = video['RUBRIQUAGE']['CATEGORIE'].encode('utf-8')
+
+ if subtitle:
+ title = title + ' - [I]' + subtitle + '[/I]'
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': description,
+ 'aired': aired,
+ 'date': date,
+ 'duration': duration,
+ 'year': year,
+ 'genre': category,
+ 'playcount': views,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': thumb,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ id=id,
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ 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_PLAYCOUNT,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ ),
+ content='tvshows')
+
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ file_video = utils.get_webcontent(
+ url_video % (get_channel_id(params), params.id)
+ )
+ video_json = json.loads(file_video)
+ return video_json['main']['MEDIA']['VIDEOS']['HLS'].encode('utf-8')
+
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/canalplus.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/canalplus.py
new file mode 100755
index 0000000..12240ef
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/canalplus.py
@@ -0,0 +1,318 @@
+# -*- coding: utf-8 -*-
+"""
+ Catch-up TV & More
+ Original work (C) JUL1EN094, SPM, SylvainCecchetto
+ Copyright (C) 2016 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
+from resources.lib import utils
+from resources.lib import common
+
+
+url_auth = 'http://service.mycanal.fr/authenticate.json/iphone/' \
+ '1.6?highResolution=1&isActivated=0&isAuthenticated=0&paired=0'
+
+url_categories = 'http://service.mycanal.fr/page/%s/4578.json?' \
+ 'cache=60000&nbContent=96'
+
+
+def channel_entry(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)
+
+
+def get_token():
+ token_json = utils.get_webcontent(url_auth)
+ token_json = json.loads(token_json)
+ token = token_json['token']
+ return token
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ # Create categories list
+ shows = []
+
+ if params.next == 'list_shows_1':
+ file_path = utils.download_catalog(
+ url_categories % get_token(),
+ '%s.json' % (params.channel_name))
+ file_categories = open(file_path).read()
+ json_categories = json.loads(file_categories)
+
+ for strate in json_categories['strates']:
+ if strate['type'] == 'textList':
+ for content in strate['contents']:
+ title = content['title'].encode('utf-8')
+ url_page = content['onClick']['URLPage'].encode('utf-8')
+
+ shows.append({
+ 'label': title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ url_page=url_page,
+ next='list_shows_2',
+ title=title
+ )
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_2':
+ # Create category's programs list
+ file_path = utils.download_catalog(
+ params.url_page,
+ '%s.json' % (params.title))
+ file_shows = open(file_path).read()
+ shows_json = json.loads(file_shows)
+
+ for strate in shows_json['strates']:
+ if strate['type'] == 'contentGrid':
+ for content in strate['contents']:
+ title = content['title'].encode('utf-8')
+ try:
+ subtitle = content['subtitle'].encode('utf-8')
+ except:
+ subtitle = ''
+ img = content['URLImage'].encode('utf-8')
+ url_page = content['onClick']['URLPage'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': subtitle,
+ }
+ }
+ shows.append({
+ 'label': title,
+ 'thumb': img,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_shows_3',
+ url_page=url_page,
+ title=title
+ ),
+ 'info': info
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_3':
+ # Check if there is any folder for this program
+ file_path = utils.download_catalog(
+ params.url_page,
+ '%s.json' % (params.title))
+ file_shows = open(file_path).read()
+ shows_json = json.loads(file_shows)
+
+ if 'strates' not in shows_json or len(shows_json['strates']) <= 2:
+ params.next = 'list_videos'
+ params.title = 'none'
+ params.index_page = 1
+ return list_videos(params)
+ else:
+ fanart = ''
+ for strate in shows_json['strates']:
+ if strate['type'] == 'carrousel':
+ for content in strate['contents']:
+ fanart = content['URLImage'].encode('utf-8')
+ elif strate['type'] == 'contentRow':
+ title = strate['title'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': title,
+ }
+ }
+
+ shows.append({
+ 'label': title,
+ 'fanart': fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos',
+ url_page=params.url_page,
+ title=title,
+ index_page=1
+ ),
+ 'info': info
+ })
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ return shows
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+ file_path = utils.download_catalog(
+ params.url_page,
+ '%s.json' % (params.url_page))
+ file_videos = open(file_path).read()
+ videos_json = json.loads(file_videos)
+
+ more_videos = False
+ no_strates = False
+ fanart = ''
+
+ if 'strates' not in videos_json:
+ no_strates = True
+ else:
+ for strate in videos_json['strates']:
+ if strate['type'] == 'carrousel':
+ for content in strate['contents']:
+ fanart = content['URLImage'].encode('utf-8')
+ if strate['type'] == 'contentRow' or strate['type'] == 'contentGrid':
+ if strate['title'].encode('utf-8') == params.title or params.title == 'none':
+ if 'URLPage' in strate['paging']:
+ url = strate['paging']['URLPage'].encode('utf-8')
+ url = url + '&indexPage=' + params.index_page
+ params.index_page = int(params.index_page) + 1
+ more_videos = True
+ file_videos = utils.get_webcontent(url)
+ videos_json = json.loads(file_videos)
+
+ if more_videos or no_strates:
+ if len(videos_json['contents']) == 0:
+ more_videos = False
+ for content in videos_json['contents']:
+ title = content['title'].encode('utf-8')
+ try:
+ subtitle = content['subtitle'].encode('utf-8')
+ except:
+ subtitle = ''
+ img = content['URLImage'].encode('utf-8')
+ url_media = content['onClick']['URLPage'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': subtitle,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': img,
+ 'fanart': fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ url_media=url_media,
+ url_page=params.url_page,
+ title=title,
+ index_page=params.index_page
+ ),
+ 'info': info,
+ 'is_playable': True
+ })
+ else:
+ for strate in videos_json['strates']:
+ if strate['type'] == 'contentRow' or strate['type'] == 'contentGrid':
+ if strate['title'].encode('utf-8') == params.title or params.title == 'none':
+ for content in strate['contents']:
+ title = content['title'].encode('utf-8')
+ try:
+ subtitle = content['subtitle'].encode('utf-8')
+ except:
+ subtitle = ''
+ img = content['URLImage'].encode('utf-8')
+ url_media = content['onClick']['URLPage'].encode('utf-8')
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': subtitle,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': img,
+ 'fanart': fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ url_media=url_media,
+ url_page=params.url_page,
+ title=title,
+ index_page=params.index_page
+ ),
+ 'info': info,
+ 'is_playable': True
+ })
+
+ if more_videos:
+ videos.append({
+ 'label': common.addon.get_localized_string(30100),
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos',
+ url_media=url_media,
+ title=params.title,
+ url_page=params.url_page,
+ index_page=params.index_page
+ ),
+
+ })
+
+ videos = common.plugin.create_listing(
+ videos,
+ content='tvshows',
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ return videos
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ file_path = utils.get_webcontent(params.url_media)
+ media_json = json.loads(file_path)
+ url = media_json['detail']['informations']['VoD']['videoURL'].encode('utf-8')
+ return url
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py
new file mode 100755
index 0000000..b7ab8ee
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/gulli.py
@@ -0,0 +1,203 @@
+# -*- 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
+from resources.lib import utils
+from resources.lib import common
+
+
+def channel_entry(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)
+
+
+categories = {}
+
+categories['Dessins animés'] = 'http://sslreplay.gulli.fr/replay/api?' \
+ 'call=%7B%22api_key%22:%22iphoner_a140e' \
+ 'e8cb4b10fcd8b12a7fe688b34de%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'
+
+categories['Émissions'] = 'https://sslreplay.gulli.fr/replay/api?' \
+ 'call=%7B%22api_key%22:%22iphoner_a140e' \
+ 'e8cb4b10fcd8b12a7fe688b34de%22,%22method' \
+ '%22:%22programme.getLatestEpisodes%22,%' \
+ '22params%22:%7B%22program_image_thumb%' \
+ '22:%5B310,230%5D,%22category_id%22:%22' \
+ 'emissions%22%7D%7D'
+
+categories['Séries & films'] = 'https://sslreplay.gulli.fr/replay/api?' \
+ 'call=%7B%22api_key%22:%22iphoner_a140e' \
+ 'e8cb4b10fcd8b12a7fe688b34de%22,%22method' \
+ '%22:%22programme.getLatestEpisodes%22,%' \
+ '22params%22:%7B%22program_image_thumb%' \
+ '22:%5B310,230%5D,%22category_id%22:%22' \
+ 'series%22%7D%7D'
+
+url_list_show = 'https://sslreplay.gulli.fr/replay/api?call=%%7B%%22api_key' \
+ '%%22:%%22iphoner_a140ee8cb4b10fcd8b12a7fe688b34de%%22,%%22' \
+ 'method%%22:%%22programme.getEpisodesByProgramIds%%22,%%22' \
+ 'params%%22:%%7B%%22program_id_list%%22:%%5B%%22%s%%22%%5D' \
+ '%%7D%%7D'
+# program_id
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ # Create categories list
+ shows = []
+
+ if params.next == 'list_shows_1':
+ for category_title, category_url in categories.iteritems():
+ shows.append({
+ 'label': category_title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url=category_url,
+ next='list_shows_cat',
+ title=category_title
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_cat':
+ file_path = utils.download_catalog(
+ params.category_url,
+ '%s_%s.json' % (params.channel_name, params.title),
+ random_ua=True)
+ file = open(file_path).read()
+ json_category = json.loads(file)
+
+ for show in json_category['res']:
+ program_title = show['program_title'.encode('utf-8')]
+ program_id = show['program_id'].encode('utf-8')
+ fanart = show['program_image'].encode('utf-8')
+
+ shows.append({
+ 'label': program_title,
+ 'thumb': fanart,
+ 'fanart': fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ program_id=program_id,
+ next='list_videos',
+ title=program_title
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+
+ file_path = utils.download_catalog(
+ url_list_show % params.program_id,
+ '%s_%s.json' % (params.channel_name, params.program_id))
+ file = open(file_path).read()
+ json_show = json.loads(file)
+
+ for show in json_show['res']:
+ # media_id = show['media_id'].encode('utf-8')
+ # program_title = show['program_title'.encode('utf-8')]
+ # cat_id = show['cat_id'].encode('utf-8')
+ # program_id = show['program_id'].encode('utf-8')
+ fanart = show['program_image'].encode('utf-8')
+ thumb = show['episode_image'].encode('utf-8')
+ episode_title = show['episode_title'].encode('utf-8')
+ episode_number = show['episode_number']
+ season_number = show['season_number']
+ # total_episodes_in_season = show['total_episodes_in_season']
+ url_ipad = show['url_ipad'].encode('utf-8')
+ # url_streaming = show['url_streaming'].encode('utf-8')
+ short_desc = show['short_desc'].encode('utf-8')
+ note = float(show['note'].encode('utf-8')) * 2
+ date_debut = show['date_debut'].encode('utf-8')
+ # "2017-02-03 00:00:00"
+ year = int(date_debut[:4])
+ day = date_debut[8:10]
+ month = date_debut[5:7]
+ date = '.'.join((day, month, str(year)))
+ aired = '-'.join((str(year), month, day))
+
+ info = {
+ 'video': {
+ 'title': episode_title,
+ 'plot': short_desc,
+ 'episode': episode_number,
+ 'season': season_number,
+ 'rating': note,
+ 'aired': aired,
+ 'date': date,
+ # 'duration': duration,
+ 'year': year,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': episode_title,
+ 'thumb': thumb,
+ 'fanart': fanart,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ url_ipad=url_ipad
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE
+ ),
+ content='tvshows')
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ return params.video_urlhd
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/itele.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/itele.py
new file mode 100755
index 0000000..0963fb3
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/itele.py
@@ -0,0 +1,192 @@
+# -*- 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
+from resources.lib import utils
+from resources.lib import common
+
+
+def channel_entry(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)
+
+
+url_category_query = 'http://service.itele.fr/iphone/categorie_news?query='
+
+
+categories = {
+ 'http://service.itele.fr/iphone/topnews': 'La Une',
+ url_category_query + 'FRANCE': 'France',
+ url_category_query + 'MONDE': 'Monde',
+ url_category_query + 'POLITIQUE': 'Politique',
+ url_category_query + 'JUSTICE': 'Justice',
+ url_category_query + 'ECONOMIE': 'Économie',
+ url_category_query + 'SPORT': 'Sport',
+ url_category_query + 'CULTURE': 'Culture',
+ url_category_query + 'INSOLITE': 'Insolite'
+}
+
+#@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ # Create categories list
+ shows = []
+
+ if params.next == 'list_shows_1':
+ for category_url, category_title in categories.iteritems():
+ shows.append({
+ 'label': category_title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url=category_url,
+ next='list_videos_cat',
+ title=category_title
+ )
+ })
+
+ shows.append({
+ 'label': 'Les Émissions',
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url='emissions',
+ next='list_shows_emissions',
+ title='Les Émissions'
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+ elif params.next == 'list_shows_emissions':
+ shows.append({
+ 'label': 'À la Une',
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url='http://service.itele.fr/iphone/dernieres_emissions?query=',
+ next='list_videos_cat',
+ title='À la Une'
+ )
+ })
+
+ shows.append({
+ 'label': 'Magazines',
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url='http://service.itele.fr/iphone/emissions?query=magazines',
+ next='list_videos_cat',
+ title='Magazines'
+ )
+ })
+
+ shows.append({
+ 'label': 'Chroniques',
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category_url='http://service.itele.fr/iphone/emissions?query=chroniques',
+ next='list_videos_cat',
+ title='Chroniques'
+ )
+ })
+
+ return common.plugin.create_listing(
+ shows,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+ )
+
+
+def list_videos(params):
+ videos = []
+ if params.next == 'list_videos_cat':
+ file_path = utils.download_catalog(
+ params.category_url,
+ '%s_%s.json' % (params.channel_name, params.title))
+ file = open(file_path).read()
+ json_category = json.loads(file)
+
+ if 'news' in json_category:
+ json_category = json_category['news']
+ elif 'videos' in json_category:
+ json_category = json_category['videos']
+ elif 'topnews' in json_category:
+ json_category = json_category['topnews']
+ for video in json_category:
+ video_id = video['id_pfv'].encode('utf-8')
+ category = video['category'].encode('utf-8')
+ date_time = video['date'].encode('utf-8') # 2017-02-10 22:05:02
+ title = video['title'].encode('utf-8')
+ description = video['description'].encode('utf-8')
+ thumb = video['preview169'].encode('utf-8')
+ video_url = video['video_urlhd'].encode('utf-8')
+ if not video_url:
+ video_url = 'no_video'
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': description,
+ # 'aired': aired,
+ # 'date': date,
+ #'duration': duration,
+ #'year': year,
+ 'genre': category,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': thumb,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ video_id=video_id,
+ video_urlhd=video_url
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=(
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE,
+ common.sp.xbmcplugin.SORT_METHOD_GENRE,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ ),
+ content='tvshows')
+
+
+def get_video_URL(params):
+ return params.video_urlhd
+
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py
new file mode 100755
index 0000000..2c1ddaf
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/pluzz.py
@@ -0,0 +1,282 @@
+# -*- coding: utf-8 -*-
+"""
+ Catch-up TV & More
+ Original work (C) JUL1EN094, SPM, SylvainCecchetto
+ Copyright (C) 2016 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
+from resources.lib import utils
+from resources.lib import common
+
+channelCatalog = 'http://pluzz.webservices.francetelevisions.fr/' \
+ 'pluzz/liste/type/replay/nb/10000/chaine/%s'
+
+showInfo = 'http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/' \
+ '?idDiffusion=%s&catalogue=Pluzz'
+
+imgURL = 'http://refonte.webservices.francetelevisions.fr%s'
+
+categories = {"france2": "France 2",
+ "france3": "France 3",
+ "france4": "France 4",
+ "france5": "France 5",
+ "franceo": "France Ô",
+ "guadeloupe": "Guadeloupe 1ère",
+ "guyane": "Guyane 1ère",
+ "martinique": "Martinique 1ère",
+ "mayotte": "Mayotte 1ère",
+ "nouvellecaledonie": "Nouvelle Calédonie 1ère",
+ "polynesie": "Polynésie 1ère",
+ "reunion": "Réunion 1ère",
+ "saintpierreetmiquelon": "St-Pierre et Miquelon 1ère",
+ "wallisetfutuna": "Wallis et Futuna 1ère",
+ "sport": "Sport",
+ "info": "Info",
+ "documentaire": "Documentaire",
+ "seriefiction": "Série & fiction",
+ "magazine": "Magazine",
+ "jeunesse": "Jeunesse",
+ "divertissement": "Divertissement",
+ "jeu": "Jeu",
+ "culture": "Culture"}
+
+
+def channel_entry(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)
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ shows = []
+ uniqueItem = dict()
+
+ realChannel = params.channel_name
+ if params.channel_name == 'la_1ere':
+ realChannel = 'la_1ere_reunion%2C' \
+ 'la_1ere_guyane%2C' \
+ 'la_1ere_polynesie%2C' \
+ 'la_1ere_martinique%2C' \
+ 'la_1ere_mayotte%2C' \
+ 'la_1ere_nouvellecaledonie%2C' \
+ 'la_1ere_guadeloupe%2C' \
+ 'la_1ere_wallisetfutuna%2C' \
+ 'la_1ere_saintpierreetmiquelon'
+
+ url_json = channelCatalog % (realChannel)
+ filePath = utils.download_catalog(
+ url_json,
+ '%s.json' % (params.channel_name))
+ filPrgm = open(filePath).read()
+ jsonParser = json.loads(filPrgm)
+ emissions = jsonParser['reponse']['emissions']
+
+ if params.next == 'list_shows_1':
+ for emission in emissions:
+ rubrique = emission['rubrique'].encode('utf-8')
+ if rubrique not in uniqueItem:
+ uniqueItem[rubrique] = rubrique
+ rubrique_title = change_to_nicer_name(rubrique)
+
+ shows.append({
+ 'label': rubrique_title,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ rubrique=rubrique,
+ next='list_shows_2'
+ )
+ })
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=sort_methods
+ )
+
+ elif params.next == 'list_shows_2':
+ for emission in emissions:
+ rubrique = emission['rubrique'].encode('utf-8')
+ if rubrique == params.rubrique:
+ titre_programme = emission['titre_programme'].encode('utf-8')
+ if titre_programme != '':
+ id_programme = emission['id_programme'].encode('utf-8')
+ if id_programme == '':
+ id_programme = emission['id_emission'].encode('utf-8')
+ if id_programme not in uniqueItem:
+ uniqueItem[id_programme] = id_programme
+ icon = imgURL % (emission['image_large'])
+ genre = emission['genre']
+ accroche_programme = emission['accroche_programme']
+
+ info = {
+ 'video': {
+ 'title': titre_programme,
+ 'plot': accroche_programme,
+ 'genre': genre
+ }
+ }
+ shows.append({
+ 'label': titre_programme,
+ 'thumb': icon,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='list_videos_1',
+ id_programme=id_programme,
+ ),
+ 'info': info
+ })
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL
+ )
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=sort_methods
+ )
+
+ return shows
+
+
+@common.plugin.cached(common.cache_time)
+def change_to_nicer_name(original_name):
+ if original_name in categories:
+ return categories[original_name]
+ return original_name
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+ filePath = utils.download_catalog(
+ channelCatalog % (params.channel_name),
+ '%s.json' % (params.channel_name)
+ )
+ filPrgm = open(filePath).read()
+ jsonParser = json.loads(filPrgm)
+ emissions = jsonParser['reponse']['emissions']
+ for emission in emissions:
+ id_programme = emission['id_programme'].encode('utf-8')
+ if id_programme == '':
+ id_programme = emission['id_emission'].encode('utf-8')
+ if id_programme == params.id_programme:
+ title = ''
+ plot = ''
+ duration = 0
+ date = ''
+ genre = ''
+ id_diffusion = emission['id_diffusion']
+ filPrgm = utils.get_webcontent(
+ showInfo % (emission['id_diffusion']))
+ if(filPrgm != ''):
+ jsonParserShow = json.loads(filPrgm)
+ if jsonParserShow['synopsis']:
+ plot = jsonParserShow['synopsis'].encode('utf-8')
+ if jsonParserShow['diffusion']['date_debut']:
+ date = jsonParserShow['diffusion']['date_debut']
+ date = date.encode('utf-8')
+ if jsonParserShow['real_duration']:
+ duration = int(jsonParserShow['real_duration'])
+ if jsonParserShow['titre']:
+ title = jsonParserShow['titre'].encode('utf-8')
+ if jsonParserShow['sous_titre']:
+ title = ' '.join((
+ title,
+ '- [I]',
+ jsonParserShow['sous_titre'].encode('utf-8'),
+ '[/I]'))
+
+ if jsonParserShow['genre'] != '':
+ genre = \
+ jsonParserShow['genre'].encode('utf-8')
+
+ year = int(date[6:10])
+ day = date[:2]
+ month = date[3:5]
+ date = '.'.join((day, month, str(year)))
+ aired = '-'.join((str(year), month, day))
+ # date : string (%d.%m.%Y / 01.01.2009)
+ # aired : string (2008-12-07)
+ image = imgURL % (jsonParserShow['image'])
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': plot,
+ 'aired': aired,
+ 'date': date,
+ 'duration': duration,
+ 'year': year,
+ 'genre': genre,
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': image,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ id_diffusion=id_diffusion
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ common.sp.xbmcplugin.SORT_METHOD_DURATION,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ )
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=sort_methods,
+ content='tvshows')
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_URL(params):
+ filPrgm = utils.get_webcontent(showInfo % (params.id_diffusion))
+ jsonParser = json.loads(filPrgm)
+ url_HD = ''
+ url_SD = ''
+ for video in jsonParser['videos']:
+ if video['format'] == 'hls_v5_os':
+ url_HD = video['url']
+ if video['format'] == 'm3u8-download':
+ url_SD = video['url']
+
+ desired_quality = common.plugin.get_setting(
+ params.channel_id + '.quality')
+
+ if desired_quality == 'HD' and url_HD is not None:
+ return url_HD
+ else:
+ return url_SD
diff --git a/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py b/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py
new file mode 100755
index 0000000..c10c181
--- /dev/null
+++ b/plugin.video.catchuptvandmore/resources/lib/channels/fr/tf1.py
@@ -0,0 +1,238 @@
+# -*- coding: utf-8 -*-
+"""
+ Catch-up TV & More
+ Original work (C) JUL1EN094, SPM, SylvainCecchetto
+ Copyright (C) 2016 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.
+"""
+
+from bs4 import BeautifulSoup as bs
+from resources.lib import utils
+from resources.lib import common
+
+url_root = "http://www.tf1.fr/"
+
+
+def channel_entry(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)
+ else:
+ return None
+
+
+@common.plugin.cached(common.cache_time)
+def list_shows(params):
+ shows = []
+
+ url = ''.join((
+ url_root,
+ params.channel_name,
+ '/programmes-tv'))
+ file_path = utils.download_catalog(
+ url,
+ params.channel_name + '.html')
+ root_html = open(file_path).read()
+ root_soup = bs(root_html, 'html.parser')
+
+ if params.next == 'list_shows_1':
+ categories_soup = root_soup.find(
+ 'ul',
+ attrs={'class': 'filters_2 contentopen'})
+ for category in categories_soup.find_all('a'):
+ category_name = category.get_text().encode('utf-8')
+ category_url = category['data-target'].encode('utf-8')
+
+ shows.append({
+ 'label': category_name,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ category=category_url,
+ next='list_shows_2')})
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL)
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=sort_methods)
+
+ elif params.next == 'list_shows_2':
+ programs_soup = root_soup.find(
+ 'ul',
+ attrs={'id': 'js_filter_el_container'})
+ for program in programs_soup.find_all('li'):
+ category = program['data-type'].encode('utf-8')
+ if params.category == category or params.category == 'all':
+ program_url = program.find(
+ 'div',
+ class_='description')
+ program_url = program_url.find('a')['href'].encode('utf-8')
+ program_name = program.find(
+ 'p',
+ class_='program').get_text().encode('utf-8')
+ img = program.find('img')
+ try:
+ img = img['data-srcset'].encode('utf-8')
+ except:
+ 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')})
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL)
+
+ shows = common.plugin.create_listing(
+ shows,
+ sort_methods=sort_methods)
+
+ return shows
+
+
+@common.plugin.cached(common.cache_time)
+def list_videos(params):
+ videos = []
+
+ url = ''.join((
+ url_root,
+ params.program_url,
+ '/videos'))
+ program_html = utils.get_webcontent(url)
+ program_soup = bs(program_html, 'html.parser')
+
+ grid = program_soup.find(
+ 'ul',
+ class_='grid')
+
+ for li in grid.find_all('li'):
+ video_type_string = li.find('strong').get_text().encode('utf-8')
+ video_type = video_type_string.lower()
+
+ if 'playlist' not in video_type:
+ if 'replay' in video_type or \
+ 'video' in video_type or \
+ common.plugin.get_setting(params.channel_id + '.bonus'):
+
+ 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 = ''
+
+ try:
+ duration = li.find(
+ 'span',
+ attrs={'data-format': 'duration'})
+ duration = int(duration.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]
+
+ aired = li.find(
+ 'span',
+ attrs={'data-format': None, 'class': 'momentDate'})
+ aired = aired.get_text().encode('utf-8')
+ aired = aired.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)
+ program_id = li.find('a')['href'].encode('utf-8')
+
+ if 'replay' not in video_type and 'video' not in video_type:
+ title = title + ' - [I]' + video_type_string + '[/I]'
+
+ info = {
+ 'video': {
+ 'title': title,
+ 'plot': stitle,
+ 'aired': aired,
+ 'date': date,
+ 'duration': duration,
+ 'year': int(aired[:4]),
+ 'mediatype': 'tvshow'
+ }
+ }
+
+ videos.append({
+ 'label': title,
+ 'thumb': img,
+ 'url': common.plugin.get_url(
+ action='channel_entry',
+ next='play',
+ program_id=program_id,
+ ),
+ 'is_playable': True,
+ 'info': info
+ })
+
+ sort_methods = (
+ common.sp.xbmcplugin.SORT_METHOD_DATE,
+ common.sp.xbmcplugin.SORT_METHOD_DURATION,
+ common.sp.xbmcplugin.SORT_METHOD_LABEL_IGNORE_THE,
+ common.sp.xbmcplugin.SORT_METHOD_UNSORTED
+ )
+ return common.plugin.create_listing(
+ videos,
+ sort_methods=sort_methods,
+ content='tvshows')
+
+
+@common.plugin.cached(common.cache_time)
+def get_video_url(params):
+ url = url_root + 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')
+
+ data_src = iframe_player_soup['data-src'].encode('utf-8')
+
+ video_id = data_src[-8:]
+
+ return 'http://wat.tv/get/ipad/' + video_id + '.m3u8'