Skip to content

Commit a0f0d79

Browse files
committed
Added slideshow based screensaver.
1 parent e8e941b commit a0f0d79

File tree

9 files changed

+221
-8
lines changed

9 files changed

+221
-8
lines changed

addon.xml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<extension point="xbmc.python.pluginsource" library="plugin.py">
1414
<provides>executable</provides>
1515
</extension>
16+
<extension point="xbmc.ui.screensaver" library="screensaver.py"/>
1617
<extension point="xbmc.service" library="service.py" start="startup"></extension>
1718
<extension point="xbmc.addon.metadata">
1819
<summary lang="en">Plex for Kodi</summary>

lib/_included_packages/plexnet/photo.py

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def isPhotoOrDirectoryItem(self):
5252

5353

5454
@plexobjects.registerLibFactory('photo')
55+
@plexobjects.registerLibFactory('image')
5556
def PhotoFactory(data, initpath=None, server=None, container=None):
5657
if data.tag == 'Photo':
5758
return Photo(data, initpath=initpath, server=server, container=container)

lib/_included_packages/plexnet/plexlibrary.py

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ def optimize(self):
7575

7676
def refresh(self):
7777
self.server.query('/library/sections/all/refresh')
78+
79+
def randomArts(self):
80+
return plexobjects.listItems(self.server, '/library/arts?sort=random&type=1%2c2%2c8&X-Plex-Container-Start=0&X-Plex-Container-Size=50')
7881

7982

8083
class LibrarySection(plexobjects.PlexObject):

lib/util.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,17 @@ def day(self):
360360

361361
class Cron(threading.Thread):
362362
def __init__(self, interval):
363-
threading.Thread.__init__(self, name='CRON')
364-
self.stopped = threading.Event()
365-
self.force = threading.Event()
366-
self.interval = interval
367-
self._lastHalfHour = self._getHalfHour()
368-
self._receivers = []
369-
370363
global CRON
371364

372-
CRON = self
365+
if CRON == None:
366+
threading.Thread.__init__(self, name='CRON')
367+
self.stopped = threading.Event()
368+
self.force = threading.Event()
369+
self.interval = interval
370+
self._lastHalfHour = self._getHalfHour()
371+
self._receivers = []
372+
373+
CRON = self
373374

374375
def __enter__(self):
375376
self.start()
@@ -469,6 +470,7 @@ class AdvancedSettings(object):
469470
("auto_seek", True),
470471
("dynamic_timeline_seek", False),
471472
("fast_back", False),
473+
("screensaver_quiz", False)
472474
)
473475

474476
def __init__(self):

lib/windows/slidehshow.py

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import time
2+
import random
3+
4+
import kodigui
5+
6+
from lib import util
7+
from plexnet import plexapp
8+
9+
class Slideshow(kodigui.BaseWindow, util.CronReceiver):
10+
xmlFile = 'script-plex-slideshow.xml'
11+
path = util.ADDON.getAddonInfo('path')
12+
theme = 'Main'
13+
res = '1080i'
14+
width = 1920
15+
height = 1080
16+
17+
TIME_BETWEEN_IMAGES = 15
18+
TIME_HIDE_TITLE_IN_QUIZ = 5
19+
TIME_DISPLAY_MOVE = 60
20+
21+
CONTROL_INFO_GROUP = 100
22+
23+
def __init__(self, *args, **kwargs):
24+
kodigui.BaseWindow.__init__(self, *args, **kwargs)
25+
self.timeBetweenImages = self.TIME_BETWEEN_IMAGES
26+
self.timeBetweenDisplayMove = self.TIME_DISPLAY_MOVE
27+
self.timeTitleIsHidden = self.TIME_HIDE_TITLE_IN_QUIZ
28+
self.quizMode = util.advancedSettings.screensaverQuiz
29+
self.initialized = False
30+
31+
def onFirstInit(self):
32+
self.setProperty('clock', '')
33+
self.setProperty('title', '')
34+
self.setProperty('thumb', '')
35+
self.setProperty('align', '0')
36+
37+
self.infoGroupControl = self.getControl(self.CONTROL_INFO_GROUP)
38+
39+
util.CRON.registerReceiver(self)
40+
self.timeFormat = util.timeFormat.replace(":%S", "")
41+
self.lastTime = ''
42+
self.displayPosition = 0
43+
self.changeTime = time.time() - 1
44+
self.displayMoveTime = time.time() + self.timeBetweenDisplayMove
45+
self.revealTitleTime = None
46+
47+
self.selectedServer = plexapp.SERVERMANAGER.selectedServer
48+
self.index = -1
49+
self.images = []
50+
51+
self.initialized = True
52+
53+
def tick(self):
54+
if not self.initialized:
55+
return
56+
57+
currentTime = time.time()
58+
timestr = time.strftime(self.timeFormat, time.localtime(currentTime))
59+
if not util.padHour and timestr[0] == "0" and timestr[1] != ":":
60+
timestr = timestr[1:]
61+
62+
if currentTime > self.changeTime:
63+
nextIndex = self.index + 1
64+
65+
if nextIndex >= len(self.images):
66+
if self.selectedServer != None:
67+
self.images = self.selectedServer.library.randomArts();
68+
util.DEBUG_LOG('[SS] Fetched {0} items'.format(len(self.images)))
69+
nextIndex = 0
70+
71+
if len(self.images) == 0:
72+
title = 'No Images'
73+
url = ''
74+
else:
75+
image = self.images[nextIndex]
76+
title = image.get('title')
77+
key = image.get('key')
78+
url = self.selectedServer.getImageTranscodeURL(key, self.width, self.height)
79+
if not self.quizMode:
80+
self.setProperty('title', title)
81+
else:
82+
self.setProperty('title', '')
83+
self.quizTitle = title
84+
self.revealTitleTime = currentTime + self.timeTitleIsHidden
85+
self.setProperty('thumb', url)
86+
87+
self.index = nextIndex
88+
self.changeTime = time.time() + self.timeBetweenImages
89+
90+
if self.revealTitleTime != None and currentTime > self.revealTitleTime:
91+
self.setProperty('title', self.quizTitle)
92+
self.revealTitleTime = None
93+
94+
if currentTime > self.displayMoveTime:
95+
oldDisplayPosition = self.displayPosition
96+
self.displayPosition = (oldDisplayPosition + random.randint(1, 3)) % 4
97+
98+
if (oldDisplayPosition&2) != (self.displayPosition&2):
99+
self.setProperty('align', str((self.displayPosition&2)>>1))
100+
101+
if (oldDisplayPosition&1) != (self.displayPosition&1):
102+
newY = self.height - self.infoGroupControl.getY() - self.infoGroupControl.getHeight()
103+
self.infoGroupControl.setPosition(self.infoGroupControl.getX(), newY)
104+
105+
self.displayMoveTime = currentTime + self.timeBetweenDisplayMove
106+
107+
if timestr != self.lastTime:
108+
self.setProperty('clock', timestr)

