def install_addon(self, addon_id, url, full_name, master): self.required_addons += [addon_id] self.build_dependency_list(addon_id, url, full_name, master) self.required_addons = list(set(self.required_addons)) self.unmet_addons = list(set(self.unmet_addons)) sources = self.sources self.sources = {} for addon_id in sources: source = sources[addon_id] if source['type'] == SOURCES.DEFAULT: self.install_addon(addon_id, source['url'], self._full_name, False) elif source['type'] == SOURCES.NATIVE: kodi.xbmc.executebuiltin("XBMC.InstallAddon(%s)" % addon_id) i=0 while kodi.get_condition_visiblity('System.HasAddon(%s)' % addon_id) == 0: if i == 30: kodi.raise_error("", "Unmet Dependencies:", "Install Timed Out", addon_id) break kodi.sleep(1000) i+=1 elif source['type'] == SOURCES.ZIP: downloader.download(source['url'], addon_id + ".zip", self._destination, True) elif source['type'] == SOURCES.REPO: src = kodi.vfs.join("special://home/addons", addon_id +"-master") dest = kodi.vfs.join("special://home/addons", addon_id) if kodi.vfs.exists(dest): if kodi.dialog_confirm("Confirm overwrite", dest): shutil.rmtree(dest) else: return downloader.download(source['url'], addon_id + ".zip", self._destination, True) shutil.move(src, dest) self.save_sources(sources) self.completed.append(addon_id)
def query_assoc(self, SQL, data=None, force_double_array=True): self.__lock.acquire(True) 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.__lock.release() return rows[0] else: self.__lock.release() return rows except Exception, e: err = str(e).lower() if 'no such table: version' not in err: kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def query_assoc(self, SQL, data=None, force_double_array=True, silent=False): self.__lock.acquire(True) 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.__lock.release() return rows[0] else: self.__lock.release() return rows except Exception, e: err = str(e).lower() if silent is False and 'no such table: version' not in err: kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def execute_many(self, SQL, data): if SQL.startswith('REPLACE INTO'): SQL = 'INSERT OR ' + SQL try: self.DBC.executemany(SQL, data) except Exception, e: if IGNORE_UNIQUE_ERRORS and re.match(self._unique_str, str(e)): kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def execute_many(self, SQL, data, silent=False): if SQL.startswith('REPLACE INTO'): SQL = 'INSERT OR ' + SQL try: self.DBC.executemany(SQL, data) except Exception, e: if silent is False and IGNORE_UNIQUE_ERRORS and re.match(self._unique_str, str(e)): kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def execute_many(self, SQL, data, silent=False): if SQL.startswith('REPLACE INTO'): SQL = 'INSERT OR ' + SQL self.__lock.acquire(True) try: self.DBC.executemany(SQL, data) except Exception, e: if silent is False and IGNORE_UNIQUE_ERRORS and re.match( self._unique_str, str(e)): kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def query(self, SQL, data=None, force_double_array=True): 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, e: if 'no such table: version' not in str(e).lower(): kodi.raise_error("Database error", e) kodi.log("Database error: %s" % e)
def query(self, SQL, data=None,force_double_array=True, silent=False): 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, e: if silent is False and 'no such table: version' not in str(e).lower(): kodi.raise_error("Database error", e) kodi.log("Database error: %s" % e)
def execute(self, SQL, data=[]): if SQL.startswith('REPLACE INTO'): SQL = 'INSERT OR ' + 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, e: if IGNORE_UNIQUE_ERRORS and re.match(self._unique_str, str(e)): kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def execute(self, SQL, data=[], silent=False): if SQL.startswith('REPLACE INTO'): SQL = 'INSERT OR ' + SQL self.__lock.acquire(True) 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, e: if silent is False and IGNORE_UNIQUE_ERRORS and re.match(self._unique_str, str(e)): kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
def query_assoc(self, SQL, data=None, force_double_array=True): try: self.DBH.row_factory = self.dict_factory cur = self.DBH.cursor() if data: cur.execute(SQL, data) else: cur.execute(SQL) rows = cur.fetchall() cur.close() if (len(rows) == 1 and not force_double_array): return rows[0] else: return rows except Exception, e: if 'no such table: version' not in str(e).lower(): kodi.raise_error("Database error", e) kodi.log("Database error: %s" % e)
def query_assoc(self, SQL, data=None, force_double_array=True, silent=False): try: self.DBH.row_factory = self.dict_factory cur = self.DBH.cursor() if data: cur.execute(SQL, data) else: cur.execute(SQL) rows = cur.fetchall() cur.close() if(len(rows)==1 and not force_double_array): return rows[0] else: return rows except Exception, e: if silent is False and 'no such table: version' not in str(e).lower(): kodi.raise_error("Database error", e) kodi.log("Database error: %s" % e)
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 = os.path.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() except Exception, e: kodi.raise_error("SqlLite Error", e) sys.exit()
def query(self, SQL, data=None, force_double_array=True, silent=False): self.__lock.acquire(True) 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): self.__lock.release() return rows[0] else: self.__lock.release() return rows except Exception, e: kodi.log(e) kodi.log(silent) err = str(e).lower() if silent is False and 'no such table: version' not in err: kodi.raise_error("Database error", e) kodi.log(SQL) kodi.log("Database error: %s" % e)
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 = os.path.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() except Exception, e: kodi.log(e) kodi.raise_error("SqlLite Error", e) sys.exit()
def build_dependency_list(self, addon_id, url, full_name, master): user, repo = full_name.split("/") if master: kodi.log('Finding dependencies from master') self.sources[addon_id] = {"type": SOURCES.REPO, "url": url} xml_str = github_api.find_xml(full_name) xml = BeautifulSoup(xml_str) else: kodi.log('Finding dependencies from zip') downloader.download(url, addon_id + ".zip", self._destination, True) 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) for dep in xml.findAll('import'): test = dep['addon'] try: if dep['optional'].lower() == 'true': continue except: pass if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % test) == 1: 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 = github_api.find_zip(user, unmet) if dep_url: kodi.log("%s found in %s repo" % (unmet, user)) self.met_addons.append(unmet) self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url} kodi.log("%s dependency met in %s" % (unmet, dep_url)) return True return False def github_resolver(unmet): results = github_api.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} 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 sr_resolver(unmet): url = 'https://cdimage.debian.org/mirror/addons.superrepo.org/v7/addons/%s' % unmet response = requests.get(url) if response.status_code == 200: for match in re.finditer('href="([^"]+)"', response.text): if match.group(1).endswith('zip'): f = match.group(1) dep_url = url + '/' + f self.met_addons.append(unmet) self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url} kodi.log("%s dependency met in %s" % (unmet, dep_url)) 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 user_resolver(user, unmet): continue # check if this exists in tva root repo if user_resolver(tva_user, unmet): continue # check if this exists on github #if github_resolver(unmet): continue # check if this exists on superrepo if sr_resolver(unmet): continue self.unmet_addons = list(set(self.unmet_addons) - set(self.met_addons)) if len(self.unmet_addons): self.install_error = True kodi.close_busy_dialog() kodi.raise_error("", "Unmet Dependencies:", "See log or install manually", ','.join(self.unmet_addons))