mirror of
https://github.com/karl0ss/GoGoDownloader.git
synced 2025-04-28 04:13:40 +01:00
gogo initial commit
This commit is contained in:
parent
3262b2c69e
commit
bf777d1a29
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
venv/
|
||||||
|
*.mp4
|
||||||
|
config.json
|
||||||
|
__pycache__/
|
130
backend.py
Normal file
130
backend.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from colorama import Fore
|
||||||
|
from parfive import Downloader
|
||||||
|
from threading import Semaphore
|
||||||
|
|
||||||
|
|
||||||
|
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
||||||
|
ERR = f"{Fore.RESET}[{Fore.RED}-{Fore.RESET}] "
|
||||||
|
IN = f"{Fore.RESET}[{Fore.LIGHTBLUE_EX}>{Fore.RESET}] "
|
||||||
|
|
||||||
|
global CONFIG
|
||||||
|
|
||||||
|
screenlock = Semaphore(value=1)
|
||||||
|
|
||||||
|
|
||||||
|
def config_check():
|
||||||
|
if os.path.exists("./config.json"):
|
||||||
|
with open("./config.json", "r") as f:
|
||||||
|
CONFIG = json.load(f)
|
||||||
|
if not "GoGoAnimeAuthKey" in CONFIG or len(CONFIG["GoGoAnimeAuthKey"]) == 0:
|
||||||
|
print("GoGoAnimeAuthKey not set in config.json")
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
return CONFIG
|
||||||
|
else:
|
||||||
|
print("config.json file not found")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
CURRENT_DOMAIN = "film"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(init=True)
|
||||||
|
class Download:
|
||||||
|
name: str
|
||||||
|
episode_quality: str
|
||||||
|
folder: str
|
||||||
|
all_episodes: int
|
||||||
|
episode_start: int
|
||||||
|
episode_end: int
|
||||||
|
config: object
|
||||||
|
printed: bool = False
|
||||||
|
|
||||||
|
def get_links(self, source=None):
|
||||||
|
if source is not None:
|
||||||
|
source_ep = f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/{self.name}-episode-"
|
||||||
|
episode_links = [
|
||||||
|
f"{source_ep}{i}"
|
||||||
|
for i in range(self.episode_start, self.episode_end + 1)
|
||||||
|
]
|
||||||
|
episode_links.insert(0, source)
|
||||||
|
else:
|
||||||
|
source_ep = f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/{self.name}-episode-"
|
||||||
|
episode_links = [
|
||||||
|
f"{source_ep}{i}"
|
||||||
|
for i in range(self.episode_start, self.episode_end + 1)
|
||||||
|
]
|
||||||
|
return episode_links
|
||||||
|
|
||||||
|
|
||||||
|
def get_download_link(config, url, episode_quality):
|
||||||
|
|
||||||
|
page = requests.get(
|
||||||
|
url,
|
||||||
|
cookies=dict(auth=config["GoGoAnimeAuthKey"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
soup = BeautifulSoup(page.content, "html.parser")
|
||||||
|
|
||||||
|
for link in soup.find_all("a", href=True):
|
||||||
|
if episode_quality in link.text:
|
||||||
|
return link["href"]
|
||||||
|
|
||||||
|
|
||||||
|
def file_downloader(file_list: dict, title: str, config: object):
|
||||||
|
dl = Downloader(
|
||||||
|
max_conn=config["MaxConcurrentDownloads"],
|
||||||
|
overwrite=False,
|
||||||
|
headers=dict(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"User-Agent",
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
|
||||||
|
),
|
||||||
|
("authority", "gogo-cdn.com"),
|
||||||
|
("referer", f"https://gogoanime.{config['CurrentGoGoAnimeDomain']}/"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for link in file_list:
|
||||||
|
dl.enqueue_file(
|
||||||
|
link,
|
||||||
|
path=f"./{title}",
|
||||||
|
)
|
||||||
|
|
||||||
|
files = dl.download()
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(init=True)
|
||||||
|
class CustomMessage(Exception):
|
||||||
|
"""Custom message that will accept message as a parameter and it will print it on the console."""
|
||||||
|
|
||||||
|
message: str = None
|
||||||
|
episode_quality: str = None
|
||||||
|
workingepisode: str = None
|
||||||
|
|
||||||
|
def print_error(self):
|
||||||
|
screenlock.acquire()
|
||||||
|
print(ERR, self.message, end=" ")
|
||||||
|
screenlock.release()
|
||||||
|
|
||||||
|
def qual_not_found(self):
|
||||||
|
screenlock.acquire()
|
||||||
|
print(
|
||||||
|
f"{ERR}Episode {self.workingepisode} {Fore.LIGHTCYAN_EX}{self.episode_quality}{Fore.RESET} quality not found."
|
||||||
|
)
|
||||||
|
screenlock.release()
|
||||||
|
|
||||||
|
def use_default_qual(self):
|
||||||
|
screenlock.acquire()
|
||||||
|
print(
|
||||||
|
f"{OK}Trying {Fore.LIGHTCYAN_EX}{self.episode_quality}{Fore.RESET} quality for Episode {self.workingepisode}."
|
||||||
|
)
|
||||||
|
screenlock.release()
|
5
config.json.default
Normal file
5
config.json.default
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"GoGoAnimeAuthKey": "",
|
||||||
|
"MaxConcurrentDownloads": 4,
|
||||||
|
"CurrentGoGoAnimeDomain": "film"
|
||||||
|
}
|
163
main.py
Normal file
163
main.py
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
import requests
|
||||||
|
import ctypes
|
||||||
|
import os
|
||||||
|
from backend import *
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from colorama import Fore
|
||||||
|
|
||||||
|
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
||||||
|
ERR = f"{Fore.RESET}[{Fore.RED}-{Fore.RESET}] "
|
||||||
|
IN = f"{Fore.RESET}[{Fore.LIGHTBLUE_EX}>{Fore.RESET}] "
|
||||||
|
try:
|
||||||
|
ctypes.windll.kernel32.SetConsoleTitleW("GoGo Downloader")
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def gogodownloader(config):
|
||||||
|
CURRENT_DOMAIN = config["CurrentGoGoAnimeDomain"]
|
||||||
|
os.system("cls")
|
||||||
|
while True:
|
||||||
|
print(
|
||||||
|
f""" {Fore.LIGHTBLUE_EX}
|
||||||
|
|
||||||
|
______ ______
|
||||||
|
/ ____/___ / ____/___
|
||||||
|
/ / __/ __ \/ / __/ __ \
|
||||||
|
/ /_/ / /_/ / /_/ / /_/ /
|
||||||
|
\__________/\____/\____/ __ __
|
||||||
|
/ __ \____ _ ______ / /___ ____ _____/ /__ _____
|
||||||
|
/ / / / __ \ | /| / / __ \/ / __ \/ __ `/ __ / _ \/ ___/
|
||||||
|
/ /_/ / /_/ / |/ |/ / / / / / /_/ / /_/ / /_/ / __/ /
|
||||||
|
/_____/\____/|__/|__/_/ /_/_/\____/\__,_/\__,_/\___/_/
|
||||||
|
|
||||||
|
{Fore.RED}
|
||||||
|
By: Karl0ss
|
||||||
|
Forked From: sh1nobuu
|
||||||
|
Github: https://github.com/karl0ss/GoGoDownloader
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
while True:
|
||||||
|
name = input(f"{IN}Enter anime name > ").lower()
|
||||||
|
if "-" in name:
|
||||||
|
title = name.replace("-", " ").title().strip()
|
||||||
|
else:
|
||||||
|
title = name.title().strip()
|
||||||
|
source = f"https://gogoanime.{CURRENT_DOMAIN}/category/{name}"
|
||||||
|
with requests.get(source) as res:
|
||||||
|
if res.status_code == 200:
|
||||||
|
soup = BeautifulSoup(res.content, "html.parser")
|
||||||
|
all_episodes = soup.find("ul", {"id": "episode_page"})
|
||||||
|
all_episodes = int(all_episodes.get_text().split("-")[-1].strip())
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"{ERR}Error 404: Anime not found. Please try again.")
|
||||||
|
while True:
|
||||||
|
quality = input(
|
||||||
|
f"{IN}Enter episode quality (1.SD/360P|2.SD/480P|3.HD/720P|4.FULLHD/1080P) > "
|
||||||
|
)
|
||||||
|
if quality == "1" or quality == "":
|
||||||
|
episode_quality = "360"
|
||||||
|
break
|
||||||
|
elif quality == "2":
|
||||||
|
episode_quality = "480"
|
||||||
|
break
|
||||||
|
elif quality == "3":
|
||||||
|
episode_quality = "720"
|
||||||
|
break
|
||||||
|
elif quality == "4":
|
||||||
|
episode_quality = "1080"
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"{ERR}Invalid input. Please try again.")
|
||||||
|
print(f"{OK}Title: {Fore.LIGHTCYAN_EX}{title}")
|
||||||
|
print(f"{OK}Episode/s: {Fore.LIGHTCYAN_EX}{all_episodes}")
|
||||||
|
print(f"{OK}Quality: {Fore.LIGHTCYAN_EX}{episode_quality}")
|
||||||
|
print(f"{OK}Link: {Fore.LIGHTCYAN_EX}{source}")
|
||||||
|
|
||||||
|
folder = os.path.join(os.getcwd(), title)
|
||||||
|
if not os.path.exists(folder):
|
||||||
|
os.mkdir(folder)
|
||||||
|
|
||||||
|
choice = "y"
|
||||||
|
|
||||||
|
if all_episodes != 1:
|
||||||
|
while True:
|
||||||
|
choice = input(
|
||||||
|
f"{IN}Do you want to download all episode? (y/n) > "
|
||||||
|
).lower()
|
||||||
|
if choice in ["y", "n"]:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"{ERR}Invalid input. Please try again.")
|
||||||
|
|
||||||
|
episode_start = None
|
||||||
|
episode_end = None
|
||||||
|
|
||||||
|
if choice == "n":
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
episode_start = int(input(f"{IN}Episode start > "))
|
||||||
|
episode_end = int(input(f"{IN}Episode end > "))
|
||||||
|
if episode_start <= 0 or episode_end <= 0:
|
||||||
|
CustomMessage(
|
||||||
|
f"{ERR}episode_start or episode_end cannot be less than or equal to 0"
|
||||||
|
).print_error()
|
||||||
|
elif episode_start >= all_episodes or episode_end > all_episodes:
|
||||||
|
CustomMessage(
|
||||||
|
f"{ERR}episode_start or episode_end cannot be more than {all_episodes}"
|
||||||
|
).print_error()
|
||||||
|
elif episode_end <= episode_start:
|
||||||
|
CustomMessage(
|
||||||
|
f"{ERR}episode_end cannot be less than or equal to episode_start"
|
||||||
|
).print_error()
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
print(f"{ERR}Invalid input. Please try again.")
|
||||||
|
|
||||||
|
if episode_start is not None:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
episode_start = 1
|
||||||
|
if episode_end is not None:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
episode_end = all_episodes
|
||||||
|
|
||||||
|
download = Download(
|
||||||
|
name,
|
||||||
|
episode_quality,
|
||||||
|
folder,
|
||||||
|
all_episodes,
|
||||||
|
episode_start,
|
||||||
|
episode_end,
|
||||||
|
config,
|
||||||
|
)
|
||||||
|
|
||||||
|
source = f"https://gogoanime.{CURRENT_DOMAIN}/{name}"
|
||||||
|
with requests.get(source) as res:
|
||||||
|
soup = BeautifulSoup(res.content, "html.parser")
|
||||||
|
episode_zero = soup.find("h1", {"class": "entry-title"}) # value: 404
|
||||||
|
|
||||||
|
if choice == "n" or episode_zero is not None:
|
||||||
|
source = None
|
||||||
|
|
||||||
|
dl_links = []
|
||||||
|
episode_links = download.get_links(source)
|
||||||
|
|
||||||
|
for link in episode_links:
|
||||||
|
dl_links.append(get_download_link(config, link, episode_quality))
|
||||||
|
|
||||||
|
file_downloader(dl_links, title, config)
|
||||||
|
|
||||||
|
use_again = input(f"{IN}Do you want to use the app again? (y|n) > ").lower()
|
||||||
|
if use_again == "y":
|
||||||
|
os.system("cls")
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
config = config_check()
|
||||||
|
gogodownloader(config)
|
25
requirements.txt
Normal file
25
requirements.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
aiohttp==3.8.1
|
||||||
|
aiosignal==1.2.0
|
||||||
|
args==0.1.0
|
||||||
|
async-timeout==4.0.2
|
||||||
|
attrs==21.4.0
|
||||||
|
beautifulsoup4==4.10.0
|
||||||
|
black==21.12b0
|
||||||
|
certifi==2021.10.8
|
||||||
|
charset-normalizer==2.0.10
|
||||||
|
click==8.0.3
|
||||||
|
colorama==0.4.4
|
||||||
|
frozenlist==1.2.0
|
||||||
|
idna==3.3
|
||||||
|
multidict==5.2.0
|
||||||
|
mypy-extensions==0.4.3
|
||||||
|
parfive==1.5.1
|
||||||
|
pathspec==0.9.0
|
||||||
|
platformdirs==2.4.1
|
||||||
|
requests==2.27.1
|
||||||
|
soupsieve==2.3.1
|
||||||
|
tomli==1.2.3
|
||||||
|
tqdm==4.62.3
|
||||||
|
typing-extensions==4.0.1
|
||||||
|
urllib3==1.26.8
|
||||||
|
yarl==1.7.2
|
Loading…
x
Reference in New Issue
Block a user