def selector(dialog_name, select_from, setting_valid=False, sort_by=None, reverse=False, show_on_one=False): """ Shows a dialog where the user can choose from the values provided Returns the value of the selected key, or None if no selection was made Usage: dialog_name = title of the dialog shown select_from = a list or a dictionary which contains the options optional arguments setting_valid (False) = sets if the passed addon setting id should be considered if the addon setting is enabled, the dialog won't be shown and the first element will be selected automatically sort_by (None) = in case of dictionaries the keys will be sorted according this value in case of a list, the list will be ordered reverse (False) = sets if order should be reversed """ if isinstance(select_from, dict): keys = sorted(list(select_from.keys()), key=sort_by, reverse=reverse) values = [select_from[x] for x in keys] else: keys = sorted(select_from, key=sort_by, reverse=reverse) values = None if not keys: return None if (setting_valid and int(addon.getSetting(setting_valid)) != 4) or (len(keys) == 1 and not show_on_one): selected = 0 else: selected = dialog.select(dialog_name, keys) if selected == -1: return None return values[selected] if values else keys[selected]
def prefquality(video_list, sort_by=None, reverse=False): maxquality = int(addon.getSetting('qualityask')) if maxquality == 4: return selector(i18n('pick_qual'), video_list, sort_by=sort_by, reverse=reverse) if isinstance(video_list, dict): for key, _ in list(video_list.items()): if key.lower() == '4k': video_list['2160'] = video_list[key] del video_list[key] video_list = {int(''.join([y for y in key if y.isdigit()])): value for key, value in list(video_list.items())} if maxquality == 1: video_list = {key: value for key, value in list(video_list.items()) if key <= 1080} elif maxquality == 2: video_list = {key: value for key, value in list(video_list.items()) if key <= 720} elif maxquality == 3: video_list = {key: value for key, value in list(video_list.items()) if key < 720} keys = sorted(list(video_list.keys()), key=lambda x: x, reverse=reverse) values = [video_list[x] for x in keys] else: keys = sorted(video_list, key=sort_by, reverse=reverse) values = None if not keys: return None return values[0] if values else keys[0]
def _select_source(self, sources): if not len(sources) > 1 or addon.getSetting("dontask") == "true": source = sources[0] else: source = self.resolveurl.choose_source(sources) if source: self.play_from_link_to_resolve(source)
def dwnld_stream(url, name): ffmpeg_location = addon.getSetting("ffmpeg location") if ffmpeg_location != '': try: ffmpeg_location = xbmcgui.Dialog().notification(0, i18n('ffmpeg location'), "", "", False, False) addon.setSetting(id='ffmpeg_location', value=ffmpeg_location) if not os.path.isfile(download_path + 'ffmpeg.exe'): notify(i18n('cumination: Could not find ffmpeg!'), download_path + 'ffmpeg.exe') return except: pass cmd = exec_module(ffmpeg_location + 'ffmpeg -i "' + url + '" -vcodec copy -acodec copy "' + download_path + name + time.strftime("%Y%m%d-%H%M%S") + '.mkv"') import shlex, subprocess SW_HIDE = 0 info = None if os.name == 'nt': info = subprocess.STARTUPINFO() info.dwFlags |= subprocess.STARTF_USESHOWWINDOW info.wShowWindow = SW_HIDE proc = subprocess.Popen(cmd, shell=True, startupinfo=info) xbmc.log(i18n('cumination: Process started at') + str(time.time())) xbmc.log(i18n('Process playing ') + cmd) time.sleep(10) while xbmc.Player.isPlaying(): xbmc.log(i18n('cumination: Process playing ') + xbmc.Player.getPlayingFile()) time.sleep(5) proc.kill() xbmc.log(i18n('Process ended at ') + str(time.time()))
def play_from_link_list(self, links): use_universal = True if addon.getSetting("universal_resolvers") == "true" else False sources = self._clean_urls([self.resolveurl.HostedMediaFile(x, title=x.split('/')[2], include_universal=use_universal) for x in links]) if not sources: notify(i18n('oh_oh'), i18n('not_found')) return self._select_source(sources)
def restore_keywords(): path = dialog.browseSingle(1, i18n('slct_file'), '') if not path: return import json compressbackup = True if addon.getSetting( "compressbackup") == "true" else False if compressbackup: import gzip try: if PY3: with gzip.open(path, "rt", encoding="utf-8") as fav_file: backup_content = json.load(fav_file) else: with gzip.open(path, "rb") as fav_file: backup_content = json.load(fav_file) except (ValueError, IOError): notify(i18n('error'), i18n('invalid_bkup')) return if not backup_content["meta"]["type"] in ("cumination-keywords", "uwc-keywords"): notify(i18n('error'), i18n('invalid_bkup')) return else: try: if PY3: with gzip.open(path, "rt", encoding="utf-8") as fav_file: backup_content = json.load(fav_file) else: with gzip.open(path, "rb") as fav_file: backup_content = json.load(fav_file) except (ValueError, IOError): notify(i18n('error'), i18n('invalid_bkup')) return if not backup_content["meta"]["type"] in ("cumination-keywords", "uwc-keywords"): notify(i18n('error'), i18n('invalid_bkup')) return keywords = backup_content["data"] if not keywords: notify(i18n('error'), i18n('empty_bkup')) added = 0 skipped = 0 for keyword in keywords: keyw = keyword['keyword'] if check_if_keyword_exists(keyw): skipped += 1 else: addKeyword(keyw) added += 1 xbmc.executebuiltin('Container.Refresh') dialog.ok( i18n('rstr_cmpl'), "{0}[CR]{1}: {2}[CR]{3}: {4}".format(i18n('rstr_msg'), i18n('added'), added, i18n('skipped'), skipped))
def CheckPin(): now = time.time() hashedpin = addon.getSetting('pincode') logintime = addon.getSetting('logintime') if not logintime: logintime = 0 timecheck = now - (60 * 60) if not float(logintime) < timecheck: return True if hashedpin: pinhash = AskPin() if pinhash == hashedpin: addon.setSetting('logintime', str(now)) return True else: retry = dialog.yesno(i18n('pin_incorrect'), '{0}[CR]{1}?'.format(i18n('incorrect_msg'), i18n('retry')), yeslabel=i18n('retry')) if retry: return CheckPin() else: return False return True
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
import time import tempfile import sqlite3 import base64 import gzip from resources.lib.brotlidecpy import decompress import json from kodi_six import xbmc, xbmcplugin, xbmcgui, xbmcvfs from resources.lib import random_ua, cloudflare, strings from resources.lib.basics import addDir, searchDir, cum_image from functools import wraps from resources.lib.url_dispatcher import URL_Dispatcher import StorageServer cache = StorageServer.StorageServer("cumination", int(addon.getSetting('cache_time'))) url_dispatcher = URL_Dispatcher('utils') USER_AGENT = random_ua.get_ua() PY2 = six.PY2 PY3 = six.PY3 TRANSLATEPATH = xbmcvfs.translatePath if PY3 else xbmc.translatePath LOGINFO = xbmc.LOGINFO if PY3 else xbmc.LOGNOTICE base_hdrs = {'User-Agent': USER_AGENT, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8', 'Connection': 'keep-alive'} openloadhdr = base_hdrs
import tempfile import sqlite3 import base64 import gzip import json import string from kodi_six import xbmc, xbmcplugin, xbmcgui, xbmcvfs from resources.lib import random_ua, cloudflare, strings from resources.lib.basics import addDir, searchDir, cum_image from functools import wraps from resources.lib.url_dispatcher import URL_Dispatcher import StorageServer cache = StorageServer.StorageServer("cumination", int(addon.getSetting('cache_time'))) url_dispatcher = URL_Dispatcher('utils') USER_AGENT = random_ua.get_ua() PY2 = six.PY2 PY3 = six.PY3 TRANSLATEPATH = xbmcvfs.translatePath if PY3 else xbmc.translatePath LOGINFO = xbmc.LOGINFO if PY3 else xbmc.LOGNOTICE base_hdrs = { 'User-Agent': USER_AGENT, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Accept-Encoding': 'gzip', 'Accept-Language': 'en-US,en;q=0.8',
def backup_keywords(): path = dialog.browseSingle(0, i18n('bkup_dir'), '') progress.create(i18n('backing_up'), i18n('init')) if not path: return import json import datetime progress.update(25, i18n('read_db')) conn = sqlite3.connect(favoritesdb) conn.text_factory = str c = conn.cursor() c.execute("SELECT * FROM keywords") keywords = [{"keyword": keyword} for (keyword, ) in c.fetchall()] if not keywords: progress.close() notify(i18n('words_empty'), i18n('no_words')) return conn.close() time = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") backup_content = { "meta": { "type": "cumination-keywords", "version": 1, "datetime": time }, "data": keywords } if progress.iscanceled(): progress.close() return progress.update(75, i18n('write_bkup')) filename = "cumination-keywords_" + time + '.bak' compressbackup = True if addon.getSetting( "compressbackup") == "true" else False if compressbackup: import gzip try: if PY3: with gzip.open(path + filename, "wt", encoding="utf-8") as fav_file: json.dump(backup_content, fav_file) else: with gzip.open(path + filename, "wb") as fav_file: json.dump(backup_content, fav_file) except IOError: progress.close() notify(i18n('invalid_path'), i18n('write_permission')) return else: try: if PY3: with gzip.open(path + filename, "wt", encoding="utf-8") as fav_file: json.dump(backup_content, fav_file) else: with gzip.open(path + filename, "wb") as fav_file: json.dump(backup_content, fav_file) except IOError: progress.close() notify(i18n('invalid_path'), i18n('write_permission')) return progress.close() dialog.ok(i18n('bkup_complete'), "{0} {1}".format(i18n('bkup_file'), path + filename))