319 lines
14 KiB
Python
319 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
# --------------------------------------------------------------------------------
|
|
# Updater (kodi)
|
|
# --------------------------------------------------------------------------------
|
|
|
|
import os, sys
|
|
import time
|
|
import threading
|
|
import traceback
|
|
import urllib
|
|
import json
|
|
import xbmc
|
|
import shutil
|
|
|
|
from platformcode import config, logger, platformtools
|
|
|
|
from core import httptools
|
|
from core import jsontools
|
|
from core import downloadtools
|
|
from core import ziptools
|
|
from core import filetools
|
|
|
|
REMOTE_FILE = "https://github.com/kodiondemand/addon/archive/master.zip"
|
|
DESTINATION_FOLDER = xbmc.translatePath("special://home/addons") + "/plugin.video.kod"
|
|
REMOTE_VERSION_FILE = "https://raw.githubusercontent.com/kodiondemand/addon/master/version.json"
|
|
|
|
def check_addon_init():
|
|
logger.info()
|
|
|
|
# Subtarea de monitor. Se activa cada X horas para comprobar si hay FIXES al addon
|
|
def check_addon_monitor():
|
|
logger.info()
|
|
|
|
# Obtiene el íntervalo entre actualizaciones y si se quieren mensajes
|
|
try:
|
|
timer = int(config.get_setting('addon_update_timer')) # Intervalo entre actualizaciones, en Ajustes de Alfa
|
|
if timer <= 0:
|
|
return # 0. No se quieren actualizaciones
|
|
verbose = config.get_setting('addon_update_message')
|
|
except:
|
|
timer = 12 # Por defecto cada 12 horas
|
|
verbose = False # Por defecto, sin mensajes
|
|
timer = timer * 3600 # Lo pasamos a segundos
|
|
|
|
if config.get_platform(True)['num_version'] >= 14: # Si es Kodi, lanzamos el monitor
|
|
import xbmc
|
|
monitor = xbmc.Monitor()
|
|
else: # Lanzamos solo una actualización y salimos
|
|
check_addon_updates(verbose) # Lanza la actualización
|
|
return
|
|
|
|
while not monitor.abortRequested(): # Loop infinito hasta cancelar Kodi
|
|
|
|
check_addon_updates(verbose) # Lanza la actualización
|
|
|
|
if monitor.waitForAbort(timer): # Espera el tiempo programado o hasta que cancele Kodi
|
|
break # Cancelación de Kodi, salimos
|
|
|
|
return
|
|
|
|
# Lanzamos en Servicio de actualización de FIXES
|
|
try:
|
|
threading.Thread(target=check_addon_monitor).start() # Creamos un Thread independiente, hasta el fin de Kodi
|
|
time.sleep(5) # Dejamos terminar la primera verificación...
|
|
except: # Si hay problemas de threading, se llama una sola vez
|
|
try:
|
|
timer = int(config.get_setting('addon_update_timer')) # Intervalo entre actualizaciones, en Ajustes de Alfa
|
|
if timer <= 0:
|
|
return # 0. No se quieren actualizaciones
|
|
verbose = config.get_setting('addon_update_message')
|
|
except:
|
|
verbose = False # Por defecto, sin mensajes
|
|
pass
|
|
check_addon_updates(verbose) # Lanza la actualización, en Ajustes de Alfa
|
|
time.sleep(5) # Dejamos terminar la primera verificación...
|
|
|
|
return
|
|
|
|
def checkforupdates(plugin_mode=True):
|
|
logger.info("kodiondemand.core.updater checkforupdates")
|
|
|
|
response = urllib.urlopen(REMOTE_VERSION_FILE)
|
|
data = json.loads(response.read())
|
|
|
|
'''
|
|
{
|
|
"update": {
|
|
"name": "Kodi on Demand",
|
|
"tag": "1.0.0",
|
|
"version": "1000",
|
|
"date": "03/05/2019",
|
|
"changes": "Added Updater"
|
|
}
|
|
}
|
|
'''
|
|
# remote is addon version without dots
|
|
remote_version = data["update"]["version"]
|
|
# tag version is version with dots used to a betterview gui
|
|
tag_version = data["update"]["tag"]
|
|
logger.info("kodiondemand.core.updater version remota="+tag_version+" "+remote_version)
|
|
|
|
'''
|
|
# Lee el fichero con la versión instalada
|
|
localFileName = LOCAL_VERSION_FILE
|
|
logger.info("kodiondemand.core.updater fichero local version: "+localFileName)
|
|
infile = open( localFileName )
|
|
data = infile.read()
|
|
infile.close()
|
|
#logger.info("xml local="+data)
|
|
'''
|
|
path_local = xbmc.translatePath("special://home/addons/") + "plugin.video.kod/version.json"
|
|
data = json.loads(open(path_local).read())
|
|
|
|
version_local = data["update"]["version"]
|
|
tag_local = data["update"]["tag"]
|
|
logger.info("kodiondemand.core.updater version local="+tag_local+" "+version_local)
|
|
|
|
try:
|
|
numero_remote_version = int(remote_version)
|
|
numero_version_local = int(version_local)
|
|
except:
|
|
import traceback
|
|
logger.info(traceback.format_exc())
|
|
remote_version = ""
|
|
version_local = ""
|
|
|
|
if remote_version=="" or version_local=="":
|
|
arraydescargada = tag_version.split(".")
|
|
arraylocal = tag_local.split(".")
|
|
|
|
# local 2.8.0 - descargada 2.8.0 -> no descargar
|
|
# local 2.9.0 - descargada 2.8.0 -> no descargar
|
|
# local 2.8.0 - descargada 2.9.0 -> descargar
|
|
if len(arraylocal) == len(arraydescargada):
|
|
logger.info("caso 1")
|
|
hayqueactualizar = False
|
|
for i in range(0, len(arraylocal)):
|
|
print arraylocal[i], arraydescargada[i], int(arraydescargada[i]) > int(arraylocal[i])
|
|
if int(arraydescargada[i]) > int(arraylocal[i]):
|
|
hayqueactualizar = True
|
|
# local 2.8.0 - descargada 2.8 -> no descargar
|
|
# local 2.9.0 - descargada 2.8 -> no descargar
|
|
# local 2.8.0 - descargada 2.9 -> descargar
|
|
if len(arraylocal) > len(arraydescargada):
|
|
logger.info("caso 2")
|
|
hayqueactualizar = False
|
|
for i in range(0, len(arraydescargada)):
|
|
#print arraylocal[i], arraydescargada[i], int(arraydescargada[i]) > int(arraylocal[i])
|
|
if int(arraydescargada[i]) > int(arraylocal[i]):
|
|
hayqueactualizar = True
|
|
# local 2.8 - descargada 2.8.8 -> descargar
|
|
# local 2.9 - descargada 2.8.8 -> no descargar
|
|
# local 2.10 - descargada 2.9.9 -> no descargar
|
|
# local 2.5 - descargada 3.0.0
|
|
if len(arraylocal) < len(arraydescargada):
|
|
logger.info("caso 3")
|
|
hayqueactualizar = True
|
|
for i in range(0, len(arraylocal)):
|
|
#print arraylocal[i], arraydescargada[i], int(arraylocal[i])>int(arraydescargada[i])
|
|
if int(arraylocal[i]) > int(arraydescargada[i]):
|
|
hayqueactualizar = False
|
|
elif int(arraylocal[i]) < int(arraydescargada[i]):
|
|
hayqueactualizar = True
|
|
break
|
|
else:
|
|
hayqueactualizar = (numero_remote_version > numero_version_local)
|
|
|
|
if hayqueactualizar:
|
|
|
|
if plugin_mode:
|
|
|
|
logger.info("kodiondemand.core.updater actualizacion disponible")
|
|
|
|
# Añade al listado de XBMC
|
|
import xbmcgui
|
|
#thumbnail = IMAGES_PATH+"Crystal_Clear_action_info.png"
|
|
thumbnail = os.path.join(config.get_runtime_path() , "resources" , "images", "service_update.png")
|
|
logger.info("thumbnail="+thumbnail)
|
|
listitem = xbmcgui.ListItem( "Scarica la versione "+tag_version, thumbnailImage=thumbnail )
|
|
itemurl = '%s?action=update&version=%s' % ( sys.argv[ 0 ] , tag_version )
|
|
import xbmcplugin
|
|
xbmcplugin.addDirectoryItem( handle = int(sys.argv[ 1 ]), url = itemurl , listitem=listitem, isFolder=True)
|
|
|
|
# Avisa con un popup
|
|
dialog = xbmcgui.Dialog()
|
|
dialog.ok("Versione "+tag_version+" disponibile","E' possibile scaricare la nuova versione del plugin\nattraverso l'opzione nel menù principale.")
|
|
|
|
else:
|
|
|
|
import xbmcgui
|
|
yes_pressed = xbmcgui.Dialog().yesno( "Versione "+tag_version+" disponibile" , "Installarla?" )
|
|
|
|
if yes_pressed:
|
|
params = {"version":tag_version}
|
|
update(params)
|
|
|
|
|
|
def update():
|
|
# Descarga el ZIP
|
|
logger.info("kodiondemand.core.updater update")
|
|
remotefilename = REMOTE_FILE
|
|
localfilename = xbmc.translatePath("special://home/addons/") + "plugin.video.kod.update.zip"
|
|
logger.info("kodiondemand.core.updater remotefilename=%s" % remotefilename)
|
|
logger.info("kodiondemand.core.updater localfilename=%s" % localfilename)
|
|
logger.info("kodiondemand.core.updater descarga fichero...")
|
|
|
|
urllib.urlretrieve(remotefilename,localfilename)
|
|
#from core import downloadtools
|
|
#downloadtools.downloadfile(remotefilename, localfilename, continuar=False)
|
|
|
|
# Lo descomprime
|
|
logger.info("kodiondemand.core.updater descomprime fichero...")
|
|
unzipper = ziptools.ziptools()
|
|
destpathname = xbmc.translatePath("special://home/addons/")
|
|
logger.info("kodiondemand.core.updater destpathname=%s" % destpathname)
|
|
unzipper.extract(localfilename,destpathname, os.path.join(xbmc.translatePath("special://home/addons/"), "plugin.video.kod/"))
|
|
|
|
temp_dir = os.path.join(destpathname,"addon-master")
|
|
files = os.listdir(temp_dir)
|
|
#for f in files:
|
|
# shutil.move(os.path.join(temp_dir, f), os.path.join(xbmc.translatePath("special://home/addons/"), "plugin.video.kod/", f))
|
|
|
|
# Borra el zip descargado
|
|
logger.info("kodiondemand.core.updater borra fichero...")
|
|
os.remove(localfilename)
|
|
#os.remove(temp_dir)
|
|
logger.info("kodiondemand.core.updater ...fichero borrado")
|
|
|
|
|
|
'''
|
|
def check_addon_updates(verbose=False):
|
|
logger.info()
|
|
|
|
ADDON_UPDATES_JSON = 'https://extra.alfa-addon.com/addon_updates/updates.json'
|
|
ADDON_UPDATES_ZIP = 'https://extra.alfa-addon.com/addon_updates/updates.zip'
|
|
|
|
try:
|
|
last_fix_json = os.path.join(config.get_runtime_path(), 'last_fix.json') # información de la versión fixeada del usuario
|
|
# Se guarda en get_runtime_path en lugar de get_data_path para que se elimine al cambiar de versión
|
|
|
|
# Descargar json con las posibles actualizaciones
|
|
# -----------------------------------------------
|
|
data = httptools.downloadpage(ADDON_UPDATES_JSON, timeout=2).data
|
|
if data == '':
|
|
logger.info('No se encuentran actualizaciones del addon')
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70667), config.get_localized_string(70668))
|
|
return False
|
|
|
|
data = jsontools.load(data)
|
|
if 'addon_version' not in data or 'fix_version' not in data:
|
|
logger.info('No hay actualizaciones del addon')
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70667), config.get_localized_string(70668))
|
|
return False
|
|
|
|
# Comprobar versión que tiene instalada el usuario con versión de la actualización
|
|
# --------------------------------------------------------------------------------
|
|
current_version = config.get_addon_version(with_fix=False)
|
|
if current_version != data['addon_version']:
|
|
logger.info('No hay actualizaciones para la versión %s del addon' % current_version)
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70667), config.get_localized_string(70668))
|
|
return False
|
|
|
|
if os.path.exists(last_fix_json):
|
|
try:
|
|
lastfix = {}
|
|
lastfix = jsontools.load(filetools.read(last_fix_json))
|
|
if lastfix['addon_version'] == data['addon_version'] and lastfix['fix_version'] == data['fix_version']:
|
|
logger.info(config.get_localized_string(70670) % (data['addon_version'], data['fix_version']))
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70667), config.get_localized_string(70671) % (data['addon_version'], data['fix_version']))
|
|
return False
|
|
except:
|
|
if lastfix:
|
|
logger.error('last_fix.json: ERROR en: ' + str(lastfix))
|
|
else:
|
|
logger.error('last_fix.json: ERROR desconocido')
|
|
lastfix = {}
|
|
|
|
# Descargar zip con las actualizaciones
|
|
# -------------------------------------
|
|
localfilename = os.path.join(config.get_data_path(), 'temp_updates.zip')
|
|
if os.path.exists(localfilename): os.remove(localfilename)
|
|
|
|
downloadtools.downloadfile(ADDON_UPDATES_ZIP, localfilename, silent=True)
|
|
|
|
# Descomprimir zip dentro del addon
|
|
# ---------------------------------
|
|
try:
|
|
unzipper = ziptools.ziptools()
|
|
unzipper.extract(localfilename, config.get_runtime_path())
|
|
except:
|
|
import xbmc
|
|
xbmc.executebuiltin('XBMC.Extract("%s", "%s")' % (localfilename, config.get_runtime_path()))
|
|
time.sleep(1)
|
|
|
|
# Borrar el zip descargado
|
|
# ------------------------
|
|
os.remove(localfilename)
|
|
|
|
# Guardar información de la versión fixeada
|
|
# -----------------------------------------
|
|
if 'files' in data: data.pop('files', None)
|
|
filetools.write(last_fix_json, jsontools.dump(data))
|
|
|
|
logger.info(config.get_localized_string(70672) % (data['addon_version'], data['fix_version']))
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70673), config.get_localized_string(70671) % (data['addon_version'], data['fix_version']))
|
|
return True
|
|
|
|
except:
|
|
logger.error('Error al comprobar actualizaciones del addon!')
|
|
logger.error(traceback.format_exc())
|
|
if verbose:
|
|
platformtools.dialog_notification(config.get_localized_string(70674), config.get_localized_string(70675))
|
|
return False
|
|
''' |