# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import urllib2
from urllib import urlencode
from urlparse import parse_qs
import re
import cookielib
import json


class Youtube:
    '''
    Example:
        yt = Youtube()
        yt.downlaod(id, filename)
    '''
    def __init__(self):
        self.cj = cookielib.CookieJar()
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
        self.opener.addheaders = [
	        ('User-Agent', 'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/4.0')
        ]

        #join html5 beta
        url = 'http://www.youtube.com/html5'
        u = self.opener.open(url)
        data = u.read()
        u.close()
        token = re.compile("'XSRF_TOKEN': '(.*?)',").findall(data)[0]
        u = self.opener.open(url, urlencode({
            "enable_html5": "true",
            "session_token": token
        }))
        u.read()
        u.close()

    def download(self, id, filename):
        #find info on html5 videos in html page and decode json blobs
        url = "http://www.youtube.com/watch?v=%s" % id
        u = self.opener.open(url)
        data = u.read()
        u.close()
        match = re.compile('"html5_fmt_map": \[(.*?)\]').findall(data)
        streams = match[0].replace('}, {', '}\n\n{').split('\n\n')
        streams = map(json.loads, streams)

        #get largest webm video
        webm = filter(lambda s: s['type'] == 'video/webm; codecs="vp8.0, vorbis"', streams)
        large = filter(lambda s: s['quality'] == 'large', webm)
        medium = filter(lambda s: s['quality'] == 'medium', webm)
        if large:
            url = large[0]['url']
        elif medium:
            url = medium[0]['url']
        else:
            print "no WebM video found"
            return False

        #download video and save to file.
        #this only works if you keep the cookies,
        #just passing the url to wget will not work
        u = self.opener.open(url)
        f = open(filename, 'w')
        data = True
        while data:
            data = u.read(4096)
            f.write(data)
        f.close()
        u.close()
        return True

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        print "usage: %s youtubeId filename" % sys.argv[0]
        sys.exit(1)
    print "Downloading %s to %s" % (sys.argv[1], sys.argv[2])

    yt = Youtube()
    if yt.download(sys.argv[1], sys.argv[2]):
        print "done"
    else:
        print "failed"

