mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-11-10 04:06:11 +00:00
user preferences
This commit is contained in:
parent
8a0701d8f1
commit
ad594ff472
10 changed files with 229 additions and 169 deletions
|
@ -41,6 +41,9 @@ elif mode == "resetauth":
|
||||||
elif mode == "adduser":
|
elif mode == "adduser":
|
||||||
entrypoint.addUser()
|
entrypoint.addUser()
|
||||||
|
|
||||||
|
elif mode == "userprefs":
|
||||||
|
entrypoint.userPreferences()
|
||||||
|
|
||||||
elif mode == "settings":
|
elif mode == "settings":
|
||||||
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')
|
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from PlaybackUtils import PlaybackUtils
|
||||||
from DownloadUtils import DownloadUtils
|
from DownloadUtils import DownloadUtils
|
||||||
from ReadEmbyDB import ReadEmbyDB
|
from ReadEmbyDB import ReadEmbyDB
|
||||||
from API import API
|
from API import API
|
||||||
|
from UserPreferences import UserPreferences
|
||||||
|
|
||||||
|
|
||||||
##### Play items via plugin://plugin.video.emby/ #####
|
##### Play items via plugin://plugin.video.emby/ #####
|
||||||
|
@ -120,6 +121,23 @@ def addUser():
|
||||||
xbmc.log("Failed to add user to session.")
|
xbmc.log("Failed to add user to session.")
|
||||||
xbmcgui.Dialog().notification("Error", "Unable to add/remove user from the session.", xbmcgui.NOTIFICATION_ERROR)
|
xbmcgui.Dialog().notification("Error", "Unable to add/remove user from the session.", xbmcgui.NOTIFICATION_ERROR)
|
||||||
|
|
||||||
|
def userPreferences():
|
||||||
|
doUtils = DownloadUtils()
|
||||||
|
addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
|
||||||
|
userPreferencesPage = UserPreferences("script-emby-kodi-UserPreferences.xml", addonSettings.getAddonInfo('path'), "default", "1080i")
|
||||||
|
url = "{server}/mediabrowser/Users/{UserId}"
|
||||||
|
result = doUtils.downloadUrl(url)
|
||||||
|
configuration = result[u'Configuration']
|
||||||
|
userPreferencesPage.setConfiguration(configuration)
|
||||||
|
userPreferencesPage.setName(result[u'Name'])
|
||||||
|
userPreferencesPage.setImage(API().getUserArtwork(result,"Primary"))
|
||||||
|
|
||||||
|
userPreferencesPage.doModal()
|
||||||
|
if userPreferencesPage.isSave():
|
||||||
|
url = "{server}/mediabrowser/Users/{UserId}/Configuration"
|
||||||
|
postdata = userPreferencesPage.getConfiguration()
|
||||||
|
doUtils.downloadUrl(url, postBody=postdata, type="POST")
|
||||||
|
|
||||||
##### BROWSE EMBY CHANNELS #####
|
##### BROWSE EMBY CHANNELS #####
|
||||||
def BrowseChannels(id, folderid=None):
|
def BrowseChannels(id, folderid=None):
|
||||||
|
|
||||||
|
@ -485,6 +503,7 @@ def doMainListing():
|
||||||
addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
|
addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
|
||||||
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
|
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
|
||||||
addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
|
addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
|
||||||
|
addDirectoryItem("Configure user preferences", "plugin://plugin.video.emby/?mode=userprefs")
|
||||||
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
|
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
|
||||||
addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache")
|
addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache")
|
||||||
|
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
|
|
||||||
import sys
|
|
||||||
import xbmc
|
|
||||||
import xbmcgui
|
|
||||||
import xbmcaddon
|
|
||||||
import json as json
|
|
||||||
import urllib
|
|
||||||
from DownloadUtils import DownloadUtils
|
|
||||||
from API import API
|
|
||||||
|
|
||||||
_MODE_GETCONTENT=0
|
|
||||||
_MODE_ITEM_DETAILS=17
|
|
||||||
|
|
||||||
class PersonInfo(xbmcgui.WindowXMLDialog):
|
|
||||||
|
|
||||||
pluginCastLink = ""
|
|
||||||
showMovies = False
|
|
||||||
personName = ""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
def onInit(self):
|
|
||||||
self.action_exitkeys_id = [10, 13]
|
|
||||||
downloadUtils = DownloadUtils()
|
|
||||||
url = "{server}/mediabrowser/Persons/" + self.personName + "?format=json"
|
|
||||||
jsonData = downloadUtils.downloadUrl(url )
|
|
||||||
result = jsonData
|
|
||||||
|
|
||||||
name = result.get("Name")
|
|
||||||
id = result.get("Id")
|
|
||||||
|
|
||||||
# other lib items count
|
|
||||||
contentCounts = ""
|
|
||||||
if(result.get("AdultVideoCount") != None and result.get("AdultVideoCount") > 0):
|
|
||||||
contentCounts = contentCounts + "\nAdult Count : " + str(result.get("AdultVideoCount"))
|
|
||||||
if(result.get("MovieCount") != None and result.get("MovieCount") > 0):
|
|
||||||
contentCounts = contentCounts + "\nMovie Count : " + str(result.get("MovieCount"))
|
|
||||||
if(result.get("SeriesCount") != None and result.get("SeriesCount") > 0):
|
|
||||||
contentCounts = contentCounts + "\nSeries Count : " + str(result.get("SeriesCount"))
|
|
||||||
if(result.get("EpisodeCount") != None and result.get("EpisodeCount") > 0):
|
|
||||||
contentCounts = contentCounts + "\nEpisode Count : " + str(result.get("EpisodeCount"))
|
|
||||||
|
|
||||||
if(len(contentCounts) > 0):
|
|
||||||
contentCounts = "Total Library Counts:" + contentCounts
|
|
||||||
|
|
||||||
#overview
|
|
||||||
overview = ""
|
|
||||||
if(len(contentCounts) > 0):
|
|
||||||
overview = contentCounts + "\n\n"
|
|
||||||
over = result.get("Overview")
|
|
||||||
if(over == None or over == ""):
|
|
||||||
overview = overview + "No details available"
|
|
||||||
else:
|
|
||||||
overview = overview + over
|
|
||||||
|
|
||||||
#person image
|
|
||||||
image = API().getArtwork(result, "Primary")
|
|
||||||
|
|
||||||
#get other movies
|
|
||||||
encoded = name.encode("utf-8")
|
|
||||||
encoded = urllib.quote(encoded)
|
|
||||||
url = "{server}/mediabrowser/Users/{UserId}/Items/?Recursive=True&Person=" + encoded + "&format=json"
|
|
||||||
jsonData = downloadUtils.downloadUrl(url)
|
|
||||||
otherMovieResult = jsonData
|
|
||||||
|
|
||||||
baseName = name.replace(" ", "+")
|
|
||||||
baseName = baseName.replace("&", "_")
|
|
||||||
baseName = baseName.replace("?", "_")
|
|
||||||
baseName = baseName.replace("=", "_")
|
|
||||||
|
|
||||||
#detailsString = getDetailsString()
|
|
||||||
#search_url = "http://" + host + ":" + port + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=PERSON_NAME&Fields=" + detailsString + "&format=json"
|
|
||||||
#search_url = "http://" + host + ":" + port + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=PERSON_NAME&format=json"
|
|
||||||
#search_url = urllib.quote(search_url)
|
|
||||||
#search_url = search_url.replace("PERSON_NAME", baseName)
|
|
||||||
#self.pluginCastLink = "XBMC.Container.Update(plugin://plugin.video.xbmb3c?mode=" + str(_MODE_GETCONTENT) + "&url=" + search_url + ")"
|
|
||||||
|
|
||||||
otherItemsList = None
|
|
||||||
try:
|
|
||||||
otherItemsList = self.getControl(3010)
|
|
||||||
|
|
||||||
items = otherMovieResult.get("Items")
|
|
||||||
if(items == None):
|
|
||||||
items = []
|
|
||||||
|
|
||||||
for item in items:
|
|
||||||
item_id = item.get("Id")
|
|
||||||
item_name = item.get("Name")
|
|
||||||
|
|
||||||
type_info = ""
|
|
||||||
image_id = item_id
|
|
||||||
item_type = item.get("Type")
|
|
||||||
|
|
||||||
if(item_type == "Season"):
|
|
||||||
image_id = item.get("SeriesId")
|
|
||||||
season = item.get("IndexNumber")
|
|
||||||
type_info = "Season " + str(season).zfill(2)
|
|
||||||
elif(item_type == "Series"):
|
|
||||||
image_id = item.get("Id")
|
|
||||||
type_info = "Series"
|
|
||||||
elif(item_type == "Movie"):
|
|
||||||
image_id = item.get("Id")
|
|
||||||
type_info = "Movie"
|
|
||||||
elif(item_type == "Episode"):
|
|
||||||
image_id = item.get("SeriesId")
|
|
||||||
season = item.get("ParentIndexNumber")
|
|
||||||
eppNum = item.get("IndexNumber")
|
|
||||||
type_info = "S" + str(season).zfill(2) + "E" + str(eppNum).zfill(2)
|
|
||||||
|
|
||||||
thumbPath = downloadUtils.imageUrl(image_id, "Primary", 0, 200, 200)
|
|
||||||
|
|
||||||
fanArt = downloadUtils.imageUrl(image_id, "Backdrop",0,10000,10000)
|
|
||||||
listItem = xbmcgui.ListItem(label=item_name, label2=type_info, iconImage=thumbPath, thumbnailImage=thumbPath)
|
|
||||||
listItem.setArt({"fanart":fanArt})
|
|
||||||
|
|
||||||
actionUrl = "plugin://plugin.video.emby?id=" + item_id + "&mode=play"
|
|
||||||
listItem.setProperty("ActionUrl", actionUrl)
|
|
||||||
|
|
||||||
otherItemsList.addItem(listItem)
|
|
||||||
|
|
||||||
except Exception, e:
|
|
||||||
xbmc.log("Exception : " + str(e))
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# set the dialog data
|
|
||||||
self.getControl(3000).setLabel(name)
|
|
||||||
self.getControl(3001).setText(overview)
|
|
||||||
self.getControl(3009).setImage(image)
|
|
||||||
|
|
||||||
def setPersonName(self, name):
|
|
||||||
self.personName = name
|
|
||||||
|
|
||||||
def setInfo(self, data):
|
|
||||||
self.details = data
|
|
||||||
|
|
||||||
def onFocus(self, controlId):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def doAction(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def closeDialog(self):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def onClick(self, controlID):
|
|
||||||
|
|
||||||
if(controlID == 3002):
|
|
||||||
self.showMovies = True
|
|
||||||
|
|
||||||
xbmc.executebuiltin('Dialog.Close(movieinformation)')
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
elif(controlID == 3010):
|
|
||||||
|
|
||||||
#xbmc.executebuiltin("Dialog.Close(all,true)")
|
|
||||||
|
|
||||||
itemList = self.getControl(3010)
|
|
||||||
item = itemList.getSelectedItem()
|
|
||||||
action = item.getProperty("ActionUrl")
|
|
||||||
|
|
||||||
xbmc.executebuiltin("RunPlugin(" + action + ")")
|
|
||||||
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
78
resources/lib/UserPreferences.py
Normal file
78
resources/lib/UserPreferences.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import xbmc
|
||||||
|
import xbmcgui
|
||||||
|
import xbmcaddon
|
||||||
|
import json as json
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
ACTION_BACK = 92
|
||||||
|
|
||||||
|
class UserPreferences(xbmcgui.WindowXMLDialog):
|
||||||
|
|
||||||
|
configuration = None
|
||||||
|
save = False
|
||||||
|
name = None
|
||||||
|
image = None
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
def onInit(self):
|
||||||
|
self.action_exitkeys_id = [10, 13]
|
||||||
|
# set the dialog data
|
||||||
|
|
||||||
|
cinemaMode = self.configuration.get(u'EnableCinemaMode')
|
||||||
|
self.getControl(8011).setSelected(cinemaMode)
|
||||||
|
self.getControl(8001).setLabel(self.name)
|
||||||
|
self.getControl(8002).setImage(self.image)
|
||||||
|
def save(self):
|
||||||
|
self.save = True
|
||||||
|
|
||||||
|
def isSave(self):
|
||||||
|
return self.save
|
||||||
|
|
||||||
|
def setConfiguration(self, configuration):
|
||||||
|
self.configuration = configuration
|
||||||
|
|
||||||
|
def getConfiguration(self):
|
||||||
|
return self.configuration
|
||||||
|
|
||||||
|
def setName(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def setImage(self, image):
|
||||||
|
self.image = image
|
||||||
|
|
||||||
|
def onFocus(self, controlId):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def doAction(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def closeDialog(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def onClick(self, controlID):
|
||||||
|
|
||||||
|
if(controlID == 8012):
|
||||||
|
# save now
|
||||||
|
self.save()
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
elif(controlID == 8013):
|
||||||
|
#cancel
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
if(controlID == 8011):
|
||||||
|
# cinema mode
|
||||||
|
cinemamode = self.getControl(8011).isSelected()
|
||||||
|
self.configuration['EnableCinemaMode'] = cinemamode
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onAction(self, action):
|
||||||
|
if action == ACTION_BACK:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<window>
|
||||||
|
<defaultcontrol always="true">8011</defaultcontrol>
|
||||||
|
<zorder>0</zorder>
|
||||||
|
<controls>
|
||||||
|
<control type="group">
|
||||||
|
<right>560</right>
|
||||||
|
<top>140</top>
|
||||||
|
<width>800</width>
|
||||||
|
<height>800</height>
|
||||||
|
<control type="group">
|
||||||
|
<control type="image">
|
||||||
|
<texture border="5" colordiffuse="ff111111">box.png</texture>
|
||||||
|
<height>100</height>
|
||||||
|
</control>
|
||||||
|
<control type="image">
|
||||||
|
<texture border="5" colordiffuse="ff222222">box.png</texture>
|
||||||
|
<top>100</top>
|
||||||
|
<height>700</height>
|
||||||
|
</control>
|
||||||
|
<control type="image" id="8002">
|
||||||
|
<description>user image</description>
|
||||||
|
<width>80</width>
|
||||||
|
<height>100</height>
|
||||||
|
</control>
|
||||||
|
<control type="label" id="8001" description="name">
|
||||||
|
<left>90</left>
|
||||||
|
<top>30</top>
|
||||||
|
<height>40</height>
|
||||||
|
<width>20%</width>
|
||||||
|
<align>left</align>
|
||||||
|
<font>font16</font>
|
||||||
|
<textcolor>ffeeeeee</textcolor>
|
||||||
|
</control>
|
||||||
|
<!-- -->
|
||||||
|
<control type="label" description="Title">
|
||||||
|
<left>320</left>
|
||||||
|
<top>30</top>
|
||||||
|
<align>left</align>
|
||||||
|
<height>40</height>
|
||||||
|
<width>100%</width>
|
||||||
|
<font>font16</font>
|
||||||
|
<textcolor>ffeeeeee</textcolor>
|
||||||
|
<label>User Preferences</label>
|
||||||
|
</control>
|
||||||
|
<control type="image">
|
||||||
|
<description>separator</description>
|
||||||
|
<left>-10</left>
|
||||||
|
<top>103</top>
|
||||||
|
<width>101%</width>
|
||||||
|
<height>1</height>
|
||||||
|
<texture colordiffuse="ffffffff" border="90,3,90,3">separator.png</texture>
|
||||||
|
</control>
|
||||||
|
<control type="grouplist">
|
||||||
|
<top>50</top>
|
||||||
|
<height>600</height>
|
||||||
|
<orientation>vertical</orientation>
|
||||||
|
<align>left</align>
|
||||||
|
<itemgap>20</itemgap>
|
||||||
|
<control type="group">
|
||||||
|
<control type="radiobutton" id="8011">
|
||||||
|
<left>8</left>
|
||||||
|
<ondown>8012</ondown>
|
||||||
|
<onup>8012</onup>
|
||||||
|
<top>100</top>
|
||||||
|
<width>785</width>
|
||||||
|
<align>left</align>
|
||||||
|
<height>70</height>
|
||||||
|
<textureradiofocus colordiffuse="B3dddddd">radio-on.png</textureradiofocus>
|
||||||
|
<textureradionofocus colordiffuse="1Fdddddd">radio-off.png</textureradionofocus>
|
||||||
|
<texturefocus border="5" colordiffuse="ff0385b5">white.png</texturefocus>
|
||||||
|
<radioposx>750</radioposx>
|
||||||
|
<radiowidth>32</radiowidth>
|
||||||
|
<radioheight>32</radioheight>
|
||||||
|
<textoffsetx>30</textoffsetx>
|
||||||
|
<textcolor>B3dddddd</textcolor>
|
||||||
|
<label>Cinema Mode Enabled</label>
|
||||||
|
</control>
|
||||||
|
</control>
|
||||||
|
</control>
|
||||||
|
<!-- buttons -->
|
||||||
|
<control type="image">
|
||||||
|
<description>separator</description>
|
||||||
|
<bottom>70</bottom>
|
||||||
|
<left>-10</left>
|
||||||
|
<width>101%</width>
|
||||||
|
<height>1</height>
|
||||||
|
<texture border="90,3,90,3">separator.png</texture>
|
||||||
|
</control>
|
||||||
|
<control type="button" id="8012">
|
||||||
|
<description>Save</description>
|
||||||
|
<left>150</left>
|
||||||
|
<bottom>20</bottom>
|
||||||
|
<width>230</width>
|
||||||
|
<onup>8011</onup>
|
||||||
|
<onleft>8013</onleft>
|
||||||
|
<onright>8013</onright>
|
||||||
|
<font>font14</font>
|
||||||
|
<label>Save</label>
|
||||||
|
<focusedcolor>FFededed</focusedcolor>
|
||||||
|
<disabledcolor>B3dddddd</disabledcolor>
|
||||||
|
<selectedcolor>FF000000</selectedcolor>
|
||||||
|
<height>40</height>
|
||||||
|
<textcolor>ff333333</textcolor>
|
||||||
|
<texturefocus colordiffuse="ff0385b5" border="5">box.png</texturefocus>
|
||||||
|
<texturenofocus colordiffuse="B3dddddd" border="5">box.png</texturenofocus>
|
||||||
|
</control>
|
||||||
|
<control type="button" id="8013">
|
||||||
|
<description>Cancel</description>
|
||||||
|
<left>430</left>
|
||||||
|
<bottom>20</bottom>
|
||||||
|
<width>230</width>
|
||||||
|
<onup>8011</onup>
|
||||||
|
<onleft>8012</onleft>
|
||||||
|
<onright>8012</onright>
|
||||||
|
<font>font14</font>
|
||||||
|
<label>222</label>
|
||||||
|
<focusedcolor>FFededed</focusedcolor>
|
||||||
|
<disabledcolor>B3dddddd</disabledcolor>
|
||||||
|
<selectedcolor>FF000000</selectedcolor>
|
||||||
|
<height>40</height>
|
||||||
|
<textcolor>ff333333</textcolor>
|
||||||
|
<texturefocus colordiffuse="ff0385b5" border="5">box.png</texturefocus>
|
||||||
|
<texturenofocus colordiffuse="B3dddddd" border="5">box.png</texturenofocus>
|
||||||
|
</control>
|
||||||
|
</control>
|
||||||
|
</control>
|
||||||
|
</controls>
|
||||||
|
</window>
|
BIN
resources/skins/default/media/box.png
Normal file
BIN
resources/skins/default/media/box.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 B |
BIN
resources/skins/default/media/radio-off.png
Normal file
BIN
resources/skins/default/media/radio-off.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 B |
BIN
resources/skins/default/media/radio-on.png
Normal file
BIN
resources/skins/default/media/radio-on.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 B |
BIN
resources/skins/default/media/separator.png
Normal file
BIN
resources/skins/default/media/separator.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/skins/default/media/white.png
Normal file
BIN
resources/skins/default/media/white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 263 B |
Loading…
Reference in a new issue