1002 lines
47 KiB
Python
1002 lines
47 KiB
Python
# -*- coding: utf-8 -*-
|
|
# --------------------------------------------------------------------------------
|
|
# renumeratetools - se encarga de renumerar episodios
|
|
# --------------------------------------------------------------------------------
|
|
|
|
import os
|
|
|
|
try:
|
|
import xbmcgui
|
|
except:
|
|
xbmcgui = None
|
|
|
|
from platformcode import config, logger
|
|
from core import jsontools
|
|
from core.item import Item
|
|
from platformcode import platformtools
|
|
|
|
TAG_TVSHOW_RENUMERATE = "TVSHOW_RENUMBER"
|
|
TAG_SEASON_EPISODE = "season_episode"
|
|
__channel__ = "renumbertools"
|
|
|
|
|
|
def access():
|
|
"""
|
|
Devuelve si se puede usar o no renumbertools
|
|
"""
|
|
allow = False
|
|
|
|
if config.is_xbmc():
|
|
allow = True
|
|
|
|
return allow
|
|
|
|
|
|
def context(item):
|
|
"""
|
|
Para xbmc/kodi que pueden mostrar el menú contextual, se añade un menu para configuración
|
|
la opción de renumerar, sólo si es para series.
|
|
|
|
@param item: elemento para obtener la información y ver que contexto añadir
|
|
@type item: item
|
|
@return: lista de opciones a mostrar en el menú contextual
|
|
@rtype: list
|
|
"""
|
|
|
|
# Dependiendo de como sea el contexto lo guardamos y añadimos las opciones de filtertools.
|
|
if type(item.context) == str:
|
|
_context = item.context.split("|")
|
|
elif type(item.context) == list:
|
|
_context = item.context
|
|
else:
|
|
_context = []
|
|
|
|
if access():
|
|
dict_data = {"title": config.get_localized_string(70585), "action": "config_item", "channel": "renumbertools"}
|
|
_context.append(dict_data)
|
|
|
|
return _context
|
|
|
|
|
|
def show_option(channel, itemlist):
|
|
if access():
|
|
itemlist.append(Item(channel=__channel__, title="[COLOR yellow]" + config.get_localized_string(70586)+ "[/COLOR]",
|
|
action="load", from_channel=channel))
|
|
|
|
return itemlist
|
|
|
|
|
|
def load(item):
|
|
return mainlist(channel=item.from_channel)
|
|
|
|
|
|
def mainlist(channel):
|
|
"""
|
|
Muestra una lista de las series renumeradas
|
|
|
|
:param channel: nombre del canal para obtener las series renumeradas
|
|
:type channel: str
|
|
:return: lista de Item
|
|
:rtype: list[Item]
|
|
"""
|
|
logger.info()
|
|
itemlist = []
|
|
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_RENUMERATE)
|
|
|
|
idx = 0
|
|
for tvshow in sorted(dict_series):
|
|
tag_color = "0xff008000"
|
|
if idx % 2 == 0:
|
|
tag_color = "blue"
|
|
|
|
idx += 1
|
|
name = tvshow
|
|
title = config.get_localized_string(70587)+" [COLOR %s][%s][/COLOR]" % (tag_color, name)
|
|
|
|
itemlist.append(Item(channel=__channel__, action="config_item", title=title, show=name, from_channel=channel))
|
|
|
|
if len(itemlist) == 0:
|
|
itemlist.append(Item(channel=channel, action="mainlist",
|
|
title=config.get_localized_string(70588) + ' ' + config.get_localized_string(70585)))
|
|
|
|
return itemlist
|
|
|
|
|
|
def config_item(item):
|
|
"""
|
|
muestra una serie renumerada para su configuración
|
|
|
|
:param item: item
|
|
:type item: Item
|
|
"""
|
|
logger.info("item %s" % item.tostring("\n"))
|
|
|
|
dict_series = jsontools.get_node_from_file(item.from_channel, TAG_TVSHOW_RENUMERATE)
|
|
data = dict_series.get(item.show, {})
|
|
|
|
if data:
|
|
data = data.get(TAG_SEASON_EPISODE, [])
|
|
|
|
ventana = RenumberWindow(show=item.show, channel=item.from_channel, data=data)
|
|
del ventana
|
|
else:
|
|
# tenemos información y devolvemos los datos añadidos para que se muestre en la ventana
|
|
if data:
|
|
return add_season(data)
|
|
# es la primera vez que se añaden datos (usando menú contextual) por lo que no devolvemos nada
|
|
# para evitar error al listar los items
|
|
else:
|
|
data = add_season(data)
|
|
write_data(item.from_channel, item.show, data)
|
|
|
|
|
|
def numbered_for_tratk(channel, show, season, episode):
|
|
"""
|
|
Devuelve la temporada y episodio convertido para que se marque correctamente en tratk.tv
|
|
|
|
@param channel: Nombre del canal
|
|
@type channel: str
|
|
@param show: Nombre de la serie a comprobar
|
|
@type show: str
|
|
@param season: Temporada que devuelve el scrapper
|
|
@type season: int
|
|
@param episode: Episodio que devuelve el scrapper
|
|
@type episode: int
|
|
@return: season, episode
|
|
@rtype: int, int
|
|
"""
|
|
logger.info()
|
|
|
|
if access():
|
|
show = show.lower()
|
|
|
|
new_season = season
|
|
new_episode = episode
|
|
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_RENUMERATE)
|
|
|
|
# ponemos en minusculas el key, ya que previamente hemos hecho lo mismo con show.
|
|
for key in dict_series.keys():
|
|
new_key = key.lower()
|
|
if new_key != key:
|
|
dict_series[new_key] = dict_series[key]
|
|
del dict_series[key]
|
|
|
|
if show in dict_series:
|
|
logger.debug(config.get_localized_string(70589) + " %s" % dict_series[show])
|
|
|
|
if len(dict_series[show]['season_episode']) > 1:
|
|
for row in dict_series[show]['season_episode']:
|
|
|
|
if new_episode > row[1]:
|
|
new_episode -= row[1]
|
|
new_season = row[0]
|
|
break
|
|
|
|
else:
|
|
new_season = dict_series[show]['season_episode'][0][0]
|
|
new_episode += dict_series[show]['season_episode'][0][1]
|
|
|
|
logger.debug("%s:%s" % (new_season, new_episode))
|
|
else:
|
|
# no se tiene acceso se devuelven los datos.
|
|
new_season = season
|
|
new_episode = episode
|
|
|
|
return new_season, new_episode
|
|
|
|
|
|
def borrar(channel, show):
|
|
logger.info()
|
|
heading = config.get_localized_string(70590)
|
|
line1 = config.get_localized_string(70591) + ' [COLOR blue]' + show.strip() + '[/COLOR], ' + config.get_localized_string(70592)
|
|
|
|
if platformtools.dialog_yesno(heading, line1) == 1:
|
|
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_RENUMERATE)
|
|
dict_series.pop(show, None)
|
|
|
|
result, json_data = jsontools.update_node(dict_series, channel, TAG_TVSHOW_RENUMERATE)
|
|
|
|
if result:
|
|
message = config.get_localized_string(60444)
|
|
else:
|
|
message = config.get_localized_string(70593)
|
|
|
|
heading = show.strip()
|
|
platformtools.dialog_notification(heading, message)
|
|
|
|
|
|
def add_season(data=None):
|
|
logger.debug("data %s" % data)
|
|
heading = config.get_localized_string(70594)
|
|
# default = 2
|
|
# se reordena la lista
|
|
list_season_episode = data
|
|
if list_season_episode:
|
|
list_season_episode.sort(key=lambda el: int(el[0]), reverse=False)
|
|
|
|
# if list_season_episode:
|
|
# # mostrar temporada + 1 de la lista
|
|
# # TODO buscar la primera posicion libre
|
|
# default = list_season_episode[0][0]+1
|
|
|
|
season = platformtools.dialog_numeric(0, heading) # , str(default))
|
|
for element in list_season_episode:
|
|
if int(season) == element[0]:
|
|
platformtools.dialog_notification(config.get_localized_string(70595), config.get_localized_string(70596))
|
|
return
|
|
|
|
# si hemos insertado un valor en la temporada
|
|
if season != "" and int(season) > 0:
|
|
heading = config.get_localized_string(70597)
|
|
# default = 0
|
|
# if list_season_episode:
|
|
# for e in list_season_episode:
|
|
# # mostrar suma episodios de la lista
|
|
# # sumar hasta el indice del primer libre encontrado
|
|
# default += e[1]
|
|
episode = platformtools.dialog_numeric(0, heading) # , str(default))
|
|
|
|
# si hemos insertado un valor en el episodio
|
|
if episode != "":
|
|
if list_season_episode:
|
|
list_season_episode.insert(0, [int(season), int(episode)])
|
|
new_list_season_episode = list_season_episode[:]
|
|
return new_list_season_episode
|
|
else:
|
|
return [[int(season), int(episode)]]
|
|
|
|
|
|
def write_data(channel, show, data):
|
|
# OBTENEMOS LOS DATOS DEL JSON
|
|
dict_series = jsontools.get_node_from_file(channel, TAG_TVSHOW_RENUMERATE)
|
|
tvshow = show.strip()
|
|
list_season_episode = dict_series.get(tvshow, {}).get(TAG_SEASON_EPISODE, [])
|
|
logger.debug("data %s" % list_season_episode)
|
|
|
|
if data:
|
|
# cambiamos el orden para que se vea en orden descendente y usarse bien en el _data.json
|
|
data.sort(key=lambda el: int(el[0]), reverse=True)
|
|
dict_renumerate = {TAG_SEASON_EPISODE: data}
|
|
|
|
dict_series[tvshow] = dict_renumerate
|
|
else:
|
|
# hemos borrado todos los elementos, por lo que se borra la serie del fichero
|
|
dict_series.pop(tvshow, None)
|
|
|
|
result, json_data = jsontools.update_node(dict_series, channel, TAG_TVSHOW_RENUMERATE)
|
|
|
|
if result:
|
|
if data:
|
|
message = config.get_localized_string(60446)
|
|
else:
|
|
message = config.get_localized_string(60444)
|
|
else:
|
|
message = config.get_localized_string(70593)
|
|
|
|
heading = show.strip()
|
|
platformtools.dialog_notification(heading, message)
|
|
|
|
|
|
if xbmcgui:
|
|
|
|
# Align
|
|
ALIGN_LEFT = 0
|
|
ALIGN_RIGHT = 1
|
|
ALIGN_CENTER_X = 2
|
|
ALIGN_CENTER_Y = 4
|
|
ALIGN_CENTER = 6
|
|
ALIGN_TRUNCATED = 8
|
|
ALIGN_JUSTIFY = 10
|
|
|
|
# button ids
|
|
ID_BUTTON_CLOSE = 3003
|
|
ID_BUTTON_ADD_SEASON = 3008
|
|
ID_BUTTON_INFO = 3009
|
|
ID_CHECK_UPDATE_INTERNET = 3010
|
|
ID_BUTTON_OK = 3012
|
|
ID_BUTTON_CANCEL = 3013
|
|
ID_BUTTON_DELETE = 3014
|
|
|
|
|
|
class RenumberWindow(xbmcgui.WindowDialog):
|
|
def __init__(self, *args, **kwargs):
|
|
logger.debug()
|
|
|
|
#### Compatibilidad con Kodi 18 ####
|
|
if config.get_platform(True)['num_version'] < 18:
|
|
if xbmcgui.__version__ == "1.2":
|
|
self.setCoordinateResolution(1)
|
|
else:
|
|
self.setCoordinateResolution(5)
|
|
|
|
self.show = kwargs.get("show")
|
|
self.channel = kwargs.get("channel")
|
|
self.data = kwargs.get("data")
|
|
self.init = True
|
|
|
|
self.mediapath = os.path.join(config.get_runtime_path(), 'resources', 'skins', 'Default', 'media')
|
|
self.font = "font12"
|
|
|
|
window_bg = xbmcgui.ControlImage(320, 130, 600, 440,
|
|
os.path.join(self.mediapath, 'Windows', 'DialogBack.png'))
|
|
self.addControl(window_bg)
|
|
|
|
header_bg = xbmcgui.ControlImage(window_bg.getX(), window_bg.getY() + 8, window_bg.getWidth(), 35,
|
|
os.path.join(self.mediapath, 'Windows', 'dialogheader.png'))
|
|
self.addControl(header_bg)
|
|
|
|
btn_close_w = 64
|
|
self.btn_close = xbmcgui.ControlButton(window_bg.getX() + window_bg.getWidth() - btn_close_w - 13,
|
|
header_bg.getY() + 6, btn_close_w, 30, '',
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'DialogCloseButton-focus.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'DialogCloseButton.png'))
|
|
self.addControl(self.btn_close)
|
|
|
|
header_title_x = window_bg.getX() + 20
|
|
header_title = xbmcgui.ControlFadeLabel(header_title_x, header_bg.getY() + 5, self.btn_close.getX() -
|
|
header_title_x, 30, font="font12_title", textColor="0xFFFFA500",
|
|
_alignment=ALIGN_CENTER)
|
|
self.addControl(header_title)
|
|
header_title.addLabel(self.show)
|
|
|
|
self.controls_bg = xbmcgui.ControlImage(window_bg.getX() + 20, header_bg.getY() + header_bg.getHeight() + 6,
|
|
562, 260,
|
|
os.path.join(self.mediapath, 'Windows', 'BackControls.png'))
|
|
self.addControl(self.controls_bg)
|
|
|
|
self.scroll_bg = xbmcgui.ControlImage(window_bg.getX() + window_bg.getWidth() - 25, self.controls_bg.getY(),
|
|
10,
|
|
self.controls_bg.getHeight(), os.path.join(self.mediapath, 'Controls',
|
|
'ScrollBack.png'))
|
|
self.addControl(self.scroll_bg)
|
|
self.scroll_bg.setVisible(False)
|
|
|
|
self.scroll2_bg = xbmcgui.ControlImage(window_bg.getX() + window_bg.getWidth() - 25,
|
|
self.controls_bg.getY(),
|
|
10, self.controls_bg.getHeight(), os.path.join(self.mediapath,
|
|
'Controls',
|
|
'ScrollBar.png'))
|
|
self.addControl(self.scroll2_bg)
|
|
self.scroll2_bg.setVisible(False)
|
|
|
|
btn_add_season = xbmcgui.ControlButton(window_bg.getX() + 20, self.controls_bg.getY() +
|
|
self.controls_bg.getHeight() + 14, 165, 30, config.get_localized_string(70600),
|
|
font=self.font, focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(btn_add_season)
|
|
|
|
self.btn_info = xbmcgui.ControlButton(window_bg.getX() + 210, btn_add_season.getY(), 120, 30, config.get_localized_string(60348),
|
|
font=self.font, focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(self.btn_info)
|
|
|
|
check_update_internet_w = 235
|
|
# Versiones antiguas no admite algunas texturas
|
|
if xbmcgui.__version__ in ["1.2", "2.0"]:
|
|
self.check_update_internet = xbmcgui.ControlRadioButton(
|
|
window_bg.getX() + window_bg.getWidth() - check_update_internet_w - 20, btn_add_season.getY() - 3,
|
|
check_update_internet_w, 34, config.get_localized_string(70601), font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'))
|
|
else:
|
|
self.check_update_internet = xbmcgui.ControlRadioButton(
|
|
window_bg.getX() + window_bg.getWidth() - check_update_internet_w - 20, btn_add_season.getY() - 3,
|
|
check_update_internet_w, 34, config.get_localized_string(70601), font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemFO.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls', 'MenuItemNF.png'),
|
|
focusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
|
|
noFocusOnTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-focus.png'),
|
|
focusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'),
|
|
noFocusOffTexture=os.path.join(self.mediapath, 'Controls', 'radiobutton-nofocus.png'))
|
|
|
|
self.addControl(self.check_update_internet)
|
|
self.check_update_internet.setEnabled(False)
|
|
|
|
hb_bg = xbmcgui.ControlImage(window_bg.getX() + 20, btn_add_season.getY() + btn_add_season.getHeight() + 13,
|
|
window_bg.getWidth() - 40, 2,
|
|
os.path.join(self.mediapath, 'Controls', 'ScrollBack.png'))
|
|
self.addControl(hb_bg)
|
|
|
|
self.btn_ok = xbmcgui.ControlButton(window_bg.getX() + 68, hb_bg.getY() + hb_bg.getHeight() + 13, 120, 30,
|
|
'OK', font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(self.btn_ok)
|
|
|
|
self.btn_cancel = xbmcgui.ControlButton(self.btn_info.getX() + 30, self.btn_ok.getY(), 120, 30, config.get_localized_string(70002),
|
|
font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(self.btn_cancel)
|
|
|
|
self.btn_delete = xbmcgui.ControlButton(self.btn_cancel.getX() + self.btn_cancel.getWidth() + 50,
|
|
self.btn_ok.getY(), 120, 30, config.get_localized_string(60437), font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(self.btn_delete)
|
|
|
|
self.controls = []
|
|
self.onInit()
|
|
self.setFocus(self.controls[0].edit_season)
|
|
self.doModal()
|
|
|
|
def onInit(self, *args, **kwargs):
|
|
try:
|
|
# listado temporada / episodios
|
|
pos_y = self.controls_bg.getY() + 10
|
|
|
|
# eliminamos los componentes al repintar la ventana
|
|
for linea in self.controls:
|
|
self.removeControls(linea.list_elements())
|
|
|
|
# mostramos el scroll si hay más de 5 elementos
|
|
if len(self.data) > 5:
|
|
self.controls_bg.setWidth(545)
|
|
self.scroll_bg.setVisible(True)
|
|
self.scroll2_bg.setVisible(True)
|
|
else:
|
|
self.controls_bg.setWidth(562)
|
|
self.scroll_bg.setVisible(False)
|
|
self.scroll2_bg.setVisible(False)
|
|
|
|
self.controls = []
|
|
# cambiamos el orden para que se vea en orden ascendente
|
|
self.data.sort(key=lambda el: int(el[0]), reverse=False)
|
|
|
|
for index, e in enumerate(self.data):
|
|
pos_x = self.controls_bg.getX() + 15
|
|
label_season_w = 100
|
|
label_season = xbmcgui.ControlLabel(pos_x, pos_y + 3, label_season_w, 34,
|
|
config.get_localized_string(60385), font=self.font, textColor="0xFF2E64FE")
|
|
self.addControl(label_season)
|
|
label_season.setVisible(False)
|
|
|
|
pos_x += label_season_w + 5
|
|
|
|
# TODO mirar retro-compatilibidad
|
|
# if xbmcgui.ControlEdit == ControlEdit:
|
|
# edit_season = xbmcgui.ControlEdit(0, 0, 0, 0, '', font=self.font, isPassword=False,
|
|
# textColor='',
|
|
# focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
# 'MenuItemFO.png'),
|
|
# noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
# 'MenuItemNF.png'), window=self)
|
|
# else:
|
|
|
|
# control bugeado se tiene que usar metodos sets para que se cree correctamente.
|
|
edit_season = xbmcgui.ControlEdit(0, 0, 0, 0, "", self.font, "", '', 4, isPassword=False,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'MenuItemFO.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'MenuItemNF.png'))
|
|
self.addControl(edit_season)
|
|
edit_season.setText(str(e[0]))
|
|
# edit_season.setLabel("Temporada:", font=self.font, textColor="0xFF2E64FE")
|
|
edit_season.setPosition(pos_x, pos_y - 2)
|
|
edit_season.setWidth(25)
|
|
edit_season.setHeight(35)
|
|
edit_season.setVisible(False)
|
|
|
|
label_episode_w = 90
|
|
pos_x += edit_season.getWidth() + 60
|
|
label_episode = xbmcgui.ControlLabel(pos_x, pos_y + 3, label_episode_w, 34, config.get_localized_string(70598),
|
|
font=self.font, textColor="0xFF2E64FE")
|
|
self.addControl(label_episode)
|
|
label_episode.setVisible(False)
|
|
|
|
pos_x += label_episode_w + 5
|
|
# control bugeado se tiene que usar metodos sets para que se cree correctamente.
|
|
edit_episode = xbmcgui.ControlEdit(0, 0, 0, 0, "", self.font, "", '', 4, isPassword=False,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'MenuItemFO.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'MenuItemNF.png'))
|
|
self.addControl(edit_episode)
|
|
edit_episode.setText(str(e[1]))
|
|
# edit_episode.setLabel("Episodios:", font=self.font, textColor="0xFF2E64FE")
|
|
edit_episode.setPosition(pos_x, pos_y - 2)
|
|
edit_episode.setWidth(40)
|
|
edit_episode.setHeight(35)
|
|
edit_episode.setVisible(False)
|
|
|
|
btn_delete_season_w = 120
|
|
btn_delete_season = xbmcgui.ControlButton(self.controls_bg.getX() + self.controls_bg.getWidth() -
|
|
btn_delete_season_w - 14, pos_y, btn_delete_season_w, 30,
|
|
config.get_localized_string(70599), font=self.font,
|
|
focusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKey.png'),
|
|
noFocusTexture=os.path.join(self.mediapath, 'Controls',
|
|
'KeyboardKeyNF.png'),
|
|
alignment=ALIGN_CENTER)
|
|
self.addControl(btn_delete_season)
|
|
btn_delete_season.setVisible(False)
|
|
|
|
hb_bg = xbmcgui.ControlImage(self.controls_bg.getX() + 10, pos_y + 40,
|
|
self.controls_bg.getWidth() - 20,
|
|
2, os.path.join(self.mediapath, 'Controls', 'ScrollBack.png'))
|
|
self.addControl(hb_bg)
|
|
hb_bg.setVisible(False)
|
|
|
|
group = ControlGroup(label_season=label_season, edit_season=edit_season,
|
|
label_episode=label_episode,
|
|
edit_episode=edit_episode, btn_delete_season=btn_delete_season, hb=hb_bg)
|
|
|
|
pos_y += 50
|
|
|
|
if index < 5:
|
|
group.set_visible(True)
|
|
|
|
self.controls.append(group)
|
|
|
|
if len(self.data) > 5:
|
|
self.move_scroll()
|
|
|
|
except Exception, Ex:
|
|
logger.error("HA HABIDO UNA HOSTIA %s" % Ex)
|
|
|
|
# def onClick(self, control_id):
|
|
# pass
|
|
#
|
|
# def onFocus(self, control_id):
|
|
# pass
|
|
|
|
def onControl(self, control):
|
|
# logger.debug("%s" % control.getId())
|
|
control_id = control.getId()
|
|
|
|
if control_id == ID_BUTTON_OK:
|
|
write_data(self.channel, self.show, self.data)
|
|
self.close()
|
|
if control_id in [ID_BUTTON_CLOSE, ID_BUTTON_CANCEL]:
|
|
self.close()
|
|
elif control_id == ID_BUTTON_DELETE:
|
|
self.close()
|
|
borrar(self.channel, self.show)
|
|
elif control_id == ID_BUTTON_ADD_SEASON:
|
|
# logger.debug("data que enviamos: {}".format(self.data))
|
|
data = add_season(self.data)
|
|
if data:
|
|
self.data = data
|
|
# logger.debug("data que recibimos: {}".format(self.data))
|
|
self.onInit()
|
|
|
|
# si hay más de 5 elementos movemos el scroll
|
|
if len(self.data) > 5:
|
|
self.scroll(len(self.data) - 2, 1)
|
|
self.move_scroll()
|
|
|
|
elif control_id == ID_BUTTON_INFO:
|
|
self.method_info()
|
|
else:
|
|
for x, grupo in enumerate(self.controls):
|
|
if control_id == self.controls[x].btn_delete_season.getId():
|
|
# logger.debug("A data %s" % self.data)
|
|
self.removeControls(self.controls[x].list_elements())
|
|
del self.controls[x]
|
|
del self.data[x]
|
|
# logger.debug("D data %s" % self.data)
|
|
self.onInit()
|
|
|
|
return
|
|
|
|
def onAction(self, action):
|
|
# logger.debug("%s" % action.getId())
|
|
# logger.debug("focus %s" % self.getFocusId())
|
|
# Obtenemos el foco
|
|
focus = self.getFocusId()
|
|
|
|
action = action.getId()
|
|
# Flecha izquierda
|
|
if action == xbmcgui.ACTION_MOVE_LEFT:
|
|
# Si el foco no está en ninguno de los 6 botones inferiores, y esta en un "list" cambiamos el valor
|
|
if focus not in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET,
|
|
ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
|
|
# Localizamos en el listado de controles el control que tiene el focus
|
|
# todo mirar tema del cursor en el valor al desplazar lateralmente
|
|
for x, linea in enumerate(self.controls):
|
|
if focus == linea.edit_season.getId():
|
|
return self.setFocus(self.controls[x].btn_delete_season)
|
|
elif focus == linea.edit_episode.getId():
|
|
return self.setFocus(self.controls[x].edit_season)
|
|
elif focus == linea.btn_delete_season.getId():
|
|
return self.setFocus(self.controls[x].edit_episode)
|
|
|
|
# Si el foco está en alguno de los 6 botones inferiores, movemos al siguiente
|
|
else:
|
|
if focus in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET]:
|
|
if focus == ID_BUTTON_ADD_SEASON:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
# TODO cambiar cuando se habilite la opcion de actualizar por internet
|
|
# self.setFocusId(ID_CHECK_UPDATE_INTERNET)
|
|
elif focus == ID_BUTTON_INFO:
|
|
self.setFocusId(ID_BUTTON_ADD_SEASON)
|
|
elif focus == ID_CHECK_UPDATE_INTERNET:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
|
|
elif focus in [ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
if focus == ID_BUTTON_OK:
|
|
self.setFocusId(ID_BUTTON_DELETE)
|
|
elif focus == ID_BUTTON_CANCEL:
|
|
self.setFocusId(ID_BUTTON_OK)
|
|
elif focus == ID_BUTTON_DELETE:
|
|
self.setFocusId(ID_BUTTON_CANCEL)
|
|
|
|
# Flecha derecha
|
|
elif action == xbmcgui.ACTION_MOVE_RIGHT:
|
|
# Si el foco no está en ninguno de los 6 botones inferiores, y esta en un "list" cambiamos el valor
|
|
if focus not in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET,
|
|
ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
|
|
# Localizamos en el listado de controles el control que tiene el focus
|
|
# todo mirar tema del cursor en el valor al desplazar lateralmente
|
|
for x, linea in enumerate(self.controls):
|
|
if focus == linea.edit_season.getId():
|
|
return self.setFocus(self.controls[x].edit_episode)
|
|
elif focus == linea.edit_episode.getId():
|
|
return self.setFocus(self.controls[x].btn_delete_season)
|
|
elif focus == linea.btn_delete_season.getId():
|
|
return self.setFocus(self.controls[x].edit_season)
|
|
|
|
# Si el foco está en alguno de los 6 botones inferiores, movemos al siguiente
|
|
else:
|
|
if focus in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET]:
|
|
if focus == ID_BUTTON_ADD_SEASON:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
if focus == ID_BUTTON_INFO:
|
|
self.setFocusId(ID_BUTTON_ADD_SEASON)
|
|
# TODO cambiar cuando se habilite la opcion de actualizar por internet
|
|
# self.setFocusId(ID_CHECK_UPDATE_INTERNET)
|
|
if focus == ID_CHECK_UPDATE_INTERNET:
|
|
self.setFocusId(ID_BUTTON_OK)
|
|
|
|
elif focus in [ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
if focus == ID_BUTTON_OK:
|
|
self.setFocusId(ID_BUTTON_CANCEL)
|
|
if focus == ID_BUTTON_CANCEL:
|
|
self.setFocusId(ID_BUTTON_DELETE)
|
|
if focus == ID_BUTTON_DELETE:
|
|
self.setFocusId(ID_BUTTON_OK)
|
|
|
|
# Flecha arriba
|
|
elif action == xbmcgui.ACTION_MOVE_UP:
|
|
self.move_up(focus)
|
|
# Flecha abajo
|
|
elif action == xbmcgui.ACTION_MOVE_DOWN:
|
|
self.move_down(focus)
|
|
# scroll up
|
|
elif action == xbmcgui.ACTION_MOUSE_WHEEL_UP:
|
|
self.move_up(focus)
|
|
# scroll down
|
|
elif action == xbmcgui.ACTION_MOUSE_WHEEL_DOWN:
|
|
self.move_down(focus)
|
|
|
|
# ACTION_PAGE_DOWN = 6
|
|
# ACTION_PAGE_UP = 5
|
|
|
|
# Menú previo o Atrás
|
|
elif action in [xbmcgui.ACTION_PREVIOUS_MENU, xbmcgui.ACTION_NAV_BACK]:
|
|
self.close()
|
|
|
|
def move_down(self, focus):
|
|
# logger.debug("focus " + str(focus))
|
|
# Si el foco está en uno de los tres botones medios, bajamos el foco a la otra linea de botones
|
|
if focus in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET]:
|
|
if focus == ID_BUTTON_ADD_SEASON:
|
|
self.setFocusId(ID_BUTTON_OK)
|
|
elif focus == ID_BUTTON_INFO:
|
|
self.setFocusId(ID_BUTTON_CANCEL)
|
|
elif focus == ID_CHECK_UPDATE_INTERNET:
|
|
self.setFocusId(ID_BUTTON_DELETE)
|
|
# Si el foco está en uno de los tres botones inferiores, subimos el foco al primer control del listado
|
|
elif focus in [ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
first_visible = 0
|
|
for x, linea in enumerate(self.controls):
|
|
if linea.get_visible():
|
|
first_visible = x
|
|
break
|
|
|
|
if focus == ID_BUTTON_OK:
|
|
self.setFocus(self.controls[first_visible].edit_season)
|
|
elif focus == ID_BUTTON_CANCEL:
|
|
self.setFocus(self.controls[first_visible].edit_episode)
|
|
elif focus == ID_BUTTON_DELETE:
|
|
self.setFocus(self.controls[first_visible].btn_delete_season)
|
|
# nos movemos entre los elementos del listado
|
|
else:
|
|
# Localizamos en el listado de controles el control que tiene el focus
|
|
for x, linea in enumerate(self.controls):
|
|
if focus == linea.edit_season.getId():
|
|
if x + 1 < len(self.controls):
|
|
if not self.controls[x + 1].get_visible():
|
|
self.scroll(x, 1)
|
|
|
|
return self.setFocus(self.controls[x + 1].edit_season)
|
|
else:
|
|
return self.setFocusId(ID_BUTTON_ADD_SEASON)
|
|
elif focus == linea.edit_episode.getId():
|
|
if x + 1 < len(self.controls):
|
|
if not self.controls[x + 1].get_visible():
|
|
self.scroll(x, 1)
|
|
|
|
return self.setFocus(self.controls[x + 1].edit_episode)
|
|
else:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
elif focus == linea.btn_delete_season.getId():
|
|
if x + 1 < len(self.controls):
|
|
if not self.controls[x + 1].get_visible():
|
|
self.scroll(x, 1)
|
|
|
|
return self.setFocus(self.controls[x + 1].btn_delete_season)
|
|
else:
|
|
return self.setFocusId(ID_BUTTON_INFO)
|
|
# TODO cambiar cuando se habilite la opcion de actualizar por internet
|
|
# return self.setFocusId(ID_CHECK_UPDATE_INTERNET)
|
|
|
|
def move_up(self, focus):
|
|
# Si el foco está en uno de los tres botones medios, subimos el foco al último control del listado
|
|
if focus in [ID_BUTTON_ADD_SEASON, ID_BUTTON_INFO, ID_CHECK_UPDATE_INTERNET]:
|
|
last_visible = 0
|
|
for x, linea in reversed(list(enumerate(self.controls))):
|
|
if linea.get_visible():
|
|
last_visible = x
|
|
break
|
|
|
|
if focus == ID_BUTTON_ADD_SEASON:
|
|
self.setFocus(self.controls[last_visible].edit_season)
|
|
elif focus == ID_BUTTON_INFO:
|
|
self.setFocus(self.controls[last_visible].edit_episode)
|
|
elif focus == ID_CHECK_UPDATE_INTERNET:
|
|
self.setFocus(self.controls[last_visible].btn_delete_season)
|
|
# Si el foco está en uno de los tres botones inferiores, subimos el foco a la otra linea de botones
|
|
elif focus in [ID_BUTTON_OK, ID_BUTTON_CANCEL, ID_BUTTON_DELETE]:
|
|
if focus == ID_BUTTON_OK:
|
|
self.setFocusId(ID_BUTTON_ADD_SEASON)
|
|
elif focus == ID_BUTTON_CANCEL:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
elif focus == ID_BUTTON_DELETE:
|
|
self.setFocusId(ID_BUTTON_INFO)
|
|
# TODO cambiar cuando se habilite la opcion de actualizar por internet
|
|
# self.setFocusId(ID_CHECK_UPDATE_INTERNET)
|
|
# nos movemos entre los elementos del listado
|
|
else:
|
|
# Localizamos en el listado de controles el control que tiene el focus
|
|
for x, linea in enumerate(self.controls):
|
|
if focus == linea.edit_season.getId():
|
|
if x > 0:
|
|
if not self.controls[x - 1].get_visible():
|
|
self.scroll(x, -1)
|
|
|
|
return self.setFocus(self.controls[x - 1].edit_season)
|
|
else:
|
|
return self.setFocusId(ID_BUTTON_OK)
|
|
elif focus == linea.edit_episode.getId():
|
|
if x > 0:
|
|
if not self.controls[x - 1].get_visible():
|
|
self.scroll(x, -1)
|
|
|
|
return self.setFocus(self.controls[x - 1].edit_episode)
|
|
else:
|
|
self.setFocusId(ID_BUTTON_CANCEL)
|
|
elif focus == linea.btn_delete_season.getId():
|
|
if x > 0:
|
|
if not self.controls[x - 1].get_visible():
|
|
self.scroll(x, -1)
|
|
|
|
return self.setFocus(self.controls[x - 1].btn_delete_season)
|
|
else:
|
|
return self.setFocusId(ID_BUTTON_DELETE)
|
|
# TODO cambiar cuando se habilite la opcion de actualizar por internet
|
|
# return self.setFocusId(ID_CHECK_UPDATE_INTERNET)
|
|
|
|
def scroll(self, position, movement):
|
|
try:
|
|
for index, group in enumerate(self.controls):
|
|
# ponemos todos los elementos como no visibles
|
|
group.set_visible(False)
|
|
|
|
if movement > 0:
|
|
pos_fin = position + movement + 1
|
|
pos_inicio = pos_fin - 5
|
|
else:
|
|
pos_inicio = position + movement
|
|
pos_fin = pos_inicio + 5
|
|
|
|
# logger.debug("position {}, movement {}, pos_inicio{}, pos_fin{}, self.data.length{}".
|
|
# format(position, movement, pos_inicio, pos_fin, len(self.data)))
|
|
pos_y = self.controls_bg.getY() + 10
|
|
for i in range(pos_inicio, pos_fin):
|
|
pos_x = self.controls_bg.getX() + 15
|
|
|
|
self.controls[i].label_season.setPosition(pos_x, pos_y + 3)
|
|
|
|
pos_x += self.controls[i].label_season.getWidth() + 5
|
|
self.controls[i].edit_season.setPosition(pos_x, pos_y - 2)
|
|
|
|
pos_x += self.controls[i].edit_season.getWidth() + 60
|
|
self.controls[i].label_episode.setPosition(pos_x, pos_y + 3)
|
|
|
|
pos_x += self.controls[i].label_episode.getWidth() + 5
|
|
self.controls[i].edit_episode.setPosition(pos_x, pos_y - 2)
|
|
|
|
self.controls[i].btn_delete_season.setPosition(
|
|
self.controls_bg.getX() + self.controls_bg.getWidth() -
|
|
self.controls[i].btn_delete_season.getWidth() - 14,
|
|
pos_y)
|
|
|
|
self.controls[i].hb.setPosition(self.controls_bg.getX() + 10, pos_y + 40)
|
|
|
|
pos_y += 50
|
|
|
|
# logger.debug("ponemos como True %s" % i)
|
|
self.controls[i].set_visible(True)
|
|
|
|
self.move_scroll()
|
|
|
|
except Exception, Ex:
|
|
logger.error("HA HABIDO UNA HOSTIA %s" % Ex)
|
|
|
|
def move_scroll(self):
|
|
visible_controls = [group for group in self.controls if group.get_visible() == True]
|
|
hidden_controls = [group for group in self.controls if group.get_visible() == False]
|
|
scroll_position = self.controls.index(visible_controls[0])
|
|
scrollbar_height = self.scroll_bg.getHeight() - (len(hidden_controls) * 10)
|
|
scrollbar_y = self.scroll_bg.getPosition()[1] + (scroll_position * 10)
|
|
self.scroll2_bg.setPosition(self.scroll_bg.getPosition()[0], scrollbar_y)
|
|
self.scroll2_bg.setHeight(scrollbar_height)
|
|
|
|
@staticmethod
|
|
def method_info():
|
|
title = config.get_localized_string(60348)
|
|
# text = "La primera temporada que se añade siempre empieza en \"0\" episodios, la segunda temporada que se "
|
|
# text += "añade empieza en el número total de episodios de la primera temporada, la tercera temporada será "
|
|
# text += "la suma de los episodios de las temporadas previas y así sucesivamente.\n"
|
|
# text += "[COLOR blue]\nEjemplo de serie divida en varias temporadas:\n"
|
|
# text += "\nFairy Tail:\n"
|
|
# text += " - SEASON 1: EPISODE 48 --> [season 1, episode: 0]\n"
|
|
# text += " - SEASON 2: EPISODE 48 --> [season 2, episode: 48]\n"
|
|
# text += " - SEASON 3: EPISODE 54 --> [season 3, episode: 96 ([48=season2] + [48=season1])]\n"
|
|
# text += " - SEASON 4: EPISODE 175 --> [season 4: episode: 150 ([54=season3] + [48=season2] + [48=season3" \
|
|
# "])][/COLOR]\n"
|
|
# text += "[COLOR green]\nEjemplo de serie que continua en la temporada de la original:\n"
|
|
# text += "\nFate/Zero 2nd Season:\n"
|
|
# text += " - SEASON 1: EPISODE 12 --> [season 1, episode: 13][/COLOR]\n"
|
|
|
|
# text += "[COLOR blue]\nEjemplo de serie que es la segunda temporada de la original:\n"
|
|
# text += "\nFate/kaleid liner Prisma☆Illya 2wei!:\n"
|
|
# text += " - SEASON 1: EPISODE 12 --> [season 2, episode: 0][/COLOR]\n"
|
|
text = config.get_localized_string(70602)
|
|
|
|
return TextBox("DialogTextViewer.xml", os.getcwd(), "Default", title=title, text=text)
|
|
|
|
|
|
class ControlGroup:
|
|
"""
|
|
conjunto de controles, son los elementos que se muestra por línea de una lista.
|
|
"""
|
|
|
|
def __init__(self, label_season, edit_season, label_episode, edit_episode, btn_delete_season, hb):
|
|
self.visible = False
|
|
self.label_season = label_season
|
|
self.edit_season = edit_season
|
|
self.label_episode = label_episode
|
|
self.edit_episode = edit_episode
|
|
self.btn_delete_season = btn_delete_season
|
|
self.hb = hb
|
|
|
|
def list_elements(self):
|
|
return [self.label_season, self.edit_season, self.label_episode, self.edit_episode, self.btn_delete_season,
|
|
self.hb]
|
|
|
|
def get_visible(self):
|
|
return self.visible
|
|
|
|
def set_visible(self, visible):
|
|
self.visible = visible
|
|
self.label_season.setVisible(visible)
|
|
self.edit_season.setVisible(visible)
|
|
self.label_episode.setVisible(visible)
|
|
self.edit_episode.setVisible(visible)
|
|
self.btn_delete_season.setVisible(visible)
|
|
self.hb.setVisible(visible)
|
|
|
|
|
|
class TextBox(xbmcgui.WindowXMLDialog):
|
|
""" Create a skinned textbox window """
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.title = kwargs.get('title')
|
|
self.text = kwargs.get('text')
|
|
self.doModal()
|
|
|
|
def onInit(self):
|
|
try:
|
|
self.getControl(5).setText(self.text)
|
|
self.getControl(1).setLabel(self.title)
|
|
except:
|
|
pass
|
|
|
|
def onClick(self, control_id):
|
|
pass
|
|
|
|
def onFocus(self, control_id):
|
|
pass
|
|
|
|
def onAction(self, action):
|
|
self.close()
|
|
|
|
# TODO mirar retro-compatiblidad
|
|
# class ControlEdit(xbmcgui.ControlButton):
|
|
# def __new__(self, *args, **kwargs):
|
|
# del kwargs["isPassword"]
|
|
# del kwargs["window"]
|
|
# args = list(args)
|
|
# return xbmcgui.ControlButton.__new__(self, *args, **kwargs)
|
|
#
|
|
# def __init__(self, *args, **kwargs):
|
|
# self.isPassword = kwargs["isPassword"]
|
|
# self.window = kwargs["window"]
|
|
# self.label = ""
|
|
# self.text = ""
|
|
# self.textControl = xbmcgui.ControlLabel(self.getX(), self.getY(), self.getWidth(), self.getHeight(),
|
|
# self.text,
|
|
# font=kwargs["font"], textColor=kwargs["textColor"], alignment=4 | 1)
|
|
# self.window.addControl(self.textControl)
|
|
#
|
|
# def setLabel(self, val):
|
|
# self.label = val
|
|
# xbmcgui.ControlButton.setLabel(self, val)
|
|
#
|
|
# def getX(self):
|
|
# return xbmcgui.ControlButton.getPosition(self)[0]
|
|
#
|
|
# def getY(self):
|
|
# return xbmcgui.ControlButton.getPosition(self)[1]
|
|
#
|
|
# def setEnabled(self, e):
|
|
# xbmcgui.ControlButton.setEnabled(self, e)
|
|
# self.textControl.setEnabled(e)
|
|
#
|
|
# def setWidth(self, w):
|
|
# xbmcgui.ControlButton.setWidth(self, w)
|
|
# self.textControl.setWidth(w / 2)
|
|
#
|
|
# def setHeight(self, w):
|
|
# xbmcgui.ControlButton.setHeight(self, w)
|
|
# self.textControl.setHeight(w)
|
|
#
|
|
# def setPosition(self, x, y):
|
|
# xbmcgui.ControlButton.setPosition(self, x, y)
|
|
# self.textControl.setPosition(x + self.getWidth() / 2, y)
|
|
#
|
|
# def setText(self, text):
|
|
# self.text = text
|
|
# if self.isPassword:
|
|
# self.textControl.setLabel("*" * len(self.text))
|
|
# else:
|
|
# self.textControl.setLabel(self.text)
|
|
#
|
|
# def getText(self):
|
|
# return self.text
|
|
#
|
|
#
|
|
# if not hasattr(xbmcgui, "ControlEdit"):
|
|
# xbmcgui.ControlEdit = ControlEdit
|