mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 02:06:09 +00:00
Fix episodes for series pooling
This commit is contained in:
parent
8915773706
commit
d54aad726e
9 changed files with 120 additions and 24 deletions
|
@ -140,6 +140,9 @@ class EmbyDatabase():
|
|||
|
||||
return self.cursor.fetchall()
|
||||
|
||||
def remove_media_by_parent_id(self, *args):
|
||||
self.cursor.execute(QU.delete_media_by_parent_id, args)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ get_media_by_id = """ SELECT emby_type
|
|||
FROM emby
|
||||
WHERE emby_id = ?
|
||||
"""
|
||||
get_media_by_parent_id = """ SELECT emby_id, emby_type
|
||||
get_media_by_parent_id = """ SELECT emby_id, emby_type, kodi_id, kodi_fileid
|
||||
FROM emby
|
||||
WHERE emby_parent_id = ?
|
||||
"""
|
||||
|
@ -165,3 +165,6 @@ delete_view = """ DELETE FROM view
|
|||
"""
|
||||
delete_parent_boxset_obj = [ None, "{Movie}"
|
||||
]
|
||||
delete_media_by_parent_id = """ DELETE FROM emby
|
||||
WHERE emby_parent_id = ?
|
||||
"""
|
||||
|
|
|
@ -122,7 +122,31 @@ def get_movies_by_boxset(boxset_id):
|
|||
|
||||
def get_episode_by_show(show_id):
|
||||
|
||||
for items in get_items(show_id, "Episode"):
|
||||
query = {
|
||||
'url': "Shows/%s/Episodes" % show_id,
|
||||
'params': {
|
||||
'EnableUserData': True,
|
||||
'EnableImages': True,
|
||||
'UserId': "{UserId}",
|
||||
'Fields': api.info()
|
||||
}
|
||||
}
|
||||
for items in _get_items(query):
|
||||
yield items
|
||||
|
||||
def get_episode_by_season(show_id, season_id):
|
||||
|
||||
query = {
|
||||
'url': "Shows/%s/Episodes" % show_id,
|
||||
'params': {
|
||||
'SeasonId': season_id,
|
||||
'EnableUserData': True,
|
||||
'EnableImages': True,
|
||||
'UserId': "{UserId}",
|
||||
'Fields': api.info()
|
||||
}
|
||||
}
|
||||
for items in _get_items(query):
|
||||
yield items
|
||||
|
||||
def get_items(parent_id, item_type=None, basic=False, params=None):
|
||||
|
@ -134,7 +158,13 @@ def get_items(parent_id, item_type=None, basic=False, params=None):
|
|||
'IncludeItemTypes': item_type,
|
||||
'SortBy': "SortName",
|
||||
'SortOrder': "Ascending",
|
||||
'Fields': api.basic_info() if basic else api.info()
|
||||
'Fields': api.basic_info() if basic else api.info(),
|
||||
'CollapseBoxSetItems': False,
|
||||
'IsVirtualUnaired': False,
|
||||
'EnableTotalRecordCount': False,
|
||||
'LocationTypes': "FileSystem,Remote,Offline",
|
||||
'IsMissing': False,
|
||||
'Recursive': True
|
||||
}
|
||||
}
|
||||
if params:
|
||||
|
@ -152,7 +182,13 @@ def get_artists(parent_id=None, basic=False, params=None, server_id=None):
|
|||
'ParentId': parent_id,
|
||||
'SortBy': "SortName",
|
||||
'SortOrder': "Ascending",
|
||||
'Fields': api.basic_info() if basic else api.music_info()
|
||||
'Fields': api.basic_info() if basic else api.music_info(),
|
||||
'CollapseBoxSetItems': False,
|
||||
'IsVirtualUnaired': False,
|
||||
'EnableTotalRecordCount': False,
|
||||
'LocationTypes': "FileSystem,Remote,Offline",
|
||||
'IsMissing': False,
|
||||
'Recursive': True
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,14 +223,6 @@ def _get_items(query, server_id=None):
|
|||
|
||||
url = query['url']
|
||||
params = query.get('params', {})
|
||||
params.update({
|
||||
'CollapseBoxSetItems': False,
|
||||
'IsVirtualUnaired': False,
|
||||
'EnableTotalRecordCount': False,
|
||||
'LocationTypes': "FileSystem,Remote,Offline",
|
||||
'IsMissing': False,
|
||||
'Recursive': True
|
||||
})
|
||||
|
||||
try:
|
||||
test_params = dict(params)
|
||||
|
|
|
@ -104,8 +104,9 @@ class FullSync(object):
|
|||
|
||||
''' Select all or whitelist libraries. Provides a new list.
|
||||
'''
|
||||
if not dialog("yesno", heading="{emby}", line1=_(33125), nolabel=_(33126), yeslabel=_(33127)):
|
||||
if dialog("yesno", heading="{emby}", line1=_(33125), nolabel=_(33127), yeslabel=_(33126)):
|
||||
LOG.info("Selected sync later.")
|
||||
|
||||
raise LibraryException('SyncLibraryLater')
|
||||
|
||||
choices = [x['Name'] for x in libraries]
|
||||
|
@ -116,6 +117,7 @@ class FullSync(object):
|
|||
raise LibraryException('LibrarySelection')
|
||||
elif not selection:
|
||||
LOG.info("Nothing was selected.")
|
||||
|
||||
raise LibraryException('SyncLibraryLater')
|
||||
|
||||
if 0 in selection:
|
||||
|
@ -140,6 +142,7 @@ class FullSync(object):
|
|||
''' Main sync process.
|
||||
'''
|
||||
LOG.info("starting sync with %s", self.sync['Libraries'])
|
||||
save_sync(self.sync)
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
for library in list(self.sync['Libraries']):
|
||||
|
@ -254,7 +257,7 @@ class FullSync(object):
|
|||
|
||||
if obj.tvshow(show, library=library) != False:
|
||||
|
||||
for episodes in server.get_items(show['Id'], "Episode"):
|
||||
for episodes in server.get_episode_by_show(show['Id']):
|
||||
for episode in episodes['Items']:
|
||||
|
||||
dialog.update(percent, message="%s/%s" % (message, episode['Name'][:10]))
|
||||
|
|
|
@ -105,9 +105,8 @@ def library_check():
|
|||
def wrapper(self, item, *args, **kwargs):
|
||||
from database import get_sync
|
||||
|
||||
sync = get_sync()
|
||||
|
||||
if kwargs.get('library') is None:
|
||||
sync = get_sync()
|
||||
|
||||
if 'e_item' in kwargs:
|
||||
try:
|
||||
|
@ -131,7 +130,7 @@ def library_check():
|
|||
|
||||
break
|
||||
|
||||
if view['Id'] not in sync['Whitelist']:
|
||||
if view['Id'] not in [x.replace('Mixed:', "") for x in sync['Whitelist'] + sync['Libraries']]:
|
||||
LOG.info("Library %s is not synced. Skip update.", view['Id'])
|
||||
|
||||
return
|
||||
|
|
|
@ -54,7 +54,7 @@ def sources():
|
|||
try:
|
||||
files = xml.find('files')
|
||||
|
||||
if not files:
|
||||
if files is None:
|
||||
files = etree.SubElement(xml, 'files')
|
||||
|
||||
for source in xml.findall('.//path'):
|
||||
|
|
|
@ -230,6 +230,12 @@ class Actions(object):
|
|||
obj['Artwork'] = API.get_all_artwork(objects.map(item, 'Artwork'))
|
||||
self.listitem_photo(obj, listitem, item)
|
||||
|
||||
elif item['Type'] in ('TvChannel'):
|
||||
|
||||
obj = objects.map(item, 'BrowseChannel')
|
||||
obj['Artwork'] = API.get_all_artwork(objects.map(item, 'Artwork'))
|
||||
self.listitem_channel(obj, listitem, item)
|
||||
|
||||
else:
|
||||
obj = objects.map(item, 'BrowseVideo')
|
||||
obj['DbId'] = db_id
|
||||
|
@ -428,6 +434,45 @@ class Actions(object):
|
|||
listitem.setInfo('video', metadata)
|
||||
listitem.setContentLookup(False)
|
||||
|
||||
def listitem_channel(self, obj, listitem, item):
|
||||
|
||||
''' Set listitem for channel content.
|
||||
'''
|
||||
API = api.API(item, self.server)
|
||||
|
||||
obj['Title'] = "%s - %s" % (obj['Title'], obj['ProgramName'])
|
||||
obj['Runtime'] = round(float((obj['Runtime'] or 0) / 10000000.0), 6)
|
||||
obj['PlayCount'] = API.get_playcount(obj['Played'], obj['PlayCount']) or 0
|
||||
obj['Overlay'] = 7 if obj['Played'] else 6
|
||||
obj['Artwork']['Primary'] = obj['Artwork']['Primary'] or "special://home/addons/plugin.video.emby/icon.png"
|
||||
obj['Artwork']['Thumb'] = obj['Artwork']['Thumb'] or "special://home/addons/plugin.video.emby/fanart.jpg"
|
||||
obj['Artwork']['Backdrop'] = obj['Artwork']['Backdrop'] or ["special://home/addons/plugin.video.emby/fanart.jpg"]
|
||||
|
||||
|
||||
metadata = {
|
||||
'title': obj['Title'],
|
||||
'originaltitle': obj['Title'],
|
||||
'playcount': obj['PlayCount'],
|
||||
'overlay': obj['Overlay']
|
||||
}
|
||||
listitem.setIconImage(obj['Artwork']['Thumb'])
|
||||
listitem.setThumbnailImage(obj['Artwork']['Primary'])
|
||||
self.set_artwork(obj['Artwork'], listitem, obj['Type'])
|
||||
|
||||
if obj['Artwork']['Primary']:
|
||||
listitem.setThumbnailImage(obj['Artwork']['Primary'])
|
||||
|
||||
if not obj['Artwork']['Backdrop']:
|
||||
listitem.setArt({'fanart': obj['Artwork']['Primary']})
|
||||
|
||||
listitem.setProperty('totaltime', str(obj['Runtime']))
|
||||
listitem.setProperty('IsPlayable', 'true')
|
||||
listitem.setProperty('IsFolder', 'false')
|
||||
|
||||
listitem.setLabel(obj['Title'])
|
||||
listitem.setInfo('video', metadata)
|
||||
listitem.setContentLookup(False)
|
||||
|
||||
def listitem_music(self, obj, listitem, item):
|
||||
API = api.API(item, self.server)
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
"Video": "MediaSources/0/MediaStreams:?Type=Video",
|
||||
"Container": "MediaSources/0/Container",
|
||||
"Location": "LocationType",
|
||||
"EmbyParentId": "ParentId"
|
||||
"EmbyParentId": "SeriesId,ParentId"
|
||||
},
|
||||
"EpisodeUserData": {
|
||||
"Id": "Id",
|
||||
|
@ -333,5 +333,15 @@
|
|||
"CameraModel": "CameraModel",
|
||||
"ExposureTime": "ExposureTime",
|
||||
"FocalLength": "FocalLength"
|
||||
},
|
||||
"BrowseChannel": {
|
||||
"Id": "Id",
|
||||
"Title": "Name",
|
||||
"Type": "Type",
|
||||
"ProgramName": "CurrentProgram/Name",
|
||||
"Played": "CurrentProgram/UserData/Played",
|
||||
"PlayCount": "CurrentProgram/UserData/PlayCount",
|
||||
"Runtime": "CurrentProgram/RunTimeTicks",
|
||||
"MediaType": "MediaType"
|
||||
}
|
||||
}
|
|
@ -127,7 +127,7 @@ class TVShows(KodiDb):
|
|||
self.add_studios(*values(obj, QU.add_studios_tvshow_obj))
|
||||
self.artwork.add(obj['Artwork'], obj['ShowId'], "tvshow")
|
||||
|
||||
season_episodes = []
|
||||
season_episodes = {}
|
||||
|
||||
for season in self.server['api'].get_seasons(obj['Id'])['Items']:
|
||||
|
||||
|
@ -140,19 +140,18 @@ class TVShows(KodiDb):
|
|||
|
||||
self.emby_db.add_reference(*values(obj, QUEM.add_reference_pool_obj))
|
||||
LOG.info("POOL %s [%s/%s]", obj['Title'], obj['Id'], obj['SeriesId'])
|
||||
season_episodes[season['Id']] = season['SeriesId']
|
||||
|
||||
try:
|
||||
self.emby_db.get_item_by_id(season['Id'])[0]
|
||||
except TypeError:
|
||||
|
||||
self.season(season, obj['ShowId'])
|
||||
season_episodes.append(season['Id'])
|
||||
else:
|
||||
season_id = self.get_season(*values(obj, QU.get_season_special_obj))
|
||||
self.artwork.add(obj['Artwork'], season_id, "season")
|
||||
|
||||
for season in season_episodes:
|
||||
for episodes in server.get_items(season, "Episode"):
|
||||
for episodes in server.get_episode_by_season(season_episodes[season], season):
|
||||
|
||||
for episode in episodes['Items']:
|
||||
self.episode(episode)
|
||||
|
@ -562,6 +561,12 @@ class TVShows(KodiDb):
|
|||
self.remove_show(obj['ParentId'], obj['Id'])
|
||||
self.emby_db.remove_item_by_kodi_id(*values(obj, QUEM.delete_item_by_parent_tvshow_obj))
|
||||
|
||||
# Remove any series pooling episodes
|
||||
for episode in self.emby_db.get_media_by_parent_id(obj['Id']):
|
||||
self.remove_episode(episode[2], episode[3], obj['Id'])
|
||||
else:
|
||||
self.emby_db.remove_media_by_parent_id(obj['Id'])
|
||||
|
||||
self.emby_db.remove_item(*values(obj, QUEM.delete_item_obj))
|
||||
|
||||
def remove_tvshow(self, kodi_id, item_id):
|
||||
|
|
Loading…
Reference in a new issue