mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 10:16:11 +00:00
Prep subfolders for dynamic
Support homevideos for now
This commit is contained in:
parent
0f38ab9e3d
commit
59ce94066e
5 changed files with 250 additions and 50 deletions
|
@ -813,3 +813,27 @@ msgstr ""
|
|||
msgctxt "#33165"
|
||||
msgid "Failed to create backup"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33166"
|
||||
msgid "(dynamic)"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33167"
|
||||
msgid "Recently added"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33168"
|
||||
msgid "Favourites"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33169"
|
||||
msgid "In Progress"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33170"
|
||||
msgid "Unwatched"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#33171"
|
||||
msgid "A-Z"
|
||||
msgstr ""
|
||||
|
|
|
@ -80,7 +80,7 @@ def items(handler="", action="GET", params=None, json=None):
|
|||
return _get("Items%s" % handler, params)
|
||||
|
||||
def user_items(handler="", params=None):
|
||||
return users("/Items%s" % handler, params)
|
||||
return users("/Items%s" % handler, params=params)
|
||||
|
||||
def shows(handler, params):
|
||||
return _get("Shows%s" % handler, params)
|
||||
|
@ -143,11 +143,13 @@ def get_suggestion(media="Movie,Episode", limit=1):
|
|||
'Limit': limit
|
||||
})
|
||||
|
||||
def get_recently_added(media=None, limit=20):
|
||||
def get_recently_added(media=None, parent_id=None, limit=20):
|
||||
return user_items("/Latest", {
|
||||
'Limit': limit,
|
||||
'UserId': "{UserId}",
|
||||
'IncludeItemTypes': media
|
||||
'IncludeItemTypes': media,
|
||||
'ParentId': parent_id,
|
||||
'Fields': info()
|
||||
})
|
||||
|
||||
def get_next(index=None, limit=1):
|
||||
|
@ -157,6 +159,30 @@ def get_next(index=None, limit=1):
|
|||
'StartIndex': None if index is None else int(index)
|
||||
})
|
||||
|
||||
def get_genres(parent_id=None):
|
||||
return _get("Genres", {
|
||||
'ParentId': parent_id,
|
||||
'UserId': "{UserId}",
|
||||
'Fields': info()
|
||||
})
|
||||
|
||||
def get_recommendation(parent_id=None, limit=20):
|
||||
return _get("Movies/Recommendations", {
|
||||
'ParentId': parent_id,
|
||||
'UserId': "{UserId}",
|
||||
'Fields': info(),
|
||||
'Limit': limit
|
||||
})
|
||||
|
||||
def get_items_by_letter(parent_id=None, media=None, letter=None):
|
||||
return user_items(params={
|
||||
'ParentId': parent_id,
|
||||
'NameStartsWith': letter,
|
||||
'Fields': info(),
|
||||
'Recursive': True,
|
||||
'IncludeItemTypes': media
|
||||
})
|
||||
|
||||
def get_intros(item_id):
|
||||
return user_items("/%s/Intros" % item_id)
|
||||
|
||||
|
@ -201,7 +227,8 @@ def get_plugins():
|
|||
def get_seasons(show_id):
|
||||
return shows("/%s/Seasons" % show_id, params={
|
||||
'UserId': "{UserId}",
|
||||
'EnableImages': True
|
||||
'EnableImages': True,
|
||||
'Fields': info()
|
||||
})
|
||||
|
||||
def get_date_modified(date, parent_id, media=None):
|
||||
|
|
|
@ -145,6 +145,7 @@ def listing():
|
|||
context = []
|
||||
|
||||
if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id not in whitelist:
|
||||
label = "%s %s" % (label, _(33166))
|
||||
context.append((_(33123), "RunPlugin(plugin://plugin.video.emby/?mode=synclib&id=%s)" % view_id))
|
||||
|
||||
if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id in whitelist:
|
||||
|
@ -228,6 +229,14 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
|
||||
return
|
||||
|
||||
folder = folder.lower() if folder else None
|
||||
|
||||
if folder is None and media in ('homevideos'):
|
||||
return browse_subfolders(media, view_id, server_id)
|
||||
|
||||
if folder and folder == 'firstletter':
|
||||
return browse_letters(media, view_id, server_id)
|
||||
|
||||
if view_id:
|
||||
|
||||
view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
|
||||
|
@ -239,29 +248,54 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
content_type = media
|
||||
elif media in ('homevideos', 'photos'):
|
||||
content_type = "images"
|
||||
elif media in ('books', 'audiobooks'):
|
||||
content_type = "videos"
|
||||
|
||||
if folder == 'FavEpisodes':
|
||||
listing = TheVoid('Browse', {'Media': "Episode", 'ServerId': server_id, 'Limit': 25, 'Filters': ["IsFavorite"]}).get()
|
||||
|
||||
if folder == 'recentlyadded':
|
||||
listing = TheVoid('RecentlyAdded', {'Id': view_id, 'ServerId': server_id}).get()
|
||||
elif folder == 'genres':
|
||||
listing = TheVoid('Genres', {'Id': view_id, 'ServerId': server_id}).get()
|
||||
elif folder == 'unwatched':
|
||||
listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsUnplayed']}).get()
|
||||
elif folder == 'favorite':
|
||||
listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsFavorite']}).get()
|
||||
elif folder == 'inprogress':
|
||||
listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Filters': ['IsResumable']}).get()
|
||||
elif folder == 'boxsets':
|
||||
listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type), 'Recursive': True}).get()
|
||||
elif folder == 'random':
|
||||
listing = TheVoid('Browse', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type),
|
||||
'Sort': "Random", 'Limit': 25, 'Recursive': True}).get()
|
||||
elif (folder or "").startswith('firstletter'):
|
||||
listing = TheVoid('NameStartsWith', {'Id': view_id, 'ServerId': server_id, 'Media': get_media_type(content_type), 'Filters': folder.split('-')[1]}).get()
|
||||
elif folder == 'favepisodes':
|
||||
listing = TheVoid('Browse', {'Media': get_media_type(content_type), 'ServerId': server_id, 'Limit': 25, 'Filters': ['IsFavorite']}).get()
|
||||
elif media == 'homevideos':
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': "Video,Folder,PhotoAlbum,Photo", 'ServerId': server_id, 'Recursive': False}).get()
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': False}).get()
|
||||
elif media == 'movies':
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': "Movie,Boxset", 'ServerId': server_id, 'Recursive': True}).get()
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': True}).get()
|
||||
elif media in ('boxset', 'library'):
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': True}).get()
|
||||
elif media == 'episodes':
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': "Episode", 'ServerId': server_id, 'Recursive': True}).get()
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'Media': get_media_type(content_type), 'ServerId': server_id, 'Recursive': True}).get()
|
||||
elif media == 'boxsets':
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False, 'Filters': ["Boxsets"]}).get()
|
||||
elif media == 'tvshows':
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': True, 'Media': get_media_type(content_type)}).get()
|
||||
elif media == 'seasons':
|
||||
listing = TheVoid('BrowseSeason', {'Id': folder, 'ServerId': server_id}).get()
|
||||
else:
|
||||
listing = TheVoid('Browse', {'Id': folder or view_id, 'ServerId': server_id, 'Recursive': False}).get()
|
||||
|
||||
|
||||
if listing and listing.get('Items'):
|
||||
if listing:
|
||||
|
||||
actions = Actions(server_id)
|
||||
list_li = []
|
||||
listing = listing if type(listing) == list else listing.get('Items', [])
|
||||
|
||||
for item in listing['Items']:
|
||||
for item in listing:
|
||||
|
||||
li = xbmcgui.ListItem()
|
||||
li.setProperty('embyid', item['Id'])
|
||||
|
@ -277,7 +311,7 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
'folder': item['Id'],
|
||||
'server': server_id
|
||||
}
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby", urllib.urlencode(params))
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby/", urllib.urlencode(params))
|
||||
context = []
|
||||
|
||||
if item['Type'] in ('Series', 'Season', 'Playlist'):
|
||||
|
@ -297,7 +331,7 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
'mode': "play",
|
||||
'server': server_id
|
||||
}
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby", urllib.urlencode(params))
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby/", urllib.urlencode(params))
|
||||
li.setProperty('path', path)
|
||||
context = [(_(13412), "RunPlugin(plugin://plugin.video.emby/?mode=playlist&id=%s&server=%s)" % (item['Id'], server_id))]
|
||||
|
||||
|
@ -321,6 +355,55 @@ def browse(media, view_id=None, folder=None, server_id=None):
|
|||
xbmcplugin.setContent(int(sys.argv[1]), content_type)
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
def browse_subfolders(media, view_id, server_id=None):
|
||||
|
||||
''' Display submenus for emby views.
|
||||
'''
|
||||
from views import DYNNODES
|
||||
|
||||
view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
|
||||
xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name'])
|
||||
nodes = DYNNODES[media]
|
||||
|
||||
for node in nodes:
|
||||
|
||||
params = {
|
||||
'id': view_id,
|
||||
'mode': "browse",
|
||||
'type': media,
|
||||
'folder': view_id if node[0] == 'all' else node[0],
|
||||
'server': server_id
|
||||
}
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby/", urllib.urlencode(params))
|
||||
directory(node[1] or view['Name'], path)
|
||||
|
||||
xbmcplugin.setContent(int(sys.argv[1]), 'files')
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
def browse_letters(media, view_id, server_id=None):
|
||||
|
||||
''' Display letters as options.
|
||||
'''
|
||||
letters = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
view = TheVoid('GetItem', {'ServerId': server_id, 'Id': view_id}).get()
|
||||
xbmcplugin.setPluginCategory(int(sys.argv[1]), view['Name'])
|
||||
|
||||
for node in letters:
|
||||
|
||||
params = {
|
||||
'id': view_id,
|
||||
'mode': "browse",
|
||||
'type': media,
|
||||
'folder': 'firstletter-%s' % node,
|
||||
'server': server_id
|
||||
}
|
||||
path = "%s?%s" % ("plugin://plugin.video.emby/", urllib.urlencode(params))
|
||||
directory(node, path)
|
||||
|
||||
xbmcplugin.setContent(int(sys.argv[1]), 'files')
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
def get_folder_type(item):
|
||||
|
||||
media = item['Type']
|
||||
|
@ -338,6 +421,19 @@ def get_folder_type(item):
|
|||
elif media == 'CollectionFolder':
|
||||
return item.get('CollectionType', 'library')
|
||||
|
||||
def get_media_type(media):
|
||||
|
||||
if media == 'movies':
|
||||
return "Movie,BoxSet"
|
||||
elif media == 'homevideos':
|
||||
return "Video,Folder,PhotoAlbum,Photo"
|
||||
elif media == 'episodes':
|
||||
return "Episode"
|
||||
elif media == 'boxsets':
|
||||
return "BoxSet"
|
||||
elif media == 'tvshows':
|
||||
return "Series"
|
||||
|
||||
def get_fanart(item_id, path, server_id=None):
|
||||
|
||||
''' Get extra fanart for listitems. This is called by skinhelper.
|
||||
|
|
|
@ -51,11 +51,12 @@ class Monitor(xbmc.Monitor):
|
|||
if sender == 'plugin.video.emby':
|
||||
method = method.split('.')[1]
|
||||
|
||||
if method not in ('GetItem', 'ReportProgressRequested', 'LoadServer',
|
||||
if method not in ('GetItem', 'ReportProgressRequested', 'LoadServer', 'RandomItems', 'Recommended',
|
||||
'GetServerAddress', 'GetPlaybackInfo', 'Browse', 'GetImages', 'GetToken',
|
||||
'PlayPlaylist', 'Play', 'GetIntros', 'GetAdditionalParts', 'RefreshItem',
|
||||
'PlayPlaylist', 'Play', 'GetIntros', 'GetAdditionalParts', 'RefreshItem', 'Genres',
|
||||
'FavoriteItem', 'DeleteItem', 'AddUser', 'GetSession', 'GetUsers', 'GetThemes',
|
||||
'GetTheme', 'Playstate', 'GeneralCommand', 'GetTranscodeOptions'):
|
||||
'GetTheme', 'Playstate', 'GeneralCommand', 'GetTranscodeOptions', 'RecentlyAdded',
|
||||
'NameStartsWith', 'BrowseSeason'):
|
||||
return
|
||||
|
||||
data = json.loads(data)[0]
|
||||
|
@ -82,68 +83,57 @@ class Monitor(xbmc.Monitor):
|
|||
if method == 'GetItem':
|
||||
|
||||
item = server['api'].get_item(data['Id'])
|
||||
window('emby_%s.json' % data['VoidName'], item)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, item)
|
||||
|
||||
elif method == 'GetAdditionalParts':
|
||||
|
||||
item = server['api'].get_additional_parts(data['Id'])
|
||||
window('emby_%s.json' % data['VoidName'], item)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, item)
|
||||
|
||||
elif method == 'GetIntros':
|
||||
|
||||
item = server['api'].get_intros(data['Id'])
|
||||
window('emby_%s.json' % data['VoidName'], item)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, item)
|
||||
|
||||
elif method == 'GetImages':
|
||||
|
||||
item = server['api'].get_images(data['Id'])
|
||||
window('emby_%s.json' % data['VoidName'], item)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, item)
|
||||
|
||||
elif method == 'GetServerAddress':
|
||||
|
||||
server_address = server['auth/server-address']
|
||||
window('emby_%s.json' % data['VoidName'], server_address)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, server_address)
|
||||
|
||||
elif method == 'GetPlaybackInfo':
|
||||
|
||||
sources = server['api'].get_play_info(data['Id'], data['Profile'])
|
||||
window('emby_%s.json' % data['VoidName'], sources)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, sources)
|
||||
|
||||
elif method == 'GetLiveStream':
|
||||
|
||||
sources = server['api'].get_play_info(data['Id'], data['PlaySessionId'], data['Token'], data['Profile'])
|
||||
window('emby_%s.json' % data['VoidName'], sources)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, sources)
|
||||
|
||||
elif method == 'GetToken':
|
||||
|
||||
token = server['auth/token']
|
||||
window('emby_%s.json' % data['VoidName'], token)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, token)
|
||||
|
||||
elif method == 'GetSession':
|
||||
|
||||
session = server['api'].get_device(self.device_id)
|
||||
window('emby_%s.json' % data['VoidName'], session)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, session)
|
||||
|
||||
elif method == 'GetUsers':
|
||||
|
||||
users = server['api'].get_users(data.get('IsDisabled', True), data.get('IsHidden', True))
|
||||
window('emby_%s.json' % data['VoidName'], users)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, users)
|
||||
|
||||
elif method == 'GetTranscodeOptions':
|
||||
|
||||
result = server['api'].get_transcode_settings()
|
||||
window('emby_%s.json' % data['VoidName'], result)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'GetThemes':
|
||||
|
||||
|
@ -152,23 +142,44 @@ class Monitor(xbmc.Monitor):
|
|||
else:
|
||||
theme = server['api'].get_items_theme_song(data['Id'])
|
||||
|
||||
window('emby_%s.json' % data['VoidName'], theme)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, theme)
|
||||
|
||||
elif method == 'GetTheme':
|
||||
|
||||
theme = server['api'].get_themes(data['Id'])
|
||||
window('emby_%s.json' % data['VoidName'], theme)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, theme)
|
||||
|
||||
elif method == 'Browse':
|
||||
|
||||
result = downloader.get_filtered_section(data.get('Id'), data.get('Media'), data.get('Limit'),
|
||||
data.get('Recursive'), data.get('Sort'), data.get('SortOrder'),
|
||||
data.get('Filters'), data.get('ServerId'))
|
||||
window('emby_%s.json' % data['VoidName'], result)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'BrowseSeason':
|
||||
|
||||
result = server['api'].get_seasons(data['Id'])
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'RecentlyAdded':
|
||||
|
||||
result = server['api'].get_recently_added(data.get('Media'), data.get('Id'), data.get('Limit'))
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'Genres':
|
||||
|
||||
result = server['api'].get_genres(data.get('Id'))
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'NameStartsWith':
|
||||
|
||||
result = server['api'].get_items_by_letter(data.get('Id'), data.get('Media'), data.get('Filters'))
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'Recommended':
|
||||
|
||||
result = server['api'].get_recommendation(data.get('Id'), data.get('Limit'))
|
||||
self.void_responder(data, result)
|
||||
|
||||
elif method == 'RefreshItem':
|
||||
server['api'].refresh_item(data['Id'])
|
||||
|
@ -221,6 +232,11 @@ class Monitor(xbmc.Monitor):
|
|||
elif method == 'VideoLibrary.OnUpdate':
|
||||
on_update(data, server)
|
||||
|
||||
def void_responder(self, data, result):
|
||||
|
||||
window('emby_%s.json' % data['VoidName'], result)
|
||||
LOG.debug("--->[ beacon/emby_%s.json ] sent", data['VoidName'])
|
||||
|
||||
def server_instance(self, server_id=None):
|
||||
|
||||
server = Emby(server_id)
|
||||
|
|
|
@ -47,17 +47,54 @@ NODES = {
|
|||
('recent', _(30256)),
|
||||
('inprogress', _(30257)),
|
||||
('unwatched', _(30258))
|
||||
]
|
||||
}
|
||||
DYNNODES = {
|
||||
'tvshows': [
|
||||
('all', None),
|
||||
('RecentlyAdded', _(30170)),
|
||||
('recentepisodes', _(30175)),
|
||||
('InProgress', _(30171)),
|
||||
('inprogressepisodes', _(30178)),
|
||||
('nextepisodes', _(30179)),
|
||||
('Genres', _(135)),
|
||||
('Random', _(30229)),
|
||||
('recommended', _(30230))
|
||||
],
|
||||
'movies': [
|
||||
('all', None),
|
||||
('RecentlyAdded', _(30174)),
|
||||
('InProgress', _(30177)),
|
||||
('Boxsets', _(20434)),
|
||||
('Favorite', _(33168)),
|
||||
('FirstLetter', _(33171)),
|
||||
('Genres', _(135)),
|
||||
('Random', _(30229)),
|
||||
#('Recommended', _(30230))
|
||||
],
|
||||
'musicvideos': [
|
||||
('all', None),
|
||||
('RecentlyAdded', _(30256)),
|
||||
('InProgress', _(30257)),
|
||||
('Unwatched', _(30258))
|
||||
],
|
||||
'homevideos': [
|
||||
('all', None),
|
||||
('recent', _(30251)),
|
||||
('recommended', _(30253))
|
||||
('RecentlyAdded', _(33167)),
|
||||
('InProgress', _(33169)),
|
||||
('Favorite', _(33168))
|
||||
],
|
||||
'photos': [
|
||||
'books': [
|
||||
('all', None),
|
||||
('recent', _(30252)),
|
||||
('sets', _(30255)),
|
||||
('recommended', _(30254))
|
||||
('RecentlyAdded', _(33167)),
|
||||
('InProgress', _(33169)),
|
||||
('Favorite', _(33168))
|
||||
],
|
||||
'audiobooks': [
|
||||
('all', None),
|
||||
('RecentlyAdded', _(33167)),
|
||||
('InProgress', _(33169)),
|
||||
('Favorite', _(33168))
|
||||
]
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue