# Gtk imports import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk as gtk from gi.repository import GLib as glib from gi.repository import GObject as gobject # Python imports import os, sys, threading, subprocess, io, requests, time # Application imports from utils import mpv def threaded(fn): def wrapper(*args, **kwargs): threading.Thread(target=fn, args=args, kwargs=kwargs).start() return wrapper class CrossClassSignals: def __init__(self, settings): self.settings = settings self.builder = self.settings.returnBuilder() self.baseUrlEntry = self.builder.get_object("baseUrlEntry") self.startRangeStepper = self.builder.get_object("startRangeStepper") self.endRangeStepper = self.builder.get_object("endRangeStepper") self.baseNameEntry = self.builder.get_object("baseNameEntry") self.threadListBox = self.builder.get_object("threadListBox") self.videoPopover = self.builder.get_object("videoPopover") self.scrptPth = os.path.dirname(os.path.realpath(__file__)) + "/" self.playImage = self.scrptPth + "../resources/play.png" self.downloadImage = self.scrptPth + "../resources/download.png" self.progressBars = list() self.mpv = None self.i = None @threaded def createDownloadList(self, widget): url = self.baseUrlEntry.get_text().strip() + "/episode/episode-" name = self.baseNameEntry.get_text().strip() start = self.startRangeStepper.get_value_as_int() end = self.endRangeStepper.get_value_as_int() html = "" self.clearListBox() while start <= end: html = requests.get(url + str(start)).text episode = self.parseHtml(html, name, start) self.addListBox(episode["url"], episode["name"]) start += 1 self.threadListBox.show_all() self.builder.get_object("dlAllbttn").set_sensitive(True) @threaded def addListBox(self, linkURI, fileName): box = gtk.Box() link = gtk.LinkButton() progBar = gtk.ProgressBar() plyBttn = gtk.Button() dlBttn = gtk.Button() link.set_uri(linkURI) link.set_label(fileName) progBar.set_pulse_step(1.0) plyBttn.set_always_show_image(True) plyBttn.set_image(gtk.Image().new_from_file(self.playImage)) plyBttn.connect("clicked", self.playVideo) dlBttn.set_always_show_image(True) dlBttn.set_image(gtk.Image().new_from_file(self.downloadImage)) dlBttn.connect("clicked", self.bttnDownload) box.pack_start(plyBttn, expand = True, fill = True, padding = 0) box.pack_start(link, expand = True, fill = True, padding = 0) box.pack_start(progBar, expand = True, fill = True, padding = 0) box.pack_start(dlBttn, expand = True, fill = True, padding = 0) self.progressBars.append(progBar) box.show_all() gobject.idle_add(self.threadListBox.add, (box)) # self.threadListBox.add(box) def playVideo(self, widget): linkBttn = widget.get_parent().get_children()[1] self.videoPopover.popup() link = linkBttn.get_uri() mpvFrame = self.builder.get_object("mpvFrame") self.mpv = mpv.MPV(wid=str(mpvFrame.get_property("window").get_xid())) self.mpv.play(link) def parseHtml(self, html, name, i): parts = None buf = io.StringIO(html) while True: line = buf.readline() if not line: break if "file:\"http" in line: url = line.split("file:\"")[1].split("\",")[0].rstrip() name = name + " - 0" + str(i) + ".mp4" parts = {"url": url, "name": name} break buf.close() return parts def bttnDownload(self, widget): linkBttn = widget.get_parent().get_children()[1] link = linkBttn.get_uri() name = linkBttn.get_label() index = self.getIndex(widget) self.download( [ {"url": link, "name": name, "index": index} ] ) def bttnDownloadAll(self, widget): self.threadListBox.select_all() rows = self.threadListBox.get_selected_rows() episodes = list() for row in rows: children = row.get_children()[0].get_children() linkBttn = children[1] index = row.get_index() link = linkBttn.get_uri() name = linkBttn.get_label() episodes.append({"url": link, "name": name, "index": index}) self.download(episodes) @threaded def download(self, episodes): for episode in episodes: self.i = int(episode["index"]) timeout_id = glib.timeout_add(800, self.pulse, None) thread = threading.Thread(target=self.downloadEpisode, args=(episode["url"], episode["name"], episode["index"])) thread.start() if sys.version_info < (3, 9): while thread.isAlive(): time.sleep(1) else: while thread.is_alive(): time.sleep(1) glib.source_remove(timeout_id) self.progressBars[self.i].set_fraction(1) def downloadEpisode(self, url, name, index): try: print(f"Download Link: {url}") r = requests.get(url, allow_redirects=True) open(name, 'wb').write(r.content) except Exception as e: print("Error occured while downloading file...") print(f"Trace is: {e}") return False return True def clearListBox(self): self.builder.get_object("dlAllbttn").set_sensitive(False) self.progressBars.clear() children = self.threadListBox.get_children() for child in children: self.threadListBox.remove(child); def getIndex(self, widget): listBoxRow = widget.get_parent().get_parent() return listBoxRow.get_index() def closePlayer(self, widget): self.mpv.terminate() self.videoPopover.popdown() self.mpv = None def pulse(self, eve): self.progressBars[self.i].pulse() return True