Files
addon/servers/torrent.py
2020-03-16 16:44:03 +01:00

1358 lines
63 KiB
Python
Executable File

# -*- coding: utf-8 -*-
#from builtins import str
from builtins import range
import sys
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 threading
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 core.item import Item
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=""):
logger.info("server=torrent, la url es la buena")
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('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_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, 'Se ha detectado un archivo .RAR en la descarga', \
'No tiene instalado el extractor UnRAR', '¿Desea descargarlo en cualquier caso?'):
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("Descarga de RAR en curso", "Puedes realizar otras tareas en Kodi mientrastanto. " + \
"Te informaremos...", time=10000)
else:
progreso = platformtools.dialog_progress('Alfa %s Cliente Torrent' % 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 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, '¿Borrarmos los archivos descargados? (completos)'):
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("Automatizando la extracción", "Acepta descargar el archivo RAR y te iremos guiando...", 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("Descarga en curso", "Puedes realizar otras tareas en Kodi mientrastanto. " + \
"Te informaremos...", time=10000)
fast = True
if not torr_data['label'].startswith('100.00%'):
log("##### Descargado: %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 FINALIZADO: %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 descargando: %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("Descarga en curso", "Puedes realizar otras tareas en Kodi mientrastanto. " + \
"Te informaremos...", 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 descargando: %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 descargando: %s" % str(returncode))
else:
log("##### Torrent descargando: %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 FINALIZADO: %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("Empezando extracción...", 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 en Archivo rar: %s" % rar_file)
log("##### ERROR en Carpeta del rar: %s" % file_path)
log(traceback.format_exc())
error_msg = "Error al abrir el RAR"
error_msg1 = "Comprueba el log para más detalles"
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="Introduce la contraseña (Mira en %s)" % pass_path)
if not password:
error_msg = "No se ha introducido la contraseña"
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("Extraer todo sin reproducir")
else:
error_msg = "El RAR está vacío"
error_msg1 = "O no contiene archivos válidos"
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 = "El RAR está vacío"
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, "Extrayendo archivos...", "Espera unos minutos....")
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, "Espera unos minutos....", "Extrayendo archivo... %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 = "Error al extraer"
error_msg1 = "Contraseña incorrecta"
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 = "Error al extraer"
error_msg1 = "Archivo rar con errores"
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 = "Error al extraer"
error_msg1 = "Comprueba el log para más detalles"
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("Siguiente extracción...", 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 = "El rar está vacío"
error_msg1 = "O no contiene archivos válidos"
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("##### Archivo extraído: %s" % video_list[0])
platformtools.dialog_notification("Archivo extraído...", video_list[0], time=10000)
log("##### Archivo remove: %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("##### Contraseña extraída: %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