Files
repebbleSearchRSS/rss-generator.py
T
2026-08-30 14:48:53 +02:00

173 lines
5.7 KiB
Python

#!/usr/bin/env python3
"""
Generate RSS feeds from Pebble Search API data.
Requires: feedgen (pip install feedgen)
"""
import requests
import json
import os
from datetime import datetime, timezone
from feedgen.feed import FeedGenerator
# Define your feeds here
FEEDS = [
{
'url': 'https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc&new_only=true&limit=50',
'name': 'New Apps',
'description': 'Latest new Pebble apps'
},
{
'url': 'https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc&recently_updated=true&limit=50',
'name': 'Updated Apps',
'description': 'Recently updated Pebble apps'
}
]
# Output folder for feeds
FEEDS_FOLDER = 'feeds'
def fetch_apps_data(url):
"""Fetch apps data from the API endpoint."""
try:
response = requests.get(url)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
return None
def fetch_app_description(app_id):
"""Fetch the description for a specific app from its detail endpoint."""
detail_url = f"https://repebblesearch.com/api/v1/apps/{app_id}"
try:
response = requests.get(detail_url)
response.raise_for_status()
# Try parsing as JSON first
try:
data = response.json()
return data.get('description', '')
except json.JSONDecodeError:
# If not JSON, try to extract from response text
print(f"Warning: Detail endpoint returned non-JSON for {app_id}")
return ""
except requests.exceptions.RequestException as e:
print(f"Error fetching description for {app_id}: {e}")
return ""
def create_rss_feed(apps_data, feed_name, feed_description, output_file):
"""Create an RSS feed from apps data using feedgen."""
# Extract the apps list from 'items' key
if not isinstance(apps_data, dict) or 'items' not in apps_data:
print(f" Unexpected data structure: 'items' key not found")
return False
apps = apps_data['items']
if not isinstance(apps, list):
print(f" Error: 'items' is not a list")
return False
print(f" Found {len(apps)} apps to process")
# Initialize the feed generator
fg = FeedGenerator()
fg.id(f'https://repebblesearch.com/api/v1/apps')
fg.title(feed_name)
fg.link(href='https://repebblesearch.com', rel='alternate')
fg.description(feed_description)
fg.language('en')
# Process each app
for i, app in enumerate(apps):
# Skip entries without required fields
if not isinstance(app, dict) or 'title' not in app:
continue
app_id = app.get('id', app['title'])
print(f" Processing app {i+1}/{len(apps)}: {app['title']}")
# Fetch description from detail endpoint
description = fetch_app_description(app_id)
# Ensure description is never None or empty string defaults to empty
if description is None:
description = ""
# Create a feed entry
fe = fg.add_entry()
fe.id(str(app_id)) # Ensure ID is a string
fe.title(str(app['title'])) # Ensure title is a string
fe.link(href=f'https://repebblesearch.com/apps/{app_id}', rel='alternate')
# Only set description if it's not empty
if description:
fe.description(description)
else:
fe.description("No description available")
# Add screenshot URL as a link with rel='enclosure' (for media)
if 'screenshot_url' in app and app['screenshot_url']:
fe.link(href=str(app['screenshot_url']), rel='enclosure', type='image/png')
# Set publication date if available
pub_date = None
if 'release_date' in app and app['release_date']:
try:
pub_date = datetime.fromisoformat(app['release_date'].replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass
# If no valid date, use current time with UTC timezone
if pub_date is None:
pub_date = datetime.now(timezone.utc)
fe.pubDate(pub_date)
# Add author if available
if 'author' in app and app['author']:
fe.author(name=str(app['author']))
# Write the RSS feed to file
try:
fg.rss_file(output_file, pretty=True)
print(f" RSS feed successfully created: {output_file}")
return True
except Exception as e:
print(f" Error writing RSS file: {e}")
return False
def main():
# Create feeds folder if it doesn't exist
if not os.path.exists(FEEDS_FOLDER):
os.makedirs(FEEDS_FOLDER)
print(f"Created '{FEEDS_FOLDER}' folder\n")
print("Generating Pebble apps RSS feeds...\n")
for feed_config in FEEDS:
feed_name = feed_config['name']
feed_url = feed_config['url']
feed_description = feed_config['description']
output_file = os.path.join(FEEDS_FOLDER, f"{feed_name.lower().replace(' ', '_')}_feed.xml")
print(f"Processing: {feed_name}")
print(f" Fetching data from API...")
apps_data = fetch_apps_data(feed_url)
if apps_data:
print(f" Creating RSS feed...")
if create_rss_feed(apps_data, feed_name, feed_description, output_file):
print(f" ✓ Done!\n")
else:
print(f" ✗ Failed to create RSS feed\n")
else:
print(f" ✗ Failed to fetch apps data\n")
print("All feeds generated!")
if __name__ == "__main__":
main()