commit fa368d5febabb1d62dce55965412d02cf80220aa
parent b8530370f2509a29ab8fb68b9d2ef8a5f588db75
Author: parazyd <parazyd@dyne.org>
Date: Fri, 17 Feb 2017 00:47:06 +0100
new xkcd in python; adds title and alt text
Diffstat:
2 files changed, 125 insertions(+), 5 deletions(-)
diff --git a/xkcd b/obsolete/xkcd
diff --git a/xkcd b/xkcd
@@ -1,7 +1,127 @@
-#!/bin/sh
+#!/usr/bin/env python
+#
+# grab a random xkcd comic, append title and alttext, and save to a dir
-tot="$(curl -s https://xkcd.com/info.0.json | jq '.num')"
-[ -n "$tot" ] || exit 1
-rnd="$(shuf -i 1-${tot} -n 1)"
+from PIL import Image, ImageDraw, ImageFont
+from requests import get
+from random import randrange
+from textwrap import wrap
+from json import loads
+from re import search
+import os
-curl -s https://xkcd.com/$rnd/info.0.json | jq '.img' | xargs feh
+download_dir = os.environ['HOME']+'/xkcd/'
+title_fontsize = 28
+alt_fontsize = 18
+line_offset = 10
+
+def add_text(image, title, alt, tfont=download_dir+'xkcd.ttf',
+ afont=download_dir+'xkcd.ttf'):
+ try:
+ img = Image.open(image)
+ except OSError:
+ return
+
+ #tfont = ImageFont.truetype(download_dir+'xkcd.ttf', title_fontsize)
+ #afont = ImageFont.truetype(download_dir+'xkcd.ttf', alt_fontsize)
+ tfont = ImageFont.truetype(tfont, title_fontsize)
+ afont = ImageFont.truetype(afont, alt_fontsize)
+
+ twidth, theight = tfont.getsize(title)
+ awidth, aheight = afont.getsize(alt)
+ line_padding = 5
+ draw = ImageDraw.Draw(img)
+ lines = text_wrap(tfont, title, img.size[0])
+ lheight = max([tfont.getsize(" ".join(i))[1] for i in lines])
+ lheight_total = (lheight+line_padding)*(len(lines))+line_padding*4
+ title_crop = (0, -1*lheight_total, img.size[0], img.size[1])
+ img = img.crop(title_crop)
+ w, h = img.size
+ old_h = h
+ draw = ImageDraw.Draw(img)
+ lheight_total = line_padding
+ for i in lines:
+ draw.text((w/2-tfont.getsize(" ".join(i))[0]/2,
+ lheight_total),
+ " ".join(i),
+ font=tfont,
+ fill=0xffffff)
+ lheight_total += lheight + line_padding
+ lheight_total = line_padding
+ lines = text_wrap(afont, alt, w)
+ lheight = max([afont.getsize(" ".join(i))[1] for i in lines])
+ lheight_total = lheight*len(lines)
+ alt_crop = (0, 0, img.size[0],
+ img.size[1]+lheight_total+(len(lines)+3)*line_padding)
+ img = img.crop(alt_crop)
+ draw = ImageDraw.Draw(img)
+ lheight_total = old_h + line_padding
+ for i in lines:
+ if not i:
+ continue
+ draw.text((w/2-afont.getsize(" ".join(i))[0]/2,
+ lheight_total),
+ " ".join(i),
+ font=afont,
+ fill=0xffffff)
+ lheight_total += lheight + line_padding
+
+ img.save(image)
+ print(image)
+ exit(0)
+
+def text_wrap(font, text, image_width, i=0):
+ lines = [[]]
+ text = text.split(" ")
+ while len(text) > 0:
+ while len(text) > 0 \
+ and font.getsize(" ".join(lines[i]))[0] < image_width:
+ if font.getsize(text[0]+" "+" ".join(lines[i]))[0] > image_width * 0.95:
+ if len(lines[i]) == 0:
+ text[0] = text[0][:len(text[0])//2+1] \
+ + " " + text[0][:len(text[0])//2+1:]
+ text = text[0].split(" ") + text[1:]
+ break
+ lines[i].append(text[0])
+ text.pop(0)
+ i += 1
+ lines.append([])
+ sub = []
+ for e, i in enumerate(lines):
+ if font.getsize(" ".join(lines[e]))[0] > image_width:
+ temp_str = ""
+ for c in "".join(i):
+ if font.getsize(temp_str+c)[0] > image_width:
+ lines[i] = lines[i][:len(lines[i])//2] \
+ + lines[i][len(lines[i])//2:]
+ break
+ temp_str += c
+ sub.append(temp_str)
+ del lines[e]
+ lines = [i for i in lines if len(i) != 0]
+ for c in [i for i in sub if len(i) != 0]:
+ lines.append(c)
+ return lines
+
+def main():
+ info = get("https://xkcd.com/info.0.json").json()
+ if not info:
+ exit(1)
+ info = get("https://xkcd.com/"+str(randrange(1, info['num']) + 1)+"/info.0.json").json()
+
+ title = info['safe_title']
+ alt = info['alt']
+ num = str(info['num'])
+
+ image = num+search("\.([a-z])+$", info['img']).group()
+
+ with open(download_dir+image, 'wb') as image_file:
+ req = get(info['img'], stream=True)
+ for block in req.iter_content(1024):
+ if block:
+ image_file.write(block)
+ image_file.flush()
+ if not search("\.gif", info['img']):
+ add_text(download_dir+image, title, alt)
+
+main()