Added python project; fixed spelling of folder
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
# 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
|
100
Python Projects/gtk/AnimeFreakDL/signal_classes/SearchWindow.py
Normal file
100
Python Projects/gtk/AnimeFreakDL/signal_classes/SearchWindow.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# Gtk imports
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk as gtk
|
||||
|
||||
# Python imports
|
||||
import threading, subprocess, os, requests, json as JSON
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
def threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class SearchWindow:
|
||||
def __init__(self, settings):
|
||||
self.settings = settings
|
||||
self.builder = self.settings.returnBuilder()
|
||||
self.searchStore = self.builder.get_object("searchStore")
|
||||
|
||||
self.endRangeStepper = self.builder.get_object("endRangeStepper")
|
||||
self.baseUrlEntry = self.builder.get_object("baseUrlEntry")
|
||||
self.titleLabel = self.builder.get_object("titleLabel")
|
||||
|
||||
self.scrptPth = os.path.dirname(os.path.realpath(__file__)) + "/"
|
||||
|
||||
|
||||
def search(self, widget):
|
||||
queryStr = widget.get_text().strip()
|
||||
if queryStr != "":
|
||||
self.searchStore.clear()
|
||||
url = 'https://www.animefreak.tv/search/topSearch?q=' + queryStr
|
||||
r = requests.get(url)
|
||||
|
||||
if r.status_code == 200:
|
||||
json = JSON.loads(r.text)
|
||||
data = self.parseJSON(json)
|
||||
self.fillImageStore(data)
|
||||
else:
|
||||
print("::Error occured while getting JSON::")
|
||||
print("Status code is: " + str(r.status_code))
|
||||
|
||||
def handleSelected(self, selection):
|
||||
if selection:
|
||||
model = selection.get_selected()[0] # Getting model
|
||||
itr = selection.get_selected()[1] # Getting iter
|
||||
title = model.get_value(itr, 0)
|
||||
link = model.get_value(itr, 1)
|
||||
count = model.get_value(itr, 2)
|
||||
|
||||
self.titleLabel.set_text(title)
|
||||
self.baseUrlEntry.set_text(link)
|
||||
self.endRangeStepper.set_value(int(count))
|
||||
|
||||
@threaded
|
||||
def fillImageStore(self, data):
|
||||
for show in data:
|
||||
path = self.scrptPth + "../thumbnails/" + show["thumbnailName"]
|
||||
if not os.path.isfile(path):
|
||||
self.downloadThumbnail(show["thumbnailLink"], path)
|
||||
|
||||
pixbuf = gtk.Image.new_from_file(path).get_pixbuf()
|
||||
self.searchStore.append([show["title"], show["link"],
|
||||
show["count"], pixbuf])
|
||||
|
||||
|
||||
def parseJSON(self, json):
|
||||
data = []
|
||||
|
||||
for obj in json["data"]:
|
||||
title = obj["name"]
|
||||
seoName = obj["seo_name"]
|
||||
count = str(1)
|
||||
id = str(obj["anime_id"])
|
||||
|
||||
if obj["episodes"]:
|
||||
try:
|
||||
epiSeoName = obj["episodes"][0]["episode_seo_name"]
|
||||
if not epiSeoName == "movie":
|
||||
count = epiSeoName.split("-")[1]
|
||||
except Exception as e:
|
||||
print(obj["episodes"])
|
||||
|
||||
thumbnailName = seoName + ".jpg"
|
||||
watchLink = "https://www.animefreak.tv/watch/" + seoName
|
||||
thumbnailLink = "https://www.animefreak.tv/meta/anime/" + id + "/" + thumbnailName
|
||||
|
||||
data.append({"title" : title, "link": watchLink, "thumbnailName": thumbnailName,
|
||||
"thumbnailLink": thumbnailLink, "count": count})
|
||||
|
||||
return data
|
||||
|
||||
def downloadThumbnail(self, thumbnailLink, path):
|
||||
r = requests.get(thumbnailLink, allow_redirects=True)
|
||||
open(path, 'wb').write(r.content)
|
@@ -0,0 +1,2 @@
|
||||
from signal_classes.CrossClassSignals import CrossClassSignals
|
||||
from signal_classes.SearchWindow import SearchWindow
|
Reference in New Issue
Block a user