feat: Add og images

This commit is contained in:
Nathan Woodburn 2025-03-06 23:21:35 +11:00
parent 25280e9c02
commit b38436deba
Signed by: nathanwoodburn
GPG Key ID: 203B000478AD0EF1
4 changed files with 110 additions and 2 deletions

View File

@ -2,4 +2,5 @@ flask
gunicorn
requests
python-dotenv
pytz
pytz
Pillow

View File

@ -9,6 +9,7 @@ from flask import (
render_template,
send_from_directory,
send_file,
Response
)
import os
import json
@ -18,6 +19,9 @@ import dotenv
from pytz import timezone
import pytz
import re
from PIL import Image, ImageDraw, ImageFont
import io
import urllib.parse
dotenv.load_dotenv()
@ -78,7 +82,20 @@ def wellknown(path):
# region Main routes
@app.route("/")
def index():
return render_template("index.html")
from_tz = request.args.get('from_tz', '')
time = request.args.get('time', '')
to_tzs = request.args.get('to_tzs', '')
# Generate the OG image URL based on the parameters
# Make sure to encode the parameters
from_tz = urllib.parse.quote(from_tz)
time = urllib.parse.quote(time)
to_tzs = urllib.parse.quote(to_tzs)
og_image = f"og_image?from_tz={from_tz}&time={time}&to_tzs={to_tzs}"
return render_template("index.html", og_image=og_image)
# Mapping of short timezone names to full names
SHORT_TZ_MAP = {
@ -193,6 +210,80 @@ def convert_multiple():
return jsonify(results)
@app.route("/og_image")
def og_image():
from_tz = request.args.get('from_tz', 'Unknown')
time = request.args.get('time', 'Unknown')
to_tzs = request.args.get('to_tzs', 'Unknown')
# Load the background image
img_path = "templates/assets/img/og_image.webp"
img = Image.open(img_path).convert("RGBA")
d = ImageDraw.Draw(img)
# Convert time format to 12-hour format and add AM/PM
try:
input_time = datetime.strptime(time, "%Y-%m-%dT%H:%M:%S")
except ValueError:
input_time = datetime.strptime(time, "%Y-%m-%dT%H:%M")
time = input_time.strftime("%I:%M %p")
# Prepare text
text = f"{time} {from_tz.replace("_","/")}"
from_tz = get_full_timezone(from_tz.replace("_", "/"))
# Check if multiple timezones are provided
if "," in to_tzs:
to_tzs = to_tzs.split(",")
to_tz_list = [(tz, get_full_timezone(tz.replace("_", "/"))) for tz in to_tzs if len(tz) > 0]
else:
to_tz_list = [(to_tzs, get_full_timezone(to_tzs.replace("_", "/")))]
if from_tz is None or any(tz[1] is None for tz in to_tz_list):
return send_from_directory("templates/assets/img", "og_image.webp")
for tz in to_tz_list:
to_tz = tz[1]
to_tz_time = from_tz.localize(input_time).astimezone(to_tz)
text += f"\n{to_tz_time.strftime('%I:%M %p')} {tz[0].replace('_','/')}"
font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"
font_size = 200
# Shrink font size if text is too long
if (max(len(line) for line in text.split("\n")) > 13):
font_size = 150
font_size -= (len(text.split("\n")) - 4) * 10
font = ImageFont.truetype(font_path, font_size)
text_bbox = d.textbbox((0, 0), text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
# Calculate text position
x = (img.width - text_width) / 2
y = (img.height - text_height) / 2
# Add text to the image
d.text((x, y), text, fill=(255, 255, 255), font=font, align="center")
# Save the image to a BytesIO object in WebP format
img_io = io.BytesIO()
img.save(img_io, 'WEBP')
img_io.seek(0)
return Response(img_io, mimetype='image/webp')
@app.route("/<path:path>")
def catch_all(path: str):
if os.path.isfile("templates/" + path):

Binary file not shown.

After

(image error) Size: 112 KiB

View File

@ -7,6 +7,22 @@
<title>Time Converter</title>
<link rel="icon" href="/assets/img/favicon.png" type="image/png">
<link rel="stylesheet" href="/assets/css/index.css">
<!-- og meta -->
<meta property="og:type" value="website" />
<meta property="og:title" value="Timezone Converter" />
<meta property="og:description" value="Convert between timezone | Nathan.Woodburn/" />
<meta property="og:url" value="https://time.c.woodburn.au" />
<meta property="og:image" value="https://time.c.woodburn.au/{{ og_image }}" />
<meta property="og:image:alt" value="Convert between timezone image" />
<!-- twitter meta -->
<meta name="twitter:card" value="summary" />
<meta name="twitter:site" value="@woodburn_nathan" />
<meta name="twitter:creator" value="@woodburn_nathan" />
<meta name="twitter:title" value="Timezone Converter" />
<meta name="twitter:description" value="Convert between timezone | Nathan.Woodburn/" />
<meta name="twitter:image" value="/{{ og_image }}" />
<meta name="twitter:image:alt" value="Convert between timezone image" />
</head>
<body>