Skip to content

Instantly share code, notes, and snippets.

@dsseng
Last active February 23, 2021 18:46
Show Gist options
  • Save dsseng/14292d2954e066f7707e861ab167e77c to your computer and use it in GitHub Desktop.
Save dsseng/14292d2954e066f7707e861ab167e77c to your computer and use it in GitHub Desktop.
Run without root. Install macOS 10.14+ dynamic HEIC wallpapers on Linux (in GNOME). You will need `exiftool` and `heif-convert` to be available in your PATH. All created wallpaper and config files' names are printed out. At the moment this script lacks support for sun-based wallpapers. Some H24 wallpapers might also be parsed incorrectly.
import plistlib
import sys
import os
import json
import base64
from pathlib import Path
name = ".".join(sys.argv[1].split(".")[:-1]).split("/")[-1]
if sys.argv[1].split(".")[-1] != "heic":
print("File is not HEIC")
images_directory = os.environ["HOME"] + "/.local/share/backgrounds/" + name
config_path = os.environ["HOME"] + "/.local/share/gnome-background-properties/heic-desktop-backgrounds-" + name + ".xml"
if Path(images_directory).exists():
print("There already is a folder for this image in ~/.local/share/backgrounds")
exit(1)
if Path(config_path).exists():
print("This background is already registered in GNOME")
exit(1)
exif = json.loads(os.popen("exiftool -j \"" + sys.argv[1] + "\"").read())[0]
if not "H24" in exif:
if "Solar" in exif:
print("Solar based wallpapers cannot be processed yet") # TODO: add support for those
else:
print("EXIF meta for dynamic wallpaper not found")
exit(1)
try:
data = plistlib.loads(base64.decodebytes(exif["H24"].encode('utf-8')))
except plistlib.InvalidFileException:
print("Not supported image format")
exit(1)
if not "ti" in data:
print("Not supported image format")
exit(1)
print("Created: " + images_directory)
os.makedirs(images_directory)
if not Path(os.environ["HOME"] + "/.local/share/gnome-background-properties/").exists():
print("Created: " + os.environ["HOME"] + "/.local/share/gnome-background-properties/")
os.makedirs(os.environ["HOME"] + "/.local/share/gnome-background-properties/")
ti = data["ti"]
print("Created " + images_directory + "/" + name + ".xml")
meta = open(images_directory + "/" + name + ".xml", "w")
meta.write("<background>\n")
meta.write(" <starttime>\n")
meta.write(" <year>2021</year>\n")
meta.write(" <month>1</month>\n")
meta.write(" <day>1</day>\n")
meta.write(" <hour>0</hour>\n")
meta.write(" <minute>0</minute>\n")
meta.write(" <second>0</second>\n")
meta.write(" </starttime>\n")
# TODO: add transitions
for i in range(len(ti)):
t = ti[i]["t"]*86400
if i != 0:
t -= ti[i - 1]["t"]*86400 # TODO: better length handling
pic = ti[i]["i"] + 1
meta.write(" <static>\n")
meta.write(" <file>" + images_directory + "/" + name + "-" + str(pic) + ".jpg</file>\n")
meta.write(" <duration>" + str(t) + "</duration>\n")
meta.write(" </static>\n")
meta.write("</background>\n")
meta.close()
os.system("heif-convert -q 50 \"" + sys.argv[1] + "\" \"" + images_directory + "/" + name + ".jpg\"")
print("Created: " + config_path)
list = open(config_path, "w")
list.write('''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
<wallpapers>
<wallpaper deleted="false">
<name>''' + name + '''</name>
<filename>''' + images_directory + "/" + name + ".xml" + '''</filename>
<options>stretched</options>
</wallpaper>
</wallpapers>
''')
list.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment