def set_download_location(): """ Sets the relevant download location to settings :return: """ storage_location = g.DOWNLOAD_PATH new_location = xbmcgui.Dialog().browse(0, g.get_language_string(30468), "video", defaultt=storage_location) g.set_setting("download.location", new_location)
def movies_genres(self): g.add_directory_item(g.get_language_string(30046), action="movieGenresGet") genres = self.trakt.get_json("genres/movies") if genres is None: g.cancel_directory() return for i in genres: g.add_directory_item(i["name"], action="movieGenresGet", action_args=i["slug"]) g.close_directory(g.CONTENT_GENRES)
def _remove_from_collection(self, item_information): self.trakt_api.post("sync/collection/remove", self._info_to_trakt_object(item_information, True)) if item_information["mediatype"] == "movie": from resources.lib.database.trakt_sync.movies import TraktSyncDatabase TraktSyncDatabase().mark_movie_uncollected( item_information["trakt_id"]) else: from resources.lib.database.trakt_sync.shows import TraktSyncDatabase trakt_id = self._get_show_id(item_information) TraktSyncDatabase().mark_show_collected(trakt_id, 0) g.container_refresh() g.notification( "{}: {}".format(g.ADDON_NAME, g.get_language_string(30286)), g.get_language_string(30291), ) g.trigger_widget_refresh()
def _common_menu_builder(self, trakt_list, content_type, action="getSources", **params): if len(trakt_list) == 0: g.log("We received no titles to build a list", "warning") g.cancel_directory() return smart_play = params.pop("smart_play", False) no_paging = params.pop("no_paging", False) sort = params.pop("sort", False) list_items = [] prepend_date = params.pop("prepend_date", False) mixed_list = params.pop("mixed_list", False) params.pop("hide_unaired", None) params.pop("hide_watched", None) try: params["bulk_add"] = True list_items = [ g.add_directory_item(item.get("name"), action=action, menu_item=item, action_args=item.get("args"), **params) for item in self._post_process_list(trakt_list, prepend_date, mixed_list) if item is not None ] if smart_play: return list_items else: xbmcplugin.addDirectoryItems(g.PLUGIN_HANDLE, list_items, len(list_items)) except Exception as e: g.log_stacktrace() if not smart_play: g.cancel_directory() raise e finally: if not smart_play: if (not (g.FROM_WIDGET and g.get_bool_setting("general.widget.hide_next")) and not no_paging and len(list_items) >= self.page_limit): g.REQUEST_PARAMS["page"] = g.PAGE + 1 params = g.REQUEST_PARAMS params.update({"special_sort": "bottom"}) g.add_directory_item(g.get_language_string(30016), **params) g.close_directory(content_type, sort=sort)
def _check_for_first_run(self, silent, trakt_auth): if ( not silent and str(self.activities["all_activities"]) == self.base_date and trakt_auth is not None ): g.notification(g.ADDON_NAME, g.get_language_string(30177)) # Give the people time to read the damn notification xbmc.sleep(500) self.silent = False self.progress_dialog = xbmcgui.DialogProgressBG() self.progress_dialog.create(g.ADDON_NAME + "Sync", "Seren: Trakt Sync")
def _add_to_list(self, item_information): from resources.lib.modules.metadataHandler import MetadataHandler get = MetadataHandler.get_trakt_info lists = self.trakt_api.get_json("users/me/lists") selection = xbmcgui.Dialog().select( "{}: {}".format(g.ADDON_NAME, g.get_language_string(30296)), [get(i, "name") for i in lists], ) if selection == -1: return selection = lists[selection] self.trakt_api.post_json( "users/me/lists/{}/items".format(selection["trakt_id"]), self._info_to_trakt_object(item_information, True), ) g.notification( "{}: {}".format(g.ADDON_NAME, g.get_language_string(30286)), g.get_language_string(30294).format(get(selection, "name")), ) g.trigger_widget_refresh()
def shows_search_history(): history = SearchHistory().get_search_history("tvshow") g.add_directory_item( g.get_language_string(30204), action="showsSearch", description=g.get_language_string(30405), ) g.add_directory_item( g.get_language_string(30202), action="clearSearchHistory", mediatype="tvshow", is_folder=False, description=g.get_language_string(30202), ) for i in history: g.add_directory_item( i, action="showsSearchResults", action_args=tools.construct_action_args(i), ) g.close_directory(g.CONTENT_FOLDER)
def check_for_updates(self, silent=False, automatic=False): """ Check all packages for updates :param silent: Optional setting to disable user feedback :type silent: bool :param automatic: Optional argument to automatically process updates if available :type automatic: bool :return: None if automatic set to True else returns a list of available updates if set to False :rtype: [None,list] """ # Automatic "True" will update all packages with available updates # Silent "True" will prevent kodi from creating any dialogs except for a single notification if not silent: update_dialog = xbmcgui.DialogProgress() update_dialog.create(g.ADDON_NAME, g.get_language_string(30082)) update_dialog.update(-1) updates = [] update_dialog = None packages = self.known_packages if len(packages) == 0: return [] for package in packages: if not package["remote_meta"]: continue meta_file = requests.get(package["remote_meta"]) if meta_file.status_code != 200: continue meta_file = json.loads(meta_file.text) if not meta_file["name"] == package["pack_name"]: g.log("Pack name check failure - {} : {}".format( meta_file["name"], package["pack_name"])) continue if not tools.compare_version_numbers(package["version"], meta_file["version"]): continue if not automatic: updates.append(meta_file) else: ProviderInstallManager().update(meta_file, silent) if not silent and update_dialog: update_dialog.close() if not automatic: return updates
def get_sources(self, action_args, overwrite_cache=False): """ Method to handle automatic background or foreground scraping :param action_args: action arguments from request uri :param overwrite_cache: Set to true if you wish to overwrite the current cached return value :return: """ item_information = tools.get_item_information(action_args) if not ProviderCache().get_provider_packages(): yesno = xbmcgui.Dialog().yesno(g.ADDON_NAME, g.get_language_string(30465)) if not yesno: return sources = Sources(item_information).get_sources( overwrite_torrent_cache=overwrite_cache) if sources is None or len(sources) <= 0 or len(sources[1]) <= 0: g.cancel_playback() g.notification(g.ADDON_NAME, g.get_language_string(30032), time=5000) return sources
def auth(self): """ Initiates and performs OAuth process :return: None :rtype: None """ data = {"client_id": self.client_id, "response_type": "device_code"} token = self.session.post("https://www.premiumize.me/token", data=data).json() expiry = int(token["expires_in"]) token_ttl = int(token["expires_in"]) interval = int(token["interval"]) poll_again = True success = False tools.copy2clip(token["user_code"]) self.progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30382), tools.create_multiline_message( line1=g.get_language_string(30019).format( g.color_string(token["verification_uri"])), line2=g.get_language_string(30020).format( g.color_string(token["user_code"])), line3=g.get_language_string(30048), ), ) self.progress_dialog.update(100) while poll_again and not token_ttl <= 0 and not self.progress_dialog.iscanceled( ): xbmc.sleep(1000) if token_ttl % interval == 0: poll_again, success = self._poll_token(token["device_code"]) progress_percent = int(float((token_ttl * 100) / expiry)) self.progress_dialog.update(progress_percent) token_ttl -= 1 self.progress_dialog.close() if success: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30021))
def _resolve_item(self, pack_select): if g.get_bool_setting('general.autotrynext') and not pack_select: sources = self.sources[self.position:] else: sources = [self.sources[self.position]] self.stream_link = Resolverhelper().resolve_silent_or_visible(sources, self.item_information, pack_select, overwrite_cache=pack_select) if self.stream_link is None: g.notification(g.ADDON_NAME, g.get_language_string(30033), time=2000) else: self.close()
def test_windows(): g.add_directory_item(g.get_language_string(30498), action='testPlayingNext', is_folder=False, description=g.get_language_string(30425)) g.add_directory_item(g.get_language_string(30499), action='testStillWatching', is_folder=False, description=g.get_language_string(30426)) g.add_directory_item(g.get_language_string(30500), action='testResolverWindow', is_folder=False, description=g.get_language_string(30427)) g.add_directory_item(g.get_language_string(30501), action='testSourceSelectWindow', is_folder=False, description=g.get_language_string(30428)) g.add_directory_item(g.get_language_string(30502), action='testManualCacheWindow', is_folder=False, description=g.get_language_string(30496)) g.close_directory(g.CONTENT_FOLDER)
def auth(self): resp = self.get_json("pin/get", reauth=True) expiry = pin_ttl = int(resp["expires_in"]) auth_complete = False tools.copy2clip(resp["pin"]) self.progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30366), tools.create_multiline_message( line1=g.get_language_string(30019).format( g.color_string(resp["base_url"]) ), line2=g.get_language_string(30020).format(g.color_string(resp["pin"])), line3=g.get_language_string(30048), ), ) # Seems the All Debrid servers need some time do something with the pin before polling # Polling to early will cause an invalid pin error xbmc.sleep(5 * 1000) self.progress_dialog.update(100) while ( not auth_complete and not expiry <= 0 and not self.progress_dialog.iscanceled() ): auth_complete, expiry = self.poll_auth(check=resp["check"], pin=resp["pin"]) progress_percent = 100 - int((float(pin_ttl - expiry) / pin_ttl) * 100) self.progress_dialog.update(progress_percent) xbmc.sleep(1 * 1000) self.progress_dialog.close() self.store_user_info() if auth_complete: xbmcgui.Dialog().ok( g.ADDON_NAME, "AllDebrid {}".format(g.get_language_string(30021)) ) else: return
def auth(self): url = "client_id={}&new_credentials=yes".format(self.client_id) url = self.oauth_url + self.device_code_url.format(url) response = self.session.get(url).json() tools.copy2clip(response["user_code"]) self.progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30018), tools.create_multiline_message( line1=g.get_language_string(30019).format( g.color_string("https://real-debrid.com/device")), line2=g.get_language_string(30020).format( g.color_string(response["user_code"])), line3=g.get_language_string(30048), ), ) self.oauth_timeout = int(response["expires_in"]) token_ttl = int(response["expires_in"]) self.oauth_time_step = int(response["interval"]) self.device_code = response["device_code"] success = False self.progress_dialog.update(100) while (not success and not token_ttl <= 0 and not self.progress_dialog.iscanceled()): xbmc.sleep(1000) if token_ttl % self.oauth_time_step == 0: success = self._auth_loop() progress_percent = int( float((token_ttl * 100) / self.oauth_timeout)) self.progress_dialog.update(progress_percent) token_ttl -= 1 self.progress_dialog.close() if success: self.token_request() user_information = self.get_url("user") if user_information["type"] != "premium": xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30216))
def shows_genres(self): g.add_directory_item(g.get_language_string(30046), action="showGenresGet") genres = self.trakt.get_json_cached("genres/shows", extended="full") if genres is None: g.cancel_directory() return for i in genres: g.add_directory_item( i["name"], action="showGenresGet", action_args=i["slug"] ) g.close_directory(g.CONTENT_GENRES)
def uninstall_package(self, package=None, silent=False): """ Initiate uninstallation of a package, optionally supply package name to automate process :param package: (Optional) name of package to uninstall :type package: basestring :param silent: Opiton to disable user feedback :type silent: bool :return: None :rtype: None """ self.silent = silent package_name = self._get_package_selection( ) if package is None else package if package_name is None: return confirm = xbmcgui.Dialog().yesno( g.ADDON_NAME, g.get_language_string(30050) + " {}".format(package_name)) if confirm == 0: return try: self._remove_package_directories(package_name) self._remove_legacy_meta_file(package_name) self.remove_provider_package(package_name) self.provider_settings.remove_package_settings(package_name) if not silent: xbmcgui.Dialog().ok( g.ADDON_NAME, "{} {}".format(package_name, g.get_language_string(30051)), ) except Exception as e: self._handle_uninstall_failure(package_name) raise e ProvidersServiceManager().stop_package_services(package_name)
def test_windows(): g.add_directory_item(g.get_language_string(30486), action='testPlayingNext', is_folder=False, description=g.get_language_string(30413)) g.add_directory_item(g.get_language_string(30487), action='testStillWatching', is_folder=False, description=g.get_language_string(30414)) g.add_directory_item(g.get_language_string(30488), action='testResolverWindow', is_folder=False, description=g.get_language_string(30415)) g.add_directory_item(g.get_language_string(30489), action='testSourceSelectWindow', is_folder=False, description=g.get_language_string(30416)) g.add_directory_item(g.get_language_string(30490), action='testManualCacheWindow', is_folder=False, description=g.get_language_string(30484)) g.close_directory(g.CONTENT_MENU)
def do_cache(self): yesno = self.prompt_download_style() if yesno: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30504)) self.thread_pool.put(self.status_update_loop) return {"result": "background", "source": None} else: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( g.get_language_string(30335), tools.create_multiline_message( line1="Title: {}".format( g.color_string( self.uncached_source["release_title"].upper())), line2=self._get_progress_string(), ), ) monitor = xbmc.Monitor() while not progress_dialog.iscanceled( ) and not monitor.abortRequested(): xbmc.sleep(5000) self.run_single_status_cycle() progress_dialog.update(int(self.current_percent), self._get_progress_string()) if self.current_percent == 100: progress_dialog.close() break if progress_dialog.iscanceled() and self.current_percent != 100: self._handle_cancellation() self.cancel_process() return {"result": "error", "source": None} else: self.uncached_source["debrid_provider"] = self.debrid_slug return {"result": "success", "source": self.uncached_source}
def display_expiry_notification(display_debrid_name): """ Ease of use method to notify user of expiry of debrid premium status :param display_debrid_name: Debrid providers full display name :type display_debrid_name: str :return: None :rtype: None """ if g.get_bool_setting("general.accountNotifications"): g.notification( "{}".format(g.ADDON_NAME), g.get_language_string(30036).format(display_debrid_name), )
def wipe_install(): """ Destroys newf's user_data folder for current user resetting addon to default :return: None :rtype: None """ confirm = xbmcgui.Dialog().yesno(g.ADDON_NAME, g.get_language_string(30086)) if confirm == 0: return confirm = xbmcgui.Dialog().yesno( g.ADDON_NAME, g.get_language_string(30035) + "{}".format(g.color_string(g.get_language_string(30036))), ) if confirm == 0: return path = tools.validate_path(g.ADDON_USERDATA_PATH) if xbmcvfs.exists(path): xbmcvfs.rmdir(path, True) xbmcvfs.mkdir(g.ADDON_USERDATA_PATH)
def auth(self): """ Performs OAuth with Trakt :return: None """ self.username = None response = self.post("oauth/device/code", data={"client_id": self.client_id}) if not response.ok: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30162)) return try: response = response.json() user_code = response["user_code"] device = response["device_code"] interval = int(response["interval"]) expiry = int(response["expires_in"]) token_ttl = int(response["expires_in"]) except (KeyError, ValueError): xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30023)) raise tools.copy2clip(user_code) failed = False try: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30022), tools.create_multiline_message( line1=g.get_language_string(30018).format( g.color_string("https://trakt.tv/activate")), line2=g.get_language_string(30019).format( g.color_string(user_code)), line3=g.get_language_string(30047), ), ) progress_dialog.update(100) while (not failed and self.username is None and not token_ttl <= 0 and not progress_dialog.iscanceled()): xbmc.sleep(1000) if token_ttl % interval == 0: failed = self._auth_poll(device) progress_percent = int(float((token_ttl * 100) / expiry)) progress_dialog.update(progress_percent) token_ttl -= 1 progress_dialog.close() finally: del progress_dialog if not failed: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30273)) self._sync_trakt_user_data_if_required()
def clear_search_history(self, media_type=None): """ Clears optionall all records for a specific media type or all if not supplied :param media_type: Type of media to restrict clear for :type media_type: str :return: None :rtype: None """ if xbmcgui.Dialog().yesno(g.ADDON_NAME, g.get_language_string(30229)): if media_type is not None: self.execute_sql("DELETE FROM {} where type = ?".format(self.table_name), (media_type,)) g.container_refresh() else: self.execute_sql("DELETE FROM {}".format(self.table_name))
def _mark_watched_dialog(self): if g.get_global_setting("marked_watched_dialog_open"): return if (self.getPlayingFile() and self._running_path and self._running_path != self.getPlayingFile() and self.watched_percentage < self.playCountMinimumPercent and (time.time() - self.playback_timestamp) > 600): xbmc.sleep(10000) g.set_global_setting("marked_watched_dialog_open", True) if xbmcgui.Dialog().yesno(g.ADDON_NAME, g.get_language_string(30526)): self._force_marked_watched = True g.set_global_setting("marked_watched_dialog_open", False)
def _handle_failure(self, reason): if not self.silent: xbmcgui.Dialog().notification( g.ADDON_NAME, g.get_language_string(30485) % self.uncached_source["release_title"], time=5000, ) self.status = "failed" self._update_database() self._delete_transfer() raise GeneralCachingFailure( "Could not create cache for magnet - {} \n Reason: {}" "".format(self.uncached_source["release_title"], reason))
def get_assist_torrents(self): g.add_directory_item(g.get_language_string(30245), action='nonActiveAssistClear') torrent_list = self.torrent_assist.get_assist_torrents() if torrent_list is not None: for i in torrent_list: debrid = tools.shortened_debrid(i['provider']) title = g.color_string('{} - {} - {}% : {}'.format( debrid, i['status'].title(), i['progress'], i['release_title'])) g.add_directory_item(title) g.close_directory(self.view_type)
def handle_action(self, action_id, control_id=None): position = self.list_control.getSelectedPosition() if control_id is None: control_id = self.getFocusId() if action_id == 117 or (action_id == 7 and control_id == 2003): response = xbmcgui.Dialog().contextmenu( [g.get_language_string(30073), g.get_language_string(30495)]) if response == 0 and position > -1: self.manager.cancel_task( self.list_control.getListItem(position).getProperty( 'hash')) if control_id == 2002 and action_id == 7: self.close() if control_id == 2001 and action_id == 7: self.manager.clear_complete() if action_id == 92 or action_id == 10: self.close()
def _mark_watched(self, item_information, silent=False): response = self.trakt_api.post_json( "sync/history", self._info_to_trakt_object(item_information)) if item_information["mediatype"] == "movie": from resources.lib.database.trakt_sync.movies import TraktSyncDatabase if not self._confirm_marked_watched(response, "movies"): return TraktSyncDatabase().mark_movie_watched( item_information["trakt_id"]) else: from resources.lib.database.trakt_sync.shows import TraktSyncDatabase if not self._confirm_marked_watched(response, "episodes"): return if item_information["mediatype"] == "episode": TraktSyncDatabase().mark_episode_watched( item_information["trakt_show_id"], item_information["season"], item_information["episode"], ) elif item_information["mediatype"] == "season": show_id = item_information["trakt_show_id"] season_no = item_information["season"] TraktSyncDatabase().mark_season_watched(show_id, season_no, 1) elif item_information["mediatype"] == "tvshow": TraktSyncDatabase().mark_show_watched( item_information["trakt_id"], 1) g.notification( "{}: {}".format(g.ADDON_NAME, g.get_language_string(30286)), g.get_language_string(30288), ) if not silent: g.container_refresh() g.trigger_widget_refresh()
def resume_show(self): """ Identifies resumse point for a show and plays from there :return: :rtype: """ g.cancel_playback() g.close_all_dialogs() g.PLAYLIST.clear() window = self._get_window() window.set_text(g.get_language_string(30063)) window.show() window.set_text(g.get_language_string(30064)) season_id, episode = self.get_resume_episode() window.set_text(g.get_language_string(30065)) window.set_text(g.get_language_string(30066)) self.build_playlist(season_id, episode) window.set_text(g.get_language_string(30338)) g.log( "Begining play from Season ID {} Episode {}".format( season_id, episode), "info", ) window.close() del window xbmc.Player().play(g.PLAYLIST)
def handle_action(self, action, control_id=None): if action == 7: if control_id == 2001: self.close() elif control_id == 3001: self._configure_package( self.package_list.getSelectedItem().getLabel()) elif control_id == 3002: g.show_busy_dialog() try: self.providers_class.install_package(None) self.packages = self.providerCache.get_provider_packages() self.fill_packages() self.setFocus(self.package_list) finally: g.close_busy_dialog() elif control_id == 1000: self._configure_package( self.package_list.getSelectedItem().getLabel()) elif control_id == 3003: package = self.package_list.getSelectedItem().getLabel() g.show_busy_dialog() try: confirm = xbmcgui.Dialog().yesno( g.ADDON_NAME, g.get_language_string(30293).format(package)) if not confirm: g.close_busy_dialog() return self.providers_class.uninstall_package( package=self.package_list.getSelectedItem().getLabel()) self.packages = self.providerCache.get_provider_packages() self.fill_packages() self.setFocus(self.package_list) finally: g.close_busy_dialog() g.close_busy_dialog() elif control_id == 3004: self.flip_mutliple_providers( 'enabled', self.package_list.getSelectedItem().getLabel()) elif control_id == 3005: self.flip_mutliple_providers( 'disabled', self.package_list.getSelectedItem().getLabel()) else: super(ProviderPackages, self).handle_action(action, control_id)
def update_provider_packages(): """ Perform checks for provider package updates :return: None :rtype: None """ provider_check_stamp = g.get_float_setting("provider.updateCheckTimeStamp", 0) automatic = g.get_bool_setting("providers.autoupdates") if time.time() > (provider_check_stamp + (24 * (60 * 60))): available_updates = ProviderInstallManager().check_for_updates( silent=True, automatic=automatic) if not automatic and len(available_updates) > 0: g.notification(g.ADDON_NAME, g.get_language_string(30278)) g.set_setting("provider.updateCheckTimeStamp", str(time.time()))