-Nuova Ricerca Globale\n-Nuova Rinumerazione\n-Messaggi di Errore più chiari\n-Fix var\n
This commit is contained in:
marco
2020-12-01 20:19:07 +01:00
parent 97e06a8b84
commit 94eac40955
233 changed files with 4568 additions and 2245 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
import xbmc, xbmcgui
import xbmcaddon
import json
from platformcode import config, logger
import requests
import sys
@@ -236,63 +235,3 @@ def test_conn(is_exit, check_dns, view_msg,
# else:
# return False
# def for creating the channels.json file
def check_channels(inutile=''):
"""
I read the channel hosts from the channels.json file, I check them,
I write the channels-test.json file with the error code and the new url in case of redirect
urls MUST have http (s)
During the urls check the ip, asdl and dns checks are carried out.
This is because it can happen that at any time the connection may have problems. If it does, check it
relative writing of the file is interrupted with a warning message
"""
logger.info()
folderJson = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('path')).decode('utf-8')
fileJson = 'channels.json'
with open(folderJson+'/'+fileJson) as f:
data = json.load(f)
risultato = {}
for chann, host in sorted(data['direct'].items()):
ris = []
# to get an idea of the timing
# useful only if you control all channels
# for channels with error 522 about 40 seconds are lost ...
logger.info("check #### INIZIO #### channel - host :%s - %s " % (chann, host))
rslt = Kdicc(lst_urls = [host]).http_Resp()
# all right
if rslt['code'] == 200:
risultato[chann] = host
# redirect
elif str(rslt['code']).startswith('3'):
# risultato[chann] = str(rslt['code']) +' - '+ rslt['redirect'][:-1]
if rslt['redirect'].endswith('/'):
rslt['redirect'] = rslt['redirect'][:-1]
risultato[chann] = rslt['redirect']
# non-existent site
elif rslt['code'] == -2:
risultato[chann] = 'Host Sconosciuto - '+ str(rslt['code']) +' - '+ host
# site not reachable - probable dns not set
elif rslt['code'] == 111:
risultato[chann] = ['Host non raggiungibile - '+ str(rslt['code']) +' - '+ host]
else:
# other types of errors
# risultato[chann] = 'Errore Sconosciuto - '+str(rslt['code']) +' - '+ host
risultato[chann] = host
logger.info("check #### FINE #### rslt :%s " % (rslt))
risultato = {'findhost': data['findhost'], 'direct': risultato}
fileJson_test = 'channels-test.json'
# I write the updated file
with open(folderJson+'/'+fileJson_test, 'w') as f:
data = json.dump(risultato, f, sort_keys=True, indent=4)
logger.info(data)

View File

