Skip to content

Instantly share code, notes, and snippets.

@blindstitch
Last active March 3, 2021 23:06
Show Gist options
  • Save blindstitch/edb1dd9c2f5aca2ae7054db96572a6db to your computer and use it in GitHub Desktop.
Save blindstitch/edb1dd9c2f5aca2ae7054db96572a6db to your computer and use it in GitHub Desktop.
Ubuntu desktop background slideshow XML generator that uses gsettings and a jinja2 template. Searches 1 level deep into subdirectories, will not see files at root level of script
import os
import subprocess
from jinja2 import Template
import pathlib
from glob import glob
import random
# Utility
list_collapse = lambda l: [item for sublist in l for item in sublist]
def randname(len=8):
out = ''
for i in range(len):
out += random.choice([a for a in 'abcdefghijklmnopqrstuvwxyz0123456789'])
return out
# Prefs
folder = "."
excludedfolders = ['shirt'] # Don't search these folders
extensions = ['jpg','jpeg','png','bmp','tif','tiff'] # Allowed extensions
duration = 900 # Seconds
name_prefix = '.slideshow-generatedxml-'
outname = f"{name_prefix}{randname(5)}.xml"
outpath = str(pathlib.Path(outname).absolute())
# Delete previously-generated XMLs
for f in glob(f"{name_prefix}*.xml"):
print(f"Removing {f}")
os.remove(f)
# Create list of all the files to use in the slideshow
imagefolders = [p for p in [pathlib.PosixPath(p) for p in glob(f'{folder}/*')] if p.is_dir() and p.name not in excludedfolders]
imagefiles = []
for f in imagefolders:
files = [p for p in f.iterdir() if p.is_file() and p.suffix[1:] in extensions] # Path.iterdir() gets contents, Path.is_file() to filter
files = [str(p.absolute()) for p in files] # Path.absolute() to get full path, str to convert
imagefiles.append(files)
imagefiles = list_collapse(imagefiles)
# Random sort
random.shuffle(imagefiles)
image_pairs = []
for i in range(len(imagefiles)):
if i != len(imagefiles)-1:
image_pairs.append([imagefiles[i],imagefiles[i+1]])
else:
image_pairs.append([imagefiles[i],imagefiles[0]])
# Render & write XML
slideshow_template = Template(
"""<background>
{% for pair in image_pairs %}
<static>
<duration>{{ duration }}</duration>
<file>{{ pair[0] }}</file>
</static>
<transition>
<duration>1.00</duration>
<from>{{ pair[0] }}</from>
<to>{{ pair[1] }}</to>
</transition>
{% endfor %}
</background>"""
)
output = slideshow_template.render(image_pairs = image_pairs,duration = duration)
outfile = open(outname,'w')
outfile.write(output)
outfile.close()
print(f"Wrote {outname}")
# Use gsettings to set the xml as background
commands = {
'set-scale' : 'gsettings set org.gnome.desktop.background picture-options "scaled"',
'set-bg' : f'gsettings set org.gnome.desktop.background picture-uri file://{outpath}'
}
for key in commands:
commands[key] = commands[key].split(' ')
for key in commands:
subprocess.call(commands[key])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment