@@ -206,11 +206,13 @@ def _load_data(out_dir: Path) -> SiteData:
206206 sd .today = datetime .now (tz = SWEDEN_TZ ).date ()
207207
208208 print ("Reading screenings…" )
209- sd .screenings = read_screenings (path = SCREENINGS_FILE )
210- print (f" { len (sd .screenings )} screenings" )
209+ all_screenings = read_screenings (path = SCREENINGS_FILE )
210+ sd .screenings = [s for s in all_screenings if s .date >= sd .today ]
211+ print (f" { len (sd .screenings )} screenings ({ len (all_screenings ) - len (sd .screenings )} past, skipped)" )
211212
212- # Today through end of next week (same weekday)
213- sd .days = [sd .today + timedelta (days = i ) for i in range (8 )]
213+ # Days are computed per-page from screening dates; keep a global
214+ # reference only for today.
215+ sd .days = []
214216
215217 tmdb_ids : set [int ] = set ()
216218 for s in sd .screenings :
@@ -347,11 +349,8 @@ def _build_premiarer(env: Environment, sd: SiteData) -> None:
347349
348350 # Premiere date: prefer Swedish release date from TMDB, fall back to
349351 # earliest screening date.
350- day_set = set (sd .days )
351352 first_screening : dict [int , date ] = {}
352353 for s in sd .screenings :
353- if s .date not in day_set :
354- continue
355354 if s .tmdb_id not in first_screening or s .date < first_screening [s .tmdb_id ]:
356355 first_screening [s .tmdb_id ] = s .date
357356
@@ -402,8 +401,7 @@ def _premiere_date(tmdb_id: int) -> date | None:
402401def _build_filmer (env : Environment , sd : SiteData ) -> None :
403402 print ("Building /filmer/" )
404403
405- day_set = set (sd .days )
406- screening_ids = {s .tmdb_id for s in sd .screenings if s .date in day_set }
404+ screening_ids = {s .tmdb_id for s in sd .screenings }
407405 movies = [m for m in sd .movies .values () if m .tmdb_id in screening_ids ]
408406 movies .sort (key = lambda m : m .title_sv .lower ())
409407
@@ -432,34 +430,45 @@ def _build_filmer(env: Environment, sd: SiteData) -> None:
432430# ---------------------------------------------------------------------------
433431
434432
433+ def _compute_days (screenings : list [Screening ]) -> list [date ]:
434+ """Return sorted list of dates that have at least one screening."""
435+ dates = {s .date for s in screenings }
436+ return sorted (dates )
437+
438+
435439def _prepare_programme_blocks (
436440 sd : SiteData ,
437441 screenings : list [Screening ],
442+ days : list [date ],
438443 * ,
439444 city : str | None = None ,
440445) -> list [dict ]:
441446 """Prepare template-ready block dicts for a programme page."""
442447
443448 now = datetime .now (tz = SWEDEN_TZ )
444- day_set = set (sd . days )
449+ day_set = set (days )
445450 filtered = [s for s in screenings if s .date in day_set ]
446451
447452 # movie → (city, cinema) → day → [(time, url)]
448453 movie_cinemas : dict [int , dict [tuple [str , str ], dict [int , list [tuple [time , str ]]]]] = defaultdict (
449454 lambda : defaultdict (lambda : defaultdict (list ))
450455 )
451456 movie_counts : dict [int , int ] = defaultdict (int )
457+ movie_earliest : dict [int , tuple [date , time ]] = {}
452458
453459 for s in filtered :
454460 try :
455- day_idx = sd . days .index (s .date )
461+ day_idx = days .index (s .date )
456462 except ValueError :
457463 continue
458464 movie_cinemas [s .tmdb_id ][(s .city , s .cinema_name )][day_idx ].append ((s .time , s .ticket_url ))
459465 movie_counts [s .tmdb_id ] += 1
466+ key = (s .date , s .time )
467+ if s .tmdb_id not in movie_earliest or key < movie_earliest [s .tmdb_id ]:
468+ movie_earliest [s .tmdb_id ] = key
460469
461470 blocks = []
462- for tmdb_id in sorted (movie_cinemas , key = lambda tid : - movie_counts [ tid ] ):
471+ for tmdb_id in sorted (movie_cinemas , key = lambda tid : ( - movie_counts . get ( tid , 0 ), movie_earliest . get ( tid , ( date . max , time . max ))) ):
463472 movie = sd .movies .get (tmdb_id )
464473 film_title = movie .title_sv if movie else f"Film { tmdb_id } "
465474 film_slug = sd .film_slugs .get (film_title , _slugify_sv (film_title ))
@@ -502,12 +511,12 @@ def _prepare_programme_blocks(
502511
503512 cells = []
504513 max_h = 55.0
505- for day_idx in range (len (sd . days )):
514+ for day_idx in range (len (days )):
506515 raw = day_times .get (day_idx , [])
507516 positions = _compute_time_positions (raw )
508517 # Mark past times
509518 for p in positions :
510- dt = datetime .combine (sd . days [day_idx ], time (* map (int , p ["label" ].split (":" ))), tzinfo = SWEDEN_TZ )
519+ dt = datetime .combine (days [day_idx ], time (* map (int , p ["label" ].split (":" ))), tzinfo = SWEDEN_TZ )
511520 p ["past" ] = dt < now
512521 h = _cell_min_height (positions )
513522 if h > max_h :
@@ -567,15 +576,16 @@ def _write_programme(
567576 out_path : Path ,
568577 city : str | None = None ,
569578) -> None :
570- blocks = _prepare_programme_blocks (sd , screenings , city = city )
571- days = [{"label" : _format_day (d )} for d in sd .days ]
579+ page_days = _compute_days (screenings )
580+ blocks = _prepare_programme_blocks (sd , screenings , page_days , city = city )
581+ days = [{"label" : _format_day (d )} for d in page_days ]
572582
573583 tmpl = env .get_template ("program.html" )
574584 html = tmpl .render (
575585 title = title ,
576586 breadcrumbs = breadcrumbs ,
577587 days = days ,
578- num_days = len (sd . days ),
588+ num_days = len (page_days ),
579589 blocks = blocks ,
580590 )
581591 out_path .parent .mkdir (parents = True , exist_ok = True )
0 commit comments