diff --git a/addon.xml b/addon.xml
index 0f3e569d..99267db0 100644
--- a/addon.xml
+++ b/addon.xml
@@ -13,6 +13,7 @@
executable
+
Plex for Kodi
diff --git a/lib/_included_packages/plexnet/photo.py b/lib/_included_packages/plexnet/photo.py
index e2036a8c..17107c4d 100644
--- a/lib/_included_packages/plexnet/photo.py
+++ b/lib/_included_packages/plexnet/photo.py
@@ -52,6 +52,7 @@ def isPhotoOrDirectoryItem(self):
@plexobjects.registerLibFactory('photo')
+@plexobjects.registerLibFactory('image')
def PhotoFactory(data, initpath=None, server=None, container=None):
if data.tag == 'Photo':
return Photo(data, initpath=initpath, server=server, container=container)
diff --git a/lib/_included_packages/plexnet/plexlibrary.py b/lib/_included_packages/plexnet/plexlibrary.py
index b8a1f8a6..d153dc28 100644
--- a/lib/_included_packages/plexnet/plexlibrary.py
+++ b/lib/_included_packages/plexnet/plexlibrary.py
@@ -75,6 +75,9 @@ def optimize(self):
def refresh(self):
self.server.query('/library/sections/all/refresh')
+
+ def randomArts(self):
+ return plexobjects.listItems(self.server, '/library/arts?sort=random&type=1%2c2%2c8&X-Plex-Container-Start=0&X-Plex-Container-Size=50')
class LibrarySection(plexobjects.PlexObject):
diff --git a/lib/util.py b/lib/util.py
index 427ff991..b932b3bb 100644
--- a/lib/util.py
+++ b/lib/util.py
@@ -89,6 +89,7 @@ class AdvancedSettings(object):
("auto_seek", True),
("dynamic_timeline_seek", False),
("fast_back", False),
+ ("screensaver_quiz", False),
)
def __init__(self):
diff --git a/lib/windows/slidehshow.py b/lib/windows/slidehshow.py
new file mode 100644
index 00000000..fac07bb6
--- /dev/null
+++ b/lib/windows/slidehshow.py
@@ -0,0 +1,108 @@
+import time
+import random
+
+import kodigui
+
+from lib import util
+from plexnet import plexapp
+
+class Slideshow(kodigui.BaseWindow, util.CronReceiver):
+ xmlFile = 'script-plex-slideshow.xml'
+ path = util.ADDON.getAddonInfo('path')
+ theme = 'Main'
+ res = '1080i'
+ width = 1920
+ height = 1080
+
+ TIME_BETWEEN_IMAGES = 15
+ TIME_HIDE_TITLE_IN_QUIZ = 5
+ TIME_DISPLAY_MOVE = 60
+
+ CONTROL_INFO_GROUP = 100
+
+ def __init__(self, *args, **kwargs):
+ kodigui.BaseWindow.__init__(self, *args, **kwargs)
+ self.timeBetweenImages = self.TIME_BETWEEN_IMAGES
+ self.timeBetweenDisplayMove = self.TIME_DISPLAY_MOVE
+ self.timeTitleIsHidden = self.TIME_HIDE_TITLE_IN_QUIZ
+ self.quizMode = util.advancedSettings.screensaverQuiz
+ self.initialized = False
+
+ def onFirstInit(self):
+ self.setProperty('clock', '')
+ self.setProperty('title', '')
+ self.setProperty('thumb', '')
+ self.setProperty('align', '0')
+
+ self.infoGroupControl = self.getControl(self.CONTROL_INFO_GROUP)
+
+ util.CRON.registerReceiver(self)
+ self.timeFormat = util.timeFormat.replace(":%S", "")
+ self.lastTime = ''
+ self.displayPosition = 0
+ self.changeTime = time.time() - 1
+ self.displayMoveTime = time.time() + self.timeBetweenDisplayMove
+ self.revealTitleTime = None
+
+ self.selectedServer = plexapp.SERVERMANAGER.selectedServer
+ self.index = -1
+ self.images = []
+
+ self.initialized = True
+
+ def tick(self):
+ if not self.initialized:
+ return
+
+ currentTime = time.time()
+ timestr = time.strftime(self.timeFormat, time.localtime(currentTime))
+ if not util.padHour and timestr[0] == "0" and timestr[1] != ":":
+ timestr = timestr[1:]
+
+ if currentTime > self.changeTime:
+ nextIndex = self.index + 1
+
+ if nextIndex >= len(self.images):
+ if self.selectedServer != None:
+ self.images = self.selectedServer.library.randomArts();
+ util.DEBUG_LOG('[SS] Fetched {0} items'.format(len(self.images)))
+ nextIndex = 0
+
+ if len(self.images) == 0:
+ title = 'No Images'
+ url = ''
+ else:
+ image = self.images[nextIndex]
+ title = image.get('title')
+ key = image.get('key')
+ url = self.selectedServer.getImageTranscodeURL(key, self.width, self.height)
+ if not self.quizMode:
+ self.setProperty('title', title)
+ else:
+ self.setProperty('title', '')
+ self.quizTitle = title
+ self.revealTitleTime = currentTime + self.timeTitleIsHidden
+ self.setProperty('thumb', url)
+
+ self.index = nextIndex
+ self.changeTime = time.time() + self.timeBetweenImages
+
+ if self.revealTitleTime != None and currentTime > self.revealTitleTime:
+ self.setProperty('title', self.quizTitle)
+ self.revealTitleTime = None
+
+ if currentTime > self.displayMoveTime:
+ oldDisplayPosition = self.displayPosition
+ self.displayPosition = (oldDisplayPosition + random.randint(1, 3)) % 4
+
+ if (oldDisplayPosition&2) != (self.displayPosition&2):
+ self.setProperty('align', str((self.displayPosition&2)>>1))
+
+ if (oldDisplayPosition&1) != (self.displayPosition&1):
+ newY = self.height - self.infoGroupControl.getY() - self.infoGroupControl.getHeight()
+ self.infoGroupControl.setPosition(self.infoGroupControl.getX(), newY)
+
+ self.displayMoveTime = currentTime + self.timeBetweenDisplayMove
+
+ if timestr != self.lastTime:
+ self.setProperty('clock', timestr)
\ No newline at end of file
diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po
index 90041a57..80e963ca 100644
--- a/resources/language/English/strings.po
+++ b/resources/language/English/strings.po
@@ -975,6 +975,13 @@ msgctxt "#32485"
msgid "Go back instantly with the previous menu action in scrolled views"
msgstr ""
+msgctxt "#32488"
+msgid "Screensaver"
+msgstr ""
+
+msgctxt "#32489"
+msgid "Quiz Mode"
+msgstr ""
msgctxt "#32492"
msgid "Kodi Subtitle Settings"
msgstr ""
\ No newline at end of file
diff --git a/resources/settings.xml b/resources/settings.xml
index a30da7ce..aa0742be 100644
--- a/resources/settings.xml
+++ b/resources/settings.xml
@@ -16,4 +16,7 @@
+
+
+
diff --git a/resources/skins/Main/1080i/script-plex-slideshow.xml b/resources/skins/Main/1080i/script-plex-slideshow.xml
new file mode 100644
index 00000000..74ef7e39
--- /dev/null
+++ b/resources/skins/Main/1080i/script-plex-slideshow.xml
@@ -0,0 +1,63 @@
+
+ 6
+
+
+
+ 0
+ 0
+ 1920
+ 1080
+
+ keep
+ 1000
+ $INFO[Window.Property(thumb)]
+
+
+ 20
+ 20
+ 100
+ 1880
+
+ String.IsEqual(Window.Property(align),0)
+ 0
+ 50
+ font45
+ left
+ FFFFFFFF
+ FF000000
+
+
+
+ String.IsEqual(Window.Property(align),0)
+ 50
+ 20
+ font16
+ left
+ FFFFFFFF
+ FF000000
+
+
+
+ String.IsEqual(Window.Property(align),1)
+ 0
+ 50
+ font45
+ right
+ FFFFFFFF
+ FF000000
+
+
+
+ String.IsEqual(Window.Property(align),1)
+ 50
+ 20
+ font16
+ right
+ FFFFFFFF
+ FF000000
+
+
+
+
+
+
\ No newline at end of file
diff --git a/screensaver.py b/screensaver.py
new file mode 100644
index 00000000..8e15051b
--- /dev/null
+++ b/screensaver.py
@@ -0,0 +1,24 @@
+import xbmc
+
+from lib import plex, util
+
+from lib.windows import slidehshow
+
+class ScreensaverMonitor(xbmc.Monitor):
+ def __init__( self, *args, **kwargs ):
+ self.action = kwargs['action']
+
+ def onScreensaverDeactivated(self):
+ self.action()
+
+def main():
+ util.DEBUG_LOG("[SS] Starting")
+ if plex.init():
+ with util.Cron(1):
+ ss = slidehshow.Slideshow.create()
+ ss.monitor = ScreensaverMonitor(action = ss.close)
+ ss.modal()
+ del ss
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file