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: try: 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(), ), ) while not progress_dialog.iscanceled( ) and not g.abort_requested(): xbmc.sleep(5000) self.run_single_status_cycle() if g.KODI_VERSION >= 19: progress_dialog.update( # pylint: disable=unexpected-keyword-arg int(self.current_percent), message=tools.create_multiline_message( line1="Title: {}".format( g.color_string( self.uncached_source["release_title"]. upper())), line2=self._get_progress_string(), ), ) else: progress_dialog.update( # pylint: disable=unexpected-keyword-arg int(self.current_percent), line2=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 } finally: del progress_dialog
def _post_process(self, item, prepend_date=False, mixed_list=False): if not item: return name = g.decode_py2(item.get("info", {}).get("title")) if not name: g.log("Item has no title: {}".format(item), "error") if (not item["info"]["mediatype"] == "list" and not self.hide_unaired and not self.is_aired(item["info"])): name = g.color_string(tools.italic_string(name), "red") if item["info"]["mediatype"] == "episode": if self.title_appends_mixed and mixed_list: name = self._handle_episode_title_appending( name, item, self.title_appends_mixed) elif self.title_appends_general and not mixed_list: name = self._handle_episode_title_appending( name, item, self.title_appends_general) if item["info"][ "mediatype"] == "list" and self.list_title_appends == "1": name += " - {}".format( g.color_string(g.encode_py2(item["info"]["username"]))) if not item["info"]["mediatype"] == "list" and prepend_date: release_day = tools.parse_datetime(item["info"]["aired"][:10]) if release_day: release_day = release_day.strftime("%d %b") name = "[{}] {}".format(release_day, g.encode_py2(name)) item.update({"name": name}) item["info"]["title"] = name return item
def _get_progress_string(self): return self.progress_message.format( g.color_string(self.status.title()), g.color_string(self.current_percent), g.color_string(self.get_display_speed()), g.color_string(self.seeds), )
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 _install_confirmation(self, pack_name, author, version): if not self.silent: accept = xbmcgui.Dialog().yesno( g.ADDON_NAME + " - {}".format(g.get_language_string(30072)), "{}\n{}\n{}".format(g.color_string(g.get_language_string(30069)) + " {} - v{}".format(pack_name, version), g.color_string(g.get_language_string(30070)) + "{}".format(author), g.get_language_string(30071)), nolabel=g.get_language_string(30073), yeslabel=g.get_language_string(30074), ) if accept == 0: return False return True
def update_properties(self, sources_information): # Set Resolution count properties self.setProperty('4k_sources', g.UNICODE(sources_information["torrents_quality"][0] + sources_information["hosters_quality"][0])) self.setProperty('1080p_sources', g.UNICODE(sources_information["torrents_quality"][1] + sources_information["hosters_quality"][1])) self.setProperty('720p_sources', g.UNICODE(sources_information["torrents_quality"][2] + sources_information["hosters_quality"][2])) self.setProperty('SD_sources', g.UNICODE(sources_information["torrents_quality"][3] + sources_information["hosters_quality"][3])) # Set total source type counts self.setProperty('total_torrents', g.UNICODE(len(sources_information["allTorrents"]))) self.setProperty('cached_torrents', g.UNICODE(len(sources_information["torrentCacheSources"]))) self.setProperty('hosters_sources', g.UNICODE(len(sources_information["hosterSources"]))) self.setProperty('cloud_sources', g.UNICODE(len(sources_information["cloudFiles"]))) self.setProperty('adaptive_sources', g.UNICODE(len(sources_information["adaptiveSources"]))) # Set remaining providers string self.setProperty("remaining_providers_count", g.UNICODE((len(sources_information["remainingProviders"])))) self.setProperty("remaining_providers_list", g.color_string(' | ') .join([i.upper() for i in sources_information["remainingProviders"]])) try: remaining_providers_list = self.getControlList(2000) remaining_providers_list.reset() remaining_providers_list.addItems(sources_information["remainingProviders"]) except Exception: pass
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"]) success = False try: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30017), tools.create_multiline_message( line1=g.get_language_string(30018).format( g.color_string("https://real-debrid.com/device") ), line2=g.get_language_string(30019).format( g.color_string(response["user_code"]) ), line3=g.get_language_string(30047), ), ) 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"] progress_dialog.update(100) while ( not success and not token_ttl <= 0 and not 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)) progress_dialog.update(progress_percent) token_ttl -= 1 progress_dialog.close() finally: del progress_dialog 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(30194))
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"]) try: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30349), tools.create_multiline_message( line1=g.get_language_string(30018).format( g.color_string(token["verification_uri"]) ), line2=g.get_language_string(30019).format( g.color_string(token["user_code"]) ), line3=g.get_language_string(30047), ), ) progress_dialog.update(100) while poll_again and not token_ttl <= 0 and not 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)) progress_dialog.update(progress_percent) token_ttl -= 1 progress_dialog.close() finally: del progress_dialog if success: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30020))
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"]) try: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( g.ADDON_NAME + ": " + g.get_language_string(30334), tools.create_multiline_message( line1=g.get_language_string(30018).format( g.color_string(resp["base_url"]) ), line2=g.get_language_string(30019).format(g.color_string(resp["pin"])), line3=g.get_language_string(30047), ), ) # 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) progress_dialog.update(100) while ( not auth_complete and not expiry <= 0 and not 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) progress_dialog.update(progress_percent) xbmc.sleep(1 * 1000) progress_dialog.close() self.store_user_info() finally: del progress_dialog if auth_complete: xbmcgui.Dialog().ok( g.ADDON_NAME, "AllDebrid {}".format(g.get_language_string(30020)) ) else: return
def _post_process(self, item, prepend_date=False, mixed_list=False): if not item: return if self.show_original_title and item.get("info", {}).get("originaltitle"): name = item.get("info", {}).get("originaltitle") else: name = item.get("info", {}).get("title") if not name: g.log("Item has no title: {}".format(item), "error") if (not item["info"]["mediatype"] == "list" and not self.hide_unaired and not self.is_aired(item)): name = g.color_string(tools.italic_string(name), "red") if item["info"]["mediatype"] == "episode": if self.title_appends_mixed and mixed_list: name = self._handle_episode_title_appending( name, item, self.title_appends_mixed) elif self.title_appends_general and not mixed_list: name = self._handle_episode_title_appending( name, item, self.title_appends_general) if item["info"]["mediatype"] == "list" and self.list_title_appends == 1: name += " - {}".format(g.color_string(item["info"]["username"])) if not item["info"]["mediatype"] == "list" and prepend_date: release_date = g.utc_to_local( item.get("air_date", item["info"].get("aired", None))) if release_date: release_day = tools.parse_datetime( release_date, g.DATE_TIME_FORMAT, date_only=False).strftime("{} @ {}".format( "%a %d %b", g.KODI_TIME_NO_SECONDS_FORMAT)) name = "[{}] {}".format(release_day, name) item.update({"name": name}) item["info"]["title"] = name return item
def list_rd_transfers(self): from resources.lib.debrid import real_debrid transfer_list = real_debrid.RealDebrid().list_torrents() if len(transfer_list) == 0: g.close_directory(self.view_type) return for i in transfer_list: title = '{} - {}% : {}' \ .format(g.color_string(i['status'].title()), g.UNICODE(i['progress']), i['filename'][:50] + "...") g.add_directory_item(title) g.close_directory(self.view_type)
def _handle_episode_title_appending(name, item, title_append_style): if title_append_style == "1": name = "{}x{} {}".format( g.UNICODE(item["info"]["season"]).zfill(2), g.UNICODE(item["info"]["episode"]).zfill(2), name, ) elif title_append_style == "2": name = "{}: {}".format(g.color_string(item["info"]["tvshowtitle"]), name) elif title_append_style == "3": name = "{}: {}x{} {}".format( g.color_string(item["info"]["tvshowtitle"]), g.UNICODE(item["info"]["season"]).zfill(2), g.UNICODE(item["info"]["episode"]).zfill(2), name, ) return name
def list_premiumize_transfers(self): from resources.lib.debrid import premiumize transfer_list = premiumize.Premiumize().list_transfers() if len(transfer_list['transfers'] ) == 0 or 'transfers' not in transfer_list: g.close_directory(self.view_type) return for i in transfer_list['transfers']: title = '{} - {}% : {}' \ .format(g.color_string(i['status'].title()), g.UNICODE(i['progress'] * 100), i['name'][:50] + "...") g.add_directory_item(title) g.close_directory(self.view_type)
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 list_premiumize_transfers(self): from resources.lib.debrid import premiumize transfer_list = premiumize.Premiumize().list_transfers() if len(transfer_list['transfers'] ) == 0 or "transfers" not in transfer_list: g.close_directory(self.view_type) return for i in transfer_list['transfers']: title = "{} - {}% : {}".format( g.color_string(i['status'].title().title()), g.UNICODE(i['progress'] * 100), (i['name'][:50] + "...") if len(i['name']) > 50 else i['name']) g.add_directory_item(title, is_playable=False, is_folder=False) g.close_directory(self.view_type)
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 update_properties(self, source_statistics): # source_statistics = { # "torrents": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "torrentsCached": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "hosters": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "cloudFiles": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "adaptive": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "totals": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "filtered": { # "torrents": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "torrentsCached": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "hosters": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "cloudFiles": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "adaptive": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # "totals": {"4K": 0, "1080p": 0, "720p": 0, "SD": 0, "total": 0}, # }, # "remainingProviders": [] # } try: def set_stats_property(source_type, quality, filtered=False): property = "{}_{}".format(source_type, quality) if filtered: property += "_filtered" stat = source_statistics['filtered'][source_type][quality] else: stat = source_statistics[source_type][quality] self.setProperty(property, g.UNICODE(stat)) source_types = [ "totals", "torrents", "torrentsCached", "hosters", "cloudFiles", "adaptive", ] qualities = ["4K", "1080p", "720p", "SD", "total"] for filtered in [False, True]: for source_type in source_types: for quality in qualities: set_stats_property(source_type, quality, filtered) # Set remaining providers string self.setProperty( "remaining_providers_count", g.UNICODE(len(source_statistics["remainingProviders"])), ) self.setProperty( "remaining_providers_list", g.color_string(' | ').join([ i.upper() for i in source_statistics["remainingProviders"] ]), ) remaining_providers_list = self.getControlList(2000) remaining_providers_list.reset() remaining_providers_list.addItems( source_statistics["remainingProviders"]) except (KeyError, IndexError) as e: g.log('Failed to set window properties, {}'.format(e), 'error')
def get_sources(self, overwrite_torrent_cache=False): """ Main endpoint to initiate scraping process :param overwrite_cache: :return: Returns (uncached_sources, sorted playable sources, items metadata) :rtype: tuple """ try: g.log('Starting Scraping', 'debug') g.log("Timeout: {}".format(self.timeout), 'debug') g.log("Pre-term-enabled: {}".format(g.get_setting("preem.enabled")), 'debug') g.log("Pre-term-limit: {}".format(g.get_setting("preem.limit")), 'debug') g.log("Pre-term-movie-res: {}".format(g.get_setting("preem.movieres")), 'debug') g.log("Pre-term-show-res: {}".format(g.get_setting("preem.tvres")), 'debug') g.log("Pre-term-type: {}".format(g.get_setting("preem.type")), 'debug') g.log("Pre-term-cloud-files: {}".format(g.get_setting("preem.cloudfiles")), 'debug') g.log("Pre-term-adaptive-files: {}".format(g.get_setting("preem.adaptiveSources")), 'debug') self._handle_pre_scrape_modifiers() self._get_imdb_info() if overwrite_torrent_cache: self._clear_local_torrent_results() else: self._check_local_torrent_database() self._update_progress() if self._prem_terminate(): return self._finalise_results() self._init_providers() # Add the users cloud inspection to the threads to be run self.torrent_threads.put(self._user_cloud_inspection) # Load threads for all sources self._create_torrent_threads() self._create_hoster_threads() self._create_adaptive_threads() self.window.create() self.window.set_text(g.get_language_string(30054), self.progress, self.sources_information, self.runtime) self.window.set_property('process_started', 'true') # Keep alive for gui display and threading g.log('Entering Keep Alive', 'info') start_time = time.time() while self.progress < 100 and not g.abort_requested(): g.log('Remaining Providers {}'.format(self.sources_information["remainingProviders"])) if self._prem_terminate() is True or (len(self.sources_information["remainingProviders"]) == 0 and self.runtime > 5): # Give some time for scrapers to initiate break if self.canceled: monkey_requests.PRE_TERM_BLOCK = True break self._update_progress() try: self.window.set_text("4K: {} | 1080: {} | 720: {} | SD: {}".format( g.color_string(self.sources_information["torrents_quality"][0] + self.sources_information["hosters_quality"][0]), g.color_string(self.sources_information["torrents_quality"][1] + self.sources_information["hosters_quality"][1]), g.color_string(self.sources_information["torrents_quality"][2] + self.sources_information["hosters_quality"][2]), g.color_string(self.sources_information["torrents_quality"][3] + self.sources_information["hosters_quality"][3]), ), self.progress, self.sources_information, self.runtime) except (KeyError, IndexError) as e: g.log('Failed to set window text, {}'.format(e), 'error') # Update Progress xbmc.sleep(200) self.runtime = time.time() - start_time self.progress = int(100 - float(1 - (self.runtime / float(self.timeout))) * 100) g.log('Exited Keep Alive', 'info') return self._finalise_results() finally: self.window.close()
def _color_number(number): if int(number) > 0: return g.color_string(number, 'green') else: return g.color_string(number, 'red')