mirror of
https://github.com/karl0ss/GoGoDownloader.git
synced 2025-04-28 12:23:41 +01:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f55d917cc9 | ||
![]() |
475466617d | ||
![]() |
02fa241ec6 | ||
3b599893bc | |||
664f5f4974 | |||
![]() |
62712a3897 | ||
![]() |
d865913154 | ||
2fc41cfa56 | |||
![]() |
5211c127e4 | ||
![]() |
fd1046f8a7 | ||
78a394ffd5 | |||
![]() |
2d1eda3b92 | ||
![]() |
8210e0b07b | ||
![]() |
fc19a690bd | ||
![]() |
b002368705 | ||
![]() |
ee82a26e76 | ||
![]() |
7c4a569678 | ||
![]() |
9ea3c6a6ce | ||
![]() |
64acd0abb2 | ||
![]() |
a09ed8c802 | ||
![]() |
a8d54be2d3 | ||
![]() |
0dffecc6ff | ||
![]() |
46001b041c | ||
![]() |
5a2d682cae | ||
1b2738d4b2 | |||
72cef9b292 | |||
![]() |
6ba9477a89 | ||
093437f464 | |||
![]() |
7a382de2f6 | ||
![]() |
02f275e13a | ||
![]() |
bc957b0607 | ||
b3b02e040c | |||
![]() |
bbec182b38 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,3 +5,7 @@ __pycache__/
|
|||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
main.spec
|
main.spec
|
||||||
|
.vscode/launch.json
|
||||||
|
app.log
|
||||||
|
bookmarkList.json
|
||||||
|
downloadHistory.json
|
||||||
|
3
CLIOutput/eng.bat
Normal file
3
CLIOutput/eng.bat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
for /R %%a in ("*.mp4") do MP4Box -lang eng "%%a"
|
||||||
|
|
||||||
|
exit
|
@ -4,6 +4,7 @@ import os
|
|||||||
from backend import gogoanime, CustomMessage, config_check
|
from backend import gogoanime, CustomMessage, config_check
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
|
import logging
|
||||||
|
|
||||||
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
||||||
ERR = f"{Fore.RESET}[{Fore.RED}-{Fore.RESET}] "
|
ERR = f"{Fore.RESET}[{Fore.RED}-{Fore.RESET}] "
|
||||||
@ -15,8 +16,8 @@ except AttributeError:
|
|||||||
|
|
||||||
|
|
||||||
def gogodownloader(config):
|
def gogodownloader(config):
|
||||||
CURRENT_DOMAIN = config["CurrentGoGoAnimeDomain"]
|
CURRENT_URL = config["CurrentGoGoAnimeURL"]
|
||||||
os.system("cls")
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
while True:
|
while True:
|
||||||
print(
|
print(
|
||||||
f""" {Fore.LIGHTBLUE_EX}
|
f""" {Fore.LIGHTBLUE_EX}
|
||||||
@ -39,16 +40,17 @@ def gogodownloader(config):
|
|||||||
)
|
)
|
||||||
while True:
|
while True:
|
||||||
name = input(f"{IN}Enter anime name > ").lower()
|
name = input(f"{IN}Enter anime name > ").lower()
|
||||||
|
logging.info("episode searched for " + name)
|
||||||
if "-" in name:
|
if "-" in name:
|
||||||
title = name.replace("-", " ").title().strip()
|
title = name.replace("-", " ").title().strip()
|
||||||
else:
|
else:
|
||||||
title = name.title().strip()
|
title = name.title().strip()
|
||||||
source = f"https://gogoanime.{CURRENT_DOMAIN}/category/{name}"
|
source = f"https://{CURRENT_URL}/category/{name}"
|
||||||
with requests.get(source) as res:
|
with requests.get(source) as res:
|
||||||
if res.status_code == 200:
|
if res.status_code == 200:
|
||||||
soup = BeautifulSoup(res.content, "html.parser")
|
soup = BeautifulSoup(res.content, "html.parser")
|
||||||
all_episodes = soup.find("ul", {"id": "episode_page"})
|
all_episodes = soup.find("ul", {"id": "episode_page"})
|
||||||
all_episodes = int(all_episodes.get_text().split("-")[-1].strip())
|
all_episodes = int(list(filter(None, "-".join(all_episodes.get_text().splitlines()).split("-")))[-1].strip())
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print(f"{ERR}Error 404: Anime not found. Please try again.")
|
print(f"{ERR}Error 404: Anime not found. Please try again.")
|
||||||
@ -70,6 +72,7 @@ def gogodownloader(config):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print(f"{ERR}Invalid input. Please try again.")
|
print(f"{ERR}Invalid input. Please try again.")
|
||||||
|
logging.info("quality selected " + episode_quality)
|
||||||
print(f"{OK}Title: {Fore.LIGHTCYAN_EX}{title}")
|
print(f"{OK}Title: {Fore.LIGHTCYAN_EX}{title}")
|
||||||
print(f"{OK}Episode/s: {Fore.LIGHTCYAN_EX}{all_episodes}")
|
print(f"{OK}Episode/s: {Fore.LIGHTCYAN_EX}{all_episodes}")
|
||||||
print(f"{OK}Quality: {Fore.LIGHTCYAN_EX}{episode_quality}")
|
print(f"{OK}Quality: {Fore.LIGHTCYAN_EX}{episode_quality}")
|
||||||
@ -107,9 +110,9 @@ def gogodownloader(config):
|
|||||||
CustomMessage(
|
CustomMessage(
|
||||||
f"{ERR}episode_start or episode_end cannot be more than {all_episodes}"
|
f"{ERR}episode_start or episode_end cannot be more than {all_episodes}"
|
||||||
).print_error()
|
).print_error()
|
||||||
elif episode_end <= episode_start:
|
elif episode_end < episode_start:
|
||||||
CustomMessage(
|
CustomMessage(
|
||||||
f"{ERR}episode_end cannot be less than or equal to episode_start"
|
f"{ERR}episode_end cannot be less than episode_start"
|
||||||
).print_error()
|
).print_error()
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@ -135,8 +138,8 @@ def gogodownloader(config):
|
|||||||
episode_end,
|
episode_end,
|
||||||
title,
|
title,
|
||||||
)
|
)
|
||||||
|
gogo.user_logged_in_check()
|
||||||
source = f"https://gogoanime.{CURRENT_DOMAIN}/{name}"
|
source = f"https://{CURRENT_URL}/{name}"
|
||||||
with requests.get(source) as res:
|
with requests.get(source) as res:
|
||||||
soup = BeautifulSoup(res.content, "html.parser")
|
soup = BeautifulSoup(res.content, "html.parser")
|
||||||
episode_zero = soup.find("h1", {"class": "entry-title"}) # value: 404
|
episode_zero = soup.find("h1", {"class": "entry-title"}) # value: 404
|
||||||
@ -163,7 +166,7 @@ def gogodownloader(config):
|
|||||||
|
|
||||||
use_again = input(f"{IN}Do you want to use the app again? (y|n) > ").lower()
|
use_again = input(f"{IN}Do you want to use the app again? (y|n) > ").lower()
|
||||||
if use_again == "y":
|
if use_again == "y":
|
||||||
os.system("cls")
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
128
GoGoDownloaderCLI.py
Normal file
128
GoGoDownloaderCLI.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import json
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from backend import *
|
||||||
|
|
||||||
|
|
||||||
|
def renameFile(filename: str):
|
||||||
|
"""_summary_
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename (str): _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
|
newFileName = "".join(re.split("\(|\)|\[|\]", filename)[::2])
|
||||||
|
try:
|
||||||
|
os.rename(filename, newFileName)
|
||||||
|
return True
|
||||||
|
except OSError as err:
|
||||||
|
return err
|
||||||
|
|
||||||
|
|
||||||
|
def loadDownloadHistory():
|
||||||
|
"""Loads the downloadHistory.json, creates it if it doesn't exist
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
object: download history list
|
||||||
|
"""
|
||||||
|
if os.path.isfile("./downloadHistory.json") and os.access(
|
||||||
|
"./downloadHistory.json", os.R_OK
|
||||||
|
):
|
||||||
|
return json.load(open("./downloadHistory.json"))
|
||||||
|
else:
|
||||||
|
with io.open(os.path.join("./", "downloadHistory.json"), "w") as db_file:
|
||||||
|
db_file.write(json.dumps([]))
|
||||||
|
return json.load(open("./downloadHistory.json"))
|
||||||
|
|
||||||
|
|
||||||
|
def writeShowToDownloadHistory(showName: str, downloadHistory: list):
|
||||||
|
"""Writes the showName and latestEpisode to the downloadHistory.json file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
showName (str): _description_
|
||||||
|
downloadHistory (list): _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
|
downloadHistory.append(showName)
|
||||||
|
with io.open(os.path.join("./", "downloadHistory.json"), "w") as db_file:
|
||||||
|
db_file.write(json.dumps(downloadHistory))
|
||||||
|
return json.load(open("./downloadHistory.json"))
|
||||||
|
|
||||||
|
|
||||||
|
def readDownloadHistory(fileNameObject: object, downloadHistory: list):
|
||||||
|
"""Reads the downloadHistory.json and checks if the fileName is present
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fileNameObject (str): _description_
|
||||||
|
downloadHistory (list): _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
|
dhFileName = (
|
||||||
|
fileNameObject["showName"] + " - " + str(fileNameObject["latestEpisode"])
|
||||||
|
)
|
||||||
|
if dhFileName not in downloadHistory:
|
||||||
|
writeShowToDownloadHistory(dhFileName, downloadHistory)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
dh = loadDownloadHistory()
|
||||||
|
config = config_check()
|
||||||
|
downloader = gogoanime(
|
||||||
|
config,
|
||||||
|
1,
|
||||||
|
config["CLIQuality"],
|
||||||
|
"a",
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
config["CLIDownloadLocation"],
|
||||||
|
)
|
||||||
|
list = downloader.get_show_from_bookmark()
|
||||||
|
dl_links = {}
|
||||||
|
for ep in list:
|
||||||
|
if readDownloadHistory(ep, dh):
|
||||||
|
showName = ep["showName"] + " - " + str(ep["latestEpisode"])
|
||||||
|
print(f"{IN}{showName} already downloaded")
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"{IN}Scraping DL for "
|
||||||
|
+ ep["showName"]
|
||||||
|
+ " Ep "
|
||||||
|
+ str(ep["latestEpisode"])
|
||||||
|
)
|
||||||
|
dl_links[downloader.get_download_link(ep["downloadURL"])] = (
|
||||||
|
ep["showName"],
|
||||||
|
ep["latestEpisode"],
|
||||||
|
)
|
||||||
|
result = downloader.file_downloader(dl_links)
|
||||||
|
if config["CleanUpFileName"]:
|
||||||
|
for file in result.data:
|
||||||
|
renameFile(file)
|
||||||
|
if len(result.errors) > 0:
|
||||||
|
while len(result.errors) > 0:
|
||||||
|
print(f"{ERR}{len(result.errors)} links failed retrying.")
|
||||||
|
print(f"{IN}Re-Scraping Links")
|
||||||
|
dl_links.clear()
|
||||||
|
for ep in list:
|
||||||
|
dl_links[downloader.get_download_link(ep["downloadURL"])] = (
|
||||||
|
ep["showName"],
|
||||||
|
ep["latestEpisode"],
|
||||||
|
)
|
||||||
|
result = downloader.file_downloader(dl_links, overwrite_downloads=0)
|
||||||
|
if config["CleanUpFileName"]:
|
||||||
|
for file in result.data:
|
||||||
|
renameFile(file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
40
GoGoDownloaderCLI.spec
Normal file
40
GoGoDownloaderCLI.spec
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(['GoGoDownloaderCLI.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=[],
|
||||||
|
datas=[],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher,
|
||||||
|
noarchive=False)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='GoGoDownloaderCLI',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=True,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None )
|
16
README.md
16
README.md
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
GoGo Downloader is based on the now broken **BitAnime**. I have had to rework quite a bit of the code to get it working again, and have ideas for some other improvements, I don't want to mess with the original codebase too much, hence **GoGo Downloader**.
|
GoGo Downloader is based on the now broken **BitAnime**. I have had to rework quite a bit of the code to get it working again, and have ideas for some other improvements, I don't want to mess with the original codebase too much, hence **GoGo Downloader**.
|
||||||
|
|
||||||
**GoGo Downloader** gets its content from [gogoanime](https://gogoanime.film/). If you get a **404** error, please look up the correct anime name on [gogoanime](https://gogoanime.film/). The application will let you download all the episodes, or you can choose how many episodes you want to download.
|
**GoGo Downloader** gets its content from [gogoanime](http://gogoanime3.net). If you get a **404** error, please look up the correct anime name on [gogoanime](http://gogoanime3.net). The application will let you download all the episodes, or you can choose how many episodes you want to download.
|
||||||
|
|
||||||
GoGo Anime has changed the way they show download links, and this no longer works via BS4, as the recaptcha blocks the links, but if you are logged in, there are other routes to get to download links, I have taken one of these routes to restore the application.
|
GoGo Anime has changed the way they show download links, and this no longer works via BS4, as the recaptcha blocks the links, but if you are logged in, there are other routes to get to download links, I have taken one of these routes to restore the application.
|
||||||
|
|
||||||
@ -57,16 +57,20 @@ If you want to run from source, or are using Linux/Mac you can run directly from
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The anime name is separated by "-". You can either type it manually, or go to [gogoanime.film](https://gogoanime.film/) and search for the anime you want to download and copy the name from the URL.
|
The anime name is separated by "-". You can either type it manually, or go to [gogoanime.gg](https://gogoanime3.gg/) and search for the anime you want to download and copy the name from the URL.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
##### One word title
|
##### One word title
|
||||||
|
|
||||||
- https://gogoanime.film/category/bakemonogatari >> bakemonogatari
|
- https://gogoanime3.gg/category/bakemonogatari >> bakemonogatari
|
||||||
- https://gogoanime.film/category/steinsgate >> steinsgate
|
- https://gogoanime3.gg/category/steinsgate >> steinsgate
|
||||||
|
|
||||||
##### Multiple word title
|
##### Multiple word title
|
||||||
|
|
||||||
- https://gogoanime.film/category/shadows-house >> shadows-house
|
- https://gogoanime3.gg/category/shadows-house >> shadows-house
|
||||||
- https://gogoanime.film/category/kono-subarashii-sekai-ni-shukufuku-wo- >> kono-subarashii-sekai-ni-shukufuku-wo-
|
- https://gogoanime3.gg/category/kono-subarashii-sekai-ni-shukufuku-wo- >> kono-subarashii-sekai-ni-shukufuku-wo-
|
||||||
|
|
||||||
|
|
||||||
|
# GoGoDownloader CLI
|
||||||
|
I have now also created the GoGoDownloader CLI, this tool can be used to run on a scheduled basis, it will login and get the latest episodes from your GoGoAnime bookmarks, and download the latest episode if it has not been downloaded yet.
|
91
backend.py
91
backend.py
@ -7,6 +7,14 @@ from dataclasses import dataclass
|
|||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
from parfive import Downloader
|
from parfive import Downloader
|
||||||
from threading import Semaphore
|
from threading import Semaphore
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
filename="app.log",
|
||||||
|
filemode="w",
|
||||||
|
format="%(name)s - %(levelname)s - %(message)s",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
OK = f"{Fore.RESET}[{Fore.GREEN}+{Fore.RESET}] "
|
||||||
@ -25,9 +33,11 @@ def config_check():
|
|||||||
[object]: Config object
|
[object]: Config object
|
||||||
"""
|
"""
|
||||||
if os.path.exists("./config.json"):
|
if os.path.exists("./config.json"):
|
||||||
|
logging.info("Config.json loaded")
|
||||||
with open("./config.json", "r") as f:
|
with open("./config.json", "r") as f:
|
||||||
CONFIG = json.load(f)
|
CONFIG = json.load(f)
|
||||||
if not "GoGoAnime_Username" in CONFIG or len(CONFIG["GoGoAnime_Username"]) == 0:
|
if not "GoGoAnime_Username" in CONFIG or len(CONFIG["GoGoAnime_Username"]) == 0:
|
||||||
|
logging.error("GoGoAnime_Username not set in config.json")
|
||||||
print("GoGoAnime_Username not set in config.json")
|
print("GoGoAnime_Username not set in config.json")
|
||||||
exit(0)
|
exit(0)
|
||||||
else:
|
else:
|
||||||
@ -35,11 +45,18 @@ def config_check():
|
|||||||
not "GoGoAnime_Password" in CONFIG
|
not "GoGoAnime_Password" in CONFIG
|
||||||
or len(CONFIG["GoGoAnime_Password"]) == 0
|
or len(CONFIG["GoGoAnime_Password"]) == 0
|
||||||
):
|
):
|
||||||
|
logging.error("GoGoAnime_Password not set in config.json")
|
||||||
print("GoGoAnime_Password not set in config.json")
|
print("GoGoAnime_Password not set in config.json")
|
||||||
exit(0)
|
exit(0)
|
||||||
else:
|
else:
|
||||||
|
logging.info(
|
||||||
|
"Config loaded and "
|
||||||
|
+ CONFIG["GoGoAnime_Username"]
|
||||||
|
+ " username found"
|
||||||
|
)
|
||||||
return CONFIG
|
return CONFIG
|
||||||
else:
|
else:
|
||||||
|
logging.error("config.json not found")
|
||||||
print("config.json file not found")
|
print("config.json file not found")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
@ -77,18 +94,18 @@ class gogoanime:
|
|||||||
def get_gogoanime_auth_cookie(self):
|
def get_gogoanime_auth_cookie(self):
|
||||||
session = requests.session()
|
session = requests.session()
|
||||||
page = session.get(
|
page = session.get(
|
||||||
f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/login.html"
|
f"https://{self.config['CurrentGoGoAnimeURL']}/login.html"
|
||||||
)
|
)
|
||||||
soup = BeautifulSoup(page.content, "html.parser")
|
soup = BeautifulSoup(page.content, "html.parser")
|
||||||
meta_path = soup.select('meta[name="csrf-token"]')
|
meta_path = soup.select('meta[name="csrf-token"]')
|
||||||
csrf_token = meta_path[0].attrs["content"]
|
csrf_token = meta_path[0].attrs["content"]
|
||||||
|
|
||||||
url = f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/login.html"
|
url = f"https://{self.config['CurrentGoGoAnimeURL']}/login.html"
|
||||||
payload = f"email={self.config['GoGoAnime_Username']}&password={self.config['GoGoAnime_Password']}&_csrf={csrf_token}"
|
payload = f"email={self.config['GoGoAnime_Username']}&password={self.config['GoGoAnime_Password']}&_csrf={csrf_token}"
|
||||||
headers = {
|
headers = {
|
||||||
"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",
|
"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",
|
"authority": "gogo-cdn.com",
|
||||||
"referer": f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/",
|
"referer": f"https://{self.config['CurrentGoGoAnimeURL']}/",
|
||||||
"content-type": "application/x-www-form-urlencoded",
|
"content-type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
session.headers = headers
|
session.headers = headers
|
||||||
@ -100,16 +117,30 @@ class gogoanime:
|
|||||||
else:
|
else:
|
||||||
print("ldldl")
|
print("ldldl")
|
||||||
|
|
||||||
|
def user_logged_in_check(
|
||||||
|
self,
|
||||||
|
):
|
||||||
|
page = requests.get(
|
||||||
|
f"https://{self.config['CurrentGoGoAnimeURL']}/one-piece-episode-1",
|
||||||
|
cookies=dict(auth=gogoanime.get_gogoanime_auth_cookie(self)),
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(page.content, "html.parser")
|
||||||
|
loginCheck = soup(text=re.compile("Logout"))
|
||||||
|
if len(loginCheck) == 0:
|
||||||
|
raise Exception(
|
||||||
|
"User is not logged in, make sure account has been activated"
|
||||||
|
)
|
||||||
|
|
||||||
def get_links(self, source=None):
|
def get_links(self, source=None):
|
||||||
if source is not None:
|
if source is not None:
|
||||||
source_ep = f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/{self.name}-episode-"
|
source_ep = f"https://{self.config['CurrentGoGoAnimeURL']}/{self.name}-episode-"
|
||||||
episode_links = [
|
episode_links = [
|
||||||
f"{source_ep}{i}"
|
f"{source_ep}{i}"
|
||||||
for i in range(self.episode_start, self.episode_end + 1)
|
for i in range(self.episode_start, self.episode_end + 1)
|
||||||
]
|
]
|
||||||
episode_links.insert(0, source)
|
episode_links.insert(0, source)
|
||||||
else:
|
else:
|
||||||
source_ep = f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/{self.name}-episode-"
|
source_ep = f"https://{self.config['CurrentGoGoAnimeURL']}/{self.name}-episode-"
|
||||||
episode_links = [
|
episode_links = [
|
||||||
f"{source_ep}{i}"
|
f"{source_ep}{i}"
|
||||||
for i in range(self.episode_start, self.episode_end + 1)
|
for i in range(self.episode_start, self.episode_end + 1)
|
||||||
@ -166,7 +197,7 @@ class gogoanime:
|
|||||||
("authority", "gogo-cdn.com"),
|
("authority", "gogo-cdn.com"),
|
||||||
(
|
(
|
||||||
"referer",
|
"referer",
|
||||||
f"https://gogoanime.{self.config['CurrentGoGoAnimeDomain']}/",
|
f"https://{self.config['CurrentGoGoAnimeURL']}/",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
@ -174,14 +205,52 @@ class gogoanime:
|
|||||||
|
|
||||||
for link in file_list:
|
for link in file_list:
|
||||||
if link is not None:
|
if link is not None:
|
||||||
dl.enqueue_file(
|
try:
|
||||||
link,
|
dl.enqueue_file(
|
||||||
path=f"./{self.title}",
|
link,
|
||||||
)
|
path=f"./{self.title}",
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
files = dl.download()
|
files = dl.download()
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
def get_show_from_bookmark(self):
|
||||||
|
print(f"{IN}Loading shows from bookmarks")
|
||||||
|
bookmarkList = []
|
||||||
|
a = dict(auth=gogoanime.get_gogoanime_auth_cookie(self))
|
||||||
|
resp = requests.get(
|
||||||
|
f"https://{self.config['CurrentGoGoAnimeURL']}/user/bookmark",
|
||||||
|
cookies=a,
|
||||||
|
)
|
||||||
|
soup = BeautifulSoup(resp.text, "html.parser")
|
||||||
|
table = soup.find("div", attrs={"class": "article_bookmark"})
|
||||||
|
splitTableLines = table.text.split("Remove")
|
||||||
|
for rows in splitTableLines:
|
||||||
|
fullRow = " ".join(rows.split())
|
||||||
|
if "Anime name" in fullRow:
|
||||||
|
fullRow = fullRow.replace("Anime name Latest", "")
|
||||||
|
splitRow = fullRow.split("Latest")
|
||||||
|
elif fullRow == "Status":
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
fullRow = fullRow.replace("Status ", "")
|
||||||
|
splitRow = fullRow.split("Latest")
|
||||||
|
animeName = splitRow[0].strip().encode("ascii", "ignore").decode()
|
||||||
|
animeName = re.sub("[^A-Za-z0-9 ]+", "", animeName)
|
||||||
|
animeDownloadName = animeName.replace(" ", "-").lower()
|
||||||
|
episodeNum = splitRow[-1].split()[-1]
|
||||||
|
bookmarkList.append(
|
||||||
|
{
|
||||||
|
"showName": animeName,
|
||||||
|
"latestEpisode": float(episodeNum),
|
||||||
|
"downloadURL": f"https://{self.config['CurrentGoGoAnimeURL']}/{animeDownloadName}-episode-{str(episodeNum)}",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
with open("bookmarkList.json", "w") as f:
|
||||||
|
json.dump(bookmarkList, f)
|
||||||
|
return bookmarkList
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=True)
|
@dataclass(init=True)
|
||||||
class CustomMessage(Exception):
|
class CustomMessage(Exception):
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
"GoGoAnime_Username":"",
|
"GoGoAnime_Username":"",
|
||||||
"GoGoAnime_Password":"",
|
"GoGoAnime_Password":"",
|
||||||
"MaxConcurrentDownloads": 4,
|
"MaxConcurrentDownloads": 4,
|
||||||
"CurrentGoGoAnimeDomain": "film",
|
"CurrentGoGoAnimeURL": "gogoanime3.net",
|
||||||
"OverwriteDownloads": 0
|
"OverwriteDownloads": 0,
|
||||||
|
"CLIQuality":"720",
|
||||||
|
"CLIDownloadLocation": "CLIOutput",
|
||||||
|
"CleanUpFileName": false
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
3.0.0
|
3.2.0
|
1
winRun.bat
Normal file
1
winRun.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
cd C:\Users\Karl.Hudgell\Documents\GoGoDownloader && venv\Scripts\activate && python GoGoDownloaderCLI.py
|
Loading…
x
Reference in New Issue
Block a user