mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 02:06:09 +00:00
Merge branch 'master' of https://github.com/MediaBrowser/Emby.Kodi
This commit is contained in:
commit
455b7262fc
6 changed files with 83 additions and 16 deletions
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.emby"
|
<addon id="plugin.video.emby"
|
||||||
name="Emby"
|
name="Emby"
|
||||||
version="2.2.5"
|
version="2.2.7"
|
||||||
provider-name="Emby.media">
|
provider-name="Emby.media">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
<language>en</language>
|
<language>en</language>
|
||||||
<license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
|
<license>GNU GENERAL PUBLIC LICENSE. Version 2, June 1991</license>
|
||||||
<forum></forum>
|
<forum></forum>
|
||||||
<website>http://mediabrowser.tv/</website>
|
<website>http://emby.media/</website>
|
||||||
<source></source>
|
<source></source>
|
||||||
<summary lang="en"></summary>
|
<summary lang="en"></summary>
|
||||||
<description lang="en">Welcome to Emby for Kodi A whole new way to manage and view your media library. The Emby addon for Kodi combines the best of Kodi - ultra smooth navigation, beautiful UIs and playback of any file under the sun, and Emby - the most powerful fully open source multi-client media metadata indexer and server. Emby for Kodi is the absolute best way to enjoy the incredible Kodi playback engine combined with the power of Emby's centralized database. Features: Direct integration with the Kodi library for native Kodi speed Instant synchronization with the Emby server Full support for Movie, TV and Music collections Emby Server direct stream and transcoding support - use Kodi when you are away from home!</description>
|
<description lang="en">Welcome to Emby for Kodi A whole new way to manage and view your media library. The Emby addon for Kodi combines the best of Kodi - ultra smooth navigation, beautiful UIs and playback of any file under the sun, and Emby - the most powerful fully open source multi-client media metadata indexer and server. Emby for Kodi is the absolute best way to enjoy the incredible Kodi playback engine combined with the power of Emby's centralized database. Features: Direct integration with the Kodi library for native Kodi speed Instant synchronization with the Emby server Full support for Movie, TV and Music collections Emby Server direct stream and transcoding support - use Kodi when you are away from home!</description>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
version 2.2.7
|
||||||
|
- Prevent Kodi screensaver during the initial sync
|
||||||
|
|
||||||
|
version 2.2.6
|
||||||
|
- Fix unicode error
|
||||||
|
- Fix grouped folders error
|
||||||
|
|
||||||
version 2.2.5
|
version 2.2.5
|
||||||
- Add generate a new device Id option, found in the add-on settings > advanced.
|
- Add generate a new device Id option, found in the add-on settings > advanced.
|
||||||
- Offer to delete cached thumbnails upon database reset.
|
- Offer to delete cached thumbnails upon database reset.
|
||||||
|
|
|
@ -456,10 +456,10 @@ def BrowseContent(viewname, type="", folderid=""):
|
||||||
if not folderid:
|
if not folderid:
|
||||||
views = emby.getViews(type)
|
views = emby.getViews(type)
|
||||||
for view in views:
|
for view in views:
|
||||||
if view.get("name") == viewname:
|
if view.get("name") == viewname.decode('utf-8'):
|
||||||
folderid = view.get("id")
|
folderid = view.get("id")
|
||||||
|
|
||||||
utils.logMsg("BrowseContent","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname, type, folderid, filter))
|
utils.logMsg("BrowseContent","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname.decode('utf-8'), type.decode('utf-8'), folderid.decode('utf-8'), filter.decode('utf-8')))
|
||||||
#set the correct params for the content type
|
#set the correct params for the content type
|
||||||
#only proceed if we have a folderid
|
#only proceed if we have a folderid
|
||||||
if folderid:
|
if folderid:
|
||||||
|
@ -494,14 +494,13 @@ def BrowseContent(viewname, type="", folderid=""):
|
||||||
li = createListItemFromEmbyItem(item,art,doUtils)
|
li = createListItemFromEmbyItem(item,art,doUtils)
|
||||||
if item.get("IsFolder") == True:
|
if item.get("IsFolder") == True:
|
||||||
#for folders we add an additional browse request, passing the folderId
|
#for folders we add an additional browse request, passing the folderId
|
||||||
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0], viewname, type, item.get("Id"))
|
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), type.decode('utf-8'), item.get("Id").decode('utf-8'))
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
||||||
else:
|
else:
|
||||||
#playable item, set plugin path and mediastreams
|
#playable item, set plugin path and mediastreams
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=li.getProperty("path"), listitem=li)
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=li.getProperty("path"), listitem=li)
|
||||||
|
|
||||||
|
|
||||||
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
|
|
||||||
if filter == "recent":
|
if filter == "recent":
|
||||||
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
|
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_DATE)
|
||||||
else:
|
else:
|
||||||
|
@ -510,6 +509,8 @@ def BrowseContent(viewname, type="", folderid=""):
|
||||||
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RATING)
|
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RATING)
|
||||||
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
|
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
|
||||||
|
|
||||||
|
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
|
||||||
|
|
||||||
##### CREATE LISTITEM FROM EMBY METADATA #####
|
##### CREATE LISTITEM FROM EMBY METADATA #####
|
||||||
def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.DownloadUtils()):
|
def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.DownloadUtils()):
|
||||||
API = api.API(item)
|
API = api.API(item)
|
||||||
|
|
|
@ -229,6 +229,8 @@ class LibrarySync(threading.Thread):
|
||||||
music_enabled = utils.settings('enableMusic') == "true"
|
music_enabled = utils.settings('enableMusic') == "true"
|
||||||
|
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(true)')
|
xbmc.executebuiltin('InhibitIdleShutdown(true)')
|
||||||
|
screensaver = utils.getScreensaver()
|
||||||
|
utils.setScreensaver(value="")
|
||||||
window('emby_dbScan', value="true")
|
window('emby_dbScan', value="true")
|
||||||
# Add sources
|
# Add sources
|
||||||
utils.sourcesXML()
|
utils.sourcesXML()
|
||||||
|
@ -280,6 +282,7 @@ class LibrarySync(threading.Thread):
|
||||||
completed = process[itemtype](embycursor, kodicursor, pDialog)
|
completed = process[itemtype](embycursor, kodicursor, pDialog)
|
||||||
if not completed:
|
if not completed:
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
|
utils.setScreensaver(value=screensaver)
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
if pDialog:
|
if pDialog:
|
||||||
pDialog.close()
|
pDialog.close()
|
||||||
|
@ -307,6 +310,7 @@ class LibrarySync(threading.Thread):
|
||||||
completed = self.music(embycursor, musiccursor, pDialog)
|
completed = self.music(embycursor, musiccursor, pDialog)
|
||||||
if not completed:
|
if not completed:
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
|
utils.setScreensaver(value=screensaver)
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
if pDialog:
|
if pDialog:
|
||||||
pDialog.close()
|
pDialog.close()
|
||||||
|
@ -334,6 +338,7 @@ class LibrarySync(threading.Thread):
|
||||||
elapsedtotal = datetime.now() - starttotal
|
elapsedtotal = datetime.now() - starttotal
|
||||||
|
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
|
utils.setScreensaver(value=screensaver)
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
window('emby_initialScan', clear=True)
|
window('emby_initialScan', clear=True)
|
||||||
if forceddialog:
|
if forceddialog:
|
||||||
|
@ -377,21 +382,17 @@ class LibrarySync(threading.Thread):
|
||||||
result = doUtils(url)
|
result = doUtils(url)
|
||||||
grouped_views = result['Items']
|
grouped_views = result['Items']
|
||||||
ordered_views = emby.getViews(sortedlist=True)
|
ordered_views = emby.getViews(sortedlist=True)
|
||||||
|
all_views = []
|
||||||
sorted_views = []
|
sorted_views = []
|
||||||
for view in ordered_views:
|
for view in ordered_views:
|
||||||
|
all_views.append(view['name'])
|
||||||
if view['type'] == "music":
|
if view['type'] == "music":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if view['type'] == "mixed":
|
if view['type'] == "mixed":
|
||||||
sorted_views.append(view['name'])
|
sorted_views.append(view['name'])
|
||||||
sorted_views.append(view['name'])
|
sorted_views.append(view['name'])
|
||||||
|
log("Sorted views: %s" % sorted_views, 1)
|
||||||
try:
|
|
||||||
groupedFolders = self.user.userSettings['Configuration']['GroupedFolders']
|
|
||||||
except TypeError:
|
|
||||||
url = "{server}/emby/Users/{UserId}?format=json"
|
|
||||||
result = doUtils(url)
|
|
||||||
groupedFolders = result['Configuration']['GroupedFolders']
|
|
||||||
|
|
||||||
# total nodes for window properties
|
# total nodes for window properties
|
||||||
vnodes.clearProperties()
|
vnodes.clearProperties()
|
||||||
|
@ -399,6 +400,15 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
current_views = emby_db.getViews()
|
current_views = emby_db.getViews()
|
||||||
# Set views for supported media type
|
# Set views for supported media type
|
||||||
|
emby_mediatypes = {
|
||||||
|
|
||||||
|
'movies': "Movie",
|
||||||
|
'tvshows': "Series",
|
||||||
|
'musicvideos': "MusicVideo",
|
||||||
|
'homevideos': "Video",
|
||||||
|
'music': "Audio",
|
||||||
|
'photos': "Photo"
|
||||||
|
}
|
||||||
mediatypes = ['movies', 'tvshows', 'musicvideos', 'homevideos', 'music', 'photos']
|
mediatypes = ['movies', 'tvshows', 'musicvideos', 'homevideos', 'music', 'photos']
|
||||||
for mediatype in mediatypes:
|
for mediatype in mediatypes:
|
||||||
|
|
||||||
|
@ -412,12 +422,14 @@ class LibrarySync(threading.Thread):
|
||||||
foldername = folder['name']
|
foldername = folder['name']
|
||||||
viewtype = folder['type']
|
viewtype = folder['type']
|
||||||
|
|
||||||
if folderid in groupedFolders:
|
if foldername not in all_views:
|
||||||
# Media folders are grouped into userview
|
# Media folders are grouped into userview
|
||||||
url = "{server}/emby/Users/{UserId}/Items?format=json"
|
url = "{server}/emby/Users/{UserId}/Items?format=json"
|
||||||
params = {
|
params = {
|
||||||
'ParentId': folderid,
|
'ParentId': folderid,
|
||||||
'Limit': 1
|
'Recursive': True,
|
||||||
|
'Limit': 1,
|
||||||
|
'IncludeItemTypes': emby_mediatypes[mediatype]
|
||||||
} # Get one item from server using the folderid
|
} # Get one item from server using the folderid
|
||||||
result = doUtils(url, parameters=params)
|
result = doUtils(url, parameters=params)
|
||||||
try:
|
try:
|
||||||
|
@ -434,8 +446,20 @@ class LibrarySync(threading.Thread):
|
||||||
# Take the userview, and validate the item belong to the view
|
# Take the userview, and validate the item belong to the view
|
||||||
if emby.verifyView(grouped_view['Id'], verifyitem):
|
if emby.verifyView(grouped_view['Id'], verifyitem):
|
||||||
# Take the name of the userview
|
# Take the name of the userview
|
||||||
|
log("Found corresponding view: %s %s"
|
||||||
|
% (grouped_view['Name'], grouped_view['Id']), 1)
|
||||||
foldername = grouped_view['Name']
|
foldername = grouped_view['Name']
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
# Unable to find a match, add the name to our sorted_view list
|
||||||
|
sorted_views.append(foldername)
|
||||||
|
log("Couldn't find corresponding grouped view: %s" % sorted_views, 1)
|
||||||
|
|
||||||
|
# Failsafe
|
||||||
|
try:
|
||||||
|
sorted_views.index(foldername)
|
||||||
|
except ValueError:
|
||||||
|
sorted_views.append(foldername)
|
||||||
|
|
||||||
# Get current media folders from emby database
|
# Get current media folders from emby database
|
||||||
view = emby_db.getView_byId(folderid)
|
view = emby_db.getView_byId(folderid)
|
||||||
|
|
|
@ -349,7 +349,7 @@ class UserClient(threading.Thread):
|
||||||
# If user has password
|
# If user has password
|
||||||
if user['HasPassword'] == True:
|
if user['HasPassword'] == True:
|
||||||
password = dialog.input(
|
password = dialog.input(
|
||||||
heading="%s %s" % (lang(33008), username),
|
heading="%s %s" % (lang(33008), username.decode('utf-8')),
|
||||||
option=xbmcgui.ALPHANUM_HIDE_INPUT)
|
option=xbmcgui.ALPHANUM_HIDE_INPUT)
|
||||||
# If password dialog is cancelled
|
# If password dialog is cancelled
|
||||||
if not password:
|
if not password:
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import cProfile
|
import cProfile
|
||||||
import inspect
|
import inspect
|
||||||
|
import json
|
||||||
import pstats
|
import pstats
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
|
@ -119,6 +120,40 @@ def getKodiMusicDBPath():
|
||||||
% dbVersion.get(kodibuild, "")).decode('utf-8')
|
% dbVersion.get(kodibuild, "")).decode('utf-8')
|
||||||
return dbPath
|
return dbPath
|
||||||
|
|
||||||
|
def getScreensaver():
|
||||||
|
# Get the current screensaver value
|
||||||
|
query = {
|
||||||
|
|
||||||
|
'jsonrpc': "2.0",
|
||||||
|
'id': 0,
|
||||||
|
'method': "Settings.getSettingValue",
|
||||||
|
'params': {
|
||||||
|
|
||||||
|
'setting': "screensaver.mode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = xbmc.executeJSONRPC(json.dumps(query))
|
||||||
|
result = json.loads(result)
|
||||||
|
screensaver = result['result']['value']
|
||||||
|
|
||||||
|
return screensaver
|
||||||
|
|
||||||
|
def setScreensaver(value):
|
||||||
|
# Toggle the screensaver
|
||||||
|
query = {
|
||||||
|
|
||||||
|
'jsonrpc': "2.0",
|
||||||
|
'id': 0,
|
||||||
|
'method': "Settings.setSettingValue",
|
||||||
|
'params': {
|
||||||
|
|
||||||
|
'setting': "screensaver.mode",
|
||||||
|
'value': value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = xbmc.executeJSONRPC(json.dumps(query))
|
||||||
|
logMsg("EMBY", "Toggling screensaver: %s %s" % (value, result), 1)
|
||||||
|
|
||||||
def reset():
|
def reset():
|
||||||
|
|
||||||
dialog = xbmcgui.Dialog()
|
dialog = xbmcgui.Dialog()
|
||||||
|
|
Loading…
Reference in a new issue