def get_in_progress_tvshows(dummy_arg, page_no, letter): def _process(item): tmdb_id = item['media_id'] meta = metadata.tvshow_meta('tmdb_id', tmdb_id, meta_user_info) watched_status = get_watched_status_tvshow(watched_info, tmdb_id, meta.get('total_aired_eps')) if watched_status[0] == 0: append(item) check_trakt_refresh() duplicates = set() data = [] append = data.append watched_indicators = settings.watched_indicators() paginate = settings.paginate() limit = settings.page_limit() meta_user_info = metadata.retrieve_user_info() watched_info = get_watched_info_tv(watched_indicators) prelim_data = [{ 'media_id': i[0], 'title': i[3] } for i in watched_info if not (i[0] in duplicates or duplicates.add(i[0]))] threads = list(make_thread_list(_process, prelim_data, Thread)) [i.join() for i in threads] original_list = sort_for_article(data, 'title', settings.ignore_articles()) if paginate: final_list, total_pages = paginate_list(original_list, page_no, letter, limit) else: final_list, total_pages = original_list, 1 return final_list, total_pages
def retrieve_favourites(db_type, page_no, letter): paginate = settings.paginate() limit = settings.page_limit() data = Favourites({}).get_favourites(db_type) data = sort_for_article(data, 'title', settings.ignore_articles()) original_list = [{'media_id': i['tmdb_id'], 'title': i['title']} for i in data] if paginate: final_list, total_pages = paginate_list(original_list, page_no, letter, limit) else: final_list, total_pages = original_list, 1 return final_list, total_pages
def get_watched_items(db_type, page_no, letter): paginate = settings.paginate() limit = settings.page_limit() watched_indicators = settings.watched_indicators() if db_type == 'tvshow': from threading import Thread from modules.utils import make_thread_list def _process(item): tmdb_id = item['media_id'] meta = metadata.tvshow_meta('tmdb_id', tmdb_id, meta_user_info) watched_status = get_watched_status_tvshow( watched_info, tmdb_id, meta.get('total_aired_eps')) if watched_status[0] == 1: append(item) meta_user_info = metadata.retrieve_user_info() watched_info = get_watched_info_tv(watched_indicators) duplicates = set() data = [] append = data.append prelim_data = [{ 'media_id': i[0], 'title': i[3] } for i in watched_info if not (i[0] in duplicates or duplicates.add(i[0]))] threads = list(make_thread_list(_process, prelim_data, Thread)) [i.join() for i in threads] original_list = sort_for_article(data, 'title', settings.ignore_articles()) else: watched_info = get_watched_info_movie(watched_indicators) data = [{'media_id': i[0], 'title': i[1]} for i in watched_info] original_list = sort_for_article(data, 'title', settings.ignore_articles()) if paginate: final_list, total_pages = paginate_list(original_list, page_no, letter, limit) else: final_list, total_pages = original_list, 1 return final_list, total_pages
def title_key(title): from modules.settings import ignore_articles if not ignore_articles(): return title import re try: if title is None: title = '' articles = ['the', 'a', 'an'] match = re.match('^((\w+)\s+)', title.lower()) if match and match.group(2) in articles: offset = len(match.group(1)) else: offset = 0 return title[offset:] except: return title
def trakt_fetch_collection_watchlist(list_type, db_type): key, string_insert = ('movie', 'movie') if db_type in ('movie', 'movies') else ('show', 'tvshow') collected_at = 'collected_at' if db_type in ( 'movie', 'movies') else 'last_collected_at' string = 'trakt_%s_%s' % (list_type, string_insert) path = 'sync/%s/' % list_type url = { 'path': path + '%s', 'path_insert': db_type, 'with_auth': True, 'pagination': False } data = trakt_cache.cache_trakt_object(get_trakt, string, url) if list_type == 'watchlist': data = [i for i in data if i['type'] == key] result = [{ 'media_ids': i[key]['ids'], 'title': i[key]['title'], 'collected_at': i.get(collected_at) } for i in data] result = sort_for_article(result, 'title', settings.ignore_articles()) return result
def build_next_episode_manager(params): def build_content(tmdb_id): try: cm = [] listitem = make_listitem() set_property = listitem.setProperty cm_append = cm.append meta = tvshow_meta('tmdb_id', tmdb_id, meta_user_info) meta_get = meta.get total_aired_eps = meta_get('total_aired_eps') total_seasons = meta_get('total_seasons') title = meta_get('title') playcount, overlay, total_watched, total_unwatched = get_watched_status_tvshow( watched_info, tmdb_id, total_aired_eps) meta.update({'playcount': playcount, 'overlay': overlay}) if tmdb_id in exclude_list: color, action, status, sort_value = 'red', 'unhide', excluded_str, 1 else: color, action, status, sort_value = 'green', 'hide', included_str, 0 display = '[COLOR=%s][%s][/COLOR] %s' % (color, status, title) extras_params = { 'mode': 'extras_menu_choice', 'tmdb_id': tmdb_id, 'db_type': 'tvshow', 'is_widget': 'False' } url_params = { 'mode': 'hide_unhide_trakt_items', 'action': action, 'media_type': 'shows', 'media_id': meta_get('imdb_id'), 'section': 'progress_watched' } url = build_url(url_params) if show_all_episodes: if all_episodes == 1 and total_seasons > 1: browse_params = { 'mode': 'build_season_list', 'tmdb_id': tmdb_id } else: browse_params = { 'mode': 'build_episode_list', 'tmdb_id': tmdb_id, 'season': 'all' } else: browse_params = { 'mode': 'build_season_list', 'tmdb_id': tmdb_id } cm_append((extras_str, 'RunPlugin(%s)' % build_url(extras_params))) cm_append((browse_str, 'Container.Update(%s)' % build_url(browse_params))) listitem.setLabel(display) set_property('watchedepisodes', str(total_watched)) set_property('unwatchedepisodes', str(total_unwatched)) set_property('totalepisodes', str(total_aired_eps)) set_property('totalseasons', str(total_seasons)) listitem.addContextMenuItems(cm) listitem.setArt({ 'poster': meta_get('poster'), 'fanart': meta_get('fanart'), 'banner': meta_get('banner'), 'clearart': meta_get('clearart'), 'clearlogo': meta_get('clearlogo'), 'landscape': meta_get('landscape') }) listitem.setCast(meta['cast']) listitem.setInfo('video', remove_meta_keys(meta, dict_removals)) append({ 'listitem': (url, listitem, False), 'sort_value': sort_value, 'sort_title': title }) except: pass __handle__ = int(argv[1]) list_items = [] append = list_items.append meta_user_info, watched_indicators, watched_info, all_episodes, include_year_in_title, open_extras = get_tvshow_info( ) ep_list = get_next_episodes(watched_info) tmdb_list = [i['tmdb_id'] for i in ep_list] try: exclude_list = trakt_get_hidden_items('progress_watched') except: exclude_list = [] show_all_episodes = True if all_episodes in (1, 2) else False threads = list(make_thread_list(build_content, tmdb_list, Thread)) [i.join() for i in threads] item_list = sorted( list_items, key=lambda k: (k['sort_value'], title_key(k['sort_title'], ignore_articles())), reverse=False) item_list = [i['listitem'] for i in item_list] kodi_utils.add_dir({'mode': 'nill'}, '[I][COLOR=grey2]%s[/COLOR][/I]' % heading.upper(), __handle__, iconImage='settings.png', isFolder=False) kodi_utils.add_items(__handle__, item_list) kodi_utils.set_content(__handle__, 'tvshows') kodi_utils.end_directory(__handle__, cacheToDisc=False) kodi_utils.set_view_mode('view.main', 'tvshows') kodi_utils.focus_index(1)
def build_single_episode(list_type, data): def _sort_results(items): if list_type_starts_with('next_episode'): def func(function): if sort_key == 'fen_name': return title_key(function, ignore_articles) elif sort_key == 'fen_last_played': return jsondate_to_datetime(function, resformat) else: return function sort_key = nextep_settings['sort_key'] sort_direction = nextep_settings['sort_direction'] if nextep_settings['sort_airing_today_to_top']: airing_today = [i for i in items if date_difference(current_date, jsondate_to_datetime(i[1].getProperty('fen_first_aired'), '%Y-%m-%d').date(), 0)] airing_today = sorted(airing_today, key=lambda i: i[1].getProperty('fen_first_aired')) remainder = [i for i in items if not i in airing_today] remainder = sorted(remainder, key=lambda i: func(i[1].getProperty(sort_key)), reverse=sort_direction) unaired = [i for i in remainder if i[1].getProperty('fen_unaired') == 'true'] aired = [i for i in remainder if not i in unaired] remainder = aired + unaired items = airing_today + remainder else: items = sorted(items, key=lambda i: func(i[1].getProperty(sort_key)), reverse=sort_direction) unaired = [i for i in items if i[1].getProperty('fen_unaired') == 'true'] aired = [i for i in items if not i in unaired] items = aired + unaired else: items.sort(key=lambda k: int(k[1].getProperty('fen_sort_order'))) return items def _process(item_position, ep_data): try: cm = [] listitem = make_listitem() set_property = listitem.setProperty cm_append = cm.append ep_data_get = ep_data.get if list_type_starts_with('trakt_'): tmdb_id = get_trakt_tvshow_id(ep_data_get('ids')) else: tmdb_id = ep_data_get('tmdb_id') if not tmdb_id: return meta = metadata.tvshow_meta('tmdb_id', tmdb_id, meta_user_info) meta_get = meta.get tmdb_id, tvdb_id, imdb_id = meta_get('tmdb_id'), meta_get('tvdb_id'), meta_get('imdb_id') title, year, rootname, banner = meta_get('title'), meta_get('year'), meta_get('rootname'), meta_get('banner') show_poster = meta_get(poster_main) or meta_get(poster_backup) or poster_empty fanart = meta_get(fanart_main) or meta_get(fanart_backup) or fanart_empty clearlogo, clearart, landscape = meta_get('clearlogo'), meta_get('clearart'), meta_get('landscape') cast, mpaa, duration = meta_get('cast'), meta_get('mpaa'), meta_get('duration') trailer, genre, studio = string(meta_get('trailer')), meta_get('genre'), meta_get('studio') tvshow_plot = meta_get('plot') orig_season = ep_data_get('season') orig_episode = ep_data_get('episode') if list_type_starts_with('next_episode'): season_data = meta_get('season_data') curr_season_data = [i for i in season_data if i['season_number'] == orig_season][0] orig_season = orig_season if orig_episode < curr_season_data['episode_count'] else orig_season + 1 orig_episode = orig_episode + 1 if orig_episode < curr_season_data['episode_count'] else 1 episodes_data = metadata.season_episodes_meta(orig_season, meta, meta_user_info) try: item = [i for i in episodes_data if i['episode'] == orig_episode][0] except: return item_get = item.get season = item_get('season') episode = item_get('episode') ep_name = item_get('title') orig_premiered = item_get('premiered') all_cast = cast + item_get('guest_stars', []) episode_date, premiered = adjust_premiered_date(orig_premiered, adjust_hours) if not episode_date or current_date < episode_date: if list_type_starts_with('next_episode'): if not include_unaired: return if not date_difference(current_date, episode_date, 7): return elif not show_unaired: return unaired = True set_property('fen_unaired', 'true') else: unaired = False set_property('fen_unaired', 'false') playcount, overlay = get_watched_status(watched_info, string(tmdb_id), season, episode) resumetime = get_resumetime(bookmarks, tmdb_id, season, episode) if display_title == 0: title_string = '%s: ' % title else: title_string = '' if display_title in (0,1): seas_ep = '%dx%.2d - ' % (season, episode) else: seas_ep = '' if list_type_starts_with('next_episode'): unwatched = ep_data_get('unwatched', False) if episode_date: display_premiered = make_day(current_date, episode_date, date_format) else: display_premiered == 'UNKNOWN' airdate = '[[COLOR magenta]%s[/COLOR]] ' % display_premiered if include_airdate else '' highlight_color = unwatched_color if unwatched else unaired_color if unaired else '' italics_open, italics_close = ('[I]', '[/I]') if highlight_color else ('', '') if highlight_color: episode_info = '%s[COLOR %s]%s %s[/COLOR]%s' % (italics_open, highlight_color, seas_ep, ep_name, italics_close) else: episode_info = '%s%s%s%s' % (italics_open, seas_ep, ep_name, italics_close) display = '%s%s%s' % (airdate, upper(title_string), episode_info) elif list_type == 'trakt_calendar': if episode_date: display_premiered = make_day(current_date, episode_date, date_format) else: display_premiered == 'UNKNOWN' display = '[%s]%s%s%s' % (display_premiered, upper(title_string), seas_ep, item_get('title')) if unaired: displays = display.split(']') display = '[COLOR red]' + displays[0] + '][/COLOR]' + displays[1] else: color_tags = ('[COLOR red]', '[/COLOR]') if unaired else ('', '') display = '%s%s%s%s%s' % (upper(title_string), color_tags[0], seas_ep, ep_name, color_tags[1]) thumb = item_get('thumb', None) or fanart if thumb_fanart: background = thumb else: background = fanart item.update({'trailer': trailer, 'tvshowtitle': title, 'premiered': premiered, 'genre': genre, 'duration': duration, 'mpaa': mpaa, 'studio': studio, 'playcount': playcount, 'overlay': overlay, 'title': display}) extras_params = build_url({'mode': 'extras_menu_choice', 'tmdb_id': tmdb_id, 'db_type': 'tvshow', 'is_widget': is_widget}) options_params = build_url({'mode': 'options_menu_choice', 'content': 'episode', 'tmdb_id': tmdb_id, 'season': season, 'episode': episode}) url_params = build_url({'mode': 'play_media', 'vid_type': 'episode', 'tmdb_id': tmdb_id, 'season': season, 'episode': episode}) if show_all_episodes: if all_episodes == 1 and meta_get('total_seasons') > 1: browse_params = build_url({'mode': 'build_season_list', 'tmdb_id': tmdb_id}) else: browse_params = build_url({'mode': 'build_episode_list', 'tmdb_id': tmdb_id, 'season': 'all'}) else: browse_params = build_url({'mode': 'build_season_list', 'tmdb_id': tmdb_id}) cm_append((extras_str, run_plugin % extras_params)) cm_append((options_str, run_plugin % options_params)) cm_append((browse_str, container_update % browse_params)) clearprog_params, unwatched_params, watched_params = '', '', '' if not unaired: if resumetime != '0': clearprog_params = build_url({'mode': 'watched_unwatched_erase_bookmark', 'db_type': 'episode', 'tmdb_id': tmdb_id, 'season': season, 'episode': episode, 'refresh': 'true'}) cm_append((clearprog_str, run_plugin % clearprog_params)) set_property('fen_in_progress', 'true') if playcount: unwatched_params = build_url({'mode': 'mark_as_watched_unwatched_episode', 'action': 'mark_as_unwatched', 'tmdb_id': tmdb_id, 'tvdb_id': tvdb_id, 'season': season, 'episode': episode, 'title': title, 'year': year}) cm_append((unwatched_str % watched_title, run_plugin % unwatched_params)) else: watched_params = build_url({'mode': 'mark_as_watched_unwatched_episode', 'action': 'mark_as_watched', 'tmdb_id': tmdb_id, 'tvdb_id': tvdb_id, 'season': season, 'episode': episode, 'title': title, 'year': year}) cm_append((watched_str % watched_title, run_plugin % watched_params)) if list_type == 'next_episode_trakt': cm_append((ls(32599), container_update % build_url({'mode': 'build_next_episode_manager'}))) listitem.setLabel(display) listitem.setContentLookup(False) listitem.addContextMenuItems(cm) listitem.setArt({'poster': show_poster, 'fanart': background, 'thumb': thumb, 'icon':thumb, 'banner': banner, 'clearart': clearart, 'clearlogo': clearlogo, 'landscape': thumb, 'tvshow.clearart': clearart, 'tvshow.clearlogo': clearlogo, 'tvshow.landscape': thumb, 'tvshow.banner': banner}) listitem.setCast(all_cast) listitem.setUniqueIDs({'imdb': imdb_id, 'tmdb': string(tmdb_id), 'tvdb': string(tvdb_id)}) listitem.setInfo('video', remove_meta_keys(item, dict_removals)) set_property('resumetime', resumetime) set_property('fen_name', '%s - %.2dx%.2d' % (title, season, episode)) if list_type_starts_with('next_episode'): last_played = ep_data_get('last_played', resinsert) set_property('fen_last_played', last_played) set_property('fen_first_aired', premiered) else: set_property('fen_sort_order', string(item_position)) if is_widget: set_property('fen_widget', 'true') set_property('fen_playcount', string(playcount)) set_property('fen_browse_params', browse_params) set_property('fen_options_menu_params', options_params) set_property('fen_extras_menu_params', extras_params) set_property('fen_unwatched_params', unwatched_params) set_property('fen_watched_params', watched_params) set_property('fen_clearprog_params', clearprog_params) else: set_property('fen_widget', 'false') append((url_params, listitem, False)) except: pass __handle__ = int(argv[1]) item_list = [] append = item_list.append list_type_starts_with = list_type.startswith get_resumetime = indicators.get_resumetime get_watched_status = indicators.get_watched_status_episode meta_user_info, watched_indicators, watched_info, show_unaired, thumb_fanart, is_widget, current_date, adjust_hours, bookmarks = get_episode_info() display_title, date_format, art_keys, all_episodes = get_single_episode_info() show_all_episodes = all_episodes in (1, 2) poster_main, poster_backup, fanart_main, fanart_backup = settings.get_art_provider() ignore_articles = settings.ignore_articles() watched_title = 'Trakt' if watched_indicators == 1 else 'Fen' if list_type_starts_with('next_episode'): nextep_settings, nextep_display_settings = settings.nextep_content_settings(), settings.nextep_display_settings() unaired_color, unwatched_color = nextep_display_settings['unaired_color'], nextep_display_settings['unwatched_color'] include_airdate = nextep_display_settings['include_airdate'] include_unaired = nextep_settings['include_unaired'] if watched_indicators == 1: resformat, resinsert = '%Y-%m-%dT%H:%M:%S.%fZ', '2000-01-01T00:00:00.000Z' else: resformat, resinsert = '%Y-%m-%d %H:%M:%S', '2000-01-01 00:00:00' threads = list(make_thread_list_enumerate(_process, data, Thread)) [i.join() for i in threads] item_list = _sort_results(item_list) kodi_utils.add_items(__handle__, item_list) kodi_utils.set_content(__handle__, 'episodes') kodi_utils.end_directory(__handle__, cacheToDisc=False) kodi_utils.set_view_mode('view.episodes', 'episodes') if list_type == 'trakt_calendar' and settings.calendar_focus_today(): today = '[%s]' % ls(32849).upper() try: index = max([i for i, x in enumerate([i[1].getLabel() for i in item_list]) if today in x]) except: return kodi_utils.focus_index(index)
def call_trakt(path, params={}, data=None, is_delete=False, with_auth=True, method=None, pagination=False, page=1, suppress_error_notification=False): def error_notification(line1, error): if suppress_error_notification: return return kodi_utils.notification('%s: %s' % (line1, error[0:50]), 3000, trakt_icon) def send_query(): resp = None if with_auth: try: ma_addon = kodi_utils.ext_addon('script.module.myaccounts') expires_at = float(ma_addon.getSetting('trakt.expires')) if time.time() > expires_at: trakt_refresh_token() except: pass token = ma_addon.getSetting('trakt.token') if token: headers['Authorization'] = 'Bearer ' + token try: if method: if method == 'post': resp = requests.post(API_ENDPOINT % path, headers=headers, timeout=timeout) elif method == 'delete': resp = requests.delete(API_ENDPOINT % path, headers=headers, timeout=timeout) elif method == 'sort_by_headers': resp = requests.get(API_ENDPOINT % path, params, headers=headers, timeout=timeout) elif data is not None: assert not params resp = requests.post(API_ENDPOINT % path, json=data, headers=headers, timeout=timeout) elif is_delete: resp = requests.delete(API_ENDPOINT % path, headers=headers, timeout=timeout) else: resp = requests.get(API_ENDPOINT % path, params, headers=headers, timeout=timeout) resp.raise_for_status() except requests.exceptions.RequestException as e: return error_notification('Trakt Error', str(e)) except Exception as e: return error_notification('', str(e)) return resp params = dict([(k, to_utf8(v)) for k, v in params.items() if v]) timeout = 15.0 numpages = 0 headers = { 'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': CLIENT_ID } if pagination: params['page'] = page response = send_query() response.raise_for_status() if response.status_code == 401: if kodi_utils.player.isPlaying() == False: if with_auth and kodi_utils.confirm_dialog( heading='%s %s' % (ls(32057), trakt_str), text=32741) and trakt_authenticate(): response = send_query() else: pass else: return if response.status_code == 429: headers = response.headers if 'Retry-After' in headers: kodi_utils.sleep(1000 * headers['Retry-After']) response = send_query() response.encoding = 'utf-8' try: result = response.json() except: result = None if method == 'sort_by_headers': headers = response.headers if 'X-Sort-By' in headers and 'X-Sort-How' in headers: result = sort_list(headers['X-Sort-By'], headers['X-Sort-How'], result, settings.ignore_articles()) if pagination: return (result, response.headers['X-Pagination-Page-Count']) else: return result