Files
YouTube-RSS/YouTube-RSS.py
2019-05-04 08:46:01 +02:00

107 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""
YouTube-RSS is a simple script to build RSS feeds from YouTube links.
You can pass links to channels, play-lists or even user pages.
The script is modular, so any new entity could be added easily.
"""
import argparse
import sys
from urllib.error import HTTPError
from urllib.request import Request, urlopen
from urllib.parse import parse_qs, urlparse, urlencode
# YouTube has only one URL to generate RSS feeds.
# GET parameters will change the output accordingly.
RSS_FEEDS_BASE_URL = r"https://www.youtube.com/feeds/videos.xml"
def get_feed(entity, token):
"""Returns a well-formatted RSS feed URL based on the constant above"""
return "{0}?{1}".format(
RSS_FEEDS_BASE_URL,
urlencode({entity: token}) # Parameters should already be URL-encoded, but who knows ?
)
def process_link(i, link):
"""Main logic, parse and analyze the link and compute RSS feed"""
# Parse the passed link.
parsing = urlparse(link)
# Parse the GET parameters (if any).
get_params = parse_qs(parsing.query)
# Check that the provided link belongs to YouTube.
if not parsing.netloc.endswith('youtube.com') and \
not parsing.netloc.endswith('youtu.be'):
print(
"[{0}] The provided link is not a YouTube link. Skipping.".format(i),
file=sys.stderr
)
return
# Starts URL pattern matching.
if parsing.path.startswith('/user/'):
rss_feed = get_feed('user', parsing.path.split('/')[2])
elif parsing.path.startswith('/channel/'):
rss_feed = get_feed('channel_id', parsing.path.split('/')[2])
elif 'list' in get_params:
rss_feed = get_feed('playlist_id', get_params.get('list')[0])
else:
print(
"[{0}] The provided link has an unknown format. Skipping.".format(i),
file=sys.stderr
)
return
# Let's verify that the built RSS feed is valid upstream.
try:
_ = urlopen(Request(rss_feed, method='HEAD'))
print("[{0}] <{1}>".format(i, rss_feed))
except HTTPError as error:
print(
"[{0}] No responding RSS feed could be retrieved ({1}).".format(
i,
error.code
),
file=sys.stderr
)
def main():
"""Simple entry point"""
parser = argparse.ArgumentParser(
description="A simple RSS feeds generation for YouTube entities",
prog="YouTube-RSS"
)
parser.add_argument(
'links',
type=str,
nargs='+',
help="YouTube link(s) to convert to RSS feed(s)"
)
parser.add_argument(
'--version',
action='version', version="%(prog)s : 1.0"
)
args = parser.parse_args()
# Iterate over passed links and process them.
for i, link in enumerate(args.links):
process_link(i, link)
if __name__ == '__main__':
main()