Alcune migliorie alla videoteca

This commit is contained in:
Alhaziel01
2021-05-20 20:23:21 +02:00
parent b773164dad
commit b0d3dd2fa7
10 changed files with 435 additions and 544 deletions

View File

@@ -14,7 +14,7 @@
<menu id="kodi.core.main">
<item library="updatetvshow.py">
<label>70269</label>
<visible>String.IsEqual(ListItem.dbtype,tvshow)</visible>
<visible>String.IsEqual(ListItem.dbtype, tvshow) + !String.IsEmpty(ListItem.DBID)</visible>
</item>
<!-- <item library="externalsearch.py">-->
<!-- <label>90001</label>-->

View File

@@ -1205,7 +1205,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
# logger.debug(videoitem)
if videoitem.video_urls or srv_param.get('active', False):
# dbg()
item.title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' and item.contentTitle or (config.get_localized_string(30161) in item.title) else item.title
item.title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' and item.contentTitle or (config.get_localized_string(30161) in item.fulltitle) else item.fulltitle
quality = videoitem.quality if videoitem.quality else item.quality if item.quality else ''
videoitem.contentLanguage = videoitem.contentLanguage if videoitem.contentLanguage else item.contentLanguage

View File

@@ -960,13 +960,13 @@ class Tmdb(object):
result = result["tv_results"][0]
else:
result = result['tv_episode_results'][0]
Mpaaurl = '{}/{}/{}/{}?api_key={}'.format(host, self.search_type, result['id'], 'release_dates' if self.search_type == 'movie' else 'content_ratings', api)
Mpaas = self.get_json(Mpaaurl).get('results',[])
for m in Mpaas:
if m.get('iso_3166_1','').lower() == 'us':
result['mpaa'] = m.get('rating', m.get('release_dates', [{}])[0].get('certification'))
break
if result.get('id'):
Mpaaurl = '{}/{}/{}/{}?api_key={}'.format(host, self.search_type, result['id'], 'release_dates' if self.search_type == 'movie' else 'content_ratings', api)
Mpaas = self.get_json(Mpaaurl).get('results',[])
for m in Mpaas:
if m.get('iso_3166_1','').lower() == 'us':
result['mpaa'] = m.get('rating', m.get('release_dates', [{}])[0].get('certification'))
break
self.results = [result]
self.total_results = 1
@@ -1691,8 +1691,8 @@ class Tmdb(object):
ret_infoLabels['studio'] = ", ".join(i['name'] for i in v)
elif k == 'credits_cast' or k == 'season_cast' or k == 'episode_guest_stars':
dic_aux = dict((name, [character, thumb, order]) for (name, character, thumb, order) in l_castandrole)
l_castandrole.extend([(p['name'], p.get('character', '') or p.get('character_name', ''), 'https://image.tmdb.org/t/p/original' + p.get('profile_path', '') if p.get('profile_path', '') else '', p.get('order')) \
dic_aux = dict((name, [character, thumb, order, id]) for (name, character, thumb, order, id) in l_castandrole)
l_castandrole.extend([(p['name'], p.get('character', '') or p.get('character_name', ''), 'https://image.tmdb.org/t/p/original' + p.get('profile_path', '') if p.get('profile_path', '') else '', p.get('order'), p.get('credit_id')) \
for p in v if 'name' in p and p['name'] not in list(dic_aux.keys())])
elif k == 'videos':

View File

@@ -193,18 +193,39 @@ def save_movie(item, silent=False):
if not head_nfo:
head_nfo = scraper.get_nfo(item)
# get extra info from fanart tv
# support.dbg()
extra_info = get_fanart_tv(item)
if not item.infoLabels.get('posters'): item.infoLabels['posters'] = []
item.infoLabels['posters'] += extra_info['poster']
if not item.infoLabels.get('fanarts'): item.infoLabels['fanarts'] = []
item.infoLabels['fanarts'] += extra_info['fanart']
if not item.infoLabels.get('clearlogos'): item.infoLabels['clearlogos'] = []
item.infoLabels['clearlogos'] += extra_info['clearlogo']
if not item.infoLabels.get('cleararts'): item.infoLabels['cleararts'] = []
item.infoLabels['cleararts'] += extra_info['clearart']
if not item.infoLabels.get('landscapes'): item.infoLabels['landscapes'] = []
item.infoLabels['landscapes'] += extra_info['landscape']
if not item.infoLabels.get('banners'): item.infoLabels['banners'] = []
item.infoLabels['banners'] += extra_info['banner']
# Make or update Videolibrary Movie Item
movie_item.channel = "videolibrary"
movie_item.action = 'findvideos'
movie_item.infoLabels = item.infoLabels
movie_item.infoLabels['playcount'] = 0
if not movie_item.head_nfo: movie_item.head_nfo = head_nfo
if not movie_item.title: movie_item.title = item.contentTitle
if not movie_item.videolibrary_id: movie_item.videolibrary_id = _id
if not movie_item.strm_path: movie_item.strm_path = strm_path
if not movie_item.nfo_path: movie_item.nfo_path = nfo_path
if not movie_item.base_name: movie_item.base_name = base_name
if not movie_item.fanart: movie_item.fanart = item.infoLabels['fanart']
if not movie_item.thumbnail: movie_item.thumbnail = item.infoLabels['thumbnail']
if not movie_item.fanart: movie_item.fanart = item.infoLabels['fanart']
if not movie_item.landscape: movie_item.landscape = item.infoLabels['landscapes'][0] if item.infoLabels['landscapes'] else item.infoLabels['fanart']
if not movie_item.banner and item.infoLabels['banners']: movie_item.clearart = item.infoLabels['banners'][0]
if not movie_item.clearart and item.infoLabels['cleararts']: movie_item.clearart = item.infoLabels['cleararts'][0]
if not movie_item.clearlogo and item.infoLabels['clearlogos']: movie_item.clearlogo = item.infoLabels['clearlogos'][0]
if not movie_item.playtime: movie_item.playtime = 0,
if not movie_item.playcounts: movie_item.playcounts = 0,
if not movie_item.prefered_lang: movie_item.prefered_lang = ''
@@ -266,8 +287,8 @@ def save_movie(item, silent=False):
p_dialog.update(100, item.contentTitle)
p_dialog.close()
# Update Kodi Library
from platformcode.dbconverter import add_video
add_video(movie_item)
# from platformcode.dbconverter import add_video
# add_video(movie_item)
# if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent and inserted:
# from platformcode.xbmc_videolibrary import update
# update(MOVIES_PATH)
@@ -334,7 +355,7 @@ def save_tvshow(item, episodelist, silent=False):
@rtype path: str
@return: serial directory
"""
logger.debug()
inserted = 0
overwritten = 0
failed = 0
@@ -394,35 +415,42 @@ def save_tvshow(item, episodelist, silent=False):
head_nfo = scraper.get_nfo(item)
if not head_nfo: return 0, 0, -1, ''
extra_info = get_fanart_tv(item)
if not item.infoLabels.get('posters'): item.infoLabels['posters'] = []
item.infoLabels['posters'] += extra_info['poster'].get('all',[])
if not item.infoLabels.get('fanarts'): item.infoLabels['fanarts'] = []
item.infoLabels['fanarts'] += extra_info['fanart']
if not item.infoLabels.get('clearlogos'): item.infoLabels['clearlogos'] = []
item.infoLabels['clearlogos'] += extra_info['clearlogo']
if not item.infoLabels.get('cleararts'): item.infoLabels['cleararts'] = []
item.infoLabels['cleararts'] += extra_info['clearart']
if not item.infoLabels.get('landscapes'): item.infoLabels['landscapes'] = []
item.infoLabels['landscapes'] += extra_info['landscape'].get('all',[])
if not item.infoLabels.get('banners'): item.infoLabels['banners'] = []
item.infoLabels['banners'] += extra_info['banner'].get('all',[])
item.infoLabels['mediatype'] = 'tvshow'
item.contentType = 'tvshow'
item.infoLabels['title'] = item.contentSerieName
tvshow_item.infoLabels = item.infoLabels
if not tvshow_item.infoLabels.get('playcount'): tvshow_item.infoLabels['playcount'] = 0
tvshow_item.channel = 'videolibrary'
tvshow_item.action = 'get_seasons'
tvshow_item.nfo_path = nfo_path
if not tvshow_item.head_nfo:
tvshow_item.head_nfo = head_nfo
if not tvshow_item.title:
tvshow_item.title = item.contentSerieName
if not tvshow_item.videolibrary_id:
tvshow_item.videolibrary_id = _id
if not tvshow_item.fanart:
tvshow_item.fanart = item.infoLabels['fanart']
if not tvshow_item.thumbnail:
tvshow_item.thumbnail = item.infoLabels['thumbnail']
if not tvshow_item.base_name:
tvshow_item.base_name = base_name
if tvshow_item.active == '':
tvshow_item.active = True
if not tvshow_item.playcounts:
tvshow_item.playcounts = 0,
if not tvshow_item.prefered_lang:
tvshow_item.prefered_lang = ''
if not tvshow_item.lang_list:
tvshow_item.lang_list = []
if not tvshow_item.head_nfo: tvshow_item.head_nfo = head_nfo
if not tvshow_item.title: tvshow_item.title = item.contentSerieName
if not tvshow_item.videolibrary_id: tvshow_item.videolibrary_id = _id
if not tvshow_item.thumbnail: tvshow_item.thumbnail = item.infoLabels['thumbnail']
if not tvshow_item.fanart: tvshow_item.fanart = item.infoLabels['fanart']
if not tvshow_item.landscape: tvshow_item.landscape = item.infoLabels['landscapes'][0] if item.infoLabels['landscapes'] else item.infoLabels['fanart']
if not tvshow_item.banner and item.infoLabels['banners']: tvshow_item.clearart = item.infoLabels['banners'][0]
if not tvshow_item.clearart and item.infoLabels['cleararts']: tvshow_item.clearart = item.infoLabels['cleararts'][0]
if not tvshow_item.clearlogo and item.infoLabels['clearlogos']: tvshow_item.clearlogo = item.infoLabels['clearlogos'][0]
if not tvshow_item.base_name: tvshow_item.base_name = base_name
if tvshow_item.active == '': tvshow_item.active = True
if not tvshow_item.prefered_lang: tvshow_item.prefered_lang = ''
if not tvshow_item.lang_list: tvshow_item.lang_list = []
remove_host(item)
item.renumber = add_renumber_options(item)
@@ -448,16 +476,19 @@ def save_tvshow(item, episodelist, silent=False):
return 0, 0, -1, path
# Save the episodes
inserted, overwritten, failed = save_episodes(tvshow_item, episodelist, silent=silent)
logger.debug()
inserted, overwritten, failed = save_episodes(tvshow_item, episodelist, extra_info, item.host, silent=silent)
videolibrarydb.close()
if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent and inserted:
from platformcode.xbmc_videolibrary import update
update(TVSHOWS_PATH, tvshow_item.basename)
# if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent and inserted:
# # from platformcode.dbconverter import add_video
# # add_video(tvshow_item)
# from platformcode.xbmc_videolibrary import update
# update(TVSHOWS_PATH, tvshow_item.basename)
return inserted, overwritten, failed, path
def save_episodes(item, episodelist, silent=False, overwrite=True):
def save_episodes(item, episodelist, extra_info, host, silent=False, overwrite=True):
"""
saves in the indicated path all the chapters included in the episodelist
@type Item: str
@@ -477,7 +508,8 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
@rtype failed: int
@return: the number of failed episodes
"""
def save_episode(item, seasons, episodes, e, inserted, overwritten, failed):
# support.dbg()
def save_episode(item, seasons, current_seasons, episodes, e, inserted, overwritten, failed):
season_episode = scrapertools.get_season_and_episode(e.title)
@@ -491,8 +523,9 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
e.contentSeason = int(season_episode.split('x')[0])
e.contentEpisodeNumber = int(season_episode.split('x')[1])
tmdb.set_infoLabels_item(e)
playcount = db['viewed'].get(e.infoLabels['tmdb_id'], {}).get('{}x{}'.format(e.contentSeason, e.contentEpisodeNumber), 0)
if not e.infoLabels.get('playcount'): e.infoLabels['playcount'] = 0
head_nfo = scraper.get_nfo(e)
episode_item = Item(action='findvideos',
@@ -511,32 +544,39 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
episode = episodes.get(season_episode, {})
try:
# e.infoLabels['episode'] = ''
if e.contentSeason not in seasons:
# season_item = Item(infoLabels = e.infoLabels)
if e.contentSeason not in current_seasons:
tmdb_info = tmdb.Tmdb(id_Tmdb = e.infoLabels['tmdb_id'], search_type='tv')
seasoninfo = tmdb.get_season_dic(tmdb_info.get_season(e.contentSeason))
infoLabels = {}
if seasoninfo.get('season_posters'): infoLabels['posters'] = seasoninfo.get('season_posters')
if seasoninfo.get('season_fanarts'): infoLabels['fanarts'] = seasoninfo.get('season_fanarts')
if seasoninfo.get('season_posters'): infoLabels['posters'] = seasoninfo.get('season_posters') + extra_info['poster'].get(str(e.contentSeason), [])
if seasoninfo.get('season_fanarts'): infoLabels['fanarts'] = seasoninfo.get('season_fanarts') + extra_info['fanart'].get(str(e.contentSeason), [])
if seasoninfo.get('season_trailer'): infoLabels['trailer'] = seasoninfo.get('season_trailer')
infoLabels['landscapes'] = extra_info['landscape'].get(str(e.contentSeason), [])
infoLabels['banners'] = extra_info['banner'].get(str(e.contentSeason), [])
infoLabels['clearlogos'] = item.infoLabels.get('clearlogos', [])
infoLabels['cleararts'] = item.infoLabels.get('cleararts', [])
if e.contentSeason in seasons: infoLabels['playcount'] = seasons[e.contentSeason].infoLabels.get('playcount', 0)
season_item = Item(action="get_episodes",
channel='videolibrary',
title=seasoninfo.get('season_title'),
thumbnail = seasoninfo.get('season_poster') if seasoninfo.get('season_poster') else item.thumbnail,
fanart = item.fanart,
plot = seasoninfo.get('season_plot') if seasoninfo.get('season_plot') else item.infoLabels.get('plot'),
contentType = 'season',
infoLabels = infoLabels,
contentSeason = e.contentSeason,
videolibrary_id = item.videolibrary_id,
playcount=0)
channel='videolibrary',
title=seasoninfo.get('season_title'),
thumbnail = seasoninfo.get('season_poster') if seasoninfo.get('season_poster') else item.thumbnail,
fanart = item.fanart,
plot = seasoninfo.get('season_plot') if seasoninfo.get('season_plot') else item.infoLabels.get('plot'),
contentType = 'season',
infoLabels = infoLabels,
contentSeason = e.contentSeason,
videolibrary_id = item.videolibrary_id,
playcount=0)
logger.debug(season_item)
if infoLabels['clearlogos']: season_item.clearlogo = infoLabels['clearlogos'][0]
if infoLabels['cleararts']: season_item.clearart = infoLabels['cleararts'][0]
if infoLabels['landscapes']: season_item.landscape = infoLabels['landscapes'][0]
if infoLabels['banners']: season_item.banner = infoLabels['banners'][0]
seasons[e.contentSeason] = season_item
current_seasons.append(e.contentSeason)
if not episode:
inserted += 1
@@ -545,7 +585,9 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
# else:
epchannels = episode.get('channels',{})
remove_host(e)
if e.url.startswith(host):
remove_host(e)
e.contentTitle = e.infoLabels['title']
e.infoLabels = {}
@@ -588,6 +630,7 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
inserted = 0
overwritten = 0
failed = 0
current_seasons = []
seasons = videolibrarydb['season'].get(item.videolibrary_id, {})
episodes = videolibrarydb['episode'].get(item.videolibrary_id, {})
videolibrarydb.close()
@@ -595,15 +638,17 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
try: t = float(100) / len(episodelist)
except: t = 0
# support.dbg()
# for i, e in enumerate(episodelist):
# item, seasons, episodes, e, inserted, overwritten, failed = save_episode(item, seasons, episodes, e, inserted, overwritten, failed)
# item, seasons, episodes, e, inserted, overwritten, failed = save_episode(item, seasons, current_seasons, episodes, e, inserted, overwritten, failed)
# if not e.contentLanguage: e.contentLanguage = item.contentLanguage if item.contentLanguage else 'ITA'
# if not e.contentLanguage in item.lang_list: item.lang_list.append(e.contentLanguage)
# if not silent:
# p_dialog.update(int(math.ceil((i + 1) * t)), e.title)
i = 0
with futures.ThreadPoolExecutor() as executor:
itlist = [executor.submit(save_episode, item, seasons, episodes, e, inserted, overwritten, failed) for e in episodelist]
itlist = [executor.submit(save_episode, item, seasons, current_seasons, episodes, e, inserted, overwritten, failed) for e in episodelist]
for res in futures.as_completed(itlist):
if res.result():
item, seasons, episodes, e, inserted, overwritten, failed = res.result()
@@ -627,7 +672,8 @@ def save_episodes(item, episodelist, silent=False, overwrite=True):
videolibrarydb['season'][item.videolibrary_id] = seasons
videolibrarydb.close()
p_dialog.close()
if not silent:
p_dialog.close()
return inserted, overwritten, failed
@@ -819,6 +865,7 @@ def add_tvshow(item, channel=None):
# Get the episode list
it = item.clone()
itemlist = getattr(channel, it.action)(it)
item.host = channel.host
if itemlist and not scrapertools.find_single_match(itemlist[0].title, r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)'):
from platformcode.autorenumber import start, check
if not check(item):
@@ -875,10 +922,9 @@ def add_tvshow(item, channel=None):
def remove_host(item):
if PY3:
import urllib.parse as urlparse # It is very slow in PY2. In PY3 it is native
else:
import urlparse # We use the native of PY2 which is faster
if PY3: import urllib.parse as urlparse # It is very slow in PY2. In PY3 it is native
else: import urlparse # We use the native of PY2 which is faster
parsed_url = urlparse.urlparse(item.url)
item.url = urlparse.urlunparse(('', '', parsed_url.path, parsed_url.params, parsed_url.query, parsed_url.fragment))
@@ -903,3 +949,41 @@ def get_local_files(item):
included_files['{}x{}'.format(s,e.zfill(2))] = f
if included_files:
return included_files, 1
def get_fanart_tv(item):
def set_dict(l):
d = {}
for k in l:
o = d.get(k['season'], [])
o.append(k['url'])
d[k['season']] = o
return d
# support.dbg()
ret = {}
_id = item.infoLabels.get('tvdb_id', item.infoLabels.get('tmdb_id'))
if _id:
_type = item.contentType.replace('show','').replace('movie','movies')
host = 'http://webservice.fanart.tv/v3/{}/{}?api_key=cab16e262d72fea6a6843d679aa10300'
url = host.format(_type, _id)
res = httptools.downloadpage(url).json
if _type == 'tv':
ret['clearlogo'] = [k.get('url') for k in res.get('hdtvlogo', [])]
ret['clearart'] = [k.get('url') for k in res.get('hdclearart', [])]
ret['fanart'] = set_dict(res.get('showbackground', []))
ret['poster'] = set_dict(res.get('seasonposter', []))
ret['poster']['all'] = [k.get('url') for k in res.get('tvposter', [])]
ret['landscape'] = set_dict(res.get('seasonthumb', []))
ret['landscape']['all'] = [k.get('url') for k in res.get('tvthumb', [])]
ret['banner'] = set_dict(res.get('seasonbanner', []))
ret['banner']['all'] = [k.get('url') for k in res.get('tvbanner', [])]
elif _type == 'movies':
ret['clearlogo'] = [k.get('url') for k in res.get('hdmovielogo', [])]
ret['poster'] = [k.get('url') for k in res.get('movieposter', [])]
ret['fanart'] = [k.get('url') for k in res.get('moviebackground', [])]
ret['clearart'] = [k.get('url') for k in res.get('hdmovieclearart', [])]
ret['landscape'] = [k.get('url') for k in res.get('moviethumb', [])]
ret['banner'] = [k.get('url') for k in res.get('moviebanner', [])]
return ret

View File

@@ -279,15 +279,19 @@ def dialog_select_group(heading, _list, preselect=0):
def itemlist_refresh():
# pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
# logger.info('Current position: ' + str(pos))
win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
cid = win.getFocusId()
ctl = win.getControl(cid)
pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
xbmc.executebuiltin("Container.Refresh")
# while Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition != pos:
# win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
# cid = win.getFocusId()
# ctl = win.getControl(cid)
# ctl.selectItem(pos)
while xbmcgui.getCurrentWindowDialogId() != 10138:
pass
while xbmcgui.getCurrentWindowDialogId() == 10138:
pass
ctl.selectItem(pos)
def itemlist_update(item, replace=False):
@@ -354,17 +358,24 @@ def render_items(itemlist, parent_item):
icon_image = "DefaultFolder.png" if item.folder else "DefaultVideo.png"
listitem = xbmcgui.ListItem(item.title)
listitem.setArt({'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail,
'fanart': item.fanart if item.fanart else default_fanart})
art = {'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail, 'fanart': item.fanart if item.fanart else default_fanart}
if item.landscape: art['landscape'] = item.landscape
if item.clearlogo: art['clearlogo'] = item.clearlogo
if item.clearart: art['clearart'] = item.clearart
if item.banner: art['banner'] = item.banner
listitem.setArt(art)
if config.get_setting("player_mode") == 1 and item.action == "play" and not item.nfo:
listitem.setProperty('IsPlayable', 'true')
set_infolabels(listitem, item)
if item.infoLabels.get('castandrole'):
cast = [{'name':c[0], 'role':c[1], 'thumbnail':c[2], 'order':c[3]} for c in item.infoLabels.get("castandrole", [])]
cast.sort(key=lambda c: c['order'])
listitem.setCast(cast)
del item.infoLabels['castandrole']
set_infolabels(listitem, item)
# context menu
if parent_item.channel != 'special':
@@ -453,11 +464,11 @@ def getCurrentView(item=None, parent_item=None):
or (item.channel in ['videolibrary'] and parent_item.action in ['list_tvshows']):
return 'tvshow', 'tvshows'
elif parent_item.action in ['get_seasons']:
elif parent_item.action in ['get_seasons'] or item.contentType == 'season':
return 'season', 'tvshows'
elif parent_item.action in ['episodios', 'get_episodes'] or item.contentType == 'episode':
return 'episode', 'tvshows'
return 'episode', 'episodes'
else:
return 'menu', 'addons' if config.get_setting('touch_view') else ''
@@ -517,6 +528,7 @@ def set_infolabels(listitem, item, player=False):
'top250': 'top250', 'tracknumber': 'tracknumber', 'trailer': 'trailer', 'thumbnail': 'None',
'tvdb_id': 'None', 'tvshowtitle': 'tvshowtitle', 'type': 'None', 'userrating': 'userrating',
'url_scraper': 'None', 'votes': 'votes', 'writer': 'writer', 'year': 'year'}
if item.infoLabels:
try:
infoLabels_kodi = {infoLabels_dict[label_tag]: item.infoLabels[label_tag] for label_tag, label_value in list(item.infoLabels.items()) if infoLabels_dict[label_tag] != 'None' and label_tag in infoLabels_dict}

View File

@@ -6,7 +6,7 @@
# standard_library.install_aliases()
#from builtins import str
from core.item import Item
import sys, os, threading, time, re, math, xbmc, xbmcgui
import sys, os, threading, time, re, math, xbmc, xbmcgui, sqlite3
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
@@ -263,78 +263,30 @@ def mark_content_as_watched_on_kodi(item, value=1):
@param value: > 0 for seen, 0 for not seen
"""
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
payload_f = ''
pos = item.itemlistPosition
winid = xbmcgui.getCurrentWindowId()
win = xbmcgui.Window(winid)
cid = win.getFocusId()
ctl = win.getControl(cid)
view = 'episode' if item.contentType != 'movie' else 'movie'
path = '%{}%'.format(item.strm_path.split('\\')[0].split('/')[0] if item.strm_path else item.base_name)
if item.contentType == "movie":
movieid = 0
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies",
"params": {"properties": ["title", "playcount", "originaltitle", "file"]},
"id": 1}
request_season = ''
request_episode = ''
if item.contentSeason: request_season = ' and c12= {}'.format(item.contentSeason)
if item.contentEpisodeNumber: request_episode = ' and strFileName= "{}"'.format(item.strm_path.split('\\')[-1].split('/')[-1])
sql = 'select idFile from {}_view where strPath like "{}"{}{}'.format(view, path, request_episode, request_season)
data = get_data(payload)
if 'result' in data and "movies" in data['result']:
if item.strm_path: # If Item is from an episode
filename = filetools.basename(item.strm_path)
head, tail = filetools.split(filetools.split(item.strm_path)[0])
else: # If Item is from the Series
filename = filetools.basename(item.path)
head, tail = filetools.split(filetools.split(item.path)[0])
path = filetools.join(tail, filename)
for d in data['result']['movies']:
if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")):
# logger.debug("I mark the movie as a view")
movieid = d['movieid']
break
if movieid != 0:
payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": movieid, "playcount": value}, "id": 1}
else: # item.contentType != 'movie'
episodeid = 0
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes",
"params": {"properties": ["title", "playcount", "showtitle", "file", "tvshowid"]},
"id": 1}
data = get_data(payload)
if 'result' in data and "episodes" in data['result']:
if item.strm_path: # If Item is from an episode
filename = filetools.basename(item.strm_path)
head, tail = filetools.split(filetools.split(item.strm_path)[0])
else: # If Item is from the Series
filename = filetools.basename(item.base_name)
head, tail = filetools.split(filetools.split(item.base_name)[0])
path = filetools.join(tail, filename)
for d in data['result']['episodes']:
if d['file'].replace("/", "\\").endswith(path.replace("/", "\\")):
# logger.debug("I mark the episode as seen")
episodeid = d['episodeid']
break
if episodeid != 0:
payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": episodeid, "playcount": value}, "id": 1}
if payload_f:
# Mark as seen
data = get_data(payload_f)
# logger.debug(str(data))
if data['result'] != 'OK':
logger.error("ERROR putting content as viewed")
xbmc.sleep(700)
ctl.selectItem(pos)
n, r = execute_sql_kodi(sql)
if r:
sql = 'update files set playCount= {} where idFile= {}'
sql_actions = [sql.format(value, i[0]) for i in r]
conn = sqlite3.connect(get_file_db())
cursor = conn.cursor()
for sql in sql_actions:
if type(sql) == list:
cursor.executemany(sql)
else:
cursor.execute(sql)
conn.commit()
conn.close()
platformtools.itemlist_refresh()
def mark_season_as_watched_on_kodi(item, value=1):
"""
@@ -359,20 +311,16 @@ def mark_season_as_watched_on_kodi(item, value=1):
if item.contentSeason > -1:
request_season = ' and c12= %s' % item.contentSeason
tvshows_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"))
item_path1 = "%" + item.base_name.replace("\\\\", "\\").replace(tvshows_path, "")
if item_path1[:-1] != "\\":
item_path1 += "\\"
item_path2 = item_path1.replace("\\", "/")
tvshows_path = filetools.join(config.config.get_videolibrary_config_path(), config.get_setting("folder_tvshows"))
sql = 'update files set playCount= %s where idFile in (select idfile from episode_view where (strPath like "%s" or strPath like "%s")%s)' % (value, item_path1, item_path2, request_season)
sql = 'update files set playCount= %s where idFile in (select idfile from episode_view where (strPath like "%s" or strPath like "%s")%s)' % (value, request_season)
execute_sql_kodi(sql)
def set_watched_on_kod(data):
# support.dbg()
from specials import videolibrary
from core.videolibrarytools import videolibrarydb
# support.dbg()
data = jsontools.load(data)
Type = data.get('item', {}).get('type','')
@@ -387,17 +335,17 @@ def set_watched_on_kod(data):
_id = scrapertools.find_single_match(records[0][0], r'\[([^\]]+)')
episode = scrapertools.find_single_match(records[0][0], r'(\d+x\d+)')
season = episode.split('x')[0]
episodes = videolibrarydb['episodes'].get(_id, {})
episodes = videolibrarydb['episode'].get(_id, {})
item = episodes.get(episode, {}).get('item', None)
if Type in ['season']:
elif Type in ['season']:
sql = 'select season, strPath from {}_view where (id{} like "{}")'.format(Type, Type.capitalize(), ID)
n, records = execute_sql_kodi(sql)
if records:
logger.debug('RECORDS' , records)
_id = scrapertools.find_single_match(records[0][1], r'\[([^\]]+)')
season = records[0][0]
seasons = videolibrarydb['seasons'].get(_id, {})
seasons = videolibrarydb['season'].get(_id, {})
item = seasons.get(season, None)
# item.all_ep
@@ -432,6 +380,7 @@ def set_watched_on_kod(data):
def mark_content_as_watched_on_kod(path):
from specials import videolibrary
from core import videolibrarytools
"""
mark the entire series or movie as viewed or unseen in the Alpha Video Library based on their status in the Kodi Video Library
@@ -446,7 +395,7 @@ def mark_content_as_watched_on_kod(path):
VIDEOLIBRARY_PATH = config.get_videolibrary_config_path()
if not VIDEOLIBRARY_PATH:
return
# set_watched_on_kod
# We can only mark the content as a view in the Kodi database if the database is local, in case of sharing database this functionality will not work
# if config.get_setting("db_mode", "videolibrary"):
# return

