- rimosso supporto a TVDB (l'accesso alle API diventerà a pagamento)
- aggiunto canale Discovery+
- aggiunta possibilità di scegliere numerazioni alternative per le serie tv
- migliorie interne di vario tipo (tra cui un migliore riconoscimento dei contenuti nel caso siano scritti male)
This commit is contained in:
mac12m99
2021-02-13 16:37:02 +01:00
parent 0ebc744115
commit 748fad7431
64 changed files with 2203 additions and 712 deletions

View File

@@ -5,23 +5,22 @@
import xbmc, xbmcgui, re, base64, inspect, sys
from core import jsontools, tvdb, scrapertools, filetools
from core import jsontools, tmdb, scrapertools, filetools
from core.item import Item
from core.support import typo, match, dbg, Item
from platformcode import config, platformtools, logger
PY3 = True if sys.version_info[0] >= 3 else False
# Json Var
TVSHOW_RENUMERATE = "TVSHOW_AUTORENUMBER"
ID = "ID"
SEASON = "Season"
EPISODE = "Episode"
SPECIAL = "Special"
MODE = "Mode"
EPLIST = "EpList"
CHECK = "ReCheck"
SPLIST = "SpList"
TYPE = "Type"
RENUMBER = 'TVSHOW_AUTORENUMBER'
ID = 'id'
SEASONSDICT = 'seasons'
SEASON = 'season'
EPISODE = 'episode'
EPISODES = 'episodes'
SPECIALEPISODES = 'specials'
MANUALMODE = 'manual'
GROUP = 'info'
# helper Functions
def check(item):
@@ -41,21 +40,15 @@ def filename(item):
def load(item):
logger.debug()
try:
json_file = open(filename(item), "r").read()
json = jsontools.load(json_file)[TVSHOW_RENUMERATE]
except:
json = {}
try: json = jsontools.load(open(filename(item), "r").read())[RENUMBER]
except: json = {}
return json
def write(item, json):
logger.debug()
json_file = open(filename(item), "r").read()
js = jsontools.load(json_file)
js[TVSHOW_RENUMERATE] = json
js = jsontools.load(open(filename(item), "r").read())
js[RENUMBER] = json
with open(filename(item), "w") as file:
file.write(jsontools.dump(js))
file.close()
@@ -69,15 +62,6 @@ def b64(json, mode = 'encode'):
ret = jsontools.load(base64.b64decode(json))
return ret
def RepresentsInt(s):
# Controllo Numro Stagione
logger.debug()
try:
int(s)
return True
except ValueError:
return False
def find_episodes(item):
logger.debug()
ch = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel])
@@ -88,6 +72,15 @@ def busy(state):
if state: xbmc.executebuiltin('ActivateWindow(busydialognocancel)')
else: xbmc.executebuiltin('Dialog.Close(busydialognocancel)')
def RepresentsInt(s):
# Controllo Numro Stagione
logger.debug()
try:
int(s)
return True
except ValueError:
return False
# Main
def start(itemlist, item=None):
if not itemlist: return
@@ -106,48 +99,44 @@ class autorenumber():
def __init__(self, itemlist, item=None):
self.item = item
self.itemlist = itemlist
self.renumberdict = load(self.itemlist[0]) if self.itemlist else load(item) if item else {}
self.selectspecials = False
self.manual = False
self.auto = False
self.dictSeries = load(self.itemlist[0]) if self.itemlist else load(item) if item else {}
self.Episodes = {}
self.sp = False
if self.item:
self.auto = config.get_setting('autorenumber', item.channel)
self.title = self.item.fulltitle.strip()
if match(self.itemlist[0].title, patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
item.exit = True
return
elif self.item.channel in self.item.channel_prefs and TVSHOW_RENUMERATE in self.item.channel_prefs[item.channel] and self.title not in self.dictSeries:
elif self.item.channel in self.item.channel_prefs and RENUMBER in self.item.channel_prefs[item.channel] and self.title not in self.renumberdict:
from core.videolibrarytools import check_renumber_options
from specials.videolibrary import update_videolibrary
check_renumber_options(self.item)
update_videolibrary(self.item)
if self.title in self.dictSeries and ID in self.dictSeries[self.title] and self.dictSeries[self.title][ID] != '0':
self.id = self.dictSeries[self.title][ID]
self.Episodes = b64(self.dictSeries[self.title][EPISODE], 'decode') if EPISODE in self.dictSeries[self.title] else {}
self.Season = self.dictSeries[self.title][SEASON]
self.Mode = self.dictSeries[self.title].get(MODE, False)
self.Type = self.dictSeries[self.title].get(TYPE, False)
if self.item.renumber:
self.config()
else:
self.renumber()
self.series = self.renumberdict.get(self.title,{})
self.id = self.series.get(ID, 0)
self.episodes = self.series.get(EPISODES,{})
self.seasonsdict = self.series.get(SEASONSDICT,{})
self.season = self.series.get(SEASON, -1)
self.episode = self.series.get(EPISODE, -1)
self.manual = self.series.get(MANUALMODE, False)
self.specials = self.series.get(SPECIALEPISODES, {})
if self.id and self.episodes and self.season >= 0 and self.episode >= 0:
if self.item.renumber: self.config()
else:self.renumber()
elif self.auto or self.item.renumber:
self.Episodes = {}
self.episodes = {}
self.config()
else:
for item in self.itemlist:
item.context = [{"title": typo(config.get_localized_string(70585), 'bold'),
"action": "start",
"channel": "autorenumber",
"from_channel": item.channel,
"from_action": item.action}]
"action": "start",
"channel": "autorenumber",
"from_channel": item.channel,
"from_action": item.action}]
def config(self):
self.id = ''
if self.title in self.dictSeries:
self.id = self.dictSeries[self.title].get(ID,'')
# Pulizia del Titolo
if any( word in self.title.lower() for word in ['specials', 'speciali']):
self.title = re.sub(r'\s*specials|\s*speciali', '', self.title.lower())
@@ -155,184 +144,149 @@ class autorenumber():
self.item.contentSerieName = self.title.rstrip('123456789 ')
while not self.item.exit:
tvdb.find_and_set_infoLabels(self.item)
if self.item.infoLabels['tvdb_id']: self.item.exit = True
else: self.item = platformtools.dialog_info(self.item, 'tvdb')
self.item.infoLabels['tmdb_id'] = ''
self.item.infoLabels['year'] = '-'
self.item.contentType ='tvshow'
tmdb.find_and_set_infoLabels(self.item)
if self.item.infoLabels['tmdb_id']: self.item.exit = True
else: self.item = platformtools.dialog_info(self.item, 'tmdb')
# Rinumerazione Automatica
if (not self.id and self.auto) or self.item.renumber:
self.id = self.item.infoLabels['tvdb_id'] if 'tvdb_id' in self.item.infoLabels else ''
self.id = self.item.infoLabels['tmdb_id'] if 'tmdb_id' in self.item.infoLabels else 0
if self.id:
self.dictRenumber = {ID: self.id}
self.dictSeries[self.title] = self.dictRenumber
if any(word in self.title.lower() for word in ['specials', 'speciali']): season = '0'
elif RepresentsInt(self.title.split()[-1]): season = self.title.split()[-1]
else: season = '1'
self.Season = self.dictRenumber[SEASON] = season
self.series = {ID: self.id}
self.renumberdict[self.title] = self.series
if any(word in self.title.lower() for word in ['specials', 'speciali']): season = 0
elif RepresentsInt(self.title.split()[-1]): season = int(self.title.split()[-1])
else: season = 1
self.season = self.series[SEASON] = season
self.episode = 1
self.renumber()
def renumber(self):
if not self.item.renumber and self.itemlist:
if '|' in self.Season:
season = int(self.Season.split('|')[0])
addNumber = int(self.Season.split('|')[-1]) - 1
else:
season = int(self.Season)
addNumber = 0
for item in self.itemlist:
if not match(item.title, patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
number = match(item.title, patron=r'(\d+)').match.lstrip('0')
if number:
if number in self.Episodes:
if season > 0: item.title = typo(self.Episodes[number] + ' - ', 'bold') + item.title
else: item.title = typo('0x%s - ' % str(int(number) + addNumber), 'bold') + item.title
else:
self.makelist()
if season > 0: item.title = typo(self.Episodes[number] + ' - ', 'bold') + item.title
else: item.title = typo('0x%s - ' % str(int(number) + addNumber), 'bold') + item.title
if not number in self.episodes: self.makelist()
item.title = '{} - {}'.format(typo(self.episodes[number], 'bold'), item.title)
else:
self.makelist()
def makelist(self):
FirstOfSeason= 0
self.EpList = b64(self.dictSeries[self.title][EPLIST], 'decode') if EPLIST in self.dictSeries[self.title] else []
self.Pages = self.dictSeries[self.title].get(CHECK, [1])
self.Mode = self.dictSeries[self.title].get(MODE, False)
self.Type = self.dictSeries[self.title].get(TYPE, False)
Specials = {}
Seasons = {}
if '|' in self.Season:
ep = int(self.Season.split('|')[-1])
Season = int(self.Season.split('|')[0])
else:
Season = int(self.Season)
ep = 1
self.epdict = {}
self.group = self.renumberdict[self.title].get(GROUP, None)
busy(True)
itemlist = find_episodes(self.item)
busy(False)
if self.item.renumber:
self.s = Season
self.e = 1
Season, Episode, self.Mode, Specials, Seasons, Exit = SelectreNumeration(self, itemlist)
if Exit: return
if ep != 1: self.Season = '%s|%s' % (Season, Episode)
else: self.Season = str(Season)
elif self.Episodes and not self.Mode:
self.s = Season
self.e = ep
self.sp = True
Season, Episode, self.Mode, Specials, Seasons, Exit = SelectreNumeration(self, itemlist)
if self.Mode:
if not Seasons:
self.s = 1
self.e = 1
Season, Episode, self.Mode, Specials, Seasons, Exit = SelectreNumeration(self, itemlist, True)
self.Episodes = Seasons
if self.item.renumber or self.manual:
self.item.renumber = False
self.season, self.episode, self.manual, self.specials, Manual, Exit = SelectreNumeration(self, itemlist)
if Exit:
self.item.exit = True
return
if self.manual:
self.episodes = Manual
else:
# Ricava Informazioni da TVDB
checkpages = []
exist = True
Page = self.Pages[-1]
Episode = ep
if self.group:
Id = self.group.split('/')[-1]
else:
Id = None
groups = tmdb.get_groups(self.item)
if groups:
Id = tmdb.select_group(groups)
if Id:
self.group = 'https://www.themoviedb.org/tv/{}/episode_group/{}'.format(self.item.infoLabels['tmdb_id'], Id)
seasons = []
groupedSeasons = tmdb.get_group(Id)
for groupedSeason in groupedSeasons:
seasons.append({'season_number':groupedSeason['order'], 'episode_count':len(groupedSeason['episodes'])})
else:
seasons = tmdb.Tmdb(id_Tmdb=self.id).get_list_episodes()
count = 0
for season in seasons:
s = season['season_number']
c = season['episode_count']
self.seasonsdict[str(s)] = c
if s > 0:
for e in range(1, c + 1):
count += 1
self.epdict[count] = '{}x{:02d}'.format(s,e)
firstep = 0
if self.season > 1:
for c in range(1, self.season):
firstep += self.seasonsdict[str(c)]
firstep += self.episode - 1
count = 0
if self.epdict:
for item in itemlist:
if not match(re.sub(r'\[[^\]]+\]','',item.title), patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
# Otiene Numerazione Episodi
scraped_ep = match(re.sub(r'\[[^\]]+\]','',item.title), patron=r'(\d+)').match
if scraped_ep:
episode = int(scraped_ep)
if episode == 0:
self.episodes[str(episode)] = '0x01'
elif str(episode) in self.specials:
self.episodes[str(episode)] = self.specials[str(episode)]
count += 1
elif episode - count + firstep in self.epdict:
self.episodes[str(episode)] = self.epdict[episode - count + firstep]
else:
self.episodes[str(episode)] = '0x{:02d}'.format(count + 1)
count += 1
if self.episodes: self.renumberdict[self.title][EPISODES] = self.episodes
if self.group: self.renumberdict[self.title][GROUP] = self.group
self.renumberdict[self.title][MANUALMODE] = self.manual
self.renumberdict[self.title][SEASON] = self.season
self.renumberdict[self.title][EPISODE] = self.episode
self.renumberdict[self.title][SPECIALEPISODES] = self.specials
self.renumberdict[self.title][SEASONSDICT] = self.seasonsdict
write(self.item, self.renumberdict)
# if self.auto: self.renumber()
while exist:
data = tvdb.Tvdb(tvdb_id=self.id).get_list_episodes(self.id, Page)
if data:
for episode in data['data']:
if episode['firstAired'] and [episode['firstAired'], episode['airedSeason'], episode['airedEpisodeNumber']] not in self.EpList:
self.EpList.append([episode['firstAired'], episode['airedSeason'], episode['airedEpisodeNumber']])
Page += 1
else:
if Page not in checkpages:
checkpages.append(Page -1)
exist = False
self.Pages = [checkpages[-1]]
self.EpList.sort()
# Crea Dizionari per la Rinumerazione
if self.EpList:
self.specials = []
self.regular = {}
self.complete = {}
allep = 1
specialep = 0
for episode in self.EpList:
self.complete[allep] = [str(episode[1]) + 'x' + str(episode[2]), episode[0]]
if episode[1] == 0:
self.specials.append(allep)
specialep = specialep + 1
else:
self.regular[ep] = [str(episode[1]) + 'x' + str(episode[2]), str(episode[0]), allep - 1]
ep = ep + 1
allep = allep + 1
if Season > 1:
for numbers, data in self.regular.items():
if data[0] == str(Season) + 'x1':
FirstOfSeason = numbers - 1
else: FirstOfSeason = Episode - 1
addiction = 0
for item in itemlist:
if not match(re.sub(r'\[[^\]]+\]','',item.title), patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
# Otiene Numerazione Episodi
scraped_ep = match(re.sub(r'\[[^\]]+\]','',item.title), patron=r'(\d+)').match
if scraped_ep:
episode = int(scraped_ep)
number = episode + FirstOfSeason - addiction
if episode == 0:
self.Episodes[str(episode)] = str(self.complete[self.regular[FirstOfSeason+1][2]][0])
elif episode in Specials:
self.Episodes[str(episode)] = Specials[episode]
addiction += 1
elif number <= len(self.regular) and number in self.regular:
self.Episodes[str(episode)] = str(self.regular[number][0])
else:
try: self.Episodes[str(episode)] = str(self.complete[self.regular[number+2][2]][0])
except: self.Episodes[str(episode)] = '0x0'
if self.Episodes: self.dictSeries[self.title][EPISODE] = b64(jsontools.dump(self.Episodes))
self.dictSeries[self.title][EPLIST] = b64(jsontools.dump(self.EpList))
self.dictSeries[self.title][MODE] = self.Mode
self.dictSeries[self.title][SEASON] = self.Season
self.dictSeries[self.title][CHECK] = self.Pages
write(self.item, self.dictSeries)
if self.auto: self.renumber()
def SelectreNumeration(opt, itemlist, manual=False):
class SelectreNumerationWindow(xbmcgui.WindowXMLDialog):
def start(self, opt):
self.episodes = opt.Episodes if opt.Episodes else {}
self.dictSeries = opt.dictSeries
self.episodes = opt.episodes if opt.episodes else {}
self.renumberdict = opt.renumberdict
self.item = opt.item
self.title = opt.title
self.season = opt.s
self.episode = opt.e
self.mode = opt.Mode
self.sp = opt.sp
self.season = opt.season
self.episode = opt.episode
self.manual = opt.manual
self.sp = opt.selectspecials
self.manual = opt.manual
self.offset = 0
self.Exit = False
self.itemlist = opt.itemlist
self.count = 1
self.specials = {}
self.specials = opt.specials
self.items = []
self.selected = []
self.seasons = {}
self.seasonsdict = opt.seasonsdict
self.doModal()
return self.season, self.episode, self.mode, self.specials, self.seasons, self.Exit
return self.season, self.episode, self.manual, self.specials, self.seasons, self.Exit
def onInit(self):
# Compatibility with Kodi 18
@@ -349,7 +303,7 @@ def SelectreNumeration(opt, itemlist, manual=False):
if fanart: self.getControl(MBACKGROUND).setImage(fanart)
self.getControl(INFO).setLabel(typo(config.get_localized_string(70822) + self.title, 'bold'))
self.mode = True
self.manual = True
se = '1'
ep = '1'
@@ -434,17 +388,19 @@ def SelectreNumeration(opt, itemlist, manual=False):
self.setFocusId(focus - 1)
elif action in [UP]:
if focus in [S]:
s += 1
self.getControl(S).setLabel(str(s))
if str(s + 1) in self.seasonsdict:
s += 1
self.getControl(S).setLabel(str(s))
elif focus in [E]:
e += 1
self.getControl(E).setLabel(str(e))
if self.seasonsdict[str(s)] > e:
e += 1
self.getControl(E).setLabel(str(e))
elif action in [DOWN]:
if focus in [S]:
if s > 0: s -= 1
if str(s - 1) in self.seasonsdict: s -= 1
self.getControl(S).setLabel(str(s))
elif focus in [E]:
if e > 0: e -= 1
if e > 1: e -= 1
self.getControl(E).setLabel(str(e))
# MANUAL
if focus in [MS, ME]:
@@ -508,7 +464,7 @@ def SelectreNumeration(opt, itemlist, manual=False):
# OPEN MANUAL
elif control_id in [M]:
self.getControl(INFO).setLabel(typo(config.get_localized_string(70823) + self.title, 'bold'))
self.mode = True
self.manual = True
if self.episodes:
items = []
se = '1'
@@ -539,8 +495,8 @@ def SelectreNumeration(opt, itemlist, manual=False):
# DELETE
if control_id in [D]:
self.Exit = True
self.dictSeries.pop(self.title)
write(self.item, self.dictSeries)
self.renumberdict.pop(self.title)
write(self.item, self.renumberdict)
self.close()
## SPECIAL SECTION
@@ -548,7 +504,7 @@ def SelectreNumeration(opt, itemlist, manual=False):
p1 = self.getControl(SELECTED).getSelectedPosition()
if control_id in [LIST]:
item = self.getControl(LIST).getSelectedItem()
it = xbmcgui.ListItem(str(len(self.selected) + 1))
it = xbmcgui.ListItem(str(len(self.selected) + len(self.specials) + 1))
it.setProperty('title', item.getLabel())
self.selected.append(it)
index = self.getControl(SELECTED).getSelectedPosition()
@@ -754,4 +710,4 @@ DOWN = 4
EXIT = 10
BACKSPACE = 92
path = config.get_runtime_path()
path = config.get_runtime_path()

View File

@@ -41,7 +41,12 @@ def run(item=None):
logger.debug()
if not item:
# Extract item from sys.argv
if sys.argv[2]:
if sys.argv[2] and 'play' in sys.argv[2]:
sp = sys.argv[2].split('/')
if len(sp) == 3:
item = Item(channel=sp[1], livefilter=sp[2], action='play')
# If no item, this is mainlist
elif sys.argv[2]:
sp = sys.argv[2].split('&')
url = sp[0]
item = Item().fromurl(url)
@@ -49,7 +54,7 @@ def run(item=None):
for e in sp[1:]:
key, val = e.split('=')
item.__setattr__(key, val)
# If no item, this is mainlist
else:
item = Item(channel="channelselector", action="getmainlist", viewmode="movie")
if not config.get_setting('show_once'):
@@ -337,6 +342,10 @@ def run(item=None):
else:
if platformtools.dialog_yesno(config.get_localized_string(60038), config.get_localized_string(60015)):
run(Item(channel="setting", action="report_menu"))
finally:
if not item.action.startswith('play'):
from core import db
db.close()
def new_search(item, channel=None):
@@ -469,6 +478,7 @@ def play_from_library(item):
else:
# Pop-up window
from specials import videolibrary
from core.channeltools import get_channel_parameters
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(60683))
p_dialog.update(0, '')
item.play_from = 'window'
@@ -499,9 +509,10 @@ def play_from_library(item):
quality = '[B][' + item.quality + '][/B]' if item.quality else ''
if item.server:
path = filetools.join(config.get_runtime_path(), 'servers', item.server.lower() + '.json')
name = jsontools.load(open(path, "r").read())['name']
name = jsontools.load(open(path, "rb").read())['name']
if name.startswith('@'): name = config.get_localized_string(int(name.replace('@','')))
it = xbmcgui.ListItem('\n[B]%s[/B] %s - %s' % (name, quality, item.contentTitle))
logger.debug(item)
it = xbmcgui.ListItem('\n[B]%s[/B] %s - %s [%s]' % (name, quality, item.contentTitle, get_channel_parameters(item.contentChannel)['title']))
it.setArt({'thumb':item.thumbnail})
options.append(it)
else:

View File

@@ -226,6 +226,45 @@ def dialog_info(item, scraper):
dialog = TitleOrIDWindow('TitleOrIDWindow.xml', config.get_runtime_path()).Start(item, scraper)
return dialog
def dialog_select_group(heading, _list, preselect=0):
class SelectGroup(xbmcgui.WindowXMLDialog):
def start(self, heading, _list, preselect):
self.selected = preselect
self.heading = heading
self.list = _list
self.doModal()
return self.selected
def onInit(self):
self.getControl(1).setText(self.heading)
itemlist = []
for n, text in enumerate(self.list):
item = xbmcgui.ListItem(str(n))
item.setProperty('title', text)
itemlist.append(item)
self.getControl(2).addItems(itemlist)
self.setFocusId(2)
self.getControl(2).selectItem(self.selected)
def onClick(self, control):
if control in [100]:
self.selected = -1
self.close()
elif control in [2]:
self.selected = self.getControl(2).getSelectedPosition()
self.close()
def onAction(self, action):
action = action.getId()
if action in [10, 92]:
self.selected = -1
self.close()
dialog = SelectGroup('SelectGroup.xml', config.get_runtime_path()).start(heading, _list, preselect)
return dialog
def itemlist_refresh():
# pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
@@ -616,63 +655,71 @@ def is_playing():
def play_video(item, strm=False, force_direct=False, autoplay=False):
logger.debug()
logger.debug(item.tostring('\n'))
if item.channel == 'downloads':
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)
set_player(item, xlistitem, item.url, True, None) # Fix Play From Download Section
return
default_action = config.get_setting("default_action")
logger.debug("default_action=%s" % default_action)
# pass referer
if item.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: exit()
# get default option of addon configuration
seleccion = get_seleccion(default_action, opciones, seleccion, video_urls)
if seleccion < 0: exit() # Canceled box
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)
if salir:
return
# we get the selected video
mediaurl, view, mpd = get_video_seleccionado(item, seleccion, video_urls, autoplay)
if not mediaurl: return
# video information is obtained.
xlistitem = xbmcgui.ListItem(path=item.url)
xlistitem.setArt({"thumb": item.contentThumbnail if item.contentThumbnail else item.thumbnail})
set_infolabels(xlistitem, item, True)
# if it is a video in mpd format, the listitem is configured to play it ith the inpustreamaddon addon implemented in Kodi 17
# from core.support import dbg;dbg()
if mpd:
if not install_inputstream():
def play():
if item.channel == 'downloads':
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)
set_player(item, xlistitem, item.url, True, None) # Fix Play From Download Section
return
xlistitem.setProperty('inputstream' if PY3 else 'inputstreamaddon', 'inputstream.adaptive')
xlistitem.setProperty('inputstream.adaptive.manifest_type', 'mpd')
if item.drm and item.license:
install_widevine()
xlistitem.setProperty("inputstream.adaptive.license_type", item.drm)
xlistitem.setProperty("inputstream.adaptive.license_key", item.license)
xlistitem.setMimeType('application/dash+xml')
if force_direct: item.play_from = 'window'
default_action = config.get_setting("default_action")
logger.debug("default_action=%s" % default_action)
set_player(item, xlistitem, mediaurl, view, strm)
# pass referer
if item.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
# get default option of addon configuration
seleccion = get_seleccion(default_action, opciones, seleccion, video_urls)
if seleccion < 0: return # Canceled box
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)
if salir:
return
# we get the selected video
mediaurl, view, mpd = get_video_seleccionado(item, seleccion, video_urls, autoplay)
if not mediaurl: return
# video information is obtained.
xlistitem = xbmcgui.ListItem(path=item.url)
xlistitem.setArt({"thumb": item.contentThumbnail if item.contentThumbnail else item.thumbnail})
set_infolabels(xlistitem, item, True)
# if it is a video in mpd format, the listitem is configured to play it ith the inpustreamaddon addon implemented in Kodi 17
# from core.support import dbg;dbg()
if mpd:
if not install_inputstream():
return
xlistitem.setProperty('inputstream' if PY3 else 'inputstreamaddon', 'inputstream.adaptive')
xlistitem.setProperty('inputstream.adaptive.manifest_type', 'mpd')
if item.drm and item.license:
install_widevine()
xlistitem.setProperty("inputstream.adaptive.license_type", item.drm)
xlistitem.setProperty("inputstream.adaptive.license_key", item.license)
xlistitem.setMimeType('application/dash+xml')
if force_direct: item.play_from = 'window'
set_player(item, xlistitem, mediaurl, view, strm)
return True
if not play():
# close db to ensure his thread will stop
from core import db
db.close()
def stop_video():
@@ -1370,71 +1417,60 @@ def get_platform():
def get_played_time(item):
import sqlite3
from core import filetools
db_name = filetools.join(config.get_data_path(), "kod_db.sqlite")
ID = item.infoLabels['tmdb_id']
conn = sqlite3.connect(db_name, timeout=15)
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS viewed (tmdb_id TEXT, season INT, episode INT, played_time REAL)')
conn.commit()
if ID:
if item.contentType == 'movie': c.execute("SELECT played_time FROM viewed WHERE tmdb_id=?", (ID,))
elif 'season' in item.infoLabels:
S = item.infoLabels['season']
E = item.infoLabels['episode']
c.execute("SELECT played_time FROM viewed WHERE tmdb_id=? AND season=? AND episode=?", (ID, S, E))
elif 'episode' in item.infoLabels:
E = item.infoLabels['episode']
c.execute("SELECT played_time FROM viewed WHERE tmdb_id=? AND episode=?", (ID, E))
result = c.fetchone()
if not result: played_time = 0
else: played_time = result[0]
else: played_time = 0
conn.close()
logger.debug()
from core import db
if not item.infoLabels:
return 0
ID = item.infoLabels.get('tmdb_id', '')
if not ID:
return 0
S = item.infoLabels.get('season', 0)
E = item.infoLabels.get('episode')
result = None
if item.contentType == 'movie':
result = db['viewed'].get(ID)
elif S and E:
result = db['viewed'].get(ID, {}).get(str(S)+'x'+str(E))
if not result: played_time = 0
else: played_time = result
return played_time
def set_played_time(item):
import sqlite3
from core import filetools
ID = item.infoLabels['tmdb_id']
logger.debug()
from core import db
played_time = item.played_time
db_name = filetools.join(config.get_data_path(), "kod_db.sqlite")
conn = sqlite3.connect(db_name, timeout=15)
c = conn.cursor()
if not item.infoLabels:
return
ID = item.infoLabels.get('tmdb_id', '')
if not ID:
return
S = item.infoLabels.get('season', 0)
E = item.infoLabels.get('episode')
if item.contentType == 'movie':
c.execute("SELECT played_time FROM viewed WHERE tmdb_id=?", (ID,))
result = c.fetchone()
if result:
if played_time > 0: c.execute("UPDATE viewed SET played_time=? WHERE tmdb_id=?", (item.played_time, ID))
else: c.execute("DELETE from viewed WHERE tmdb_id=?", (ID,))
else: c.execute("INSERT INTO viewed (tmdb_id, played_time) VALUES (?, ?)", (ID, item.played_time))
elif 'season' in item.infoLabels:
S = item.infoLabels['season']
E = item.infoLabels['episode']
c.execute("SELECT played_time FROM viewed WHERE tmdb_id=? AND season = ? AND episode=?", (ID, S, E))
result = c.fetchone()
if result:
if played_time > 0: c.execute("UPDATE viewed SET played_time=? WHERE tmdb_id=? AND season=? AND episode=?", (item.played_time, ID, S, E))
else: c.execute("DELETE from viewed WHERE tmdb_id=? AND season=? AND episode=?", (ID, S, E))
else: c.execute("INSERT INTO viewed (tmdb_id, season, episode, played_time) VALUES (?, ?, ?, ?)", (ID, S, E, item.played_time))
elif 'episode' in item.infoLabels:
E = item.infoLabels['episode']
c.execute("SELECT played_time FROM viewed WHERE tmdb_id=? AND episode=?", (ID, E))
result = c.fetchone()
if result:
if played_time > 0: c.execute("UPDATE viewed SET played_time=? WHERE tmdb_id=? AND episode=?", (item.played_time, ID, E))
else: c.execute("DELETE from viewed WHERE tmdb_id=? AND episode=?", (ID, E))
else: c.execute("INSERT INTO viewed (tmdb_id, episode, played_time) VALUES (?, ?, ?)", (ID, E, item.played_time))
conn.commit()
conn.close()
db['viewed'][ID] = played_time
elif E:
newDict = db['viewed'].get(ID, {})
newDict[str(S) + 'x' + str(E)] = played_time
db['viewed'][ID] = newDict
def prevent_busy(item):
logger.debug()
if not item.autoplay and not item.window:
if item.globalsearch: xbmc.Player().play(os.path.join(config.get_runtime_path(), "resources", "kod.mp4"))
else: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(path=os.path.join(config.get_runtime_path(), "resources", "kod.mp4")))
xbmc.sleep(100)
xbmc.sleep(200)
xbmc.Player().stop()
# xbmc.executebuiltin('Action(Stop)')
# xbmc.sleep(500)