resources/language/English/strings.po

+8
Original file line numberDiff line numberDiff line change
@@ -973,4 +973,12 @@ msgstr ""
973973

974974
msgctxt "#32485"
975975
msgid "Go back instantly with the previous menu action in scrolled views"
976+
msgstr ""
977+
978+
msgctxt "#32488"
979+
msgid "Screensaver"
980+
msgstr ""
981+
982+
msgctxt "#32489"
983+
msgid "Quiz Mode"
976984
msgstr ""

resources/settings.xml

+3
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@
1616
<category label="32467">
1717
<setting id="fast_back" type="bool" label="32485" default="false" />
1818
</category>
19+
<category label="32488">
20+
<setting id="screensaver_quiz" type="bool" label="32489" default="false" />
21+
</category>
1922
</settings>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<window>
2+
<zorder>6</zorder>
3+
<controls>
4+
<control type="group">
5+
<control type="image" id="1">
6+
<posx>0</posx>
7+
<posy>0</posy>
8+
<width>1920</width>
9+
<height>1080</height>
10+
<texture background="true"></texture>
11+
<aspectratio>keep</aspectratio>
12+
<fadetime>1000</fadetime>
13+
<texture>$INFO[Window.Property(thumb)]</texture>
14+
</control>
15+
<control type="group" id="100">
16+
<posx>20</posx>
17+
<posy>20</posy>
18+
<height>100</height>
19+
<width>1880</width>
20+
<control type="label" id="101">
21+
<visible>String.IsEqual(Window.Property(align),0)</visible>
22+
<posy>0</posy>
23+
<height>50</height>
24+
<font>font45</font>
25+
<align>left</align>
26+
<textcolor>FFFFFFFF</textcolor>
27+
<shadowcolor>FF000000</shadowcolor>
28+
<label>$INFO[Window.Property(clock)]</label>
29+
</control>
30+
<control type="label" id="105">
31+
<visible>String.IsEqual(Window.Property(align),0)</visible>
32+
<posy>50</posy>
33+
<height>20</height>
34+
<font>font16</font>
35+
<align>left</align>
36+
<textcolor>FFFFFFFF</textcolor>
37+
<shadowcolor>FF000000</shadowcolor>
38+
<label>$INFO[Window.Property(title)]</label>
39+
</control>
40+
<control type="label" id="111">
41+
<visible>String.IsEqual(Window.Property(align),1)</visible>
42+
<posy>0</posy>
43+
<height>50</height>
44+
<font>font45</font>
45+
<align>right</align>
46+
<textcolor>FFFFFFFF</textcolor>
47+
<shadowcolor>FF000000</shadowcolor>
48+
<label>$INFO[Window.Property(clock)]</label>
49+
</control>
50+
<control type="label" id="115">
51+
<visible>String.IsEqual(Window.Property(align),1)</visible>
52+
<posy>50</posy>
53+
<height>20</height>
54+
<font>font16</font>
55+
<align>right</align>
56+
<textcolor>FFFFFFFF</textcolor>
57+
<shadowcolor>FF000000</shadowcolor>
58+
<label>$INFO[Window.Property(title)]</label>
59+
</control>
60+
</control>
61+
</control>
62+
</controls>
63+
</window>

screensaver.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import xbmc
2+
3+
from lib import plex, util
4+
5+
from lib.windows import slidehshow
6+
7+
class ScreensaverMonitor(xbmc.Monitor):
8+
def __init__( self, *args, **kwargs ):
9+
self.action = kwargs['action']
10+
11+
def onScreensaverDeactivated(self):
12+
self.action()
13+
14+
def main():
15+
util.DEBUG_LOG("[SS] Starting")
16+
if plex.init():
17+
with util.Cron(1):
18+
ss = slidehshow.Slideshow.create()
19+
ss.monitor = ScreensaverMonitor(action = ss.close)
20+
ss.modal()
21+
del ss
22+
23+
if __name__ == '__main__':
24+
main()

0 commit comments

Comments
 (0)