Files
addon/servers/torrent.py
2020-04-20 19:51:22 +02:00

1357 lines
62 KiB
Python
Executable File

# -*- coding: utf-8 -*-
import sys
# from builtins import str
from builtins import range
PY3 = False
VFS = True
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int; VFS = False
if PY3:
#from future import standard_library
#standard_library.install_aliases()
import urllib.parse as urllib # Es muy lento en PY2. En PY3 es nativo
else:
import urllib
import time
import os
import traceback
import re
try:
import xbmc
import xbmcgui
import xbmcaddon
except:
pass
from core import filetools
from core import httptools
from core import scrapertools
from core import jsontools
from platformcode import logger
from platformcode import config
from platformcode import platformtools
trackers = [
"udp://tracker.openbittorrent.com:80/announce",
"http://tracker.torrentbay.to:6969/announce",
"http://tracker.pow7.com/announce",
"udp://tracker.ccc.de:80/announce",
"udp://open.demonii.com:1337",
"http://9.rarbg.com:2710/announce",
"http://bt.careland.com.cn:6969/announce",
"http://explodie.org:6969/announce",
"http://mgtracker.org:2710/announce",
"http://tracker.best-torrents.net:6969/announce",
"http://tracker.tfile.me/announce",
"http://tracker1.wasabii.com.tw:6969/announce",
"udp://9.rarbg.com:2710/announce",
"udp://9.rarbg.me:2710/announce",
"udp://coppersurfer.tk:6969/announce",
"http://www.spanishtracker.com:2710/announce",
"http://www.todotorrents.com:2710/announce",
]
# Returns an array of possible video url's from the page_url
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
torrent_options = platformtools.torrent_client_installed(show_tuple=True)
if len(torrent_options) == 0:
from specials import elementum_download
elementum_download.download()
logger.info("server=torrent, the url is the good")
if page_url.startswith("magnet:"):
video_urls = [["magnet: [torrent]", page_url]]
else:
video_urls = [[".torrent [torrent]", page_url]]
return video_urls
class XBMCPlayer(xbmc.Player):
def __init__(self, *args):
pass
xbmc_player = XBMCPlayer()
def caching_torrents(url, referer=None, post=None, torrents_path=None, timeout=10, \
lookup=False, data_torrent=False, headers={}, proxy_retries=1):
if torrents_path != None:
logger.info("path = " + torrents_path)
else:
logger.info()
if referer and post:
logger.info('REFERER: ' + referer)
torrent_file = ''
t_hash = ''
if referer:
headers.update({'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
torrents_path_encode = torrents_path
#if url.endswith(".rar") or url.startswith("magnet:"): #No es un archivo .torrent
if url.endswith(".rar"): #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 url.startswith("magnet:"):
if config.get_setting("magnet2torrent", server="torrent", default=False):
torrent_file = magnet2torrent(url, headers=headers) #Convierte el Magnet en un archivo Torrent
else:
if data_torrent:
return (url, torrent_file)
return url
if not torrent_file:
logger.error('No es un archivo Magnet: ' + url)
torrents_path = ''
if data_torrent:
return (torrents_path, torrent_file)
return torrents_path #Si hay un error, devolvemos el "path" vacío
else:
if lookup:
proxy_retries = 0
if post: #Descarga con POST
response = httptools.downloadpage(url, headers=headers, post=post, \
follow_redirects=False, timeout=timeout, proxy_retries=proxy_retries)
else: #Descarga sin post
response = httptools.downloadpage(url, headers=headers, timeout=timeout, \
proxy_retries=proxy_retries)
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
torrent_file_uncoded = response.data
if PY3 and isinstance(torrent_file, bytes):
torrent_file = "".join(chr(x) for x in bytes(torrent_file_uncoded))
#Si es un archivo .ZIP tratamos de extraer el contenido
if torrent_file.startswith("PK"):
logger.info("it's a zip archive: " + 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_uncoded, vfs=VFS): #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)
for root, folders, files in filetools.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, vfs=VFS) #leemos el .torrent
torrent_file_uncoded = torrent_file
if PY3 and isinstance(torrent_file, bytes):
torrent_file = "".join(chr(x) for x in bytes(torrent_file_uncoded))
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
#Calculamos el Hash del Torrent y modificamos el path
import bencode, hashlib
decodedDict = bencode.bdecode(torrent_file_uncoded)
if not PY3:
t_hash = hashlib.sha1(bencode.bencode(decodedDict[b"info"])).hexdigest()
else:
t_hash = hashlib.sha1(bencode.bencode(decodedDict["info"])).hexdigest()
if t_hash:
torrents_path = filetools.join(filetools.dirname(torrents_path), t_hash + '.torrent')
torrents_path_encode = filetools.join(filetools.dirname(torrents_path_encode), t_hash + '.torrent')
#Salvamos el .torrent
if not lookup:
if not filetools.write(torrents_path_encode, torrent_file_uncoded, vfs=VFS):
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 magnet2torrent(magnet, headers={}):
logger.info()
torrent_file = ''
info = ''
post = ''
LIBTORRENT_PATH = config.get_setting("libtorrent_path", server="torrent", default="")
LIBTORRENT_MAGNET_PATH = filetools.join(config.get_setting("downloadpath"), 'magnet')
MAGNET2TORRENT = config.get_setting("magnet2torrent", server="torrent", default=False)
btih = scrapertools.find_single_match(magnet, 'urn:btih:([\w\d]+)\&').upper()
if magnet.startswith('magnet') and MAGNET2TORRENT:
# Tratamos de convertir el magnet on-line (opción más rápida, pero no se puede convertir más de un magnet a la vez)
url_list = [
('https://itorrents.org/torrent/', 6, '', '.torrent')
] # Lista de servicios on-line testeados
for url, timeout, id, sufix in url_list:
if id:
post = '%s=%s' % (id, magnet)
else:
url = '%s%s%s' % (url, btih, sufix)
response = httptools.downloadpage(url, timeout=timeout, headers=headers, post=post)
if not response.sucess:
continue
if not scrapertools.find_single_match(response.data, '^d\d+:.*?\d+:') and not response.data.startswith("PK"):
continue
torrent_file = response.data
break
#Usamos Libtorrent para la conversión del magnet como alternativa (es lento)
if not torrent_file:
lt, e, e1, e2 = import_libtorrent(LIBTORRENT_PATH) # Importamos Libtorrent
if lt:
ses = lt.session() # Si se ha importado bien, activamos Libtorrent
ses.add_dht_router("router.bittorrent.com",6881)
ses.add_dht_router("router.utorrent.com",6881)
ses.add_dht_router("dht.transmissionbt.com",6881)
if ses:
filetools.mkdir(LIBTORRENT_MAGNET_PATH) # Creamos la carpeta temporal
params = {
'save_path': LIBTORRENT_MAGNET_PATH,
'trackers': trackers,
'storage_mode': lt.storage_mode_t.storage_mode_allocate
} # Creamos los parámetros de la sesión
h = lt.add_magnet_uri(ses, magnet, params) # Abrimos la sesión
i = 0
while not h.has_metadata() and not xbmc.abortRequested: # Esperamos mientras Libtorrent abre la sesión
h.force_dht_announce()
time.sleep(1)
i += 1
logger.error(i)
if i > 5:
LIBTORRENT_PATH = '' # No puede convertir el magnet
break
if LIBTORRENT_PATH:
info = h.get_torrent_info() # Obtiene la información del .torrent
torrent_file = lt.bencode(lt.create_torrent(info).generate()) # Obtiene los datos del .torrent
ses.remove_torrent(h) # Desactiva Libtorrent
filetools.rmdirtree(LIBTORRENT_MAGNET_PATH) # Elimina la carpeta temporal
return torrent_file
def verify_url_torrent(url, timeout=5):
"""
Verifica si el archivo .torrent al que apunta la url está disponible, descargándolo en un area temporal
Entrada: url
Salida: True o False dependiendo del resultado de la operación
"""
if not url or url == 'javascript:;': #Si la url viene vacía...
return False #... volvemos con error
torrents_path = caching_torrents(url, timeout=timeout, lookup=True) #Descargamos el .torrent
if torrents_path: #Si ha tenido éxito...
return True
else:
return False
# Reproductor Cliente Torrent propio (libtorrent)
def bt_client(mediaurl, xlistitem, rar_files, subtitle=None, password=None, item=None):
logger.info()
# Importamos el cliente
from btserver import Client
played = False
debug = False
try:
save_path_videos = ''
save_path_videos = filetools.join(config.get_setting("bt_download_path", server="torrent", \
default=config.get_setting("downloadpath")), 'BT-torrents')
except:
pass
if not config.get_setting("bt_download_path", server="torrent") and save_path_videos:
config.set_setting("bt_download_path", filetools.join(config.get_data_path(), 'downloads'), server="torrent")
if not save_path_videos:
save_path_videos = filetools.join(config.get_data_path(), 'downloads', 'BT-torrents')
config.set_setting("bt_download_path", filetools.join(config.get_data_path(), 'downloads'), server="torrent")
UNRAR = config.get_setting("unrar_path", server="torrent", default="")
BACKGROUND = config.get_setting("mct_background_download", server="torrent", default=True)
RAR = config.get_setting("mct_rar_unpack", server="torrent", default=True)
try:
BUFFER = int(config.get_setting("bt_buffer", server="torrent", default="50"))
except:
BUFFER = 50
DOWNLOAD_LIMIT = config.get_setting("mct_download_limit", server="torrent", default="")
if DOWNLOAD_LIMIT:
try:
DOWNLOAD_LIMIT = int(DOWNLOAD_LIMIT)
except:
DOWNLOAD_LIMIT = 0
else:
DOWNLOAD_LIMIT = 0
UPLOAD_LIMIT = 100
torr_client = 'BT'
rar_file = ''
rar_names = []
rar = False
rar_res = False
bkg_user = False
video_names = []
video_file = ''
video_path = ''
videourl = ''
msg_header = 'KoD %s Client Torrent' % torr_client
extensions_list = ['.aaf', '.3gp', '.asf', '.avi', '.flv', '.mpeg',
'.m1v', '.m2v', '.m4v', '.mkv', '.mov', '.mpg',
'.mpe', '.mp4', '.ogg', '.rar', '.wmv', '.zip']
for entry in rar_files:
for file, path in list(entry.items()):
if file == 'path' and '.rar' in str(path):
for file_r in path:
rar_names += [file_r]
rar = True
if RAR and BACKGROUND:
bkg_user = True
elif file == 'path' and not '.rar' in str(path):
for file_r in path:
if os.path.splitext(file_r)[1] in extensions_list:
video_names += [file_r]
elif file == '__name':
video_path = path
video_file = path
if rar: rar_file = '%s/%s' % (video_path, rar_names[0])
erase_file_path = filetools.join(save_path_videos, video_path)
video_path = erase_file_path
if video_names: video_file = video_names[0]
if not video_file and mediaurl.startswith('magnet'):
video_file = urllib.unquote_plus(scrapertools.find_single_match(mediaurl, '(?:\&|&)dn=([^\&]+)\&'))
erase_file_path = filetools.join(save_path_videos, video_file)
if rar and RAR and not UNRAR:
if not platformtools.dialog_yesno(msg_header, config.get_localized_string(70791)):
return
# Iniciamos el cliente:
c = Client(url=mediaurl, is_playing_fnc=xbmc_player.isPlaying, wait_time=None, auto_shutdown=False, timeout=10,
temp_path=save_path_videos, print_status=debug, auto_delete=False)
activo = True
finalizado = False
dp_cerrado = True
# Mostramos el progreso
if rar and RAR and BACKGROUND: # Si se descarga un RAR...
progreso = platformtools.dialog_progress_bg(msg_header)
platformtools.dialog_notification(config.get_localized_string(70790), config.get_localized_string(70769), time=10000)
else:
progreso = platformtools.dialog_progress('%s Torrent Client' % torr_client, '')
dp_cerrado = False
# Mientras el progreso no sea cancelado ni el cliente cerrado
try:
while not c.closed and not xbmc.abortRequested:
# Obtenemos el estado del torrent
s = c.status
if debug:
# Montamos las tres lineas con la info del torrent
txt = '%.2f%% de %.1fMB %s | %.1f kB/s' % \
(s.progress_file, s.file_size, s.str_state, s._download_rate)
txt2 = 'S: %d(%d) P: %d(%d) | DHT:%s (%d) | Trakers: %d | Pi: %d(%d)' % \
(s.num_seeds, s.num_complete, s.num_peers, s.num_incomplete, s.dht_state, s.dht_nodes,
s.trackers, s.pieces_sum, s.pieces_len)
txt3 = 'Origen Peers TRK: %d DHT: %d PEX: %d LSD %d ' % \
(s.trk_peers, s.dht_peers, s.pex_peers, s.lsd_peers)
else:
txt = '%.2f%% de %.1fMB %s | %.1f kB/s' % \
(s.progress_file, s.file_size, s.str_state, s._download_rate)
txt2 = 'S: %d(%d) P: %d(%d) | DHT:%s (%d) | Trakers: %d | Pi: %d(%d)' % \
(s.num_seeds, s.num_complete, s.num_peers, s.num_incomplete, s.dht_state, s.dht_nodes,
s.trackers, s.pieces_sum, s.pieces_len)
txt3 = video_file
if rar and RAR and BACKGROUND or bkg_user:
progreso.update(s.buffer, txt, txt2)
else:
progreso.update(s.buffer, txt, txt2, txt3)
time.sleep(1)
if (not bkg_user and progreso.iscanceled()) and (not (rar and RAR and BACKGROUND) and progreso.iscanceled()):
if not dp_cerrado:
progreso.close()
dp_cerrado = True
if 'Finalizado' in s.str_state or 'Seeding' in s.str_state:
"""
if not rar and platformtools.dialog_yesno(msg_header, config.get_localized_string(70198)):
played = False
dp_cerrado = False
progreso = platformtools.dialog_progress(msg_header, '')
progreso.update(s.buffer, txt, txt2, txt3)
else:
"""
dp_cerrado = False
progreso = platformtools.dialog_progress(msg_header, '')
break
else:
if not platformtools.dialog_yesno(msg_header, config.get_localized_string(30031), config.get_localized_string(30032)):
dp_cerrado = False
progreso = platformtools.dialog_progress(msg_header, '')
break
else:
bkg_user = True
if not dp_cerrado: progreso.close()
dp_cerrado = False
progreso = platformtools.dialog_progress_bg(msg_header)
progreso.update(s.buffer, txt, txt2)
if not c.closed:
c.set_speed_limits(DOWNLOAD_LIMIT, UPLOAD_LIMIT) # Bajamos la velocidad en background
# Si el buffer se ha llenado y la reproduccion no ha sido iniciada, se inicia
if ((s.pieces_sum >= BUFFER or 'Finalizado' in s.str_state or 'Seeding' in s.str_state) and not rar and not bkg_user) or \
(s.pieces_sum >= s.pieces_len - 3 and s.pieces_len > 0 and ('Finalizado' in s.str_state or 'Seeding' \
in s.str_state) and (rar or bkg_user)) and not played:
if rar and RAR and UNRAR:
c.stop()
activo = False
finalizado = True
bkg_user = False
dp_cerrado = False
video_file, rar_res, video_path, erase_file_path = extract_files(rar_file, \
save_path_videos, password, progreso, item, torr_client) # ... extraemos el vídeo del RAR
if rar_res and not xbmc.abortRequested:
time.sleep(1)
else:
break
elif (rar and not UNRAR) or (rar and not RAR):
break
elif bkg_user:
finalizado = True
break
# Cerramos el progreso
if not dp_cerrado:
progreso.close()
dp_cerrado = True
# Reproducimos el vídeo extraido, si no hay nada en reproducción
if not c.closed:
c.set_speed_limits(DOWNLOAD_LIMIT, UPLOAD_LIMIT) # Bajamos la velocidad en background
bkg_auto = True
while xbmc_player.isPlaying() and not xbmc.abortRequested:
time.sleep(3)
# Obtenemos el playlist del torrent
#videourl = c.get_play_list()
if not rar_res: # Es un Magnet ?
video_file = filetools.join(save_path_videos, s.file_name)
if erase_file_path == save_path_videos:
erase_file_path = video_file
videourl = video_file
else:
videourl = filetools.join(video_path, video_file)
# Iniciamos el reproductor
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear()
playlist.add(videourl, xlistitem)
# xbmc_player = xbmc_player
log("##### videourl: %s" % videourl)
xbmc_player.play(playlist)
# Marcamos como reproducido para que no se vuelva a iniciar
played = True
mark_auto_as_watched(item)
# Y esperamos a que el reproductor se cierre
bkg_auto = True
dp_cerrado = True
while xbmc_player.isPlaying() and not xbmc.abortRequested:
time.sleep(1)
if xbmc.getCondVisibility('Player.Playing'):
if not dp_cerrado:
dp_cerrado = True
progreso.close()
if xbmc.getCondVisibility('Player.Paused') and not rar_res:
if not c.closed: s = c.status
txt = '%.2f%% de %.1fMB %s | %.1f kB/s' % \
(s.progress_file, s.file_size, s.str_state, s._download_rate)
txt2 = 'S: %d(%d) P: %d(%d) | DHT:%s (%d) | Trakers: %d | Pi: %d(%d)' % \
(s.num_seeds, s.num_complete, s.num_peers, s.num_incomplete, s.dht_state, s.dht_nodes,
s.trackers, s.pieces_sum, s.pieces_len)
txt3 = video_file[:99]
if dp_cerrado:
dp_cerrado = False
progreso = xbmcgui.DialogProgressBG()
progreso.create(msg_header)
progreso.update(s.buffer, msg_header, '[CR][CR]' + txt + '[CR]' + txt2)
if not dp_cerrado:
dp_cerrado = True
progreso.close()
# Miramos si se ha completado la descarga para borrar o no los archivos
if activo:
s = c.status
if s.pieces_sum == s.pieces_len:
finalizado = True
break
if not platformtools.dialog_yesno(msg_header, config.get_localized_string(30031), config.get_localized_string(30032)):
progreso = platformtools.dialog_progress(msg_header, '')
dp_cerrado = False
break
else:
bkg_user = True
played = False
if not dp_cerrado: progreso.close()
progreso = platformtools.dialog_progress_bg(msg_header)
progreso.update(s.buffer, txt, txt2)
dp_cerrado = False
continue
# Cuando este cerrado, Volvemos a mostrar el dialogo
if not (rar and bkg_user):
progreso = platformtools.dialog_progress(msg_header, '')
progreso.update(s.buffer, txt, txt2, txt3)
dp_cerrado = False
break
except:
logger.error(traceback.format_exc(1))
return
if not dp_cerrado:
if rar or bkg_user:
progreso.update(100, config.get_localized_string(70200), " ")
else:
progreso.update(100, config.get_localized_string(70200), " ", " ")
# Detenemos el cliente
if activo and not c.closed:
c.stop()
activo = False
# Cerramos el progreso
if not dp_cerrado:
progreso.close()
dp_cerrado = True
# Y borramos los archivos de descarga restantes
time.sleep(1)
if filetools.exists(erase_file_path) and not bkg_user:
if finalizado and not platformtools.dialog_yesno(msg_header, config.get_localized_string(70792)):
return
log("##### erase_file_path: %s" % erase_file_path)
for x in range(10):
if filetools.isdir(erase_file_path):
if erase_file_path != save_path_videos:
filetools.rmdirtree(erase_file_path)
else:
break
else:
filetools.remove(erase_file_path)
time.sleep(5)
if not filetools.exists(erase_file_path):
break
def call_torrent_via_web(mediaurl, torr_client):
# Usado para llamar a los clientes externos de Torrents para automatizar la descarga de archivos que contienen .RAR
logger.info()
post = ''
ELEMENTUMD_HOST = "http://localhost:65220"
if torr_client == 'elementum':
try:
ADDON = xbmcaddon.Addon("plugin.video.elementum")
except:
ADDON = False
if ADDON:
ELEMENTUMD_HOST = "http://" + ADDON.getSetting("remote_host") + ":" + ADDON.getSetting("remote_port")
local_host = {"quasar": ["http://localhost:65251/torrents/", "add?uri"], \
"elementum": ["%s/torrents/" % ELEMENTUMD_HOST, "add"]}
if torr_client == "quasar":
uri = '%s%s=%s' % (local_host[torr_client][0], local_host[torr_client][1], mediaurl)
elif torr_client == "elementum":
uri = '%s%s' % (local_host[torr_client][0], local_host[torr_client][1])
post = 'uri=%s&file=null&all=1' % mediaurl
if post:
response = httptools.downloadpage(uri, post=post, timeout=5, alfa_s=True, ignore_response_code=True)
else:
response = httptools.downloadpage(uri, timeout=5, alfa_s=True, ignore_response_code=True)
return response.sucess
def mark_auto_as_watched(item):
time_limit = time.time() + 150 #Marcamos el timepo máx. de buffering
while not platformtools.is_playing() and time.time() < time_limit: #Esperamos mientra buffera
time.sleep(5) #Repetimos cada intervalo
#logger.debug(str(time_limit))
if item.subtitle:
time.sleep(5)
xbmc_player.setSubtitles(item.subtitle)
#subt = xbmcgui.ListItem(path=item.url, thumbnailImage=item.thumbnail)
#subt.setSubtitles([item.subtitle])
if item.strm_path and platformtools.is_playing(): #Sólo si es de Videoteca
from platformcode import xbmc_videolibrary
xbmc_videolibrary.mark_auto_as_watched(item) #Marcamos como visto al terminar
#logger.debug("Llamado el marcado")
def wait_for_download(item, mediaurl, rar_files, torr_client, password='', size='', rar_control={}):
logger.info()
from subprocess import Popen, PIPE, STDOUT
# Analizamos los archivos dentro del .torrent
rar = False
rar_names = []
rar_names_abs = []
folder = ''
if rar_control:
for x, entry in enumerate(rar_control['rar_files']):
if '__name' in entry:
folder = rar_control['rar_files'][x]['__name']
break
rar_names = [rar_control['rar_names'][0]]
else:
for entry in rar_files:
for file, path in list(entry.items()):
if file == 'path' and '.rar' in str(path):
for file_r in path:
rar_names += [file_r]
rar = True
elif file == '__name':
folder = path
if not folder: # Si no se detecta el folder...
return ('', '', '') # ... no podemos hacer nada
if not rar_names:
return ('', '', folder)
rar_file = '%s/%s' % (folder, rar_names[0])
log("##### rar_file: %s" % rar_file)
if len(rar_names) > 1:
log("##### rar_names: %s" % str(rar_names))
# Localizamos el path de descarga del .torrent
save_path_videos = ''
__settings__ = xbmcaddon.Addon(id="plugin.video.%s" % torr_client) # Apunta settings del cliente torrent
if torr_client == 'torrenter':
save_path_videos = str(xbmc.translatePath(__settings__.getSetting('storage')))
if not save_path_videos:
save_path_videos = str(filetools.join(xbmc.translatePath("special://home/"), \
"cache", "xbmcup", "plugin.video.torrenter", "Torrenter"))
else:
save_path_videos = str(xbmc.translatePath(__settings__.getSetting('download_path')))
if __settings__.getSetting('download_storage') == '1': # Descarga en memoria?
return ('', '', folder) # volvemos
if not save_path_videos: # No hay path de descarga?
return ('', '', folder) # Volvemos
log("##### save_path_videos: %s" % save_path_videos)
# Si es nueva descarga, ponemos un archivo de control para reiniciar el UNRar si ha habido cancelación de Kodi
# Si ya existe el archivo (llamada), se reinicia el proceso de UNRar donde se quedó
if rar_control:
if 'downloading' not in rar_control['status']:
log("##### Torrent DESCARGADO Anteriormente: %s" % str(folder))
return (rar_file, save_path_videos, folder)
else:
rar_control = {
'torr_client': torr_client,
'rar_files': rar_files,
'rar_names': rar_names,
'size': size,
'password': password,
'download_path': filetools.join(save_path_videos, folder),
'status': 'downloading',
'error': 0,
'error_msg': '',
'item': item.tourl(),
'mediaurl': mediaurl
}
if torr_client == 'quasar': # Quasar no copia en .torrent
ret = filetools.copy(item.url, filetools.join(save_path_videos, 'torrents', \
filetools.basename(item.url)), silent=True)
# Esperamos mientras el .torrent se descarga. Verificamos si el .RAR está descargado al completo
platformtools.dialog_notification(config.get_localized_string(70803), "", time=10000)
# Plan A: usar el monitor del cliente torrent para ver el status de la descarga
loop = 3600 # Loop de 10 horas hasta crear archivo
wait_time = 10
time.sleep(wait_time)
fast = False
ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), jsontools.dump(rar_control))
for x in range(loop):
if xbmc.abortRequested:
return ('', '', folder)
torr_data, deamon_url, index = get_tclient_data(folder, torr_client)
if not torr_data or not deamon_url:
if len(filetools.listdir(rar_control['download_path'], silent=True)) <= 1:
filetools.remove(filetools.join(rar_control['download_path'], '_rar_control.json'), silent=True)
filetools.rmdir(rar_control['download_path'], silent=True)
return ('', '', folder) # Volvemos
if (torr_client in ['quasar'] or torr_client in ['elementum']) and not \
torr_data['label'].startswith('0.00%') and not fast:
platformtools.dialog_notification(config.get_localized_string(60200), config.get_localized_string(70769), time=10000)
fast = True
if not torr_data['label'].startswith('100.00%'):
log("##### Downloading: %s, ID: %s" % (scrapertools.find_single_match(torr_data['label'], '(^.*?\%)'), index))
time.sleep(wait_time)
continue
update_rar_control(rar_control['download_path'], status='downloaded')
log("##### Torrent FINALIZED: %s" % str(folder))
return (rar_file, save_path_videos, folder)
# Plan B: monitorizar con UnRAR si los archivos se han desacargado por completo
unrar_path = config.get_setting("unrar_path", server="torrent", default="")
if not unrar_path: # Si Unrar no está instalado...
return ('', '', folder) # ... no podemos hacer nada
cmd = []
for rar_name in rar_names: # Preparamos por si es un archivo multiparte
cmd.append(['%s' % unrar_path, 'l', '%s' % filetools.join(save_path_videos, folder, rar_name)])
creationflags = ''
if xbmc.getCondVisibility("system.platform.Windows"):
creationflags = 0x08000000
loop = 30 # Loop inicial de 5 minutos hasta crear archivo
wait_time = 10
loop_change = 0
loop_error = 6
part_name = ''
y = 0
returncode = ''
fast = False
while rar and not xbmc.abortRequested:
for x in range(loop): # Loop corto (5 min.) o largo (10 h.)
if xbmc.abortRequested:
return ('', '', folder)
if not rar or loop_change > 0:
loop = loop_change # Paso de loop corto a largo
loop_change = 0
break
try:
responses = []
for z, command in enumerate(cmd): # Se prueba por cada parte
if xbmc.getCondVisibility("system.platform.Windows"):
data_rar = Popen(command, bufsize=0, stdout=PIPE, stdin=PIPE, \
stderr=STDOUT, creationflags=creationflags)
else:
data_rar = Popen(command, bufsize=0, stdout=PIPE, stdin=PIPE, \
stderr=STDOUT)
out_, error_ = data_rar.communicate()
responses.append([z, str(data_rar.returncode), out_, error_]) # Se guarda la respuesta de cada parte
except:
logger.error(traceback.format_exc(1)) # Error de incompatibilidad de UnRAR
rar = False
break
else:
dl_files = 0
for z, returncode, out__, error__ in responses: # Analizamos las respuestas
if returncode == '0': # Ya se ha descargado... parte ...
dl_files += 1
part_name = scrapertools.find_single_match(str(out__), '(\.part\d+.rar)')
log("##### Torrent downloading: %s, %s" % (part_name, str(returncode)))
if dl_files == len(cmd): # ... o todo
fast = True
rar = False
break # ... o sólo una parte
elif returncode == '10': # archivo no existe
if loop != 30: # Si el archivo es borrado durante el proceso ...
rar = False
break #... abortamos
elif returncode == '6': # En proceso de descarga
y += 1
#if loop == 30 and y == len(responses): # Si es la primera vez en proceso ...
if loop == 30 and y == 1: # Si es la primera vez en proceso ...
if torr_client in ['quasar']:
platformtools.dialog_notification(config.get_localized_string(60200), config.get_localized_string(70769), time=10000)
loop_change = 3600 # ... pasamos a un loop de 10 horas
elif loop <= 6: # Recuerado el error desconocido
loop_change = 3600 # ... pasamos a un loop de 10 horas
loop_error = 6 # Restauramos loop_error por si acaso
break
elif returncode == '1': # Ha alcanzado el fin de archivo ??? pasamos
part_name = scrapertools.find_single_match(str(out__), '(\.part\d+.rar)')
log("##### Torrent downloading: %s, %s" % (part_name, str(returncode)))
else: # No entendemos el error
loop_change = loop_error # ... pasamos a un loop de 1 minutos para reintentar
loop_error += -1
break #... abortamos
if str(returncode) in ['0', '6', '10']:
log("##### Torrent downloading: %s" % str(returncode))
else:
log("##### Torrent downloading: %s, %s" % (str(out__), str(returncode)))
if not rar or fast:
fast = False
break
time.sleep(wait_time) # Esperamos un poco y volvemos a empezar
else:
rar = False
break
if str(returncode) == '0':
log("##### Torrent FINALIZED: %s" % str(returncode))
else:
rar_file = ''
logger.error('##### Torrent NO DESCARGADO: %s, %s' % (str(out__), str(returncode)))
return (rar_file, save_path_videos, folder)
def get_tclient_data(folder, torr_client):
# Monitoriza el estado de descarga del torrent en Quasar y Elementum
ELEMENTUMD_HOST = "http://localhost:65220"
if torr_client == 'elementum':
try:
ADDON = xbmcaddon.Addon("plugin.video.elementum")
except:
ADDON = False
if ADDON:
ELEMENTUMD_HOST = "http://" + ADDON.getSetting("remote_host") + ":" + ADDON.getSetting("remote_port")
local_host = {"quasar": "http://localhost:65251/torrents/", "elementum": "%s/torrents/" % ELEMENTUMD_HOST}
torr = ''
torr_id = ''
x = 0
y = ''
try:
data = httptools.downloadpage(local_host[torr_client], timeout=5, alfa_s=True).data
if not data:
return '', local_host[torr_client], 0
data = jsontools.load(data)
data = data['items']
for x, torr in enumerate(data):
if not folder in torr['label']:
continue
if "elementum" in torr_client:
torr_id = scrapertools.find_single_match(str(torr), 'torrents\/move\/(.*?)\)')
break
else:
return '', local_host[torr_client], 0
except:
log(traceback.format_exc(1))
return '', local_host[torr_client], 0
if torr_id:
y = torr_id
else:
y = x
return torr, local_host[torr_client], y
def extract_files(rar_file, save_path_videos, password, dp, item=None, \
torr_client=None, rar_control={}, size='RAR', mediaurl=''):
logger.info()
from platformcode import custom_code
if not rar_control:
rar_control = {
'torr_client': torr_client,
'rar_files': [{"__name": "%s" % rar_file.split("/")[0]}],
'rar_names': [filetools.basename(rar_file)],
'size': size,
'password': password,
'download_path': save_path_videos,
'status': 'downloaded',
'error': 0,
'error_msg': '',
'item': item.tourl(),
'mediaurl': mediaurl
}
ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), jsontools.dump(rar_control))
#reload(sys)
#sys.setdefaultencoding('utf-8')
sys.path.insert(0, config.get_setting("unrar_path", server="torrent", default="")\
.replace('/unrar', '').replace('\\unrar,exe', ''))
import rarfile
# Verificamos si hay path para UnRAR
rarfile.UNRAR_TOOL = config.get_setting("unrar_path", server="torrent", default="")
if not rarfile.UNRAR_TOOL:
if xbmc.getCondVisibility("system.platform.Android"):
rarfile.UNRAR_TOOL = xbmc.executebuiltin("StartAndroidActivity(com.rarlab.rar)")
return rar_file, False, '', ''
log("##### unrar_path: %s" % rarfile.UNRAR_TOOL)
rarfile.DEFAULT_CHARSET = 'utf-8'
# Preparamos un path alternativo más corto para no sobrepasar la longitud máxima
video_path = ''
if item:
if item.contentType == 'movie':
video_path = '%s-%s' % (item.contentTitle, item.infoLabels['tmdb_id'])
else:
video_path = '%s-%sx%s-%s' % (item.contentSerieName, item.contentSeason, \
item.contentEpisodeNumber, item.infoLabels['tmdb_id'])
video_path = video_path.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o")\
.replace("ú", "u").replace("ü", "u").replace("ñ", "n")\
.replace("Á", "A").replace("É", "E").replace("Í", "I").replace("Ó", "O")\
.replace("Ú", "U").replace("Ü", "U").replace("Ñ", "N")
# Renombramos el path dejado en la descarga a uno más corto
rename_status = False
org_rar_file = rar_file
org_save_path_videos = save_path_videos
if video_path and '/' in rar_file:
log("##### rar_file: %s" % rar_file)
rename_status, rar_file = rename_rar_dir(org_rar_file, org_save_path_videos, video_path, torr_client)
# Calculamos el path para del RAR
if "/" in rar_file:
folders = rar_file.split("/")
erase_file_path = filetools.join(save_path_videos, folders[0])
file_path = save_path_videos
for f in folders:
file_path = filetools.join(file_path, f)
else:
file_path = save_path_videos
erase_file_path = save_path_videos
# Calculamos el path para la extracción
if "/" in rar_file:
folders = rar_file.split("/")
for f in folders:
if not '.rar' in f:
save_path_videos = filetools.join(save_path_videos, f)
save_path_videos = filetools.join(save_path_videos, 'Extracted')
if not filetools.exists(save_path_videos): filetools.mkdir(save_path_videos)
log("##### save_path_videos: %s" % save_path_videos)
rar_control = update_rar_control(erase_file_path, status='UnRARing')
# Permite hasta 5 pasadas de extracción de .RARs anidados
platformtools.dialog_notification(config.get_localized_string(70793), rar_file, time=5000)
for x in range(5):
try:
if not PY3:
archive = rarfile.RarFile(file_path.decode("utf8"))
else:
archive = rarfile.RarFile(file_path)
except:
log("##### ERROR in rar archive: %s" % rar_file)
log("##### ERROR in rar folder: %s" % file_path)
log(traceback.format_exc())
error_msg = config.get_localized_string(70796)
error_msg1 = config.get_localized_string(60015)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
return rar_file, False, '', ''
# Analizamos si es necesaria una contraseña, que debería estar en item.password
if archive.needs_password():
if not password:
pass_path = filetools.split(file_path)[0]
password = last_password_search(pass_path, erase_file_path)
if not password :
password = platformtools.dialog_input(heading=config.get_localized_string(70794) % pass_path)
if not password:
error_msg = config.get_localized_string(60309)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
archive.setpassword(password)
log("##### Password rar: %s" % password)
# Miramos el contenido del RAR a extraer
files = archive.infolist()
info = []
for idx, i in enumerate(files):
if i.file_size == 0:
files.pop(idx)
continue
filename = i.filename
if "/" in filename:
filename = filename.rsplit("/", 1)[1]
info.append("%s - %.2f MB" % (filename, i.file_size / 1048576.0))
if info:
info.append(config.get_localized_string(70801))
else:
error_msg = config.get_localized_string(70797)
error_msg1 = config.get_localized_string(70798)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
# Seleccionamos extraer TODOS los archivos del RAR
#selection = xbmcgui.Dialog().select("Selecciona el fichero a extraer y reproducir", info)
selection = len(info) - 1
if selection < 0:
error_msg = config.get_localized_string(70797)
platformtools.dialog_notification(error_msg)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
return rar_file, False, '', ''
else:
try:
log("##### RAR Extract INI #####")
if selection == len(info) - 1:
log("##### rar_file 1: %s" % file_path)
log("##### save_path_videos 1: %s" % save_path_videos)
dp.update(99, config.get_localized_string(70803), config.get_localized_string(70802))
archive.extractall(save_path_videos)
else:
log("##### rar_file 2: %s" % file_path)
log("##### save_path_videos 2: %s" % save_path_videos)
dp.update(99, config.get_localized_string(70802), config.get_localized_string(70803) + " %s" % info[selection])
archive.extract(files[selection], save_path_videos)
log("##### RAR Extract END #####")
except (rarfile.RarWrongPassword, rarfile.RarCRCError):
log(traceback.format_exc(1))
error_msg = config.get_localized_string(70799)
error_msg1 = config.get_localized_string(60309)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg1, status='ERROR')
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
except rarfile.BadRarFile:
log(traceback.format_exc(1))
error_msg = config.get_localized_string(70799)
error_msg1 = config.get_localized_string(60800)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg1, status='ERROR')
#return rar_file, False, '', erase_file_path
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
except:
log(traceback.format_exc(1))
error_msg = config.get_localized_string(70799)
error_msg1 = config.get_localized_string(60015)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
extensions_list = ['.aaf', '.3gp', '.asf', '.avi', '.flv', '.mpeg',
'.m1v', '.m2v', '.m4v', '.mkv', '.mov', '.mpg',
'.mpe', '.mp4', '.ogg', '.wmv']
# Localizamos el path donde se ha dejado la extracción
folder = True
file_result = filetools.listdir(save_path_videos)
while folder:
for file_r in file_result:
if filetools.isdir(filetools.join(save_path_videos, file_r)):
file_result_alt = filetools.listdir(filetools.join(save_path_videos, file_r))
if file_result_alt:
file_result = file_result_alt
save_path_videos = filetools.join(save_path_videos, file_r)
else:
folder = False
break
else:
folder = False
# Si hay RARs anidados, ajustamos los paths para la siguiente pasada
if '.rar' in str(file_result):
for file_r in file_result:
if '.rar' in file_r:
rar_file = file_r
file_path = str(filetools.join(save_path_videos, rar_file))
save_path_videos = filetools.join(save_path_videos, 'Extracted')
rar_control = update_rar_control(erase_file_path, newextract=(rar_file))
if not filetools.exists(save_path_videos): filetools.mkdir(save_path_videos)
platformtools.dialog_notification(config.get_localized_string(70804), rar_file, time=5000)
# Si ya se ha extraido todo, preparamos el retorno
else:
video_list = []
for file_r in file_result:
if os.path.splitext(file_r)[1] in extensions_list:
video_list += [file_r]
if len(video_list) == 0:
error_msg = config.get_localized_string(70797)
error_msg1 = config.get_localized_string(70798)
platformtools.dialog_notification(error_msg, error_msg1)
rar_control = update_rar_control(erase_file_path, error=True, error_msg=error_msg, status='ERROR')
dp.close()
return custom_code.reactivate_unrar(init=False, mute=False)
else:
log("##### Archive extracted: %s" % video_list[0])
platformtools.dialog_notification(config.get_localized_string(70795), video_list[0], time=10000)
log("##### Archive removes: %s" % file_path)
#rar_control = update_rar_control(erase_file_path, status='DONE')
ret = filetools.remove(filetools.join(erase_file_path, '_rar_control.json'), silent=True)
return str(video_list[0]), True, save_path_videos, erase_file_path
def rename_rar_dir(rar_file, save_path_videos, video_path, torr_client):
logger.info()
rename_status = False
folders = rar_file.split("/")
if filetools.exists(filetools.join(save_path_videos, folders[0])) and video_path not in folders[0]:
if not PY3:
src = filetools.join(save_path_videos, folders[0]).decode("utf8")
dst = filetools.join(save_path_videos, video_path).decode("utf8")
dst_file = video_path.decode("utf8")
else:
src = filetools.join(save_path_videos, folders[0])
dst = filetools.join(save_path_videos, video_path)
dst_file = video_path
for x in range(20):
if xbmc.abortRequested:
return rename_status, rar_file
xbmc.sleep(1000)
# Se para la actividad para que libere los archivos descargados
if torr_client in ['quasar', 'elementum']:
torr_data, deamon_url, index = get_tclient_data(folders[0], torr_client)
if torr_data and deamon_url:
log("##### Client URL: %s" % '%spause/%s' % (deamon_url, index))
data = httptools.downloadpage('%spause/%s' % (deamon_url, index), timeout=5, alfa_s=True).data
try:
if filetools.exists(src):
filetools.rename(src, dst_file, silent=True, strict=True)
elif not filetools.exists(dst_file):
break
except:
log("##### Rename ERROR: SRC: %s" % src)
log(traceback.format_exc(1))
else:
if filetools.exists(dst):
log("##### Renamed: SRC: %s" % src)
log("##### TO: DST: %s" % dst)
rar_file = video_path + '/' + folders[1]
rename_status = True
update_rar_control(dst, newpath=dst)
break
return rename_status, rar_file
def last_password_search(pass_path, erase_file_path=''):
logger.info(pass_path)
if not erase_file_path:
erase_file_path = pass_path
# Busca en el Path de extracción si hay algún archivo que contenga la URL donde pueda estar la CONTRASEÑA
password = ''
patron_url = '(http.*\:\/\/(?:www.)?\w+\.\w+\/.*?)[\n|\r|$]'
patron_pass = '<input\s*type="text"\s*id="txt_password"\s*name="[^"]+"\s*onClick="[^"]+"\s*value="([^"]+)"'
try:
pass_path_list = filetools.listdir(pass_path)
for file in pass_path_list:
if 'contrase' in file.lower() and '.rar' not in file:
file_pass = filetools.read(filetools.join(pass_path, file))
url = scrapertools.find_single_match(file_pass, patron_url)
if url:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url).data)
password = scrapertools.find_single_match(data, patron_pass)
if password:
update_rar_control(erase_file_path, password=password, status='UnRARing: Password update')
break
except:
log(traceback.format_exc(1))
log("##### Password Extracted: %s" % password)
return password
def update_rar_control(path, newpath='', newextract='', password='', error='', error_msg='', status=''):
try:
rar_control = {}
rar_control = jsontools.load(filetools.read(filetools.join(path, '_rar_control.json')))
if rar_control:
if newpath:
rar_control['download_path'] = newpath
for x, entry in enumerate(rar_control['rar_files']):
if '__name' in entry:
rar_control['rar_files'][x]['__name'] = filetools.basename(newpath)
break
if newextract:
for x, entry in enumerate(rar_control['rar_files']):
if '__name' in entry:
#rar_control['rar_files'][x]['__name'] = filetools.join(rar_control['rar_files'][x]['__name'], 'Extracted')
rar_control['rar_files'][x]['__name'] = rar_control['rar_files'][x]['__name'] + '/Extracted'
break
rar_control['rar_names'] = [newextract]
if password: rar_control['password'] = password
if error: rar_control['error'] += 1
if error_msg: rar_control['error_msg'] = error_msg
if status and status not in rar_control['status']: rar_control['status'] = status
ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), \
jsontools.dump(rar_control))
logger.debug('%s, %s, %s, %s, %s, %s' % (rar_control['download_path'], \
rar_control['rar_names'][0], rar_control['password'], \
str(rar_control['error']), rar_control['error_msg'], rar_control['status']))
except:
log(traceback.format_exc(1))
return rar_control
def import_libtorrent(LIBTORRENT_PATH):
logger.info(LIBTORRENT_PATH)
e = ''
e1 = ''
e2 = ''
fp = ''
pathname = ''
description = ''
lt = ''
try:
sys.path.insert(0, LIBTORRENT_PATH)
if LIBTORRENT_PATH:
try:
if not xbmc.getCondVisibility("system.platform.android"):
import libtorrent as lt
pathname = LIBTORRENT_PATH
else:
import imp
from ctypes import CDLL
dll_path = os.path.join(LIBTORRENT_PATH, 'liblibtorrent.so')
liblibtorrent = CDLL(dll_path)
path_list = [LIBTORRENT_PATH, xbmc.translatePath('special://xbmc')]
fp, pathname, description = imp.find_module('libtorrent', path_list)
# Esta parte no funciona en Android. Por algún motivo da el error "dlopen failed: library "liblibtorrent.so" not found"
# Hay que encontrar un hack para rodear el problema. Lo siguiente ha sido probado sin éxito:
#if fp: fp.close()
#fp = filetools.file_open(filetools.join(LIBTORRENT_PATH, 'libtorrent.so'), mode='rb') # Usa XbmcVFS
#fp = open(os.path.join(LIBTORRENT_PATH, 'libtorrent.so'), 'rb')
try:
lt = imp.load_module('libtorrent', fp, pathname, description)
finally:
if fp: fp.close()
except Exception as e1:
logger.error(traceback.format_exc(1))
log('fp = ' + str(fp))
log('pathname = ' + str(pathname))
log('description = ' + str(description))
if fp: fp.close()
from lib.python_libtorrent.python_libtorrent import get_libtorrent
lt = get_libtorrent()
except Exception as e2:
try:
logger.error(traceback.format_exc())
if fp: fp.close()
e = e1 or e2
ok = platformtools.dialog_ok(config.get_localized_string(30035), config.get_localized_string(30036), config.get_localized_string(60015), str(e2))
except:
pass
try:
if not e1 and e2: e1 = e2
except:
try:
if e2:
e1 = e2
else:
e1 = ''
e2 = ''
except:
e1 = ''
e2 = ''
return lt, e, e1, e2
def log(texto):
try:
xbmc.log(texto, xbmc.LOGNOTICE)
except:
pass