from PIL import Image, ImageDraw, ImageFont from datetime import date, timedelta import io import requests # Read in the quotes with open('Tao Te Ching.txt', 'r', encoding='utf-8') as f: tao = [line.replace('\ufeff', '').strip() for line in f.readlines()] # Pick the day to send and pick which quote to send show_new_quote_frequency_days = 3 start_date = date(2024, 7, 26) today = date.today() yesterday = today - timedelta(days=1) index_today = (today - start_date).days // show_new_quote_frequency_days index_yesterday = (yesterday - start_date).days // show_new_quote_frequency_days if index_today < 0 or not (index_today > index_yesterday): print('not today') exit() if index_today >= len(tao): print("we're done") exit() verse_index = index_today + 1 text = tao[verse_index-1] # Generating the image global_scale = 10 size = (134*8*global_scale, 181*8*global_scale) margin = int(0.1*size[0]) text_box_size = (size[0] - 2*margin, size[1] - 2*margin) font_path = "Compass 9.ttf" image = Image.new('RGB', size, (0,0,0)) draw = ImageDraw.Draw(image) fontsize = 40*global_scale font = ImageFont.truetype(font_path, fontsize) # Helper functions def get_width(text, font): return get_dims(text, font)[0] def get_dims(text, font): lines = text.split('\n') width = 0 height = 0 for line in lines: box = font.getbbox(line) if box[2] - box[0] > width: width = box[2] - box[0] height += 1.2 * (box[3] - box[1]) return width, height def get_ratio(text, font): w, h = get_dims(text, font) return w/h # Finding where to add \n and which font size will fit the kindle screen best words = text.split() print(words) current_ratio = None previous_ratio = None goal_ratio = text_box_size[0]/text_box_size[1] wrapped_text = None while wrapped_text is None or current_ratio is None or previous_ratio is None or (abs(goal_ratio - current_ratio) < abs(goal_ratio - previous_ratio) and get_dims(wrapped_text, font)[1] < text_box_size[1]): lines = [[]] word_index = 0 line_index = 0 while word_index < len(words): if get_width(' '.join(lines[line_index]) + ' ' + words[word_index], font) >= text_box_size[0]: break while get_width(' '.join(lines[line_index]) + ' ' + words[word_index], font) < text_box_size[0]: lines[line_index].append(words[word_index]) word_index += 1 if word_index >= len(words) - 1: break line_index += 1 lines.append([]) wrapped_text = '\n'.join([' '.join(line) for line in lines]).strip() previous_ratio = current_ratio current_ratio = get_ratio(wrapped_text, font) fontsize += global_scale * 10 font = ImageFont.truetype(font_path, fontsize) print(goal_ratio, current_ratio, fontsize, text_box_size, get_dims(wrapped_text, font)) # Stepping back the fontsize fontsize -= global_scale * 20 font = ImageFont.truetype(font_path, fontsize) lines = [[words[0]]] word_index = 1 line_index = 0 while word_index < len(words): while get_width(' '.join(lines[line_index]) + ' ' + words[word_index], font) < text_box_size[0]: lines[line_index].append(words[word_index]) word_index += 1 if word_index >= len(words) - 1: break line_index += 1 lines.append([]) print(goal_ratio, current_ratio, fontsize, text_box_size, get_dims(wrapped_text, font)) print(lines) # Drawing the quote and the attribution wrapped_text = '\n'.join([' '.join(line) for line in lines]) draw.multiline_text((margin, margin), wrapped_text, font=font, fill=(255,255,255), stroke_width=int(0.1*global_scale)) attribution = f'Verse {verse_index} from "Tao Te Ching" translated by Carol Deppe. Font "Compass" by somepx.' fontsize = 10*global_scale font = ImageFont.truetype(font_path, fontsize) while get_width(attribution, font) < size[0]*0.9: fontsize += global_scale font = ImageFont.truetype(font_path, fontsize) w, h = get_dims(attribution, font) print(w, h, size) attr_margin = int((size[0]-w)/2) draw.multiline_text((attr_margin, size[1]-h*2.5), attribution, font=font, fill=(255,255,255), stroke_width=int(0.1*global_scale)) image = image.resize((size[0]//global_scale, size[1]//global_scale), resample=Image.NEAREST) # image.save("image.png") # And off to the kindle image_bytes = io.BytesIO() image.save(image_bytes, format='PNG') image_bytes = image_bytes.getvalue() requests.post('http://kindle.sn0w.cx/data', data=image_bytes)