summaryrefslogtreecommitdiff
path: root/plugin.video.cmore/addon.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.video.cmore/addon.py')
-rw-r--r--plugin.video.cmore/addon.py399
1 files changed, 399 insertions, 0 deletions
diff --git a/plugin.video.cmore/addon.py b/plugin.video.cmore/addon.py
new file mode 100644
index 0000000..a86c0fb
--- /dev/null
+++ b/plugin.video.cmore/addon.py
@@ -0,0 +1,399 @@
+import sys
+import urlparse
+import json
+
+from resources.lib.kodihelper import KodiHelper
+
+base_url = sys.argv[0]
+handle = int(sys.argv[1])
+helper = KodiHelper(base_url, handle)
+
+
+def run():
+ try:
+ router(sys.argv[2][1:]) # trim the leading '?' from the plugin call paramstring
+ except helper.c.CMoreError as error:
+ if error.value == 'SESSION_NOT_AUTHENTICATED' or error.value == 'User is not authenticated':
+ helper.login_process()
+ router(sys.argv[2][1:])
+ else:
+ helper.dialog('ok', helper.language(30028), error.value)
+
+
+def list_root_pages():
+ for page in helper.c.root_pages[helper.c.locale]:
+ if page == 'start':
+ title = helper.language(30020)
+ elif page == 'movies':
+ title = helper.language(30021)
+ elif page == 'series':
+ title = helper.language(30022)
+ elif page == 'sports':
+ title = helper.language(30023)
+ elif page == 'tv':
+ title = helper.language(30024)
+ elif page == 'programs':
+ title = helper.language(30025)
+ elif page == 'kids':
+ title = helper.language(30026)
+ else:
+ title = page
+
+ params = {
+ 'action': 'list_page',
+ 'page': page,
+ 'namespace': 'page',
+ 'root_page': 'true'
+ }
+
+ helper.add_item(title, params=params)
+ helper.add_item(helper.language(30030), params={'action': 'search'}) # search
+ helper.eod()
+
+
+def list_page(page=None, namespace=None, root_page=False, page_data=None, search_query=None):
+ if page:
+ page_dict = helper.c.parse_page(page, namespace, helper.get_as_bool(root_page))
+ elif page_data:
+ page_dict = json.loads(page_data)
+ elif search_query:
+ page_dict = helper.c.get_search_data(search_query)
+
+ if not page_dict:
+ if search_query:
+ helper.dialog('ok', helper.language(30017), '{0} \'{1}\'.'.format(helper.language(30031), search_query))
+ helper.log('No page data found.')
+ return False
+
+ for i in page_dict:
+ page = i.get('id')
+ # search queries doesn't include the videoId in response
+ if i.get('videoId') or search_query:
+ if i.get('type') == 'movie':
+ list_movie(i)
+ elif i.get('type') == 'series':
+ list_show(i)
+ elif i.get('type') == 'live_event':
+ list_live_event(i)
+ elif 'displayableDate' in i:
+ list_event_date(i)
+ elif 'channel' in i:
+ list_channel(i)
+ elif 'namespace' in i: # theme pages
+ list_genres(i, page)
+ elif 'page_data' in i: # parsed containers
+ list_containers(i)
+ helper.eod()
+
+
+def list_genres(i, page):
+ params = {
+ 'action': 'list_page',
+ 'namespace': i['namespace'],
+ 'page': page,
+ 'root_page': 'false'
+ }
+
+ helper.add_item(i['headline'], params)
+
+
+def list_channel(i):
+ params = {
+ 'action': 'play',
+ 'video_id': i['channel']['videoId']
+ }
+
+ program_info = {
+ 'mediatype': 'video',
+ 'title': i['programs'][0]['title'],
+ 'genre': i['programs'][0].get('mainCategory'),
+ 'plot': i['programs'][0].get('description')
+ }
+
+ channel_art = {
+ 'fanart': helper.c.get_image_url(i['programs'][0].get('landscapeImage')),
+ 'thumb': helper.c.get_image_url(i['programs'][0].get('landscapeImage')),
+ 'cover': helper.c.get_image_url(i['programs'][0].get('landscapeImage')),
+ 'icon': helper.c.get_image_url(i['channel']['logoUrl'])
+ }
+
+ channel_colored = coloring(i['channel']['title'], 'live').encode('utf-8')
+ time_colored = coloring(i['programs'][0]['caption'], 'live').encode('utf-8')
+ program_title = i['programs'][0]['title'].encode('utf-8')
+ list_title = '[B]{0} {1}[/B]: {2}'.format(channel_colored, time_colored, program_title)
+
+ helper.add_item(list_title, params=params, info=program_info, art=channel_art, content='episodes', playable=True)
+
+
+def list_containers(i):
+ headline = i['attributes']['headline'].encode('utf-8')
+ if i['attributes'].get('subtitle'):
+ subtitle = i['attributes']['subtitle'].encode('utf-8')
+ title = '{0}: {1}'.format(subtitle, headline)
+ else:
+ title = headline
+
+ params = {
+ 'action': 'list_page_with_page_data',
+ 'page_data': json.dumps(i['page_data'])
+ }
+
+ helper.add_item(title, params)
+
+
+def list_event_date(date):
+ params = {
+ 'action': 'list_page_with_page_data',
+ 'page_data': json.dumps(date['events'])
+ }
+
+ helper.add_item(date['displayableDate'], params)
+
+
+def coloring(text, meaning):
+ """Return the text wrapped in appropriate color markup."""
+ if meaning == 'live':
+ color = 'FF03F12F'
+ elif meaning == 'archive':
+ color = 'FFFF0EE0'
+ elif meaning == 'upcoming':
+ color = 'FFF16C00'
+
+ colored_text = '[COLOR=%s]%s[/COLOR]' % (color, text)
+
+ return colored_text
+
+
+def list_live_event(event):
+ if event.get('commentators'):
+ if ',' in event.get('commentators'):
+ commentators = event.get('commentators').split(',')
+ else:
+ commentators = [event['commentators']]
+ else:
+ commentators = []
+
+ if helper.c.parse_datetime(event['startTime']) > helper.c.get_current_time():
+ event_status = 'upcoming'
+ params = {'action': 'noop'}
+ playable = False
+ else:
+ if 'liveEventEnd' in event: # if sports content is on-demand
+ event_status = 'archive'
+ else:
+ event_status = 'live'
+ params = {
+ 'action': 'play',
+ 'video_id': event['videoId']
+ }
+ playable = True
+
+ list_title = '[B]{0}:[/B] {1}'.format(coloring(event['displayableStartTime'].encode('utf-8'), event_status), event['title'].encode('utf-8'))
+
+ event_info = {
+ 'mediatype': 'video',
+ 'title': event.get('title'),
+ 'plot': event.get('description'),
+ 'plotoutline': event.get('caption'),
+ 'year': int(event['year']) if event.get('year') else None,
+ 'genre': ', '.join(event['subCategories']) if event.get('subCategories') else None,
+ 'cast': commentators
+ }
+
+ event_art = {
+ 'fanart': helper.c.get_image_url(event.get('landscapeImage')),
+ 'thumb': helper.c.get_image_url(event.get('landscapeImage')),
+ 'banner': helper.c.get_image_url(event.get('ultraforgeImage')),
+ 'cover': helper.c.get_image_url(event.get('landscapeImage')),
+ 'icon': helper.c.get_image_url(event.get('categoryIcon'))
+ }
+
+ helper.add_item(list_title, params=params, info=event_info, art=event_art, content='episodes', playable=playable)
+
+
+def list_movie(movie):
+ params = {
+ 'action': 'play',
+ 'video_id': movie['videoId']
+ }
+
+ movie_info = {
+ 'mediatype': 'movie',
+ 'title': movie.get('title'),
+ 'plot': movie.get('description') if movie.get('description') else movie.get('caption'),
+ 'cast': movie.get('actors', []),
+ 'genre': extract_genre_year(movie.get('caption'), 'genre'),
+ 'duration': movie.get('duration'),
+ 'year': int(extract_genre_year(movie.get('caption'), 'year'))
+ }
+
+ movie_art = {
+ 'fanart': helper.c.get_image_url(movie.get('landscapeImage')),
+ 'thumb': helper.c.get_image_url(movie.get('posterImage')),
+ 'banner': helper.c.get_image_url(movie.get('ultraforgeImage')),
+ 'cover': helper.c.get_image_url(movie.get('landscapeImage')),
+ 'poster': helper.c.get_image_url(movie.get('posterImage'))
+ }
+
+ helper.add_item(movie['title'], params=params, info=movie_info, art=movie_art, content='movies', playable=True)
+
+
+def extract_genre_year(caption, what_to_extract):
+ """Try to extract the genre or year from the caption."""
+ if what_to_extract == 'year':
+ list_index = 1
+ else:
+ list_index = 0
+
+ if caption:
+ try:
+ return caption.split(', ')[list_index]
+ except IndexError:
+ pass
+
+ return None
+
+
+def list_show(show):
+ params = {
+ 'action': 'list_episodes_or_seasons',
+ 'page_id': show['id']
+ }
+
+ show_info = {
+ 'mediatype': 'tvshow',
+ 'title': show.get('title'),
+ 'plot': show.get('description') if show.get('description') else show.get('caption'),
+ 'cast': show.get('actors', []),
+ 'genre': extract_genre_year(show.get('caption'), 'genre'),
+ 'duration': show.get('duration'),
+ 'year': extract_genre_year(show.get('caption'), 'year')
+ }
+
+ show_art = {
+ 'fanart': helper.c.get_image_url(show.get('landscapeImage')),
+ 'thumb': helper.c.get_image_url(show.get('posterImage')),
+ 'banner': helper.c.get_image_url(show.get('ultraforgeImage')),
+ 'cover': helper.c.get_image_url(show.get('landscapeImage')),
+ 'poster': helper.c.get_image_url(show.get('posterImage'))
+ }
+
+ helper.add_item(show['title'], params=params, info=show_info, art=show_art, content='tvshows')
+
+
+def list_episodes_or_seasons(page_id):
+ series = helper.c.get_content_details('series', page_id)
+ if len(series['availableSeasons']) > 1:
+ list_seasons(series)
+ else:
+ list_episodes(series_data=series)
+
+
+def list_seasons(series):
+ for season in series['availableSeasons']:
+ title = '{0} {1}'.format(helper.language(30029), str(season))
+ params = {
+ 'action': 'list_episodes',
+ 'page_id': series['id'],
+ 'season': str(season)
+ }
+ helper.add_item(title, params)
+ helper.eod()
+
+
+def list_episodes(page_id=None, season=None, series_data=None):
+ if page_id:
+ series = helper.c.get_content_details('series', page_id, season)
+ else:
+ series = series_data
+
+ for i in series['capiAssets']:
+ params = {
+ 'action': 'play',
+ 'video_id': i['videoId']
+ }
+
+ title = i.get('title').replace(': ', '').encode('utf-8')
+
+ episode_info = {
+ 'mediatype': 'episode',
+ 'title': title,
+ 'tvshowtitle': i['seriesTitle'] if i.get('seriesTitle') else title,
+ 'plot': i.get('description'),
+ 'year': int(i['year']) if i.get('year') else None,
+ 'season': int(i['season']) if i.get('season') else None,
+ 'episode': int(i['episode']) if i.get('episode') else None,
+ 'genre': ', '.join(i['subCategories']) if i.get('subCategories') else None,
+ 'cast': i.get('actors', []),
+ 'duration': i.get('duration')
+ }
+
+ list_title = add_season_episode_to_title(title, episode_info['season'], episode_info['episode'])
+
+ episode_art = {
+ 'fanart': helper.c.get_image_url(i.get('landscapeImage')),
+ 'thumb': helper.c.get_image_url(i.get('landscapeImage')),
+ 'banner': helper.c.get_image_url(i.get('ultraforgeImage')),
+ 'cover': helper.c.get_image_url(i.get('landscapeImage')),
+ 'poster': helper.c.get_image_url(i.get('posterImage'))
+ }
+
+ helper.add_item(list_title, params=params, info=episode_info, art=episode_art, content='episodes', playable=True)
+ helper.eod()
+
+
+def add_season_episode_to_title(title, season, episode):
+ if season and episode:
+ if int(season) <= 9:
+ season_format = '0' + str(season)
+ else:
+ season_format = str(season)
+ if int(episode) <= 9:
+ episode_format = '0' + str(episode)
+ else:
+ episode_format = str(episode)
+
+ return '[B]S{0}E{1}[/B] {2}'.format(season_format, episode_format, title)
+ else:
+ helper.log('No season/episode information found.')
+ return title
+
+
+def search():
+ search_query = helper.get_user_input(helper.language(30030))
+ if search_query:
+ list_page(search_query=search_query)
+ else:
+ helper.log('No search query provided.')
+ return False
+
+
+def router(paramstring):
+ """Router function that calls other functions depending on the provided paramstring."""
+ params = dict(urlparse.parse_qsl(paramstring))
+ if 'setting' in params:
+ if params['setting'] == 'get_operator':
+ helper.get_operator()
+ elif params['setting'] == 'set_locale':
+ helper.set_locale()
+ elif params['setting'] == 'reset_credentials':
+ helper.reset_credentials()
+ elif 'action' in params:
+ if helper.check_for_prerequisites():
+ if params['action'] == 'noop':
+ pass
+ elif params['action'] == 'play':
+ helper.play_item(params['video_id'])
+ elif params['action'] == 'list_page':
+ list_page(params['page'], params['namespace'], params['root_page'])
+ elif params['action'] == 'list_page_with_page_data':
+ list_page(page_data=params['page_data'])
+ elif params['action'] == 'list_episodes_or_seasons':
+ list_episodes_or_seasons(params['page_id'])
+ elif params['action'] == 'list_episodes':
+ list_episodes(page_id=params['page_id'], season=params['season'])
+ elif params['action'] == 'search':
+ search()
+ else:
+ if helper.check_for_prerequisites():
+ list_root_pages()