Generate multiple RSS files
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
feeds/
|
||||||
+76
-27
@@ -1,14 +1,42 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Generate an RSS feed from Pebble Search API data.
|
Generate RSS feeds from Pebble Search API data.
|
||||||
Requires: feedgen (pip install feedgen)
|
Requires: feedgen (pip install feedgen)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from feedgen.feed import FeedGenerator
|
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',
|
||||||
|
'name': 'New Apps',
|
||||||
|
'description': 'Latest new Pebble apps'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url': 'https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc&recently_updated=true',
|
||||||
|
'name': 'Updated Apps',
|
||||||
|
'description': 'Recently updated Pebble apps'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url': 'https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc&categories=Games',
|
||||||
|
'name': 'Games',
|
||||||
|
'description': 'Pebble games'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url': 'https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc',
|
||||||
|
'name': 'All Apps',
|
||||||
|
'description': 'All Pebble apps sorted by release date'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Output folder for feeds
|
||||||
|
FEEDS_FOLDER = 'feeds'
|
||||||
|
|
||||||
def fetch_apps_data(url):
|
def fetch_apps_data(url):
|
||||||
"""Fetch apps data from the API endpoint."""
|
"""Fetch apps data from the API endpoint."""
|
||||||
try:
|
try:
|
||||||
@@ -38,28 +66,28 @@ def fetch_app_description(app_id):
|
|||||||
print(f"Error fetching description for {app_id}: {e}")
|
print(f"Error fetching description for {app_id}: {e}")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def create_rss_feed(apps_data, output_file="apps_feed.xml"):
|
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."""
|
||||||
|
|
||||||
# Extract the apps list from 'items' key
|
# Extract the apps list from 'items' key
|
||||||
if not isinstance(apps_data, dict) or 'items' not in apps_data:
|
if not isinstance(apps_data, dict) or 'items' not in apps_data:
|
||||||
print("Unexpected data structure: 'items' key not found")
|
print(f" Unexpected data structure: 'items' key not found")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
apps = apps_data['items']
|
apps = apps_data['items']
|
||||||
|
|
||||||
if not isinstance(apps, list):
|
if not isinstance(apps, list):
|
||||||
print("Error: 'items' is not a list")
|
print(f" Error: 'items' is not a list")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print(f"Found {len(apps)} apps to process")
|
print(f" Found {len(apps)} apps to process")
|
||||||
|
|
||||||
# Initialize the feed generator
|
# Initialize the feed generator
|
||||||
fg = FeedGenerator()
|
fg = FeedGenerator()
|
||||||
fg.id('https://repebblesearch.com/api/v1/apps')
|
fg.id(f'https://repebblesearch.com/api/v1/apps')
|
||||||
fg.title('Pebble Apps Feed')
|
fg.title(feed_name)
|
||||||
fg.link(href='https://repebblesearch.com', rel='alternate')
|
fg.link(href='https://repebblesearch.com', rel='alternate')
|
||||||
fg.description('Latest Pebble apps sorted by release date')
|
fg.description(feed_description)
|
||||||
fg.language('en')
|
fg.language('en')
|
||||||
|
|
||||||
# Process each app
|
# Process each app
|
||||||
@@ -69,24 +97,32 @@ def create_rss_feed(apps_data, output_file="apps_feed.xml"):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
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 description from detail endpoint
|
||||||
description = fetch_app_description(app_id)
|
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
|
# Create a feed entry
|
||||||
fe = fg.add_entry()
|
fe = fg.add_entry()
|
||||||
fe.id(app_id)
|
fe.id(str(app_id)) # Ensure ID is a string
|
||||||
fe.title(app['title'])
|
fe.title(str(app['title'])) # Ensure title is a string
|
||||||
|
|
||||||
|
# Only set description if it's not empty
|
||||||
|
if description:
|
||||||
fe.description(description)
|
fe.description(description)
|
||||||
|
else:
|
||||||
|
fe.description("No description available")
|
||||||
|
|
||||||
# Add screenshot URL as a link with rel='enclosure' (for media)
|
# Add screenshot URL as a link with rel='enclosure' (for media)
|
||||||
if 'screenshot_url' in app:
|
if 'screenshot_url' in app and app['screenshot_url']:
|
||||||
fe.link(href=app['screenshot_url'], rel='enclosure', type='image/png')
|
fe.link(href=str(app['screenshot_url']), rel='enclosure', type='image/png')
|
||||||
|
|
||||||
# Set publication date if available
|
# Set publication date if available
|
||||||
pub_date = None
|
pub_date = None
|
||||||
if 'release_date' in app:
|
if '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'))
|
||||||
except (ValueError, AttributeError):
|
except (ValueError, AttributeError):
|
||||||
@@ -99,33 +135,46 @@ def create_rss_feed(apps_data, output_file="apps_feed.xml"):
|
|||||||
fe.pubDate(pub_date)
|
fe.pubDate(pub_date)
|
||||||
|
|
||||||
# Add author if available
|
# Add author if available
|
||||||
if 'author' in app:
|
if 'author' in app and app['author']:
|
||||||
fe.author(name=app['author'])
|
fe.author(name=str(app['author']))
|
||||||
|
|
||||||
# Write the RSS feed to file
|
# Write the RSS feed to file
|
||||||
try:
|
try:
|
||||||
fg.rss_file(output_file, pretty=True)
|
fg.rss_file(output_file, pretty=True)
|
||||||
print(f"RSS feed successfully created: {output_file}")
|
print(f" RSS feed successfully created: {output_file}")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error writing RSS file: {e}")
|
print(f" Error writing RSS file: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
api_url = "https://repebblesearch.com/api/v1/apps?sort=release_date&order=desc"
|
# Create feeds folder if it doesn't exist
|
||||||
output_file = "apps_feed.xml"
|
if not os.path.exists(FEEDS_FOLDER):
|
||||||
|
os.makedirs(FEEDS_FOLDER)
|
||||||
|
print(f"Created '{FEEDS_FOLDER}' folder\n")
|
||||||
|
|
||||||
print("Fetching apps data...")
|
print("Generating Pebble apps RSS feeds...\n")
|
||||||
apps_data = fetch_apps_data(api_url)
|
|
||||||
|
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:
|
if apps_data:
|
||||||
print("Creating RSS feed...")
|
print(f" Creating RSS feed...")
|
||||||
if create_rss_feed(apps_data, output_file):
|
if create_rss_feed(apps_data, feed_name, feed_description, output_file):
|
||||||
print(f"Done! Your RSS feed is ready at: {output_file}")
|
print(f" ✓ Done!\n")
|
||||||
else:
|
else:
|
||||||
print("Failed to create RSS feed")
|
print(f" ✗ Failed to create RSS feed\n")
|
||||||
else:
|
else:
|
||||||
print("Failed to fetch apps data")
|
print(f" ✗ Failed to fetch apps data\n")
|
||||||
|
|
||||||
|
print("All feeds generated!")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user