tnew xkcd in python; adds title and alt text - scripts - random scripts (HTM) git clone git://parazyd.org/scripts.git (DIR) Log (DIR) Files (DIR) Refs --- (DIR) commit fa368d5febabb1d62dce55965412d02cf80220aa (DIR) parent b8530370f2509a29ab8fb68b9d2ef8a5f588db75 (HTM) Author: parazyd <parazyd@dyne.org> Date: Fri, 17 Feb 2017 00:47:06 +0100 new xkcd in python; adds title and alt text Diffstat: C xkcd -> obsolete/xkcd | 0 M xkcd | 130 +++++++++++++++++++++++++++++-- 2 files changed, 125 insertions(+), 5 deletions(-) --- (DIR) diff --git a/xkcd b/obsolete/xkcd (DIR) diff --git a/xkcd b/xkcd t@@ -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()