Created
March 23, 2011 18:41
-
-
Save markpasc/883679 to your computer and use it in GitHub Desktop.
ytf: describe a YouTube video from the command line
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
markpasc@markpascbook:~$ ytf http://www.youtube.com/watch?v=bWBbt--UUP8 | |
IT'S CAT-ERTAINMENT! (3:29) | |
Posted 2011-03-22 by BargainBinofOblivion to 5801 views | |
www.everythingisterrible.com | |
markpasc@markpascbook:~$ yt http://youtu.be/rTUwqxHpXMY | |
Android on crack..lol (2:25) | |
Posted 2011-03-21 by dark32 to 155718 views | |
This was taken in Taiwan,near 101 tower,at new Sony Xperia Arc | |
cellphone stand. | |
markpasc@markpascbook:~$ ytf oXoj4bq4w | |
ValueError: Can't determine video ID from URL 'oXoj4bq4w' | |
markpasc@markpascbook:~$ ytf r-oXoj4bq4w | |
Banana Ocarina "Cuckoo" (0:29) | |
Posted 2010-08-31 by heita3 to 41399 views | |
I made an ocarina with a banana. I played "a cuckoo". |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# ytf | |
# | |
# Describe a YouTube video from the command line. | |
# | |
from __future__ import division | |
import re | |
import sys | |
from textwrap import wrap | |
from xml.etree import cElementTree as ElementTree | |
import httplib2 | |
def video_id_for_url(url): | |
mo = re.match(r'^([\w-]{11})$', url) | |
if mo is not None: | |
return url | |
mo = re.search(r'(?:v=|youtu\.be/)([\w-]{11})', url) | |
if mo is not None: | |
return mo.group(1) | |
raise ValueError("Can't determine video ID from URL %r" % url) | |
def fetch(video_id): | |
h = httplib2.Http() | |
resp, cont = h.request('http://gdata.youtube.com/feeds/api/videos/%s' % video_id) | |
if resp.status != 200: | |
raise ValueError("Unexpected response from YouTube: %d %s" % (resp.status, resp.reason)) | |
if not resp['content-type'].startswith('application/atom+xml'): | |
raise ValueError("Unexpected response from YouTube: %s" % resp['content-type']) | |
doc = ElementTree.fromstring(cont) | |
data = { | |
'title': doc.findtext('./{http://www.w3.org/2005/Atom}title'), | |
'keywords': doc.findtext('./{http://search.yahoo.com/mrss/}group/{http://search.yahoo.com/mrss/}keywords'), | |
'description': '\n'.join(wrap(doc.findtext('./{http://search.yahoo.com/mrss/}group/{http://search.yahoo.com/mrss/}description'))), | |
'date': doc.findtext('./{http://www.w3.org/2005/Atom}published')[:10], | |
'author': doc.findtext('./{http://www.w3.org/2005/Atom}author/{http://www.w3.org/2005/Atom}name'), | |
} | |
stats = doc.find('./{http://gdata.youtube.com/schemas/2007}statistics') | |
if stats is not None: | |
data['views'] = stats.attrib['viewCount'] | |
duration = doc.find('./{http://search.yahoo.com/mrss/}group/{http://gdata.youtube.com/schemas/2007}duration') | |
if duration is not None: | |
duration_secs = int(duration.attrib['seconds']) | |
data['duration'] = '%d:%d' % (duration_secs / 60, duration_secs % 60) | |
return data | |
def show_data(data): | |
text = """ | |
%(title)s (%(duration)s) | |
Posted %(date)s by %(author)s to %(views)s views | |
%(description)s | |
""" % data | |
print text.strip() | |
def main(argv): | |
try: | |
show_data(fetch(video_id_for_url(argv[0]))) | |
except Exception, exc: | |
print >>sys.stderr, '%s: %s' % (type(exc).__name__, str(exc)) | |
return 1 | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main(sys.argv[1:])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment