import requests import os from datetime import datetime from feedgen.feed import FeedGenerator from feedgen.entry import FeedEntry API_BASE_URL = "https://repebblesearch.com/api/v1/apps" OUTPUT_FOLDER = "feeds" def format_description(text): """Convert release notes text to HTML with paragraph and list support.""" if not text: return "" html = "" lines = text.split("\n") in_list = False for line in lines: line = line.strip() if not line: if in_list: html += "" in_list = False continue # Check if line is a list item (starts with -, *, or •) if line.startswith(("-", "*", "•")): if not in_list: html += "" in_list = False html += f"

{line}

" if in_list: html += "" return html def create_description_with_screenshots(app_data): """Build description with screenshots on a single line, then release notes.""" description = "" # Add screenshots on a single line at the top screenshots = app_data.get("screenshots", []) if screenshots: screenshot_html = '
' for idx, screenshot in enumerate(screenshots, 1): url = screenshot.get("url", "") width = screenshot.get("width", "auto") height = screenshot.get("height", "auto") hardware = screenshot.get("hardware", "") label = f"Screenshot {idx}" if hardware: label += f" ({hardware})" screenshot_html += f'{label}' screenshot_html += '
' description += screenshot_html # Add release notes below screenshots changelog = app_data.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" description += f"

Version {version}

" description += f"Released: {formatted_date}
" description += format_description(release_notes) else: # Fallback to latest_release_notes latest_notes = app_data.get("latest_release_notes", "") if latest_notes: description += format_description(latest_notes) return description def fetch_apps(query, platform="basalt"): """Fetch apps from the Pebble Search API.""" params = { "query": query, "platform": platform, "limit": 100 } try: response = requests.get(API_BASE_URL, params=params) response.raise_for_status() data = response.json() return data.get("apps", []) except requests.exceptions.RequestException as e: print(f"Error fetching apps for query '{query}': {e}") return [] def create_rss_feed(filename, title, description, apps): """Create an RSS feed from app data.""" fg = FeedGenerator() fg.title(title) fg.link(href="https://repebblesearch.com", rel="alternate") fg.description(description) fg.language("en") for app in apps: fe = fg.add_entry() app_title = app.get("title", "Unknown App") app_id = app.get("uuid", "") app_url = f"https://repebblesearch.com/app/{app_id}" if app_id else "https://repebblesearch.com" fe.title(app_title) fe.link(href=app_url) fe.guid(app_url) # Build description with screenshots and release notes description_html = create_description_with_screenshots(app) fe.description(description_html) # Add enclosures for screenshots (for readers that support them) screenshots = app.get("screenshots", []) for screenshot in screenshots: url = screenshot.get("url", "") if url: fe.enclosure(url=url, type="image/png") # Set publication date from latest changelog entry or fallback pub_date = None changelog = app.get("changelog", []) if changelog and len(changelog) > 0: pub_date_str = changelog[0].get("published_date", "") if pub_date_str: try: pub_date = datetime.fromisoformat(pub_date_str.replace('Z', '+00:00')) except: pub_date = datetime.now() else: pub_date = datetime.now() if pub_date: fe.pubDate(pub_date) # Ensure output folder exists os.makedirs(OUTPUT_FOLDER, exist_ok=True) # Write RSS feed to file output_path = os.path.join(OUTPUT_FOLDER, filename) fg.rss_file(output_path, pretty=True) print(f"Feed created: {output_path}") def main(): """Main function to generate RSS feeds.""" print("Fetching Pebble apps and generating RSS feeds...") # Fetch new apps print("Fetching new apps...") new_apps = fetch_apps("*", platform="basalt") # Fetch updated apps (you might want to adjust the query) print("Fetching updated apps...") updated_apps = fetch_apps("*", platform="basalt") # Create RSS feeds create_rss_feed( "new_apps.xml", "New Pebble Apps", "Recently released Pebble apps from the Pebble Search database", new_apps[:20] # Limit to 20 most recent ) create_rss_feed( "updated_apps.xml", "Updated Pebble Apps", "Recently updated Pebble apps from the Pebble Search database", updated_apps[:20] # Limit to 20 most recent ) print("Done!") if __name__ == "__main__": main()