Skip to content

Commit

Permalink
Support mysql along with sqlite, and provide some info labels
Browse files Browse the repository at this point in the history
Modified queries as needed based on which database type  the My Pictures Database is using.
Set some window properties based on tags in the image files.
Provide the option to display the tag information on each slide.
  • Loading branch information
smfontes committed Feb 10, 2023
1 parent d94c172 commit 8cc94e6
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 67 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@

This Screensaver uses the database from the plugin.image.mypicsdb2 addon. Filters can be used to select which pictures will be shown in the slideshow.

The values of some image tags are set in Window properties. There is an option to display the values overlayed on the images. The values that can be displayed are:

Headline, Caption, Location, Date and Time, and Folder and File name.

4 changes: 2 additions & 2 deletions lib/getfilternames.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@
tree.write(settings_file)

# Notify that you must exit from settings and return to see any new filter names
heading = xbmcaddon.Addon().getLocalizedString(30009)
message = xbmcaddon.Addon().getLocalizedString(30010)
heading = xbmcaddon.Addon().getLocalizedString(30010)
message = xbmcaddon.Addon().getLocalizedString(30011)
xbmc.executebuiltin('Notification('+heading+','+message+',10000)')
136 changes: 107 additions & 29 deletions lib/screensaver.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
# The screensaver uses the picture database created by the plugin.image.mypicsdb2 addon.
# You can also use Filters created in the plugin.image.mypicsdb2 addon to select which
# pictures are shown in the slideshow.
# The values of some image tags are set in Window properties. There is an option
# to display the values overlayed on the images. The values displayed are
# Headline, Caption, Location, Date and Time, and Folder and File name.

import os.path
import sys
import random
import urllib.parse
import time

import xbmc
import xbmcgui
Expand All @@ -32,32 +36,41 @@

ADDON = xbmcaddon.Addon()

SETTINGS_ERROR = ADDON.getLocalizedString(30005)
NO_FILTER_NAME_ERROR = ADDON.getLocalizedString(30006)
BAD_FILTER_NAME_ERROR = ADDON.getLocalizedString(30007)
NO_FILES_MATCH_FILTER = ADDON.getLocalizedString(30008)
SETTINGS_ERROR = ADDON.getLocalizedString(30006)
NO_FILTER_NAME_ERROR = ADDON.getLocalizedString(30007)
BAD_FILTER_NAME_ERROR = ADDON.getLocalizedString(30008)
NO_FILES_MATCH_FILTER = ADDON.getLocalizedString(30009)

def log(msg, level=xbmc.LOGINFO):
filename = os.path.basename(sys._getframe(1).f_code.co_filename)
lineno = str(sys._getframe(1).f_lineno)
xbmc.log(str("[%s] line %5d in %s >> %s"%(ADDON.getAddonInfo('name'), int(lineno), filename, msg.__str__())), level)

DB_BACKEND = xbmcaddon.Addon('plugin.image.mypicsdb2').getSetting('db_backend').lower()
# The random function is different in mysql and sqlite
DB_RANDOM = {"mysql" :"RAND()","sqlite":"RANDOM()"}
# DateTimes are stored and retreived differently between mysql and sqlite.
IMGDATE = {"mysql" :"DATE_FORMAT(ImageDateTime,'%Y-%m-%d')",
"sqlite":"SUBSTR(ImageDateTime, 0, 11)"}
IMGDATETIME = {"mysql" :"DATE_FORMAT(ImageDateTime,'%Y-%m-%d %T')",
"sqlite":"ImageDateTime"}

# Formats that can be displayed in a slideshow
PICTURE_FORMATS = ('jpg', 'jpeg', 'tiff', 'gif', 'png', 'bmp', 'mng', 'ico', 'pcx', 'tga')
SINGLE_PICTURE_QUERY = """ SELECT strPath, strFilename FROM Files """
SINGLE_PICTURE_QUERY += """ WHERE strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ OR strFilename LIKE '%s' """
SINGLE_PICTURE_QUERY += """ ORDER BY RANDOM() LIMIT 1 """
SINGLE_PICTURE_QUERY = " SELECT strPath, strFilename FROM Files "
SINGLE_PICTURE_QUERY += " WHERE strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " OR strFilename LIKE '%s' "
SINGLE_PICTURE_QUERY += " ORDER BY " + DB_RANDOM[DB_BACKEND] + " LIMIT 1 "
SINGLE_PICTURE_QUERY = SINGLE_PICTURE_QUERY % PICTURE_FORMATS
SINGLE_PICTURE_QUERY = SINGLE_PICTURE_QUERY.replace("LIKE '", "LIKE '%")
SINGLE_PICTURE_QUERY = SINGLE_PICTURE_QUERY.replace("LIKE '", "LIKE '%")