View File

@@ -46,6 +46,7 @@ def mark_auto_as_watched(item):
ND = next_dialogs[next_ep_type]
try: next_episode = next_ep(item)
except: next_episode = False
logger.debug(next_episode)
while platformtools.is_playing():
actual_time = xbmc.Player().getTime()
@@ -108,9 +109,6 @@ def mark_auto_as_watched(item):
threading.Thread(target=mark_as_watched_subThread, args=[item]).start()
def sync_trakt_addon(path_folder):
"""
Updates the values of episodes seen if
@@ -351,6 +349,38 @@ def mark_season_as_watched_on_kodi(item, value=1):
execute_sql_kodi(sql)
def set_watched_on_kod(data):
from specials import videolibrary
from core import videolibrarytools
data = jsontools.load(data)
Type = data.get('item', {}).get('type','')
ID = data.get('item', {}).get('id','')
if not Type or not ID:
return
playcount = data.get('playcount',0)
for Type in ['movie', 'episode']:
sql = 'select strFileName, strPath, uniqueid_value from %s_view where (id%s like "%s")' % (Type, Type.capitalize(), ID)
n, records = execute_sql_kodi(sql)
if records:
for filename, path, uniqueid_value in records:
if Type in ['movie']:
title = filename.replace('.strm', ' [' + uniqueid_value + ']')
filename = title +'.nfo'
else:
title = filename.replace('.strm', '')
filename = 'tvshow.nfo'
path = filetools.join(path, filename)
head_nfo, item = videolibrarytools.read_nfo(path)
item.library_playcounts.update({title: playcount})
filetools.write(path, head_nfo + item.tojson())
if item.infoLabels['mediatype'] == "tvshow":
for season in item.library_playcounts:
if "season" in season:
season_num = int(scrapertools.find_single_match(season, r'season (\d+)'))
item = videolibrary.check_season_playcount(item, season_num)
filetools.write(path, head_nfo + item.tojson())
def mark_content_as_watched_on_kod(path):
from specials import videolibrary
@@ -384,6 +414,7 @@ def mark_content_as_watched_on_kod(path):
if "\\" in path:
path = path.replace("/", "\\")
head_nfo, item = videolibrarytools.read_nfo(path) # I read the content .nfo
old = item.clone()
if not item:
logger.error('.NFO not found: ' + path)
return
@@ -437,8 +468,9 @@ def mark_content_as_watched_on_kod(path):
if "season" in season: # we look for the tags "season" inside playCounts
season_num = int(scrapertools.find_single_match(season, r'season (\d+)')) # we save the season number
item = videolibrary.check_season_playcount(item, season_num) # We call the method that updates Temps. and series
filetools.write(path, head_nfo + item.tojson())
if item.library_playcounts != old.library_playcounts:
logger.debug('scrivo')
filetools.write(path, head_nfo + item.tojson())
#logger.debug(item)
@@ -626,37 +658,14 @@ def set_content(content_type, silent=False, custom=False):
xbmc.executebuiltin('Addon.OpenSettings(metadata.universal)', True)
else: # SERIES
scraper = [config.get_localized_string(70098), config.get_localized_string(70093)]
scraper = [config.get_localized_string(70093), config.get_localized_string(70098)]
if not custom:
seleccion = 0 # tvdb
seleccion = 0 # tmdb
else:
seleccion = platformtools.dialog_select(config.get_localized_string(70107), scraper)
# Instalar The TVDB
if seleccion == -1 or seleccion == 0:
if not xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'):
if not silent:
#Ask if we want to install metadata.tvdb.com
install = platformtools.dialog_yesno(config.get_localized_string(60048),'')
else:
install = True
if install:
try:
# Install metadata.tvdb.com
xbmc.executebuiltin('InstallAddon(metadata.tvdb.com)', True)
logger.debug("The TVDB series Scraper installed ")
except:
pass
continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'))
if not continuar:
msg_text = config.get_localized_string(60049)
if continuar:
xbmc.executebuiltin('Addon.OpenSettings(metadata.tvdb.com)', True)
# Instalar The Movie Database
elif seleccion == 1:
if seleccion == -1 or seleccion == 0:
if continuar and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'):
continuar = False
if not silent:
@@ -680,6 +689,29 @@ def set_content(content_type, silent=False, custom=False):
if continuar:
xbmc.executebuiltin('Addon.OpenSettings(metadata.tvshows.themoviedb.org)', True)
# Instalar The TVDB
elif seleccion == 1:
if not xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'):
if not silent:
#Ask if we want to install metadata.tvdb.com
install = platformtools.dialog_yesno(config.get_localized_string(60048),'')
else:
install = True
if install:
try:
# Install metadata.tvdb.com
xbmc.executebuiltin('InstallAddon(metadata.tvdb.com)', True)
logger.debug("The TVDB series Scraper installed ")
except:
pass
continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'))
if not continuar:
msg_text = config.get_localized_string(60049)
if continuar:
xbmc.executebuiltin('Addon.OpenSettings(metadata.tvdb.com)', True)
idPath = 0
idParentPath = 0
if continuar:
@@ -753,11 +785,11 @@ def set_content(content_type, silent=False, custom=False):
strContent = 'tvshows'
scanRecursive = 0
if seleccion == -1 or seleccion == 0:
strScraper = 'metadata.tvdb.com'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvdb.com/settings.xml")
elif seleccion == 1:
strScraper = 'metadata.tvshows.themoviedb.org'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml")
elif seleccion == 1:
strScraper = 'metadata.tvdb.com'
path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvdb.com/settings.xml")
if not os.path.exists(path_settings):
logger.debug("%s: %s" % (content_type, path_settings + " doesn't exist"))
return continuar
@@ -961,13 +993,14 @@ def clean(path_list=[]):
sql = 'SELECT idPath FROM path where strPath LIKE "%s"' % sql_path
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
idPath = records[0][0]
sql = 'DELETE from path WHERE idPath=%s' % idPath
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
sql = 'DELETE from path WHERE idParentPath=%s' % idPath
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
idPath = records[0][0]
sql = 'DELETE from path WHERE idPath=%s' % idPath
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
sql = 'DELETE from path WHERE idParentPath=%s' % idPath
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
from core import videolibrarytools
for path, folders, files in filetools.walk(videolibrarytools.MOVIES_PATH):
@@ -1236,7 +1269,6 @@ def update_sources(new='', old=''):
def ask_set_content(silent=False):
logger.debug()
logger.debug("videolibrary_kodi %s" % config.get_setting("videolibrary_kodi"))
def do_config(custom=False):
if set_content("movie", True, custom) and set_content("tvshow", True, custom):
platformtools.dialog_ok(config.get_localized_string(80026), config.get_localized_string(70104))
@@ -1271,11 +1303,11 @@ def ask_set_content(silent=False):
config.set_setting("folder_movies", movies_folder)
config.set_setting("folder_tvshows", tvshows_folder)
config.verify_directories_created()
do_config(True)
do_config(False)
# default path and folders
else:
platformtools.dialog_ok(config.get_localized_string(80026), config.get_localized_string(80030))
do_config(True)
do_config(False)
# default settings
else:
platformtools.dialog_ok(config.get_localized_string(80026), config.get_localized_string(80027))
@@ -1286,7 +1318,7 @@ def ask_set_content(silent=False):
# configuration from the settings menu
else:
platformtools.dialog_ok(config.get_localized_string(80026), config.get_localized_string(80023))
do_config(True)
do_config(False)
def next_ep(item):