# retoor from molodetz.database import ( insert_post, soft_delete, update_post_row, now_iso, db, ) from molodetz.constants import LEGACY_TOPICS from molodetz.database.core import make_combined_slug from molodetz.utils.audit import record from molodetz.utils.notifications import create_notification PLACEHOLDER_NOTE = ( "\n\n> Placeholder. Carried over from the old Molodetz page. " "retoor will replace it with his own story." ) def create_post(user, title, body, topic, status="draft", is_placeholder=False, request=None): if is_placeholder and PLACEHOLDER_NOTE.strip() not in body: body = body.rstrip() + PLACEHOLDER_NOTE row = insert_post(user["uid"], title, body, topic, status=status, is_placeholder=is_placeholder) record(request, "post.create", payload={"uid": row["uid"], "status": status}, targets=[("post", row["uid"])], user=user) if status == "published": create_notification(user["uid"], "post.published", f"Published: {title}", f"/posts/{row['slug']}") return row def edit_post(post, user, title, body, topic, status, is_placeholder=False, request=None): fields = { "title": title, "body": body, "topic": topic, "status": status, "is_placeholder": bool(is_placeholder), "updated_at": now_iso(), } if status == "published" and not post.get("published_at"): fields["published_at"] = now_iso() update_post_row(post["uid"], **fields) record(request, "post.edit", payload={"uid": post["uid"]}, targets=[("post", post["uid"])], user=user) return {**post, **fields} def delete_post(post, actor, request=None): stamp = now_iso() soft_delete("posts", actor["uid"], stamp=stamp, uid=post["uid"]) record( request, "post.delete", payload={"uid": post["uid"], "stamp": stamp}, targets=[("post", post["uid"])], user=actor, ) return stamp SEED_POSTS = [ ( "standard", "Thirty-one choices. You have zero.", "Python 3.12. FastAPI. Jinja2. SQLite. No JWT, because that is a hobby. No JavaScript framework, because that is a catalogue. The document says MUST 107 times. Whoever turns that into \"it depends\" has no taste. They have a roadmap made of other people's tutorials.", ), ("roll", "A pass is not an ambition.", "Settle for good enough and you build good enough. Molodetz starts where that stops."), ("roll", "Finished is a feature.", "A project that stays open is an opinion. A project that is finished is a fact."), ("roll", "The assistant is not a senior.", "AI speeds up the work. It does not replace judgement. Confuse the two and you hand in a chat log."), ("roll", "No course.", "Knowledge travels here from people to people. Not through an ebook promising you will become someone else over a weekend."), ] LEGACY_SEED_TITLES = { "Eenendertig keuzes. Jij hebt er nul.": "Thirty-one choices. You have zero.", "Een zes is geen ambitie.": "A pass is not an ambition.", "Af is een eigenschap.": "Finished is a feature.", "De assistent is geen senior.": "The assistant is not a senior.", "Geen cursus.": "No course.", } def seed_placeholder_posts(admin): created = [] for topic, title, body in SEED_POSTS: existing = db["posts"].find_one(title=title, deleted_at=None) if "posts" in db.tables else None if existing: continue created.append(create_post(admin, title, body, topic, status="published", is_placeholder=topic == "roll")) return created def translate_seeded_posts(): if "posts" not in db.tables: return 0 seeds = {title: (topic, body) for topic, title, body in SEED_POSTS} table = db["posts"] for old, new in LEGACY_TOPICS.items(): for row in list(table.find(topic=old)): table.update({"uid": row["uid"], "topic": new}, ["uid"]) changed = 0 for dutch, english in LEGACY_SEED_TITLES.items(): topic, body = seeds[english] for row in list(table.find(title=dutch)): body_out = body.rstrip() + PLACEHOLDER_NOTE if row.get("is_placeholder") else body table.update( { "uid": row["uid"], "title": english, "body": body_out, "topic": topic, "slug": make_combined_slug(english, row["uid"]), "updated_at": now_iso(), }, ["uid"], ) changed += 1 return changed