# Get the Database from the My Pictures Database addon
MPDB = MypicsDB.MyPictureDB()
Expand All @@ -67,6 +80,7 @@ def __init__(self, *args, **kwargs):
pass

def onInit(self):
self.db_backend = xbmcaddon.Addon('plugin.image.mypicsdb2').getSetting('db_backend').lower()
# Get the screensaver window id
self.winid = xbmcgui.Window(xbmcgui.getCurrentWindowDialogId())
# Init the monitor class to catch onscreensaverdeactivated calls
Expand All @@ -80,13 +94,32 @@ def onInit(self):

def _get_settings(self):
# read addon settings
self.anim_time = 101000
self.slideshow_time = ADDON.getSettingInt('time')
self.slideshow_filter = ADDON.getSettingBool('filter')
self.slideshow_filtername = ADDON.getSettingString('filtername')
self.slideshow_showinfo = ADDON.getSettingBool('tags')
# Set the image controls from the xml we are going to use
self.image1 = self.getControl(1)
self.image2 = self.getControl(2)
# Get MyPicsDB tagids for the information that can be displayed for each slide
_query = " Select idTagType FROM TagTypes WHERE TagType = 'Headline'; "
_ids = self._exec_query(_query)
self.headline_tagid = _ids[0][0]
_query = " Select idTagType FROM TagTypes WHERE TagType = 'Caption/abstract'; "
_ids = self._exec_query(_query)
self.caption_tagid = _ids[0][0]
_query = " Select idTagType FROM TagTypes WHERE TagType = 'Sub-location'; "
_ids = self._exec_query(_query)
self.sublocation_tagid = _ids[0][0]
_query = " Select idTagType FROM TagTypes WHERE TagType = 'City'; "
_ids = self._exec_query(_query)
self.city_tagid= _ids[0][0]
_query = " Select idTagType FROM TagTypes WHERE TagType = 'Province/state'; "
_ids = self._exec_query(_query)
self.state_tagid= _ids[0][0]
_query = " Select idTagType FROM TagTypes WHERE TagType = 'Country/primary location name'; "
_ids = self._exec_query(_query)
self.country_tagid= _ids[0][0]

def _get_filtered_pictures(self):
# If we are going to use a MyPicsDB filter, then get all of the possible pictures we could use to match the filter
Expand All @@ -100,9 +133,9 @@ def _get_filtered_pictures(self):
else:
# Use filter selected, and filter name specified
# Make sure the specified filter exists
query = """SELECT pkFilter FROM FilterWizard"""
query += """ WHERE strFilterName IS '%s'; """ %(self.slideshow_filtername.replace("'","''"))
filter_ids = self.exec_query(query)
query = "Select pkFilter FROM FilterWizard"
query += " WHERE strFilterName = '%s'; " %(self.slideshow_filtername.replace("'","''"))
filter_ids = self._exec_query(query)
if len(filter_ids) != 1:
# Filter name was not found in the My Pictures Database.
message = 'Notification(' + SETTINGS_ERROR + ', ' + BAD_FILTER_NAME_ERROR%(self.slideshow_filtername) + ', 15000, DefaultIconError.png)'
Expand Down Expand Up @@ -133,10 +166,14 @@ def _start_show(self):
# loop until onScreensaverDeactivated is called
while (not self.Monitor.abortRequested()) and (not self.stop):
# Get the next picture
img_name = self._get_item()
picture = self._get_item()
img_name = os.path.join(picture[0], picture[1])
current_image_control.setImage(img_name, False)
xbmc.sleep(1000)
self._set_prop('Fade%d' % order[0], '0')
self._set_prop('Fade%d' % order[1], '1')
if (self.slideshow_showinfo):
self._set_info_fields(picture)
# define next image
if current_image_control == self.image1:
current_image_control = self.image2
Expand All @@ -146,7 +183,7 @@ def _start_show(self):
order = [1,2]

# display the image for the specified amount of time
count = timetowait
count = timetowait - 1000
while (not self.Monitor.abortRequested()) and (not self.stop) and count > 0:
count -= 1000
xbmc.sleep(1000)
Expand All @@ -167,20 +204,61 @@ def _get_item(self, update=False):
self.filtered_results_index = 0
else:
# Not using a filter
result_list = self.exec_query(SINGLE_PICTURE_QUERY)
result_list = self._exec_query(SINGLE_PICTURE_QUERY)
result = result_list[0]
(folder, file) = result
return os.path.join(folder, file)
return result

def _set_info_fields(self, picture):
self._clear_prop('Headline')
self._clear_prop('Caption')
self._clear_prop('Sublocation')
self._clear_prop('City')
self._clear_prop('State')
self._clear_prop('Country')
self._clear_prop('Date')
self._clear_prop('Time')
# Get info to set in window properties
(folder,file) = picture
self._set_prop('Folder',folder)
self._set_prop('File',file)
query = " Select idFile, " + IMGDATETIME[self.db_backend]+ " FROM Files WHERE strPath = '%s' AND strFilename = '%s'; " \
%(folder.replace("'","''"), file.replace("'","''"))
file_info = self._exec_query(query)
if len(file_info) > 0:
self._set_prop('Date',time.strftime('%A %B %e, %Y',time.strptime(file_info[0][1], '%Y-%m-%d %H:%M:%S')))
self._set_prop('Time',time.strftime('%I:%M:%S %p',time.strptime(file_info[0][1], '%Y-%m-%d %H:%M:%S')))
image_id=file_info[0][0]
# Get all of the tags that are on this image
query = " Select idTagContent FROM TagsInFiles WHERE idFile = '%s'; " %(image_id)
content_ids = self._exec_query(query)
for content_id in content_ids:
# Go through each of the tags, and store the ones of interest
query = " Select idTagtype, TagContent FROM TagContents WHERE idTagContent = '%s'; " %(content_id[0])
tags = self._exec_query(query)
tag_id = tags[0][0]
tag_value = tags[0][1]
if tag_id == self.headline_tagid:
self._set_prop('Headline',tag_value)
elif tag_id == self.caption_tagid:
self._set_prop('Caption',tag_value)
elif tag_id == self.sublocation_tagid:
self._set_prop('Sublocation',tag_value)
elif tag_id == self.city_tagid:
self._set_prop('City',tag_value)
elif tag_id == self.state_tagid:
self._set_prop('State',tag_value)
elif tag_id == self.country_tagid:
self._set_prop('Country',tag_value)

# Utility functions
def exec_query(self,query):
def _exec_query(self,query):
return MPDB.cur.request(query)

def _set_prop(self, name, value):
self.winid.setProperty('SlideView.%s' % name, value)
self.winid.setProperty('Screensaver.%s' % name, value)

def _clear_prop(self, name):
self.winid.clearProperty('SlideView.%s' % name)
self.winid.clearProperty('Screensaver.%s' % name)

def _exit(self):
# exit when onScreensaverDeactivated gets called
Expand Down
18 changes: 13 additions & 5 deletions resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,30 @@ msgid "Update Filter Names"
msgstr "Update Filter Names"

msgctxt "#30005"
msgid "Show Picture Information on Slides"
msgstr "Show Picture Information on Slides"

msgctxt "#30006"
msgid "Slideshow settings error"
msgstr "Slideshow settings error"

msgctxt "#30006"
msgctxt "#30007"
msgid "Filter name was not specified"
msgstr "Filter name was not specified"

msgctxt "#30007"
msgctxt "#30008"
msgid "Filtername '%s' not found in MyPictures Database"
msgstr "Filtername '%s' not found in MyPictures Database"

msgctxt "#30008"
msgctxt "#30009"
msgid "No files match filter '%s'in MyPictures Database"
msgstr "No files match filter '%s'in MyPictures Database"

msgctxt "#30009"
msgctxt "#30010"
msgid "Filter Names Updated"
msgstr "Filter Names Updated"

msgctxt "#30010"
msgctxt "#30011"
msgid "Exit from 'Settings' and return to see new Filter Names"
msgstr "Exit from 'Settings' and return to see new Filter Names"

Expand All @@ -70,3 +74,7 @@ msgid "The name of the Filter to use for matching."
msgctxt "#30104"
msgstr "Help for Update Filter Names"
msgid "Select this if the list of Filters to choose from is not up-to-date. After updating the Filter Names, you must exit from 'Settings' and return in order to see the updated Filter names."

msgctxt "#30105"
msgstr "Help for Ahow Picture Inforamtion on Slides"
msgid "Select this to have information about the picture overlayed on top of the picture."
6 changes: 6 additions & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
</dependency>
</dependencies>
</setting>
<setting help="30105" id="tags" label="30005" type="boolean">
<description>Display picture information</description>
<level>0</level>
<default>false</default>
<control type="toggle" />
</setting>
</group>
</category>
</section>
Expand Down
Loading

0 comments on commit 8cc94e6

Please sign in to comment.