def query_assoc(self, SQL, data=None, force_double_array=True, quiet=False): SQL = self.prepaire_sql(SQL) with self.db_lock: try: try: from sqlite3 import dbapi2 as database except: from pysqlite2 import dbapi2 as database DBH = database.connect(self.db_file, check_same_thread=False) DBH.row_factory = self.dict_factory cur = DBH.cursor() if data: cur.execute(SQL, data) else: cur.execute(SQL) rows = cur.fetchall() if len(rows) == 1 and not force_double_array: self.db_lock.release() return rows[0] else: self.db_lock.release() return rows except Exception as e: if self.quiet is False or quiet is False and not self.ignore_errors( e): self.handel_error( DatabaseException("SQLite Database Error: %s" % e)) kodi.log("SQLite Database Error: %s" % e) finally: del DBH self.db_lock.release()
def get_season_art(self, tvdb_id): result = {} def sort_art(record): return record['ratingsInfo']['average'] try: uri = "/series/%s/images/query" % tvdb_id response = self.request(uri, query={"keyType": "season"}, auth=True, cache_limit=EXPIRE_TIMES.WEEK) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) data = sorted(response['data'], reverse=True, key=lambda k: sort_art(k)) for d in data: s = int(d["subKey"]) if s == 0: continue img = "http://thetvdb.com/banners/" + d["fileName"] result[s] = img except: pass return result
def github_resolver(unmet): results = github.web_search(unmet) c = kodi.dialog_select("GitHub Search Results for %s" % unmet, [r['full_name'] for r in results['items']]) if c is not False: dep = results['items'][c] dep_url = url = "https://github.com/%s/archive/master.zip" % ( dep['full_name']) self.met_addons.append(unmet) dep_filename = "%s.zip" % unmet self.sources[unmet] = { "type": SOURCES.REPO, "url": dep_url, "user": user, "repo": repo, "version": "" } kodi.log("%s dependency met in %s" % (unmet, dep_url)) self.install_addon(unmet, dep_url, dep['full_name'], master=True) return True return False
def _connect(self): if self.quiet is False: kodi.log("Connecting to " + self.db_file) try: from sqlite3 import dbapi2 as database if self.quiet is False: kodi.log("%s loading sqlite3 as DB engine" % kodi.get_name()) except: from pysqlite2 import dbapi2 as database if self.quiet is False: kodi.log("%s loading pysqlite2 as DB engine" % kodi.get_name()) if self.quiet is False: kodi.log("Connecting to SQLite on: " + self.db_file) directory = kodi.vfs.dirname(self.db_file) if not kodi.vfs.exists(directory): kodi.vfs.mkdir(directory) self.DBH = database.connect(self.db_file, check_same_thread=False) try: self.DBC = self.DBH.cursor() self.__connected = True except Exception as e: self.handel_error( DatabaseException("SQLite Database Error: %s" % e)) kodi.log("SQLite Database Error: %s" % e)
def get_activity(fresh, activity, uri, data=None, params=None, auth=False): if fresh[0]: results = trakt.query( "SELECT cache FROM trakt_activity_cache WHERE activity=?", [activity]) if results: kodi.log('return cached activity: %s' % activity) return json.loads(results[0][0]) kodi.log('request remote activity: %s, %s' % (activity, uri)) results = trakt.request(uri, query=params, data=data, auth=auth) results = results['items'] if results: SQL = "REPLACE INTO trakt_activity_cache(activity, cache) VALUES (?,?)" trakt.execute(SQL, [activity, json.dumps(results)]) if activity.endswith('_at') is False: activity = re.sub('_[a-zA-Z0-9]+$', '', activity) if DB_TYPE == 'MySQL': ts = fresh[1][0:len(fresh[1]) - 5].replace("T", " ") SQL = "REPLACE INTO trakt_activities(activity, ts) VALUES (?, ?)" trakt.execute(SQL, [activity, ts]) else: SQL = "REPLACE INTO trakt_activities(activity, ts) VALUES (?, strftime('%s',?))" trakt.execute(SQL, [activity, fresh[1]]) trakt.commit() return results
def download(url, addon_id, destination, unzip=False, quiet=False): version = None filename = addon_id + '.zip' r = requests.get(url, stream=True) kodi.log("Download: %s" % url) if r.status_code == requests.codes.ok: temp_file = kodi.vfs.join(kodi.get_profile(), "downloads") if not kodi.vfs.exists(temp_file): kodi.vfs.mkdir(temp_file, recursive=True) temp_file = kodi.vfs.join(temp_file, filename) try: total_bytes = int(r.headers["Content-Length"]) except: total_bytes = 0 block_size = 1000 cached_bytes = 0 if not quiet: pb = xbmcgui.DialogProgress() pb.create("Downloading",filename,' ', ' ') kodi.sleep(150) start = time.time() with open(temp_file, 'wb') as f: for block in r.iter_content(chunk_size=block_size): if not block: break if not quiet and pb.iscanceled(): raise downloaderException('Download Aborted') return False cached_bytes += len(block) f.write(block) if total_bytes > 0: delta = int(time.time() - start) if delta: bs = int(cached_bytes / (delta)) else: bs = 0 if not quiet: percent = int(cached_bytes * 100 / total_bytes) pb.update(percent, "Downloading",filename, format_status(cached_bytes, total_bytes, bs)) if not quiet: pb.close() if unzip: zip_ref = zipfile.ZipFile(temp_file, 'r') zip_ref.extractall(destination) zip_ref.close() kodi.vfs.rm(temp_file, quiet=True) try: xml = kodi.vfs.read_file(kodi.vfs.join(destination, kodi.vfs.join(addon_id, 'addon.xml')), soup=True) version = get_version_by_xml(xml) if not version: version = get_version_by_name(filename) except: kodi.log("Unable to fine version from addon.xml for addon: %s" % addon_id) else: kodi.vfs.mv(temp_file, kodi.vfs.join(destination, filename)) else: kodi.close_busy_dialog() raise downloaderException(r.status_code) return version
def premiumize_direct(): if kodi.args['type'] == 'txt': import requests text = requests.get(kodi.args['url']).text kodi.dialog_textbox(kodi.args['name'], text) else: kodi.log(kodi.args['url']) kodi.play_stream(kodi.args['url'])
def handel_error(self, error, response, request_args, request_kwargs): if response is None: raise error if response.status_code == 401 and request_kwargs['auth'] and self.attemp == 0: self.attempt = 1 refresh_token() return self.request(*request_args, **request_kwargs) else: kodi.log(response.status_code) kodi.log(response.text)
def execute_many(self, SQL, data, quiet=False): SQL = self.prepaire_sql(SQL) try: self.DBC.executemany(SQL, data) except Exception as e: if self.quiet is False or quiet is False and not self.ignore_errors( e): self.handel_error(DatabaseException("Database Error: %s" % e)) kodi.log("Database Error: %s" % e)
def master_control(): options = [ "Send to Master Control", "Stream with Master Control", "Master Control Queue" ] c = kodi.dialog_select("Master Control Menu", options) if c is False: return if c == 2: kodi.execute_url("plugin://master.control?mode=queue") elif c == 1: from scrapecore import scrapers resolved_url = scrapers.get_scraper_by_name( kodi.args['service']).resolve_url(kodi.args['raw_url']) if not resolved_url: return from mastercontrol import api as master_control stream_url = master_control.get_streaming_url(resolved_url) kodi.play_url(stream_url) elif c == 0: ids = kodi.arg('ids', decode='json') from commoncore import trakt from mastercontrol import api as master_control if kodi.args['media'] == 'movie': media = 'movie' title = "%s (%s)" % (kodi.args['title'], kodi.args['year']) filename = kodi.vfs.clean_file_name(title) destination = '' else: media = 'tvshow' destination = kodi.vfs.join(kodi.args['title'], "Season %s" % kodi.args['season']) title = "%s - S%02dE%02d" % (kodi.args['title'], int(kodi.args['season']), int(kodi.args['episode'])) filename = kodi.vfs.clean_file_name(title) from scrapecore import scrapers resolved_url = scrapers.get_scraper_by_name( kodi.args['service']).resolve_url(kodi.args['raw_url']) if not resolved_url: return video = { "type": media, "filename": filename, "url": resolved_url, "title": title, "addon": kodi.get_id(), "destination": destination, "trakt_id": kodi.args['trakt_id'] } response = master_control.enqueue(video) kodi.log(response) message = 'Failed Adding to Queue %s.' % (title) try: if response['status'] == 200: message = 'Added to Queue %s.' % (title) except: pass kodi.notify(kodi.get_name(), message)
def resolve_url(self, raw_url): import urlresolver try: source = urlresolver.HostedMediaFile(url=raw_url) resolved_url = source.resolve() if source else None return resolved_url except Exception, e: kodi.log(e) return ''
def highest_versions(results): last = "" final = [] for a in results: addon_id, version = split_version(a['name']) if addon_id == last: continue last = addon_id kodi.log(a) final.append(a) return final
def user_resolver(user, unmet): dep_url, dep_filename, dep_full_name, version = github.find_zip(user, unmet) if dep_url: kodi.log("%s found in %s repo" % (unmet, user)) self.met_addons.append(unmet) user, repo = dep_full_name.split("/") self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url, "user": user, "repo": repo, "version": ""} kodi.log("%s dependency met in %s" % (unmet, dep_url)) return True return False
def handel_error(self, error, response, request_args, request_kwargs): if response is None: raise error if response.status_code == 401 and request_kwargs[ 'auth'] and self.attemp == 0: self.attempt = 1 refresh_token() return self.request(*request_args, **request_kwargs) else: kodi.log(response.status_code) kodi.log(response.text)
def get_person_art(self, tmdb_id): try: uri = "/person/%s" % tmdb_id response = self.request(uri) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) if 'profile_path' in response and response[ 'profile_path'] is not None: return "http://image.tmdb.org/t/p/w500%s" % response[ 'profile_path'] except: return False
def get_episode_art(self, tmdb_id, tvdb_id, imdb_id, season, episode): try: uri = "/tv/%s/season/%s/episode/%s/images" % (tmdb_id, season, episode) response = self.request(uri, cache_limit=EXPIRE_TIMES.DAY) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) if response and 'stills' in response and response['stills']: return "http://image.tmdb.org/t/p/w500%s" % response['stills'][ 0]['file_path'] except: return False
def get_episode_art(self, tmdb_id, tvdb_id, imdb_id, season, episode): try: uri = '/episodes/%s' % tvdb_id response = self.request(uri, auth=True, cache_limit=EXPIRE_TIMES.DAY) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) if response and 'data' in response and response['data']['filename']: return 'http://thetvdb.com/banners/_cache/' + response['data'][ 'filename'] except: return False
def execute_many(self, SQL, data, quiet=False): SQL = self.prepaire_sql(SQL) with self.db_lock: try: self.DBC.executemany(SQL, data) except Exception as e: if self.quiet is False or quiet is False and not self.ignore_errors( e): self.handel_error( DatabaseException("SQLite Database Error: %s" % e)) kodi.log("SQLite Database Error: %s" % e) finally: self.db_lock.release()
def enable_addon(self, addon_id): try: if addon_id in ['xbmc.python', 'xbmc.gui' ] or kodi.get_condition_visiblity( 'System.HasAddon(%s)' % addon_id) == 1: return True kodi.log("Enable Addon: %s" % addon_id) kodi.kodi_json_request("Addons.SetAddonEnabled", { "addonid": addon_id, "enabled": True }) except: pass
def premiumize_resolver(raw_url): resolved_url = '' if kodi.get_setting('premiumize_enable', ADDON_ID) != 'true': return resolved_url attempt = 0 attempts = 5 try: response = premiumize.create_transfer(raw_url) id = response['id'] except: premiumize.clear_transfers() response = premiumize.create_transfer(raw_url) id = response['id'] try: while attempt < attempts: folder_id = False file_id = False target_folder_id = False kodi.log("Resolve Attempt %s" % attempt) temp = premiumize.list_transfers() for t in temp['transfers']: if t['id'] == id and t['status'] == 'finished': if 'target_folder_id' in t: target_folder_id = t['target_folder_id'] if 'folder_id' in t: folder_id = t['folder_id'] if 'file_id' in t: file_id = t['file_id'] break if file_id: response = premiumize.item_details(file_id) resolved_url = response['stream_link'] kodi.set_property('Playback.Resolver', 'premiumize') kodi.set_property('Playback.ID', file_id) return resolved_url if folder_id: response = premiumize.list_folder(folder_id) resolved_url = premiumize.get_folder_stream(response) kodi.set_property('Playback.Resolver', 'premiumize') kodi.set_property('Playback.ID', folder_id) return resolved_url if target_folder_id: response = premiumize.list_folder(target_folder_id) resolved_url = premiumize.get_folder_stream(response) kodi.set_property('Playback.Resolver', 'premiumize') kodi.set_property('Playback.ID', target_folder_id) return resolved_url attempt += 1 kodi.sleep(150) except: pass return resolved_url
def get_show_art(self, tmdb_id, tvdb_id, imdb_id): result = {"fanart": "", "poster": ""} try: response = self.request('/', query={ "i": imdb_id, "apikey": OIMDB_KEY }) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) result['poster'] = response['Poster'].split('._')[0] except: pass return result
def get_cached_response(self, url, cache_limit): cache_hash = hashlib.md5(str(url)).hexdigest() cache_file = vfs.join(CACHE_PATH, cache_hash) if vfs.exists(cache_file): temp = vfs.read_file(cache_file + '.ts') if (time.time() - vfs.get_stat(cache_file).st_ctime()) / 3600 > int(temp): vfs.rm(cache_file, quiet=True) vfs.rm(cache_file + '.ts', quiet=True) return False else: html = zlib.decompress(vfs.read_file(cache_file)) kodi.log('Returning cached request') return html return False
def get_movie_art(self, tmdb_id, imdb_id): result = {"fanart": "", "poster": ""} try: response = self.request('/api', data={ "id": imdb_id, "key": IMDB_KEY }) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) result['poster'] = response['poster'].split('._')[0] except: pass return result
def github_resolver(unmet): results = github.web_search(unmet) c = kodi.dialog_select("GitHub Search Results for %s" % unmet, [r['full_name'] for r in results['items']]) if c is not False: dep = results['items'][c] dep_url = url = "https://github.com/%s/archive/master.zip" % (dep['full_name']) self.met_addons.append(unmet) dep_filename = "%s.zip" % unmet self.sources[unmet] = {"type": SOURCES.REPO, "url": dep_url, "user": user, "repo": repo, "version": ""} kodi.log("%s dependency met in %s" % (unmet, dep_url)) self.install_addon(unmet, dep_url, dep['full_name'], master=True) return True return False
def clear_art(self): kodi.log("Clearing Bad Art...") DB_FILE = kodi.vfs.join("special://database", 'Textures13.db') BAD_FILE = kodi.vfs.join(kodi.get_profile(), 'badart.log') bad_files = list(set(kodi.vfs.read_file(BAD_FILE).split("\n"))) with database.connect(DB_FILE, check_same_thread=False) as dbh: dbc = dbh.cursor() for bad_file in bad_files: if not bad_file: continue f = kodi.vfs.join(bad_file[0], bad_file) + '.jpg' dbc.execute("DELETE FROM texture WHERE cachedurl=?", [f]) f = kodi.vfs.join("special://thumbnails", f) kodi.vfs.rm(f, quiet=True) dbh.commit() kodi.vfs.write_file(BAD_FILE, '')
def resolve_url(self, raw_url): resolved_url = '' kodi.open_busy_dialog() hash = self.get_hash_from_magnet(raw_url) if not hash: hash = self.get_hash_from_url(raw_url) if hash: kodi.set_property('Playback.Hash', hash) else: kodi.clear_property('Playback.Hash') attempt = 0 attempts = 5 try: response = premiumize.create_transfer(raw_url) id = response['id'] except: premiumize.clear_transfers() response = premiumize.create_transfer(raw_url) id = response['id'] try: while attempt < attempts: folder_id = False file_id = False target_folder_id = False kodi.log("Resolve Attempt %s" % attempt) temp = premiumize.list_transfers() for t in temp['transfers']: if t['id'] == id and t['status'] == 'finished': target_folder_id = t['target_folder_id'] folder_id = t['folder_id'] file_id = t['file_id'] break if folder_id: response = premiumize.list_folder(folder_id) resolved_url = premiumize.get_folder_stream(response) break if target_folder_id: response = premiumize.list_folder(target_folder_id) resolved_url = premiumize.get_folder_stream(response) break attempt += 1 kodi.sleep(150) except: kodi.close_busy_dialog() kodi.close_busy_dialog() return resolved_url
def get_season_art(self, tvdb_id): result = {} uri = '/tv/%s' % tvdb_id try: response = self.request(uri, cache_limit=EXPIRE_TIMES.WEEK) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) except: return result try: for poster in response['seasonposter']: if poster['lang'] != 'en' or int(poster['season']) in result: continue result[int(poster['season'])] = poster['url'] except: pass return result
def query(self, SQL, data=None, force_double_array=True, quiet=False): SQL = self.prepaire_sql(SQL) try: if data: self.DBC.execute(SQL, data) else: self.DBC.execute(SQL) rows = self.DBC.fetchall() if len(rows) == 1 and not force_double_array: return rows[0] else: return rows except Exception as e: if self.quiet is False or quiet is False and not self.ignore_errors( e): self.handel_error(DatabaseException("Database Error: %s" % e)) kodi.log("Database Error: %s" % e)
def execute(self, SQL, data=[], quiet=False): SQL = self.prepaire_sql(SQL) try: if data: self.DBC.execute(SQL, data) else: self.DBC.execute(SQL) try: self.lastrowid = self.DBC.lastrowid except: self.lastrowid = None except Exception as e: if self.quiet is False or quiet is False and not self.ignore_errors( e): self.handel_error( DatabaseException("SQLite Database Error: %s" % e)) kodi.log("Database Error: %s" % e)
def get_episode_art(self, tmdb_id, tvdb_id, imdb_id, season, episode): try: tvmaze_id = self.lookup_id(imdb_id) if not tvmaze_id: return False uri = "/shows/%s/episodes" % tvmaze_id response = self.request(uri, query={"specials": 0}, cache_limit=EXPIRE_TIMES.DAY) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) season = int(season) episode = int(season) for e in response: if e['season'] == season and e['number'] == episode: if e['image'] is not None: return e['image']['original'] except: return False
def get_show_art(self, tmdb_id, tvdb_id, imdb_id): result = {"fanart": "", "poster": ""} uri = '/tv/%s' % tvdb_id try: response = self.request(uri, cache_limit=EXPIRE_TIMES.WEEK) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) except: return result try: result['fanart'] = response['showbackground'][0]['url'] except: pass try: result['poster'] = response['tvposter'][0]['url'] except: pass return result
def get_movie_art(self, tmdb_id, imdb_id): result = {"fanart": "", "poster": ""} uri = "/movie/%s/images" % tmdb_id try: response = self.request(uri, cache_limit=EXPIRE_TIMES.WEEK) if kodi.get_setting('enable_fanart_debug') == "true": kodi.log(response) except: return result try: result['fanart'] = "http://image.tmdb.org/t/p/w1280%s" % response[ 'backdrops'][0]['file_path'] except: pass try: result['poster'] = "http://image.tmdb.org/t/p/w1280%s" % response[ 'posters'][0]['file_path'] except: pass return result
def start(self): enable_updates class Monitor(xbmc.Monitor): def onSettingsChanged(self): global enable_updates enable_updates = kodi.get_setting('enable_updates') == 'true' monitor = Monitor() kodi.log("Service Starting...") if is_depricated: while not xbmc.abortRequested: kodi.sleep(1000) self.update() else: while not monitor.abortRequested(): if monitor.waitForAbort(10): break self.update() self.shutdown()
def get_activity(fresh, activity, uri, data=None, params=None, auth=False): if fresh[0]: results = trakt.query("SELECT cache FROM trakt_activity_cache WHERE activity=?", [activity]) if results: kodi.log('return cached activity: %s' % activity) return json.loads(results[0][0]) kodi.log('request remote activity: %s, %s' % (activity, uri)) results = trakt.request(uri, query=params, data=data, auth=auth) results=results['items'] if results: SQL = "REPLACE INTO trakt_activity_cache(activity, cache) VALUES (?,?)" trakt.execute(SQL, [activity, json.dumps(results)]) if activity.endswith('_at') is False: activity = re.sub('_[a-zA-Z0-9]+$', '', activity) if DB_TYPE == 'MySQL': ts = fresh[1][0:len(fresh[1])-5].replace("T", " ") SQL = "REPLACE INTO trakt_activities(activity, ts) VALUES (?, ?)" trakt.execute(SQL, [activity, ts]) else: SQL = "REPLACE INTO trakt_activities(activity, ts) VALUES (?, strftime('%s',?))" trakt.execute(SQL, [activity, fresh[1]]) trakt.commit() return results
def build_dependency_list(self, addon_id, url, full_name, master): #if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % addon_id) == 1: return True if addon_id in self.installed_list: kodi.log('Dependency is already installed: %s' % addon_id) return True user, repo = full_name.split("/") kodi.log('Finding dependencies for: %s' % addon_id) if master: self.sources[addon_id] = {"type": SOURCES.REPO, "url": url, "user": user, "repo": repo, "version": ""} xml_str = github.find_xml(full_name) self.sources[addon_id]['version'] = github.get_version_by_xml(BeautifulSoup(xml_str)) else: version = downloader.download(url, addon_id, self._destination, True, self.quiet) src_file = kodi.vfs.join("special://home/addons", addon_id) kodi.vfs.join(src_file, "addon.xml") xml = kodi.vfs.read_file(kodi.vfs.join(src_file, "addon.xml"), soup=True) self.save_source(addon_id, {"type": SOURCES.ZIP, "url": url, "user": user, "repo": repo, "version": version}) for dep in xml.findAll('import'): test = dep['addon'] try: if dep['optional'].lower() == 'true': if kodi.get_setting('install_optional') == 'false': continue elif kodi.get_setting('prompt_optional') == "true": c = kodi.dialog_confirm("Install Optional Dependency", dep['name'], dep['addon']) if not c: continue except: pass if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % test) == 1 or test in self.installed_list: kodi.log('Dependency is already installed: %s' % test) continue self.required_addons += [test] if test not in self.available_addons: self.unmet_addons += [test] else: self.sources[test] = {"type": SOURCES.DEFAULT, "url": self.source_table[test]} kodi.log("%s dependency met in %s" % (test, self.source_table[test])) def user_resolver(user, unmet): dep_url, dep_filename, dep_full_name, version = github.find_zip(user, unmet) if dep_url: kodi.log("%s found in %s repo" % (unmet, user)) self.met_addons.append(unmet) user, repo = dep_full_name.split("/") self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url, "user": user, "repo": repo, "version": ""} kodi.log("%s dependency met in %s" % (unmet, dep_url)) return True return False def github_resolver(unmet): results = github.web_search(unmet) c = kodi.dialog_select("GitHub Search Results for %s" % unmet, [r['full_name'] for r in results['items']]) if c is not False: dep = results['items'][c] dep_url = url = "https://github.com/%s/archive/master.zip" % (dep['full_name']) self.met_addons.append(unmet) dep_filename = "%s.zip" % unmet self.sources[unmet] = {"type": SOURCES.REPO, "url": dep_url, "user": user, "repo": repo, "version": ""} kodi.log("%s dependency met in %s" % (unmet, dep_url)) self.install_addon(unmet, dep_url, dep['full_name'], master=True) return True return False for unmet in self.unmet_addons: # Now attempt to locate dependencies from available sources # The addons that can be found in any enabled repos will be installed at the end. # check if this exists in users root repo if kodi.get_setting('source_user') == 'true': if user_resolver(user, unmet): continue # check if this exists in tva root repo if kodi.get_setting('source_tva') == 'true': if user_resolver(tva_user, unmet): continue # check if this exists on github if kodi.get_setting('source_github') == 'true': if github_resolver(unmet): continue self.unmet_addons = list(set(self.unmet_addons) - set(self.met_addons)) if len(self.unmet_addons): self.install_error = True if not self.quiet: kodi.close_busy_dialog() kodi.raise_error("", "Unmet Dependencies:", "See log or install manually", ','.join(self.unmet_addons)) kodi.log("Unmet Dependencies for addon install: %s" % addon_id) # % self.addon_id) kodi.log(','.join(self.unmet_addons)) self.completed.append(addon_id)
def enable_addon(self, addon_id): try: if addon_id in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % addon_id) == 1: return True kodi.log("Enable Addon: %s" % addon_id) kodi.kodi_json_request("Addons.SetAddonEnabled", {"addonid": addon_id, "enabled": True}) except: pass
def install_batch(): import xbmcgui from libs import github from libs import github_installer if kodi.mode == 'install_batch': url = kodi.arg('url') xml, zip_ref = github.batch_installer(url) else: url = kodi.dialog_file_browser('Select a install file', mask='.zip') if not github.re_installer.search(url): return xml, zip_ref = github.batch_installer(url, True) if not kodi.dialog_confirm('Batch Installer?', "Click YES to proceed.", "This will install a list of addons.", "Some configuration files and settings may be overwritten."): return if not xml: return # Install each addon as instructed installed_list = [] count = 0 for a in xml.findAll('addon'): count +=1 PB = kodi.ProgressBar() PB.new('Batch Installer - Progress', count) for a in xml.findAll('addon'): addon_id = a.find('addon_id') username = a.find('username') if addon_id is None or username is None: continue username = username.text addon_id = addon_id.text PB.next(addon_id) if not kodi.get_condition_visiblity("System.HasAddon(%s)"% addon_id): if PB.is_canceled(): return kodi.log("Batch install " + addon_id) url, filename, full_name, version = github.find_zip(username, addon_id) installed_list += github_installer.GitHub_Installer(addon_id, url, full_name, kodi.vfs.join("special://home", "addons"), quiet=True, batch=True, installed_list=installed_list).installed_list kodi.sleep(1000) # Look for config files. # Need to add error checking for missing config files configs= xml.find('configs') if configs is not None and 'dir' in configs.attrs[0]: config_dir = configs['dir'] for config in configs.findAll('config'): source = config.find('source') destination = config.find('destination') if source is None or destination is None: continue source = source.text destination = destination.text if not kodi.vfs.exists(destination): kodi.vfs.mkdir(destination, True) kodi.vfs.write_file(kodi.vfs.join(destination, source), zip_ref.read(config_dir + '/' + source)) # Now look for individual setting key and value pairs # Set them as instructed settings= xml.find('settings') if settings is not None: for setting in settings.findAll('setting'): if 'addon_id' in setting.attrs[0]: addon_id = setting['addon_id'] k = setting.find('key') v = setting.find('value') if k is None or v is None: continue kodi.set_setting(k.text, v.text, addon_id) builtins= xml.find('builtins') if builtins is not None: for cmd in builtins.findAll('command'): cmd = cmd.text kodi.run_command(cmd) jsonrpc= xml.find('jsonrpc') if jsonrpc is not None: from ast import literal_eval for cmd in jsonrpc.findAll('command'): method = cmd.find('method').text params = literal_eval(cmd.find('params').text) id = cmd.find('id').text kodi.kodi_json_request(method, params, id) # Now clean up zip_ref.close() PB.close() r = kodi.dialog_confirm(kodi.get_name(), 'Click Continue to install more addons or', 'Restart button to finalize addon installation', yes='Restart', no='Continue') if r: import sys import xbmc if sys.platform in ['linux', 'linux2', 'win32']: xbmc.executebuiltin('RestartApp') else: xbmc.executebuiltin('ShutDown')
def handel_error(self, error, response, request_args, request_kwargs): kodi.log(error) if response is not None: kodi.log(response.url) traceback.print_stack() raise error