@@ -0,0 +1,604 @@
# -*- coding: utf-8 -*-
import xbmc, xbmcgui, sys, channelselector, time
from core.support import dbg, typo, tmdb
from core.item import Item
from core import channeltools, servertools, scrapertools
from platformcode import platformtools, config, logger
from platformcode.launcher import run
from threading import Thread
if sys.version_info[0] >= 3: from concurrent import futures
else: from concurrent_py2 import futures
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
def busy(state):
if state: xbmc.executebuiltin('ActivateWindow(busydialognocancel)')
else: xbmc.executebuiltin('Dialog.Close(busydialognocancel)')
def set_workers():
workers = config.get_setting('thread_number') if config.get_setting('thread_number') > 0 else None
return workers
def Search(item):
xbmc.executebuiltin('Dialog.Close(all,true)')
SearchWindow('GlobalSearch.xml', config.get_runtime_path()).start(item)
xbmc.sleep(600)
# Actions
LEFT = 1
RIGHT = 2
UP = 3
DOWN = 4
EXIT = 10
BACKSPACE = 92
SWIPEUP = 531
CONTEXT = 117
# Container
SEARCH = 1
EPISODES = 2
SERVERS = 3
NORESULTS = 4
LOADING = 5
# Search
MAINTITLE = 100
CHANNELS = 101
RESULTS = 102
PROGRESS = 500
COUNT = 501
MENU = 502
BACK = 503
CLOSE = 504
QUALITYTAG = 505
# Servers
EPISODESLIST = 200
SERVERLIST = 300
class SearchWindow(xbmcgui.WindowXML):
def start(self, item):
logger.debug()
self.exit = False
self.item = item
self.lastSearch()
if not self.item.text: return
self.type = self.item.mode
self.channels = []
self.find = []
self.persons = []
self.episodes = []
self.servers = []
self.results = {}
self.channelsList = self.get_channels()
self.focus = SEARCH
self.process = True
self.page = 1
self.moduleDict = {}
self.searchActions = []
self.thread = None
self.doModal()
def lastSearch(self):
logger.debug()
if not self.item.text:
if config.get_setting('last_search'): last_search = channeltools.get_channel_setting('Last_searched', 'search', '')
else: last_search = ''
if not self.item.text: self.item.text = platformtools.dialog_input(default=last_search, heading='')
if self.item.text: channeltools.set_channel_setting('Last_searched', self.item.text, 'search')
def select(self):
logger.debug()
self.PROGRESS.setVisible(False)
items = []
if self.persons:
tmdb_info = tmdb.discovery(self.item, dict_=self.item.discovery)
results = tmdb_info.results.get('cast',[])
else:
tmdb_info = tmdb.Tmdb(texto_buscado=self.item.text, tipo=self.item.mode.replace('show', ''))
results = tmdb_info.results
for result in results:
logger.info(result)
result = tmdb_info.get_infoLabels(result, origen=result)
movie = result.get('title','')
tvshow = result.get('name','')
title = tvshow if tvshow else movie
result['mode'] = 'tvshow' if tvshow else 'movie'
self.find.append(result)
thumb = 'Infoplus/' + result['mode'].replace('show','') + '.png'
it = xbmcgui.ListItem(title)
it.setProperty('thumb', result.get('thumbnail', thumb))
it.setProperty('fanart', result.get('fanart',''))
it.setProperty('plot', result.get('overview', ''))
it.setProperty('search','search')
year = result.get('release_date','')
if year: it.setProperty('year','[' + year.split('/')[-1] + ']')
else:
year = result.get('first_air_date','')
if year: it.setProperty('year','[' + year.split('-')[0] + ']')
items.append(it)
if items:
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.setFocusId(RESULTS)
else:
self.NORESULTS.setVisible(True)
def actors(self):
logger.debug()
self.PROGRESS.setVisible(False)
items = []
dict_ = {'url': 'search/person', 'language': def_lang, 'query': self.item.text, 'page':self.page}
prof = {'Acting': 'Actor', 'Directing': 'Director', 'Production': 'Productor'}
plot = ''
self.item.search_type = 'person'
tmdb_inf = tmdb.discovery(self.item, dict_=dict_)
results = tmdb_inf.results
for elem in results:
name = elem.get('name', '')
if not name: continue
rol = elem.get('known_for_department', '')
rol = prof.get(rol, rol)
know_for = elem.get('known_for', '')
cast_id = elem.get('id', '')
if know_for:
t_k = know_for[0].get('title', '')
if t_k: plot = '%s in %s' % (rol, t_k)
t = elem.get('profile_path', '')
if t: thumb = 'https://image.tmdb.org/t/p/original' + t
else : thumb = 'Infoplus/no_photo.png'
discovery = {'url': 'person/%s/combined_credits' % cast_id, 'page': '1', 'sort_by': 'primary_release_date.desc', 'language': def_lang}
self.persons.append(discovery)
it = xbmcgui.ListItem(name)
it.setProperty('thumb', thumb)
it.setProperty('plot', plot)
it.setProperty('search','persons')
items.append(it)
if len(results) > 19:
it = xbmcgui.ListItem(config.get_localized_string(70006))
it.setProperty('thumb', 'Infoplus/next_focus.png')
it.setProperty('search','next')
items.append(it)
if self.page > 1:
it = xbmcgui.ListItem(config.get_localized_string(70005))
it.setProperty('thumb', 'Infoplus/previous_focus.png')
it.setProperty('search','previous')
items.insert(0, it)
if items:
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.setFocusId(RESULTS)
else:
self.NORESULTS.setVisible(True)
def get_channels(self):
logger.debug()
channels_list = []
all_channels = channelselector.filterchannels('all')
for ch in all_channels:
channel = ch.channel
ch_param = channeltools.get_channel_parameters(channel)
if not ch_param.get("active", False):
continue
list_cat = ch_param.get("categories", [])
if not ch_param.get("include_in_global_search", False):
continue
if 'anime' in list_cat:
n = list_cat.index('anime')
list_cat[n] = 'tvshow'
if self.item.mode == 'all' or self.item.type in list_cat:
if config.get_setting("include_in_global_search", channel) and ch_param.get("active", False):
channels_list.append(channel)
logger.debug('search in channels:',channels_list)
return channels_list
def getModule(self, channel):
logger.debug()
try:
module = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel])
mainlist = getattr(module, 'mainlist')(Item(channel=channel, global_search=True))
action = [elem for elem in mainlist if elem.action == "search" and (self.item.mode == 'all' or elem.contentType in [self.item.mode, 'undefined'])]
return module, action
except:
import traceback
logger.error('error importing/getting search items of ' + channel)
logger.error(traceback.format_exc())
return None, None
def search(self):
count = 0
self.count = 0
self.LOADING.setVisible(True)
with futures.ThreadPoolExecutor() as executor:
for channel in self.channelsList:
if self.exit: break
module, action = executor.submit(self.getModule, channel).result()
if module and action:
self.moduleDict[channel] = module
self.searchActions += action
count += 1
percent = (float(count) / len(self.channelsList)) * 100
self.PROGRESS.setPercent(percent)
self.COUNT.setText('%s/%s' % (count, len(self.channelsList)))
with futures.ThreadPoolExecutor(max_workers=set_workers()) as executor:
for searchAction in self.searchActions:
if self.exit: break
executor.submit(self.get_channel_results, self.item, self.moduleDict, searchAction)
def get_channel_results(self, item, module_dict, search_action):
logger.debug()
channel = search_action.channel
results = []
valid = []
other = []
module = module_dict[channel]
searched_id = item.infoLabels['tmdb_id']
try:
results.extend(module.search(search_action, item.text))
if len(results) == 1:
if not results[0].action or config.get_localized_string(70006).lower() in results[0].title.lower():
results = []
if self.item.mode != 'all':
for elem in results:
if not elem.infoLabels.get('year', ""):
elem.infoLabels['year'] = '-'
tmdb.set_infoLabels_item(elem)
if elem.infoLabels['tmdb_id'] == searched_id:
elem.from_channel = channel
elem.verified ='ok.png'
valid.append(elem)
else:
other.append(elem)
except:
pass
self.count += 1
if self.item.mode == 'all': self.update(channel, results)
else: self.update(channel, valid + other)
def makeItem(self, item):
logger.debug()
thumb = item.thumbnail if item.thumbnail else 'Infoplus/' + item.contentType.replace('show','') + 'png'
logger.info('THUMB', thumb)
it = xbmcgui.ListItem(item.title)
it.setProperty('year', '[' + str(item.year if item.year else item.infoLabels.get('year','')) + ']')
it.setProperty('thumb', thumb)
it.setProperty('fanart', item.fanart)
it.setProperty('plot', item.plot)
it.setProperty('verified', item.verified)
if item.server:
color = scrapertools.find_single_match(item.alive, r'(FF[^\]]+)')
it.setProperty('channel', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('thumb', "https://raw.githubusercontent.com/kodiondemand/media/master/resources/servers/%s.png" % item.server.lower())
it.setProperty('servername', servertools.get_server_parameters(item.server.lower()).get('name',item.server))
it.setProperty('color', color if color else 'FF0082C2')
return it
def update(self, channel, results):
logger.debug('Search on channel', channel)
if results:
channelParams = channeltools.get_channel_parameters(channel)
name = channelParams['title']
if name not in self.results:
self.results[name] = [results, len(self.channels)]
item = xbmcgui.ListItem(name)
item.setProperty('thumb', channelParams['thumbnail'])
item.setProperty('position', '0')
item.setProperty('results', str(len(results)))
item.setProperty('verified', results[0].verified)
self.channels.append(item)
else:
self.results[name].append([results, len(self.channels)])
self.channels[int(self.results[name][1])].setProperty('results', str(len(results)))
pos = self.CHANNELS.getSelectedPosition()
self.CHANNELS.reset()
self.CHANNELS.addItems(self.channels)
self.CHANNELS.selectItem(pos)
if len(self.channels) == 1:
self.setFocusId(CHANNELS)
items = []
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
percent = (float(self.count) / len(self.searchActions)) * 100
self.LOADING.setVisible(False)
self.PROGRESS.setPercent(percent)
self.COUNT.setText('%s/%s [%s"]' % (self.count, len(self.searchActions), int(time.time() - self.time) ))
if percent == 100 and not self.results:
self.PROGRESS.setVisible(False)
self.NORESULTS.setVisible(True)
def onInit(self):
self.time = time.time()
# collect controls
self.CHANNELS = self.getControl(CHANNELS)
self.RESULTS = self.getControl(RESULTS)
self.PROGRESS = self.getControl(PROGRESS)
self.COUNT = self.getControl(COUNT)
self.MAINTITLE = self.getControl(MAINTITLE)
self.MAINTITLE.setText(typo(config.get_localized_string(30993).replace('...','') % '"%s"' % self.item.text, 'bold'))
self.SEARCH = self.getControl(SEARCH)
self.EPISODES = self.getControl(EPISODES)
self.EPISODESLIST = self.getControl(EPISODESLIST)
self.SERVERS = self.getControl(SERVERS)
self.SERVERLIST = self.getControl(SERVERLIST)
self.NORESULTS = self.getControl(NORESULTS)
self.NORESULTS.setVisible(False)
self.LOADING = self.getControl(LOADING)
self.LOADING.setVisible(False)
self.Focus(self.focus)
if self.type:
self.type = None
if self.item.mode in ['all', 'search']:
if self.item.type: self.item.mode = self.item.type
self.thread = Thread(target=self.search)
self.thread.start()
elif self.item.mode in ['movie', 'tvshow']:
self.select()
elif self.item.mode in ['person']:
self.actors()
def Focus(self, focusid):
if focusid in [SEARCH]:
self.focus = CHANNELS
self.SEARCH.setVisible(True)
self.EPISODES.setVisible(False)
self.SERVERS.setVisible(False)
if focusid in [EPISODES]:
self.focus = focusid
self.SEARCH.setVisible(False)
self.EPISODES.setVisible(True)
self.SERVERS.setVisible(False)
if focusid in [SERVERS]:
self.focus = SERVERLIST
self.SEARCH.setVisible(False)
self.EPISODES.setVisible(False)
self.SERVERS.setVisible(True)
def onAction(self, action):
action = action.getId()
focus = self.getFocusId()
if action in [CONTEXT] and focus in [RESULTS, EPISODESLIST, SERVERLIST]:
self.context()
elif action in [SWIPEUP] and self.CHANNELS.isVisible() :
self.setFocusId(CHANNELS)
pos = self.CHANNELS.getSelectedPosition()
self.CHANNELS.selectItem(pos)
elif action in [LEFT, RIGHT] and focus in [CHANNELS] and self.CHANNELS.isVisible():
items = []
name = self.CHANNELS.getSelectedItem().getLabel()
subpos = int(self.CHANNELS.getSelectedItem().getProperty('position'))
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.RESULTS.selectItem(subpos)
elif action in [DOWN] and focus in [BACK, CLOSE, MENU]:
if self.SERVERS.isVisible(): self.setFocusId(SERVERLIST)
elif self.EPISODES.isVisible(): self.setFocusId(EPISODESLIST)
else: self.setFocusId(RESULTS)
elif focus in [RESULTS] and self.item.mode == 'all':
pos = self.RESULTS.getSelectedPosition()
self.CHANNELS.getSelectedItem().setProperty('position', str(pos))
if action in [BACKSPACE]:
self.Back()
elif action in [EXIT]:
self.Close()
def onClick(self, control_id):
if self.RESULTS.getSelectedItem(): search = self.RESULTS.getSelectedItem().getProperty('search')
else: search = None
if control_id in [CHANNELS]:
items = []
name = self.CHANNELS.getSelectedItem().getLabel()
subpos = int(self.CHANNELS.getSelectedItem().getProperty('position'))
for result in self.results[name][0]:
items.append(self.makeItem(result))
self.RESULTS.reset()
self.RESULTS.addItems(items)
self.RESULTS.selectItem(subpos)
self.CHANNELS.getSelectedItem().setProperty('position', str(subpos))
# self.setFocusId(RESULTS)
elif control_id in [BACK]:
self.Back()
elif control_id in [CLOSE]:
self.Close()
elif control_id in [MENU]:
self.context()
elif search:
pos = self.RESULTS.getSelectedPosition()
if search == 'next':
self.page += 1
self.actors()
elif search == 'previous':
self.page -= 1
self.actors()
elif search == 'persons':
self.item.discovery = self.persons[pos]
self.select()
else:
result = self.find[pos]
name = self.RESULTS.getSelectedItem().getLabel()
item = Item(mode='search', type=result['mode'], contentType=result['mode'], infoLabels=result, selected = True, text=name)
if self.item.mode == 'movie': item.contentTitle = self.RESULTS.getSelectedItem().getLabel()
else: item.contentSerieName = self.RESULTS.getSelectedItem().getLabel()
return Search(item)
elif control_id in [RESULTS, EPISODESLIST]:
busy(True)
if control_id in [RESULTS]:
name = self.CHANNELS.getSelectedItem().getLabel()
self.pos = self.RESULTS.getSelectedPosition()
item = self.results[name][0][self.pos]
else:
self.pos = self.EPISODESLIST.getSelectedPosition()
item = self.episodes[self.pos]
try:
self.channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel])
self.itemsResult = getattr(self.channel, item.action)(item)
except:
import traceback
logger.error('error importing/getting search items of ' + item.channel)
logger.error(traceback.format_exc())
self.itemsResult = []
if self.itemsResult and self.itemsResult[0].action in ['play', '']:
if config.get_setting('checklinks') and not config.get_setting('autoplay'):
self.itemsResult = servertools.check_list_links(self.itemsResult, config.get_setting('checklinks_number'))
self.servers = self.itemsResult
self.itemsResult = []
uhd = []
fhd = []
hd = []
sd = []
unknown = []
for i, item in enumerate(self.servers):
if item.server:
it = self.makeItem(item)
it.setProperty('index', str(i))
if item.quality in ['4k', '2160p', '2160', '4k2160p', '4k2160', '4k 2160p', '4k 2160', '2k']:
it.setProperty('quality', 'uhd.png')
uhd.append(it)
elif item.quality in ['fullhd', 'fullhd 1080', 'fullhd 1080p', 'full hd', 'full hd 1080', 'full hd 1080p', 'hd1080', 'hd1080p', 'hd 1080', 'hd 1080p', '1080', '1080p']:
it.setProperty('quality', 'Fhd.png')
fhd.append(it)
elif item.quality in ['hd', 'hd720', 'hd720p', 'hd 720', 'hd 720p', '720', '720p', 'hdtv']:
it.setProperty('quality', 'hd.png')
hd.append(it)
elif item.quality in ['sd', '480p', '480', '360p', '360', '240p', '240']:
it.setProperty('quality', 'sd.png')
sd.append(it)
else:
it.setProperty('quality', '')
unknown.append(it)
elif not item.action:
self.getControl(QUALITYTAG).setText(item.fulltitle)
uhd.sort(key=lambda it: it.getProperty('index'))
fhd.sort(key=lambda it: it.getProperty('index'))
hd.sort(key=lambda it: it.getProperty('index'))
sd.sort(key=lambda it: it.getProperty('index'))
unknown.sort(key=lambda it: it.getProperty('index'))
serverlist = uhd + fhd + hd + sd + unknown
self.Focus(SERVERS)
self.SERVERLIST.reset()
self.SERVERLIST.addItems(serverlist)
self.setFocusId(SERVERLIST)
else:
self.episodes = self.itemsResult
self.itemsResult = []
episodes = []
for item in self.episodes:
if item.action == 'findvideos':
it = xbmcgui.ListItem(item.title)
episodes.append(it)
self.Focus(EPISODES)
self.EPISODESLIST.reset()
self.EPISODESLIST.addItems(episodes)
self.setFocusId(EPISODESLIST)
busy(False)
elif control_id in [SERVERLIST]:
index = int(self.getControl(control_id).getSelectedItem().getProperty('index'))
server = self.servers[index]
server.player_mode = 0
run(server)
def Back(self):
self.getControl(QUALITYTAG).setText('')
if self.SERVERS.isVisible():
if self.episodes:
self.Focus(EPISODES)
self.setFocusId(EPISODESLIST)
else:
self.Focus(SEARCH)
self.setFocusId(RESULTS)
self.RESULTS.selectItem(self.pos)
elif self.EPISODES.isVisible():
self.episodes = []
self.Focus(SEARCH)
self.setFocusId(RESULTS)
self.RESULTS.selectItem(self.pos)
elif self.item.mode in ['person'] and self.find:
self.find = []
self.actors()
else:
self.Close()
def Close(self):
self.exit = True
if self.thread:
busy(True)
while self.thread.is_alive(): xbmc.sleep(200)
busy(False)
self.close()
def context(self):
pos = self.RESULTS.getSelectedPosition()
name = self.CHANNELS.getSelectedItem().getLabel()
item = self.results[name][0][pos]
context = [config.get_localized_string(70739), config.get_localized_string(70557), config.get_localized_string(60359)]
context_commands = ["RunPlugin(%s?%s)" % (sys.argv[0], 'action=open_browser&url=' + item.url),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=kodfavorites&action=addFavourite&from_channel=' + item.channel + '&from_action=' + item.action),
"RunPlugin(%s?%s)" % (sys.argv[0], 'channel=trailertools&action=buscartrailer&contextual=True&search_title=' + item.contentTitle if item.contentTitle else item.fulltitle)]
if item.contentType == 'movie':
context += [config.get_localized_string(60353), config.get_localized_string(60354)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'action=add_pelicula_to_library&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' +item.action)]
else:
context += [config.get_localized_string(60352), config.get_localized_string(60355), config.get_localized_string(60357)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'action=add_serie_to_library&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action),
"RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel +'&from_action=' + item.action)]
if self.EPISODES.isVisible() or self.SERVERS.isVisible():
pos = self.EPISODESLIST.getSelectedPosition()
item = self.episodes[pos]
context += [config.get_localized_string(60356)]
context_commands += ["RunPlugin(%s?%s&%s)" % (sys.argv[0], item.tourl(), 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' +item.action)]
index = xbmcgui.Dialog().contextmenu(context)
if index > 0: xbmc.executebuiltin(context_commands[index])

View File

@@ -191,7 +191,8 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.getControl(NUMBER).setText(support.typo(config.get_localized_string(70362),'uppercase bold'))
else:
it = xbmcgui.ListItem(item.infoLabels['title'])
it.setProperty('channel', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('channelname', channeltools.get_channel_parameters(item.channel).get('title',''))
it.setProperty('channel', item.channel)
it.setProperty('action', item.action)
it.setProperty('server', servertools.get_server_parameters(item.server.lower()).get('name',item.server))
it.setProperty('url', item.url)
@@ -213,7 +214,6 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.commands.append(itemlist[0].clone(channel='downloads', action='save_download', from_channel=itemlist[0].channel, from_action=itemlist[0].action, thumbnail=support.thumb('downloads')))
else:
self.commands.append(Info.clone(channel='downloads', action='save_download', from_channel=Info.channel, from_action=Info.action, thumbnail=support.thumb('downloads')))
if self.commands:
commands = []
for command in self.commands:
@@ -248,7 +248,8 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
if action == 'play':
item.server = self.getControl(RECOMANDED).getSelectedItem().getProperty('server')
self.close()
platformtools.play_video(item)
from platformcode.launcher import run
run(item)
xbmc.sleep(500)
while xbmc.Player().isPlaying():
xbmc.sleep(500)

View File

@@ -19,7 +19,7 @@ def start():
Within this function all calls should go to
functions that we want to execute as soon as we open the plugin.
"""
logger.info()
logger.debug()
# config.set_setting('show_once', True)
# Test if all the required directories are created
config.verify_directories_created()
@@ -37,7 +37,7 @@ def start():
updater.showSavedChangelog()
def run(item=None):
logger.info()
logger.debug()
if not item:
# Extract item from sys.argv
if sys.argv[2]:
@@ -94,7 +94,7 @@ def run(item=None):
# If item has no action, stops here
if item.action == "":
logger.info("Item without action")
logger.debug("Item without action")
return
# Action for main menu in channelselector
@@ -135,6 +135,12 @@ def run(item=None):
from platformcode import infoplus
return infoplus.Main(item)
elif config.get_setting('new_search') and item.channel == "search" and item.action == 'new_search':
from platformcode.globalsearch import Search
item.contextual = True
Search(item)
return
elif item.channel == "backup":
from platformcode import backup
return getattr(backup, item.action)(item)
@@ -187,7 +193,7 @@ def run(item=None):
channel_file = os.path.join(config.get_runtime_path(), CHANNELS, item.channel + ".py")
logger.info("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel)
logger.debug("channel_file= " + channel_file + ' - ' + CHANNELS + ' - ' + item.channel)
channel = None
@@ -207,12 +213,12 @@ def run(item=None):
trakt_tools.set_trakt_info(item)
except:
pass
logger.info("item.action=%s" % item.action.upper())
logger.debug("item.action=%s" % item.action.upper())
# logger.debug("item_toPlay: " + "\n" + item.tostring('\n'))
# First checks if channel has a "play" function
if hasattr(channel, 'play'):
logger.info("Executing channel 'play' method")
logger.debug("Executing channel 'play' method")
itemlist = channel.play(item)
b_favourite = item.isFavourite
# Play should return a list of playable URLS
@@ -233,7 +239,7 @@ def run(item=None):
# If player don't have a "play" function, not uses the standard play from platformtools
else:
logger.info("Executing core 'play' method")
logger.debug("Executing core 'play' method")
platformtools.play_video(item)
# Special action for findvideos, where the plugin looks for known urls
@@ -246,8 +252,7 @@ def run(item=None):
# If not, uses the generic findvideos function
else:
logger.info("No channel 'findvideos' method, "
"executing core method")
logger.debug("No channel 'findvideos' method, " "executing core method")
itemlist = servertools.find_video_items(item)
if config.get_setting("max_links", "videolibrary") != 0:
@@ -291,7 +296,7 @@ def run(item=None):
else:
filetools.remove(temp_search_file)
logger.info("item.action=%s" % item.action.upper())
logger.debug("item.action=%s" % item.action.upper())
from core import channeltools
if config.get_setting('last_search'):
@@ -312,7 +317,7 @@ def run(item=None):
# For all other actions
else:
# import web_pdb; web_pdb.set_trace()
logger.info("Executing channel '%s' method" % item.action)
logger.debug("Executing channel '%s' method" % item.action)
itemlist = getattr(channel, item.action)(item)
if config.get_setting('trakt_sync'):
from core import trakt_tools
@@ -336,13 +341,10 @@ def run(item=None):
logger.error(traceback.format_exc())
patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"'
Channel = scrapertools.find_single_match(traceback.format_exc(), patron)
platformtools.dialog_ok(
config.get_localized_string(59985) + Channel,
config.get_localized_string(60013) %(e))
except:
config.get_localized_string(59985) % e.channel,
config.get_localized_string(60013) % e.url)
except Exception as e:
import traceback
from core import scrapertools
@@ -351,26 +353,15 @@ def run(item=None):
patron = 'File "' + os.path.join(config.get_runtime_path(), "channels", "").replace("\\", "\\\\") + r'([^.]+)\.py"'
Channel = scrapertools.find_single_match(traceback.format_exc(), patron)
try:
import xbmc
if config.get_platform(True)['num_version'] < 14:
log_name = "xbmc.log"
else:
log_name = "kodi.log"
log_message = config.get_localized_string(50004) + xbmc.translatePath("special://logpath") + log_name
except:
log_message = ""
if Channel:
if Channel or e.__class__ == logger.ChannelScraperException:
if item.url:
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message, nolabel='ok', yeslabel=config.get_localized_string(70739)):
if platformtools.dialog_yesno(config.get_localized_string(60087) % Channel, config.get_localized_string(60014), nolabel='ok', yeslabel=config.get_localized_string(70739)):
run(Item(action="open_browser", url=item.url))
else:
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014) + '\n' + log_message)
platformtools.dialog_ok(config.get_localized_string(60087) % Channel, config.get_localized_string(60014))
else:
platformtools.dialog_ok(
config.get_localized_string(60038),
config.get_localized_string(60015) + '\n' + log_message)
if platformtools.dialog_yesno(config.get_localized_string(60038), config.get_localized_string(60015)):
run(Item(channel="setting", action="report_menu"))
def new_search(item, channel=None):
@@ -393,7 +384,7 @@ def set_search_temp(item):
filetools.write(temp_search_file, f)
def reorder_itemlist(itemlist):
logger.info()
logger.debug()
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
new_list = []
@@ -431,7 +422,7 @@ def reorder_itemlist(itemlist):
new_list.extend(mod_list)
new_list.extend(not_mod_list)
logger.info("Modified Titles:%i |Unmodified:%i" % (modified, not_modified))
logger.debug("Modified Titles:%i |Unmodified:%i" % (modified, not_modified))
if len(new_list) == 0:
new_list = itemlist
@@ -441,7 +432,7 @@ def reorder_itemlist(itemlist):
def limit_itemlist(itemlist):
logger.info()
logger.debug()
# logger.debug("Inlet itemlist size: %i" % len(itemlist))
try:
@@ -474,7 +465,7 @@ def play_from_library(item):
itemlist=[]
item.fromLibrary = True
logger.info()
logger.debug()
# logger.debug("item: \n" + item.tostring('\n'))
# Try to reproduce an image (this does nothing and also does not give an error)

View File

@@ -3,7 +3,7 @@
# Logger (kodi)
# --------------------------------------------------------------------------------
from __future__ import unicode_literals
import inspect, os, xbmc, sys
import inspect,os, xbmc, sys
from platformcode import config
# for test suite
@@ -53,5 +53,11 @@ def log(*args, **kwargs):
class WebErrorException(Exception):
def __init__(self, *args, **kwargs):
def __init__(self, url, channel, *args, **kwargs):
self.url = url
self.channel = channel
Exception.__init__(self, *args, **kwargs)
class ChannelScraperException(Exception):
pass

View File

@@ -178,6 +178,60 @@ def dialog_register(heading, user=False, email=False, password=False, user_defau
dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img)
return dialog
def dialog_info(item, scraper):
class TitleOrIDWindow(xbmcgui.WindowXMLDialog):
def Start(self, item, scraper):
self.item = item
self.item.exit = False
self.title = item.show if item.show else item.fulltitle
self.id = item.infoLabels.get('tmdb_id', '') if scraper == 'tmdb' else item.infoLabels.get('tvdb_id', '')
self.scraper = scraper
self.idtitle = 'TMDB ID' if scraper == 'tmdb' else 'TVDB ID'
self.doModal()
return self.item
def onInit(self):
#### Kodi 18 compatibility ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
self.HEADER = self.getControl(100)
self.TITLE = self.getControl(101)
self.ID = self.getControl(102)
self.EXIT = self.getControl(103)
self.EXIT2 = self.getControl(104)
self.HEADER.setText(config.get_localized_string(60228) % self.title)
self.TITLE.setLabel('[UPPERCASE]' + config.get_localized_string(60230).replace(':','') + '[/UPPERCASE]')
self.ID.setLabel(self.idtitle)
self.setFocusId(101)
def onClick(self, control):
if control in [101]:
result = dialog_input(self.title)
if result:
if self.item.contentType == 'movie': self.item.contentTitle = result
else: self.item.contentSerieName = result
self.close()
elif control in [102]:
result = dialog_numeric(0, self.idtitle, self.id)
if result:
if self.scraper == 'tmdb': self.item.infoLabels['tmdb_id'] = result
elif self.scraper == 'tvdb': self.item.infoLabels['tvdb_id'] = result
self.close()
elif control in [103, 104]:
self.item.exit = True
self.close()
def onAction(self, action):
action = action.getId()
if action in [92, 10]:
self.item.exit = True
self.close()
dialog = TitleOrIDWindow('TitleOrIDWindow.xml', config.get_runtime_path()).Start(item, scraper)
return dialog
def itemlist_refresh():
# pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
@@ -202,7 +256,7 @@ def render_items(itemlist, parent_item):
"""
Function used to render itemlist on kodi
"""
logger.info('START render_items')
logger.debug('START render_items')
thumb_type = config.get_setting('video_thumbnail_type')
from platformcode import shortcuts
# from core import httptools
@@ -287,7 +341,7 @@ def render_items(itemlist, parent_item):
set_view_mode(itemlist[0], parent_item)
xbmcplugin.endOfDirectory(_handle)
logger.info('END render_items')
logger.debug('END render_items')
def getCurrentView(item=None, parent_item=None):
@@ -344,11 +398,11 @@ def set_view_mode(item, parent_item):
if content:
mode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
if mode == 0:
logger.info('default mode')
logger.debug('default mode')
mode = 55
xbmcplugin.setContent(handle=int(sys.argv[1]), content=Type)
xbmc.executebuiltin('Container.SetViewMode(%s)' % mode)
logger.info('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content)
logger.debug('TYPE: ' + Type + ' - ' + 'CONTENT: ' + content)
def set_infolabels(listitem, item, player=False):
@@ -568,10 +622,10 @@ def is_playing():
def play_video(item, strm=False, force_direct=False, autoplay=False):
logger.info()
logger.debug()
logger.debug(item.tostring('\n'))
if item.channel == 'downloads':
logger.info("Play local video: %s [%s]" % (item.title, item.url))
logger.debug("Play local video: %s [%s]" % (item.title, item.url))
xlistitem = xbmcgui.ListItem(path=item.url)
xlistitem.setArt({"thumb": item.thumbnail})
set_infolabels(xlistitem, item, True)
@@ -579,18 +633,22 @@ def play_video(item, strm=False, force_direct=False, autoplay=False):
return
default_action = config.get_setting("default_action")
logger.info("default_action=%s" % default_action)
logger.debug("default_action=%s" % default_action)
# pass referer
from core import httptools
httptools.default_headers['Referer'] = item.referer
# Open the selection dialog to see the available options
opciones, video_urls, seleccion, salir = get_dialogo_opciones(item, default_action, strm, autoplay)
if salir: return
if salir: exit()
# get default option of addon configuration
seleccion = get_seleccion(default_action, opciones, seleccion, video_urls)
if seleccion < 0: return # Canceled box
if seleccion < 0: exit() # Canceled box
logger.info("selection=%d" % seleccion)
logger.info("selection=%s" % opciones[seleccion])
logger.debug("selection=%d" % seleccion)
logger.debug("selection=%s" % opciones[seleccion])
# run the available option, jdwonloader, download, favorites, add to the video library ... IF IT IS NOT PLAY
salir = set_opcion(item, seleccion, opciones, video_urls)
@@ -751,7 +809,7 @@ def alert_unsopported_server():
def handle_wait(time_to_wait, title, text):
logger.info("handle_wait(time_to_wait=%d)" % time_to_wait)
logger.debug("handle_wait(time_to_wait=%d)" % time_to_wait)
espera = dialog_progress(' ' + title, "")
secs = 0
@@ -770,15 +828,15 @@ def handle_wait(time_to_wait, title, text):
break
if cancelled:
logger.info('Wait canceled')
logger.debug('Wait canceled')
return False
else:
logger.info('Wait finished')
logger.debug('Wait finished')
return True
def get_dialogo_opciones(item, default_action, strm, autoplay):
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
from core import servertools
@@ -827,10 +885,6 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
# "Add to Favorites"
opciones.append(config.get_localized_string(30155))
if not strm and item.contentType == 'movie' and item.channel != 'videolibrary':
# "Add to video library"
opciones.append(config.get_localized_string(30161))
if default_action == 3:
seleccion = len(opciones) - 1
@@ -844,13 +898,14 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
if not autoplay:
if item.server != "":
if "<br/>" in motivo:
ret = dialog_yesno(config.get_localized_string(60362), motivo.split("<br/>")[0] + '\n' + motivo.split("<br/>")[1] + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, motivo.split("<br/>")[0] + '\n' + motivo.split("<br/>")[1], nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), motivo + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, motivo, nolabel='ok', yeslabel=config.get_localized_string(70739))
else:
ret = dialog_yesno(config.get_localized_string(60362), config.get_localized_string(60363) + '\n' + config.get_localized_string(60364) + '\n' + item.url, nolabel='ok', yeslabel=config.get_localized_string(70739))
ret = dialog_yesno(config.get_localized_string(60362) % item.server, config.get_localized_string(60363) + '\n' + config.get_localized_string(60364), nolabel='ok', yeslabel=config.get_localized_string(70739))
if ret:
xbmc.executebuiltin("Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
xbmc.executebuiltin("Container.Update (%s?%s)" %
(sys.argv[0], Item(action="open_browser", url=item.url).tourl()))
if item.channel == "favorites":
# "Remove from favorites"
opciones.append(config.get_localized_string(30154))
@@ -862,7 +917,7 @@ def get_dialogo_opciones(item, default_action, strm, autoplay):
def set_opcion(item, seleccion, opciones, video_urls):
logger.info()
logger.debug()
# logger.debug(item.tostring('\n'))
salir = False
# You have not chosen anything, most likely because you have given the ESC
@@ -912,7 +967,7 @@ def set_opcion(item, seleccion, opciones, video_urls):
def get_video_seleccionado(item, seleccion, video_urls):
logger.info()
logger.debug()
mediaurl = ""
view = False
wait_time = 0
@@ -938,7 +993,7 @@ def get_video_seleccionado(item, seleccion, video_urls):
mpd = True
# If there is no mediaurl it is because the video is not there :)
logger.info("mediaurl=" + mediaurl)
logger.debug("mediaurl=" + mediaurl)
if mediaurl == "":
if item.server == "unknown":
alert_unsopported_server()
@@ -955,7 +1010,7 @@ def get_video_seleccionado(item, seleccion, video_urls):
def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=None, item_nfo=None):
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
# Moved del conector "torrent" here
if item.server == "torrent":
@@ -969,7 +1024,10 @@ def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=No
xbmc_player.setSubtitles(item.subtitle)
else:
player_mode = config.get_setting("player_mode")
if type(item.player_mode) == int:
player_mode = item.player_mode
else:
player_mode = config.get_setting("player_mode")
if (player_mode == 3 and mediaurl.startswith("rtmp")) or item.play_from == 'window' or item.nfo: player_mode = 0
elif "megacrypter.com" in mediaurl: player_mode = 3
logger.info("mediaurl=" + mediaurl)
@@ -989,9 +1047,10 @@ def set_player(item, xlistitem, mediaurl, view, strm, nfo_path=None, head_nfo=No
elif player_mode == 1:
logger.info('Player Mode: setResolvedUrl')
xlistitem.setPath(mediaurl)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem)
xbmc.sleep(2500)
# xlistitem.setPath(mediaurl)
par = int(sys.argv[1])
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=mediaurl))
# xbmc.sleep(2500)
elif player_mode == 2:
logger.info('Player Mode: Built-In')
@@ -1038,7 +1097,7 @@ def torrent_client_installed(show_tuple=False):
def play_torrent(item, xlistitem, mediaurl):
logger.info()
logger.debug()
import time
from servers import torrent
@@ -1074,7 +1133,7 @@ def play_torrent(item, xlistitem, mediaurl):
torrent.mark_auto_as_watched(item)
while is_playing() and not xbmc.abortRequested:
while is_playing() and not xbmc.Monitor().abortRequested():
time.sleep(3)

View File

@@ -65,7 +65,7 @@ class Recaptcha(xbmcgui.WindowXMLDialog):
data = httptools.downloadpage(self.url, post=post, headers=self.headers).data
from platformcode import logger
logger.info(data)
logger.debug(data)
self.result = scrapertools.find_single_match(data, '<div class="fbc-verification-token">.*?>([^<]+)<')
if self.result:
platformtools.dialog_notification("Captcha corretto", "Verifica conclusa")

View File

@@ -126,7 +126,7 @@ def SettingOnPosition(item):
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.kod)')
category = item.category if item.category else 0
setting = item.setting if item.setting else 0
logger.info('SETTING= ' + str(setting))
logger.debug('SETTING= ' + str(setting))
xbmc.executebuiltin('SetFocus(%i)' % (category - 100))
xbmc.executebuiltin('SetFocus(%i)' % (setting - 80))

View File

@@ -43,7 +43,7 @@ def set_menu_settings(item):
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def check_user_home(item):
logger.info()
logger.debug()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
if 'user_home' in menu_node:
@@ -55,7 +55,7 @@ def check_user_home(item):
return item
def set_custom_start(item):
logger.info()
logger.debug()
if os.path.exists(menu_settings_path):
menu_node = jsontools.get_node_from_file('menu_settings_data.json', 'menu')
else:
@@ -69,7 +69,7 @@ def set_custom_start(item):
jsontools.update_node(menu_node, 'menu_settings_data.json', "menu")
def get_start_page():
logger.info()
logger.debug()
dictCategory = {
config.get_localized_string(70137): 'peliculas',
@@ -355,7 +355,7 @@ class Main(xbmcgui.WindowXMLDialog):
self.focus -= 1
def run_action(self, item):
logger.info()
logger.debug()
if item.menu != True:
self.close()
xbmc.executebuiltin("Container.update(%s)"%launcher.run(item))

View File

@@ -84,7 +84,7 @@ def regex_tvshow(compare, file, sub=""):
def set_Subtitle():
logger.info()
logger.debug()
exts = [".srt", ".sub", ".txt", ".smi", ".ssa", ".ass"]
subtitle_folder_path = filetools.join(config.get_data_path(), "subtitles")
@@ -216,7 +216,7 @@ def searchSubtitle(item):
filetools.mkdir(full_path_tvshow) # title_new + ".mp4"
full_path_video_new = xbmc.translatePath(
filetools.join(full_path_tvshow, "%s %sx%s.mp4" % (tvshow_title, season, episode)))
logger.info(full_path_video_new)
logger.debug(full_path_video_new)
listitem = xbmcgui.ListItem(title_new, iconImage="DefaultVideo.png", thumbnailImage="")
listitem.setInfo("video", {"Title": title_new, "Genre": "Tv shows", "episode": int(episode), "season": int(season), "tvshowtitle": tvshow_title})
@@ -230,7 +230,7 @@ def searchSubtitle(item):
try:
filetools.copy(path_video_temp, full_path_video_new)
copy = True
logger.info("nuevo path =" + full_path_video_new)
logger.debug("nuevo path =" + full_path_video_new)
time.sleep(2)
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.clear()
@@ -288,7 +288,7 @@ def get_from_subdivx(sub_url):
:return: The path to the unzipped subtitle
"""
logger.info()
logger.debug()
sub = ''
sub_dir = os.path.join(config.get_data_path(), 'temp_subs')
@@ -312,9 +312,9 @@ def get_from_subdivx(sub_url):
filetools.write(filename, data_dl)
sub = extract_file_online(sub_dir, filename)
except:
logger.info('sub invalid')
logger.debug('sub invalid')
else:
logger.info('sub invalid')
logger.debug('sub invalid')
return sub
@@ -328,7 +328,7 @@ def extract_file_online(path, filename):
:return:
"""
logger.info()
logger.debug()
url = "http://online.b1.org/rest/online/upload"

View File

@@ -1,14 +1,21 @@
# -*- coding: utf-8 -*-
import xbmcgui
import xbmcgui, sys
from core.tmdb import Tmdb
from platformcode import config, logger
from core import filetools
if sys.version_info[0] >= 3:
from concurrent import futures
else:
from concurrent_py2 import futures
BACKGROUND = 30000
LOADING = 30001
SELECT = 30002
CLOSE = 30003
EXIT = 10
BACKSPACE = 92
def imagepath(image):
if len(image.split('.')) == 1: image += '.png'
@@ -25,23 +32,30 @@ class InfoWindow(xbmcgui.WindowXMLDialog):
self.scraper = scraper
self.doModal()
logger.info('RESPONSE',self.response)
logger.debug('RESPONSE',self.response)
return self.response
def make_items(self, i, result):
infoLabels = self.scraper().get_infoLabels(origen=result)
it = xbmcgui.ListItem(infoLabels['title'])
it.setProperty('fanart', infoLabels.get('fanart', ''))
it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv')))
it.setProperty('genre', infoLabels.get('genre', 'N/A'))
it.setProperty('rating', str(infoLabels.get('rating', 'N/A')))
it.setProperty('plot', str(infoLabels.get('plot', '')))
it.setProperty('year', str(infoLabels.get('year', '')))
it.setProperty('position', str(i))
return it
def onInit(self):
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
for result in self.results:
infoLabels = self.scraper().get_infoLabels(origen=result)
it = xbmcgui.ListItem(infoLabels['title'])
it.setProperty('fanart', infoLabels.get('fanart', ''))
it.setProperty('thumbnail', infoLabels.get('thumbnail', imagepath('movie' if infoLabels['mediatype'] == 'movie' else 'tv')))
it.setProperty('genre', infoLabels.get('genre', 'N/A'))
it.setProperty('rating', str(infoLabels.get('rating', 'N/A')))
it.setProperty('plot', str(infoLabels.get('plot', '')))
it.setProperty('year', str(infoLabels.get('year', '')))
self.items.append(it)
with futures.ThreadPoolExecutor() as executor:
for i, result in enumerate(self.results):
logger.debug(result)
if ('seriesName' in result and result['seriesName']) or ('name' in result and result['name']) or ('title' in result and result['title']):
self.items += [executor.submit(self.make_items, i, result).result()]
self.items.sort(key=lambda it: int(it.getProperty('position')))
self.getControl(SELECT).addItems(self.items)
self.getControl(BACKGROUND).setImage(self.items[0].getProperty('fanart'))
@@ -51,5 +65,16 @@ class InfoWindow(xbmcgui.WindowXMLDialog):
def onClick(self, control_id):
if control_id == SELECT:
self.response = self.results[self.getControl(SELECT).getSelectedPosition()]
self.close()
self.close()
elif control_id == CLOSE:
self.close()
def onAction(self, action):
if self.getFocusId() in [SELECT]:
fanart = self.getControl(self.getFocusId()).getSelectedItem().getProperty('fanart')
self.getControl(BACKGROUND).setImage(fanart)
if action in [BACKSPACE]:
self.close()
elif action in [EXIT]:
self.close()

View File

@@ -22,7 +22,7 @@ from xml.dom import minidom
def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
def mark_as_watched_subThread(item, nfo_path, head_nfo, item_nfo):
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
time_limit = time.time() + 30
@@ -53,7 +53,7 @@ def mark_auto_as_watched(item, nfo_path=None, head_nfo=None, item_nfo=None):
# Mark as Watched
if actual_time > mark_time and not marked:
logger.debug("Marked as Watched")
logger.info("Marked as Watched")
item.playcount = 1
marked = True
show_server = False
@@ -104,7 +104,7 @@ def sync_trakt_addon(path_folder):
"""
Updates the values of episodes seen if
"""
logger.info()
logger.debug()
# if the addon exists we do the search
if xbmc.getCondVisibility('System.HasAddon("script.trakt")'):
# we import dependencies
@@ -230,7 +230,7 @@ def sync_trakt_kodi(silent=True):
notificacion = False
xbmc.executebuiltin('RunScript(script.trakt,action=sync,silent=%s)' % silent)
logger.info("Synchronization with Trakt started")
logger.debug("Synchronization with Trakt started")
if notificacion:
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(60045), sound=False, time=2000)
@@ -244,7 +244,7 @@ def mark_content_as_watched_on_kodi(item, value=1):
@type value: int
@param value: > 0 for seen, 0 for not seen
"""
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
payload_f = ''
@@ -316,7 +316,7 @@ def mark_season_as_watched_on_kodi(item, value=1):
@type value: int
@param value: > 0 for seen, 0 for not seen
"""
logger.info()
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
# We can only mark the season as seen in the Kodi database if the database is local, in case of sharing database this functionality will not work
@@ -350,7 +350,7 @@ def mark_content_as_watched_on_kod(path):
@type str: path
@param path: content folder to mark
"""
logger.info()
logger.debug()
#logger.debug("path: " + path)
FOLDER_MOVIES = config.get_setting("folder_movies")
@@ -443,7 +443,7 @@ def get_data(payload):
import urllib.request as urllib
except ImportError:
import urllib
logger.info("payload: %s" % payload)
logger.debug("payload: %s" % payload)
# Required header for XBMC JSON-RPC calls, otherwise you'll get a 415 HTTP response code - Unsupported media type
headers = {'content-type': 'application/json'}
@@ -460,7 +460,7 @@ def get_data(payload):
response = f.read()
f.close()
logger.info("get_data: response %s" % response)
logger.debug("get_data: response %s" % response)
data = jsontools.load(response)
except Exception as ex:
template = "An exception of type %s occured. Arguments:\n%r"
@@ -476,7 +476,7 @@ def get_data(payload):
logger.error("error en xbmc.executeJSONRPC: %s" % message)
data = ["error"]
logger.info("data: %s" % data)
logger.debug("data: %s" % data)
return data
@@ -490,7 +490,7 @@ def update(folder_content=config.get_setting("folder_tvshows"), folder=""):
@type folder: str
@param folder: name of the folder to scan.
"""
logger.info(folder)
logger.debug(folder)
payload = {
"jsonrpc": "2.0",
@@ -554,7 +554,7 @@ def set_content(content_type, silent=False, custom=False):
@type content_type: str ('movie' o 'tvshow')
@param content_type: content type to configure, series or movies
"""
logger.info()
logger.debug()
continuar = True
msg_text = ""
videolibrarypath = config.get_setting("videolibrarypath")
@@ -580,7 +580,7 @@ def set_content(content_type, silent=False, custom=False):
try:
# Install metadata.themoviedb.org
xbmc.executebuiltin('InstallAddon(metadata.themoviedb.org)', True)
logger.info("Instalado el Scraper de películas de TheMovieDB")
logger.debug("Instalado el Scraper de películas de TheMovieDB")
except:
pass
@@ -634,7 +634,7 @@ def set_content(content_type, silent=False, custom=False):
try:
# Install metadata.tvdb.com
xbmc.executebuiltin('InstallAddon(metadata.tvdb.com)', True)
logger.info("The TVDB series Scraper installed ")
logger.debug("The TVDB series Scraper installed ")
except:
pass
@@ -729,7 +729,7 @@ def set_content(content_type, silent=False, custom=False):
strScraper = 'metadata.universal'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.universal/settings.xml")
if not os.path.exists(path_settings):
logger.info("%s: %s" % (content_type, path_settings + " doesn't exist"))
logger.debug("%s: %s" % (content_type, path_settings + " doesn't exist"))
return continuar
settings_data = filetools.read(path_settings)
strSettings = ' '.join(settings_data.split()).replace("> <", "><")
@@ -748,7 +748,7 @@ def set_content(content_type, silent=False, custom=False):
strScraper = 'metadata.tvshows.themoviedb.org'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml")
if not os.path.exists(path_settings):
logger.info("%s: %s" % (content_type, path_settings + " doesn't exist"))
logger.debug("%s: %s" % (content_type, path_settings + " doesn't exist"))
return continuar
settings_data = filetools.read(path_settings)
strSettings = ' '.join(settings_data.split()).replace("> <", "><")
@@ -758,7 +758,7 @@ def set_content(content_type, silent=False, custom=False):
videolibrarypath += sep
strPath = videolibrarypath + config.get_setting("folder_tvshows") + sep
logger.info("%s: %s" % (content_type, strPath))
logger.debug("%s: %s" % (content_type, strPath))
# We check if strPath already exists in the DB to avoid duplicates
sql = 'SELECT idPath FROM path where strPath="%s"' % strPath
nun_records, records = execute_sql_kodi(sql)
@@ -800,15 +800,15 @@ def set_content(content_type, silent=False, custom=False):
heading = config.get_localized_string(70103) % content_type
msg_text = config.get_localized_string(70104)
logger.info("%s: %s" % (heading, msg_text))
logger.debug("%s: %s" % (heading, msg_text))
return continuar
def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvshows_folder, new_tvshows_folder, progress):
def path_replace(path, old, new):
logger.info()
logger.info('path: ' + path + ', old: ' + old + ', new: ' + new)
logger.debug()
logger.debug('path: ' + path + ', old: ' + old + ', new: ' + new)
if new.startswith("special://") or '://' in new: sep = '/'
else: sep = os.sep
@@ -819,7 +819,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
return path
logger.info()
logger.debug()
sql_old_path = old_path
if sql_old_path.startswith("special://"):
@@ -831,10 +831,10 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
if not sql_old_path.endswith(sep):
sql_old_path += sep
logger.info('sql_old_path: ' + sql_old_path)
logger.debug('sql_old_path: ' + sql_old_path)
# search MAIN path in the DB
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# change main path
@@ -842,7 +842,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = records[0][0]
strPath = path_replace(records[0][1], old_path, new_path)
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
else:
progress.update(100)
@@ -859,7 +859,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
# Search Main Sub Folder
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# Change Main Sub Folder
@@ -868,13 +868,13 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# Search if Sub Folder exixt in all paths
sql_old_folder += '%'
sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
#Change Sub Folder in all paths
@@ -883,7 +883,7 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
idPath = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE path SET strPath="%s" WHERE idPath=%s' % (strPath, idPath)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
@@ -891,27 +891,27 @@ def update_db(old_path, new_path, old_movies_folder, new_movies_folder, old_tvsh
# if is Movie Folder
# search and modify in "movie"
sql = 'SELECT idMovie, c22 FROM movie where c22 LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
for record in records:
idMovie = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE movie SET c22="%s" WHERE idMovie=%s' % (strPath, idMovie)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
else:
# if is TV Show Folder
# search and modify in "episode"
sql = 'SELECT idEpisode, c18 FROM episode where c18 LIKE "%s"' % sql_old_folder
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
for record in records:
idEpisode = record[0]
strPath = path_replace(record[1], filetools.join(old_path, OldFolder), filetools.join(new_path, NewFolder))
sql = 'UPDATE episode SET c18="%s" WHERE idEpisode=%s' % (strPath, idEpisode)
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
p += 5
progress.update(p, config.get_localized_string(20000) + '\n' + config.get_localized_string(80013))
@@ -936,26 +936,26 @@ def clean(path_list=[]):
return path, sep
logger.info()
logger.debug()
progress = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(80025))
progress.update(0)
# if the path list is empty, clean the entire video library
if not path_list:
logger.info('the path list is empty, clean the entire video library')
logger.debug('the path list is empty, clean the entire video library')
if not config.get_setting("videolibrary_kodi"):
sql_path, sep = sql_format(config.get_setting("videolibrarypath"))
if not sql_path.endswith(sep): sql_path += sep
sql = 'SELECT idPath FROM path where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
idPath = records[0][0]
sql = 'DELETE from path WHERE idPath=%s' % idPath
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
sql = 'DELETE from path WHERE idParentPath=%s' % idPath
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
from core import videolibrarytools
@@ -969,7 +969,7 @@ def clean(path_list=[]):
if filetools.exists(tvshow_nfo):
path_list.append(filetools.join(config.get_setting("videolibrarypath"), videolibrarytools.FOLDER_TVSHOWS, folder))
logger.info('path_list: ' + str(path_list))
logger.debug('path_list: ' + str(path_list))
if path_list: t = float(100) / len(path_list)
for i, path in enumerate(path_list):
progress.update(int(math.ceil((i + 1) * t)))
@@ -979,13 +979,13 @@ def clean(path_list=[]):
sql_path, sep = sql_format(path)
if filetools.isdir(path) and not sql_path.endswith(sep): sql_path += sep
logger.info('path: ' + path)
logger.info('sql_path: ' + sql_path)
logger.debug('path: ' + path)
logger.debug('sql_path: ' + sql_path)
if filetools.isdir(path):
# search movie in the DB
sql = 'SELECT idMovie FROM movie where c22 LIKE "%s"' % (sql_path + '%')
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete movie
if records:
@@ -994,7 +994,7 @@ def clean(path_list=[]):
continue
# search TV show in the DB
sql = 'SELECT idShow FROM tvshow_view where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete TV show
if records:
@@ -1003,7 +1003,7 @@ def clean(path_list=[]):
elif config.get_setting("folder_movies") in sql_path:
# search movie in the DB
sql = 'SELECT idMovie FROM movie where c22 LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete movie
if records:
@@ -1012,7 +1012,7 @@ def clean(path_list=[]):
else:
# search episode in the DB
sql = 'SELECT idEpisode FROM episode where c18 LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
# delete episode
if records:
@@ -1031,7 +1031,7 @@ def check_db(path):
ret = False
sql_path = '%' + sep + path.split(sep)[-1] + sep + '%'
sql = 'SELECT idShow FROM tvshow_view where strPath LIKE "%s"' % sql_path
logger.info('sql: ' + sql)
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
ret = True
@@ -1048,7 +1048,7 @@ def execute_sql_kodi(sql):
@return: list with the query result
@rtype records: list of tuples
"""
logger.info()
logger.debug()
file_db = ""
nun_records = 0
records = None
@@ -1069,14 +1069,14 @@ def execute_sql_kodi(sql):
break
if file_db:
logger.info("DB file: %s" % file_db)
logger.debug("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.info("Running sql: %s" % sql)
logger.debug("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
@@ -1090,7 +1090,7 @@ def execute_sql_kodi(sql):
nun_records = conn.total_changes
conn.close()
logger.info("Query executed. Records: %s" % nun_records)
logger.debug("Query executed. Records: %s" % nun_records)
except:
logger.error("Error executing sql query")
@@ -1110,7 +1110,7 @@ def check_sources(new_movies_path='', new_tvshows_path=''):
if not path.endswith(sep): path += sep
return path
logger.info()
logger.debug()
new_movies_path = format_path(new_movies_path)
new_tvshows_path = format_path(new_tvshows_path)
@@ -1140,7 +1140,7 @@ def check_sources(new_movies_path='', new_tvshows_path=''):
def update_sources(new='', old=''):
logger.info()
logger.debug()
if new == old: return
SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml")
@@ -1182,9 +1182,9 @@ def update_sources(new='', old=''):
# create new path
list_path = [p.firstChild.data for p in paths_node]
if new in list_path:
logger.info("The path %s already exists in sources.xml" % new)
logger.debug("The path %s already exists in sources.xml" % new)
return
logger.info("The path %s does not exist in sources.xml" % new)
logger.debug("The path %s does not exist in sources.xml" % new)
# if the path does not exist we create one
source_node = xmldoc.createElement("source")
@@ -1223,7 +1223,7 @@ def update_sources(new='', old=''):
def ask_set_content(silent=False):
logger.info()
logger.debug()
logger.debug("videolibrary_kodi %s" % config.get_setting("videolibrary_kodi"))
def do_config(custom=False):
@@ -1280,7 +1280,7 @@ def ask_set_content(silent=False):
def next_ep(item):
from core.item import Item
logger.info()
logger.debug()
item.next_ep = False
# check if next file exist
@@ -1296,7 +1296,7 @@ def next_ep(item):
nextIndex = fileList.index(current_filename) + 1
if nextIndex == 0 or nextIndex == len(fileList): next_file = None
else: next_file = fileList[nextIndex]
logger.info('Next File:' + str(next_file))
logger.debug('Next File:' + str(next_file))
# start next episode window afther x time
if next_file: