Generating pretty images for each talks.

This commit is contained in:
Julien Palard 2023-02-10 22:53:55 +01:00
parent 561239bfa5
commit 0df5876fbd
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
7 changed files with 213 additions and 5 deletions

View File

@ -4,15 +4,39 @@ import argparse
import logging
import re
import sqlite3
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from time import sleep
from pathlib import Path
from zoneinfo import ZoneInfo
from contextlib import suppress
from mastodon import Mastodon
from jinja2 import Environment, FileSystemLoader
from html2image import Html2Image
def generate_file(output_path, title, author, type, date, salle):
environment = Environment(loader=FileSystemLoader("template/"))
template = environment.get_template("template.html")
rend = template.render(
title=title, author=author, type=type, date=date, salle=salle
)
hti = Html2Image()
hti.load_file("template/illustration_1.png")
hti.load_file("template/logo_pyconfr_1.png")
hti.screenshot(
html_str=rend,
css_file="template/styles.css",
save_as=output_path,
size=(1200, 675),
)
def convert_datetime(val):
"""Convert ISO 8601 datetime to datetime.datetime object."""
return datetime.fromisoformat(val.decode())
return datetime.fromisoformat(val.decode() + "+00:00")
sqlite3.register_converter("datetime", convert_datetime)
@ -64,7 +88,8 @@ def get_talks(django_site_id=4):
with con:
res = con.execute(
f"""
SELECT cfp_talk.start_date,
SELECT cfp_talk.id,
cfp_talk.start_date,
cfp_room.name room,
GROUP_CONCAT(cfp_participant.name, x'00') participant,
GROUP_CONCAT(cfp_participant.mastodon, x'00') mastodon,
@ -116,12 +141,28 @@ def live_toot(talks, mastodon: Mastodon, ahead_days=0):
for talk in talks:
if talk.category == "Sprint":
continue # We don't toot sprints.
delta = talk.start_date - datetime.now() - timedelta(days=ahead_days)
delta = (
talk.start_date - datetime.now(timezone.utc) - timedelta(days=ahead_days)
)
if delta.total_seconds() > 10:
logging.info("Waiting %s for %s to start.", delta, talk.title)
sleep(delta.total_seconds() - 2) # Wait for the talk to start.
sleep(2) # This is just a fool guard so we can Ctrl-C easily anytime.
mastodon.toot(toot_for(talk, ahead_days))
png_name = f"talk-{talk.id}.png"
with suppress(FileNotFoundError):
Path(png_name).unlink()
generate_file(
output_path=png_name,
title=talk.title,
author=", ".join(talk.participants),
type=talk.category.split()[0],
date=talk.start_date.astimezone(ZoneInfo("Europe/Paris")).strftime(
"%A %d %B %HH%M"
),
salle="Salle " + talk.room.split("/")[0],
)
media = mastodon.media_post("rend.png")
mastodon.status_post(toot_for(talk, ahead_days), media_ids=[media])
class DryRunMastodon:
@ -136,6 +177,12 @@ class DryRunMastodon:
def toot(self, message):
print(message)
def media_post(self, *args, **kwargs):
print("Would upload media to Mastodon.")
def status_post(self, *args, **kwargs):
print("Would tooting", args, kwargs)
def main():
args = parse_args()

View File

@ -1 +1,3 @@
Mastodon.py
Jinja2==3.1.2
html2image==2.0.1

BIN
template/illustration_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 KiB

BIN
template/logo_pyconfr_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

133
template/styles.css Normal file
View File

@ -0,0 +1,133 @@
.1_3 {
overflow:hidden;
}
.e1_3 {
background-color:rgba(255, 255, 255, 1);
width:1200px;
height:675px;
}
.e1_4 {
width:1200px;
height:675px;
position:absolute;
left:0px;
top:0px;
}
.e4_34 {
width:1200px;
height:675px;
position:absolute;
left:0px;
top:0px;
background-image:url(illustration_1.png);
background-repeat:no-repeat;
background-size:cover;
}
.e1_8 {
background-color:rgba(22.4910007417202, 61.18752770125866, 69.30900290608406, 1);
width:975px;
height:309px;
position:absolute;
left:127px;
top:138px;
border-top-left-radius:16px;
border-top-right-radius:16px;
border-bottom-left-radius:16px;
border-bottom-right-radius:16px;
}
.e1_9 {
color:rgba(183.60000729560852, 242.1246188879013, 255, 1);
width:943px;
height:79px;
position:absolute;
left:16px;
top:8px;
font-family:Fira Sans;
text-align:center;
font-size:64px;
letter-spacing:5;
}
.e1_10 {
width:943px;
height:198px;
position:absolute;
left:16px;
top:95px;
}
.e1_11 {
color:rgba(255, 255, 255, 1);
width:943px;
height:154px;
position:absolute;
left:0px;
top:0px;
font-family:Fira Sans;
text-align:center;
font-size:42px;
letter-spacing:0;
}
.e1_12 {
color:rgba(255, 255, 255, 1);
width:943px;
height:44px;
position:absolute;
left:0px;
top:154px;
font-family:Fira Sans;
text-align:center;
font-size:30px;
letter-spacing:0;
}
.e1_13 {
background-color:rgba(250.00000029802322, 249.00000035762787, 247.00000047683716, 1);
width:739px;
height:115px;
position:absolute;
left:231px;
top:493px;
border-top-left-radius:16px;
border-top-right-radius:16px;
border-bottom-left-radius:16px;
border-bottom-right-radius:16px;
}
.e1_15 {
width:515px;
height:83px;
position:absolute;
left:208px;
top:16px;
}
.e1_16 {
color:rgba(22.000000588595867, 61.00000016391277, 69.00000348687172, 1);
width:515px;
height:38px;
position:absolute;
left:0px;
top:0px;
font-family:Fira Sans;
text-align:center;
font-size:44px;
letter-spacing:-2;
}
.e1_17 {
color:rgba(22.000000588595867, 61.00000016391277, 69.00000348687172, 1);
width:512px;
height:27px;
position:absolute;
left:0px;
top:56px;
font-family:Fira Sans;
text-align:center;
font-size:26px;
letter-spacing:-1.5;
}
.e4_35 {
width:176px;
height:83px;
position:absolute;
left:16px;
top:16px;
background-image:url(logo_pyconfr_1.png);
background-repeat:no-repeat;
background-size:cover;
}

25
template/template.html Normal file
View File

@ -0,0 +1,25 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Html Generated</title>
<meta name="description" content="Figma htmlGenerator">
<meta name="author" content="htmlGenerator">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
<style>
/*
Figma Background for illustrative/preview purposes only.
You can remove this style tag with no consequence
*/
body {background: #E5E5E5; }
</style>
</head>
<body>
<div class=e1_3><div class=e1_4><div class="e4_34"></div></div><div class=e1_8><span class="e1_9">{{type}}</span><div class=e1_10><span class="e1_11">{{title}}</span><span class="e1_12">{{type}} de {{author}}</span></div></div><div class=e1_13><div class=e1_15><span class="e1_16">{{date}}</span><span class="e1_17">Université de Bordeaux · {{salle}}</span></div><div class="e4_35"></div></div></div>
</body>
</html>

1
template/variables.scss Normal file
View File

@ -0,0 +1 @@
$fira sans-font : "Fira Sans"