French-Coach / backfill_class_dates.py
Asma-F's picture
Deploy: fixed React routing + OpenBMB backend
cc13fc9 verified
Raw
History Blame Contribute Delete
2.22 kB
"""
One-off script: assign real-feeling sequential dates to the "Class N M" /
"Class A2 ..." lecture pages, which were all imported with the same date
(the day of the Notion export). These 20 pages are an actual chronological
course sequence (Class 1.1 -> 1.5, 2.1 -> 2.7, A2 1 -> 3, A2 U1 L4 -> L6,
A2 U2 L1 -> L2), so we space them every other day starting April 28 — that
lands the last one (Class A2 U2 L2) on June 5, just before "today".
Run from the host (uses localhost:5432) or inside the app container.
Usage:
python backfill_class_dates.py [--dry-run]
"""
import os
import sys
from datetime import date, timedelta
import psycopg2
from psycopg2.extras import RealDictCursor
USER_ID = "dev_user"
START_DATE = date(2026, 4, 28)
STEP_DAYS = 2
DATABASE_URL = os.environ.get(
"DATABASE_URL",
"postgresql://postgres:localdevpassword@localhost:5432/frenchcoach",
).replace("@db:", "@localhost:")
# Chronological order of the course sequence
CLASS_TITLES = (
[f"Class 1 {n}" for n in range(1, 6)]
+ [f"Class 2 {n}" for n in range(1, 8)]
+ [f"Class A2 {n}" for n in range(1, 4)]
+ [f"Class A2 U1 L{n}" for n in range(4, 7)]
+ [f"Class A2 U2 L{n}" for n in range(1, 3)]
)
def main():
dry_run = "--dry-run" in sys.argv
conn = psycopg2.connect(DATABASE_URL)
with conn.cursor(cursor_factory=RealDictCursor) as cur:
for i, title in enumerate(CLASS_TITLES):
new_date = START_DATE + timedelta(days=i * STEP_DAYS)
cur.execute(
"SELECT id::text, date::text FROM pages WHERE user_id = %s AND title = %s",
(USER_ID, title),
)
row = cur.fetchone()
if not row:
print(f" ⚠ not found: {title!r}")
continue
print(f" {title:<18} {row['date']} -> {new_date.isoformat()}")
if not dry_run:
cur.execute("UPDATE pages SET date = %s WHERE id = %s", (new_date, row["id"]))
if dry_run:
conn.rollback()
print("\n(dry run — no changes made)")
else:
conn.commit()
print(f"\nUpdated {len(CLASS_TITLES)} lesson dates.")
conn.close()
if __name__ == "__main__":
main()