View File

@@ -709,11 +709,11 @@ msgid "Do you want to report the issue?\n(Be sure you follow all steps and give
msgstr ""
msgctxt "#60016"
msgid "Segna film come non visto"
msgid "Mark movie as not watched"
msgstr ""
msgctxt "#60017"
msgid "Mark movie as not watched"
msgid "Mark movie as watched"
msgstr ""
msgctxt "#60018"

View File

@@ -708,11 +708,11 @@ msgid "Do you want to report the issue?\n(Be sure you follow all steps and give
msgstr "Vuoi fare una segnalazione agli sviluppatori?\n(Assicurati di seguire bene tutti i punti e dai una spiegazione chiara ed esaustiva di quanto accaduto)"
msgctxt "#60016"
msgid "Segna film come non visto"
msgid "Mark movie as not watched"
msgstr "Segna film come non visto"
msgctxt "#60017"
msgid "Mark movie as not watched"
msgid "Mark movie as watched"
msgstr "Segna film come visto"
msgctxt "#60018"

View File

@@ -77,13 +77,25 @@ def list_movies(item, silent=False):
# if key not in ids:
# del videolibrarydb['movie'][key]
# else:
item = value['item']
item.context = [{'title':config.get_localized_string(70084),'channel':'videolibrary', 'action':'delete'}]
if len(item.lang_list) > 1:
item.context += [{"title": config.get_localized_string(70246),
it = value['item']
it.context = [{'title':config.get_localized_string(70084),'channel':'videolibrary', 'action':'delete'}]
if len(it.lang_list) > 1:
it.context += [{"title": config.get_localized_string(70246),
"action": "prefered_lang",
"channel": "videolibrary"}]
itemlist.append(item)
watched = it.infoLabels.get("playcount", 0)
if watched > 0:
title = config.get_localized_string(60016)
value = 0
else:
title = config.get_localized_string(60017)
value = 1
it.context += [{"title": title,
"action": "mark_content_as_watched",
"channel": "videolibrary",
"playcount": value}]
itemlist.append(it)
if silent == False: return sorted(itemlist, key=lambda it: it.title.lower())
else: return
@@ -128,22 +140,21 @@ def list_tvshows(item):
series = dict(videolibrarydb['tvshow'])
videolibrarydb.close()
for key, value in series.items():
def sub_thread(key, value):
it = value['item']
it.contentType = 'tvshow'
item = value['item']
item.contentType = 'tvshow'
it.context = [{'title':config.get_localized_string(70085),'channel':'videolibrary', 'action':'delete'}]
item.context = [{'title':config.get_localized_string(70085),'channel':'videolibrary', 'action':'delete'}]
if len(item.lang_list) > 1:
item.context += [{"title": config.get_localized_string(70246),
if len(it.lang_list) > 1:
it.context += [{"title": config.get_localized_string(70246),
"action": "prefered_lang",
"channel": "videolibrary"}]
if len(value['channels'].keys()) > 1:
item.context += [{"title": config.get_localized_string(70837),
it.context += [{"title": config.get_localized_string(70837),
"action": "disable_channels",
"channel": "videolibrary"}]
watched = item.infoLabels.get("playcount", 0)
watched = it.infoLabels.get("playcount", 0)
if watched > 0:
title = config.get_localized_string(60020)
value = 0
@@ -151,38 +162,42 @@ def list_tvshows(item):
title = config.get_localized_string(60021)
value = 1
item.context += [{"title": title,
it.context += [{"title": title,
"action": "mark_content_as_watched",
"channel": "videolibrary",
"playcount": value,
"videolibrary_id": item.videolibrary_id}]
if not item.active:
item.title = '{} {}'.format(item.title, support.typo('','bullet bold'))
"playcount": value}]
if not it.active:
it.title = '{} {}'.format(it.title, support.typo('','bullet bold'))
title = config.get_localized_string(60023)
else:
title = config.get_localized_string(60022)
item.context += [{"title": title,
"action": "set_active",
"channel": "videolibrary",
"playcount": value,
"videolibrary_id": item.videolibrary_id}]
item.context += [{"title": 'Poster',
it.context += [{"title": title,
"action": "set_active",
"channel": "videolibrary",
"playcount": value}]
it.context += [{"title": config.get_localized_string(70269),
"action": "update_videolibrary",
"channel": "videolibrary"}]
it.context += [{"title": 'Poster',
"action": "change_poster",
"channel": "videolibrary",
"playcount": value,
"videolibrary_id": item.videolibrary_id}]
item.context += [{"title": 'fanart',
"playcount": value}]
it.context += [{"title": 'fanart',
"action": "change_fanart",
"channel": "videolibrary",
"playcount": value,
"videolibrary_id": item.videolibrary_id}]
"playcount": value}]
return it
itemlist.append(item)
with futures.ThreadPoolExecutor() as executor:
_list = [executor.submit(sub_thread, key, value) for key, value in series.items()]
for res in futures.as_completed(_list):
itemlist.append(res.result())
if itemlist:
itemlist = sorted(itemlist, key=lambda it: it.title.lower())
itemlist += [Item(channel=item.channel, action="update_videolibrary", thumbnail=item.thumbnail,
fanart=item.thumbnail, landscape=item.thumbnail,
title=typo(config.get_localized_string(70269), 'bold color kod'), folder=False)]
return itemlist
@@ -332,12 +347,13 @@ def get_seasons(item):
seasons = videolibrarydb['season'][item.videolibrary_id]
videolibrarydb.close()
# We create one item for each season
for season in seasons.values():
new_item = season
new_item.contentType = 'season'
def sub_thread(season):
it = season
it.contentType = 'season'
#Contextual menu: Mark the season as viewed or not
watched = new_item.infoLabels.get("playcount", 0)
watched = it.infoLabels.get("playcount", 0)
if watched > 0:
title = config.get_localized_string(60028)
value = 0
@@ -345,14 +361,16 @@ def get_seasons(item):
title = config.get_localized_string(60029)
value = 1
new_item.context = [{"title": title,
it.context = [{"title": title,
"action": "mark_content_as_watched",
"channel": "videolibrary",
"playcount": value,
"videolibrary_id": item.videolibrary_id}]
"playcount": value}]
return it
# logger.debug("new_item:\n" + new_item.tostring('\n'))
itemlist.append(new_item)
with futures.ThreadPoolExecutor() as executor:
_list = [executor.submit(sub_thread, season) for season in seasons.values()]
for res in futures.as_completed(_list):
itemlist.append(res.result())
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: int(it.contentSeason))
@@ -360,9 +378,9 @@ def get_seasons(item):
return get_episodes(itemlist[0])
if config.get_setting("show_all_seasons", "videolibrary"):
new_item = item.clone(action="get_episodes", title=config.get_localized_string(60030), all=True)
new_item.infoLabels["playcount"] = 0
itemlist.insert(0, new_item)
it = item.clone(action="get_episodes", title=config.get_localized_string(60030), all=True)
it.infoLabels["playcount"] = 0
itemlist.insert(0, it)
add_download_items(item, itemlist)
return itemlist
@@ -375,7 +393,7 @@ def get_episodes(item):
episodes = videolibrarydb['episode'][item.videolibrary_id]
videolibrarydb.close()
for title, ep in episodes.items():
def sub_thread(title, ep):
it = ep['item']
if it.contentSeason == item.contentSeason or item.all:
@@ -394,10 +412,15 @@ def get_episodes(item):
it.context = [{"title": title,
"action": "mark_content_as_watched",
"channel": "videolibrary",
"playcount": value,
'allep': True,
"videolibrary_id": item.videolibrary_id}]
itemlist.append(it)
"playcount": value}]
return it
return
with futures.ThreadPoolExecutor() as executor:
_list = [executor.submit(sub_thread, title, ep) for title, ep in episodes.items()]
for res in futures.as_completed(_list):
if res.result(): itemlist.append(res.result())
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
add_download_items(item, itemlist)
@@ -541,24 +564,8 @@ def play(item):
def update_videolibrary(item=''):
logger.debug()
# Update active series by overwriting
# import service
# service.check_for_update(overwrite=True)
check_for_update(item)
# Delete movie folders that do not contain strm file
# for raiz, subcarpetas, ficheros in filetools.walk(videolibrarytools.MOVIES_PATH):
# strm = False
# for f in ficheros:
# if f.endswith(".strm"):
# strm = True
# break
# if ficheros and not strm:
# logger.debug("Deleting deleted movie folder: %s" % raiz)
# filetools.rmdirtree(raiz)
def check_for_update(ITEM = None):
logger.debug("Update Series...")
@@ -577,14 +584,14 @@ def check_for_update(ITEM = None):
p_dialog.update(0, '')
show_list = []
if ITEM:
if ITEM and ITEM.videolibrary_id:
show = videolibrarydb['tvshow'][ITEM.videolibrary_id]
videolibrarydb.close()
for s in show['channels'].values():
show_list += s
else:
shows = dict(videolibrarydb['tvshow']).values()
videolibrarydb.close()
for show in shows:
if show['item'].active:
@@ -600,12 +607,12 @@ def check_for_update(ITEM = None):
try: channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel])
except: channel = __import__('specials.%s' % item.channel, fromlist=["specials.%s" % item.channel])
itemlist = getattr(channel, item.action)(item)
videolibrarytools.save_tvshow(item, itemlist, silent=True)
videolibrarytools.save_tvshow(item, itemlist)
p_dialog.close()
except:
p_dialog.close()
logger.error(traceback.format_exc())
videolibrarydb.close()
if ITEM:
update_when_finished = set_active_tvshow(show)
else:
@@ -754,204 +761,148 @@ def delete_videolibrary(item):
platformtools.dialog_notification(config.get_localized_string(20000), config.get_localized_string(80039), time=5000, sound=False)
# context menu methods
def update_tvshow(item):
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
# def add_local_episodes(item):
# logger.debug()
heading = config.get_localized_string(60037)
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading)
p_dialog.update(0, heading, item.contentSerieName)
# done, local_episodes_path = videolibrarytools.config_local_episodes_path(item.path, item, silent=True)
# if done < 0:
# logger.debug("An issue has occurred while configuring local episodes")
# elif local_episodes_path:
# nfo_path = filetools.join(item.path, "tvshow.nfo")
# head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
# item_nfo.local_episodes_path = local_episodes_path
# if not item_nfo.active:
# item_nfo.active = 1
# filetools.write(nfo_path, head_nfo + item_nfo.tojson())
import service
if service.update(item.path, p_dialog, 0, 100, item, False) and config.is_xbmc() and config.get_setting("videolibrary_kodi"):
from platformcode import xbmc_videolibrary
xbmc_videolibrary.update(folder=filetools.basename(item.path))
# update_tvshow(item)
p_dialog.close()
# check if the TV show is ended or has been canceled and ask the user to remove it from the video library update
nfo_path = filetools.join(item.path, "tvshow.nfo")
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
if item.active and not item_nfo.active:
# if not platformtools.dialog_yesno(config.get_localized_string(60037).replace('...',''), config.get_localized_string(70268) % item.contentSerieName):
item_nfo.active = 1
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
platformtools.itemlist_refresh()
# platformtools.itemlist_refresh()
def add_local_episodes(item):
logger.debug()
# def remove_local_episodes(item):
# logger.debug()
done, local_episodes_path = videolibrarytools.config_local_episodes_path(item.path, item, silent=True)
if done < 0:
logger.debug("An issue has occurred while configuring local episodes")
elif local_episodes_path:
nfo_path = filetools.join(item.path, "tvshow.nfo")
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
item_nfo.local_episodes_path = local_episodes_path
if not item_nfo.active:
item_nfo.active = 1
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
# nfo_path = filetools.join(item.path, "tvshow.nfo")
# head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
update_tvshow(item)
# for season_episode in item_nfo.local_episodes_list:
# filetools.remove(filetools.join(item.path, season_episode + '.strm'))
platformtools.itemlist_refresh()
# item_nfo.local_episodes_list = []
# item_nfo.local_episodes_path = ''
# filetools.write(nfo_path, head_nfo + item_nfo.tojson())
# update_tvshow(item)
def remove_local_episodes(item):
logger.debug()
nfo_path = filetools.join(item.path, "tvshow.nfo")
head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
for season_episode in item_nfo.local_episodes_list:
filetools.remove(filetools.join(item.path, season_episode + '.strm'))
item_nfo.local_episodes_list = []
item_nfo.local_episodes_path = ''
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
update_tvshow(item)
platformtools.itemlist_refresh()
def verify_playcount_series(item, path):
logger.debug()
"""
This method reviews and repairs the PlayCount of a series that has become out of sync with the actual list of episodes in its folder. Entries for missing episodes, seasons, or series are created with the "not seen" mark. Later it is sent to verify the counters of Seasons and Series
On return it sends status of True if updated or False if not, usually by mistake. With this status, the caller can update the status of the "verify_playcount" option in "videolibrary.py". The intention of this method is to give a pass that repairs all the errors and then deactivate it. It can be reactivated in the Alpha Video Library menu.
"""
#logger.debug("item:\n" + item.tostring('\n'))
# If you have never done verification, we force it
estado = config.get_setting("verify_playcount", "videolibrary")
if not estado or estado == False:
estado = True # If you have never done verification, we force it
else:
estado = False
if item.contentType == 'movie': # This is only for Series
return (item, False)
if filetools.exists(path):
nfo_path = filetools.join(path, "tvshow.nfo")
head_nfo, it = videolibrarytools.read_nfo(nfo_path) # We get the .nfo of the Series
if not hasattr(it, 'library_playcounts') or not it.library_playcounts: # If the .nfo does not have library_playcounts we will create it for you
logger.error('** It does not have PlayCount')
it.library_playcounts = {}
# We get the archives of the episodes
raiz, carpetas_series, ficheros = next(filetools.walk(path))
# Create an item in the list for each strm found
estado_update = False
for i in ficheros:
if i.endswith('.strm'):
season_episode = scrapertools.get_season_and_episode(i)
if not season_episode:
# The file does not include the season and episode number
continue
season, episode = season_episode.split("x")
if season_episode not in it.library_playcounts: # The episode is not included
it.library_playcounts.update({season_episode: 0}) # update the .nfo playCount
estado_update = True # We mark that we have updated something
if 'season %s' % season not in it.library_playcounts: # Season is not included
it.library_playcounts.update({'season %s' % season: 0}) # update the .nfo playCount
estado_update = True # We mark that we have updated something
if it.contentSerieName not in it.library_playcounts: # Series not included
it.library_playcounts.update({item.contentSerieName: 0}) # update the .nfo playCount
estado_update = True # We mark that we have updated something
if estado_update:
logger.error('** Update status: ' + str(estado) + ' / PlayCount: ' + str(it.library_playcounts))
estado = estado_update
# it is verified that if all the episodes of a season are marked, tb the season is marked
for key, value in it.library_playcounts.items():
if key.startswith("season"):
season = scrapertools.find_single_match(key, r'season (\d+)') # We obtain in no. seasonal
it = check_season_playcount(it, season)
# We save the changes to item.nfo
if filetools.write(nfo_path, head_nfo + it.tojson()):
return (it, estado)
return (item, False)
# platformtools.itemlist_refresh()
def mark_content_as_watched(item):
logger.debug()
class mark_as_watched(object):
def __init__(self, *args, **kwargs):
self.item = kwargs.get('item')
self.s = self.item.contentSeason
self.e = self.item.contentEpisodeNumber
self.playcount = self.item.playcount
if not item.videolibrary_id:
for code in item.infoLabels['code']:
if code and code != 'None':
break
item.videolibrary_id=code
if item.contentType == 'episode':
episodes = videolibrarydb['episode'][item.videolibrary_id]
episodes['{}x{}'.format(item.contentSeason, str(item.contentEpisodeNumber).zfill(2))]['item'].infoLabels['playcount'] = item.playcount
videolibrarydb['episode'][item.videolibrary_id] = episodes
videolibrarydb.close()
if self.item.contentType == 'movie':
self.movie = videolibrarydb['movie'][self.item.videolibrary_id]
else:
self.tvshow = videolibrarydb['tvshow'][self.item.videolibrary_id]
self.seasons = videolibrarydb['season'][self.item.videolibrary_id]
self.episodes = videolibrarydb['episode'][self.item.videolibrary_id]
season_episodes = [ep for ep in episodes.values() if ep['item'].contentSeason == item.contentSeason]
watched = [ep for ep in season_episodes if ep['item'].infoLabels['playcount'] > 0]
if len(watched) == len(season_episodes):
item.playcount = 1
else:
item.playcount = 0
mark_season_as_watched(item)
getattr(self, 'mark_' + self.item.contentType)()
elif item.contentType == 'season':
mark_season_as_watched(item)
videolibrarydb.close()
# support.dbg()
if config.is_xbmc() and not self.item.not_update:
from platformcode import xbmc_videolibrary
xbmc_videolibrary.mark_content_as_watched_on_kodi(self.item, self.playcount)
else:
platformtools.itemlist_refresh()
else:
content = videolibrarydb[item.contentType][item.videolibrary_id]
content['item'].infoLabels['playcount'] = item.playcount
videolibrarydb[item.contentType][item.videolibrary_id] = content
seasons = videolibrarydb['season'][item.videolibrary_id]
videolibrarydb.close()
item.all_ep = True
if item.contentType == 'tvshow':
for season in seasons.keys():
item.contentSeason = season
mark_season_as_watched(item)
def mark_episode(self):
current_playcount = self.episodes['{:d}x{:02d}'.format(self.s, self.e)]['item'].infoLabels['playcount']
if config.is_xbmc() and not item.not_update:
from platformcode import xbmc_videolibrary
xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount)
if self.playcount > 0:
self.episodes['{:d}x{:02d}'.format(self.s, self.e)]['item'].infoLabels['playcount'] += self.playcount
else:
self.episodes['{:d}x{:02d}'.format(self.s, self.e)]['item'].infoLabels['playcount'] = 0
videolibrarydb['episode'][self.item.videolibrary_id] = self.episodes
def mark_season_as_watched(item):
logger.debug()
if current_playcount == 0 or self.playcount == 0:
self.check_playcount('episode')
seasons = videolibrarydb['season'][item.videolibrary_id]
seasons[item.contentSeason].infoLabels['playcount'] = item.playcount
videolibrarydb['season'][item.videolibrary_id] = seasons
episodes = videolibrarydb['episode'][item.videolibrary_id]
videolibrarydb.close()
def mark_season(self):
current_playcount = self.seasons[self.s].infoLabels['playcount']
for n, ep in episodes.items():
if ep['item'].contentSeason == item.contentSeason:
episodes[n]['item'].infoLabels['playcount'] = item.playcount
if self.playcount > 0:
self.seasons[self.s].infoLabels['playcount'] += self.playcount
else:
self.seasons[self.s].infoLabels['playcount'] = 0
videolibrarydb['episode'][item.videolibrary_id] = episodes
videolibrarydb.close()
videolibrarydb['season'][self.item.videolibrary_id] = self.seasons
self.mark_all('episodes')
watched = True
for season in seasons.values():
if season.infoLabels['playcount'] != item.playcount:
watched = False
if current_playcount == 0 or self.playcount == 0:
self.check_playcount('season')
if watched or item.playcount == 0:
tvshow = videolibrarydb['tvshow'][item.videolibrary_id]
it = videolibrarydb['tvshow'][item.videolibrary_id]['item']
it.infoLabels['playcount'] = item.playcount
tvshow['item'] = it
videolibrarydb['tvshow'][item.videolibrary_id] = tvshow
videolibrarydb.close()
def mark_tvshow(self):
if self.playcount > 0:
self.tvshow['item'].infoLabels['playcount'] += self.playcount
else:
self.tvshow['item'].infoLabels['playcount'] = 0
videolibrarydb['tvshow'][self.item.videolibrary_id] = self.tvshow
self.mark_all('seasons')
def mark_movie(self):
if self.playcount:
self.movie['item'].infoLabels['playcount'] += self.playcount
else:
self.movie['item'].infoLabels['playcount'] = 0
videolibrarydb['movie'][self.item.videolibrary_id] = self.movie
def check_playcount(self, _type):
tv_playcount = 0
season_playcount = 0
if _type == 'episode':
episodes = [e for e in self.episodes.values() if e['item'].contentSeason == self.s]
watched = [e for e in episodes if e['item'].infoLabels['playcount'] > 0]
all_watched = [e for e in self.episodes.values() if e['item'].infoLabels['playcount'] > 0]
if len(all_watched) == len(self.episodes):
tv_playcount = self.playcount
if len(watched) == len(episodes):
season_playcount = self.playcount
self.tvshow['item'].infoLabels['playcount'] = tv_playcount
self.seasons[self.s].infoLabels['playcount'] = season_playcount
videolibrarydb['season'][self.item.videolibrary_id] = self.seasons
else:
watched = [s for s in self.seasons.values() if s.infoLabels['playcount'] > 0]
if len(watched) == len(self.seasons):
tv_playcount = self.playcount
self.tvshow['item'].infoLabels['playcount'] = tv_playcount
videolibrarydb['tvshow'][self.item.videolibrary_id] = self.tvshow
def mark_all(self, _type):
episodes = [e for e in self.episodes.values() if e['item'].contentSeason == self.s]
if _type == 'episodes':
for n, ep in self.episodes.items():
self.episodes[n]['item'].infoLabels['playcount'] = self.playcount
# self.check_playcount('season')
else:
for n, season in self.seasons.items():
self.seasons[n].infoLabels['playcount'] = self.playcount
for n, ep in self.episodes.items():
self.episodes[n]['item'].infoLabels['playcount'] = self.playcount
videolibrarydb['season'][self.item.videolibrary_id] = self.seasons
videolibrarydb['episode'][self.item.videolibrary_id] = self.episodes
# support.dbg()
mark_as_watched(item=item)
def mark_tvshow_as_updatable(item, silent=False):
@@ -1036,52 +987,6 @@ def delete(item):
videolibrarydb.close()
def check_season_playcount(item, season):
logger.debug()
if season:
episodios_temporada = 0
episodios_vistos_temporada = 0
for key, value in item.library_playcounts.items():
if key.startswith("%sx" % season):
episodios_temporada += 1
if value > 0:
episodios_vistos_temporada += 1
if episodios_temporada == episodios_vistos_temporada:
# it is verified that if all the seasons are seen, the series is marked as view
item.library_playcounts.update({"season %s" % season: 1})
else:
# it is verified that if all the seasons are seen, the series is marked as view
item.library_playcounts.update({"season %s" % season: 0})
return check_tvshow_playcount(item, season)
def check_tvshow_playcount(item, season):
logger.debug()
if season:
temporadas_serie = 0
temporadas_vistas_serie = 0
for key, value in item.library_playcounts.items():
if key.startswith("season" ):
temporadas_serie += 1
if value > 0:
temporadas_vistas_serie += 1
if temporadas_serie == temporadas_vistas_serie:
item.library_playcounts.update({item.title: 1})
else:
item.library_playcounts.update({item.title: 0})
else:
playcount = item.library_playcounts.get(item.title, 0)
item.library_playcounts.update({item.title: playcount})
return item
def add_download_items(item, itemlist):
if config.get_setting('downloadenabled'):
localOnly = True
@@ -1131,6 +1036,7 @@ def prefered_lang(item):
videolibrarydb[item.contentType][item.videolibrary_id] = tempdb
videolibrarydb.close()
def disable_channels(item):
from core import channeltools
tempdb = videolibrarydb[item.contentType][item.videolibrary_id]
@@ -1145,6 +1051,7 @@ def disable_channels(item):
videolibrarydb[item.contentType][item.videolibrary_id] = tempdb
videolibrarydb.close()
def get_host(item , channel=None):
if item.url.startswith('//'): item.url = 'https:' + item.url
if not item.url.startswith('/') and not httptools.downloadpage(item.url, only_headers=True).success:
@@ -1160,6 +1067,7 @@ def get_host(item , channel=None):
return item
def set_active(item):
show = videolibrarydb['tvshow'][item.videolibrary_id]
videolibrarydb.close()
@@ -1168,6 +1076,7 @@ def set_active(item):
videolibrarydb.close()
platformtools.itemlist_refresh()
def change_poster(item):
import xbmcgui
video = videolibrarydb[item.contentType][item.videolibrary_id]
@@ -1188,6 +1097,7 @@ def change_poster(item):
videolibrarydb.close()
platformtools.itemlist_refresh()
def change_fanart(item):
import xbmcgui
video = videolibrarydb[item.contentType][item.videolibrary_id]

