#!/usr/bin/env python3 """ Generate an RSS feed from Pebble Search API data. Requires: feedgen (pip install feedgen) """ import requests import json from datetime import datetime, timezone from feedgen.feed import FeedGenerator 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, output_file="apps_feed.xml"): """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("Unexpected data structure: 'items' key not found") return False apps = apps_data['items'] if not isinstance(apps, list): print("Error: 'items' is not a list") return False print(f"Found {len(apps)} apps to process") # Initialize the feed generator fg = FeedGenerator() fg.id('https://repebblesearch.com/api/v1/apps') fg.title('Pebble Apps Feed') fg.link(href='https://repebblesearch.com', rel='alternate') fg.description('Latest Pebble apps sorted by release date') 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) # Create a feed entry fe = fg.add_entry() fe.id(app_id) fe.title(app['title']) fe.description(description) # Add screenshot URL as a link with rel='enclosure' (for media) if 'screenshot_url' in app: fe.link(href=app['screenshot_url'], rel='enclosure', type='image/png') # Set publication date if available pub_date = None if 'release_date' in app: 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: fe.author(name=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(): api_url = "https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc" output_file = "apps_feed.xml" print("Fetching apps data...") apps_data = fetch_apps_data(api_url) if apps_data: print("Creating RSS feed...") if create_rss_feed(apps_data, output_file): print(f"Done! Your RSS feed is ready at: {output_file}") else: print("Failed to create RSS feed") else: print("Failed to fetch apps data") if __name__ == "__main__": main()