Added python project; fixed spelling of folder
49
Python Projects/gtk/AnimeFreakDL/AnimeFreakDL.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Gtk imports
|
||||
import gi, faulthandler, signal
|
||||
gi.require_version('Gtk', '3.0')
|
||||
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk as gdk
|
||||
from gi.repository import GLib
|
||||
|
||||
# Python imports
|
||||
import inspect
|
||||
from setproctitle import setproctitle
|
||||
|
||||
# Application imports
|
||||
from utils import Settings
|
||||
from signal_classes import CrossClassSignals, SearchWindow
|
||||
|
||||
|
||||
class AnimeFreakDL:
|
||||
def __init__(self):
|
||||
setproctitle('AnimeFreakDL')
|
||||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, gtk.main_quit)
|
||||
faulthandler.enable() # For better debug info
|
||||
|
||||
settings = Settings()
|
||||
builder = settings.returnBuilder()
|
||||
|
||||
# Gets the methods from the classes and sets to handler.
|
||||
# Then, builder connects to any signals it needs.
|
||||
classes = [CrossClassSignals(settings),
|
||||
SearchWindow(settings)]
|
||||
|
||||
handlers = {}
|
||||
for c in classes:
|
||||
methods = inspect.getmembers(c, predicate=inspect.ismethod)
|
||||
handlers.update(methods)
|
||||
|
||||
builder.connect_signals(handlers)
|
||||
window = settings.createWindow()
|
||||
window.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main = AnimeFreakDL()
|
||||
gtk.main()
|
||||
except Exception as e:
|
||||
print(e)
|
12
Python Projects/gtk/AnimeFreakDL/clear_pycache_dirs.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
find . -name "__pycache__" -exec rm -rf $1 {} \;
|
||||
find . -name "*.pyc" -exec rm -rf $1 {} \;
|
||||
}
|
||||
main
|
11
Python Projects/gtk/AnimeFreakDL/dlAnime.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
python3 AnimeFreakDL.py
|
||||
}
|
||||
main $@;
|
19
Python Projects/gtk/AnimeFreakDL/notes.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
:: CURL ::
|
||||
|
||||
-- Search --
|
||||
curl 'https://www.animefreak.tv/search/topSearch?q=' + queryText -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://www.animefreak.tv/watch/enen-no-shouboutai' -H 'X-Requested-With: XMLHttpRequest'
|
||||
|
||||
Ex:
|
||||
curl 'https://www.animefreak.tv/search/topSearch?q=naruto' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Referer: https://www.animefreak.tv/watch/enen-no-shouboutai' -H 'X-Requested-With: XMLHttpRequest'
|
||||
|
||||
|
||||
-- Thumbnail --
|
||||
https://www.animefreak.tv/meta/anime/<anime_id>/<seo_name> + .jpg
|
||||
|
||||
EX: https://www.animefreak.tv/meta/anime/5833/naruto-shippuuden-movie-3.jpg
|
||||
|
||||
|
||||
|
||||
-- Root Page Link --
|
||||
|
||||
https://www.animefreak.tv/watch/<seo_name>
|
454
Python Projects/gtk/AnimeFreakDL/resources/Main_Window.glade
Normal file
@@ -0,0 +1,454 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkAdjustment" id="adjustmentEnd">
|
||||
<property name="lower">1</property>
|
||||
<property name="upper">2000</property>
|
||||
<property name="value">24</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustmentStart">
|
||||
<property name="lower">1</property>
|
||||
<property name="upper">2000</property>
|
||||
<property name="value">1</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="downloadImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-save-as</property>
|
||||
<property name="icon_size">5</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="searchStore">
|
||||
<columns>
|
||||
<!-- column-name Titles -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Links -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Episode -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Images -->
|
||||
<column type="GdkPixbuf"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkImage" id="showList">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-index</property>
|
||||
<property name="icon_size">5</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="Main_Window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">AnimeFreakDL</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">600</property>
|
||||
<property name="icon">icon.png</property>
|
||||
<property name="gravity">center</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="popuotPoint">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">15</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">15</property>
|
||||
<property name="margin_bottom">15</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
<signal name="search-changed" handler="search" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="titleLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">searchStore</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="headers_clickable">False</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection">
|
||||
<signal name="changed" handler="handleSelected" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">column</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="visible">False</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
<attribute name="max-width-chars">2</attribute>
|
||||
<attribute name="placeholder-text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">column</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="visible">False</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">column</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText">
|
||||
<property name="visible">False</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">column</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">15</property>
|
||||
<property name="margin_top">15</property>
|
||||
<property name="margin_bottom">15</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="baseUrlEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Base URL...</property>
|
||||
<property name="placeholder_text" translatable="yes">Base URL...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="baseNameEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Base Video Name...</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="text" translatable="yes">Video</property>
|
||||
<property name="placeholder_text" translatable="yes">Base Video Name...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">15</property>
|
||||
<property name="margin_right">15</property>
|
||||
<property name="label" translatable="yes">Start Range</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="startRangeStepper">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Start range...</property>
|
||||
<property name="max_length">2000</property>
|
||||
<property name="text" translatable="yes">1</property>
|
||||
<property name="placeholder_text" translatable="yes">1</property>
|
||||
<property name="input_purpose">digits</property>
|
||||
<property name="adjustment">adjustmentStart</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="snap_to_ticks">True</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="update_policy">if-valid</property>
|
||||
<property name="value">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">15</property>
|
||||
<property name="margin_right">15</property>
|
||||
<property name="label" translatable="yes">End Range</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="endRangeStepper">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">End range...</property>
|
||||
<property name="max_length">2000</property>
|
||||
<property name="text" translatable="yes">15</property>
|
||||
<property name="placeholder_text" translatable="yes">15</property>
|
||||
<property name="input_purpose">digits</property>
|
||||
<property name="adjustment">adjustmentEnd</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="snap_to_ticks">True</property>
|
||||
<property name="numeric">True</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="update_policy">if-valid</property>
|
||||
<property name="value">15</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Show List</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">showList</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="createDownloadList" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="dlAllbttn">
|
||||
<property name="label" translatable="yes">Download All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">downloadImage</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="bttnDownloadAll" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="threadListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="selection_mode">multiple</property>
|
||||
<property name="activate_on_single_click">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="videoPopover">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="relative_to">popuotPoint</property>
|
||||
<property name="position">bottom</property>
|
||||
<signal name="closed" handler="closePlayer" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkFrame" id="mpvFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
BIN
Python Projects/gtk/AnimeFreakDL/resources/download.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/resources/icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/resources/play.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,3 @@
|
||||
progress, trough {
|
||||
min-height: 75px;
|
||||
}
|
@@ -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
@@ -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
|
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 16 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/death-note.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 27 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/kimi-no-na-wa.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 62 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/mirai-nikki.jpg
Normal file
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 14 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/munou-na-nana.jpg
Normal file
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 13 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/naruto.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Python Projects/gtk/AnimeFreakDL/thumbnails/noragami.jpg
Normal file
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,152 @@
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>
|
||||
Animefreak.TV - Watch Anime Online for Free. Subbed & Dubbed
|
||||
</title>
|
||||
<meta name="description" content="Animefreak.TV #1 Site to watch thousands of dubbed and subbed anime episodes including Dragon Ball Super, Attack on Titan, Naruto Shippuden, One Piece">
|
||||
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/reset.css">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/all.css?rel=1610991072522">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/extensions.css">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/bower_components/font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/uploadjs.css">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/swiper-min.css">
|
||||
<link rel="stylesheet" href="https://www.animefreak.tv/css/adpops.css">
|
||||
|
||||
|
||||
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||
|
||||
|
||||
<script>
|
||||
var base_url = 'https://www.animefreak.tv/';
|
||||
var chatserver_url = 'https://chat.animefreak.tv/';
|
||||
</script>
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-129291100-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-129291100-1');
|
||||
</script>
|
||||
<script type="text/javascript" src="//st.bebi.com/bebi_v3.js"></script>
|
||||
<script src="https://cdn.siteswithcontent.com/js/push/subscribe.js?v=1.1.0"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="searchModal">
|
||||
<div class="sm-filter"></div>
|
||||
<div class="sm-content">
|
||||
<div class="searchClose"><i class="fa fa-close"></i></div>
|
||||
<div class="smc-search">
|
||||
<input type="text" class="smcs-input" id="topSearch" placeholder="Search Anime">
|
||||
<button class="smcs-button"><i class="fa fa-search"></i></button>
|
||||
</div>
|
||||
<div id="arama_title" class="smc-title"></div>
|
||||
<div class="smc-results">
|
||||
<div class="nano">
|
||||
<div class="nano-content">
|
||||
<div id="animeSearchResult">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="main">
|
||||
<a class="back-to-top" ><i class="fa fa-arrow-up"></i><br>Go To Top
|
||||
</a>
|
||||
<div class="header">
|
||||
<div class="mobileMenuTrigger"><i class="fa fa-bars"></i></div>
|
||||
<a href="https://www.animefreak.tv/" class="logo"></a>
|
||||
<div class="main-menu">
|
||||
<ul>
|
||||
<li><a href="https://www.animefreak.tv/home/ongoing">Ongoing</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/Spring 2021" >Spring 2021</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/anime-list">Anime List</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/genres">Browse by Genre</a></li>
|
||||
<li><a href="https://www.animefreak.tv/search">Search</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/latest-episodes">Latest Episodes</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/latest-animes">Latest Anime</a></li>
|
||||
<li><a href="https://www.animefreak.tv/home/popular-animes">Popular Anime</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="searchTrigger"><i class="fa fa-search"></i> Search</div>
|
||||
|
||||
<div class="header-right">
|
||||
<a class="an-link" href="https://www.animefreak.tv/user/login">Login</a>
|
||||
<a class="an-link" href="https://www.animefreak.tv/user/register">Register</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Container -->
|
||||
<div class="container">
|
||||
<div class="centerAligner">
|
||||
<div class="w-center">
|
||||
<div class="w-container">
|
||||
<div><img src="https://www.animefreak.tv/img/404-image.png"></div>
|
||||
<div class="w-text">
|
||||
<span><strong>Page Not Found</strong> </span><br>
|
||||
</div>
|
||||
<a href="https://www.animefreak.tv/" class="auto-button">Homepage</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Container -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var user = null;
|
||||
|
||||
</script>
|
||||
|
||||
<script src="https://www.animefreak.tv/bower_components/uploadjs/dist/uploadjs.js"></script>
|
||||
|
||||
<script src="https://www.animefreak.tv/js/all.js?rel=1610991072518"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
if(!window.BB_a) { BB_a = [];} if(!window.BB_ind) { BB_ind = 0; } if(!window.BB_vrsa) { BB_vrsa = 'v3'; }if(!window.BB_r) { BB_r = Math.floor(Math.random()*1000000000)} BB_ind++; BB_a.push({ "pl" : 41415, "index": BB_ind});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
document.write('<scr'+'ipt data-cfasync="false" async id="BB_SLOT_'+BB_r+'_'+BB_ind+'" src="//st.bebi.com/bebi_'+BB_vrsa+'.js"></scr'+'ipt>');
|
||||
</script>
|
||||
|
||||
|
||||
<script src="https://www.animefreak.tv/js/androidapp2.js"></script>
|
||||
<script type="text/javascript" src="//inpagepush.com/400/3091648" data-cfasync="false" async="async"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 11 KiB |
56
Python Projects/gtk/AnimeFreakDL/utils/Settings.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# Gtk imports
|
||||
import gi, cairo
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('Gdk', '3.0')
|
||||
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk as gdk
|
||||
|
||||
# Python imports
|
||||
import os
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
class Settings:
|
||||
def __init__(self):
|
||||
self.scrptPth = os.path.dirname(os.path.realpath(__file__)) + "/"
|
||||
gladeFile = "../resources/Main_Window.glade"
|
||||
self.builder = gtk.Builder()
|
||||
self.builder.add_from_file(self.scrptPth + gladeFile)
|
||||
|
||||
|
||||
def createWindow(self):
|
||||
# Get window and connect signals
|
||||
window = self.builder.get_object("Main_Window")
|
||||
window.connect("delete-event", gtk.main_quit)
|
||||
self.setWindowData(window)
|
||||
return window
|
||||
|
||||
def setWindowData(self, window):
|
||||
screen = window.get_screen()
|
||||
visual = screen.get_rgba_visual()
|
||||
if visual != None and screen.is_composited():
|
||||
window.set_visual(visual)
|
||||
|
||||
# bind css file
|
||||
cssProvider = gtk.CssProvider()
|
||||
cssProvider.load_from_path(self.scrptPth + '../resources/stylesheet.css')
|
||||
screen = gdk.Screen.get_default()
|
||||
styleContext = gtk.StyleContext()
|
||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
|
||||
# window.set_app_paintable(True)
|
||||
|
||||
def getMonitorData(self, screen):
|
||||
monitors = []
|
||||
for m in range(screen.get_n_monitors()):
|
||||
monitors.append(screen.get_monitor_geometry(m))
|
||||
|
||||
for monitor in monitors:
|
||||
print(str(monitor.width) + "x" + str(monitor.height) + "+" + str(monitor.x) + "+" + str(monitor.y))
|
||||
|
||||
return monitors
|
||||
|
||||
|
||||
def returnBuilder(self): return self.builder
|
2
Python Projects/gtk/AnimeFreakDL/utils/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from utils.Settings import Settings
|
||||
from utils.mpv import MPV
|