def __init__(self, heading, line1='', line2='', line3='', active=True, countdown=60, interval=5): self.heading = heading self.countdown = countdown self.interval = interval self.line1 = line1 self.line2 = line2 self.line3 = line3 if active: if xbmc.getCondVisibility('Window.IsVisible(progressdialog)'): pd = CustomProgressDialog.ProgressDialog() else: pd = xbmcgui.DialogProgress() if not self.line3: line3 = 'Expires in: %s seconds' % countdown if six.PY2: pd.create(self.heading, line1, line2, line3) else: pd.create(self.heading, line1 + '\n' + line2 + '\n' + line3) pd.update(100) self.pd = pd else: self.pd = None
def _create_dialog(self): dialog = xbmcgui.DialogProgressBG() if self._background else xbmcgui.DialogProgress() dialog.create(self._heading, self._message) self.__percent = 0 return dialog
def _install_widevine_x86(self): """Install Widevine CDM on x86 based architectures.""" cdm_version = self._latest_widevine_version() cdm_os = config.WIDEVINE_OS_MAP[system_os()] cdm_arch = config.WIDEVINE_ARCH_MAP_X86[self._arch()] url = config.WIDEVINE_DOWNLOAD_URL.format(version=cdm_version, os=cdm_os, arch=cdm_arch) downloaded = self._http_download(url) if downloaded: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create(heading=localize(30043), line1=localize(30044)) # Extracting Widevine CDM progress_dialog.update(94, line1=localize(30049)) # Installing Widevine CDM self._unzip(self._ia_cdm_path()) progress_dialog.update(97, line1=localize(30050)) # Finishing self._cleanup() if not self._widevine_eula(): return False if self._has_widevine(): if os.path.lexists(self._widevine_config_path()): os.remove(self._widevine_config_path()) os.rename(os.path.join(self._ia_cdm_path(), config.WIDEVINE_MANIFEST_FILE), self._widevine_config_path()) wv_check = self._check_widevine() if wv_check: progress_dialog.update(100, line1=localize(30051)) # Widevine CDM successfully installed. xbmcgui.Dialog().notification(localize(30037), localize(30051)) # Success! Widevine successfully installed. progress_dialog.close() return wv_check progress_dialog.close() xbmcgui.Dialog().ok(localize(30004), localize(30005)) # An error occurred return False
def add_books_dialog(auto=False): """Try to add a bunch of publications, or enter one manually""" books = 'bh bhs bt cf cl fg fy gt hf hl ia jd jl jr jy kr la lc lfb ll lr lv lvs mb my rj rr th yb10 yb11 ' \ 'yb12 yb13 yb14 yb15 yb16 yb17 yc ypq'.split() if auto or xbmcgui.Dialog().yesno(S.AUTO_SCAN, S.SCAN_QUESTION): progressbar = xbmcgui.DialogProgress() progressbar.create(S.AUTO_SCAN) try: for i in range(len(books)): if progressbar.iscanceled(): break progressbar.update(i * 100 // len(books), S.SCANNING + ' ' + books[i]) try: get_pub_data(PublicationData(pub=books[i], lang=global_language)) except NotFoundError: pass else: xbmcgui.Dialog().ok(S.AUTO_SCAN, S.SCAN_DONE) finally: progressbar.close() else: code = xbmcgui.Dialog().input(S.ENTER_PUB) if code: try: get_pub_data(PublicationData(pub=code, lang=global_language)) xbmcgui.Dialog().ok('', S.PUB_ADDED) except NotFoundError: xbmcgui.Dialog().ok('', S.WRONG_CODE)
def download(url, dest, dp=None): if not dp: dp = xbmcgui.DialogProgress() dp.create(AddonTitle, "Download In Progress", ' ', ' ') dp.update(0) start_time = time.time() urlretrieve(url, dest, lambda nb, bs, fs: _pbhook(dest, nb, bs, fs, dp, start_time))
def export_playlists(self, playlists, filename): path = settings.import_export_path if len(path) == 0: return full_path = os.path.join(path, filename) fd = xbmcvfs.File(full_path, 'w') numItems = 0 progress = xbmcgui.DialogProgress() progress.create(_S(Msg.i30433)) idx = 0 for playlist in playlists: idx = idx + 1 percent = int((idx * 100) / len(playlists)) progress.update(percent, playlist.getLabel(extended=False)) items = self._session.get_playlist_items(playlist=playlist) items = [item for item in items if item.available] if len(items) > 0: numItems = numItems + playlist.numberOfItems fd.write( repr({ 'uuid': playlist.id, 'title': playlist.title, 'description': playlist.description, 'parentFolderId': playlist.parentFolderId, 'parentFolderName': playlist.parentFolderName, 'ids': [item.id for item in items] }) + '\n') fd.close() progress.close() xbmcgui.Dialog().notification(_P('Playlists'), _S(Msg.i30428).format(n=numItems), xbmcgui.NOTIFICATION_INFO)
def language_dialog(pubdata=None, track=None, preselect=None): # type: (PublicationData, int, str) -> None """Show a dialog window with languages :param pubdata: Search available language for this publication, instead of globally (needs track) :param track: Dialog will play this track instead of setting language (needs pubdata) :param preselect: ISO language code to search for and set as global language """ progressbar = xbmcgui.DialogProgress() progressbar.create('', S.LOADING_LANG) progressbar.update(1) try: # Get language data in the form of (lang, name) if pubdata: data = getpubmedialinks_json(pubdata, alllangs=True) # Note: data['languages'] is a dict languages = [(code, data['languages'][code]['name']) for code in data['languages']] # Sort by name (list is provided sorted by code) languages.sort(key=lambda x: x[1]) else: # Note: the list from jw.org is already sorted by ['name'] data = get_json(LANGUAGE_API) if preselect: for l in data['languages']: if l.get('symbol') == preselect: log('autoselecting language: {}'.format(l['langcode'])) set_language_action(l['langcode'], l['name'] + ' / ' + l['vernacularName']) return else: raise StopIteration else: # Note: data['languages'] is a list languages = [(l['langcode'], l['name'] + ' / ' + l['vernacularName']) for l in data['languages']] # Get the languages matching the ones from history and put them first history = addon.getSetting(SettingID.LANG_HIST).split() languages = [l for l in languages if l[0] in history] + languages dialog_strings = [] dialog_actions = [] for code, name in languages: dialog_strings.append(name) if pubdata: request = request_to_self(M.PLAY, pubdata=pubdata, lang=code, track=track) # Opens normally, like from a folder view dialog_actions.append('PlayMedia(' + request + ')') else: request = request_to_self(M.SET_LANG, lang=code, langname=name) # RunPlugin opens in the background dialog_actions.append('RunPlugin(' + request + ')') finally: progressbar.close() selection = xbmcgui.Dialog().select('', dialog_strings) if selection >= 0: xbmc.executebuiltin(dialog_actions[selection])
def DialogProgress_Create(self, *args, **kwargs): dialog = xbmcgui.DialogProgress() self._objects[id(dialog)] = dialog if PLATFORM['kodi'] < 19: dialog.create(*args, **kwargs) else: heading, message = makeMessage(*args, **kwargs) dialog.create(heading, message) return id(dialog)
def __create_dialog(self, line1, line2, line3): if self.background: pd = xbmcgui.DialogProgressBG() msg = line1 + line2 + line3 pd.create(self.heading, msg) else: pd = xbmcgui.DialogProgress() pd.create(self.heading, line1, line2, line3) return pd
def progressDialog(percent=0, control=None, string1='', header=ADDON_NAME): if percent == 0 and control is None: control = xbmcgui.DialogProgress() control.create(header, ADDON_NAME) control.update(percent, string1) if control is not None: if control.iscanceled() or percent >= 100: return control.close() else: control.update(percent, string1) return control
def __init__(self, message='', heading=None, percent=0, background=False): heading = _make_heading(heading) self._background = background if self._background: self._dialog = xbmcgui.DialogProgressBG() else: self._dialog = xbmcgui.DialogProgress() self._dialog.create(heading, *self._get_args(message)) self.update(percent)
def __create_dialog(self, line1, line2, line3): if self.background: pd = xbmcgui.DialogProgressBG() msg = line1 + line2 + line3 pd.create(self.heading, msg) else: if xbmc.getCondVisibility('Window.IsVisible(progressdialog)'): pd = CustomProgressDialog.ProgressDialog() else: pd = xbmcgui.DialogProgress() pd.create(self.heading, line1, line2, line3) return pd
def __init__(self, message, heading=None, percent=0): if message is not None and KODI_VERSION < 19: args = message.split('\n')[:3] while len(args) < 3: args.append(' ') else: args = [message] heading = _make_heading(heading) self._dialog = xbmcgui.DialogProgress() self._dialog.create(heading, *args) self.update(percent)
def root(): tvbus_url = plugin.args.get("url", [""])[-1] if tvbus_url: access_code = plugin.args.get("access_code", [""])[-1] timeout = int(plugin.args.get("timeout", ["90"])[-1]) localport = int(plugin.args.get("localport", [find_free_port()])[-1]) playerport = int(plugin.args.get("playerport", [find_free_port()])[-1]) player_url = "http://127.0.0.1:{0}/mpegts_live".format(playerport) if xbmc.getCondVisibility("system.platform.android"): pass elif xbmc.getCondVisibility("system.platform.linux"): TVBUS_SCRIPT = XBMC_TVBUS_SCRIPT elif xbmc.getCondVisibility("system.platform.windows"): TVBUS_SCRIPT = XBMC_TVBUS_SCRIPT if TVBUS_SCRIPT: LIVE = False xbmc.executebuiltin("RunScript({0},{1},{2},{3},{4},{5})".format( TVBUS_SCRIPT, ADDON_DATA_DIR, tvbus_url, access_code, localport, playerport)) pDialog = xbmcgui.DialogProgress() pDialog.create(plugin.name) session = requests.session() for i in range(timeout): pDialog.update(int(i / float(timeout) * 100)) if pDialog.iscanceled(): break try: _r = session.get(player_url, stream=True, timeout=1) _r.raise_for_status() LIVE = True break except Exception: xbmc.sleep(1000) session.close() pDialog.close() if LIVE: # wait 5 seconds for stream buffer xbmc.sleep(5 * 1000) li = xbmcgui.ListItem(path=player_url) xbmcplugin.setResolvedUrl(plugin.handle, True, li) else: xbmcplugin.setResolvedUrl(plugin.handle, False, xbmcgui.ListItem()) else: li = xbmcgui.ListItem(path=tvbus_url) xbmcplugin.setResolvedUrl(plugin.handle, True, li)
def add_playlist_entries(self, playlist=None, item_ids=[]): ok = False try: ok = TidalUser.add_playlist_entries(self, playlist=playlist, item_ids=item_ids) except: try: progress = xbmcgui.DialogProgress() progress.create(_S(Msg.i30434)) valid_ids = [] idx = 0 notFound = 0 for item_id in item_ids: if progress.iscanceled(): break validItem = None try: validItem = self._session.get_track(item_id) except: pass if not validItem: try: validItem = self._session.get_video(item_id) except: pass idx = idx + 1 percent = int((idx * 100) / len(item_ids)) if validItem: line1 = validItem.getLabel(extended=False) valid_ids.append(item_id) else: line1 = '%s: %s' % (item_id, _S(Msg.i30412)) notFound = notFound + 1 line3 = '%s: %s' % (_S(Msg.i30412), notFound) progress.update(percent, line1=line1, line2=_S(Msg.i30413).format( n=len(valid_ids), m=len(item_ids)), line3=line3) if len(valid_ids) > 0 and not progress.iscanceled(): ok = TidalUser.add_playlist_entries(self, playlist=playlist, item_ids=valid_ids) except: pass finally: progress.close() return ok
def progressDialog(percent=0, control=None, string1='', string2='', string3='', header=ADDON_NAME): if percent == 0 and control is None: control = xbmcgui.DialogProgress() control.create(header, '%s\n%s\%s' % (string1, string2, string3)) control.update(percent, '%s\n%s\%s' % (string1, string2, string3)) if control is not None: if percent == 100 or control.iscanceled(): return control.close() else: control.update(percent, '%s\n%s\%s' % (string1, string2, string3)) return control
def progress(message, heading=None, percent=0): heading = _make_heading(heading) lines = list() for line in message.splitlines(): lines.append(line) dialog = xbmcgui.DialogProgress() dialog.create(heading, *lines) dialog.update(percent) try: yield dialog finally: dialog.close()
def downloadAPK(self, url, dest): if self.fileExists(dest): return self.installAPK(dest) start_time = time.time() dia = xbmcgui.DialogProgress() fle = dest.rsplit('/', 1)[1] dia.create(ADDON_NAME, LANGUAGE(30002) % fle) try: urllib.request.urlretrieve( url.rstrip('/'), dest, lambda nb, bs, fs: self.pbhook( nb, bs, fs, dia, start_time, fle)) except Exception as e: dia.close() xbmcgui.Dialog().notification(ADDON_NAME, LANGUAGE(30001), ICON, 4000) log("downloadAPK, Failed! (%s) %s" % (url, str(e)), xbmc.LOGERROR) return self.deleleAPK(dest) dia.close() return self.installAPK(dest)
def _install_widevine_x86(self): """Install Widevine CDM on x86 based architectures.""" cdm_version = self._latest_widevine_version() cdm_os = config.WIDEVINE_OS_MAP[system_os()] cdm_arch = config.WIDEVINE_ARCH_MAP_X86[self._arch()] self._url = config.WIDEVINE_DOWNLOAD_URL.format(version=cdm_version, os=cdm_os, arch=cdm_arch) downloaded = self._http_download() if downloaded: progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( heading=LANGUAGE(30043), line1=LANGUAGE(30044)) # Extracting Widevine CDM self._unzip(self._addon_cdm_path()) if not self._widevine_eula(): self._cleanup() return False self._install_cdm() self._cleanup() if self._has_widevine(): if os.path.lexists(self._widevine_config_path()): os.remove(self._widevine_config_path()) os.rename( os.path.join(self._addon_cdm_path(), config.WIDEVINE_MANIFEST_FILE), self._widevine_config_path()) wv_check = self._check_widevine() if wv_check: xbmcgui.Dialog().notification( LANGUAGE(30037), LANGUAGE(30003)) # Widevine successfully installed progress_dialog.close() return wv_check progress_dialog.close() xbmcgui.Dialog().ok(LANGUAGE(30004), LANGUAGE(30005)) # An error occurred return False
def _http_download(self, message=None): """Makes HTTP request and displays a progress dialog on download.""" log('Request URL: {0}'.format(self._url)) filename = self._url.split('/')[-1] try: req = urlopen(self._url) log('Response code: {0}'.format(req.getcode())) if 400 <= req.getcode() < 600: raise HTTPError('HTTP %s Error for url: %s' % (req.getcode(), self._url), response=req) except HTTPError: xbmcgui.Dialog().ok( LANGUAGE(30004), LANGUAGE(30013).format(filename)) # Failed to retrieve file return False if not message: # display "downloading [filename]" message = LANGUAGE(30015).format(filename) # Downloading file self._download_path = os.path.join(self._temp_path(), filename) total_length = float(req.info().get('content-length')) progress_dialog = xbmcgui.DialogProgress() progress_dialog.create(LANGUAGE(30014), message) # Download in progress chunk_size = 32 * 1024 with open(self._download_path, 'wb') as f: dl = 0 while True: chunk = req.read(chunk_size) if not chunk: break f.write(chunk) dl += len(chunk) percent = int(dl * 100 / total_length) if progress_dialog.iscanceled(): progress_dialog.close() req.close() return False progress_dialog.update(percent) progress_dialog.close() return True
def __init__(self, heading, line1='', line2='', line3='', active=True, countdown=60, interval=5): self.heading = heading self.countdown = countdown self.interval = interval self.line3 = line3 if active: pd = xbmcgui.DialogProgress() if not self.line3: line3 = 'Expires in: %s seconds' % countdown pd.create(self.heading, line1, line2, line3) pd.update(100) self.pd = pd
def onInit(self): p = xbmcgui.DialogProgress() p.create( common.get_localized_string(32000), # 'Transmission' common.get_localized_string(32001)) # 'Connecting to Transmission' try: self.transmission = common.get_rpc_client() except: p.close() self.close() (type, e, traceback) = sys.exc_info() message = common.get_localized_string(32900) # Unexpected error if type is transmissionrpc.TransmissionError: if e.original: if e.original.code is 401: message = common.get_localized_string( 32902) # Invalid auth else: message = common.get_localized_string( 32901) # Unable to connect if xbmcgui.Dialog().yesno( common.get_localized_string(32002), message + '\n' + common.get_localized_string(32003)): common.open_settings() elif type is ValueError: # In python 2.4, urllib2.HTTPDigestAuthHandler will barf up a lung # if auth fails and the server wants non-digest authentication message = common.get_localized_string(32902) # Invalid auth if xbmcgui.Dialog().yesno( common.get_localized_string(32002), message + '\n' + common.get_localized_string(32003)): common.open_settings() else: message = common.get_localized_string( 32900) # Unexpected error xbmcgui.Dialog().ok(common.get_localized_string(32002), message) return False self.updateTorrents() p.close() self.timer = threading.Timer(UPDATE_INTERVAL, self.updateTorrents) self.timer.start()
def delete_all(self, what, action, remove): try: ok = False progress = xbmcgui.DialogProgress() progress.create(_S(Msg.i30430).format(what=_P(what))) idx = 0 items = action() for item in items: if progress.iscanceled(): break idx = idx + 1 percent = int((idx * 100) / len(items)) progress.update(percent, item.getLabel(extended=False)) remove(item.id) ok = not progress.iscanceled() except Exception as e: log.logException(e) finally: progress.close() return ok
def update_translations(lang): """Download a jw.org web page and save some extracted strings to cache""" # If there are any translations for the current language in the cache, do nothing if any(cache.trans.select(TranslationData(lang=lang))): return progressbar = xbmcgui.DialogProgress() progressbar.create('', S.TRANS_UPDATE) progressbar.update(50) try: url = '{}?docid={}&wtlocale={}'.format(FINDER_API, DOCID_MAGAZINES, lang) log('scrapping translations from ' + url) # urlopen returns bytes # Set high timeout, because AWS blocks requests from urllib for a while response = urlopen(url, timeout=30).read().decode('utf-8') translations = JwOrgParser.parse(response) for key, value in translations.items(): cache.trans.delete(TranslationData(key=key, lang=lang)) cache.trans.insert(TranslationData(key=key, string=value, lang=lang)) finally: progressbar.close()
def _http_request(self, download=False, message=None): """Makes HTTP request and displays a progress dialog on download.""" self._log('Request URL: {0}'.format(self._url)) filename = self._url.split('/')[-1] dialog = xbmcgui.Dialog() try: req = requests.get(self._url, stream=download) self._log('Response code: {0}'.format(req.status_code)) if not download: self._log('Response: {0}'.format(req.content)) req.raise_for_status() except requests.exceptions.HTTPError: dialog.ok(LANGUAGE(30004), LANGUAGE(30013).format(filename)) return False if download: if not message: # display "downloading [filename]" message = LANGUAGE(30015).format(filename) self._download_path = os.path.join(self._temp_path(), filename) total_length = float(req.headers.get('content-length')) progress_dialog = xbmcgui.DialogProgress() progress_dialog.create(LANGUAGE(30014), message) with open(self._download_path, 'wb') as f: dl = 0 for chunk in req.iter_content(chunk_size=1024): f.write(chunk) dl += len(chunk) percent = int(dl * 100 / total_length) if progress_dialog.iscanceled(): progress_dialog.close() req.close() return False progress_dialog.update(percent) progress_dialog.close() return True else: return req.text
def rbt_main(): # WIN = xbmcgui.Window(10000) # WIN.clearProperty('rbt.script_started') # if not WIN.getProperty('rbt.script_started'): xbmc.log(msg='Retro BIOS Tool: Tool Started', level=xbmc.LOGINFO) # WIN.setProperty('rbt.script_started','True') addon_name = 'plugin.program.retrobiostool' addon_handle = xbmcaddon.Addon(id='%(addon_name)s' % {'addon_name': addon_name}) bios_folder = addon_handle.getSetting(id='rbt_folder') if addon_handle.getSetting(id='rbt_generate_report') == 'true': generate_report = True else: generate_report = False addon_timeout = 5 bios_keyword = [ 'firmware%(number)s_path' % { 'number': x } for x in range(0, 21) ] libretro_git = r'https://raw.githubusercontent.com/libretro/libretro-super/master/dist/info/xxx_core_xxx.info' #These games are already known to not require any system/bios files, so skip them to make the tool faster ignore_these_addons = [ 'game.libretro', 'game.libretro.2048', 'game.libretro.2048_libretro_buildbot', 'game.libretro.81', 'game.libretro.81_libretro_buildbot', 'game.libretro.beetle-bsnes', 'game.libretro.beetle-bsnes_libretro_buildbot', 'game.libretro.beetle-bsnes_cplusplus98', 'game.libretro.beetle-bsnes_cplusplus98_libretro_buildbot', 'game.libretro.beetle-ngp', 'game.libretro.beetle-ngp_libretro_buildbot', 'game.libretro.beetle-vb', 'game.libretro.beetle-vb_libretro_buildbot', 'game.libretro.beetle-wswan', 'game.libretro.beetle-wswan_libretro_buildbot', 'game.libretro.bnes', 'game.libretro.bnes_libretro_buildbot', 'game.libretro.cannonball', 'game.libretro.cannonball_libretro_buildbot', 'game.libretro.cap32', 'game.libretro.cap32_libretro_buildbot', 'game.libretro.chailove', 'game.libretro.chailove_libretro_buildbot', 'game.libretro.craft', 'game.libretro.craft_libretro_buildbot', 'game.libretro.crocods', 'game.libretro.crocods_libretro_buildbot', 'game.libretro.daphne', 'game.libretro.daphne_libretro_buildbot', 'game.libretro.dinothawr', 'game.libretro.dinothawr_libretro_buildbot', 'game.libretro.dosbox', 'game.libretro.dosbox_libretro_buildbot', 'game.libretro.dosbox_svn', 'game.libretro.dosbox_svn_libretro_buildbot', 'game.libretro.easyrpg', 'game.libretro.easyrpg_libretro_buildbot', 'game.libretro.emux_nes', 'game.libretro.emux_nes_libretro_buildbot', 'game.libretro.fbalpha', 'game.libretro.fbalpha2012', 'game.libretro.fbalpha2012_libretro_buildbot', 'game.libretro.fbalpha2012_cps1', 'game.libretro.fbalpha2012_cps1_libretro_buildbot', 'game.libretro.fbalpha2012_cps2', 'game.libretro.fbalpha2012_cps2_libretro_buildbot', 'game.libretro.fbalpha2012_neogeo', 'game.libretro.fbalpha2012_neogeo_libretro_buildbot', 'game.libretro.fbalpha_libretro_buildbot', 'game.libretro.fuse', 'game.libretro.fuse_libretro_buildbot', 'game.libretro.gearboy', 'game.libretro.gearboy_libretro_buildbot', 'game.libretro.gearsystem', 'game.libretro.gearsystem_libretro_buildbot', 'game.libretro.gme', 'game.libretro.gme_libretro_buildbot', 'game.libretro.gw', 'game.libretro.gw_libretro_buildbot', 'game.libretro.lutro', 'game.libretro.lutro_libretro_buildbot', 'game.libretro.mednafen_ngp', 'game.libretro.mednafen_ngp_libretro_buildbot', 'game.libretro.mednafen_snes', 'game.libretro.mednafen_snes_libretro_buildbot', 'game.libretro.mednafen_vb', 'game.libretro.mednafen_vb_libretro_buildbot', 'game.libretro.mednafen_wswan', 'game.libretro.mednafen_wswan_libretro_buildbot', 'game.libretro.meteor', 'game.libretro.meteor_libretro_buildbot', 'game.libretro.mrboom', 'game.libretro.mrboom_libretro_buildbot', 'game.libretro.nekop2', 'game.libretro.nekop2_libretro_buildbot', 'game.libretro.nx', 'game.libretro.nx_libretro_buildbot', 'game.libretro.nxengine', 'game.libretro.nxengine_libretro_buildbot', 'game.libretro.openlara', 'game.libretro.openlara_libretro_buildbot', 'game.libretro.pocketcdg', 'game.libretro.pocketcdg_libretro_buildbot', 'game.libretro.prboom', 'game.libretro.prboom_libretro_buildbot', 'game.libretro.quicknes', 'game.libretro.quicknes_libretro_buildbot', 'game.libretro.reminiscence', 'game.libretro.reminiscence_libretro_buildbot', 'game.libretro.scummvm', 'game.libretro.scummvm_libretro_buildbot', 'game.libretro.snes9x2002', 'game.libretro.snes9x2002_libretro_buildbot', 'game.libretro.snes9x2005', 'game.libretro.snes9x2005_libretro_buildbot', 'game.libretro.snes9x2005_plus', 'game.libretro.snes9x2005_plus_libretro_buildbot', 'game.libretro.snes9x2010', 'game.libretro.snes9x2010_libretro_buildbot', 'game.libretro.stella', 'game.libretro.stella2014', 'game.libretro.stella2014_libretro_buildbot', 'game.libretro.stella_libretro_buildbot', 'game.libretro.tgbdual', 'game.libretro.tgbdual_libretro_buildbot', 'game.libretro.theodore', 'game.libretro.theodore_libretro_buildbot', 'game.libretro.thepowdertoy', 'game.libretro.thepowdertoy_libretro_buildbot', 'game.libretro.tyrquake', 'game.libretro.tyrquake_libretro_buildbot', 'game.libretro.vecx', 'game.libretro.vecx_libretro_buildbot', 'game.libretro.vice_x128', 'game.libretro.vice_x128_libretro_buildbot', 'game.libretro.vice_x64', 'game.libretro.vice_x64_libretro_buildbot', 'game.libretro.vice_x64sc', 'game.libretro.vice_x64sc_libretro_buildbot', 'game.libretro.vice_xplus4', 'game.libretro.vice_xplus4_libretro_buildbot', 'game.libretro.vice_xvic', 'game.libretro.vice_xvic_libretro_buildbot', 'game.libretro.virtualjaguar', 'game.libretro.virtualjaguar_libretro_buildbot', 'game.libretro.xrick', 'game.libretro.xrick_libretro_buildbot' ] #Rename the following addons to match libretro naming retroplayer_to_libretro_map = { 'bsnes-mercury-accuracy': 'bsnes_mercury_accuracy', 'bsnes-mercury-balanced': 'bsnes_mercury_balanced', 'bsnes-mercury-performance': 'bsnes_mercury_performance', 'genplus': 'genesis_plus_gx', 'beetle-gba': 'mednafen_gba', 'beetle-lynx': 'mednafen_lynx', 'beetle-ngp': 'mednafen_ngp', 'beetle-pce-fast': 'mednafen_pce_fast', 'beetle-pcfx': 'mednafen_pcfx', 'beetle-psx': 'mednafen_psx', 'beetle-saturn': 'mednafen_saturn', 'beetle-bsnes': 'mednafen_snes', 'beetle-supergrafx': 'mednafen_supergrafx', 'beetle-vb': 'mednafen_vb', 'beetle-wswan': 'mednafen_wswan', 'pcsx-rearmed': 'pcsx_rearmed', 'uae': 'puae', 'vba-next': 'vba_next', 'vice': 'vice_x64' } #These special cases have folders listed in their info files rather than all the individual files, need to copy the entire folder special_folder_cases_map = { 'game.libretro.bluemsx': ['Databases', 'Machines'], 'game.libretro.bluemsx_libretro_buildbot': ['Databases', 'Machines'], 'game.libretro.reicast': ['dc'], 'game.libretro.dolphin_libretro_buildbot': ['dolphin-emu'], 'game.libretro.dolphin': ['dolphin-emu'], 'game.libretro.mame': ['mame'], 'game.libretro.mame_libretro_buildbot': ['mame'], 'game.libretro.mame2000': ['mame2000'], 'game.libretro.mame2000_libretro_buildbot': ['mame2000'], 'game.libretro.mame2003': ['mame2003'], 'game.libretro.mame2003_libretro_buildbot': ['mame2003'], 'game.libretro.mame2003_plus': ['mame2003-plus'], 'game.libretro.mame2003_plus_libretro_buildbot': ['mame2003-plus'], 'game.libretro.mame2010': ['mame2010'], 'game.libretro.mame2010_libretro_buildbot': ['mame2010'], 'game.libretro.mame2014': ['mame2014'], 'game.libretro.mame2014_libretro_buildbot': ['mame2014'], 'game.libretro.mame2015': ['mame2015'], 'game.libretro.mame2015_libretro_buildbot': ['mame2015'], 'game.libretro.mess2015': ['mess2015'], 'game.libretro.mess2015_libretro_buildbot': ['mess2015'], 'game.libretro.ppsspp': ['PPSSPP'], 'game.libretro.ppsspp_libretro_buildbot': ['PPSSPP'], 'game.libretro.puae': ['uae_data'], 'game.libretro.puae_libretro_buildbot': ['uae_data'], 'game.libretro.ume2014': ['ume2014'], 'game.libretro.ume2014_libretro_buildbot': ['ume2014'], } #Initialize report dict report_data = dict() report_data['addon_id'] = list() report_data['firmware_listed'] = list() report_data['firmware_files'] = list() report_data['firmware_found'] = list() report_data['info_file'] = list() if bios_folder is None or len(bios_folder) < 1: current_dialog = xbmcgui.Dialog() ret = current_dialog.ok( 'Retro BIOS Tool', 'The tool did not run.[CR]Enter a BIOS file location in settings first!' ) else: try: addons_available = xbmc.executeJSONRPC( '{ "jsonrpc": "2.0", "method": "Addons.GetAddons","params":{"type":"kodi.gameclient", "enabled": true}, "id": "1"}' ) addon_ids = [ x.get('addonid') for x in json.loads(addons_available).get( 'result').get('addons') if x.get('type') == 'kodi.gameclient' and x.get('addonid') not in ignore_these_addons ] xbmc.log( msg= 'Retro BIOS Tool: The following addons will be checked %(current_aids)s' % {'current_aids': ', '.join(addon_ids)}, level=xbmc.LOGDEBUG) except: addon_ids = None if addon_ids is not None: total_files_copied = 0 dp = xbmcgui.DialogProgress() dp.create('Retro BIOS Tools', 'Checking for BIOS Files') dp.update(0) s = requests.Session() for iiaid, aid in enumerate(addon_ids): dp.update(int(100 * (iiaid + 1) / len(addon_ids))) xbmc.log( msg='Retro BIOS Tool: Checking addon %(current_aid)s' % {'current_aid': aid}, level=xbmc.LOGINFO) report_data['addon_id'].append(aid) report_data['firmware_listed'].append(False) report_data['firmware_files'].append(None) report_data['firmware_found'].append(None) report_data['info_file'].append('') if dp.iscanceled(): run_was_cancelled = True dp.close() raise if aid.replace('game.libretro.', '').replace( '_libretro_buildbot', '') in retroplayer_to_libretro_map.keys(): current_git_url = libretro_git.replace( 'xxx_core_xxx', retroplayer_to_libretro_map[aid.replace( 'game.libretro.', '').replace( '_libretro_buildbot', '')] + '_libretro') else: current_git_url = libretro_git.replace( 'xxx_core_xxx', aid.replace('game.libretro.', '').replace( '_libretro_buildbot', '') + '_libretro') xbmc.log( msg= 'Retro BIOS Tool: Checking libretro for core info at %(current_git_url)s' % {'current_git_url': current_git_url}, level=xbmc.LOGDEBUG) try: r = s.get(current_git_url, verify=False, stream=True, timeout=addon_timeout) except Exception as current_exc: xbmc.log( msg= 'Retro BIOS Tool: Error getting libretro for core info at %(current_exc)s' % {'current_exc': current_exc}, level=xbmc.LOGDEBUG) current_info = r.text if len(current_info) > 0: report_data['info_file'][-1] = current_info current_bios_files = list() for bk in bios_keyword: current_check = re.findall( r'%(current_bk)s\s+=\s+\"(.*?)\"' % {'current_bk': bk}, current_info) if current_check is not None and len(current_check) > 0: current_bios_files.append(current_check[0].strip()) if len(current_bios_files) > 0: report_data['firmware_listed'][-1] = True if type(current_bios_files) is list: report_data['firmware_files'][-1] = current_bios_files report_data['firmware_found'][-1] = [ False for x in current_bios_files ] else: report_data['firmware_files'][-1] = [ current_bios_files ] report_data['firmware_found'][-1] = [False] xbmc.log( msg= 'Retro BIOS Tool: Looking for the following bios files %(current_files)s' % {'current_files': ', '.join(current_bios_files)}, level=xbmc.LOGDEBUG) current_addon = xbmcaddon.Addon(id='%(addon_name)s' % {'addon_name': aid}) current_addon_data_folder = py2_decode( xbmc.translatePath( current_addon.getAddonInfo('profile'))) current_addon_resources_folder = os.path.join( current_addon_data_folder, 'resources') current_addon_systems_folder = os.path.join( current_addon_resources_folder, 'system') for cbf in current_bios_files: current_bios_fullpath = os.path.join( bios_folder, *os.path.split(cbf)) if xbmcvfs.exists(current_bios_fullpath): xbmc.log( msg= 'Retro BIOS Tool: Found file %(current_cbf)s' % {'current_cbf': cbf}, level=xbmc.LOGDEBUG) if not xbmcvfs.exists( os.path.join(current_addon_data_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_data_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join(current_addon_data_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join( current_addon_resources_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_resources_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join( current_addon_resources_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data resources folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join(current_addon_systems_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_systems_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join( current_addon_systems_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data resources/system folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join(current_addon_systems_folder, cbf)): if xbmcvfs.copy( os.path.join(bios_folder, cbf), os.path.join( current_addon_systems_folder, cbf) ): #Copy the file to the correct system folder xbmc.log( msg= 'Retro BIOS Tool: Copying file %(current_cbf)s to %(current_folder)s' % { 'current_cbf': os.path.join(bios_folder, cbf), 'current_folder': os.path.join( current_addon_systems_folder, cbf) }, level=xbmc.LOGINFO) total_files_copied = total_files_copied + 1 report_data['firmware_found'][-1][ report_data['firmware_files'] [-1].index(cbf)] = True else: xbmc.log( msg= 'Retro BIOS Tool: Error copying file %(current_cbf)s to %(current_folder)s' % { 'current_cbf': os.path.join(bios_folder, cbf), 'current_folder': os.path.join( current_addon_systems_folder, cbf) }, level=xbmc.LOGERROR) else: xbmc.log( msg= 'Retro BIOS Tool: BIOS file %(current_cbf)s already present in %(current_folder)s' % { 'current_cbf': cbf, 'current_folder': os.path.join( current_addon_systems_folder, cbf) }, level=xbmc.LOGDEBUG) report_data['firmware_found'][-1][report_data[ 'firmware_files'][-1].index(cbf)] = True else: if xbmcvfs.exists( os.path.join(current_addon_systems_folder, cbf)): report_data['firmware_found'][-1][report_data[ 'firmware_files'][-1].index(cbf)] = True else: report_data['firmware_found'][-1][report_data[ 'firmware_files'][-1].index(cbf)] = False xbmc.log( msg= 'Retro BIOS Tool: Unable to find the file in your BIOS folder %(current_cbf)s ' % { 'current_cbf': os.path.join( bios_folder, cbf) }, level=xbmc.LOGERROR) else: xbmc.log( msg= 'Retro BIOS Tool: No bios files found for %(current_aid)s' % {'current_aid': aid}, level=xbmc.LOGDEBUG) report_data['firmware_listed'][-1] = False #Check folder specific cases if aid in special_folder_cases_map.keys(): current_addon = xbmcaddon.Addon(id='%(addon_name)s' % {'addon_name': aid}) current_addon_data_folder = py2_decode( xbmc.translatePath( current_addon.getAddonInfo('profile'))) current_addon_resources_folder = os.path.join( current_addon_data_folder, 'resources') current_addon_systems_folder = os.path.join( current_addon_resources_folder, 'system') current_bios_folder_fullpaths = [ os.path.join(bios_folder, x) for x in special_folder_cases_map[aid] ] current_ind_folders = [ x for x in special_folder_cases_map[aid] ] for cbfi, current_bios_folder_fullpath in enumerate( current_bios_folder_fullpaths): report_data['firmware_listed'][-1] = True report_data['firmware_files'][-1] = [ ', '.join([ x + ' (Folder)' for x in special_folder_cases_map[aid] ]) ] report_data['firmware_found'][-1] = [False] xbmc.log( msg= 'Retro BIOS Tool: Looking for the following bios folder %(current_folder)s' % {'current_folder': current_ind_folders[cbfi]}, level=xbmc.LOGDEBUG) if xbmcvfs.exists( os.path.join(current_bios_folder_fullpath, '')): if not xbmcvfs.exists( os.path.join(current_addon_data_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_data_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join(current_addon_data_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join( current_addon_resources_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_resources_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join( current_addon_resources_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data resources folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join(current_addon_systems_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: The folder %(current_folder)s does not yet exist, so it will be created' % { 'current_folder': current_addon_systems_folder }, level=xbmc.LOGDEBUG) if not xbmcvfs.mkdir( os.path.join( current_addon_systems_folder, '')): xbmc.log( msg= 'Retro BIOS Tool: Unable to create addon_data resources/system folder', level=xbmc.LOGERROR) if not xbmcvfs.exists( os.path.join(current_addon_systems_folder, current_ind_folders[cbfi], '')): copied_folder_files, folder_copy_success = copy_directory_contents_xbmcvfs( current_bios_folder_fullpath, os.path.join(current_addon_systems_folder, current_ind_folders[cbfi])) if folder_copy_success: xbmc.log( msg= 'Retro BIOS Tool: Successfully copied the BIOS folder %(current_folder)s ' % { 'current_folder': os.path.join( bios_folder, current_ind_folders[cbfi]) }, level=xbmc.LOGDEBUG) report_data['firmware_found'][-1] = [True] total_files_copied = total_files_copied + 1 else: xbmc.log( msg= 'Retro BIOS Tool: The BIOS folder %(current_folder)s was found but could not be copied' % { 'current_folder': os.path.join( bios_folder, current_ind_folders[cbfi]) }, level=xbmc.LOGERROR) report_data['firmware_found'][-1] = [False] else: xbmc.log( msg= 'Retro BIOS Tool: The BIOS folder %(current_folder)s is already present' % { 'current_folder': os.path.join( current_addon_systems_folder, current_ind_folders[cbfi]) }, level=xbmc.LOGDEBUG) report_data['firmware_found'][-1] = [True] else: if xbmcvfs.exists( os.path.join(current_addon_systems_folder, current_ind_folders[cbfi], '')): report_data['firmware_found'][-1] = [True] xbmc.log( msg= 'Retro BIOS Tool: The BIOS folder is already present in your addon folder %(current_folder)s ' % { 'current_folder': os.path.join( current_addon_systems_folder, current_ind_folders[cbfi]) }, level=xbmc.LOGDEBUG) else: report_data['firmware_found'][-1] = [False] xbmc.log( msg= 'Retro BIOS Tool: Unable to find the folder in your BIOS folder %(current_folder)s ' % { 'current_folder': os.path.join( current_addon_systems_folder, current_ind_folders[cbfi]) }, level=xbmc.LOGDEBUG) dp.close() current_dialog = xbmcgui.Dialog() if total_files_copied > 0: ok_ret = current_dialog.ok( 'Completed', 'Tool copied %(total_files_copied)s total files.' % {'total_files_copied': total_files_copied}) else: ok_ret = current_dialog.ok( 'Completed', 'Tool did not copy any files' % {'total_files_copied': total_files_copied}) if generate_report: xbmc.log(msg='Retro BIOS Tool: Report Generated', level=xbmc.LOGDEBUG) xbmcplugin.addDirectoryItem( plugin_handle.handle, '', xbmcgui.ListItem( 'Retro BIOS Tool Report ([COLOR green]green=present[/COLOR], [COLOR red]red=missing[/COLOR]): ', offscreen=True)) for iiaid, aid in enumerate(report_data['addon_id']): report_item = 'Addon: %(current_addon_id)s, BIOS Listed: %(current_firmware_listed)s, ' % { 'current_addon_id': aid, 'current_firmware_listed': report_data['firmware_listed'][iiaid] } if report_data['firmware_listed'][iiaid]: report_subitem = 'Files: ' for icff, cff in enumerate( report_data['firmware_files'][iiaid]): if report_data['firmware_found'][iiaid][icff]: report_subitem = report_subitem + '[COLOR green]%(current_ff)s[/COLOR], ' % { 'current_ff': cff } else: report_subitem = report_subitem + '[COLOR red]%(current_ff)s[/COLOR], ' % { 'current_ff': cff } report_item = report_item + report_subitem if report_item.endswith(', '): report_item = report_item[:-2] li = xbmcgui.ListItem(report_item, offscreen=True) li.setInfo('video', { 'plot': report_subitem + '[CR]' + report_data['info_file'][iiaid] }) if xbmcvfs.exists( xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'icon.png'))): li.setArt({ 'icon': xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'icon.png')) }) elif xbmcvfs.exists( xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'resources', 'icon.png'))): li.setArt({ 'icon': xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'resources', 'icon.png')) }) elif xbmcvfs.exists( xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'icon.jpg'))): li.setArt({ 'icon': xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'icon.jpg')) }) elif xbmcvfs.exists( xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'resources', 'icon.jpg'))): li.setArt({ 'icon': xbmc.translatePath( os.path.join('special://home', 'addons', str(aid), 'resources', 'icon.jpg')) }) else: xbmc.log( msg='Retro BIOS Tool: No icon found for %(current_aid)s' % {'current_aid': aid}, level=xbmc.LOGDEBUG) xbmcplugin.addDirectoryItem(plugin_handle.handle, '', li) xbmcplugin.endOfDirectory(plugin_handle.handle) else: xbmc.log(msg='Retro BIOS Tool: Report Skipped', level=xbmc.LOGDEBUG) # WIN.clearProperty('rbt.script_started') xbmc.log(msg='Retro BIOS Tool: Tool completed', level=xbmc.LOGINFO)
def root(): sop_url = plugin.args.get("url", [""])[-1] if sop_url: timeout = int(plugin.args.get("timeout", ["90"])[-1]) localport = int(plugin.args.get("localport", [find_free_port()])[-1]) playerport = int(plugin.args.get("playerport", [find_free_port()])[-1]) player_url = "http://127.0.0.1:{0}".format(playerport) # Linux, Android <=4.4: run sopcast binary # Windows: Run docker sopcast container # Other: External player if xbmc.getCondVisibility("system.platform.android"): OS_VERSION = xbmc.getInfoLabel("System.OSVersionInfo") API_LEVEL = int(re.search("API level (\d+)", OS_VERSION).group(1)) if API_LEVEL < 20: SOP_SCRIPT = XBMC_SOP_SCRIPT else: APKS = [ "org.sopcast.android", "com.devaward.soptohttp", "com.trimarts.soptohttp" ] for EXTERNAL_SOP in APKS: if os.path.exists( os.path.join("/data", "data", EXTERNAL_SOP)): SOP_ACTIVITY = """XBMC.StartAndroidActivity("{0}","android.intent.action.VIEW","",{1})""".format( EXTERNAL_SOP, url) break xbmc.executebuiltin(SOP_ACTIVITY) elif xbmc.getCondVisibility("system.platform.linux"): SOP_SCRIPT = XBMC_SOP_SCRIPT elif xbmc.getCondVisibility("system.platform.windows"): SOP_SCRIPT = XBMC_SOP_SCRIPT if SOP_SCRIPT: LIVE = False xbmc.executebuiltin("RunScript({0},{1},{2},{3},{4})".format( SOP_SCRIPT, ADDON_DATA_DIR, sop_url, localport, playerport)) pDialog = xbmcgui.DialogProgress() pDialog.create(plugin.name) session = requests.session() for i in range(timeout): pDialog.update(int(i / float(timeout) * 100)) if pDialog.iscanceled(): break try: _r = session.get(player_url, stream=True, timeout=1) _r.raise_for_status() LIVE = True break except Exception: xbmc.sleep(1000) session.close() pDialog.close() if LIVE: li = xbmcgui.ListItem(path=player_url) xbmcplugin.setResolvedUrl(plugin.handle, True, li) else: xbmcplugin.setResolvedUrl(plugin.handle, False, xbmcgui.ListItem()) else: li = xbmcgui.ListItem(path=sop_url) xbmcplugin.setResolvedUrl(plugin.handle, True, li)
player = xbmc.Player monitor = xbmc.Monitor wait = monitor().waitForAbort aborted = monitor().abortRequested cleanmovietitle = xbmc.getCleanMovieTitle transPath = xbmc.translatePath skinPath = transPath('special://skin/') addonPath = transPath(addonInfo('path')) legalfilename = xbmc.makeLegalFilename dataPath = transPath(addonInfo('profile')) window = xbmcgui.Window(10000) dialog = xbmcgui.Dialog() progressDialog = xbmcgui.DialogProgress() progressDialogGB = xbmcgui.DialogProgressBG() windowDialog = xbmcgui.WindowDialog() button = xbmcgui.ControlButton image = xbmcgui.ControlImage alphanum_input = xbmcgui.INPUT_ALPHANUM password_input = xbmcgui.INPUT_PASSWORD hide_input = xbmcgui.ALPHANUM_HIDE_INPUT verify = xbmcgui.PASSWORD_VERIFY item = xbmcgui.ListItem openFile = xbmcvfs.File read = openFile.read readbytes = openFile.readBytes makeFile = xbmcvfs.mkdir makeFiles = xbmcvfs.mkdirs
def downloadVideo(url, name): def _pbhook(downloaded, filesize, url=None, dp=None, name=''): try: percent = min(int((downloaded * 100) / filesize), 100) currently_downloaded = float(downloaded) / (1024 * 1024) kbps_speed = int(downloaded / (time.perf_counter() if PY3 else time.clock() - start)) if kbps_speed > 0: eta = (filesize - downloaded) / kbps_speed else: eta = 0 kbps_speed = kbps_speed / 1024 total = float(filesize) / (1024 * 1024) mbs = '%.02f MB of %.02f MB' % (currently_downloaded, total) e = 'Speed: %.02f Kb/s ' % kbps_speed e += 'ETA: %02d:%02d' % divmod(eta, 60) dp.update(percent, '{0}[CR]{1}[CR]{2}'.format(name[:50], mbs, e)) except: percent = 100 dp.update(percent) if dp.iscanceled(): dp.close() raise StopDownloading('Stopped Downloading') def getResponse(url, headers2, size): try: if size > 0: size = int(size) headers2['Range'] = 'bytes=%d-' % size req = Request(url, headers=headers2) resp = urlopen(req, timeout=30) return resp except: return None def doDownload(url, dest, dp, name): headers = {} if '|' in url: url, uheaders = url.split('|') headers = dict(urllib_parse.parse_qsl(uheaders)) if 'User-Agent' not in list(headers.keys()): headers.update({'User-Agent': USER_AGENT}) resp = getResponse(url, headers, 0) if not resp: dialog.ok("Cumination", '{0}[CR]{1}'.format(i18n('dnld_fail'), i18n('no_resp'))) return False try: content = int(resp.headers['Content-Length']) except: content = 0 try: resumable = 'bytes' in resp.headers['Accept-Ranges'].lower() except: resumable = False if resumable: six.print_("Download is resumable") if content < 1: dialog.ok("Cumination", '{0}[CR]{1}'.format(i18n('unkn_size'), i18n('no_dnld'))) return False size = 8192 mb = content / (1024 * 1024) if content < size: size = content total = 0 errors = 0 count = 0 resume = 0 sleep = 0 six.print_('{0} : {1}MB {2} '.format(i18n('file_size'), mb, dest)) f = xbmcvfs.File(dest, 'w') chunk = None chunks = [] while True: downloaded = total for c in chunks: downloaded += len(c) percent = min(100 * downloaded / content, 100) _pbhook(downloaded, content, url, dp, name) chunk = None error = False try: chunk = resp.read(size) if not chunk: if percent < 99: error = True else: while len(chunks) > 0: c = chunks.pop(0) f.write(c) del c f.close() return True except Exception as e: six.print_(str(e)) error = True sleep = 10 errno = 0 if hasattr(e, 'errno'): errno = e.errno if errno == 10035: # 'A non-blocking socket operation could not be completed immediately' pass if errno == 10054: # 'An existing connection was forcibly closed by the remote host' errors = 10 # force resume sleep = 30 if errno == 11001: # 'getaddrinfo failed' errors = 10 # force resume sleep = 30 if chunk: errors = 0 chunks.append(chunk) if len(chunks) > 5: c = chunks.pop(0) f.write(c) total += len(c) del c if error: errors += 1 count += 1 xbmc.sleep(sleep * 1000) if (resumable and errors > 0) or errors >= 10: if (not resumable and resume >= 50) or resume >= 500: # Give up! return False resume += 1 errors = 0 if resumable: chunks = [] # create new response resp = getResponse(url, headers, total) else: # use existing response pass def clean_filename(s): if not s: return '' badchars = '\\/:*?\"<>|\'' for c in badchars: s = s.replace(c, '') return s.strip() download_path = addon.getSetting('download_path') if download_path == '': try: download_path = dialog.browse(0, i18n('dnld_path'), "", "", False, False) addon.setSetting(id='download_path', value=download_path) if not xbmcvfs.exists(download_path): xbmcvfs.mkdir(download_path) except: pass if download_path != '': dp = xbmcgui.DialogProgress() name = re.sub(r'\[COLOR.+?\/COLOR\]', '', name).strip() dp.create(i18n('cum_dnld'), name[:50]) tmp_file = tempfile.mktemp(dir=download_path, suffix=".mp4") tmp_file = xbmc.makeLegalFilename(tmp_file) if PY2 else xbmcvfs.makeLegalFilename(tmp_file) start = time.perf_counter() if PY3 else time.clock() try: downloaded = doDownload(url, tmp_file, dp, name) if downloaded: if PY2: vidfile = xbmc.makeLegalFilename(download_path + clean_filename(name) + ".mp4") else: vidfile = xbmcvfs.makeLegalFilename(download_path + clean_filename(name) + ".mp4") try: xbmcvfs.rename(tmp_file, vidfile) return vidfile except: return tmp_file else: raise StopDownloading(i18n('stop_dnld')) except: while xbmcvfs.exists(tmp_file): try: xbmcvfs.delete(tmp_file) break except: pass
def DialogProgress_Create(self, *args, **kwargs): dialog = xbmcgui.DialogProgress() self._objects[id(dialog)] = dialog dialog.create(*args, **kwargs) return id(dialog)