15:0a64b0583576
Anton Shestakov <engored@ya.ru>, Thu, 25 Sep 2014 14:35:55 +0900
Youtube-watch script.

next change 16:2a4c890a667a

youtube-watch/watch.py

Permissions: -rw-r--r--

Other formats: Feeds:
import sys
from argparse import ArgumentParser, FileType
from calendar import timegm
from contextlib import contextmanager
from operator import itemgetter
from time import localtime, sleep, strftime
import feedparser
def user_entries(user):
url = 'https://gdata.youtube.com/feeds/api/users/%s/uploads?v=2' % user
feed = feedparser.parse(url)
return feed['entries']
def formatter(template, limit, entries):
entries = sorted(entries, key=itemgetter('published_parsed'))
if limit is not None:
entries = entries[-limit:]
for entry in 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):
if candidate is None:
return templates['default']
elif candidate in templates:
return templates[candidate]
else:
return candidate.decode('utf-8')
templates = {
'default': u'{link:<43} | {published_nice:<19} | {author:<25} | {title}',
'long': u'{title}\nBy {author} ({link})'
}
@contextmanager
def activity_status(msg):
sys.stderr.write(msg)
sys.stderr.flush()
yield
sys.stderr.write('\r' + ' ' * len(msg) + '\r')
sys.stderr.flush()
def fetch_entries(users, delay=0):
entries = []
for user in users:
if delay:
msg = 'Sleeping for %s' % delay
with activity_status(msg):
sleep(delay)
msg = 'Fetching entries for %s' % user
with activity_status(msg):
entries += user_entries(user)
return entries
def main():
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)
args = parser.parse_args()
template = get_template(args.template)
users = args.users or []
if args.input_file is not None:
users += args.input_file.read().splitlines()
entries = fetch_entries(users)
formatter(template, args.limit, entries)
if not args.follow:
return
earlier = None
try:
while True:
if earlier is not None:
new_entries = [entry for entry in entries if entry['published_parsed'] > earlier]
formatter(template, None, new_entries)
earlier = max([entry['published_parsed'] for entry in entries])
entries = fetch_entries(users, args.delay)
except KeyboardInterrupt:
print
if __name__ == '__main__':
main()