View File

@@ -1,104 +1,40 @@
# -*- coding: utf-8 -*-
import xbmc, sys, xbmcgui, os, xbmcvfs, traceback
from platformcode import config, logger
# from specials import videolibrary
import os, sys, xbmc
try:
import xbmcvfs
xbmc.translatePath = xbmcvfs.translatePath
xbmc.validatePath = xbmcvfs.validatePath
xbmc.makeLegalFilename = xbmcvfs.makeLegalFilename
except:
pass
from platformcode import config, logger
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core.item import Item
from lib.sambatools import libsmb as samba
from core import scrapertools
from core.videolibrarydb import videolibrarydb
from platformcode.xbmc_videolibrary import execute_sql_kodi
from specials.videolibrary import update_videolibrary
def exists(path, silent=False, vfs=True):
path = xbmc.translatePath(path)
try:
if vfs:
result = bool(xbmcvfs.exists(path))
if not result and not path.endswith('/') and not path.endswith('\\'):
result = bool(xbmcvfs.exists(join(path, ' ').rstrip()))
return result
elif path.lower().startswith("smb://"):
return samba.exists(path)
else:
return os.path.exists(path)
except:
logger.error("ERROR when checking the path: %s" % path)
if not silent:
logger.error(traceback.format_exc())
return False
def join(*paths):
list_path = []
if paths[0].startswith("/"):
list_path.append("")
for path in paths:
if path:
list_path += path.replace("\\", "/").strip("/").split("/")
if scrapertools.find_single_match(paths[0], r'(^\w+:\/\/)'):
return str("/".join(list_path))
else:
return str(os.sep.join(list_path))
def search_paths(Id):
records = execute_sql('SELECT idPath FROM tvshowlinkpath WHERE idShow LIKE "%s"' % Id)
if len(records) >= 1:
for record in records:
path_records = execute_sql('SELECT strPath FROM path WHERE idPath LIKE "%s"' % record[0])
for path in path_records:
if config.get_setting('videolibrarypath') in path[0] and exists(join(path[0], 'tvshow.nfo')):
return path[0]
def search_id(Id):
n, records = execute_sql_kodi('SELECT idPath FROM tvshowlinkpath WHERE idShow= {}'.format(Id))
if records:
n, records = execute_sql_kodi('SELECT strPath FROM path WHERE idPath= "{}"'.format(records[0][0]))
if records:
return scrapertools.find_single_match(records[0][0], r'\[(tt[^\]]+)')
return ''
def execute_sql(sql):
logger.debug()
from platformcode.xbmc_videolibrary import get_file_db
file_db = get_file_db()
records = None
if file_db:
logger.debug("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.debug("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
records = cursor.fetchall()
if sql.lower().startswith("select"):
if len(records) == 1 and records[0][0] is None:
records = []
conn.close()
logger.debug("Query executed. Records: %s" % len(records))
except:
logger.error("Error executing sql query")
if conn:
conn.close()
else:
logger.debug("Database not found")
return records
if __name__ == '__main__':
path = search_paths(sys.listitem.getVideoInfoTag().getDbId())
if path:
item = Item(action="update_tvshow", channel="videolibrary", path=path)
# Why? I think it is not necessary, just commented
# item.tourl()
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")")
else:
dialog = xbmcgui.Dialog()
title = sys.listitem.getVideoInfoTag().getTitle()
if dialog.yesno(title, config.get_localized_string(70817) % title, nolabel=config.get_localized_string(70170), yeslabel=config.get_localized_string(30022)):
item = Item(action="new_search", channel="search", mode="tvshow", search_text=sys.listitem.getVideoInfoTag().getTitle())
xbmc.executebuiltin("ActivateWindow(10025,plugin://plugin.video.kod/?" + item.tourl() + ")")
videolibrary_id = search_id(sys.listitem.getVideoInfoTag().getDbId())
if videolibrary_id:
tvshows_ids = list(videolibrarydb['tvshow'].keys())
videolibrarydb.close()
if videolibrary_id in tvshows_ids:
item = Item(videolibrary_id=videolibrary_id)
update_videolibrary(item)