def removeTree(dir): if os.path.isdir(dir): try: shutil.rmtree(dir, ignore_errors=False, onerror=onerror) except Exception as e: logger.info('Cartella ' + dir + ' NON eliminata') logger.error(e)
def update(folder_content=config.get_setting("folder_tvshows"), folder=""): """ Actualiza la libreria dependiendo del tipo de contenido y la ruta que se le pase. @type folder_content: str @param folder_content: tipo de contenido para actualizar, series o peliculas @type folder: str @param folder: nombre de la carpeta a escanear. """ logger.info(folder) payload = {"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1} if folder: folder = str(folder) videolibrarypath = config.get_videolibrary_config_path() if folder.endswith('/') or folder.endswith('\\'): folder = folder[:-1] update_path = None if videolibrarypath.startswith("special:"): if videolibrarypath.endswith('/'): videolibrarypath = videolibrarypath[:-1] update_path = videolibrarypath + "/" + folder_content + "/" + folder + "/" else: #update_path = filetools.join(videolibrarypath, folder_content, folder) + "/" # Problemas de encode en "folder" update_path = filetools.join(videolibrarypath, folder_content, ' ').rstrip() if not scrapertools.find_single_match(update_path, '(^\w+:\/\/)'): payload["params"] = {"directory": update_path} """while xbmc.getCondVisibility('Library.IsScanningVideo()'):
def check_sources(new_movies_path='', new_tvshows_path=''): def format_path(path): if path.startswith("special://") or '://' in path: sep = '/' else: sep = os.sep if not path.endswith(sep): path += sep return path logger.info() new_movies_path = format_path(new_movies_path) new_tvshows_path = format_path(new_tvshows_path) SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml") if filetools.isfile(SOURCES_PATH): xmldoc = minidom.parse(SOURCES_PATH) video_node = xmldoc.childNodes[0].getElementsByTagName("video")[0] paths_node = video_node.getElementsByTagName("path") list_path = [p.firstChild.data for p in paths_node] return new_movies_path in list_path, new_tvshows_path in list_path else: xmldoc = minidom.Document() source_nodes = xmldoc.createElement("sources") for type in ['programs', 'video', 'music', 'picture', 'files']: nodo_type = xmldoc.createElement(type) element_default = xmldoc.createElement("default") element_default.setAttribute("pathversion", "1") nodo_type.appendChild(element_default) source_nodes.appendChild(nodo_type) xmldoc.appendChild(source_nodes) return False, False
def fOpen(file, mode = 'r'): # per android è necessario, su kodi 18, usare FileIO # https://forum.kodi.tv/showthread.php?tid=330124 # per xbox invece, è necessario usare open perchè _io è rotto :( # https://github.com/jellyfin/jellyfin-kodi/issues/115#issuecomment-538811017 if xbmc.getCondVisibility('system.platform.linux') and xbmc.getCondVisibility('system.platform.android'): logger.info('android, uso FileIO per leggere') return io.FileIO(file, mode) else: return open(file, mode)
def remove_tags(title): """ devuelve el titulo sin tags como color @type title: str @param title: title @rtype: str @return: cadena sin tags """ logger.info() title_without_tags = scrapertools.find_single_match( title, '\[color .+?\](.+)\[\/color\]') if title_without_tags: return title_without_tags else: return title
def chooseBranch(): global branch apiLink = 'https://api.github.com/repos/' + user + '/' + repo + '/branches' try: branches = urllib.urlopen(apiLink).read() except Exception as e: platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80031)) logger.info(e) return False branches = json.loads(branches) chDesc = [config.get_localized_string(80034), config.get_localized_string(80035)] chDesc.extend([b['name'] for b in branches if b['name'] not in ['stable', 'master']]) chName = ['stable', 'master'] chName.extend([b['name'] for b in branches if b['name'] not in ['stable', 'master']]) sel = platformtools.dialog_select(config.get_localized_string(80033), chDesc) branch = chName[sel] return True
def remove_smb_credential(path): """ devuelve el path sin contraseña/usuario para paths de SMB @param path: ruta @type path: str @return: cadena sin credenciales @rtype: str """ logger.info() if not scrapertools.find_single_match(path, '(^\w+:\/\/)'): return path protocol = scrapertools.find_single_match(path, '(^\w+:\/\/)') path_without_credentials = scrapertools.find_single_match( path, '^\w+:\/\/(?:[^;\n]+;)?(?:[^:@\n]+[:|@])?(?:[^@\n]+@)?(.*?$)') if path_without_credentials: return (protocol + path_without_credentials) else: return path
def updateFromZip(message=config.get_localized_string(80050)): dp = platformtools.dialog_progress_bg(config.get_localized_string(20000), message) dp.update(0) remotefilename = 'https://github.com/' + user + "/" + repo + "/archive/" + branch + ".zip" localfilename = filetools.join(xbmc.translatePath("special://home/addons/"), "plugin.video.kod.update.zip") destpathname = xbmc.translatePath("special://home/addons/") extractedDir = filetools.join(destpathname, "addon-" + branch) logger.info("remotefilename=%s" % remotefilename) logger.info("localfilename=%s" % localfilename) logger.info('extract dir: ' + extractedDir) # pulizia preliminare remove(localfilename) removeTree(extractedDir) try: urllib.urlretrieve(remotefilename, localfilename, lambda nb, bs, fs, url=remotefilename: _pbhook(nb, bs, fs, url, dp)) except Exception as e: platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80031)) logger.info('Non sono riuscito a scaricare il file zip') logger.info(e) dp.close() return False # Lo descomprime logger.info("decompressione...") logger.info("destpathname=%s" % destpathname) if os.path.isfile(localfilename): logger.info('il file esiste') dp.update(80, config.get_localized_string(20000), config.get_localized_string(80032)) import zipfile try: hash = fixZipGetHash(localfilename) logger.info(hash) with zipfile.ZipFile(fOpen(localfilename, 'rb')) as zip: size = sum([zinfo.file_size for zinfo in zip.filelist]) cur_size = 0 for member in zip.infolist(): zip.extract(member, destpathname) cur_size += member.file_size dp.update(int(80 + cur_size * 15 / size)) except Exception as e: logger.info('Non sono riuscito ad estrarre il file zip') logger.error(e) import traceback logger.error(traceback.print_exc()) dp.close() remove(localfilename) return False dp.update(95) # puliamo tutto global addonDir if extractedDir != addonDir: removeTree(addonDir) xbmc.sleep(1000) rename(extractedDir, 'plugin.video.kod') addonDir = filetools.join(destpathname, 'plugin.video.kod') logger.info("Cancellando il file zip...") remove(localfilename) dp.update(100) xbmc.sleep(1000) dp.close() xbmc.executebuiltin("UpdateLocalAddons") # in run() # refreshLang() return hash
def rename(dir1, dir2): try: filetools.rename(dir1, dir2, silent=True, vfs=False) except: logger.info('cartella ' + dir1 + ' NON rinominata')
def remove(file): if os.path.isfile(file): try: os.remove(file) except: logger.info('File ' + file + ' NON eliminato')
def update_sources(new='', old=''): logger.info() if new == old: return SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml") if filetools.isfile(SOURCES_PATH): xmldoc = minidom.parse(SOURCES_PATH) else: xmldoc = minidom.Document() source_nodes = xmldoc.createElement("sources") for type in ['programs', 'video', 'music', 'picture', 'files']: nodo_type = xmldoc.createElement(type) element_default = xmldoc.createElement("default") element_default.setAttribute("pathversion", "1") nodo_type.appendChild(element_default) source_nodes.appendChild(nodo_type) xmldoc.appendChild(source_nodes) # collect nodes # nodes = xmldoc.getElementsByTagName("video") video_node = xmldoc.childNodes[0].getElementsByTagName("video")[0] paths_node = video_node.getElementsByTagName("path") if old: # delete old path for node in paths_node: if node.firstChild.data == old: parent = node.parentNode remove = parent.parentNode remove.removeChild(parent) # write changes if sys.version_info[0] >= 3: #PY3 filetools.write( SOURCES_PATH, '\n'.join([ x for x in xmldoc.toprettyxml().splitlines() if x.strip() ])) else: filetools.write(SOURCES_PATH, '\n'.join([ x for x in xmldoc.toprettyxml().splitlines() if x.strip() ]), vfs=False) logger.info("The path %s has been removed from sources.xml" % old) if new: # create new path list_path = [p.firstChild.data for p in paths_node] if new in list_path: logger.info("The path %s already exists in sources.xml" % new) return logger.info("The path %s does not exist in sources.xml" % new) # if the path does not exist we create one source_node = xmldoc.createElement("source") # <name> Node name_node = xmldoc.createElement("name") sep = os.sep if new.startswith("special://") or scrapertools.find_single_match( new, r'(^\w+:\/\/)'): sep = "/" name = new if new.endswith(sep): name = new[:-1] name_node.appendChild(xmldoc.createTextNode(name.rsplit(sep)[-1])) source_node.appendChild(name_node) # <path> Node path_node = xmldoc.createElement("path") path_node.setAttribute("pathversion", "1") path_node.appendChild(xmldoc.createTextNode(new)) source_node.appendChild(path_node) # <allowsharing> Node allowsharing_node = xmldoc.createElement("allowsharing") allowsharing_node.appendChild(xmldoc.createTextNode('true')) source_node.appendChild(allowsharing_node) # Añadimos <source> a <video> video_node.appendChild(source_node) # write changes if sys.version_info[0] >= 3: #PY3 filetools.write( SOURCES_PATH, '\n'.join([ x for x in xmldoc.toprettyxml().splitlines() if x.strip() ])) else: filetools.write(SOURCES_PATH, '\n'.join([ x for x in xmldoc.toprettyxml().splitlines() if x.strip() ]), vfs=False) logger.info("The path %s has been added to sources.xml" % new)
def execute_sql_kodi(sql): """ Run sql query against kodi database @param sql: Valid sql query @type sql: str @return: Number of records modified or returned by the query @rtype nun_records: int @return: list with the query result @rtype records: list of tuples """ logger.info() file_db = "" nun_records = 0 records = None # We look for the archive of the video database according to the version of kodi video_db = config.get_platform(True)['video_db'] if video_db: file_db = filetools.join( xbmc.translatePath("special://userdata/Database"), video_db) # alternative method to locate the database if not file_db or not filetools.exists(file_db): file_db = "" for f in filetools.listdir( xbmc.translatePath("special://userdata/Database")): path_f = filetools.join( xbmc.translatePath("special://userdata/Database"), f) if filetools.isfile(path_f) and f.lower().startswith( 'myvideos') and f.lower().endswith('.db'): file_db = path_f break if file_db: logger.info("DB file: %s" % file_db) conn = None try: import sqlite3 conn = sqlite3.connect(file_db) cursor = conn.cursor() logger.info("Running sql: %s" % sql) cursor.execute(sql) conn.commit() records = cursor.fetchall() if sql.lower().startswith("select"): nun_records = len(records) if nun_records == 1 and records[0][0] is None: nun_records = 0 records = [] else: nun_records = conn.total_changes conn.close() logger.info("Query executed. Records: %s" % nun_records) except: logger.error("Error executing sql query") if conn: conn.close() else: logger.info("Database not found") return nun_records, records