feat: add RSS feed generation support - #3
raofal-msodeh wants to merge 1 commit into
Conversation
This commit introduces automatic RSS 2.0 feed generation to the static site generator. It includes: - A new generate_rss_feed method in StaticSiteGenerator. - Integration of RSS generation into the build process. - Auto-discovery link and footer link in the base template. - Support for site_url, site_name, and site_description from config.yaml.
📝 WalkthroughWalkthroughThe generator now generates an RSS 2.0 feed during build via a new Changes
Sequence DiagramsequenceDiagram
participant Build as Build Process
participant Gen as Generator
participant Config as Configuration
participant Pages as Pages Collection
participant FS as File System
Build->>Gen: build()
Gen->>Gen: generate_rss_feed()
Gen->>Config: Read site metadata
Config-->>Gen: site_url, site_name, site_description
Gen->>Pages: Access and sort by date
Pages-->>Gen: Sorted pages (descending)
Gen->>Gen: Filter top 20 items
Gen->>Gen: Generate RSS metadata
Gen->>Gen: Format feed with items
Gen->>FS: Write rss.xml
FS-->>Gen: File written
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
generator/templates/base.html (1)
67-67: Optional: add an accessible label to the RSS footer link.The icon-plus-text is fine for sighted users, but consider an explicit
aria-label(ortitle) so the link's purpose is unambiguous to assistive tech, especially since the icon is decorative.♻️ Suggested tweak
- <a href="/rss.xml" class="text-white me-3"><i class="bi bi-rss-fill"></i> RSS</a> + <a href="/rss.xml" class="text-white me-3" aria-label="RSS feed" title="Subscribe via RSS"><i class="bi bi-rss-fill" aria-hidden="true"></i> RSS</a>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@generator/templates/base.html` at line 67, The RSS footer link (<a href="/rss.xml" class="text-white me-3">) should include an explicit accessible label so screen readers understand its purpose; update that anchor to add an aria-label (or title) such as "RSS feed" (e.g., aria-label="RSS feed") while keeping the existing icon and text unchanged to provide clear intent for assistive technology.generator/generator.py (2)
248-294: Recommended: consider usingfeedgen(or stdlibxml.etree.ElementTree) instead of hand-built strings.Hand-rolled XML via
str.append/f-strings is the root cause of the escaping and CDATA edge cases above.feedgenis widely used for RSS/Atom and handles escaping, namespaces, and date formatting correctly. If adding a dependency isn't desirable, building the tree withxml.etree.ElementTreeand callingElementTree.tostring(...)gets you correct escaping for free.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@generator/generator.py` around lines 248 - 294, The generate_rss_feed function currently builds RSS XML by concatenating strings (rss_lines), which risks escaping and CDATA issues; replace the hand-rolled construction with a proper RSS builder — either use feedgen (FeedGenerator) to create the feed and add entries from self.pages (use metadata['title'], ['description'], ['date'] and page['url']), or use xml.etree.ElementTree to build an Element tree (root rss -> channel -> item entries) so namespaces, escaping, and RFC-822 pubDate formatting are handled correctly; ensure the atom:link, lastBuildDate, and only the latest 20 pages are added, then serialize the tree/FeedGenerator output to rss_path (self.output_dir / 'rss.xml') with UTF-8 encoding.
260-260: Minor: drop thefprefix — no placeholders (Ruff F541).- rss_lines.append(f' <language>en-us</language>') + language = self.config.get('language', 'en-us') + rss_lines.append(f' <language>{language}</language>')Bonus: sourcing the language from config lets non-English sites produce a correct feed instead of always advertising
en-us.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@generator/generator.py` at line 260, The line using rss_lines.append currently uses an unnecessary f-string and hardcodes "en-us"; change rss_lines.append to use a regular string (remove the f prefix) and instead source the language from your configuration with a fallback to "en-us" so non-English sites get correct feeds (use the existing config object, e.g. config.get('language', 'en-us') or self.config.language with a default) and call rss_lines.append with that value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@generator/generator.py`:
- Line 261: The code uses datetime.now() and hard-codes "+0000" when building
RSS timestamps (e.g., the rss_lines.append call that writes <lastBuildDate> and
the similar fallback <pubDate> construction), which mixes local time with a UTC
offset; replace datetime.now() with a UTC-aware datetime (e.g.,
datetime.utcnow() or datetime.now(timezone.utc)) and either format with a real
offset via %z or remove the hard-coded "+0000" so the timestamp is correct;
update both the <lastBuildDate> append and the pubDate fallback construction in
generator.py accordingly.
- Around line 257-262: Escape XML-special characters before interpolating into
RSS/ sitemap strings: instead of directly appending f-strings with site_name,
site_description, page["metadata"]["title"], page["url"], and base_url in
generator.py (the rss_lines.append calls and the generate_sitemap block at the
earlier sitemap lines), run those values through xml.sax.saxutils.escape (or
equivalent) and use the escaped values in the f-strings; for descriptions that
may include "]]>" either escape them or replace "]]>" with "]]>" (or
consistently use escaped text rather than CDATA), and ensure atom:link href and
any URLs are escaped as well so generated RSS and sitemap XML are always valid.
- Around line 278-279: The bare except: should be replaced with a specific
exception handler to avoid swallowing SystemExit/KeyboardInterrupt; change it to
catch the exceptions that datetime parsing can raise (e.g., except (ValueError,
TypeError) as e) and keep the fallback assignment to formatted_date =
datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000"); reference the existing
formatted_date assignment and ensure the except targets ValueError/TypeError
rather than a bare except.
- Around line 265-279: The YAML-parsed `date` fields are datetime.date objects
causing sorting and strptime to fail; normalize dates when you parse files so
downstream code can assume a consistent string format: in parse_markdown_file
detect metadata['date'] (use isinstance(..., date) or datetime.date), convert it
to an ISO string like 'YYYY-MM-DD' (or store None/'') and replace the original
value, and ensure metadata always contains a string or empty string for date;
then you can safely use sorted(self.pages, key=lambda x:
x['metadata'].get('date',''), reverse=True) in
generate_index_page/generate_sitemap and keep the pub_date handling around
pub_date/datetime.strptime without TypeError.
---
Nitpick comments:
In `@generator/generator.py`:
- Around line 248-294: The generate_rss_feed function currently builds RSS XML
by concatenating strings (rss_lines), which risks escaping and CDATA issues;
replace the hand-rolled construction with a proper RSS builder — either use
feedgen (FeedGenerator) to create the feed and add entries from self.pages (use
metadata['title'], ['description'], ['date'] and page['url']), or use
xml.etree.ElementTree to build an Element tree (root rss -> channel -> item
entries) so namespaces, escaping, and RFC-822 pubDate formatting are handled
correctly; ensure the atom:link, lastBuildDate, and only the latest 20 pages are
added, then serialize the tree/FeedGenerator output to rss_path (self.output_dir
/ 'rss.xml') with UTF-8 encoding.
- Line 260: The line using rss_lines.append currently uses an unnecessary
f-string and hardcodes "en-us"; change rss_lines.append to use a regular string
(remove the f prefix) and instead source the language from your configuration
with a fallback to "en-us" so non-English sites get correct feeds (use the
existing config object, e.g. config.get('language', 'en-us') or
self.config.language with a default) and call rss_lines.append with that value.
In `@generator/templates/base.html`:
- Line 67: The RSS footer link (<a href="/rss.xml" class="text-white me-3">)
should include an explicit accessible label so screen readers understand its
purpose; update that anchor to add an aria-label (or title) such as "RSS feed"
(e.g., aria-label="RSS feed") while keeping the existing icon and text unchanged
to provide clear intent for assistive technology.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 72f56ce5-884f-4004-8407-e2cf971d46aa
📒 Files selected for processing (2)
generator/generator.pygenerator/templates/base.html
| rss_lines.append(f' <title>{site_name}</title>') | ||
| rss_lines.append(f' <link>{base_url}</link>') | ||
| rss_lines.append(f' <description>{site_description}</description>') | ||
| rss_lines.append(f' <language>en-us</language>') | ||
| rss_lines.append(f' <lastBuildDate>{datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")}</lastBuildDate>') | ||
| rss_lines.append(f' <atom:link href="{base_url}/rss.xml" rel="self" type="application/rss+xml" />') |
There was a problem hiding this comment.
Critical: RSS output is not XML-escaped — special characters will produce invalid feeds.
site_name, site_description, page["metadata"]["title"], page["url"], and base_url are interpolated directly into XML via f-strings without escaping. Any &, <, >, or quote in a title/description (e.g., a post titled Tips & Tricks or a URL with ?a=1&b=2) will yield a malformed RSS document that feed readers and validators will reject. The <![CDATA[...]]> wrapper also breaks if the description ever contains the sequence ]]>.
This is the same class of issue as generate_sitemap at lines 230–246, which should also be fixed for consistency.
🛡️ Suggested fix using xml.sax.saxutils
@@
-import os
+import os
+from xml.sax.saxutils import escape as xml_escape, quoteattr
@@
def generate_rss_feed(self):
"""Generate RSS 2.0 feed for the site"""
base_url = self.config.get('site_url', 'https://example.com').rstrip('/')
site_name = self.config.get('site_name', 'My Static Site')
site_description = self.config.get('site_description', 'A modern static site')
@@
- rss_lines.append(f' <title>{site_name}</title>')
- rss_lines.append(f' <link>{base_url}</link>')
- rss_lines.append(f' <description>{site_description}</description>')
+ rss_lines.append(f' <title>{xml_escape(site_name)}</title>')
+ rss_lines.append(f' <link>{xml_escape(base_url)}</link>')
+ rss_lines.append(f' <description>{xml_escape(site_description)}</description>')
@@
- rss_lines.append(' <item>')
- rss_lines.append(f' <title>{page["metadata"].get("title", "Untitled")}</title>')
- rss_lines.append(f' <link>{base_url}{page["url"]}</link>')
- rss_lines.append(f' <guid isPermaLink="true">{base_url}{page["url"]}</guid>')
- rss_lines.append(f' <pubDate>{formatted_date}</pubDate>')
- rss_lines.append(f' <description><![CDATA[{page["metadata"].get("description", "")}]]></description>')
- rss_lines.append(' </item>')
+ title = xml_escape(str(page["metadata"].get("title", "Untitled")))
+ item_link = xml_escape(f'{base_url}{page["url"]}')
+ description = str(page["metadata"].get("description", "")).replace(']]>', ']]]]><![CDATA[>')
+ rss_lines.append(' <item>')
+ rss_lines.append(f' <title>{title}</title>')
+ rss_lines.append(f' <link>{item_link}</link>')
+ rss_lines.append(f' <guid isPermaLink="true">{item_link}</guid>')
+ rss_lines.append(f' <pubDate>{formatted_date}</pubDate>')
+ rss_lines.append(f' <description><![CDATA[{description}]]></description>')
+ rss_lines.append(' </item>')Alternatively, consider feedgen which handles all of this (and namespacing/validation) for you.
Also applies to: 282-286
🧰 Tools
🪛 Ruff (0.15.11)
[error] 260-260: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generator/generator.py` around lines 257 - 262, Escape XML-special characters
before interpolating into RSS/ sitemap strings: instead of directly appending
f-strings with site_name, site_description, page["metadata"]["title"],
page["url"], and base_url in generator.py (the rss_lines.append calls and the
generate_sitemap block at the earlier sitemap lines), run those values through
xml.sax.saxutils.escape (or equivalent) and use the escaped values in the
f-strings; for descriptions that may include "]]>" either escape them or replace
"]]>" with "]]>" (or consistently use escaped text rather than CDATA), and
ensure atom:link href and any URLs are escaped as well so generated RSS and
sitemap XML are always valid.
| rss_lines.append(f' <link>{base_url}</link>') | ||
| rss_lines.append(f' <description>{site_description}</description>') | ||
| rss_lines.append(f' <language>en-us</language>') | ||
| rss_lines.append(f' <lastBuildDate>{datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")}</lastBuildDate>') |
There was a problem hiding this comment.
Minor: lastBuildDate / fallback pubDate mix local time with +0000.
datetime.now() returns local time, but the format string hard-codes +0000 (UTC). On any non-UTC host this yields incorrect timestamps in the feed. Use datetime.utcnow() (or datetime.now(timezone.utc)) — or emit a real offset via %z on a timezone-aware datetime.
♻️ Diff
- rss_lines.append(f' <lastBuildDate>{datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")}</lastBuildDate>')
+ rss_lines.append(f' <lastBuildDate>{datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")}</lastBuildDate>')Also applies to: 279-279
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generator/generator.py` at line 261, The code uses datetime.now() and
hard-codes "+0000" when building RSS timestamps (e.g., the rss_lines.append call
that writes <lastBuildDate> and the similar fallback <pubDate> construction),
which mixes local time with a UTC offset; replace datetime.now() with a
UTC-aware datetime (e.g., datetime.utcnow() or datetime.now(timezone.utc)) and
either format with a real offset via %z or remove the hard-coded "+0000" so the
timestamp is correct; update both the <lastBuildDate> append and the pubDate
fallback construction in generator.py accordingly.
| sorted_pages = sorted( | ||
| self.pages, | ||
| key=lambda x: x['metadata'].get('date', ''), | ||
| reverse=True | ||
| ) | ||
|
|
||
| # Only include the latest 20 items in RSS | ||
| for page in sorted_pages[:20]: | ||
| # Skip pages without a date or index page if desired, but usually all content is fine | ||
| pub_date = page['metadata'].get('date', datetime.now().strftime('%Y-%m-%d')) | ||
| try: | ||
| dt = datetime.strptime(pub_date, '%Y-%m-%d') | ||
| formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000") | ||
| except: | ||
| formatted_date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect a few content frontmatter dates to confirm whether they are quoted strings or bare YAML dates.
fd -e md . content 2>/dev/null | head -20 | xargs -I{} sh -c 'echo "=== {} ==="; sed -n "1,15p" "{}"'Repository: Alqudimi/MarkSite
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Explore repository structure
find . -type f -name "*.py" | grep -i generator | head -10
ls -laRepository: Alqudimi/MarkSite
Length of output: 971
🏁 Script executed:
#!/bin/bash
# Look for content files or examples
fd -e md . 2>/dev/null | head -20
find . -name "*.md" -type f | head -20Repository: Alqudimi/MarkSite
Length of output: 463
🏁 Script executed:
#!/bin/bash
# Read the generator.py file to inspect the actual code
cat -n generator/generator.py | sed -n '1,50p'
wc -l generator/generator.pyRepository: Alqudimi/MarkSite
Length of output: 2032
🏁 Script executed:
#!/bin/bash
# Read the relevant sections of generator.py
cat -n generator/generator.py | sed -n '170,190p'
echo "---"
cat -n generator/generator.py | sed -n '230,250p'
echo "---"
cat -n generator/generator.py | sed -n '260,285p'Repository: Alqudimi/MarkSite
Length of output: 3611
🏁 Script executed:
#!/bin/bash
# Check parse_markdown_file function
rg -n "def parse_markdown_file" generator/generator.py -A 20Repository: Alqudimi/MarkSite
Length of output: 1060
🏁 Script executed:
#!/bin/bash
# Check for sample markdown files in doc directory
cat doc/index.md | head -20Repository: Alqudimi/MarkSite
Length of output: 946
🏁 Script executed:
#!/bin/bash
# Test frontmatter date parsing behavior
python3 << 'EOF'
import frontmatter
from datetime import datetime, date
# Test 1: Parse markdown with bare YAML date (no quotes)
test_markdown_bare = """---
title: Test Post
date: 2025-01-15
---
# Test Content
"""
post = frontmatter.loads(test_markdown_bare)
print("Test 1 - Bare YAML date (date: 2025-01-15):")
print(f" Type: {type(post.metadata['date'])}")
print(f" Value: {post.metadata['date']}")
print()
# Test 2: Parse markdown with quoted date
test_markdown_quoted = """---
title: Test Post
date: "2025-01-15"
---
# Test Content
"""
post2 = frontmatter.loads(test_markdown_quoted)
print("Test 2 - Quoted date (date: \"2025-01-15\"):")
print(f" Type: {type(post2.metadata['date'])}")
print(f" Value: {post2.metadata['date']}")
print()
# Test 3: Try sorting mixed types
print("Test 3 - Sorting with mixed types (date object vs empty string):")
try:
items = [
{'metadata': {'date': date(2025, 1, 15)}},
{'metadata': {'date': ''}},
{'metadata': {'date': date(2025, 1, 10)}}
]
sorted_items = sorted(items, key=lambda x: x['metadata'].get('date', ''), reverse=True)
print(" Sorting succeeded (unexpected)")
except TypeError as e:
print(f" TypeError: {e}")
print()
# Test 4: Try strptime with date object
print("Test 4 - strptime with datetime.date object:")
try:
pub_date = date(2025, 1, 15)
dt = datetime.strptime(pub_date, '%Y-%m-%d')
print(f" Success (unexpected): {dt}")
except TypeError as e:
print(f" TypeError: {e}")
EOFRepository: Alqudimi/MarkSite
Length of output: 185
🏁 Script executed:
#!/bin/bash
# Find all markdown files and sample their dates
find . -name "*.md" -type f | while read file; do
echo "=== $file ==="
sed -n '1,10p' "$file" | grep -i "^date:"
doneRepository: Alqudimi/MarkSite
Length of output: 403
🏁 Script executed:
#!/bin/bash
# Install requirements
pip install -q -r requirements.txt
# Test frontmatter date parsing behavior
python3 << 'EOF'
import frontmatter
from datetime import datetime, date
# Test 1: Parse markdown with bare YAML date (no quotes)
test_markdown_bare = """---
title: Test Post
date: 2025-01-15
---
# Test Content
"""
post = frontmatter.loads(test_markdown_bare)
print("Test 1 - Bare YAML date (date: 2025-01-15):")
print(f" Type: {type(post.metadata['date'])}")
print(f" Value: {post.metadata['date']}")
print()
# Test 2: Parse markdown with quoted date
test_markdown_quoted = """---
title: Test Post
date: "2025-01-15"
---
# Test Content
"""
post2 = frontmatter.loads(test_markdown_quoted)
print("Test 2 - Quoted date (date: \"2025-01-15\"):")
print(f" Type: {type(post2.metadata['date'])}")
print(f" Value: {post2.metadata['date']}")
print()
# Test 3: Try sorting mixed types
print("Test 3 - Sorting with mixed types (date object vs empty string):")
try:
items = [
{'metadata': {'date': date(2025, 1, 15)}},
{'metadata': {'date': ''}},
{'metadata': {'date': date(2025, 1, 10)}}
]
sorted_items = sorted(items, key=lambda x: x['metadata'].get('date', ''), reverse=True)
print(" Sorting succeeded (unexpected)")
except TypeError as e:
print(f" TypeError: {e}")
print()
# Test 4: Try strptime with date object
print("Test 4 - strptime with datetime.date object:")
try:
pub_date = date(2025, 1, 15)
dt = datetime.strptime(pub_date, '%Y-%m-%d')
print(f" Success (unexpected): {dt}")
except TypeError as e:
print(f" TypeError: {e}")
print()
# Test 5: Format date object directly to string
print("Test 5 - Formatting date object with strftime:")
pub_date = date(2025, 1, 15)
try:
# This is what happens at line 239 of generator.py
formatted = f'{pub_date}'
print(f" Direct string conversion: {formatted}")
except Exception as e:
print(f" Error: {e}")
EOFRepository: Alqudimi/MarkSite
Length of output: 1263
Major: date from YAML frontmatter is a datetime.date object, not a string — sorting and strptime both fail.
When frontmatter parses date: 2025-01-15 (bare YAML without quotes), PyYAML auto-converts it to a datetime.date object. This causes two critical failures:
sorted(..., key=lambda x: x['metadata'].get('date', ''))at lines 179 and 267 mixesdateobjects with''strings, raisingTypeError: '<' not supported between instances of 'str' and 'datetime.date'whenever a page lacks a date.datetime.strptime(pub_date, '%Y-%m-%d')at line 276 raisesTypeError: strptime() argument 1 must be str, not datetime.date. The bareexceptthen silently replaces everypubDatewith the current timestamp, erasing real publication dates.
The same sorting issue affects generate_index_page (line 179) and generate_sitemap (line 239). Root cause: the inconsistent date type across functions. Normalize dates to strings in parse_markdown_file so downstream code handles a consistent representation.
Suggested fix inside the loop (and a normalization helper)
- for page in sorted_pages[:20]:
- # Skip pages without a date or index page if desired, but usually all content is fine
- pub_date = page['metadata'].get('date', datetime.now().strftime('%Y-%m-%d'))
- try:
- dt = datetime.strptime(pub_date, '%Y-%m-%d')
- formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000")
- except:
- formatted_date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
+ for page in sorted_pages[:20]:
+ pub_date = page['metadata'].get('date')
+ dt = None
+ if isinstance(pub_date, datetime):
+ dt = pub_date
+ elif isinstance(pub_date, date):
+ dt = datetime(pub_date.year, pub_date.month, pub_date.day)
+ elif isinstance(pub_date, str):
+ try:
+ dt = datetime.strptime(pub_date, '%Y-%m-%d')
+ except ValueError:
+ dt = None
+ if dt is None:
+ dt = datetime.utcnow()
+ formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000")(Also import from datetime import date alongside datetime.)
🧰 Tools
🪛 Ruff (0.15.11)
[error] 278-278: Do not use bare except
(E722)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generator/generator.py` around lines 265 - 279, The YAML-parsed `date` fields
are datetime.date objects causing sorting and strptime to fail; normalize dates
when you parse files so downstream code can assume a consistent string format:
in parse_markdown_file detect metadata['date'] (use isinstance(..., date) or
datetime.date), convert it to an ISO string like 'YYYY-MM-DD' (or store None/'')
and replace the original value, and ensure metadata always contains a string or
empty string for date; then you can safely use sorted(self.pages, key=lambda x:
x['metadata'].get('date',''), reverse=True) in
generate_index_page/generate_sitemap and keep the pub_date handling around
pub_date/datetime.strptime without TypeError.
| except: | ||
| formatted_date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000") |
There was a problem hiding this comment.
Replace bare except with a specific exception (Ruff E722).
A bare except: swallows KeyboardInterrupt and SystemExit. Catch only what strptime can raise.
♻️ Diff
- try:
- dt = datetime.strptime(pub_date, '%Y-%m-%d')
- formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000")
- except:
- formatted_date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000")
+ try:
+ dt = datetime.strptime(pub_date, '%Y-%m-%d')
+ formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000")
+ except (TypeError, ValueError):
+ formatted_date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except: | |
| formatted_date = datetime.now().strftime("%a, %d %b %Y %H:%M:%S +0000") | |
| try: | |
| dt = datetime.strptime(pub_date, '%Y-%m-%d') | |
| formatted_date = dt.strftime("%a, %d %b %Y %H:%M:%S +0000") | |
| except (TypeError, ValueError): | |
| formatted_date = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000") |
🧰 Tools
🪛 Ruff (0.15.11)
[error] 278-278: Do not use bare except
(E722)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@generator/generator.py` around lines 278 - 279, The bare except: should be
replaced with a specific exception handler to avoid swallowing
SystemExit/KeyboardInterrupt; change it to catch the exceptions that datetime
parsing can raise (e.g., except (ValueError, TypeError) as e) and keep the
fallback assignment to formatted_date = datetime.now().strftime("%a, %d %b %Y
%H:%M:%S +0000"); reference the existing formatted_date assignment and ensure
the except targets ValueError/TypeError rather than a bare except.
This commit introduces automatic RSS 2.0 feed generation to the static site generator. It includes:
Summary by CodeRabbit