diff --git a/README.md b/README.md index 0112274..cd3ee2f 100644 --- a/README.md +++ b/README.md @@ -88,12 +88,28 @@ npm start "https://www.youtube.com/@LinusTechTips" --- -### `/feed/` (GET) +### `/feed//` (GET) ### Get RSS feed via URL path Access a YouTube channel's RSS feed by passing the channel URL in the path. +Supported feed types: + +- `all` (existing combined behavior) +- `videos` (regular videos tab) +- `shorts` (shorts tab) +- `live` (live/streams tab) + +Endpoint examples: + +```text +/feed/all/:channel +/feed/videos/:channel +/feed/shorts/:channel +/feed/live/:channel +``` + **Important:** The `channel_url` parameter must be URL-encoded (percent-encoded) to avoid 404 errors. **Example with encoding:** @@ -105,13 +121,13 @@ const encodedUrl = encodeURIComponent(channelUrl); // Result: https%3A%2F%2Fwww.youtube.com%2Fchannel%2FUCXuqSBlHAE6Xw-yeJA0Tunw // Use in request -fetch(`/feed/${encodedUrl}`) +fetch(`/feed/videos/${encodedUrl}`) ``` -**Alternative (recommended):** Use query parameters to avoid encoding issues: +**Alternative (recommended):** Use URL-encoded paths to avoid encoding issues: ```bash -/feed?channel_url=https://www.youtube.com/channel/UCXuqSBlHAE6Xw-yeJA0Tunw +/feed/all/https%3A%2F%2Fwww.youtube.com%2Fchannel%2FUCXuqSBlHAE6Xw-yeJA0Tunw ``` --- diff --git a/api/app.py b/api/app.py index 3805816..3676572 100644 --- a/api/app.py +++ b/api/app.py @@ -50,6 +50,9 @@ def api_feed(): try: # Normalize include_api_endpoints to boolean raw_value = data.get('include_api_endpoints', False) + feed_type = str(data.get('feed_type', request.args.get('feed_type', 'all'))).lower().strip() + if feed_type not in ('all', 'videos', 'shorts', 'live'): + return jsonify({'error': 'Invalid feed_type. Use all, videos, shorts, or live.'}), 400 if isinstance(raw_value, bool): include_api_endpoints = raw_value elif isinstance(raw_value, str): @@ -63,7 +66,8 @@ def api_feed(): youtube_rss, channel_id, channel_name, atom_feed, video_count, _, api_endpoints = rss_scanner.get_rss_feed( url, include_api_endpoints=include_api_endpoints, - base_url=base_url + base_url=base_url, + feed_type=feed_type ) discord_result = None @@ -134,57 +138,34 @@ def send_to_discord(webhook_url: str, youtube_rss: str, channel_id: str | None, @app.route('/feed/') -@app.route('/feed/') -def get_feed(channel_url=None): - """Generate RSS feed for given channel.""" +def feed_usage(): + return "Usage: /feed/{type}/{youtube_channel_url} where type is all|videos|shorts|live" + + +@app.route('/feed//') +@cache.cached(timeout=300, key_prefix=lambda: f"feed_{request.path}") +def get_feed(feed_type, channel_url=None): + """Generate RSS feed for given channel. Cached for 5 minutes.""" if channel_url is None: - return "Usage: /feed/{youtube_channel_url}" - + return "Usage: /feed/{type}/{youtube_channel_url}" + + if feed_type not in ("all", "videos", "shorts", "live"): + return Response("Invalid feed type", status=400) + # Decode URL-encoded parts channel_url = urllib.parse.unquote(channel_url) - + # Reconstruct full URL (Flask captures everything after /feed/) if not channel_url.startswith('http'): full_url = f"https://{channel_url}" else: full_url = channel_url - - try: - _, channel_id, channel_name, atom_feed, video_count, _, _ = rss_scanner.get_rss_feed(full_url) - - if atom_feed: - # Fix channel name in feed - if channel_name: - atom_feed = atom_feed.replace( - f">{channel_id or channel_id} - YouTube Videos", - f">{channel_name} - YouTube Videos" - ) - atom_feed = atom_feed.replace( - f"{channel_id or channel_id}", - f"{channel_name}" - ) - return Response(atom_feed, mimetype='application/xml') - else: - return Response("No videos found", status=404) - except Exception as e: - return Response(f"Error: {str(e)}", status=500) - -@app.route('/feed/', methods=['GET']) -@cache.cached(timeout=300, key_prefix='feed_') -def get_cached_feed(channel): - """Cached RSS feed endpoint - updates every 5 minutes.""" - # Clean channel from URL - channel = urllib.parse.unquote(channel) - if channel.startswith('http'): - full_url = channel - else: - full_url = f"https://{channel}" - try: - _, channel_id, channel_name, atom_feed, video_count, _, _ = rss_scanner.get_rss_feed(full_url) - + _, channel_id, channel_name, atom_feed, video_count, _, _ = rss_scanner.get_rss_feed(full_url, feed_type=feed_type) + if atom_feed: + # Fix channel name in feed if channel_name: atom_feed = atom_feed.replace( f">{channel_id or channel_id} - YouTube Videos", diff --git a/api/index.html b/api/index.html index db471c1..dbfd3e2 100644 --- a/api/index.html +++ b/api/index.html @@ -122,6 +122,16 @@

YouTube RSS Scanner

+
+ + +
+
+
+ + +
+
+
+ + +
+