108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from xml.dom.minidom import getDOMImplementation
|
|
import httplib as compat_http_client
|
|
import urllib2 as compat_urllib_error
|
|
import socket
|
|
import youtube_dl
|
|
|
|
class ytd(youtube_dl.YoutubeDL):
|
|
"""Custom implementation of YoutubeDL class"""
|
|
|
|
def __init__(self):
|
|
params = { "quiet": True }
|
|
youtube_dl.YoutubeDL.__init__(self, params)
|
|
|
|
|
|
def convert_file(path, preferredcodec=None, preferredquality=u"5"):
|
|
y = ytd()
|
|
pp = youtube_dl.postprocessor.FFmpegExtractAudioPP(y, preferredcodec=preferredcodec, preferredquality=preferredquality)
|
|
try:
|
|
pp.run({'filepath': path})
|
|
except Exception as e:
|
|
return e.msg
|
|
|
|
return ""
|
|
|
|
def get_extractor(url):
|
|
"""Get first matching extractor for the given URL"""
|
|
extractors = youtube_dl.extractor.gen_extractors()
|
|
|
|
for e in extractors:
|
|
if e.suitable(url):
|
|
return e
|
|
return None
|
|
|
|
def get_downloader(url):
|
|
"""Return an initialized downloader for the given URL"""
|
|
info = get_informations(url)
|
|
info["url"] = url
|
|
|
|
y = ytd()
|
|
|
|
downloader = youtube_dl.downloader.get_suitable_downloader(info)
|
|
return downloader(y, y.params)
|
|
|
|
def download_video(fd, info, hooks=list()):
|
|
"""Realy download the link"""
|
|
try:
|
|
for ph in hooks:
|
|
fd.add_progress_hook(ph)
|
|
|
|
filename = u"test.local" # TODO: find a better name
|
|
if fd.download(filename, info):
|
|
return filename
|
|
return None
|
|
except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error, OSError, IOError) as err:
|
|
return u'unable to download video data: %s' % str(err)
|
|
except (youtube_dl.utils.ContentTooShortError, ) as err:
|
|
return u'content too short (expected %s bytes and served %s)' % (err.expected, err.downloaded)
|
|
|
|
def is_valid_URL(url):
|
|
"""True if an extractor is found"""
|
|
e = get_extractor(url)
|
|
return e is not None and type(e) != youtube_dl.extractor.GenericIE
|
|
|
|
|
|
def get_informations(url, ie=None):
|
|
"""Get movie's information"""
|
|
if ie is None:
|
|
ie = get_extractor(url)
|
|
|
|
ie.set_downloader(ytd())
|
|
return ie.extract(url)
|
|
|
|
def dict_to_xml(fdict, parent, newdoc):
|
|
"""Generate a XML tree from a Python dictionnary"""
|
|
for k, i in fdict.items():
|
|
node = newdoc.createElement(k)
|
|
if i is None:
|
|
continue
|
|
elif type(i) == dict:
|
|
dict_to_xml(i, node, newdoc)
|
|
elif type(i) == list:
|
|
for j in i:
|
|
dict_to_xml({ k: j }, parent, newdoc)
|
|
continue
|
|
elif type(i) == int:
|
|
nodeT = newdoc.createTextNode("%d" % i)
|
|
node.appendChild(nodeT)
|
|
else:
|
|
nodeT = newdoc.createTextNode(i.encode('utf8', 'replace'))
|
|
node.appendChild(nodeT)
|
|
parent.appendChild(node)
|
|
|
|
def gen_error(status, txt=""):
|
|
"""Generate a XML tree for error purpose"""
|
|
impl = getDOMImplementation()
|
|
|
|
newdoc = impl.createDocument(None, "gearman_musik", None)
|
|
root = newdoc.documentElement
|
|
|
|
root.setAttribute("status", "%d" % status)
|
|
error = newdoc.createElement("error")
|
|
errorstr = newdoc.createTextNode(txt)
|
|
error.appendChild(errorstr)
|
|
root.appendChild(error)
|
|
|
|
return newdoc.toxml()
|