Files
addon/core/jsontools.py
marco ca6d5eb56d KoD 0.8
- tanti miglioramenti sotto il cofano, supporto iniziale al futuro kodi 19
- Nuova modalità di visualizzazione per episodio successivo
- fixato wstream tramite l'aggiunta della finestra per risolvere il reCaptcha
- aggiunta sezione segnala un problema in Aiuto
- altri fix e migliorie varie a canali e server
2020-02-22 13:36:58 +01:00

201 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# --------------------------------------------------------------------------------
# json_tools - JSON load and parse functions with library detection
# --------------------------------------------------------------------------------
import traceback
from platformcode import logger
try:
import json
except:
logger.info("json included in the interpreter **NOT** available")
try:
import simplejson as json
except:
logger.info("simplejson included in the interpreter **NOT** available")
try:
from lib import simplejson as json
except:
logger.info("simplejson in lib directory **NOT** available")
logger.error("A valid JSON parser was not found")
json = None
else:
logger.info("Using simplejson in the lib directory")
else:
logger.info("Using simplejson included in the interpreter")
# ~ else:
# ~ logger.info("Usando json incluido en el interprete")
import sys
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
def load(*args, **kwargs):
if "object_hook" not in kwargs:
kwargs["object_hook"] = to_utf8
try:
value = json.loads(*args, **kwargs)
except:
logger.error("**NOT** able to load the JSON")
logger.error(traceback.format_exc())
value = {}
return value
def dump(*args, **kwargs):
if not kwargs:
kwargs = {"indent": 4, "skipkeys": True, "sort_keys": True, "ensure_ascii": True}
try:
value = json.dumps(*args, **kwargs)
except:
logger.error("JSON could **NOT** be saved")
logger.error(traceback.format_exc())
value = ""
return value
def to_utf8(dct):
if isinstance(dct, dict):
return dict((to_utf8(key), to_utf8(value)) for key, value in dct.items())
elif isinstance(dct, list):
return [to_utf8(element) for element in dct]
elif isinstance(dct, unicode):
dct = dct.encode("utf8")
if PY3: dct = dct.decode("utf8")
return dct
elif PY3 and isinstance(dct, bytes):
return dct.decode('utf-8')
else:
return dct
def get_node_from_file(name_file, node, path=None):
"""
Obtiene el nodo de un fichero JSON
@param name_file: Puede ser el nombre de un canal o server (sin incluir extension)
o bien el nombre de un archivo json (con extension)
@type name_file: str
@param node: nombre del nodo a obtener
@type node: str
@param path: Ruta base del archivo json. Por defecto la ruta de settings_channels.
@return: dict con el nodo a devolver
@rtype: dict
"""
logger.info()
from platformcode import config
from core import filetools
dict_node = {}
if not name_file.endswith(".json"):
name_file += "_data.json"
if not path:
path = filetools.join(config.get_data_path(), "settings_channels")
fname = filetools.join(path, name_file)
if filetools.isfile(fname):
data = filetools.read(fname)
dict_data = load(data)
check_to_backup(data, fname, dict_data)
if node in dict_data:
dict_node = dict_data[node]
#logger.debug("dict_node: %s" % dict_node)
return dict_node
def check_to_backup(data, fname, dict_data):
"""
Comprueba que si dict_data(conversion del fichero JSON a dict) no es un diccionario, se genere un fichero con
data de nombre fname.bk.
@param data: contenido del fichero fname
@type data: str
@param fname: nombre del fichero leido
@type fname: str
@param dict_data: nombre del diccionario
@type dict_data: dict
"""
logger.info()
if not dict_data:
logger.error("Error loading json from file %s" % fname)
if data != "":
# se crea un nuevo fichero
from core import filetools
title = filetools.write("%s.bk" % fname, data)
if title != "":
logger.error("There was an error saving the file: %s.bk" % fname)
else:
logger.debug("A copy with the name has been saved: %s.bk" % fname)
else:
logger.debug("The file is empty: %s" % fname)
def update_node(dict_node, name_file, node, path=None):
"""
actualiza el json_data de un fichero con el diccionario pasado
@param dict_node: diccionario con el nodo
@type dict_node: dict
@param name_file: Puede ser el nombre de un canal o server (sin incluir extension)
o bien el nombre de un archivo json (con extension)
@type name_file: str
@param node: nodo a actualizar
@param path: Ruta base del archivo json. Por defecto la ruta de settings_channels.
@return result: Devuelve True si se ha escrito correctamente o False si ha dado un error
@rtype: bool
@return json_data
@rtype: dict
"""
logger.info()
from platformcode import config
from core import filetools
json_data = {}
result = False
if not name_file.endswith(".json"):
name_file += "_data.json"
if not path:
path = filetools.join(config.get_data_path(), "settings_channels")
fname = filetools.join(path, name_file)
try:
data = filetools.read(fname)
dict_data = load(data)
# es un dict
if dict_data:
if node in dict_data:
logger.debug(" the key exists %s" % node)
dict_data[node] = dict_node
else:
logger.debug(" The key does NOT exist %s" % node)
new_dict = {node: dict_node}
dict_data.update(new_dict)
else:
logger.debug(" It is NOT a dict")
dict_data = {node: dict_node}
json_data = dump(dict_data)
result = filetools.write(fname, json_data)
except:
logger.error("Could not update %s" % fname)
return result, json_data