Skip to content

Commit e378b7c

Browse files
committed
feat: data update, static RSS
1 parent c9974f9 commit e378b7c

6 files changed

Lines changed: 2175 additions & 964 deletions

File tree

.github/workflows/update-all-data.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
8282
8383
# Add specific files
84-
git add src/lib/data/data.csv static/recent_updates.json
84+
git add src/lib/data/data.csv static/recent_updates.json static/rss.xml
8585
8686
# Check if there are changes
8787
if git diff --staged --quiet; then

scripts/data_import.py

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ def get_date(x):
307307
return ''
308308

309309
new_films.sort(key=get_date, reverse=True)
310-
311310
recent_updates = new_films[:limit]
312311

313312
os.makedirs(os.path.dirname(output_json_path), exist_ok=True)
@@ -316,9 +315,123 @@ def get_date(x):
316315

317316
print(f"Saved {len(recent_updates)} recent updates to {output_json_path}")
318317

318+
# GENERATE RSS
319+
generate_rss_feed(recent_updates)
320+
319321
except Exception as e:
320322
print(f"Error generating recent updates: {e}")
321323

324+
def generate_rss_feed(films, output_path="static/rss.xml"):
325+
"""Generate RSS feed from recent films list."""
326+
from html import escape
327+
import base64
328+
329+
print("Generating static RSS feed...")
330+
331+
rss_items = []
332+
333+
for film in films:
334+
title = escape(f"CBFC Watch: {film.get('movie_name', 'Unknown')} ({film.get('year', '')}) - {film.get('language', '')}")
335+
link = f"https://www.cbmcwatch.com/film/{film.get('slug', '')}"
336+
337+
try:
338+
date_obj = datetime.strptime(film.get('cert_date', ''), '%Y-%m-%d')
339+
pub_date = date_obj.strftime("%a, %d %b %Y 00:00:00 GMT")
340+
except:
341+
pub_date = ""
342+
343+
# Description Construction
344+
desc_html = ""
345+
346+
# Poster
347+
if film.get('imdb_poster_url'):
348+
desc_html += f'<img src="{escape(film.get("imdb_poster_url"))}" alt="{escape(film.get("movie_name", ""))}" style="width: 150px; height: 225px; object-fit: cover;" /><br/>'
349+
350+
# Rating & IMDb
351+
if film.get('imdb_rating') or film.get('rating'):
352+
meta_parts = []
353+
if film.get('rating'): meta_parts.append(f"Certificate: {film.get('rating')}")
354+
if film.get('imdb_rating'): meta_parts.append(f"IMDb: {film.get('imdb_rating')}/10")
355+
desc_html += f'<p><strong>Rating:</strong> {escape(" | ".join(meta_parts))}</p>'
356+
357+
# Overview
358+
if film.get('imdb_overview'):
359+
desc_html += f'<p>{escape(film.get("imdb_overview"))}</p>'
360+
361+
# Credits
362+
credits = []
363+
if film.get('imdb_directors'):
364+
d = ", ".join(film.get('imdb_directors').split('|')[:3])
365+
credits.append(f"<strong>Director:</strong> {escape(d)}")
366+
if film.get('imdb_actors'):
367+
a = ", ".join(film.get('imdb_actors').split('|')[:4])
368+
credits.append(f"<strong>Cast:</strong> {escape(a)}")
369+
if credits:
370+
desc_html += f'<p>{" | ".join(credits)}</p>'
371+
372+
desc_html += "<hr/>"
373+
374+
# Modifications
375+
mod_desc = film.get('ai_cleaned_description') or film.get('description') or 'No description'
376+
cut_no = film.get('cut_no') or '1'
377+
378+
desc_html += "<h3><strong>Modifications</strong></h3><ul>"
379+
desc_html += f"<li><strong>#{cut_no}:</strong> {escape(mod_desc)}</li>"
380+
desc_html += "</ul>"
381+
382+
# Footer Links
383+
links = []
384+
links.append(f'<a href="{link}">View on CBFC Watch</a>')
385+
if film.get('imdb_id'):
386+
imdb_clean = film.get('imdb_id', '').split('.')[0].zfill(7)
387+
links.append(f'<a href="https://www.imdb.com/title/tt{imdb_clean}/">IMDb</a>')
388+
389+
if film.get('id'):
390+
links.append(f'<a href="https://www.ecinepramaan.gov.in/cbfc/?a=Certificate_Detail&i={escape(film.get("id"))}">E-Cinepramaan</a>')
391+
392+
if film.get('cbfc_file_no'):
393+
try:
394+
encoded = base64.b64encode(film.get('cbfc_file_no').encode('utf-8')).decode('utf-8')
395+
links.append(f'<a href="https://www.cbfcindia.gov.in/cbfcAdmin/search-result.php?recid={encoded}">CBFC Listing</a>')
396+
except:
397+
pass
398+
399+
desc_html += f'<p>{" | ".join(links)}</p>'
400+
401+
if film.get('id'):
402+
desc_html += f'<p><em>For original modifications, refer to <a href="https://www.ecinepramaan.gov.in/cbfc/?a=Certificate_Detail&i={escape(film.get("id"))}">E-Cinepramaan</a></em></p>'
403+
404+
rss_items.append(f""" <item>
405+
<title>{title}</title>
406+
<link>{link}</link>
407+
<pubDate>{pub_date}</pubDate>
408+
<guid isPermaLink="false">{film.get('slug', 'unknown')}</guid>
409+
<description><![CDATA[{desc_html}]]></description>
410+
<media:content url="{escape(film.get('imdb_poster_url', ''))}" medium="image" />
411+
</item>""")
412+
413+
rss_xml = f"""<?xml version="1.0" encoding="UTF-8" ?>
414+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dc="http://purl.org/dc/elements/1.1/">
415+
<channel>
416+
<title>CBFC Watch - Recent Certifications</title>
417+
<link>https://www.cbmcwatch.com</link>
418+
<description>Latest film certifications and censorship records from the Central Board of Film Certification, India.</description>
419+
<language>en</language>
420+
<lastBuildDate>{datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT")}</lastBuildDate>
421+
<atom:link href="https://www.cbmcwatch.com/rss.xml" rel="self" type="application/rss+xml" />
422+
"""
423+
rss_xml += "\n".join(rss_items)
424+
rss_xml += """
425+
</channel>
426+
</rss>"""
427+
428+
try:
429+
with open(output_path, 'w', encoding='utf-8') as f:
430+
f.write(rss_xml)
431+
print(f"Saved static RSS feed to {output_path}")
432+
except Exception as e:
433+
print(f"Error saving RSS feed: {e}")
434+
322435
def fetch_remote_data(output_path="src/lib/data/data.csv", limit=20):
323436
"""Fetch latest data from remote source by cloning the repo."""
324437
os.makedirs(os.path.dirname(output_path), exist_ok=True)

0 commit comments

Comments
 (0)