Added media downloader project
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
# Gtk imports
|
||||
import gi, faulthandler, signal
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GLib
|
||||
from gi.repository.GdkPixbuf import Pixbuf
|
||||
|
||||
# Python imports
|
||||
import threading, subprocess, os, requests
|
||||
|
||||
from setproctitle import setproctitle
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
def threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class Controller:
|
||||
def __init__(self, settings):
|
||||
setproctitle('Media Downloader')
|
||||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, Gtk.main_quit)
|
||||
faulthandler.enable() # For better debug info
|
||||
|
||||
self.settings = settings
|
||||
self.builder = self.settings.returnBuilder()
|
||||
self.downloadTypes = self.builder.get_object("downloadTypes")
|
||||
self.urlEntry = self.builder.get_object("urlEntry")
|
||||
self.downloadButton = self.builder.get_object("downloadButton")
|
||||
self.thumbnail = self.builder.get_object("thumbnailImg")
|
||||
|
||||
self.selected = None
|
||||
|
||||
|
||||
def updateYoutubeDl(self, widget):
|
||||
pass
|
||||
|
||||
def paste(self, widget):
|
||||
entry = self.getClipboardData()
|
||||
self.urlEntry.set_text(entry)
|
||||
|
||||
@threaded
|
||||
def urlChanged(self, widget): # This also gets called by paste
|
||||
entry = widget.get_text().strip()
|
||||
size = len(entry)
|
||||
thumbUrl = "https://img.youtube.com/vi/" + entry[(size - 11): size] + "/hqdefault.jpg"
|
||||
|
||||
self.setThumbnail(thumbUrl)
|
||||
self.downloadButton.set_sensitive(False)
|
||||
self.downloadTypes.clear()
|
||||
if entry:
|
||||
if len(entry) in [28, 43]:
|
||||
if "youtu.be" in entry or "watch?v=" in entry:
|
||||
self.showDownloadTypes()
|
||||
|
||||
|
||||
def showDownloadTypes(self):
|
||||
lines = self.getFormatData().split("\n")
|
||||
|
||||
# Remove pre format strings
|
||||
i = 0
|
||||
while i <= 3:
|
||||
del lines[0]
|
||||
i += 1
|
||||
|
||||
for line in lines:
|
||||
parts = line.split()
|
||||
|
||||
while len(parts) != 4:
|
||||
parts.append("NO DATA")
|
||||
|
||||
if parts[3][len(parts[3]) - 1] == ",":
|
||||
parts[3] = parts[3][0:len(parts[3]) - 1]
|
||||
|
||||
self.downloadTypes.append(parts)
|
||||
|
||||
|
||||
@threaded
|
||||
def download(self, widget):
|
||||
url = self.urlEntry.get_text()
|
||||
dlComm = ["youtube-dl", "--no-playlist", "-o", "~/Downloads/%(title)s.%(ext)s",
|
||||
"-f", self.selected, url]
|
||||
proc = subprocess.Popen(dlComm, stdout=subprocess.PIPE) # Gets formats
|
||||
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if not line: break
|
||||
print(line.decode("utf-8").rstrip())
|
||||
|
||||
def setSelected(self, widget, row, col):
|
||||
model = widget.get_model()
|
||||
self.selected = model[row][0]
|
||||
self.downloadButton.set_sensitive(True)
|
||||
|
||||
@threaded
|
||||
def setThumbnail(self, url):
|
||||
fname = "/tmp/thumbnail-hqdefault.jpg"
|
||||
r = requests.get(url, allow_redirects=True)
|
||||
|
||||
open(fname, 'wb').write(r.content)
|
||||
self.thumbnail.set_from_pixbuf(Pixbuf.new_from_file(fname))
|
||||
|
||||
def getFormatData(self):
|
||||
url = self.urlEntry.get_text()
|
||||
dlComm = ["youtube-dl", "-F", url]
|
||||
awkComm = ["awk", "{ print $1, $2, $3, $11 }"]
|
||||
|
||||
proc = subprocess.Popen(dlComm, stdout=subprocess.PIPE) # Gets formats
|
||||
proc.wait()
|
||||
data = subprocess.check_output(awkComm, stdin=proc.stdout) # "Piping" to awk to get columns
|
||||
return data.decode("utf-8").strip()
|
||||
|
||||
def getClipboardData(self):
|
||||
proc = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE)
|
||||
retcode = proc.wait()
|
||||
data = proc.stdout.read()
|
||||
return data.decode("utf-8").strip()
|
||||
|
||||
def setClipboardData(self, data):
|
||||
proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.close()
|
||||
retcode = proc.wait()
|
Reference in New Issue
Block a user