def nextEpPrep(self): auto_nextep_limit_reached = False autoplay_next_check_threshold = settings.autoplay_next_check_threshold( ) try: current_number = int( window.getProperty('current_autoplay_next_number')) except: current_number = 1 if autoplay_next_check_threshold != 0: if current_number == autoplay_next_check_threshold: auto_nextep_limit_reached = True continue_playing = xbmcgui.Dialog().yesno( 'Fen Next Episode', '[B]Are you still watching %s?[/B]' % self.meta['title'], '', '', 'Not Watching', 'Still Watching', 10000) if not continue_playing == 1: from modules.nav_utils import notification notification('Fen Next Episode Cancelled', 6000) self.nextep_info = {'pass': True} if not self.nextep_info: from modules.next_episode import nextep_playback_info, nextep_play self.nextep_info = nextep_playback_info(self.meta['tmdb_id'], int(self.meta['season']), int(self.meta['episode']), self.library_setting) if not self.nextep_info.get('pass', False): if not auto_nextep_limit_reached: self.delete_nextep_playcount = False window.setProperty('current_autoplay_next_number', str(current_number + 1)) nextep_play(self.nextep_info)
def remove_all_history(self): from modules.nav_utils import notification if not dialog.yesno('Are you sure?','Fen will Clear Discover\'s %s History.' % self.db_type.upper()): return all_history = self.history(self.db_type, display=False) for item in all_history: self.remove_from_history(data_id=item) notification('Discover History Cleared')
def update_subscriptions(self, suppress_extras=False): from datetime import datetime, timedelta self.db_type = 'tvshow' self.action = 'add' self.path = settings.tv_show_directory() subscriptions = self.get_subscriptions() if not subscriptions: return notification('No TV Show Subscriptions to Update', 1200) close_all_dialog() bg_dialog = xbmcgui.DialogProgressBG() bg_dialog.create('Please Wait', 'Preparing Subscription Update...') for count, item in enumerate(subscriptions, 1): self.tmdb_id = item['media_id'] self.add_remove_constants() self.add_remove_tvshow(silent=True) display = 'Fen Updating - [B][I]%s[/I][/B]' % self.rootname bg_dialog.update( int(float(count) / float(len(subscriptions)) * 100), 'Please Wait', '%s' % display) xbmc.sleep(300) if int(__addon__.getSetting('subsciptions.update_type')) == 0: hours = settings.subscription_timer() __addon__.setSetting( 'service_time', str(datetime.now() + timedelta(hours=hours)).split('.')[0]) xbmc.sleep(500) bg_dialog.close() notification('Fen Subscriptions Updated', 4500) if settings.update_library_after_service() and not suppress_extras: xbmc.executebuiltin('UpdateLibrary(video)')
def next_episode_options_choice(setting=None): from modules.nav_utils import notification from modules.utils import selection_dialog params = dict(parse_qsl(sys.argv[2].replace('?', ''))) choices = [('Sort Type', 'nextep.sort_type', [('RECENTLY WATCHED', '0'), ('AIRDATE', '1'), ('TITLE', '2')]), ('Sort Order', 'nextep.sort_order', [('DESCENDING', '0'), ('ASCENDING', '1')]), ('Include Unaired', 'nextep.include_unaired', [('OFF', 'false'), ('ON', 'true')]), ('Include Trakt or Fen Unwatched', 'nextep.include_unwatched', [('OFF', 'false'), ('ON', 'true')]), ('Cache To Disk', 'nextep.cache_to_disk', [('OFF', 'false'), ('ON', 'true')]), ('Include Airdate in Title', 'nextep.include_airdate', [('OFF', 'false'), ('ON', 'true')]), ('Airdate Format', 'nextep.airdate_format', [('DAY-MONTH-YEAR', '0'), ('YEAR-MONTH-DAY', '1'), ('MONTH-DAY-YEAR', '2')])] prelim_setting = params.get('setting') if not setting else setting title, setting = [(i[0], i[1]) for i in choices if i[0] == prelim_setting][0] string = 'Please Choose Setting for %s' % title full_list = [i[2] for i in choices if i[0] == prelim_setting][0] dialog_list = [i[0] for i in full_list] function_list = [i[1] for i in full_list] selection = selection_dialog(dialog_list, function_list, string) if not selection: return setting_name = [i[0] for i in full_list if i[1] == selection][0] __addon__.setSetting(setting, selection) notification('%s set to %s' % (title, setting_name), 6000)
def clear_search_history(): import xbmcgui from modules.nav_utils import notification dialog = xbmcgui.Dialog() choice_list = [ ('Delete Movie Search History', 'movie_queries', 'Movie'), ('Delete TV Show Search History', 'tvshow_queries', 'TV Show'), ('Delete People Search History', 'people_queries', 'People'), ('Delete Furk Video Search History', 'furk_video_queries', 'Furk Video'), ('Delete Furk Audio Search History', 'furk_audio_queries', 'Furk Audio'), ('Delete Easynews Video Search History', 'easynews_video_queries', 'Easynews Video') ] try: selection = dialog.select('Choose Search History to Delete', [i[0] for i in choice_list]) if selection < 0: return setting = choice_list[selection][1] _cache.set(setting, '', expiration=timedelta(days=365)) notification("%s Search History Removed" % choice_list[selection][2], 3500) except: return
def toggle_jump_to(): from modules.nav_utils import toggle_setting, notification from modules.settings import nav_jump_use_alphabet use_alphabet = nav_jump_use_alphabet() (setting, new_action) = ('0', 'PAGE') if use_alphabet == True else ('1', 'ALPHABET') toggle_setting(setting_id='nav_jump', setting_value=setting, refresh=True) notification('Jump To Action Switched to [B]%s[/B]' % new_action)
def add_remove_tvshow(self, silent=False): if self.action == 'add': self.make_folder() self.make_nfo() self.create_tvshow_strm_files() elif self.action == 'remove': self.remove_folder() if not silent: notification(self.notify % self.rootname, 4500)
def remove_from_favourites(self): dbcon = database.connect(self.fav_database) dbcon.execute("DELETE FROM favourites where db_type=? and tmdb_id=?", (self.db_type, str(self.tmdb_id))) dbcon.commit() dbcon.close() xbmc.executebuiltin("Container.Refresh") notification('[B]%s[/B] removed from Favourites' % self.title.upper(), 3500)
def _get(self, url, stream=False, retry=False): response = requests.get(url, headers=self.headers, stream=stream) if '200' in str(response): return response elif '429' in str(response) and retry: notification('OpenSubtitles Rate Limited. Retrying in 10 secs..', 3500) time.sleep(10) return self._get(url, stream) else: return
def add_to_favourites(self): try: dbcon = database.connect(self.fav_database) dbcon.execute( "INSERT INTO favourites VALUES (?, ?, ?)", (self.db_type, str(self.tmdb_id), to_unicode(self.title))) dbcon.commit() dbcon.close() notification('[B]%s[/B] added to Favourites' % self.title.upper(), 3500) except: notification( '[B]%s[/B] already in Favourites' % self.title.upper(), 3500)
def myfiles_protect_unprotect(name='', item_id='', action=''): from modules.nav_utils import notification params = dict(parse_qsl(sys.argv[2].replace('?',''))) name = params.get('name') if 'name' in params else name item_id = params.get('item_id') if 'item_id' in params else item_id action = params.get('action') if 'action' in params else action is_protected = '1' if action == 'protect' else '0' line1 = 'File added to Protected List' if action == 'protect' else 'File removed from Protected List' try: response = Furk.file_protect(item_id, is_protected) if response['status'] == 'ok': xbmc.executebuiltin("Container.Refresh") notification(line1, time=7000) except: return
def add_to_files(name='', item_id=''): from modules.nav_utils import notification params = dict(parse_qsl(sys.argv[2].replace('?',''))) name = params.get('name') if 'name' in params else name item_id = params.get('item_id') if 'item_id' in params else item_id resp = dialog.yesno('Are you sure?', "Add\n[B]%s[/B]\nto My Furk Files?" % name) if resp: response = Furk.file_link(item_id) if response['status'] == 'ok': notification('{}'.format('Item added to My Furk Files'), 3500) else: notification('{}'.format('Error - [B][I]%s[/I][/B]' % response['status']), 3500) return (None, None) dialog.close() else: return
def mark_episode_as_watched_unwatched(params=None): from modules.next_episode import add_next_episode_unwatched params = dict(parse_qsl(sys.argv[2].replace('?', ''))) if not params else params action = 'mark_as_watched' if params.get( 'action') == 'mark_as_watched' else 'mark_as_unwatched' media_id = params.get('media_id') tvdb_id = int(params.get('tvdb_id', '0')) imdb_id = params.get('imdb_id') season = int(params.get('season')) episode = int(params.get('episode')) title = params.get('title') year = params.get('year') refresh = params.get('refresh', 'true') from_playback = params.get('from_playback', 'false') watched_indicators = settings.watched_indicators() if season == 0: from modules.nav_utils import notification notification( 'Specials cannot be marked as %s' % ('Watched' if action == 'mark_as_watched' else 'Unwatched'), time=5000) return if watched_indicators in (1, 2): import time from apis.trakt_api import trakt_watched_unwatched, trakt_official_status if from_playback == 'true' and trakt_official_status( 'episode') == False: skip_trakt_mark = True else: skip_trakt_mark = False if not skip_trakt_mark: trakt_watched_unwatched(action, 'episode', imdb_id, tvdb_id, season, episode) if skip_trakt_mark: time.sleep(3) clear_trakt_watched_data('tvshow') clear_trakt_collection_watchlist_data('watchlist', 'tvshow') if watched_indicators in (0, 1): mark_as_watched_unwatched('episode', media_id, action, season, episode, title) erase_bookmark('episode', media_id, season, episode) if action == 'mark_as_watched': add_next_episode_unwatched('remove', media_id, silent=True) if settings.sync_kodi_library_watchstatus(): from modules.kodi_library import mark_as_watched_unwatched_kodi_library mark_as_watched_unwatched_kodi_library('episode', action, title, year, season, episode) refresh_container(refresh)
def biography_results(self): from modules.utils import calculate_age def _make_biography(): age = None heading = 'FEN Biography' name = bio_info.get('name') place_of_birth = bio_info.get('place_of_birth') biography = bio_info.get('biography') birthday = bio_info.get('birthday') deathday = bio_info.get('deathday') if deathday: age = calculate_age(birthday, '%Y-%m-%d', deathday) elif birthday: age = calculate_age(birthday, '%Y-%m-%d') text = '\n[COLOR dodgerblue][B]NAME:[/B][/COLOR] %s' % name if place_of_birth: text += '\n\n[COLOR dodgerblue][B]PLACE OF BIRTH[/B][/COLOR]: %s' % place_of_birth if birthday: text += '\n\n[COLOR dodgerblue][B]BIRTHDAY[/B][/COLOR]: %s' % birthday if deathday: text += '\n\n[COLOR dodgerblue][B]DIED:[/B][/COLOR] %s, aged %s' % (deathday, age) elif age: text += '\n\n[COLOR dodgerblue][B]AGE:[/B][/COLOR] %s' % age if biography: text += '\n\n[COLOR dodgerblue][B]BIOGRAPHY:[/B][/COLOR]\n%s' % biography return heading, text dialog = xbmcgui.Dialog() bio_info = TMDb.tmdb_people_biography(self.actor_id) if bio_info.get('biography', None) in ('', None): bio_info = TMDb.tmdb_people_biography(self.actor_id, 'en') if not bio_info: return notification('No Biography Found') heading, text = _make_biography() return dialog.textviewer(heading, text)
def remove_from_files(name='', item_id=''): from modules.nav_utils import notification params = dict(parse_qsl(sys.argv[2].replace('?',''))) name = params.get('name') item_id = params.get('item_id') resp = dialog.yesno('Are you sure?', "Remove [B][I]%s[/I][/B] from My Furk Files?" % name) if resp: response = Furk.file_unlink(item_id) if response['status'] == 'ok': notification('{}'.format('Item removed from My Furk Files'), 3500) xbmc.executebuiltin("Container.Refresh") else: notification('{}'.format('Error - [B][I]%s[/I][/B]' % response['status']), 3500) return (None, None) dialog.close() else: return
def remove_from_history(self, data_id=None): try: from sqlite3 import dbapi2 as database except ImportError: from pysqlite2 import dbapi2 as database from modules.nav_utils import notification display_notification = False if not data_id: params = dict(parse_qsl(sys.argv[2].replace('?',''))) data_id = params['data_id'] display_notification = True cache_file = os.path.join(__addon_profile__, "fen_cache.db") settings.check_database(cache_file) dbcon = database.connect(cache_file) dbcur = dbcon.cursor() dbcur.execute("DELETE FROM fencache WHERE id=?", (data_id,)) dbcon.commit() window.clearProperty(data_id) xbmc.executebuiltin("Container.Refresh") if display_notification: notification('Result Removed from Discover History')
def clear_favourites(self): fl = [('Movie Favourites', 'movie'), ('TV Show Favourites', 'tvshow')] fl_choose = self.dialog.select("Choose Favourites to Erase", [i[0] for i in fl]) if fl_choose < 0: return selection = fl[fl_choose] self.db_type = selection[1] confirm = self.dialog.yesno( 'Are you sure?', 'Continuing will erase all your [B]%s[/B]' % selection[0]) if not confirm: return dbcon = database.connect(self.fav_database) dbcon.execute("DELETE FROM favourites WHERE db_type=?", (self.db_type, )) dbcon.execute("VACUUM") dbcon.commit() dbcon.close() notification('[B]%s[/B] Erased' % selection[0], 3000)
def add_next_episode_unwatched(action=None, media_id=None, silent=False): from modules.nav_utils import notification from modules.indicators_bookmarks import mark_as_watched_unwatched settings.check_database(WATCHED_DB) params = dict(parse_qsl(sys.argv[2].replace('?', ''))) media_id = params['tmdb_id'] if not media_id else media_id action = params['action'] if not action else action if action == 'add': command, line1 = "INSERT OR IGNORE INTO unwatched_next_episode VALUES (?)", '%s Added to Fen Next Episode' % params.get( 'title') else: command, line1 = "DELETE FROM unwatched_next_episode WHERE media_id=?", '%s Removed from Fen Next Episode' % params.get( 'title') dbcon = database.connect(WATCHED_DB) dbcon.execute(command, (media_id, )) dbcon.commit() dbcon.close() if not silent: notification(line1, time=3500)
def export(self): try: db_type = self.discover_params['db_type'] query = self.discover_params['final_string'] name = self.discover_params['name'] set_history(db_type, name, query) if db_type == 'movie': mode = 'build_movie_list' action = 'tmdb_movies_discover' else: mode = 'build_tvshow_list' action = 'tmdb_tv_discover' final_params = {'name': name, 'mode': mode, 'action': action, 'query': query, 'iconImage': self.icon} url_params = {'mode': 'navigator.adjust_main_lists', 'method': 'add_external', 'list_name': name, 'menu_item': json.dumps(final_params)} xbmc.executebuiltin('XBMC.RunPlugin(%s)' % self._build_url(url_params)) except: from modules.nav_utils import notification notification('Please set some filters before exporting')
def clear_subscriptions(self, confirm=True, silent=False, db_type=None): if confirm: if not self.subscription_choice( 'Choose Subscriptions to Erase', 'Continuing will erase all your %s'): return self.db_type = self.choice[1] if not db_type else db_type self.path = settings.movies_directory( ) if self.db_type == 'movie' else settings.tv_show_directory() subscriptions = self.get_subscriptions() if len(subscriptions) == 0: return notification( '%s Subscriptions is already Empty' % self.db_type.upper(), 4500) self.remove_folder(self.path) self.make_folder(self.path) if not silent: notification( '%s Subscriptions has been Cleared' % self.db_type.upper(), 4500)
def add_remove(self, silent=False): self.add_remove_constants() if self.check_exists() and self.action == 'add': return notification( '[B]%s[/B] already in Subscriptions' % self.rootname, 4500) self.add_remove_movie( silent) if self.db_type == 'movie' else self.add_remove_tvshow( silent) if self.orig_mode in ('subscriptions_tvshows', 'subscriptions_movies' ) and self.action == 'remove': xbmc.executebuiltin('Container.Refresh')
def remove_from_history(): import xbmc import sys try: from urlparse import parse_qsl except ImportError: from urllib.parse import parse_qsl from modules.nav_utils import notification params = dict(parse_qsl(sys.argv[2].replace('?', ''))) try: result = _cache.get(params['setting_id']) result.remove(params.get('name')) _cache.set(params['setting_id'], result, expiration=timedelta(days=365)) notification( '[B]%s[/B] Removed from History' % params.get('name').upper(), 3500) xbmc.executebuiltin('Container.Refresh') except: return
def add_to_remove_from_next_episode_excludes(): from modules.nav_utils import notification settings.check_database(WATCHED_DB) params = dict(parse_qsl(sys.argv[2].replace('?', ''))) action = params.get('action') media_id = str(params.get('media_id')) title = str(params.get('title')) dbcon = database.connect(WATCHED_DB) if action == 'add': dbcon.execute("INSERT INTO exclude_from_next_episode VALUES (?, ?)", (media_id, title)) line1 = '[B]{}[/B] excluded from Fen Next Episode'.format( title.upper()) elif action == 'remove': dbcon.execute("DELETE FROM exclude_from_next_episode WHERE media_id=?", (media_id, )) line1 = '[B]{}[/B] included in Fen Next Episode'.format(title.upper()) dbcon.commit() dbcon.close() notification('{}'.format(line1), time=5000) xbmc.sleep(500) xbmc.executebuiltin("Container.Refresh")
def media_results(self, media_type, page_no, letter): from indexers.movies import Movies from indexers.tvshows import TVShows from modules.nav_utils import paginate_list, cached_page from modules.utils import title_key def _add_misc_dir(url_params, list_name='Next Page >>', info='Navigate to Next Page...', iconImage='item_next.png'): listitem = xbmcgui.ListItem(list_name, iconImage=os.path.join(icon_directory, iconImage)) listitem.setArt({'fanart': __addon__.getAddonInfo('fanart')}) listitem.setInfo('video', {'title': list_name, 'plot': info}) if url_params['mode'] == 'build_navigate_to_page': listitem.addContextMenuItems([("[B]Switch Jump To Action[/B]","XBMC.RunPlugin(%s)" % build_url({'mode': 'toggle_jump_to'}))]) xbmcplugin.addDirectoryItem(handle=__handle__, url=build_url(url_params), listitem=listitem, isFolder=True) not_widget = xbmc.getInfoLabel('Container.PluginName') cache_page = settings.cache_page() cache_page_string = 'people_search_%s_%s' % (media_type, self.actor_id) limit = 20 if cache_page: if not 'new_page' in params: silent = False if not_widget else True retrieved_page = cached_page(cache_page_string, silent=silent) if retrieved_page: page_no = retrieved_page try: builder = Movies if media_type == 'movies' else TVShows function = TMDb.tmdb_movies_actor_roles if media_type == 'movies' else TMDb.tmdb_tv_actor_roles content = 'movies' if media_type == 'movies' else 'tvshows' key = 'title' if media_type == 'movies' else 'name' result = function(self.actor_id) data = sorted(result, key=lambda k: title_key(k[key])) original_list = [{'media_id': i['id'], 'title': i[key]} for i in data] paginated_list, total_pages = paginate_list(original_list, page_no, letter, limit) media_list = [i['media_id'] for i in paginated_list] if total_pages > 2 and not_widget: _add_misc_dir({'mode': 'build_navigate_to_page', 'db_type': 'Media', 'media_type': media_type, 'actor_id': self.actor_id, 'actor_name': self.actor_name, 'actor_image': self.actor_image, 'current_page': page_no, 'total_pages': total_pages, 'transfer_mode': 'people_search.media_results'}, 'Jump To...', 'Jump To a Certain Page/Letter...', 'item_jump.png') builder(media_list, action='people_search_%s' % media_type).worker() if total_pages > page_no: _add_misc_dir({'mode': 'people_search.media_results', 'media_type': media_type, 'actor_id': self.actor_id, 'actor_name': self.actor_name, 'actor_image': self.actor_image, 'new_page': str(page_no + 1), 'new_letter': letter}) if cache_page: cached_page(cache_page_string, page_no=page_no) xbmcplugin.setContent(__handle__, content) xbmcplugin.endOfDirectory(__handle__) setView('view.%s' % content, content) except: notification('No Results', 3000)
def add_remove_movie(self, silent=False): if self.action == 'add': in_library = get_library_video( 'movie', self.title, self.year) if settings.skip_duplicates() else False if in_library: return self.make_folder() self.make_nfo() stream_file = self.create_movie_strm_files() params = to_utf8({ 'mode': 'play_media', 'library': 'True', 'query': self.rootname, 'poster': self.meta['poster'], 'year': self.year, 'plot': self.meta['plot'], 'title': self.title, 'tmdb_id': self.meta['tmdb_id'], 'vid_type': 'movie' }) self.make_stream(stream_file, params) elif self.action == 'remove': self.remove_folder() if not silent: notification(self.notify % self.rootname, 4500)
def mark_as_watched_unwatched(db_type='', media_id='', action='', season='', episode='', title=''): try: settings.check_database(WATCHED_DB) last_played = datetime.now().strftime('%Y-%m-%d %H:%M:%S') dbcon = database.connect(WATCHED_DB, timeout=40.0) erase_bookmark(db_type, media_id, season, episode) if action == 'mark_as_watched': dbcon.execute( "INSERT OR IGNORE INTO watched_status VALUES (?, ?, ?, ?, ?, ?)", (db_type, media_id, season, episode, last_played, to_unicode(title))) elif action == 'mark_as_unwatched': dbcon.execute( "DELETE FROM watched_status WHERE (db_type = ? and media_id = ? and season = ? and episode = ?)", (db_type, media_id, season, episode)) dbcon.commit() except: from modules.nav_utils import notification notification('Error Marking Watched in Fen', time=5000)
def clear_all_trakt_cache_data(list_type='progress_watched', confirm=True, silent=False): from modules.nav_utils import notification, close_all_dialog def _process(use_progress=False): window.setProperty('fen_refresh_trakt_info_complete', 'true') try: try: clear_trakt_hidden_data(list_type) except: pass try: clear_trakt_calendar() except: pass if use_progress: bg_dialog.update(25, 'Clearing Trakt Cache', '') for i in ('movie', 'tvshow'): try: clear_trakt_watched_data(i) except: pass for j in ('collection', 'watchlist'): try: clear_trakt_collection_watchlist_data(j, i) except: pass if use_progress: bg_dialog.update(50, 'Clearing Trakt Cache', '') try: clear_trakt_list_contents_data(clear_all=True) except: pass if use_progress: bg_dialog.update(75, 'Clearing Trakt Cache', '') for i in ('my_lists', 'liked_lists'): try: clear_trakt_list_data(i) except: pass try: dbcon = database.connect(trakt_cache_file) dbcon.execute("VACUUM") dbcon.commit() except: pass if use_progress: bg_dialog.update(100, 'Clearing Trakt Cache', '') return True except: return False if silent: return _process() if settings.refresh_trakt_on_startup() and not confirm: if window.getProperty('fen_refresh_trakt_info_complete') == 'true': return not_home_window = xbmc.getInfoLabel('Container.PluginName') use_progress = False if not_home_window == '' else True if use_progress: close_all_dialog() xbmc.sleep(200) bg_dialog = xbmcgui.DialogProgressBG() bg_dialog.create('Clearing Trakt Cache', 'Please Wait') success = _process(use_progress) if use_progress: bg_dialog.close() if success: if use_progress: return notification('Trakt Cache Refreshed') return else: return notification('Error Refreshing Trakt Cache') if confirm: if not xbmcgui.Dialog().yesno('Are you sure?', 'Fen will Clear the Trakt Cache.'): return False close_all_dialog() xbmc.sleep(200) bg_dialog = xbmcgui.DialogProgressBG() bg_dialog.create('Clearing Trakt Cache', 'Please Wait') result = _process(use_progress=True) bg_dialog.close() return result
def build_next_episode(): from modules.indicators_bookmarks import get_watched_info_tv check_meta_database() clear_all_trakt_cache_data(confirm=False) sync_watched_trakt_to_fen() try: threads = [] seen = set() ep_list = [] nextep_settings = settings.nextep_content_settings() nextep_display_settings = settings.nextep_display_settings() watched_info, use_trakt = get_watched_info_tv() meta_user_info = retrieve_user_info() cache_to_disk = nextep_settings['cache_to_disk'] nextep_display_settings['cache_to_disk'] = cache_to_disk window.setProperty('fen_fanart_error', 'true') if nextep_settings['include_unwatched']: for i in get_unwatched_next_episodes(): ep_list.append(i) if settings.watched_indicators() in (1, 2): from apis.trakt_api import trakt_get_next_episodes ep_list += trakt_get_next_episodes() else: settings.check_database(WATCHED_DB) dbcon = database.connect(WATCHED_DB) dbcur = dbcon.cursor() dbcur.execute( '''SELECT media_id, season, episode, last_played FROM watched_status WHERE db_type=?''', ('episode', )) rows = dbcur.fetchall() rows = sorted(rows, key=lambda x: (x[0], x[1], x[2]), reverse=True) [ ep_list.append({ "tmdb_id": a, "season": int(b), "episode": int(c), "last_played": d }) for a, b, c, d in rows if not (a in seen or seen.add(a)) ] ep_list = [ x for x in ep_list if x['tmdb_id'] not in check_for_next_episode_excludes() ] ep_list = [i for i in ep_list if not i['tmdb_id'] == None] for item in ep_list: threads.append( Thread(target=process_eps, args=(item, nextep_settings, nextep_display_settings, watched_info, use_trakt, meta_user_info))) [i.start() for i in threads] [i.join() for i in threads] r = [i for i in result if i is not None] r = sort_next_eps(r, nextep_settings) item_list = [i['listitem'] for i in r] for i in item_list: xbmcplugin.addDirectoryItem(__handle__, i[0], i[1], i[2]) xbmcplugin.setContent(__handle__, 'episodes') xbmcplugin.endOfDirectory(__handle__, cacheToDisc=cache_to_disk) setView('view.episode_lists', 'episodes') except: from modules.nav_utils import notification notification('Error getting Next Episode Info', time=3500) pass
def build_next_episode_manager(): from modules.nav_utils import add_dir from modules.indicators_bookmarks import get_watched_status_tvshow, get_watched_info_tv def _process(tmdb_id, action): try: meta = tvshow_meta('tmdb_id', tmdb_id, meta_user_info) title = meta['title'] if action == 'manage_unwatched': action, display = 'remove', '[COLOR=%s][UNWATCHED][/COLOR] %s' % ( NEXT_EP_UNWATCHED, title) url_params = { 'mode': 'add_next_episode_unwatched', 'action': 'remove', 'tmdb_id': tmdb_id, 'title': title } elif action == 'trakt_and_fen': action, display = 'unhide' if tmdb_id in exclude_list else 'hide', '[COLOR=red][EXCLUDED][/COLOR] %s' % title if tmdb_id in exclude_list else '[COLOR=green][INCLUDED][/COLOR] %s' % title url_params = { "mode": "hide_unhide_trakt_items", "action": action, "media_type": "shows", "media_id": meta['imdb_id'], "section": "progress_watched" } else: action, display = 'remove' if tmdb_id in exclude_list else 'add', '[COLOR=red][EXCLUDED][/COLOR] %s' % title if tmdb_id in exclude_list else '[COLOR=green][INCLUDED][/COLOR] %s' % title url_params = { 'mode': 'add_to_remove_from_next_episode_excludes', 'action': action, 'title': title, 'media_id': tmdb_id } sorted_list.append({ 'tmdb_id': tmdb_id, 'display': display, 'url_params': url_params, 'meta': json.dumps(meta) }) except: pass check_meta_database() clear_all_trakt_cache_data(confirm=False) sync_watched_trakt_to_fen() params = dict(parse_qsl(sys.argv[2].replace('?', ''))) NEXT_EP_UNWATCHED = __addon__.getSetting('nextep.unwatched_colour') if not NEXT_EP_UNWATCHED or NEXT_EP_UNWATCHED == '': NEXT_EP_UNWATCHED = 'red' threads = [] sorted_list = [] action = params['action'] if action == 'manage_unwatched': tmdb_list = [i['tmdb_id'] for i in get_unwatched_next_episodes()] heading = 'Select Show to remove from Fen Next Episode:' elif settings.watched_indicators() in (1, 2): from apis.trakt_api import trakt_get_next_episodes tmdb_list, exclude_list = trakt_get_next_episodes(include_hidden=True) heading = 'Select Show to Hide/Unhide from Trakt Progress:' action = 'trakt_and_fen' else: settings.check_database(WATCHED_DB) dbcon = database.connect(WATCHED_DB) dbcur = dbcon.cursor() dbcur.execute( '''SELECT media_id FROM watched_status WHERE db_type=? GROUP BY media_id''', ('episode', )) rows = dbcur.fetchall() tmdb_list = [row[0] for row in rows] exclude_list = check_for_next_episode_excludes() heading = 'Select Show to Include/Exclude in Fen Next Episode:' add_dir({'mode': 'nill'}, '[I][COLOR=grey][B]INFO:[/B][/COLOR] [COLOR=grey2]%s[/COLOR][/I]' % heading, iconImage='settings.png') if not tmdb_list: from modules.nav_utils import notification return notification('No Shows Present', time=5000) meta_user_info = retrieve_user_info() window.setProperty('fen_fanart_error', 'true') for tmdb_id in tmdb_list: threads.append(Thread(target=_process, args=(tmdb_id, action))) [i.start() for i in threads] [i.join() for i in threads] sorted_items = sorted(sorted_list, key=lambda k: k['display']) watched_info, use_trakt = get_watched_info_tv() for i in sorted_items: try: cm = [] meta = json.loads(i['meta']) playcount, overlay, total_watched, total_unwatched = get_watched_status_tvshow( watched_info, use_trakt, meta['tmdb_id'], meta.get('total_episodes')) meta.update({ 'playcount': playcount, 'overlay': overlay, 'total_watched': str(total_watched), 'total_unwatched': str(total_unwatched) }) url = build_url(i['url_params']) browse_url = build_url({ 'mode': 'build_season_list', 'meta': i['meta'] }) cm.append( ("[B]Browse...[/B]", 'XBMC.Container.Update(%s)' % browse_url)) listitem = xbmcgui.ListItem(i['display']) listitem.setProperty('watchedepisodes', str(total_watched)) listitem.setProperty('unwatchedepisodes', str(total_unwatched)) listitem.setProperty('totalepisodes', str(meta['total_episodes'])) listitem.setProperty('totalseasons', str(meta['total_seasons'])) listitem.addContextMenuItems(cm) listitem.setArt({ 'poster': meta['poster'], 'fanart': meta['fanart'], 'banner': meta['banner'], 'clearart': meta['clearart'], 'clearlogo': meta['clearlogo'], 'landscape': meta['landscape'] }) listitem.setCast(meta['cast']) listitem.setInfo('video', remove_unwanted_info_keys(meta)) xbmcplugin.addDirectoryItem(__handle__, url, listitem, isFolder=True) except: pass xbmcplugin.setContent(__handle__, 'tvshows') xbmcplugin.endOfDirectory(__handle__, cacheToDisc=False) setView('view.main', 'tvshows')
def _ext_scrapers_notice(status): from modules.nav_utils import notification notification('[B]External Scrapers Manager[/B] %s' % status, 2500)