Last active
October 13, 2017 22:20
-
-
Save thiagokokada/20b63bb67c49b02f33860193c8476430 to your computer and use it in GitHub Desktop.
Downloads and show random xkcd comic as i3lock background
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# i3lock-xkcd.py | |
# Downloads and show random xkcd comic as i3lock background | |
import os | |
import sys | |
from subprocess import run | |
from tempfile import NamedTemporaryFile | |
from textwrap import wrap | |
from xkcd import getRandomComic | |
from PIL import Image, ImageDraw, ImageFont | |
from screeninfo import get_monitors | |
# Set options below | |
FONT_FAMILY = "xkcd.otf" | |
FONT_TITLE_SIZE = 36 | |
FONT_ALTTEXT_SIZE = 12 | |
RESIZE_RATIO = 0.8 | |
class I3LockXkcdException(Exception): | |
pass | |
class I3LockXkcd(object): | |
def __init__(self, filename, resolution, retries=3): | |
for i in range(retries): | |
try: | |
self.xkcd = getRandomComic() | |
self.xkcd.download( | |
os.path.dirname(filename), | |
os.path.basename(filename) | |
) | |
except: | |
# Maybe we got a comic that can't be downloaded | |
# (like 1190: Time), so we try again | |
next | |
self.bg = Image.new("RGBA", resolution, "white") | |
self.bg_w, self.bg_h = self.bg.size | |
self.comic = Image.open(filename) | |
self.comic_w, self.comic_h = self.comic.size | |
if not self.comic: | |
raise I3LockXkcdException("No comic has been downloaded") | |
def get_image(self): | |
self.draw_comic() | |
self.draw_title() | |
self.draw_alttext() | |
return self.bg | |
def draw_comic(self): | |
# Calculate comic offset relative to background | |
offset_w = (self.bg_w - self.comic_w) // 2 | |
offset_h = (self.bg_h - self.comic_h) // 2 | |
offset = (offset_w, offset_h) | |
# Draw comic inside background | |
self.bg.paste(self.comic, offset) | |
def draw_title(self, base_offset=100): | |
# Draw title above comic | |
font = ImageFont.truetype(FONT_FAMILY, FONT_TITLE_SIZE) | |
title = ImageDraw.Draw(self.bg) | |
xkcd_title = self.xkcd.getTitle() | |
title_w, title_h = title.textsize(xkcd_title, font=font) | |
# Calculate title offset relative to comic | |
offset_w = (self.bg_w - title_w) // 2 | |
offset_h = (self.bg_h - self.comic_h - base_offset - title_h) // 2 | |
offset = (offset_w, offset_h) | |
# Draw title inside background | |
title.text(offset, xkcd_title, font=font, fill="black") | |
def draw_alttext(self, line_offset=100): | |
# Draw alt-text above comic | |
font = ImageFont.truetype(FONT_FAMILY, FONT_ALTTEXT_SIZE) | |
alt_text = ImageDraw.Draw(self.bg) | |
# Since alt-text can be too long, we wrap it using textwrap.wrap | |
for line in wrap(self.xkcd.getAltText(), width=120): | |
line_w, line_h = alt_text.textsize(line, font=font) | |
offset_w = (self.bg_w - line_w) // 2 | |
offset_h = (self.bg_h + self.comic_h + line_offset - line_h) // 2 | |
offset = (offset_w, offset_h) | |
alt_text.text(offset, line, font=font, fill="black") | |
line_offset += 40 | |
def main(): | |
monitor = get_monitors()[0] | |
monitor_w = monitor.width | |
monitor_h = monitor.height | |
resolution = (monitor_w, monitor_h) | |
with NamedTemporaryFile(suffix=".png") as tempfile: | |
try: | |
image = I3LockXkcd(tempfile.name, resolution).get_image() | |
except I3LockXkcdException as e: | |
# Failed to get comic, just open i3lock instead | |
print(e, file=sys.stderr) | |
run(["i3lock"]) | |
sys.exit(1) | |
# Write result in temporary file, loads in i3lock | |
with NamedTemporaryFile(suffix=".png") as tempfile: | |
image.save(tempfile.name) | |
run(['i3lock', '-i', tempfile.name]) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
olefile==0.44 | |
Pillow==4.3.0 | |
screeninfo==0.3 | |
xkcd==2.4.2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment