def findvideos(item): from core import servertools if item.infoLabels["tmdb_id"]: tmdb.set_infoLabels_item(item, __modo_grafico__) data = httptools.downloadpage(item.url).data iframe = scrapertools.find_single_match(data, '<iframe src="([^"]+)"') if "goo.gl/" in iframe: data += httptools.downloadpage(iframe, follow_redirects=False, only_headers=True).headers.get( "location", "") itemlist = servertools.find_video_items(item, data) library_path = config.get_videolibrary_path() if config.get_videolibrary_support(): title = "Añadir película a la videoteca" if item.infoLabels["imdb_id"] and not library_path.lower().startswith( "smb://"): try: from core import filetools movie_path = filetools.join(config.get_videolibrary_path(), 'CINE') files = filetools.walk(movie_path) for dirpath, dirname, filename in files: for f in filename: if item.infoLabels["imdb_id"] in f and f.endswith( ".nfo"): from core import videolibrarytools head_nfo, it = videolibrarytools.read_nfo( filetools.join(dirpath, dirname, f)) canales = it.library_urls.keys() canales.sort() if "clasicofilm" in canales: canales.pop(canales.index("clasicofilm")) canales.insert( 0, "[COLOR red]clasicofilm[/COLOR]") title = "Película ya en tu videoteca. [%s] ¿Añadir?" % ",".join( canales) break except: import traceback logger.error(traceback.format_exc()) itemlist.append( item.clone(action="add_pelicula_to_library", title=title)) token_auth = config.get_setting("token_trakt", "tvmoviedb") if token_auth and item.infoLabels["tmdb_id"]: itemlist.append( item.clone(channel="tvmoviedb", title="[Trakt] Gestionar con tu cuenta", action="menu_trakt", extra="movie")) return itemlist
def mark_season_as_watched_on_kodi(item, value=1): """ marca toda la temporada como vista o no vista en la libreria de Kodi @type item: item @param item: elemento a marcar @type value: int @param value: >0 para visto, 0 para no visto """ logger.info() # logger.debug("item:\n" + item.tostring('\n')) # Solo podemos marcar la temporada como vista en la BBDD de Kodi si la BBDD es local, # en caso de compartir BBDD esta funcionalidad no funcionara if config.get_setting("db_mode", "videolibrary"): return if value == 0: value = 'Null' request_season = '' if item.contentSeason > -1: request_season = ' and c12= %s' % item.contentSeason tvshows_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows")) item_path1 = "%" + item.path.replace("\\\\", "\\").replace(tvshows_path, "") if item_path1[:-1] != "\\": item_path1 += "\\" item_path2 = item_path1.replace("\\", "/") sql = 'update files set playCount= %s where idFile in ' \ '(select idfile from episode_view where (strPath like "%s" or strPath like "%s")%s)' % \ (value, item_path1, item_path2, request_season) execute_sql_kodi(sql)
def move_to_libray(item): download_path = filetools.join(config.get_setting("downloadpath"), item.downloadFilename) library_path = filetools.join(config.get_videolibrary_path(), *filetools.split(item.downloadFilename)) final_path = download_path if config.get_setting("library_add", "downloads") == True and config.get_setting("library_move", "downloads") == True: if not filetools.isdir(filetools.dirname(library_path)): filetools.mkdir(filetools.dirname(library_path)) if filetools.isfile(library_path) and filetools.isfile(download_path): filetools.remove(library_path) if filetools.isfile(download_path): if filetools.move(download_path, library_path): final_path = library_path if len(filetools.listdir(filetools.dirname(download_path))) == 0: filetools.rmdir(filetools.dirname(download_path)) if config.get_setting("library_add", "downloads") == True: if filetools.isfile(final_path): if item.contentType == "movie" and item.infoLabels["tmdb_id"]: library_item = Item(title=config.get_localized_string(70228) % item.downloadFilename, channel="downloads", action="findvideos", infoLabels=item.infoLabels, url=final_path) videolibrarytools.save_movie(library_item) elif item.contentType == "episode" and item.infoLabels["tmdb_id"]: library_item = Item(title=config.get_localized_string(70228) % item.downloadFilename, channel="downloads", action="findvideos", infoLabels=item.infoLabels, url=final_path) tvshow = Item(channel="downloads", contentType="tvshow", infoLabels={"tmdb_id": item.infoLabels["tmdb_id"]}) videolibrarytools.save_tvshow(tvshow, [library_item])
def emergency_urls(item, channel=None, path=None): logger.info() import re """ Llamamos a Findvideos del canal con la variable "item.videolibray_emergency_urls = True" para obtener la variable "item.emergency_urls" con la lista de listas de tuplas de los enlaces torrent y de servidores directos para ese episodio o película En la lista [0] siempre deben ir los enlaces torrents, si los hay. Si se desea cachear los .torrents, la búsqueda va contra esa lista. En la lista dos irán los enlaces de servidores directos, pero también pueden ir enlaces magnet (que no son cacheables) """ #lanazamos un "lookup" en el "findvideos" del canal para obtener los enlaces de emergencia try: if channel == None: #Si el llamador no ha aportado la estructura de channel, se crea channel = generictools.verify_channel(item.channel) #Se verifica si es un clon, que devuelva "newpct1" channel = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel]) if hasattr(channel, 'findvideos'): #Si el canal tiene "findvideos"... item.videolibray_emergency_urls = True #... se marca como "lookup" channel_save = item.channel #... guarda el canal original por si hay fail-over en Newpct1 item_res = getattr(channel, 'findvideos')(item) #... se procesa Findvideos item_res.channel = channel_save #... restaura el canal original por si hay fail-over en Newpct1 item_res.category = channel_save.capitalize() #... y la categoría del item_res.videolibray_emergency_urls #... y se borra la marca de lookup except: logger.error('ERROR al procesar el título en Findvideos del Canal: ' + item.channel + ' / ' + item.title) logger.error(traceback.format_exc()) item_res = item.clone() #Si ha habido un error, se devuelve el Item original #Si el usuario ha activado la opción "emergency_urls_torrents", se descargarán los archivos .torrent de cada título else: #Si se han cacheado con éxito los enlaces... try: channel_bis = generictools.verify_channel(item.channel) if config.get_setting("emergency_urls_torrents", channel_bis) and item_res.emergency_urls and path != None: videolibrary_path = config.get_videolibrary_path() #detectamos el path absoluto del título movies = config.get_setting("folder_movies") series = config.get_setting("folder_tvshows") if movies in path: folder = movies else: folder = series videolibrary_path = filetools.join(videolibrary_path, folder) i = 1 for url in item_res.emergency_urls[0]: #Recorremos las urls de emergencia... torrents_path = re.sub(r'(?:\.\w+$)', '_%s.torrent' % str(i).zfill(2), path) path_real = caching_torrents(url, torrents_path=torrents_path) #... para descargar los .torrents if path_real: #Si ha tenido éxito... item_res.emergency_urls[0][i-1] = path_real.replace(videolibrary_path, '') #se guarda el "path" relativo i += 1 except: logger.error('ERROR al cachear el .torrent de: ' + item.channel + ' / ' + item.title) logger.error(traceback.format_exc()) item_res = item.clone() #Si ha habido un error, se devuelve el Item original #logger.debug(item_res.emergency_urls) return item_res #Devolvemos el Item actualizado con los enlaces de emergencia
def ext_size(url): torrents_path = config.get_videolibrary_path() + '/torrents' if not os.path.exists(torrents_path): os.mkdir(torrents_path) try: urllib.urlretrieve("http://anonymouse.org/cgi-bin/anon-www.cgi/" + url, torrents_path + "/temp.torrent") pepe = open(torrents_path + "/temp.torrent", "rb").read() except: pepe = "" torrent = decode(pepe) try: name = torrent["info"]["name"] sizet = torrent["info"]['length'] sizet = convert_size(sizet) except: name = "no disponible" try: check_video = scrapertools.find_multiple_matches( str(torrent["info"]["files"]), "'length': (\d+)}") size = max([int(i) for i in check_video]) for file in torrent["info"]["files"]: manolo = "%r - %d bytes" % ("/".join(file["path"]), file["length"]) if str(size) in manolo: video = manolo size = convert_size(size) ext_v = re.sub( r"-.*? bytes|.*?\[.*?\].|'|.*?COM.|.*?\[.*?\]|\(.*?\)|.*?\.", "", video) try: os.remove(torrents_path + "/temp.torrent") except: pass except: try: size = sizet ext_v = re.sub( r"-.*? bytes|.*?\[.*?\].|'|.*?COM.|.*?\.es.|.*?\[.*?\]|.*?\(.*?\)\.|.*?\.", "", name) except: size = "NO REPRODUCIBLE" ext_v = "" try: os.remove(torrents_path + "/temp.torrent") except: pass if "rar" in ext_v: ext_v = ext_v + " -- No reproducible" size = "" return ext_v, size
def play(item): #Permite preparar la descarga de los subtítulos externos logger.info() itemlist = [] headers = [] import os from core import downloadtools if item.subtitle: #Si hay urls de sub-títulos, se descargan headers.append(["User-Agent", httptools.random_useragent()]) #Se busca un User-Agent aleatorio if not os.path.exists(os.path.join(config.get_videolibrary_path(), "subtitles")): #Si no hay carpeta se Sub-títulos, se crea os.mkdir(os.path.join(config.get_videolibrary_path(), "subtitles")) subtitles = [] subtitles.extend(item.subtitle) item.subtitle = subtitles[0] #ponemos por defecto el primeroç #item.subtitle = os.path.join(config.get_videolibrary_path(), os.path.join("subtitles", scrapertools.find_single_match(subtitles[0], '\/\d{2}\/(.*?\.\w+)$'))) for subtitle in subtitles: #recorremos la lista subtitle_name = scrapertools.find_single_match(subtitle, '\/\d{2}\/(.*?\.\w+)$') #se pone el nombre del Sub-título subtitle_folder_path = os.path.join(config.get_videolibrary_path(), "subtitles", subtitle_name) #Path de descarga ret = downloadtools.downloadfile(subtitle, subtitle_folder_path, headers=headers, continuar=True, silent=True) #Descarga itemlist.append(item.clone()) #Reproducción normal return itemlist
def set_Kodi_video_DB_useFolderNames(): logger.info() from platformcode.xbmc_videolibrary import execute_sql_kodi strPath = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_movies"), ' ').strip() scanRecursive = 2147483647 while xbmc.getCondVisibility('Library.IsScanningVideo()'): time.sleep(1) sql = 'UPDATE path SET useFolderNames=1 WHERE (strPath="%s" and scanRecursive=%s and strContent="movies" ' \ 'and useFolderNames=0)' % (strPath, scanRecursive) nun_records, records = execute_sql_kodi(sql) if nun_records > 0: logger.debug('MyVideos DB updated to Videolibrary %s useFolderNames=1' % config.get_setting("folder_movies"))
def file_cine_library(item, url_targets): import os from core import filetools videolibrarypath = os.path.join(config.get_videolibrary_path(), "CINE") archivo = item.show.strip() strmfile = archivo + ".strm" strmfilepath = filetools.join(videolibrarypath, strmfile) if not os.path.exists(strmfilepath): itemlist = [] itemlist.append( Item(channel=item.channel, title=">> Añadir a la videoteca...", url=url_targets, action="add_file_cine_library", extra="episodios", show=archivo)) return itemlist
def findvideos(item): logger.info() itemlist = [] itemlist_t = [] #Itemlist total de enlaces itemlist_f = [] #Itemlist de enlaces filtrados matches = [] data = '' response = {'data': data, 'sucess': False, 'code': 0} response = type('HTTPResponse', (), response) torrent_params = { 'url': item.url, 'torrents_path': None, 'local_torr': item.torrents_path, 'lookup': False, 'force': True, 'data_torrent': True, 'subtitles': True, 'file_list': True } #logger.debug(item) #Bajamos los datos de la página patron = '<a\s*class="torrent_download[^"]*"\s*href="([^"]+)"' if not item.matches: data, response, item, itemlist = generictools.downloadpage( item.url, timeout=timeout, canonical=canonical, headers=item.headers, s2=False, patron=patron, item=item, itemlist=itemlist) # Descargamos la página #Verificamos si se ha cargado una página, y si además tiene la estructura correcta if (not data and not item.matches) or response.code == 999: if item.emergency_urls and not item.videolibray_emergency_urls: # Hay urls de emergencia? if len(item.emergency_urls) > 1: matches = item.emergency_urls[ 1] # Restauramos matches de vídeos elif len(item.emergency_urls) == 1 and item.emergency_urls[0]: matches = item.emergency_urls[ 0] # Restauramos matches de vídeos - OLD FORMAT item.armagedon = True # Marcamos la situación como catastrófica else: if item.videolibray_emergency_urls: # Si es llamado desde creación de Videoteca... return item # Devolvemos el Item de la llamada else: return itemlist # si no hay más datos, algo no funciona, pintamos lo que tenemos if not item.armagedon: if not item.matches: matches = re.compile(patron, re.DOTALL).findall(data) else: matches = item.matches #logger.debug("PATRON: " + patron) #logger.debug(matches) #logger.debug(data) if not matches: # error return itemlist # Si es un lookup para cargar las urls de emergencia en la Videoteca... if item.videolibray_emergency_urls: item.emergency_urls = [] # Iniciamos emergency_urls item.emergency_urls.append( []) # Reservamos el espacio para los .torrents locales matches_list = [] # Convertimos matches-tuple a matches-list for tupla in matches: if isinstance(tupla, tuple): matches_list.append(list(tupla)) if matches_list: item.emergency_urls.append( matches_list) # Salvamnos matches de los vídeos... else: item.emergency_urls.append(matches) # Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB if not item.videolibray_emergency_urls: item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) # Ahora tratamos los enlaces .torrent con las diferentes calidades for x, (scrapedurl) in enumerate(matches): scrapedpassword = '' #Generamos una copia de Item para trabajar sobre ella item_local = item.clone() item_local.url = generictools.convert_url_base64( scrapedurl, host_torrent) if item.videolibray_emergency_urls and item_local.url != scrapedurl: item.emergency_urls[1][x][0] = item_local.url # Buscamos el enlace definitivo, si es necesario if not item_local.url.startswith( 'magnet') and not item_local.url.endswith('.torrent'): patron = '<a\s*id="link"[^>]*href="([^"]+)"' data, response, item, itemlist = generictools.downloadpage( item_local.url, timeout=timeout, canonical=canonical, s2=False, patron=patron, item=item, itemlist=itemlist) item_local.url = scrapertools.find_single_match(data, patron) if not item_local.url: continue # Restauramos urls de emergencia si es necesario local_torr = '' if item.emergency_urls and not item.videolibray_emergency_urls: try: # Guardamos la url ALTERNATIVA if item.emergency_urls[0][0].startswith( 'http') or item.emergency_urls[0][0].startswith('//'): item_local.torrent_alt = generictools.convert_url_base64( item.emergency_urls[0][0], host_torrent) else: item_local.torrent_alt = generictools.convert_url_base64( item.emergency_urls[0][0]) except: item_local.torrent_alt = '' item.emergency_urls[0] = [] from core import filetools if item.contentType == 'movie': FOLDER = config.get_setting("folder_movies") else: FOLDER = config.get_setting("folder_tvshows") if item.armagedon and item_local.torrent_alt: item_local.url = item_local.torrent_alt # Restauramos la url if not item.torrent_alt.startswith('http'): local_torr = filetools.join(config.get_videolibrary_path(), FOLDER, item_local.url) if len(item.emergency_urls[0]) > 1: del item.emergency_urls[0][0] #Buscamos tamaño en el archivo .torrent size = '' if item_local.torrent_info: size = item_local.torrent_info if not size and not item.videolibray_emergency_urls and not item_local.url.startswith( 'magnet:'): if not item.armagedon: torrent_params['url'] = item_local.url torrent_params[ 'local_torr'] = local_torr or item_local.torrents_path torrent_params = generictools.get_torrent_size( item_local.url, torrent_params=torrent_params, item=item_local) size = torrent_params['size'] if torrent_params['torrents_path']: item_local.torrents_path = torrent_params['torrents_path'] if 'ERROR' in size and item.emergency_urls and not item.videolibray_emergency_urls: item_local.armagedon = True try: # Restauramos la url if item.emergency_urls[0][0].startswith( 'http' ) or item.emergency_urls[0][0].startswith('//'): item_local.url = generictools.convert_url_base64( item.emergency_urls[0][0], host_torrent) else: item_local.url = generictools.convert_url_base64( item.emergency_urls[0][0]) if not item.url.startswith('http'): local_torr = filetools.join( config.get_videolibrary_path(), FOLDER, item_local.url) except: item_local.torrent_alt = '' item.emergency_urls[0] = [] torrent_params['url'] = item_local.url torrent_params['local_torr'] = local_torr torrent_params = generictools.get_torrent_size( item_local.url, torrent_params=torrent_params, item=item_local) size = torrent_params['size'] if torrent_params['torrents_path']: item_local.torrents_path = torrent_params[ 'torrents_path'] if size: size = size.replace('GB', 'G·B').replace('Gb', 'G·b').replace('MB', 'M·B')\ .replace('Mb', 'M·b').replace('.', ',') item_local.torrent_info = '%s, ' % size #Agregamos size if item_local.url.startswith( 'magnet:') and not 'Magnet' in item_local.torrent_info: item_local.torrent_info += ' Magnet' if item_local.torrent_info: item_local.torrent_info = item_local.torrent_info.strip().strip( ',') if item.videolibray_emergency_urls: item.torrent_info = item_local.torrent_info if not item.unify: item_local.torrent_info = '[%s]' % item_local.torrent_info # Guadamos la password del RAR password = scrapedpassword # Si tiene contraseña, la guardamos y la pintamos if password or item.password: if not item.password: item.password = password item_local.password = item.password itemlist.append( item.clone( action="", title="[COLOR magenta][B] Contraseña: [/B][/COLOR]'" + item_local.password + "'", folder=False)) # Guardamos urls de emergencia si se viene desde un Lookup de creación de Videoteca if item.videolibray_emergency_urls: item.emergency_urls[0].append( item_local.url) #guardamos la url y nos vamos continue if item_local.armagedon: item_local.quality = '[COLOR hotpink][E][/COLOR] [COLOR limegreen]%s[/COLOR]' % item_local.quality #Ahora pintamos el link del Torrent item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \ + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \ (item_local.quality, str(item_local.language), \ item_local.torrent_info) #Preparamos título y calidad, quitando etiquetas vacías item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) item_local.title = item_local.title.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() item_local.quality = re.sub( r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) item_local.quality = item_local.quality.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() if not item_local.torrent_info or 'Magnet' in item_local.torrent_info: item_local.alive = "??" #Calidad del link sin verificar elif 'ERROR' in item_local.torrent_info and 'Pincha' in item_local.torrent_info: item_local.alive = "ok" #link en error, CF challenge, Chrome disponible elif 'ERROR' in item_local.torrent_info and 'Introduce' in item_local.torrent_info: item_local.alive = "??" #link en error, CF challenge, ruta de descarga no disponible item_local.channel = 'setting' item_local.action = 'setting_torrent' item_local.unify = False item_local.folder = False item_local.item_org = item.tourl() elif 'ERROR' in item_local.torrent_info: item_local.alive = "no" #Calidad del link en error, CF challenge? else: item_local.alive = "ok" #Calidad del link verificada if item_local.channel != 'setting': item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Seridor Torrent itemlist_t.append( item_local.clone()) #Pintar pantalla, si no se filtran idiomas # Requerido para FilterTools if config.get_setting( 'filter_languages', channel) > 0: #Si hay idioma seleccionado, se filtra itemlist_f = filtertools.get_link( itemlist_f, item_local, list_language) #Pintar pantalla, si no está vacío #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) #logger.debug(item_local) #Si es un lookup para cargar las urls de emergencia en la Videoteca... if item.videolibray_emergency_urls: return item #... nos vamos if len(itemlist_f) > 0: #Si hay entradas filtradas... itemlist.extend(itemlist_f) #Pintamos pantalla filtrada else: if config.get_setting('filter_languages', channel) > 0 and len( itemlist_t) > 0: #Si no hay entradas filtradas ... thumb_separador = get_thumb( "next.png") #... pintamos todo con aviso itemlist.append( Item( channel=item.channel, url=host, title= "[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]", thumbnail=thumb_separador, folder=False)) if len(itemlist_t) == 0: if len(itemlist) == 0 or (len(itemlist) > 0 and itemlist[-1].server != 'torrent'): return [] itemlist.extend( itemlist_t) #Pintar pantalla con todo si no hay filtrado # Requerido para AutoPlay autoplay.start(itemlist, item) #Lanzamos Autoplay return itemlist
def init(): logger.info() """ Todo el código añadido al add-on se borra con cada actualización. Esta función permite restaurarlo automáticamente con cada actualización. Esto permite al usuario tener su propio código, bajo su responsabilidad, y restaurarlo al add-on cada vez que se actualiza. El mecanismo funciona copiando el contenido de la carpeta-arbol "./userdata/addon_data/plugin.video.alfa/custom_code/..." sobre las carpetas de código del add-on. No verifica el contenido, solo vuelca(reemplaza) el contenido de "custom_code". El usuario almacenará en las subcarpetas de "custom_code" su código actualizado y listo para ser copiado en cualquier momento. Si no se desea que copie algo, simplemente se borra de "custom_code" y ya no se copiará en la próxima actualización. Los pasos que sigue esta función, son los siguientes: 1.- La función se llama desde videolibrary_service.py, desde la función inicial: # Copia Custom code a las carpetas de Alfa desde la zona de Userdata from platformcode import custom_code custom_code.init() 2.- En el inicio de Kodi, comprueba si existe la carpeta "custom_code" en "./userdata/addon_data/plugin.video.alfa/". Si no existe, la crea y sale sin más, dando al ususario la posibilidad de copiar sobre esa estructura su código, y que la función la vuelque sobre el add-on en el próximo inicio de Kodi. 3.- En el siguiente inicio de Kodi, comprueba si existe el custom_code.json en la carpeta root del add-on. Si no existe, lo crea con el número de versión del add-on vacío, para permitir que se copien los archivos en esta pasada. 4.- Verifica que el número de versión del add-on es diferente de el de custom_code.json. Si es la misma versión, se sale porque ya se realizo la copia anteriormente. Si la versión es distinta, se realiza el volcado de todos los archivos de la carpeta-árbol "custom_code" sobre el add-on. Si la carpeta de destino no existe, dará un error y se cancelará la copia. Se considera que no tienen sentido nuevas carpetas. 5.- Si la copia ha terminado con éxito, se actualiza el custom_code.json con el número de versión del add-on, para que en inicios sucesivos de Kodi no se realicen las copias, hasta que el add-on cambie de versión. En el número de versión del add-on no se considera el número de fix. Tiempos: Copiando 7 archivos de prueba, el proceso ha tardado una décima de segundo. """ try: #Borra el .zip de instalación de Alfa de la carpeta Packages, por si está corrupto, y que así se pueda descargar de nuevo version = 'plugin.video.alfa-%s.zip' % config.get_addon_version( with_fix=False) filetools.remove( filetools.join(xbmc.translatePath('special://home'), 'addons', 'packages', version), True) #Borrar contenido de carpeta de Torrents filetools.rmdirtree(filetools.join(config.get_videolibrary_path(), 'temp_torrents_Alfa'), silent=True) #Verifica si Kodi tiene algún achivo de Base de Datos de Vídeo de versiones anteriores, entonces los borra verify_Kodi_video_DB() #LIBTORRENT: se descarga el binario de Libtorrent cada vez que se actualiza Alfa try: threading.Thread(target=update_libtorrent).start( ) # Creamos un Thread independiente, hasta el fin de Kodi time.sleep(2) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, nos vamos logger.error(traceback.format_exc()) #QUASAR: Preguntamos si se hacen modificaciones a Quasar if not filetools.exists(filetools.join(config.get_data_path(), "quasar.json")) \ and not config.get_setting('addon_quasar_update', default=False): question_update_external_addon("quasar") #QUASAR: Hacemos las modificaciones a Quasar, si está permitido, y si está instalado if config.get_setting('addon_quasar_update', default=False) or \ (filetools.exists(filetools.join(config.get_data_path(), \ "quasar.json")) and not xbmc.getCondVisibility('System.HasAddon("plugin.video.quasar")')): if not update_external_addon("quasar"): platformtools.dialog_notification( "Actualización Quasar", "Ha fallado. Consulte el log") #Existe carpeta "custom_code" ? Si no existe se crea y se sale custom_code_dir = filetools.join(config.get_data_path(), 'custom_code') if not filetools.exists(custom_code_dir): create_folder_structure(custom_code_dir) return else: #Existe "custom_code.json" ? Si no existe se crea custom_code_json_path = config.get_runtime_path() custom_code_json = filetools.join(custom_code_json_path, 'custom_code.json') if not filetools.exists(custom_code_json): create_json(custom_code_json_path) #Se verifica si la versión del .json y del add-on son iguales. Si es así se sale. Si no se copia "custom_code" al add-on verify_copy_folders(custom_code_dir, custom_code_json_path) #Si se han quedado "colgadas" descargas con archivos .RAR, se intenta identificarlos y reactivar el UnRar reactivate_unrar(init=True, mute=True) #Inicia un rastreo de vídeos decargados desde .torrent: marca los VISTOS y elimina los controles de los BORRADOS from servers import torrent try: threading.Thread(target=torrent.mark_torrent_as_watched).start( ) # Creamos un Thread independiente, hasta el fin de Kodi time.sleep(2) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, nos vamos logger.error(traceback.format_exc()) except: logger.error(traceback.format_exc())
def caching_torrents(url, referer=None, post=None, torrents_path=None, timeout=10, lookup=False, data_torrent=False): if torrents_path != None: logger.info("path = " + torrents_path) else: logger.info() if referer and post: logger.info('REFERER: ' + referer) from core import httptools torrent_file = '' headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': referer } #Necesario para el Post del .Torrent """ Descarga en el path recibido el .torrent de la url recibida, y pasa el decode Devuelve el path real del .torrent, o el path vacío si la operación no ha tenido éxito """ videolibrary_path = config.get_videolibrary_path( ) #Calculamos el path absoluto a partir de la Videoteca if torrents_path == None: if not videolibrary_path: torrents_path = '' if data_torrent: return (torrents_path, torrent_file) return torrents_path #Si hay un error, devolvemos el "path" vacío torrents_path = filetools.join( videolibrary_path, 'temp_torrents_Alfa', 'cliente_torrent_Alfa.torrent') #path de descarga temporal if '.torrent' not in torrents_path: torrents_path += '.torrent' #path para dejar el .torrent torrents_path_encode = filetools.encode( torrents_path) #encode utf-8 del path if url.endswith(".rar") or url.startswith( "magnet:"): #No es un archivo .torrent logger.error('No es un archivo Torrent: ' + url) torrents_path = '' if data_torrent: return (torrents_path, torrent_file) return torrents_path #Si hay un error, devolvemos el "path" vacío try: #Descargamos el .torrent if referer and post: #Descarga con POST response = httptools.downloadpage(url, headers=headers, post=post, follow_redirects=False, timeout=timeout) else: #Descarga sin post response = httptools.downloadpage(url, timeout=timeout) if not response.sucess: logger.error('Archivo .torrent no encontrado: ' + url) torrents_path = '' if data_torrent: return (torrents_path, torrent_file) return torrents_path #Si hay un error, devolvemos el "path" vacío torrent_file = response.data if "used CloudFlare" in torrent_file: #Si tiene CloudFlare, usamos este proceso response = httptools.downloadpage( "http://anonymouse.org/cgi-bin/anon-www.cgi/" + url.strip(), timeout=timeout) if not response.sucess: logger.error('Archivo .torrent no encontrado: ' + url) torrents_path = '' if data_torrent: return (torrents_path, torrent_file) return torrents_path #Si hay un error, devolvemos el "path" vacío torrent_file = response.data #Si es un archivo .ZIP tratamos de extraer el contenido if torrent_file.startswith("PK"): logger.info('Es un archivo .ZIP: ' + url) torrents_path_zip = filetools.join( videolibrary_path, 'temp_torrents_zip') #Carpeta de trabajo torrents_path_zip = filetools.encode(torrents_path_zip) torrents_path_zip_file = filetools.join( torrents_path_zip, 'temp_torrents_zip.zip') #Nombre del .zip import time filetools.rmdirtree( torrents_path_zip) #Borramos la carpeta temporal time.sleep(1) #Hay que esperar, porque si no da error filetools.mkdir(torrents_path_zip) #La creamos de nuevo if filetools.write(torrents_path_zip_file, torrent_file): #Salvamos el .zip torrent_file = '' #Borramos el contenido en memoria try: #Extraemos el .zip from core import ziptools unzipper = ziptools.ziptools() unzipper.extract(torrents_path_zip_file, torrents_path_zip) except: import xbmc xbmc.executebuiltin( 'XBMC.Extract("%s", "%s")' % (torrents_path_zip_file, torrents_path_zip)) time.sleep(1) import os for root, folders, files in os.walk( torrents_path_zip ): #Recorremos la carpeta para leer el .torrent for file in files: if file.endswith(".torrent"): input_file = filetools.join( root, file) #nombre del .torrent torrent_file = filetools.read( input_file) #leemos el .torrent filetools.rmdirtree( torrents_path_zip) #Borramos la carpeta temporal #Si no es un archivo .torrent (RAR, HTML,..., vacío) damos error if not scrapertools.find_single_match(torrent_file, '^d\d+:.*?\d+:'): logger.error('No es un archivo Torrent: ' + url) torrents_path = '' if data_torrent: return (torrents_path, torrent_file) return torrents_path #Si hay un error, devolvemos el "path" vacío #Salvamos el .torrent if not lookup: if not filetools.write(torrents_path_encode, torrent_file): logger.error('ERROR: Archivo .torrent no escrito: ' + torrents_path_encode) torrents_path = '' #Si hay un error, devolvemos el "path" vacío torrent_file = '' #... y el buffer del .torrent if data_torrent: return (torrents_path, torrent_file) return torrents_path except: torrents_path = '' #Si hay un error, devolvemos el "path" vacío torrent_file = '' #... y el buffer del .torrent logger.error('Error en el proceso de descarga del .torrent: ' + url + ' / ' + torrents_path_encode) logger.error(traceback.format_exc()) #logger.debug(torrents_path) if data_torrent: return (torrents_path, torrent_file) return torrents_path
def list_storage(item): logger.info() from core import filetools from lib import generictools itemlist = [] torrent_params = { 'url': item.url, 'torrents_path': '', 'local_torr': item.torrents_path, 'lookup': False, 'force': True, 'data_torrent': True, 'subtitles': True, 'file_list': True } #logger.debug(item) browse_type = 0 path_out = item.url if not filetools.exists(path_out): path_out = '' if not path_out: msg = 'Seleccione carpeta de destino:' path_out = platformtools.dialog_browse(browse_type, msg, shares='') path_list = filetools.listdir(path_out) VIDEOLIBRARY_PATH = config.get_videolibrary_path() FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") FOLDER = '' if VIDEOLIBRARY_PATH in path_out: if FOLDER_MOVIES in path_out: FOLDER = FOLDER_MOVIES elif FOLDER_TVSHOWS in path_out: FOLDER = FOLDER_TVSHOWS MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES) TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS) VIDEO_FOLDER = filetools.join(VIDEOLIBRARY_PATH, FOLDER) TEMP_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'cached_torrents_Alfa') MIS_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'Mis_Torrents') for file in path_list: if FOLDER and file.endswith('.json') and file.split( '.')[0] + '_01.torrent' in str(path_list): json_video = Item().fromjson( filetools.read(filetools.join(path_out, file))) json_video.channel = 'url' json_video.action = 'findvideos' json_video.torrents_path = json_video.url itemlist.append(json_video) elif FOLDER and filetools.isdir(filetools.join(path_out, file)): if '.torrent' in str(filetools.listdir(filetools.join(path_out, file))) \ or '.magnet' in str(filetools.listdir(filetools.join(path_out, file))): itemlist.append( Item(channel=item.channel, action="list_storage", url=filetools.join(path_out, file), title=file.title(), contentTitle=file.title(), contentType="list", unify=False, context=context)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos elif not FOLDER and filetools.isdir(filetools.join(path_out, file)): if MIS_TORRENT_FOLDER in path_out: title = file.title() if 'BTDigg' in file: title = title.replace( 'Btdigg', '[B][COLOR limegreen]BT[/COLOR][COLOR red]Digg[/COLOR][/B]' ) itemlist.append( Item(channel=item.channel, action="list_storage", url=filetools.join(path_out, file), title=title, contentTitle=title, contentType="list", unify=False, btdigg=True if 'BTDigg' in file else False, url_org=filetools.join(path_out, file), context=context)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos elif not FOLDER and ('.torrent' in file or '.magnet' in file): btdigg = False if '.torrent' in file: url = filetools.join(TEMP_TORRENT_FOLDER, file) filetools.copy(filetools.join(path_out, file), url, silent=True) if not filetools.exists(url): continue else: url = filetools.read(filetools.join(path_out, file), silent=True) if btdigg_magnet in url: btdigg = True size = 'MAGNET' if not url: continue torrent_params['url'] = url torrent_params['torrents_path'] = '' torrent_params['local_torr'] = filetools.join( TEMP_TORRENT_FOLDER, file) torrent_params = generictools.get_torrent_size( url, torrent_params=torrent_params) if '.magnet' in file and 'ERROR' in torrent_params['size']: torrent_params['size'] = 'MAGNET' size = torrent_params['size'] itemlist.append( Item(channel=item.channel, action="play", url=url, url_org=filetools.join(path_out, file), server='torrent', title=filetools.join( filetools.basename(path_out.rstrip('/').rstrip('\\')), file).title() + " [%s]" % size, contentTitle=filetools.join( filetools.basename(path_out.rstrip('/').rstrip('\\')), file).title(), contentType="movie", unify=False, torrents_path=torrent_params['torrents_path'], infoLabels={"tmdb_id": "111"}, context=context, btdigg=btdigg)) if len(itemlist) > 1: itemlist = sorted(itemlist, key=lambda it: it.title) #clasificamos return itemlist
def episodios(item): logger.info() itemlist = [] # Descarga la página data = httptools.downloadpage(item.url).data data = re.sub(r"\n|\r|\t|\s{2}| |<br>", "", data) if not item.infoLabels["tmdb_id"]: item.infoLabels["tmdb_id"] = scrapertools.find_single_match(data, '<a href="https://www.themoviedb.org/[^/]+/(\d+)') item.infoLabels["year"] = scrapertools.find_single_match(data, 'class="e_new">(\d{4})') if not item.infoLabels["genre"]: item.infoLabels["genre"] = ", ".join(scrapertools.find_multiple_matches(data, '<a itemprop="genre"[^>]+>([^<]+)</a>')) if not item.infoLabels["plot"]: item.infoLabels["plot"] = scrapertools.find_single_match(data, 'itemprop="description">([^<]+)</div>') dc = scrapertools.find_single_match(data, "var dc_ic = '\?dc=([^']+)'") patron = '<div class="f_cl_l_c f_cl_l_c_id[^"]+" c_id="([^"]+)" .*?c_num="([^"]+)" c_name="([^"]+)"' \ '.*?load_f_links\(\d+\s*,\s*(\d+).*?<div class="([^"]+)" onclick="marcar_capitulo' matches = scrapertools.find_multiple_matches(data, patron) lista_epis = [] for c_id, episodio, title, ficha, status in matches: episodio = episodio.replace("X", "x") if episodio in lista_epis: continue lista_epis.append(episodio) url = "https://playmax.mx/c_enlaces_n.php?ficha=%s&c_id=%s&dc=%s" % (ficha, c_id, dc) title = "%s - %s" % (episodio, title) if "_mc a" in status: title = "[COLOR %s]%s[/COLOR] %s" % (color5, u"\u0474".encode('utf-8'), title) new_item = Item(channel=item.channel, action="findvideos", title=title, url=url, thumbnail=item.thumbnail, fanart=item.fanart, show=item.show, infoLabels=item.infoLabels, text_color=color2, referer=item.url, contentType="episode") try: new_item.infoLabels["season"], new_item.infoLabels["episode"] = episodio.split('x', 1) except: pass itemlist.append(new_item) itemlist.sort(key=lambda it: (it.infoLabels["season"], it.infoLabels["episode"]), reverse=True) if __modo_grafico__: tmdb.set_infoLabels_itemlist(itemlist, __modo_grafico__) library_path = config.get_videolibrary_path() if config.get_videolibrary_support() and not item.extra: title = "Añadir serie a la videoteca" if item.infoLabels["imdb_id"] and not library_path.lower().startswith("smb://"): try: from core import filetools path = filetools.join(library_path, "SERIES") files = filetools.walk(path) for dirpath, dirname, filename in files: if item.infoLabels["imdb_id"] in dirpath: for f in filename: if f != "tvshow.nfo": continue from core import videolibrarytools head_nfo, it = videolibrarytools.read_nfo(filetools.join(dirpath, dirname, f)) canales = it.library_urls.keys() canales.sort() if "playmax" in canales: canales.pop(canales.index("playmax")) canales.insert(0, "[COLOR red]playmax[/COLOR]") title = "Serie ya en tu videoteca. [%s] ¿Añadir?" % ",".join(canales) break except: import traceback logger.error(traceback.format_exc()) pass itemlist.append(item.clone(action="add_serie_to_library", title=title, text_color=color5, extra="episodios###library")) if itemlist and not __menu_info__: ficha = scrapertools.find_single_match(item.url, '-f(\d+)-') itemlist.extend(acciones_fichas(item, sid, ficha)) return itemlist
def next_ep(item): logger.info() item.next_ep = False item.show_server = True VL = True if item.videolibrary else False time_over = False time_limit = time() + 30 TimeFromEnd = config.get_setting('next_ep_seconds') # wait until the video plays while not platformtools.is_playing() and time() < time_limit: sleep(1) while platformtools.is_playing() and not time_over: try: Total = xbmc.Player().getTotalTime() Actual = xbmc.Player().getTime() Difference = Total - Actual if Total > TimeFromEnd >= Difference: time_over = True except: break if time_over: # check i next file exist current_filename = os.path.basename(item.strm_path) base_path = os.path.basename( os.path.normpath(os.path.dirname(item.strm_path))) path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"), base_path) fileList = [] strmList = [] for file in os.listdir(path): if file.endswith('.strm'): fileList.append(file) for strm in fileList: se = re.search(r"(\d+)x(\d+)", strm) se = se.group(0).split("x") strmList.append([int(se[0]), int(se[1]), strm]) strmList = sorted(strmList, key=lambda s: (s[0], s[1])) for index, value in enumerate(strmList): if current_filename == value[2]: nextIndex = index + 1 break if nextIndex == 0 or nextIndex == len(strmList): next_file = None else: next_file = strmList[nextIndex][2] # start next episode window after x time if next_file: season = strmList[nextIndex][0] episode = strmList[nextIndex][1] next_ep = '%sx%s' % (season, str(episode).zfill(2)) info_file = next_file.replace("strm", "nfo") item = Item(action='play_from_library', channel='videolibrary', contentEpisodeNumber=episode, contentSeason=season, contentTitle=next_ep, contentType='episode', infoLabels={ 'episode': episode, 'mediatype': 'episode', 'season': season, 'title': next_ep }, strm_path=filetools.join(base_path, next_file)) global INFO INFO = filetools.join(path, info_file) nextDialog = NextDialog(ND, config.get_runtime_path()) nextDialog.show() while platformtools.is_playing( ) and not nextDialog.is_still_watching(): xbmc.sleep(100) pass nextDialog.close() logger.info('Next Episode: ' + str(nextDialog.stillwatching)) if nextDialog.stillwatching or nextDialog.continuewatching: item.next_ep = True xbmc.Player().stop() if VL: sleep(1) xbmc.executebuiltin('Action(Back)') sleep(0.5) return play_from_library(item) else: item.show_server = False if VL: sleep(1) xbmc.executebuiltin('Action(Back)') sleep(0.5) return None return item
def get_environment(): """ Devuelve las variables de entorno del OS, de Kodi y de Alfa más habituales, necesarias para el diagnóstico de fallos """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = '%s (%s, %s)' % (str(platform.python_version()), \ str(sys.api_version), str(platform.python_implementation())) environment['os_release'] = str(platform.release()) environment['prod_model'] = '' try: import multiprocessing environment['proc_num'] = ' (%sx)' % str( multiprocessing.cpu_count()) except: environment['proc_num'] = '' if xbmc.getCondVisibility("system.platform.Windows"): try: if platform.platform(): environment['os_release'] = str( platform.platform()).replace('Windows-', '') elif platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) command = ["wmic", "cpu", "get", "name"] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=0x08000000) output_cmd, error_cmd = p.communicate() if PY3 and isinstance(output_cmd, bytes): output_cmd = output_cmd.decode() output_cmd = re.sub(r'\n|\r|\s{2}', '', output_cmd) environment['prod_model'] = str(scrapertools.find_single_match(output_cmd, \ '\w+.*?(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) except: pass if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass environment['prod_model'] += ' (%s)' % config.is_rooted( silent=True) elif xbmc.getCondVisibility("system.platform.Linux"): environment['os_name'] = 'Linux' try: for label_a in subprocess.check_output('hostnamectl').split( FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'Operating' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, 'Operating\s*S\w+:\s*(.*?)\s*$')) break for label_a in subprocess.check_output( ['cat', '/proc/cpuinfo']).split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'model name' in label_a: environment['prod_model'] = str(scrapertools.find_single_match(label_a, \ 'model.*?:\s*(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) break except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) if not environment['os_release']: environment['os_release'] = str(platform.release()) if environment['proc_num'] and environment['prod_model']: environment['prod_model'] += environment['proc_num'] environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( old_div(int(memoryStatus.dwTotalPhys), (1024**2))) environment['mem_free'] = str( old_div(int(memoryStatus.dwAvailPhys), (1024**2))) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( old_div( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]), 1024)) environment['mem_free'] = str( old_div( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]), 1024)) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join("special://userdata", "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join("special://userdata", "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( old_div( int( scrapertools.find_single_match( label_a, '>(\d+)<\/')), 1024**2)) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, '>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, '>(.*?)<\/')) except: pass environment['userdata_path'] = str(config.get_data_path()) environment['userdata_path_perm'] = filetools.file_info( environment['userdata_path']) if not environment['userdata_path_perm']: del environment['userdata_path_perm'] try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' if environment['userdata_path_perm']: environment['userdata_path'] = environment['userdata_path_perm'] del environment['userdata_path_perm'] environment['torrent_lang'] = '%s/%s' % (config.get_setting("channel_language", default="").upper(), \ config.get_setting("second_language", default="").upper()) try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str(config.get_videolibrary_path()) environment['videolab_path_perm'] = filetools.file_info( environment['videolab_path']) if not environment['videolab_path_perm']: environment['videolab_path_perm'] = environment[ 'videolab_path'] if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): environment['videolab_series'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))): environment['videolab_pelis'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))))) except: pass try: video_updates = [ 'No', 'Inicio', 'Una vez', 'Inicio+Una vez', 'Dos veces al día' ] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' environment['torrent_list'] = [] environment['torrentcli_option'] = '' environment['torrent_error'] = '' environment['torrentcli_rar'] = config.get_setting("mct_rar_unpack", server="torrent", default=True) environment['torrentcli_backgr'] = config.get_setting( "mct_background_download", server="torrent", default=True) environment['torrentcli_lib_path'] = config.get_setting( "libtorrent_path", server="torrent", default="") if environment['torrentcli_lib_path']: lib_path = 'Activo' else: lib_path = 'Inactivo' if config.get_setting("libtorrent_version", server="torrent", default=""): lib_path += '-%s' % config.get_setting( "libtorrent_version", server="torrent", default="") environment['torrentcli_unrar'] = config.get_setting("unrar_path", server="torrent", default="") if environment['torrentcli_unrar']: if xbmc.getCondVisibility("system.platform.Android"): unrar = 'Android' else: unrar = filetools.dirname(environment['torrentcli_unrar']) unrar = filetools.basename(unrar).capitalize() else: unrar = 'Inactivo' torrent_id = config.get_setting("torrent_client", server="torrent", default=0) environment['torrentcli_option'] = str(torrent_id) torrent_options = platformtools.torrent_client_installed() if lib_path != 'Inactivo': torrent_options = ['MCT'] + torrent_options torrent_options = ['BT'] + torrent_options environment['torrent_list'].append({'Torrent_opt': str(torrent_id), 'Libtorrent': lib_path, \ 'RAR_Auto': str(environment['torrentcli_rar']), \ 'RAR_backgr': str(environment['torrentcli_backgr']), \ 'UnRAR': unrar}) environment['torrent_error'] = config.get_setting("libtorrent_error", server="torrent", default="") if environment['torrent_error']: environment['torrent_list'].append( {'Libtorrent_error': environment['torrent_error']}) for torrent_option in torrent_options: cliente = dict() cliente['D_load_Path'] = '' cliente['Libre'] = '?' cliente['Plug_in'] = torrent_option.replace('Plugin externo: ', '') if cliente['Plug_in'] == 'BT': cliente['D_load_Path'] = str( config.get_setting("bt_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'BT-torrents') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("bt_buffer", server="torrent", default=50)) elif cliente['Plug_in'] == 'MCT': cliente['D_load_Path'] = str( config.get_setting("mct_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'MCT-torrent-videos') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("mct_buffer", server="torrent", default=50)) elif xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % cliente['Plug_in']): try: __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % cliente['Plug_in']) except: continue cliente['Plug_in'] = cliente['Plug_in'].capitalize() if cliente['Plug_in'] == 'Torrenter': cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('storage'))) if not cliente['D_load_Path']: cliente['D_load_Path'] = str(filetools.join("special://home/", \ "cache", "xbmcup", "plugin.video.torrenter", "Torrenter")) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('pre_buffer_bytes')) else: cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('download_path'))) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('buffer_size')) if __settings__.getSetting( 'download_storage' ) == '1' and __settings__.getSetting('memory_size'): cliente['Memoria'] = str( __settings__.getSetting('memory_size')) if cliente['D_load_Path']: try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(cliente['D_load_Path']), None, None, ctypes.pointer(free_bytes)) cliente['Libre'] = str(round(float(free_bytes.value) / \ (1024**3), 3)).replace('.', ',') else: disk_space = os.statvfs(cliente['D_load_Path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize cliente['Libre'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)).replace('.', ',') except: pass if cliente['D_load_Path_perm']: cliente['D_load_Path'] = cliente['D_load_Path_perm'] del cliente['D_load_Path_perm'] environment['torrent_list'].append(cliente) environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in list( proxy_channel_bloqued.items()): if proxy_active != 'OFF': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk("special://logpath/"): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment['log_path']: environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024*1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = '%s (Upd: %s h.)' % (str(config.get_addon_version()), \ str(config.get_setting("addon_update_timer", default=12)).replace('0', 'No')) environment['assistant_version'] = str(None) if filetools.exists( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')): environment['assistant_version'] = filetools.read( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')) environment['assistant_cf_ua'] = str( config.get_setting('cf_assistant_ua', None)) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['machine'] = '' environment['platform'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['videolab_path_perm'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrent_list'] = [] environment['torrent_lang'] = '' environment['torrentcli_option'] = '' environment['torrentcli_rar'] = '' environment['torrentcli_lib_path'] = '' environment['torrentcli_unrar'] = '' environment['torrent_error'] = '' environment['assistant_version'] = '' environment['assistant_cf_ua'] = '' return environment
def get_environment(): """ Returns the most common OS, Kodi and Alpha environment variables, necessary for fault diagnosis """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = str(platform.python_version()) environment['os_release'] = str(platform.release()) if xbmc.getCondVisibility("system.platform.Windows"): try: if platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) except: pass environment['prod_model'] = '' if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split('\n'): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, r':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, r':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( old_div(int(memoryStatus.dwTotalPhys), (1024**2))) environment['mem_free'] = str( old_div(int(memoryStatus.dwAvailPhys), (1024**2))) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( old_div( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]), 1024)) environment['mem_free'] = str( old_div( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]), 1024)) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( old_div( int( scrapertools.find_single_match( label_a, r'>(\d+)<\/')), 1024**2)) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, r'>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, r'>(.*?)<\/')) except: pass environment['userdata_path'] = str( xbmc.translatePath(config.get_data_path())) try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str( round((float(disk_space.f_bavail) / (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str( xbmc.translatePath(config.get_videolibrary_path())) if filetools.exists( filetools.join(environment['videolab_path'], config.get_setting("folder_tvshows"))): environment['videolab_series'] = str( len( filetools.listdir( filetools.join( environment['videolab_path'], config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk( filetools.join(environment['videolab_path'], config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists( filetools.join(environment['videolab_path'], config.get_setting("folder_movies"))): environment['videolab_pelis'] = str( len( filetools.listdir( filetools.join( environment['videolab_path'], config.get_setting("folder_movies"))))) except: pass try: video_updates = ['No', 'Inicio', 'Una vez', 'Inicio+Una vez'] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str( round((float(disk_space.f_bavail) / (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' # environment['torrent_list'] = [] # environment['torrentcli_option'] = '' # environment['torrent_error'] = '' # environment['torrentcli_rar'] = config.get_setting("mct_rar_unpack", server="torrent", default=True) # environment['torrentcli_backgr'] = config.get_setting("mct_background_download", server="torrent", default=True) # environment['torrentcli_lib_path'] = config.get_setting("libtorrent_path", server="torrent", default="") # if environment['torrentcli_lib_path']: # lib_path = 'Activo' # else: # lib_path = 'Inactivo' # environment['torrentcli_unrar'] = config.get_setting("unrar_path", server="torrent", default="") # if environment['torrentcli_unrar']: # if xbmc.getCondVisibility("system.platform.Android"): # unrar = 'Android' # else: # unrar, bin = filetools.split(environment['torrentcli_unrar']) # unrar = unrar.replace('\\', '/') # if not unrar.endswith('/'): # unrar = unrar + '/' # unrar = scrapertools.find_single_match(unrar, '\/([^\/]+)\/$').capitalize() # else: # unrar = 'Inactivo' # torrent_id = config.get_setting("torrent_client", server="torrent", default=0) # environment['torrentcli_option'] = str(torrent_id) # torrent_options = platformtools.torrent_client_installed() # if lib_path == 'Activo': # torrent_options = ['MCT'] + torrent_options # torrent_options = ['BT'] + torrent_options # environment['torrent_list'].append({'Torrent_opt': str(torrent_id), 'Libtorrent': lib_path, \ # 'RAR_Auto': str(environment['torrentcli_rar']), \ # 'RAR_backgr': str(environment['torrentcli_backgr']), \ # 'UnRAR': unrar}) # environment['torrent_error'] = config.get_setting("libtorrent_error", server="torrent", default="") # if environment['torrent_error']: # environment['torrent_list'].append({'Libtorrent_error': environment['torrent_error']}) # for torrent_option in torrent_options: # cliente = dict() # cliente['D_load_Path'] = '' # cliente['Libre'] = '?' # cliente['Plug_in'] = torrent_option.replace('Plugin externo: ', '') # if cliente['Plug_in'] == 'BT': # cliente['D_load_Path'] = str(config.get_setting("bt_download_path", server="torrent", default='')) # if not cliente['D_load_Path']: continue # cliente['Buffer'] = str(config.get_setting("bt_buffer", server="torrent", default=50)) # elif cliente['Plug_in'] == 'MCT': # cliente['D_load_Path'] = str(config.get_setting("mct_download_path", server="torrent", default='')) # if not cliente['D_load_Path']: continue # cliente['Buffer'] = str(config.get_setting("mct_buffer", server="torrent", default=50)) # elif xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % cliente['Plug_in']): # __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % cliente['Plug_in']) # cliente['Plug_in'] = cliente['Plug_in'].capitalize() # if cliente['Plug_in'] == 'Torrenter': # cliente['D_load_Path'] = str(xbmc.translatePath(__settings__.getSetting('storage'))) # if not cliente['D_load_Path']: # cliente['D_load_Path'] = str(filetools.join(xbmc.translatePath("special://home/"), \ # "cache", "xbmcup", "plugin.video.torrenter", # "Torrenter")) # cliente['Buffer'] = str(__settings__.getSetting('pre_buffer_bytes')) # else: # cliente['D_load_Path'] = str(xbmc.translatePath(__settings__.getSetting('download_path'))) # cliente['Buffer'] = str(__settings__.getSetting('buffer_size')) # if __settings__.getSetting('download_storage') == '1' and __settings__.getSetting('memory_size'): # cliente['Memoria'] = str(__settings__.getSetting('memory_size')) # if cliente['D_load_Path']: # try: # if environment['os_name'].lower() == 'windows': # free_bytes = ctypes.c_ulonglong(0) # ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(cliente['D_load_Path']), # None, None, ctypes.pointer(free_bytes)) # cliente['Libre'] = str(round(float(free_bytes.value) / \ # (1024 ** 3), 3)).replace('.', ',') # else: # disk_space = os.statvfs(cliente['D_load_Path']) # if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize # cliente['Libre'] = str(round((float(disk_space.f_bavail) / \ # (1024 ** 3)) * float(disk_space.f_frsize), 3)).replace('.', ',') # except: # pass # environment['torrent_list'].append(cliente) environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in list( proxy_channel_bloqued.items()): if proxy_active != 'OFF': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk( xbmc.translatePath("special://logpath/")): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment['log_path']: environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024 * 1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = str(config.get_addon_version()) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['machine'] = '' environment['platform'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrent_list'] = [] environment['torrentcli_option'] = '' environment['torrentcli_rar'] = '' environment['torrentcli_lib_path'] = '' environment['torrentcli_unrar'] = '' environment['torrent_error'] = '' return environment
def findvideos(item): logger.info() itemlist = [] itemlist_t = [] #Itemlist total de enlaces itemlist_f = [] #Itemlist de enlaces filtrados if not item.language: item.language = ['CAST'] #Castellano por defecto item.category = categoria item.extra2 = 'xyz' del item.extra2 item.url = item.url.replace('http:', 'https:') #Por si viene de la videoteca #logger.debug(item) #Bajamos los datos de la página data = '' patron = '<p><a href="([^"]+)" rel' try: data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(item.url, timeout=timeout).data) if not PY3: data = unicode(data, "utf-8", errors="replace").encode("utf-8") except: pass if not data: logger.error( "ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url) itemlist.append( item.clone( action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log', folder=False)) if item.emergency_urls and not item.videolibray_emergency_urls: #Hay urls de emergencia? matches = item.emergency_urls[1] #Restauramos matches item.armagedon = True #Marcamos la situación como catastrófica else: if item.videolibray_emergency_urls: #Si es llamado desde creación de Videoteca... return item #Devolvemos el Item de la llamada else: return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos if not item.armagedon: matches = re.compile(patron, re.DOTALL).findall(data) if not matches: #error item = generictools.web_intervenida( item, data) #Verificamos que no haya sido clausurada if item.intervencion: #Sí ha sido clausurada judicialmente item, itemlist = generictools.post_tmdb_findvideos( item, itemlist) #Llamamos al método para el pintado del error else: logger.error( "ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron + data) itemlist.append( item.clone( action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log', folder=False)) if item.emergency_urls and not item.videolibray_emergency_urls: #Hay urls de emergencia? matches = item.emergency_urls[1] #Restauramos matches item.armagedon = True #Marcamos la situación como catastrófica else: if item.videolibray_emergency_urls: #Si es llamado desde creación de Videoteca... return item #Devolvemos el Item de la llamada else: return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos #logger.debug("PATRON: " + patron) #logger.debug(matches) #logger.debug(data) #Si es un lookup para cargar las urls de emergencia en la Videoteca... if item.videolibray_emergency_urls: item.emergency_urls = [] #Iniciamos emergency_urls item.emergency_urls.append( []) #Reservamos el espacio para los .torrents locales item.emergency_urls.append( matches) #Salvamnos matches de los vídeos... #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB if not item.videolibray_emergency_urls: item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) #Ahora tratamos los enlaces .torrent for scrapedurl in matches: #leemos los torrents con la diferentes calidades if 'javascript' in scrapedurl: #evitamos la basura continue url = '' if not item.armagedon: url = urlparse.urljoin(host, scrapedurl) #Leemos la siguiente página, que es de verdad donde está el magnet/torrent try: data = re.sub( r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(url, timeout=timeout).data) if not PY3: data = unicode(data, "utf-8", errors="replace").encode("utf-8") except: pass patron = "window.open\('([^']+)'" url = scrapertools.find_single_match(data, patron) if not url: #error logger.error( "ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron + data) itemlist.append( item.clone( action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log', folder=False)) if item.emergency_urls and not item.videolibray_emergency_urls: #Hay urls de emergencia? item.armagedon = True #Marcamos la situación como catastrófica else: continue #si no hay más datos, algo no funciona, pasamos al siguiente #Generamos una copia de Item para trabajar sobre ella item_local = item.clone() item_local.url = urlparse.urljoin(host, url) if item.videolibray_emergency_urls: item.emergency_urls[0].append( item_local.url) #guardamos la url y pasamos a la siguiente continue local_torr = '' if item.emergency_urls and not item.videolibray_emergency_urls: item_local.torrent_alt = item.emergency_urls[0][ 0] #Guardamos la url del .Torrent ALTERNATIVA if item.armagedon: item_local.url = item.emergency_urls[0][0] #Restauramos la url if item_local.url.startswith( "\\") or item_local.url.startswith("/"): from core import filetools if item.contentType == 'movie': FOLDER = config.get_setting("folder_movies") else: FOLDER = config.get_setting("folder_tvshows") local_torr = filetools.join(config.get_videolibrary_path(), FOLDER, item_local.url) if len(item.emergency_urls[0]) > 1: del item.emergency_urls[0][0] #Buscamos si ya tiene tamaño, si no, los buscamos en el archivo .torrent size = scrapertools.find_single_match( item_local.quality, '\s?\[(\d+,?\d*?\s\w\s?[b|B])\]') if not size and not item.videolibray_emergency_urls: size = generictools.get_torrent_size( item_local.url, local_torr=local_torr) #Buscamos el tamaño en el .torrent if size: item_local.title = re.sub( r'\s?\[\d+,?\d*?\s\w\s?[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía size = size.replace('GB', 'G·B').replace('Gb', 'G·b').replace('MB', 'M·B')\ .replace('Mb', 'M·b').replace('.', ',') item_local.quality = re.sub( r'\s?\[\d+,?\d*?\s\w\s?[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía item_local.torrent_info = '%s' % size #Agregamos size if not item.unify: item_local.torrent_info = '[%s]' % item_local.torrent_info.strip( ).strip(',') if item.armagedon: #Si es catastrófico, lo marcamos item_local.quality = '[/COLOR][COLOR hotpink][E] [COLOR limegreen]%s' % item_local.quality #Ahora pintamos el link del Torrent item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \ + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \ (item_local.quality, str(item_local.language), \ item_local.torrent_info) #Preparamos título de Torrent #Preparamos título y calidad, quitamos etiquetas vacías item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) item_local.title = item_local.title.replace("--", "").replace( "[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() item_local.quality = re.sub( r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality).strip() item_local.quality = item_local.quality.replace("--", "").replace( "[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() item_local.alive = "??" #Calidad del link sin verificar item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Servidor Torrent itemlist_t.append( item_local.clone()) #Pintar pantalla, si no se filtran idiomas # Requerido para FilterTools if config.get_setting( 'filter_languages', channel) > 0: #Si hay idioma seleccionado, se filtra itemlist_f = filtertools.get_link( itemlist_f, item_local, list_language) #Pintar pantalla, si no está vacío #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) #logger.debug(item_local) if item.videolibray_emergency_urls: #Si ya hemos guardado todas las urls... return item #... nos vamos if len(itemlist_f) > 0: #Si hay entradas filtradas... itemlist.extend(itemlist_f) #Pintamos pantalla filtrada else: if config.get_setting('filter_languages', channel) > 0 and len( itemlist_t) > 0: #Si no hay entradas filtradas ... thumb_separador = get_thumb( "next.png") #... pintamos todo con aviso itemlist.append( Item( channel=item.channel, url=host, title= "[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]", thumbnail=thumb_separador, folder=False)) itemlist.extend( itemlist_t) #Pintar pantalla con todo si no hay filtrado # Requerido para AutoPlay autoplay.start(itemlist, item) #Lanzamos Autoplay return itemlist
def findvideos(item): logger.info() itemlist = [] itemlist_t = [] #Itemlist total de enlaces itemlist_f = [] #Itemlist de enlaces filtrados matches = [] data = '' code = 0 #logger.debug(item) #Bajamos los datos de la página y seleccionamos el bloque patron = '\s*<th\s*class="hide-on-mobile">Total\s*Descargas<\/th>\s*<th>' patron += 'Descargar<\/th>\s*<\/thead>\s*<tbody>\s*(.*?<\/tr>)\s*<\/tbody>' patron += '\s*<\/table>\s*<\/div>\s*<\/div>\s*<\/div>' if not item.matches: data, success, code, item, itemlist = generictools.downloadpage(item.url, timeout=timeout, s2=False, patron=patron, item=item, itemlist=[]) # Descargamos la página) #Verificamos si se ha cargado una página, y si además tiene la estructura correcta if (not data and not item.matches) or code == 999: if item.emergency_urls and not item.videolibray_emergency_urls: #Hay urls de emergencia? if len(item.emergency_urls) > 1: matches = item.emergency_urls[1] #Restauramos matches de vídeos item.armagedon = True #Marcamos la situación como catastrófica else: if item.videolibray_emergency_urls: #Si es llamado desde creación de Videoteca... return item #Devolvemos el Item de la llamada else: return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos elif data: # Seleccionamos el bloque y buscamos los apartados data = scrapertools.find_single_match(data, patron) patron = '<tr>(?:\s*<td>[^<]+<\/td>)?\s*<td>([^<]+)<\/td>\s*<td>([^<]+)<\/td>\s*' patron += '<td\s*class=[^<]+<\/td>(?:<td>([^<]+)<\/td>)?\s*<td\s*class=[^<]+<\/td>\s*' patron += '<td>\s*<a\s*class="[^"]+"\s*(?:data-row="[^"]+"\s*data-post="[^"]+"\s*)?' patron += 'href="([^"]+)"\s*(?:data-season="([^"]+)"\s*data-serie="([^"]+)")?' if not item.armagedon: if not item.matches: matches = re.compile(patron, re.DOTALL).findall(data) else: matches = item.matches #logger.debug("PATRON: " + patron) #logger.debug(matches) #logger.debug(data) if not matches: #error return itemlist #Si es un lookup para cargar las urls de emergencia en la Videoteca... if item.videolibray_emergency_urls: item.emergency_urls = [] #Iniciamos emergency_urls item.emergency_urls.append([]) #Reservamos el espacio para los .torrents locales item.emergency_urls.append(matches) #Salvamnos matches de los vídeos... #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB if not item.videolibray_emergency_urls: item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) #Ahora tratamos los enlaces .torrent con las diferentes calidades for scrapedquality, scrapedlanguage, scrapedsize, scrapedurl, season_num, episode_num in matches: scrapedpassword = '' #Generamos una copia de Item para trabajar sobre ella item_local = item.clone() item_local.url = scrapedurl # Restauramos urls de emergencia si es necesario local_torr = '' if item.emergency_urls and not item.videolibray_emergency_urls: item_local.torrent_alt = item.emergency_urls[0][0] #Guardamos la url del .Torrent ALTERNATIVA if item.armagedon: item_local.url = item.emergency_urls[0][0] #Restauramos la url if item_local.url.startswith("\\") or item_local.url.startswith("/"): from core import filetools if item.contentType == 'movie': FOLDER = config.get_setting("folder_movies") else: FOLDER = config.get_setting("folder_tvshows") local_torr = filetools.join(config.get_videolibrary_path(), FOLDER, item_local.url) if len(item.emergency_urls[0]) > 1: del item.emergency_urls[0][0] # Procesamos idiomas item_local.language = [] #creamos lista para los idiomas item_local.quality = scrapedquality # Copiamos la calidad if '[Subs. integrados]' in scrapedlanguage or '(Sub Forzados)' in scrapedlanguage \ or 'Subs integrados' in scrapedlanguage: item_local.language = ['VOS'] # añadimos VOS if 'castellano' in scrapedlanguage.lower() or ('español' in scrapedlanguage.lower() and not 'latino' in scrapedlanguage.lower()): item_local.language += ['CAST'] # añadimos CAST if 'dual' in item_local.quality.lower(): item_local.quality = re.sub(r'(?i)dual.*?', '', item_local.quality).strip() item_local.language += ['DUAL'] # añadimos DUAL if not item_local.language: item_local.language = ['LAT'] # [LAT] por defecto #Buscamos tamaño en el archivo .torrent size = '' if item_local.torrent_info: size = item_local.torrent_info elif scrapedsize: size = scrapedsize if not size and not item.videolibray_emergency_urls and not item_local.url.startswith('magnet:'): if not item.armagedon: size = generictools.get_torrent_size(item_local.url, local_torr=local_torr) #Buscamos el tamaño en el .torrent desde la web if 'ERROR' in size and item.emergency_urls and not item.videolibray_emergency_urls: item_local.armagedon = True item_local.url = item.emergency_urls[0][0] #Restauramos la url local_torr = filetools.join(config.get_videolibrary_path(), FOLDER, item_local.url) size = generictools.get_torrent_size(item_local.url, local_torr=local_torr) #Buscamos el tamaño en el .torrent emergencia if size: size = size.replace('GB', 'G·B').replace('Gb', 'G·b').replace('MB', 'M·B')\ .replace('Mb', 'M·b').replace('.', ',') item_local.torrent_info = '%s, ' % size #Agregamos size if item_local.url.startswith('magnet:') and not 'Magnet' in item_local.torrent_info: item_local.torrent_info += ' Magnet' if item_local.torrent_info: item_local.torrent_info = item_local.torrent_info.strip().strip(',') item.torrent_info = item_local.torrent_info if not item.unify: item_local.torrent_info = '[%s]' % item_local.torrent_info # Guadamos la password del RAR password = scrapedpassword # Si tiene contraseña, la guardamos y la pintamos if password or item.password: if not item.password: item.password = password item_local.password = item.password itemlist.append(item.clone(action="", title="[COLOR magenta][B] Contraseña: [/B][/COLOR]'" + item_local.password + "'", folder=False)) # Guardamos urls de emergencia si se viene desde un Lookup de creación de Videoteca if item.videolibray_emergency_urls: item.emergency_urls[0].append(item_local.url) #guardamos la url y nos vamos continue if item_local.armagedon: item_local.quality = '[COLOR hotpink][E][/COLOR] [COLOR limegreen]%s[/COLOR]' % item_local.quality #Ahora pintamos el link del Torrent item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \ + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \ (item_local.quality, str(item_local.language), \ item_local.torrent_info) #Preparamos título y calidad, quitando etiquetas vacías item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) item_local.title = item_local.title.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) item_local.quality = item_local.quality.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() if not size or 'Magnet' in size: item_local.alive = "??" #Calidad del link sin verificar elif 'ERROR' in size and 'Pincha' in size: item_local.alive = "ok" #link en error, CF challenge, Chrome disponible elif 'ERROR' in size and 'Introduce' in size: item_local.alive = "??" #link en error, CF challenge, ruta de descarga no disponible item_local.channel = 'setting' item_local.action = 'setting_torrent' item_local.unify = False item_local.folder = False item_local.item_org = item.tourl() elif 'ERROR' in size: item_local.alive = "no" #Calidad del link en error, CF challenge? else: item_local.alive = "ok" #Calidad del link verificada if item_local.channel != 'setting': item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Seridor Torrent itemlist_t.append(item_local.clone()) #Pintar pantalla, si no se filtran idiomas # Requerido para FilterTools if config.get_setting('filter_languages', channel) > 0: #Si hay idioma seleccionado, se filtra itemlist_f = filtertools.get_link(itemlist_f, item_local, list_language) #Pintar pantalla, si no está vacío #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) #logger.debug(item_local) #Si es un lookup para cargar las urls de emergencia en la Videoteca... if item.videolibray_emergency_urls: return item #... nos vamos if len(itemlist_f) > 0: #Si hay entradas filtradas... itemlist.extend(itemlist_f) #Pintamos pantalla filtrada else: if config.get_setting('filter_languages', channel) > 0 and len(itemlist_t) > 0: #Si no hay entradas filtradas ... thumb_separador = get_thumb("next.png") #... pintamos todo con aviso itemlist.append(Item(channel=item.channel, url=host, title="[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]", thumbnail=thumb_separador, folder=False)) itemlist.extend(itemlist_t) #Pintar pantalla con todo si no hay filtrado # Requerido para AutoPlay autoplay.start(itemlist, item) #Lanzamos Autoplay return itemlist
def play( item ): #Permite preparar la descarga de los .torrents y subtítulos externos logger.info() itemlist = [] headers = [] from core import downloadtools from core import ziptools from core import filetools #buscamos la url del .torrent patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?">' patron += '\s*Torrent:<\/td><td class="(?:[^"]+)?">\s*<img src="(?:[^"]+)?"\s*' patron += 'alt="(?:[^"]+)?"\s*border="(?:[^"]+)?"\s*\/>\s*<a onmouseover="' patron += '(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?" href="([^"]+)".*?<\/a>' data, response, item, itemlist = generictools.downloadpage( item.url, timeout=timeout, patron=patron, item=item, itemlist=[], quote_rep=False, check_blocked_IP=True) if not data or response.code in [ 999, 99 ]: # Si ERROR o lista de errores lo reintentamos con otro Host return itemlist # ... Salimos item.url = urlparse.urljoin(host, scrapertools.find_single_match(data, patron)) #buscamos subtítulos en español patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*>\s*Subs.*?<\/td><td class="(?:[^"]+)?"\s*>(.*?)(?:<br\/>)?<\/td><\/tr>' data_subt = scrapertools.find_single_match(data, patron) if data_subt: patron = '<a href="([^"]+)"\s*onmouseover="return overlib\(' patron += "'Download Spanish subtitles'" patron += '\)"\s*onmouseout="(?:[^"]+)?"\s*><img src="(?:[^"]+)?"\s*><\/a>' subt = scrapertools.find_single_match(data_subt, patron) if subt: item.subtitle = urlparse.urljoin(host, subt) if item.subtitle: #Si hay urls de sub-títulos, se descargan from core import httptools headers.append(["User-Agent", httptools.get_user_agent() ]) #Se busca el User-Agent por defecto videolibrary_path = config.get_videolibrary_path( ) #Calculamos el path absoluto a partir de la Videoteca if videolibrary_path.lower().startswith( "smb://"): #Si es una conexión SMB, usamos userdata local videolibrary_path = config.get_data_path( ) #Calculamos el path absoluto a partir de Userdata videolibrary_path = filetools.join(videolibrary_path, "subtitles") #Primero se borra la carpeta de subtitulos para limpiar y luego se crea if filetools.exists(videolibrary_path): filetools.rmtree(videolibrary_path) time.sleep(1) if not filetools.exists(videolibrary_path): filetools.mkdir(videolibrary_path) subtitle_name = 'Rarbg-ES_SUBT.zip' #Nombre del archivo de sub-títulos subtitle_folder_path = filetools.join(videolibrary_path, subtitle_name) #Path de descarga ret = downloadtools.downloadfile(item.subtitle, subtitle_folder_path, headers=headers, continuar=True, silent=True) if filetools.exists(subtitle_folder_path): # Descomprimir zip dentro del addon # --------------------------------- try: unzipper = ziptools.ziptools() unzipper.extract(subtitle_folder_path, videolibrary_path) except: import xbmc xbmc.executebuiltin('Extract("%s", "%s")' % (subtitle_folder_path, videolibrary_path)) time.sleep(1) # Borrar el zip descargado # ------------------------ filetools.remove(subtitle_folder_path) #Tomo el primer archivo de subtítulos como valor por defecto for raiz, subcarpetas, ficheros in filetools.walk( videolibrary_path): for f in ficheros: if f.endswith(".srt"): #f_es = 'rarbg_subtitle.spa.srt' f_es = scrapertools.find_single_match( item.url, '&f=(.*?).torrent$').replace('.', ' ').replace( '-', ' ').lower() + '.spa.srt' if not f_es: f_es = item.infoLabels['originaltitle'] + '.spa.srt' f_es = f_es.replace(':', '').lower() filetools.rename( filetools.join(videolibrary_path, f), filetools.join(videolibrary_path, f_es)) item.subtitle = filetools.join( videolibrary_path, f_es) #Archivo de subtitulos break break itemlist.append(item.clone()) #Reproducción normal return itemlist
def menu_info(item): logger.info() itemlist = [] data = httptools.downloadpage(item.url).data data = re.sub(r"\n|\r|\t|\s{2}| |<br>", "", data) item.infoLabels["tmdb_id"] = scrapertools.find_single_match(data, '<a href="https://www.themoviedb.org/[^/]+/(\d+)') item.infoLabels["year"] = scrapertools.find_single_match(data, 'class="e_new">(\d{4})') item.infoLabels["plot"] = scrapertools.find_single_match(data, 'itemprop="description">([^<]+)</div>') item.infoLabels["genre"] = ", ".join(scrapertools.find_multiple_matches(data, '<a itemprop="genre"[^>]+>([^<]+)</a>')) if __modo_grafico__: tmdb.set_infoLabels_item(item, __modo_grafico__) action = "findvideos" title = "Ver enlaces" if item.contentType == "tvshow": action = "episodios" title = "Ver capítulos" itemlist.append(item.clone(action=action, title=title)) carpeta = "CINE" tipo = "película" action = "add_pelicula_to_library" extra = "" if item.contentType == "tvshow": carpeta = "SERIES" tipo = "serie" action = "add_serie_to_library" extra = "episodios###library" library_path = config.get_videolibrary_path() if config.get_videolibrary_support(): title = "Añadir %s a la videoteca" % tipo if item.infoLabels["imdb_id"] and not library_path.lower().startswith("smb://"): try: from core import filetools path = filetools.join(library_path, carpeta) files = filetools.walk(path) for dirpath, dirname, filename in files: if item.infoLabels["imdb_id"] in dirpath: namedir = dirpath.replace(path, '')[1:] for f in filename: if f != namedir + ".nfo" and f != "tvshow.nfo": continue from core import videolibrarytools head_nfo, it = videolibrarytools.read_nfo(filetools.join(dirpath, f)) canales = it.library_urls.keys() canales.sort() if "playmax" in canales: canales.pop(canales.index("playmax")) canales.insert(0, "[COLOR red]playmax[/COLOR]") title = "%s ya en tu videoteca. [%s] ¿Añadir?" % (tipo.capitalize(), ",".join(canales)) break except: import traceback logger.error(traceback.format_exc()) pass itemlist.append(item.clone(action=action, title=title, text_color=color5, extra=extra)) token_auth = config.get_setting("token_trakt", "tvmoviedb") if token_auth and item.infoLabels["tmdb_id"]: extra = "movie" if item.contentType != "movie": extra = "tv" itemlist.append(item.clone(channel="tvmoviedb", title="[Trakt] Gestionar con tu cuenta", action="menu_trakt", extra=extra)) itemlist.append(item.clone(channel="trailertools", action="buscartrailer", title="Buscar Tráiler", text_color="magenta", context="")) itemlist.append(item.clone(action="", title="")) ficha = scrapertools.find_single_match(item.url, '-f(\d+)-') if not ficha: ficha = scrapertools.find_single_match(item.url, 'f=(\d+)') itemlist.extend(acciones_fichas(item, sid, ficha, season=True)) itemlist.append(item.clone(action="acciones_cuenta", title="Añadir a una lista", text_color=color3, ficha=ficha)) return itemlist
def play( item ): #Permite preparar la descarga de los .torrents y subtítulos externos logger.info() itemlist = [] headers = [] import os from core import downloadtools from core import ziptools #buscamos la url del .torrent patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?">\s*Torrent:<\/td><td class="(?:[^"]+)?">\s*<img src="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*border="(?:[^"]+)?"\s*\/>\s*<a onmouseover="(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?" href="([^"]+)".*?<\/a>' try: data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data) data = unicode(data, "utf-8", errors="replace").encode("utf-8") except: pass status, itemlist = check_blocked_IP( data, itemlist) #Comprobamos si la IP ha sido bloqueada if status: return itemlist #IP bloqueada if not scrapertools.find_single_match(data, patron): logger.error( 'ERROR 02: PLAY: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log: PATRON: ' + patron + ' / DATA: ' + data) itemlist.append( item.clone( action='', title=item.channel.capitalize() + ': ERROR 02: PLAY: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log' )) return itemlist item.url = urlparse.urljoin(host, scrapertools.find_single_match(data, patron)) #buscamos subtítulos en español patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*>\s*Subs.*?<\/td><td class="(?:[^"]+)?"\s*>(.*?)(?:<br\/>)?<\/td><\/tr>' data_subt = scrapertools.find_single_match(data, patron) if data_subt: patron = '<a href="([^"]+)"\s*onmouseover="return overlib\(' patron += "'Download Spanish subtitles'" patron += '\)"\s*onmouseout="(?:[^"]+)?"\s*><img src="(?:[^"]+)?"\s*><\/a>' subt = scrapertools.find_single_match(data_subt, patron) if subt: item.subtitle = urlparse.urljoin(host, subt) if item.subtitle: #Si hay urls de sub-títulos, se descargan headers.append(["User-Agent", httptools.get_user_agent() ]) #Se busca el User-Agent por defecto videolibrary_path = config.get_videolibrary_path( ) #Calculamos el path absoluto a partir de la Videoteca if videolibrary_path.lower().startswith( "smb://"): #Si es una conexión SMB, usamos userdata local videolibrary_path = config.get_data_path( ) #Calculamos el path absoluto a partir de Userdata videolibrary_path = os.path.join(videolibrary_path, "subtitles") #Primero se borra la carpeta de subtitulos para limpiar y luego se crea if os.path.exists(videolibrary_path): import shutil shutil.rmtree(videolibrary_path, ignore_errors=True) time.sleep(1) if not os.path.exists(videolibrary_path): os.mkdir(videolibrary_path) subtitle_name = 'Rarbg-ES_SUBT.zip' #Nombre del archivo de sub-títulos subtitle_folder_path = os.path.join(videolibrary_path, subtitle_name) #Path de descarga ret = downloadtools.downloadfile(item.subtitle, subtitle_folder_path, headers=headers, continuar=True, silent=True) if os.path.exists(subtitle_folder_path): # Descomprimir zip dentro del addon # --------------------------------- try: unzipper = ziptools.ziptools() unzipper.extract(subtitle_folder_path, videolibrary_path) except: import xbmc xbmc.executebuiltin('XBMC.Extract("%s", "%s")' % (subtitle_folder_path, videolibrary_path)) time.sleep(1) # Borrar el zip descargado # ------------------------ os.remove(subtitle_folder_path) #Tomo el primer archivo de subtítulos como valor por defecto for raiz, subcarpetas, ficheros in os.walk(videolibrary_path): for f in ficheros: if f.endswith(".srt"): #f_es = 'rarbg_subtitle.spa.srt' f_es = scrapertools.find_single_match( item.url, '&f=(.*?).torrent$').replace('.', ' ').replace( '-', ' ').lower() + '.spa.srt' if not f_es: f_es = item.infoLabels['originaltitle'] + '.spa.srt' f_es = f_es.replace(':', '').lower() os.rename(os.path.join(videolibrary_path, f), os.path.join(videolibrary_path, f_es)) item.subtitle = os.path.join( videolibrary_path, f_es) #Archivo de subtitulos break break itemlist.append(item.clone()) #Reproducción normal return itemlist
def mark_season_as_watched_on_kodi(item, value=1): """ marca toda la temporada como vista o no vista en la libreria de Kodi @type item: item @param item: elemento a marcar @type value: int @param value: >0 para visto, 0 para no visto """ logger.info() # logger.debug("item:\n" + item.tostring('\n')) # Solo podemos marcar la temporada como vista en la BBDD de Kodi si la BBDD es local, # en caso de compartir BBDD esta funcionalidad no funcionara if config.get_setting("db_mode", "videolibrary"): return if value == 0: value = 'Null' request_season = '' if item.contentSeason: request_season = ' and c12= %s' % item.contentSeason request_episode = '' if item.contentSeason and item.contentEpisodeNumber: season_episode = '%sx%s.strm' % (str(item.contentSeason), str(item.contentEpisodeNumber).zfill(2)) request_episode = ' and strFileName= "%s"' % season_episode if item.video_path: path = item.video_path else: path = item.path if item.contentType == 'movie': video_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_movies")) view = 'movie' else: video_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows")) view = 'episode' item_path1 = "%" + path.replace("\\\\", "\\").replace(video_path, "") if item_path1[:-1] != "\\": item_path1 += "\\" item_path2 = item_path1.replace("\\", "/") while xbmc.getCondVisibility('Library.IsScanningVideo()'): # Por si la DB está Scanning time.sleep(1) sql = 'update files set playCount= %s where idFile in ' \ '(select idfile from %s_view where (strPath like "%s" or strPath like "%s")%s%s)' % \ (value, view, item_path1, item_path2, request_season, request_episode) nun_records, records = execute_sql_kodi(sql) if not nun_records: return # Lanzamos un scan de la Videoteca de Kodi contra un directorio vacío para forzar el refresco de los widgets de pelis y series payload = { "jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1, "params": {"directory": filetools.join(config.get_runtime_path(), 'tools')} } while xbmc.getCondVisibility('Library.IsScanningVideo()'): return # Ya está actualizando try: data = get_data(payload) """ # Recargamos el Skin para que actualice los widgets. Dejamos un tiempo para que termine la actualización xbmc.executebuiltin('ReloadSkin()') time.sleep(1) """ except: pass
def get_environment(): """ Devuelve las variables de entorno del OS, de Kodi y de Alfa más habituales, necesarias para el diagnóstico de fallos """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = str(platform.python_version()) environment['os_release'] = str(platform.release()) if xbmc.getCondVisibility("system.platform.Windows"): try: if platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) except: pass environment['prod_model'] = '' if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split('\n'): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( int(memoryStatus.dwTotalPhys) / (1024**2)) environment['mem_free'] = str( int(memoryStatus.dwAvailPhys) / (1024**2)) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]) / 1024) environment['mem_free'] = str( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]) / 1024) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join(xbmc.translatePath("special://userdata"), "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( int( scrapertools.find_single_match( label_a, '>(\d+)<\/')) / 1024**2) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, '>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, '>(.*?)<\/')) except: pass environment['userdata_path'] = str( xbmc.translatePath(config.get_data_path())) try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str( xbmc.translatePath(config.get_videolibrary_path())) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): environment['videolab_series'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))): environment['videolab_pelis'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))))) except: pass try: video_updates = ['No', 'Inicio', 'Una vez', 'Inicio+Una vez'] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' environment['torrentcli_option'] = '' environment['torrentcli_name'] = '' environment['torrentcli_dload_path'] = '' environment['torrentcli_buffer'] = '' environment['torrentcli_dload_estrgy'] = '' environment['torrentcli_mem_size'] = '' environment['torrentcli_free'] = '' torrent_id = config.get_setting("torrent_client", server="torrent", default=0) environment['torrentcli_option'] = str(torrent_id) if torrent_id > 0: torrent_id = torrent_id - 3 if torrent_id < 0: logger.error('torrent_id: ' + str(torrent_id) + ' / torrent_options: ' + str(platformtools.torrent_client_installed())) torrent_options = platformtools.torrent_client_installed() if torrent_options and torrent_id >= 0: environment['torrentcli_name'] = torrent_options[ torrent_id].replace('Plugin externo: ', '') if xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % environment['torrentcli_name']): __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % environment['torrentcli_name']) environment['torrentcli_name'] = environment[ 'torrentcli_name'].capitalize() if environment['torrentcli_name'] == 'Torrenter': environment['torrentcli_dload_path'] = str( xbmc.translatePath(__settings__.getSetting('storage'))) environment['torrentcli_buffer'] = str( __settings__.getSetting('pre_buffer_bytes')) else: environment['torrentcli_dload_path'] = str( xbmc.translatePath( __settings__.getSetting('download_path'))) environment['torrentcli_buffer'] = str( __settings__.getSetting('buffer_size')) environment['torrentcli_dload_estrgy'] = str( __settings__.getSetting('download_storage')) environment['torrentcli_mem_size'] = str( __settings__.getSetting('memory_size')) if environment['torrentcli_dload_path']: try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['torrentcli_dload_path']), None, None, ctypes.pointer(free_bytes)) environment['torrentcli_free'] = str(round(float(free_bytes.value) / \ (1024**3), 3)) else: disk_space = os.statvfs( environment['torrentcli_dload_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['torrentcli_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['torrentcli_free'] = '?' environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in proxy_channel_bloqued.items(): if proxy_active == 'ON': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk( xbmc.translatePath("special://logpath/")): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment['log_path']: environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024*1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = str(config.get_addon_version()) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['torrentcli_mem_size'] = '' environment['torrentcli_dload_path'] = '' environment['torrentcli_dload_estrgy'] = '' environment['machine'] = '' environment['platform'] = '' environment['torrentcli_buffer'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['torrentcli_free'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['torrentcli_name'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrentcli_option'] = '' return environment
def get_videos_watched_on_kodi(item, value=1, list_videos=False): """ Obtiene la lista de videos vistos o no vistos en la libreria de Kodi @type item: item @param item: elemento a obtener @type value: int @param value: >0 para visto, 0 para no visto @type list_videos: bool @param list_videos: True: devuelve la lista obtenida en la query @type Return: bool si list_videos=False @param Return: True si list_videos=False y todos tiene el estado "value". Si list_videos=True, devuelve lista de vídeos """ logger.info() # logger.debug("item:\n" + item.tostring('\n')) # Solo podemos obtener los vídeos como vistos en la BBDD de Kodi si la BBDD es local, # en caso de compartir BBDD esta funcionalidad no funcionara if config.get_setting("db_mode", "videolibrary"): return request_season = '' if item.contentSeason: request_season = ' and c12= %s' % item.contentSeason if item.video_path: path = item.video_path else: path = item.path if item.contentType == 'movie': video_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_movies")) view = 'movie' else: video_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows")) view = 'episode' tvshows_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows")) item_path1 = "%" + path.replace("\\\\", "\\").replace(tvshows_path, "") if item_path1[:-1] != "\\": item_path1 += "\\" item_path2 = item_path1.replace("\\", "/") sql = 'select strFileName, playCount from %s_view where (strPath like "%s" or strPath like "%s")' % (view, item_path1, item_path2) nun_records, records = execute_sql_kodi(sql, silent=True) if not nun_records: if list_videos: return {} else: return False records = filetools.decode(records, trans_none=0) records = dict(records) if list_videos: return records for path, mark in list(records.items()): if mark != value: return False return True
import errno import math import traceback from core import filetools from core import scraper from core import scrapertools from core.item import Item from platformcode import config, logger from platformcode import platformtools from lib import generictools FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") VIDEOLIBRARY_PATH = config.get_videolibrary_path() MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES) TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS) if not FOLDER_MOVIES or not FOLDER_TVSHOWS or not VIDEOLIBRARY_PATH \ or not filetools.exists(MOVIES_PATH) or not filetools.exists(TVSHOWS_PATH): config.verify_directories_created() addon_name = "plugin://plugin.video.%s/" % config.PLUGIN_NAME def read_nfo(path_nfo, item=None): """ Metodo para leer archivos nfo. Los arcivos nfo tienen la siguiente extructura: url_scraper | xml + item_json [url_scraper] y [xml] son opcionales, pero solo uno de ellos ha de existir siempre.
def next_ep(item): logger.info() condition = config.get_setting('next_ep') item.next_ep = False item.show_server = True VL = True if item.videolibrary else False time_over = False time_limit = time() + 30 time_steps = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120] time_setting = config.get_setting('next_ep_seconds') TimeFromEnd = time_setting if time_setting > 10 else time_steps[ time_setting] # wait until the video plays while not platformtools.is_playing() and time() < time_limit: sleep(1) while platformtools.is_playing() and time_over == False: try: Total = xbmc.Player().getTotalTime() Actual = xbmc.Player().getTime() Difference = Total - Actual if Total > TimeFromEnd >= Difference: time_over = True except: break if time_over: if condition == 1: # hide server afther x second item.show_server = False elif condition == 2: # play next fileif exist # check i next file exist current_filename = os.path.basename(item.strm_path) base_path = os.path.basename( os.path.normpath(os.path.dirname(item.strm_path))) path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"), base_path) fileList = [] for file in filetools.listdir(path): if file.endswith('.strm'): fileList.append(file) fileList.sort() nextIndex = fileList.index(current_filename) + 1 if nextIndex == 0 or nextIndex == len(fileList): next_file = None else: next_file = fileList[nextIndex] logger.info('NEXTFILE' + next_file) # start next episode window afther x time if next_file: from core.item import Item season_ep = next_file.split('.')[0] season = season_ep.split('x')[0] episode = season_ep.split('x')[1] next_ep = '%sx%s' % (season, episode) item = Item(action='play_from_library', channel='videolibrary', contentEpisodeNumber=episode, contentSeason=season, contentTitle=next_ep, contentType='tvshow', infoLabels={ 'episode': episode, 'mediatype': 'tvshow', 'season': season, 'title': next_ep }, strm_path=filetools.join(base_path, next_file)) global INFO INFO = filetools.join(path, next_file.replace("strm", "nfo")) logger.info('NEXTINFO' + INFO) nextDialog = NextDialog(ND, config.get_runtime_path()) nextDialog.show() while platformtools.is_playing( ) and not nextDialog.is_still_watching(): xbmc.sleep(100) pass nextDialog.close() logger.info('Next Episode: ' + str(nextDialog.stillwatching)) if nextDialog.stillwatching or nextDialog.continuewatching: item.next_ep = True xbmc.Player().stop() if VL: sleep(1) xbmc.executebuiltin('Action(Back)') sleep(0.5) from platformcode.launcher import play_from_library return play_from_library(item) else: item.show_server = False if VL: sleep(1) xbmc.executebuiltin('Action(Back)') sleep(0.5) return None return item
def menu_storage(item): logger.info() from core import filetools from servers.torrent import torrent_dirs FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") FOLDER = FOLDER_TVSHOWS if item.infoLabels['mediatype'] else FOLDER_MOVIES VIDEOLIBRARY_PATH = config.get_videolibrary_path() MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES) TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS) VIDEO_FOLDER = filetools.join(VIDEOLIBRARY_PATH, FOLDER) TORRENT_PATHS = torrent_dirs() MIS_TORRENT_FOLDER = filetools.join( config.get_setting('downloadpath', default=''), 'Mis_Torrents') itemlist = [] if 'videolibrary' in item.list_type: itemlist.append( Item(channel=item.channel, action="", title="Videoteca Alfa")) itemlist.append( Item(channel=item.channel, action="list_storage", url=MOVIES_PATH, title=" - " + FOLDER_MOVIES)) itemlist.append( Item(channel=item.channel, action="list_storage", url=TVSHOWS_PATH, title=" - " + FOLDER_TVSHOWS)) itemlist.append( Item(channel=item.channel, action="", title="Almacenamiento general")) itemlist.append( Item(channel=item.channel, action="list_storage", url=MIS_TORRENT_FOLDER, title=" - Mis Torrents")) itemlist.append( Item( channel=item.channel, action="btdigg", url="", title= " - Buscar Mis Torrents en [B][COLOR limegreen]BT[/COLOR][COLOR red]Digg[/COLOR][/B]" )) itemlist.append( Item(channel=item.channel, action="list_storage", url='', title=" - Almacenamiento")) if TORRENT_PATHS['TORREST_torrents'] or TORRENT_PATHS['QUASAR_torrents'] \ or TORRENT_PATHS['ELEMENTUM_torrents'] or TORRENT_PATHS['TORRENTER_torrents']: itemlist.append( Item(channel=item.channel, action="", title="Gestores Torrent")) if TORRENT_PATHS['TORREST_torrents']: itemlist.append( Item(channel=item.channel, action="list_storage", url=TORRENT_PATHS['TORREST_torrents'], title=" - Torrest")) if TORRENT_PATHS['QUASAR_torrents']: itemlist.append( Item(channel=item.channel, action="list_storage", url=TORRENT_PATHS['QUASAR_torrents'], title=" - Quasar")) if TORRENT_PATHS['ELEMENTUM_torrents']: itemlist.append( Item(channel=item.channel, action="list_storage", url=TORRENT_PATHS['ELEMENTUM_torrents'], title=" - Elementum")) if TORRENT_PATHS['TORRENTER_torrents']: itemlist.append( Item(channel=item.channel, action="list_storage", url=TORRENT_PATHS['TORRENTER_torrents'], title=" - Torrenter")) return itemlist
def move_to_libray(item): if item.contentType == 'movie': FOLDER = FOLDER_MOVIES path_title = "%s [%s]" % (item.contentTitle.strip(), item.infoLabels['IMDBNumber']) move_path = filetools.join(config.get_videolibrary_path(), FOLDER, path_title) else: FOLDER = FOLDER_TVSHOWS path_title = "%s [%s]" % (item.contentSerieName, item.infoLabels['IMDBNumber']) move_path = filetools.join(config.get_videolibrary_path(), FOLDER) download_path = filetools.join(config.get_setting("downloadpath"), item.downloadFilename) library_path = filetools.join(move_path, *filetools.split(item.downloadFilename)) final_path = download_path if config.get_setting("library_add", "downloads") == True and config.get_setting( "library_move", "downloads") == True: if not filetools.isdir(filetools.dirname(library_path)): filetools.mkdir(filetools.dirname(library_path)) if filetools.isfile(library_path) and filetools.isfile(download_path): filetools.remove(library_path) if filetools.isfile(download_path): if filetools.move(download_path, library_path): final_path = library_path if len(filetools.listdir(filetools.dirname(download_path))) == 0: filetools.rmdir(filetools.dirname(download_path)) logger.info('ITEM = ' + str(item)) name = item.contentTitle if item.contentType == 'movie' else str( item.infoLabels['season']) + 'x' + str( item.infoLabels['episode']).zfill(2) list_item = os.listdir( filetools.join(config.get_videolibrary_path(), FOLDER, path_title)) clean = False for File in list_item: filename = File.lower() name = name.lower() if filename.startswith(name) and (filename.endswith('.strm') or filename.endswith('.json') or filename.endswith('.nfo')): clean = True logger.info('Delete File: ' + str( os.path.join(config.get_videolibrary_path(), FOLDER, path_title, File))) os.remove( os.path.join(config.get_videolibrary_path(), FOLDER, path_title, File)) from platformcode import xbmc_videolibrary xbmc_videolibrary.update(FOLDER) if clean == True: import xbmc while xbmc.getCondVisibility('Library.IsScanningVideo()'): xbmc.sleep(500) xbmc_videolibrary.clean() if config.get_setting("library_add", "downloads") == True and config.get_setting( "library_move", "downloads") == False: if filetools.isfile(final_path): if item.contentType == "movie" and item.infoLabels["tmdb_id"]: library_item = Item(title=config.get_localized_string(70228) % item.downloadFilename, channel="downloads", action="findvideos", infoLabels=item.infoLabels, url=final_path) videolibrarytools.save_movie(library_item) elif item.contentType == "episode" and item.infoLabels["tmdb_id"]: library_item = Item(title=config.get_localized_string(70228) % item.downloadFilename, channel="downloads", action="findvideos", infoLabels=item.infoLabels, url=final_path) tvshow = Item( channel="downloads", contentType="tvshow", infoLabels={"tmdb_id": item.infoLabels["tmdb_id"]}) videolibrarytools.save_tvshow(tvshow, [library_item])
def findvideos(item): logger.info() from core import filetools from lib import generictools itemlist = [] size = '' torrent_params = { 'url': item.url, 'torrents_path': None, 'local_torr': item.torrents_path, 'lookup': False, 'force': True, 'data_torrent': True, 'subtitles': True, 'file_list': True } #logger.debug(item) FOLDER_MOVIES = config.get_setting("folder_movies") FOLDER_TVSHOWS = config.get_setting("folder_tvshows") FOLDER = FOLDER_TVSHOWS if item.infoLabels[ 'mediatype'] == 'episode' else FOLDER_MOVIES VIDEOLIBRARY_PATH = config.get_videolibrary_path() MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES) TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS) VIDEO_FOLDER = filetools.join(VIDEOLIBRARY_PATH, FOLDER) # Viene desde Kodi/Videoteca de una canal desactivado if not item.list_type: if item.emergency_urls: # Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB item.infoLabels['playcount'] = 0 if item.contentChannel == 'videolibrary': item.armagedon = True # Lo marcammos como URLs de Emergencia item.channel_recovery = 'url' item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) for x, link in enumerate(item.emergency_urls[0]): quality = item.quality if link.startswith('magnet'): link_path = link item.torrents_path = '' else: link_path = filetools.join(VIDEO_FOLDER, link) if link_path.startswith('magnet') or filetools.isfile( link_path): if btdigg_magnet in link_path and len( item.emergency_urls) > 3 and len( item.emergency_urls[3]) >= x + 1: try: z, quality, size = item.emergency_urls[3][x].split( '#') except: pass else: torrent_params['url'] = link_path torrent_params['torrents_path'] = link_path torrent_params['local_torr'] = link_path torrent_params = generictools.get_torrent_size( link_path, torrent_params=torrent_params, item=item) # Tamaño en el .torrent size = torrent_params['size'] item.torrents_path = torrent_params['torrents_path'] if size: # Generamos una copia de Item para trabajar sobre ella item_local = item.clone() item_local.channel = 'url' item_local.url = link_path if btdigg_magnet in item_local.url: item_local.btdigg = True item_local.torrent_info = size item_local.quality = quality # Si viene de la Videoteca de Kodi, mostramos que son URLs de Emergencia if item_local.contentChannel == 'videolibrary': item_local.quality = '[COLOR hotpink][E][/COLOR] [COLOR limegreen]%s[/COLOR]' % item_local.quality #Ahora pintamos el link del Torrent item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \ + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \ (item_local.quality, str(item_local.language), \ item_local.torrent_info) # Preparamos título y calidad, quitando etiquetas vacías item_local.title = re.sub( r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) item_local.title = re.sub( r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) item_local.title = item_local.title.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() item_local.quality = re.sub( r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) item_local.quality = re.sub( r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) item_local.quality = item_local.quality.replace("--", "").replace("[]", "")\ .replace("()", "").replace("(/)", "").replace("[/]", "")\ .replace("|", "").strip() if not size or 'Magnet' in size: item_local.alive = "??" #Calidad del link sin verificar elif 'ERROR' in size and 'Pincha' in size: item_local.alive = "ok" #link en error, CF challenge, Chrome disponible elif 'ERROR' in size and 'Introduce' in size: item_local.alive = "??" #link en error, CF challenge, ruta de descarga no disponible item_local.channel = 'setting' item_local.action = 'setting_torrent' item_local.unify = False item_local.folder = False item_local.item_org = item.tourl() elif 'ERROR' in size: item_local.alive = "no" #Calidad del link en error, CF challenge? else: item_local.alive = "ok" #Calidad del link verificada item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Seridor Torrent itemlist.append(item_local) #Pintar pantalla #logger.debug(item_local) return itemlist
def init(): logger.info() """ Todo el código añadido al add-on se borra con cada actualización. Esta función permite restaurarlo automáticamente con cada actualización. Esto permite al usuario tener su propio código, bajo su responsabilidad, y restaurarlo al add-on cada vez que se actualiza. El mecanismo funciona copiando el contenido de la carpeta-arbol "./userdata/addon_data/plugin.video.alfa/custom_code/..." sobre las carpetas de código del add-on. No verifica el contenido, solo vuelca(reemplaza) el contenido de "custom_code". El usuario almacenará en las subcarpetas de "custom_code" su código actualizado y listo para ser copiado en cualquier momento. Si no se desea que copie algo, simplemente se borra de "custom_code" y ya no se copiará en la próxima actualización. Los pasos que sigue esta función, son los siguientes: 1.- La función se llama desde videolibrary_service.py, desde la función inicial: # Copia Custom code a las carpetas de Alfa desde la zona de Userdata from platformcode import custom_code custom_code.init() 2.- En el inicio de Kodi, comprueba si existe la carpeta "custom_code" en "./userdata/addon_data/plugin.video.alfa/". Si no existe, la crea y sale sin más, dando al ususario la posibilidad de copiar sobre esa estructura su código, y que la función la vuelque sobre el add-on en el próximo inicio de Kodi. 3.- En el siguiente inicio de Kodi, comprueba si existe el custom_code.json en la carpeta root del add-on. Si no existe, lo crea con el número de versión del add-on vacío, para permitir que se copien los archivos en esta pasada. 4.- Verifica que el número de versión del add-on es diferente de el de custom_code.json. Si es la misma versión, se sale porque ya se realizo la copia anteriormente. Si la versión es distinta, se realiza el volcado de todos los archivos de la carpeta-árbol "custom_code" sobre el add-on. Si la carpeta de destino no existe, dará un error y se cancelará la copia. Se considera que no tienen sentido nuevas carpetas. 5.- Si la copia ha terminado con éxito, se actualiza el custom_code.json con el número de versión del add-on, para que en inicios sucesivos de Kodi no se realicen las copias, hasta que el add-on cambie de versión. En el número de versión del add-on no se considera el número de fix. Tiempos: Copiando 7 archivos de prueba, el proceso ha tardado una décima de segundo. """ try: #Limpiamos los mensajes de ayuda obsoletos y restauramos los que tienen "version": True. Por cada nueva versión if not filetools.exists(ADDON_CUSTOMCODE_JSON): from platformcode import help_window help_window.clean_watched_new_version() #Se realizan algunas funciones con cada nueva versión de Alfa if not filetools.exists(ADDON_CUSTOMCODE_JSON): config.set_setting('cf_assistant_ua', '') # Se limpia CF_UA. Mejora de rendimiento en httptools CF #Se verifica si están bien las rutas a la videoteca config.verify_directories_created() #Comprime la BD de cache de TMDB para evitar que crezca demasiado bd_tmdb_maintenance() if config.get_setting('tmdb_cache_expire', default=4) == 4: config.set_setting('tmdb_cache_expire', 2) #Borra el .zip de instalación de Alfa de la carpeta Packages, por si está corrupto, y que así se pueda descargar de nuevo #version = 'plugin.video.alfa-%s.zip' % ADDON_VERSION #filetools.remove(filetools.join('special://home', 'addons', 'packages', version), True) #Verifica si es necesario instalar script.alfa-update-helper verify_script_alfa_update_helper() #Borrar contenido de carpeta de Torrents y de Subtitles filetools.rmdirtree(filetools.join(config.get_videolibrary_path(), 'temp_torrents_arch'), silent=True) filetools.rmdirtree(filetools.join(config.get_videolibrary_path(), 'temp_torrents_Alfa'), silent=True) subtitle_path = config.get_kodi_setting("subtitles.custompath") if subtitle_path and filetools.exists(subtitle_path): for file in filetools.listdir(subtitle_path): if not file.endswith('.srt'): continue file_path = filetools.join(subtitle_path, file) ret = filetools.remove(file_path, silent=True) if not ret: logger.error('ERROR on REMOVING subtitle: ' + file_path) #Verifica si Kodi tiene algún achivo de Base de Datos de Vídeo de versiones anteriores, entonces los borra verify_Kodi_video_DB() #Verifica si la Base de Datos de Vídeo tiene la fuente de CINE con useFolderNames=1 try: threading.Thread(target=set_Kodi_video_DB_useFolderNames).start() # Creamos un Thread independiente por si la DB está Scanning time.sleep(1) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, nos vamos logger.error(traceback.format_exc()) #LIBTORRENT: se descarga el binario de Libtorrent cada vez que se actualiza Alfa update_libtorrent() #TORREST: Modificaciones temporales if xbmc.getCondVisibility('System.HasAddon("plugin.video.torrest")'): try: __settings__ = xbmcaddon.Addon(id="plugin.video.torrest") if __settings__.getSetting("s:check_available_space") == 'true': __settings__.setSetting("s:check_available_space", "false") # No comprobar espacio disponible hasta que lo arreglen #if not filetools.exists(filetools.join(config.get_data_path(), "quasar.json")) \ # and not config.get_setting('addon_quasar_update', default=False): # question_update_external_addon("torrest") except: pass #QUASAR: Preguntamos si se hacen modificaciones a Quasar if not filetools.exists(filetools.join(config.get_data_path(), "quasar.json")) \ and not config.get_setting('addon_quasar_update', default=False): question_update_external_addon("quasar") #QUASAR: Hacemos las modificaciones a Quasar, si está permitido, y si está instalado if config.get_setting('addon_quasar_update', default=False) or \ (filetools.exists(filetools.join(config.get_data_path(), \ "quasar.json")) and xbmc.getCondVisibility('System.HasAddon("plugin.video.quasar")')): if not update_external_addon("quasar"): platformtools.dialog_notification("Actualización Quasar", "Ha fallado. Consulte el log") #Existe carpeta "custom_code" ? Si no existe se crea y se sale custom_code_dir = filetools.join(ADDON_USERDATA_PATH, 'custom_code') custom_code_json_path = ADDON_PATH custom_code_json = ADDON_CUSTOMCODE_JSON if not filetools.exists(custom_code_dir): create_folder_structure(custom_code_dir) #Existe "custom_code.json" ? Si no existe se crea if not filetools.exists(custom_code_json): create_json(custom_code_json_path) #Se verifica si la versión del .json y del add-on son iguales. Si es así se sale. Si no se copia "custom_code" al add-on verify_copy_folders(custom_code_dir, custom_code_json_path) #Si se han quedado "colgadas" descargas con archivos .RAR, se intenta identificarlos y reactivar el UnRar reactivate_unrar(init=True, mute=True) #Inicia un rastreo de vídeos decargados desde .torrent: marca los VISTOS y elimina los controles de los BORRADOS from servers.torrent import mark_torrent_as_watched try: threading.Thread(target=mark_torrent_as_watched).start() # Creamos un Thread independiente, hasta el fin de Kodi time.sleep(2) # Dejamos terminar la inicialización... except: # Si hay problemas de threading, nos vamos logger.error(traceback.format_exc()) #Ejecuta la sobrescritura de la videoteca para los canales seleccionados reset_videotlibrary_by_channel() except: logger.error(traceback.format_exc())