Fix changelog
This commit is contained in:
+56
-56
@@ -37,8 +37,8 @@ def fetch_apps_data(url):
|
|||||||
print(f"Error fetching data: {e}")
|
print(f"Error fetching data: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def fetch_app_description(app_id):
|
def fetch_app_details(app_id):
|
||||||
"""Fetch the description for a specific app from its detail endpoint."""
|
"""Fetch the full app details from the detail endpoint."""
|
||||||
detail_url = f"https://repebblesearch.com/api/v1/apps/{app_id}"
|
detail_url = f"https://repebblesearch.com/api/v1/apps/{app_id}"
|
||||||
try:
|
try:
|
||||||
response = requests.get(detail_url)
|
response = requests.get(detail_url)
|
||||||
@@ -47,14 +47,14 @@ def fetch_app_description(app_id):
|
|||||||
# Try parsing as JSON first
|
# Try parsing as JSON first
|
||||||
try:
|
try:
|
||||||
data = response.json()
|
data = response.json()
|
||||||
return data.get('description', '')
|
return data
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
# If not JSON, try to extract from response text
|
# If not JSON, try to extract from response text
|
||||||
print(f"Warning: Detail endpoint returned non-JSON for {app_id}")
|
print(f"Warning: Detail endpoint returned non-JSON for {app_id}")
|
||||||
return ""
|
return {}
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
print(f"Error fetching description for {app_id}: {e}")
|
print(f"Error fetching details for {app_id}: {e}")
|
||||||
return ""
|
return {}
|
||||||
|
|
||||||
def format_description(text):
|
def format_description(text):
|
||||||
"""Convert plain text description to formatted HTML with proper line breaks and lists."""
|
"""Convert plain text description to formatted HTML with proper line breaks and lists."""
|
||||||
@@ -72,11 +72,11 @@ def format_description(text):
|
|||||||
stripped = line.strip()
|
stripped = line.strip()
|
||||||
|
|
||||||
# Check if this is a bullet point
|
# Check if this is a bullet point
|
||||||
if stripped and stripped[0] in ('-', '*', '•'):
|
if stripped and stripped[0] == '-':
|
||||||
if not in_list:
|
if not in_list:
|
||||||
formatted_lines.append('<ul>')
|
formatted_lines.append('<ul>')
|
||||||
in_list = True
|
in_list = True
|
||||||
# Remove the leading dash/bullet and clean up
|
# Remove the leading dash and clean up
|
||||||
item_text = stripped[1:].strip()
|
item_text = stripped[1:].strip()
|
||||||
formatted_lines.append(f'<li>{item_text}</li>')
|
formatted_lines.append(f'<li>{item_text}</li>')
|
||||||
else:
|
else:
|
||||||
@@ -124,33 +124,6 @@ def build_screenshots_html(app):
|
|||||||
|
|
||||||
return screenshots_html
|
return screenshots_html
|
||||||
|
|
||||||
def build_changelog_html(app):
|
|
||||||
"""Build HTML for changelog entries."""
|
|
||||||
changelog_html = ""
|
|
||||||
changelog = app.get("changelog", [])
|
|
||||||
|
|
||||||
if changelog:
|
|
||||||
for entry in changelog:
|
|
||||||
version = entry.get("version", "Unknown")
|
|
||||||
published_date = entry.get("published_date", "")
|
|
||||||
release_notes = entry.get("release_notes", "")
|
|
||||||
|
|
||||||
# Format the date
|
|
||||||
if published_date:
|
|
||||||
try:
|
|
||||||
date_obj = datetime.fromisoformat(published_date.replace('Z', '+00:00'))
|
|
||||||
formatted_date = date_obj.strftime("%Y-%m-%d %H:%M UTC")
|
|
||||||
except:
|
|
||||||
formatted_date = published_date
|
|
||||||
else:
|
|
||||||
formatted_date = "Unknown"
|
|
||||||
|
|
||||||
changelog_html += f"<h4>Version {version}</h4>"
|
|
||||||
changelog_html += f"<em>Released: {formatted_date}</em><br/>"
|
|
||||||
changelog_html += format_description(release_notes)
|
|
||||||
|
|
||||||
return changelog_html
|
|
||||||
|
|
||||||
def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
||||||
"""Create an RSS feed from apps data using feedgen."""
|
"""Create an RSS feed from apps data using feedgen."""
|
||||||
|
|
||||||
@@ -184,11 +157,12 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
app_id = app.get('id', app['title'])
|
app_id = app.get('id', app['title'])
|
||||||
print(f" Processing app {i+1}/{len(apps)}: {app['title']}")
|
print(f" Processing app {i+1}/{len(apps)}: {app['title']}")
|
||||||
|
|
||||||
# Fetch description from detail endpoint
|
# Fetch full app details from detail endpoint
|
||||||
description = fetch_app_description(app_id)
|
app_details = fetch_app_details(app_id)
|
||||||
# Format the description with HTML
|
|
||||||
|
# Get description from details
|
||||||
|
description = app_details.get('description', '')
|
||||||
description = format_description(description)
|
description = format_description(description)
|
||||||
# Ensure description is never None
|
|
||||||
if description is None:
|
if description is None:
|
||||||
description = ""
|
description = ""
|
||||||
|
|
||||||
@@ -196,7 +170,7 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
description_sections = []
|
description_sections = []
|
||||||
|
|
||||||
# Add screenshots on a single line at the top
|
# Add screenshots on a single line at the top
|
||||||
screenshots_html = build_screenshots_html(app)
|
screenshots_html = build_screenshots_html(app_details if app_details else app)
|
||||||
if screenshots_html:
|
if screenshots_html:
|
||||||
description_sections.append(screenshots_html)
|
description_sections.append(screenshots_html)
|
||||||
|
|
||||||
@@ -206,13 +180,37 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
description_sections.append(description)
|
description_sections.append(description)
|
||||||
|
|
||||||
# Add changelog if available
|
# Add changelog if available
|
||||||
changelog_html = build_changelog_html(app)
|
changelog = app_details.get('changelog', []) if app_details else []
|
||||||
if changelog_html:
|
if isinstance(changelog, list) and len(changelog) > 0:
|
||||||
description_sections.append('<h3>Changelog</h3>')
|
description_sections.append('<h3>Changelog</h3>')
|
||||||
description_sections.append(changelog_html)
|
changelog_html = []
|
||||||
|
for entry in changelog:
|
||||||
|
if isinstance(entry, dict):
|
||||||
|
version = entry.get('version', 'Unknown')
|
||||||
|
release_notes = entry.get('release_notes', '')
|
||||||
|
published_date = entry.get('published_date', '')
|
||||||
|
|
||||||
# Fallback to latest release notes if no changelog
|
changelog_html.append(f'<h4>Version {version}</h4>')
|
||||||
if not changelog_html and 'latest_release_notes' in app and app['latest_release_notes']:
|
|
||||||
|
if published_date:
|
||||||
|
try:
|
||||||
|
# Parse and format the date nicely
|
||||||
|
pub_date = datetime.fromisoformat(published_date.replace('Z', '+00:00'))
|
||||||
|
formatted_date = pub_date.strftime('%Y-%m-%d %H:%M UTC')
|
||||||
|
changelog_html.append(f'<p><em>Released: {formatted_date}</em></p>')
|
||||||
|
except (ValueError, AttributeError):
|
||||||
|
changelog_html.append(f'<p><em>Released: {published_date}</em></p>')
|
||||||
|
|
||||||
|
if release_notes:
|
||||||
|
formatted_notes = format_description(release_notes)
|
||||||
|
changelog_html.append(formatted_notes)
|
||||||
|
else:
|
||||||
|
changelog_html.append('<p>No release notes provided.</p>')
|
||||||
|
|
||||||
|
description_sections.append('\n'.join(changelog_html))
|
||||||
|
|
||||||
|
# Fallback to latest_release_notes if no changelog
|
||||||
|
elif app.get('latest_release_notes'):
|
||||||
release_notes = str(app['latest_release_notes']).strip()
|
release_notes = str(app['latest_release_notes']).strip()
|
||||||
if release_notes:
|
if release_notes:
|
||||||
formatted_notes = format_description(release_notes)
|
formatted_notes = format_description(release_notes)
|
||||||
@@ -235,8 +233,8 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
fe.description("No description available")
|
fe.description("No description available")
|
||||||
|
|
||||||
# Add screenshot URLs as enclosures (for readers that support them)
|
# Add screenshot URLs as enclosures (for readers that support them)
|
||||||
screenshots = app.get("screenshots", [])
|
screenshots = app_details.get("screenshots", []) if app_details else []
|
||||||
if not screenshots and 'screenshot_url' in app and app['screenshot_url']:
|
if not screenshots and app.get('screenshot_url'):
|
||||||
screenshots = [{'url': app['screenshot_url']}]
|
screenshots = [{'url': app['screenshot_url']}]
|
||||||
|
|
||||||
for screenshot in screenshots:
|
for screenshot in screenshots:
|
||||||
@@ -247,17 +245,17 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
# Set publication date if available
|
# Set publication date if available
|
||||||
pub_date = None
|
pub_date = None
|
||||||
|
|
||||||
# Try changelog first
|
# Try to get the earliest changelog date
|
||||||
changelog = app.get("changelog", [])
|
if app_details and 'changelog' in app_details and isinstance(app_details['changelog'], list) and len(app_details['changelog']) > 0:
|
||||||
if changelog and len(changelog) > 0:
|
# Get the last entry (oldest) of the changelog
|
||||||
pub_date_str = changelog[0].get("published_date", "")
|
last_entry = app_details['changelog'][-1]
|
||||||
if pub_date_str:
|
if isinstance(last_entry, dict) and 'published_date' in last_entry:
|
||||||
try:
|
try:
|
||||||
pub_date = datetime.fromisoformat(pub_date_str.replace('Z', '+00:00'))
|
pub_date = datetime.fromisoformat(last_entry['published_date'].replace('Z', '+00:00'))
|
||||||
except:
|
except (ValueError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Fallback to release_date
|
# Fallback to release_date from the app list
|
||||||
if pub_date is None and 'release_date' in app and app['release_date']:
|
if pub_date is None and 'release_date' in app and app['release_date']:
|
||||||
try:
|
try:
|
||||||
pub_date = datetime.fromisoformat(app['release_date'].replace('Z', '+00:00'))
|
pub_date = datetime.fromisoformat(app['release_date'].replace('Z', '+00:00'))
|
||||||
@@ -271,7 +269,9 @@ def create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
|||||||
fe.pubDate(pub_date)
|
fe.pubDate(pub_date)
|
||||||
|
|
||||||
# Add author if available
|
# Add author if available
|
||||||
if 'author' in app and app['author']:
|
if app_details and 'author' in app_details and app_details['author']:
|
||||||
|
fe.author(name=str(app_details['author']))
|
||||||
|
elif 'author' in app and app['author']:
|
||||||
fe.author(name=str(app['author']))
|
fe.author(name=str(app['author']))
|
||||||
|
|
||||||
# Write the RSS feed to file
|
# Write the RSS feed to file
|
||||||
|
|||||||
Reference in New Issue
Block a user