Files
addon/core/channeltools.py
2020-05-27 12:31:48 +02:00

345 lines
16 KiB
Python

# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# channeltools - Tools for working with channels
# ------------------------------------------------------------
from __future__ import absolute_import
from core import jsontools
from platformcode import config, logger
DEFAULT_UPDATE_URL = "/channels/"
dict_channels_parameters = dict()
default_file = dict()
remote_path = 'https://raw.githubusercontent.com/kodiondemand/media/master/'
def is_enabled(channel_name):
logger.info("channel_name=" + channel_name)
return get_channel_parameters(channel_name)["active"] and get_channel_setting("enabled", channel=channel_name,
default=True)
def get_channel_parameters(channel_name):
from core import filetools
global dict_channels_parameters
if channel_name not in dict_channels_parameters:
try:
channel_parameters = get_channel_json(channel_name)
# logger.debug(channel_parameters)
if channel_parameters:
# name and default changes
channel_parameters["title"] = channel_parameters.pop("name") + (' [DEPRECATED]' if 'deprecated' in channel_parameters and channel_parameters['deprecated'] else '')
channel_parameters["channel"] = channel_parameters.pop("id")
# if the key does not exist, they are declared a default value so that there are no failures in the functions that call it
channel_parameters["update_url"] = channel_parameters.get("update_url", DEFAULT_UPDATE_URL)
channel_parameters["language"] = channel_parameters.get("language", ["all"])
channel_parameters["active"] = channel_parameters.get("active", False)
channel_parameters["include_in_global_search"] = channel_parameters.get("include_in_global_search",
False)
channel_parameters["categories"] = channel_parameters.get("categories", list())
channel_parameters["thumbnail"] = channel_parameters.get("thumbnail", "")
channel_parameters["banner"] = channel_parameters.get("banner", "")
channel_parameters["fanart"] = channel_parameters.get("fanart", "")
# Images: url and local files are allowed inside "resources / images"
if channel_parameters.get("thumbnail") and "://" not in channel_parameters["thumbnail"]:
channel_parameters["thumbnail"] = filetools.join(remote_path, "resources", "thumb", channel_parameters["thumbnail"])
if channel_parameters.get("banner") and "://" not in channel_parameters["banner"]:
channel_parameters["banner"] = filetools.join(remote_path, "resources", "banner", channel_parameters["banner"])
if channel_parameters.get("fanart") and "://" not in channel_parameters["fanart"]:
channel_parameters["fanart"] = filetools.join(remote_path, "resources", channel_parameters["fanart"])
# We obtain if the channel has configuration options
channel_parameters["has_settings"] = False
if 'settings' in channel_parameters:
channel_parameters['settings'] = get_default_settings(channel_name)
for s in channel_parameters['settings']:
if 'id' in s:
if s['id'] == "include_in_global_search":
channel_parameters["include_in_global_search"] = True
elif s['id'] == "filter_languages":
channel_parameters["filter_languages"] = s.get('lvalues', [])
elif s['id'].startswith("include_in_"):
channel_parameters["has_settings"] = True
del channel_parameters['settings']
dict_channels_parameters[channel_name] = channel_parameters
else:
# To avoid cases where channels are not defined as configuration, we throw the exception and thus we have the basic values
raise Exception
except Exception as ex:
logger.error(channel_name + ".json error \n%s" % ex)
channel_parameters = dict()
channel_parameters["channel"] = ""
channel_parameters['active'] = False
channel_parameters["language"] = ""
channel_parameters["update_url"] = DEFAULT_UPDATE_URL
return channel_parameters
return dict_channels_parameters[channel_name]
def get_channel_json(channel_name):
# logger.info("channel_name=" + channel_name)
from core import filetools
channel_json = None
try:
channel_path = filetools.join(config.get_runtime_path(), "channels", channel_name + ".json")
if not filetools.isfile(channel_path):
channel_path = filetools.join(config.get_runtime_path(), "specials", channel_name + ".json")
if not filetools.isfile(channel_path):
channel_path = filetools.join(config.get_runtime_path(), "servers", channel_name + ".json")
if not filetools.isfile(channel_path):
channel_path = filetools.join(config.get_runtime_path(), "servers", "debriders",
channel_name + ".json")
if filetools.isfile(channel_path):
# logger.info("channel_data=" + channel_path)
channel_json = jsontools.load(filetools.read(channel_path))
# logger.info("channel_json= %s" % channel_json)
except Exception as ex:
template = "An exception of type %s occured. Arguments:\n%r"
message = template % (type(ex).__name__, ex.args)
logger.error(" %s" % message)
return channel_json
def get_channel_controls_settings(channel_name):
# logger.info("channel_name=" + channel_name)
dict_settings = {}
# import web_pdb; web_pdb.set_trace()
# list_controls = get_channel_json(channel_name).get('settings', list())
list_controls = get_default_settings(channel_name)
for c in list_controls:
if 'id' not in c or 'type' not in c or 'default' not in c:
# If any control in the list does not have id, type or default, we ignore it
continue
# new dict with key(id) and value(default) from settings
dict_settings[c['id']] = c['default']
return list_controls, dict_settings
def get_lang(channel_name):
channel = __import__('channels.%s' % channel_name, fromlist=["channels.%s" % channel_name])
list_language = [config.get_localized_string(70522)]
if hasattr(channel, 'list_language'):
for language in channel.list_language:
list_language.append(language)
logger.info(list_language)
else:
sub = False
langs = []
language = get_channel_json(channel_name).get('language', list())
for lang in language:
if 'vos' not in lang:
langs.append(lang.upper())
else:
sub = True
if sub == True:
for lang in langs:
list_language.append(lang)
list_language.append('Sub-' + lang)
else:
for lang in langs:
list_language.append(lang)
return list_language
def get_default_settings(channel_name):
from core import filetools
default_path = filetools.join(config.get_runtime_path(), 'default_channel_settings' + '.json')
global default_file
if not default_file:
default_file = jsontools.load(filetools.read(default_path))
channel_path = filetools.join(config.get_runtime_path(), 'channels', channel_name + '.json')
# from core.support import dbg; dbg()
if filetools.exists(channel_path):
default_controls = default_file['settings']
default_controls_renumber = default_file['renumber']
channel_json = get_channel_json(channel_name)
# Collects configurations
channel_language = channel_json['language']
channel_controls = channel_json['settings']
categories = channel_json['categories']
not_active = channel_json['not_active'] if 'not_active' in channel_json else []
default_off = channel_json['default_off'] if 'default_off' in channel_json else []
# Apply default configurations if they do not exist
for control in default_controls:
if control['id'] not in str(channel_controls):
if 'include_in_newest' in control['id'] and 'include_in_newest' not in not_active and control[
'id'] not in not_active:
label = control['id'].split('_')
label = label[-1]
if label == 'peliculas':
if 'movie' in categories:
control['label'] = config.get_localized_string(70727) + ' - ' + config.get_localized_string( 30122)
control['default'] = False if ('include_in_newest' in default_off) or ( ' include_in_newest_peliculas' in default_off) else True
channel_controls.append(control)
else:
pass
elif label == 'series':
if 'tvshow' in categories:
control['label'] = config.get_localized_string(70727) + ' - ' + config.get_localized_string( 30123)
control['default'] = False if ('include_in_newest' in default_off) or ( 'include_in_newest_series' in default_off) else True
channel_controls.append(control)
else:
pass
elif label == 'anime':
if 'anime' in categories:
control['label'] = config.get_localized_string(70727) + ' - ' + config.get_localized_string( 30124)
control['default'] = False if ('include_in_newest' in default_off) or ( 'include_in_newest_anime' in default_off) else True
channel_controls.append(control)
else:
pass
else:
control['label'] = config.get_localized_string(70727) + ' - ' + label.capitalize()
control['default'] = control['default'] if control['id'] not in default_off else False
channel_controls.append(control)
elif control['id'] not in not_active and 'include_in_newest' not in control['id']:
if type(control['default']) == bool:
control['default'] = control['default'] if control['id'] not in default_off else False
channel_controls.append(control)
if 'anime' in categories:
for control in default_controls_renumber:
if control['id'] not in str(channel_controls):
channel_controls.append(control)
else:
pass
else:
return get_channel_json(channel_name).get('settings', list())
return channel_controls
def get_channel_setting(name, channel, default=None):
from core import filetools
"""
Returns the configuration value of the requested parameter.
Returns the value of the parameter 'name' in the own configuration of the channel 'channel'.
Look in the path \addon_data\plugin.video.kod\settings_channels for the file channel_data.json and read
the value of the parameter 'name'. If the file channel_data.json does not exist look in the channels folder for the file
channel.json and create a channel_data.json file before returning the requested value. If the parameter 'name'
also does not exist in the channel.json file the default parameter is returned.
@param name: parameter name
@type name: str
@param channel: channel name
@type channel: str
@param default: return value in case the name parameter does not exist
@type default: any
@return: The value of the parameter 'name'
@rtype: any
"""
file_settings = filetools.join(config.get_data_path(), "settings_channels", channel + "_data.json")
dict_settings = {}
dict_file = {}
if channel not in ['trakt']: def_settings = get_default_settings(channel)
if filetools.exists(file_settings):
# We get saved configuration from ../settings/channel_data.json
try:
dict_file = jsontools.load(filetools.read(file_settings))
if isinstance(dict_file, dict) and 'settings' in dict_file:
dict_settings = dict_file['settings']
except EnvironmentError:
logger.error("ERROR when reading the file: %s" % file_settings)
if not dict_settings or name not in dict_settings:
# We get controls from the file ../channels/channel.json
try:
list_controls, default_settings = get_channel_controls_settings(channel)
except:
default_settings = {}
if name in default_settings: #If the parameter exists in the channel.json we create the channel_data.json
default_settings.update(dict_settings)
dict_settings = default_settings
dict_file['settings'] = dict_settings
# We create the file ../settings/channel_data.json
json_data = jsontools.dump(dict_file)
if not filetools.write(file_settings, json_data, silent=True):
logger.error("ERROR saving file: %s" % file_settings)
# We return the value of the local parameter 'name' if it exists, if default is not returned
return dict_settings.get(name, default)
def set_channel_setting(name, value, channel):
from core import filetools
"""
Sets the configuration value of the indicated parameter.
Set 'value' as the value of the parameter 'name' in the own configuration of the channel 'channel'.
Returns the changed value or None if the assignment could not be completed.
If the name of the channel is specified, search in the path \addon_data\plugin.video.kod\settings_channels the
channel_data.json file and set the parameter 'name' to the value indicated by 'value'.
If the parameter 'name' does not exist, it adds it, with its value, to the corresponding file.
@param name: parameter name
@type name: str
@param value: parameter value
@type value: str
@param channel: channel name
@type channel: str
@return: 'value' if the value could be set and None otherwise
@rtype: str, None
"""
# We create the folder if it does not exist
if not filetools.exists(filetools.join(config.get_data_path(), "settings_channels")):
filetools.mkdir(filetools.join(config.get_data_path(), "settings_channels"))
file_settings = filetools.join(config.get_data_path(), "settings_channels", channel + "_data.json")
dict_settings = {}
dict_file = None
if filetools.exists(file_settings):
# We get saved settings from ../settings/channel_data.json
try:
dict_file = jsontools.load(filetools.read(file_settings))
dict_settings = dict_file.get('settings', {})
except EnvironmentError:
logger.error("ERROR when reading the file: %s" % file_settings)
dict_settings[name] = value
# we check if dict_file exists and it is a dictionary, if not we create it
if dict_file is None or not dict_file:
dict_file = {}
dict_file['settings'] = dict_settings
# Creamos el archivo ../settings/channel_data.json
json_data = jsontools.dump(dict_file)
if not filetools.write(file_settings, json_data, silent=True):
logger.error("ERROR saving file: %s" % file_settings)
return None
return value