Anton Shestakov <engored@ya.ru>, Fri, 26 Sep 2014 14:35:43 +0900
youtube-watch: download option, don't rely on publication time for new_entries.
youtube-watch/watch.py
Permissions: -rw-r--r--
from argparse import ArgumentParser, FileType from calendar import timegm from contextlib import contextmanager from operator import itemgetter from time import localtime, sleep, strftime url = 'https://gdata.youtube.com/feeds/api/users/%s/uploads?v=2' % user feed = feedparser.parse(url) def prepare_entries(entries, limit=None): entries = sorted(entries, key=itemgetter('published_parsed')) entries = entries[-limit:] def formatter(template, entries): entry['link'] = entry['link'].replace('&feature=youtube_gdata', '') entry['published_nice'] = strftime('%Y-%m-%d %H:%M:%S', localtime(timegm(entry['published_parsed']))) print template.format(**entry) def get_template(candidate): return templates['default'] elif candidate in templates: return templates[candidate] return candidate.decode('utf-8') 'default': u'{link:<43} | {published_nice:<19} | {author:<25} | {title}', 'long': u'{title}\nBy {author} ({link})' def activity_status(msg): sys.stderr.write('\r' + ' ' * len(msg) + '\r') def fetch_entries(users, delay=0): msg = 'Sleeping for %s' % delay with activity_status(msg): msg = 'Fetching entries for %s' % user with activity_status(msg): entries += user_entries(user) subprocess.call(['cclive', '--continue', '--timestamp', '--stream', 'best'] + [entry['link'] for entry in entries]) return entry['id'].rpartition(':')[2] parser = ArgumentParser() parser.add_argument('-U', '--user', action='append', dest='users', help='author of uploads', metavar='USER [+]') parser.add_argument('-F', '--input-file', type=FileType('r'), help='file with users') parser.add_argument('-T', '--template', help='template for python .format()') parser.add_argument('-l', '--limit', type=int, help='limit number of initial videos') parser.add_argument('-f', '--follow', action='store_true', help='continuous mode') parser.add_argument('-d', '--delay', type=int, help='delay for continuous mode', default=60) parser.add_argument('-D', '--download', action='store_true', help='download each video') args = parser.parse_args() template = get_template(args.template) if args.input_file is not None: users += args.input_file.read().splitlines() entries = fetch_entries(users) earlier = {identify(entry) for entry in entries} entries = prepare_entries(entries, args.limit) formatter(template, entries) entries = fetch_entries(users, args.delay) new_entries = [entry for entry in entries if identify(entry) not in earlier] earlier |= {identify(entry) for entry in new_entries} new_entries = prepare_entries(new_entries) formatter(template, new_entries) except KeyboardInterrupt: if __name__ == '__main__':