Add ability to use more pictures

This commit is contained in:
2026-08-30 10:48:26 +03:00
parent 334d65c4d8
commit 9540aea3be
8 changed files with 68 additions and 11 deletions
+56 -6
View File
@@ -91,6 +91,15 @@ def init_db():
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS post_images (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL,
filename TEXT UNIQUE NOT NULL,
caption TEXT NOT NULL DEFAULT '',
position INTEGER NOT NULL,
created_at TEXT NOT NULL,
FOREIGN KEY (post_id) REFERENCES posts(id)
);
"""
)
user_columns = {row["name"] for row in db.execute("PRAGMA table_info(users)")}
@@ -168,8 +177,7 @@ def post_from_request(post_id=None):
return title, unique_slug(title, post_id), excerpt, body, category, now
def save_post_image():
image_file = request.files.get("image")
def save_post_image(image_file):
if image_file is None or not image_file.filename:
return None
try:
@@ -189,6 +197,43 @@ def save_post_image():
return filename
def save_inline_images(post_id):
image_files = [image_file for image_file in request.files.getlist("images") if image_file.filename]
captions = request.form.getlist("image_captions")
if not image_files:
return
next_position = get_db().execute(
"SELECT COALESCE(MAX(position), 0) + 1 FROM post_images WHERE post_id = ?", (post_id,)
).fetchone()[0]
now = datetime.now(timezone.utc).isoformat()
for offset, image_file in enumerate(image_files):
filename = save_post_image(image_file)
caption = captions[offset].strip() if offset < len(captions) else ""
get_db().execute(
"INSERT INTO post_images (post_id, filename, caption, position, created_at) VALUES (?, ?, ?, ?, ?)",
(post_id, filename, caption, next_position + offset, now),
)
def article_blocks(body, images):
image_map = {str(index): image for index, image in enumerate(images, start=1)}
blocks = []
marker = re.compile(r"\[\[image:(\d+)\]\]")
cursor = 0
for match in marker.finditer(body):
if match.start() > cursor:
blocks.append(("text", body[cursor:match.start()]))
image = image_map.get(match.group(1))
if image is not None:
blocks.append(("image", image))
else:
blocks.append(("text", match.group(0)))
cursor = match.end()
if cursor < len(body):
blocks.append(("text", body[cursor:]))
return blocks
def valid_email(email):
return re.fullmatch(r"[^\s@]+@[^\s@]+\.[^\s@]+", email) is not None
@@ -249,7 +294,8 @@ def post(slug):
).fetchone()
if article is None:
abort(404)
return render_template("post.html", post=article)
images = get_db().execute("SELECT * FROM post_images WHERE post_id = ? ORDER BY position", (article["id"],)).fetchall()
return render_template("post.html", post=article, blocks=article_blocks(article["body"], images))
@app.get("/uploads/<path:filename>")
@@ -458,12 +504,14 @@ def write():
if request.method == "POST":
try:
title, slug, excerpt, body, category, now = post_from_request()
image_filename = save_post_image()
get_db().execute(
image_file = request.files.get("image")
image_filename = save_post_image(image_file) if image_file and image_file.filename else None
cursor = get_db().execute(
"""INSERT INTO posts (title, slug, excerpt, body, category, image_filename, author_id, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(title, slug, excerpt, body, category, image_filename, session["user_id"], now, now),
)
save_inline_images(cursor.lastrowid)
get_db().commit()
return redirect(url_for("post", slug=slug))
except ValueError as error:
@@ -482,11 +530,13 @@ def edit_post(slug):
if request.method == "POST":
try:
title, new_slug, excerpt, body, category, now = post_from_request(article["id"])
image_filename = save_post_image() or article["image_filename"]
image_file = request.files.get("image")
image_filename = save_post_image(image_file) if image_file and image_file.filename else article["image_filename"]
get_db().execute(
"""UPDATE posts SET title=?, slug=?, excerpt=?, body=?, category=?, image_filename=?, updated_at=? WHERE id=?""",
(title, new_slug, excerpt, body, category, image_filename, now, article["id"]),
)
save_inline_images(article["id"])
get_db().commit()
if image_filename != article["image_filename"] and article["image_filename"]:
(app.config["UPLOAD_FOLDER"] / article["image_filename"]).unlink(missing_ok=True)