mirror of
https://github.com/karl0ss/GoGoDownloader.git
synced 2025-05-13 10:18:12 +01:00
first commit
This commit is contained in:
commit
16540ce084
141
.gitignore
vendored
Normal file
141
.gitignore
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Executable files
|
||||
exe/
|
54
README.md
Normal file
54
README.md
Normal file
@ -0,0 +1,54 @@
|
||||
<div align="center">
|
||||
<img
|
||||
style="width: 165px; height: 165px"
|
||||
src="https://i.postimg.cc/VkSMVQrg/ba-logo.png"
|
||||
title="BitAnime"
|
||||
alt="BitAnime"
|
||||
/>
|
||||
<h3>BitAnime</h3>
|
||||
<p>
|
||||
A Python script that allows you to download all of an anime's episodes at once.
|
||||
</p>
|
||||
<a href="https://github.com/sh1nobuu/BitAnime/releases"> <strong>· Download executable version ·</strong></a>
|
||||
</div>
|
||||
|
||||
## About BitAnime
|
||||
|
||||
**BitAnime** is a python script that allows you to download anime in large batches. It can also be used to download anime films. **BitAnime** gets its content from [gogoanime](https://gogoanime.pe/). If you get a **404** error, please look up the correct anime name on [gogoanime](https://gogoanime.pe/). This application can only download **1**-**99** episodes at the time. At the moment, the quality of the episodes that will be downloaded is different for every anime. For **older anime**, the quality will be **360p** to **480p**, for **newer anime** the quality will be **720p** to **1080p**.
|
||||
|
||||
## Installation
|
||||
|
||||
```console
|
||||
git clone https://github.com/sh1nobuu/BitAnime.git
|
||||
```
|
||||
|
||||
## Screenshot
|
||||
|
||||
<div align="center">
|
||||
<img src="https://i.postimg.cc/q76DzZ5y/ba-screenshot.png"
|
||||
title="BitAnime in action" alt="BitAnime Screenshot">
|
||||
</div>
|
||||
|
||||
## Dependencies
|
||||
|
||||
**BitAnime** is highly reliant on the python modules `requests`, `colorama`, `tqdm`, and `BeautifulSoup`.
|
||||
|
||||
```console
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The anime name is separated by "-". You can either type it manually, or go to [gogoanime.pe](https://gogoanime.pe/) and search for the anime you want to download and copy the name from the URL.
|
||||
|
||||
### Examples
|
||||
|
||||
##### One word title
|
||||
|
||||
- https://gogoanime.pe/category/bakemonogatari >> bakemonogatari
|
||||
- https://gogoanime.pe/category/steinsgate >> steinsgate
|
||||
|
||||
##### Multiple word title
|
||||
|
||||
- https://gogoanime.pe/category/shadows-house >> shadows-house
|
||||
- https://gogoanime.pe/category/kono-subarashii-sekai-ni-shukufuku-wo- >> kono-subarashii-sekai-ni-shukufuku-wo-
|
BIN
images/ba-logo.png
Normal file
BIN
images/ba-logo.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 26 KiB |
BIN
images/ba-screenshot.PNG
Normal file
BIN
images/ba-screenshot.PNG
Normal file
Binary file not shown.
After (image error) Size: 21 KiB |
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
68
src/backend.py
Normal file
68
src/backend.py
Normal file
@ -0,0 +1,68 @@
|
||||
import requests
|
||||
import os
|
||||
import shutil
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
folder_path = ""
|
||||
|
||||
|
||||
def get_path(folder):
|
||||
global folder_path
|
||||
folder_path = folder
|
||||
|
||||
|
||||
def get_links(name, episode_number, source=None):
|
||||
if source is not None:
|
||||
source_ep = f"https://gogoanime.pe/{name}-episode-"
|
||||
episode_links = [f"{source_ep}{i}" for i in range(1, int(episode_number) + 1)]
|
||||
episode_links.insert(0, source)
|
||||
else:
|
||||
source_ep = f"https://gogoanime.pe/{name}-episode-"
|
||||
episode_links = [f"{source_ep}{i}" for i in range(1, int(episode_number) + 1)]
|
||||
return episode_links
|
||||
|
||||
|
||||
def get_download_links(episode_links):
|
||||
download_links = []
|
||||
for episode_link in episode_links:
|
||||
episode_link_resp = requests.get(episode_link)
|
||||
soup = BeautifulSoup(episode_link_resp.content, "html.parser")
|
||||
links = soup.find("li", {"class": "dowloads"})
|
||||
for link in links:
|
||||
link = link.get("href")
|
||||
download_links.append(link)
|
||||
return download_links
|
||||
|
||||
|
||||
def get_download_urls(download_links, bool):
|
||||
download_urls = []
|
||||
for link in download_links:
|
||||
link = requests.get(link)
|
||||
soup = BeautifulSoup(link.content, "html.parser")
|
||||
download_link = soup.find_all("div", {"class": "dowload"})
|
||||
download_urls.append(download_link[0].a.get("href"))
|
||||
if bool:
|
||||
conv_download_urls = {
|
||||
episode_title: url for episode_title, url in enumerate(download_urls)
|
||||
}
|
||||
else:
|
||||
conv_download_urls = {
|
||||
episode_title + 1: url
|
||||
for episode_title, url in enumerate(download_urls)
|
||||
}
|
||||
conv_download_urls = sorted(set(conv_download_urls.items()))
|
||||
return conv_download_urls
|
||||
|
||||
|
||||
def download_episodes(url):
|
||||
header = {
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Connection": "close",
|
||||
}
|
||||
url_resp = requests.get(url[1], headers=header, stream=True)
|
||||
file_name = os.path.join(folder_path, f"{url[0]}.mp4")
|
||||
with open(file_name, "wb") as file:
|
||||
shutil.copyfileobj(url_resp.raw, file)
|
114
src/bitanime.py
Normal file
114
src/bitanime.py
Normal file
@ -0,0 +1,114 @@
|
||||
# Dependencies
|
||||
|
||||
import requests
|
||||
import ctypes
|
||||
import os
|
||||
import backend as bd
|
||||
import colorama
|
||||
from tqdm.contrib.concurrent import thread_map
|
||||
from bs4 import BeautifulSoup
|
||||
from colorama import Fore
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
ctypes.windll.kernel32.SetConsoleTitleW("BitAnime")
|
||||
|
||||
|
||||
def bitanime():
|
||||
again = True
|
||||
while again:
|
||||
print(
|
||||
f""" {Fore.LIGHTBLUE_EX}
|
||||
____ _ _ _ _
|
||||
| __ )(_) |_ / \ _ __ (_)_ __ ___ ___
|
||||
| _ \| | __| / _ \ | '_ \| | '_ ` _ \ / _ \\
|
||||
| |_) | | |_ / ___ \| | | | | | | | | | __/
|
||||
|____/|_|\__/_/ \_\_| |_|_|_| |_| |_|\___|
|
||||
{Fore.LIGHTYELLOW_EX}
|
||||
By: sh1nobu
|
||||
Github: https://github.com/sh1nobuu/BitAnime
|
||||
"""
|
||||
)
|
||||
"""
|
||||
Ask user for input and then check if the anime provided exists or if not, loop
|
||||
"""
|
||||
check = True
|
||||
while check:
|
||||
name = input(f"Enter anime name >> ").lower()
|
||||
if "-" in name:
|
||||
title = name.replace("-", " ").title().strip()
|
||||
else:
|
||||
title = name.title().strip()
|
||||
source = f"https://gogoanime.pe/category/{name}"
|
||||
resp = requests.get(source)
|
||||
if resp.status_code == 200:
|
||||
print(f"{Fore.LIGHTGREEN_EX}====================================")
|
||||
check = False
|
||||
else:
|
||||
print(
|
||||
f"{Fore.LIGHTRED_EX}Error 404: Anime not found. Please try again."
|
||||
)
|
||||
check = True
|
||||
"""
|
||||
Get how many episode/s the anime has
|
||||
"""
|
||||
soup = BeautifulSoup(resp.content, "html.parser")
|
||||
episode_number = soup.find("ul", {"id": "episode_page"})
|
||||
episode_number = episode_number.get_text().split("-")[1].strip()
|
||||
"""
|
||||
Print the anime name, episode, and the link of the anime
|
||||
"""
|
||||
print(f"Title: {Fore.LIGHTCYAN_EX}{title}")
|
||||
print(f"Episode/s: {Fore.LIGHTCYAN_EX}{episode_number}")
|
||||
print(f"Link: {Fore.LIGHTCYAN_EX}{source}")
|
||||
print(f"{Fore.LIGHTGREEN_EX}====================================")
|
||||
"""
|
||||
Create a download folder for the anime
|
||||
"""
|
||||
folder = os.path.join(os.getcwd(), title)
|
||||
if not os.path.exists(folder):
|
||||
os.mkdir(folder)
|
||||
"""
|
||||
Check if the anime has episode 0 or not
|
||||
"""
|
||||
source = f"https://gogoanime.pe/{name}"
|
||||
resp = requests.get(source)
|
||||
soup = BeautifulSoup(resp.content, "html.parser")
|
||||
episode_zero = soup.find("h1", {"class": "entry-title"})
|
||||
if episode_zero is None:
|
||||
# Episode 0 does exist
|
||||
episode_links = bd.get_links(name, episode_number, source)
|
||||
download_links = bd.get_download_links(episode_links)
|
||||
download_urls = bd.get_download_urls(download_links, True)
|
||||
print(f"Downloading {Fore.LIGHTCYAN_EX}{len(download_urls)} episode/s")
|
||||
print(f"{Fore.LIGHTGREEN_EX}====================================")
|
||||
print(download_urls)
|
||||
bd.get_path(folder)
|
||||
thread_map(
|
||||
bd.download_episodes, download_urls, ncols=75, total=len(download_urls)
|
||||
)
|
||||
os.startfile(folder)
|
||||
|
||||
else:
|
||||
# Episode 0 does not exist
|
||||
episode_links = bd.get_links(name, episode_number)
|
||||
download_links = bd.get_download_links(episode_links)
|
||||
download_urls = bd.get_download_urls(download_links, False)
|
||||
print(
|
||||
f"Downloading {Fore.LIGHTCYAN_EX}{len(download_urls)}{Fore.RESET} episode/s"
|
||||
)
|
||||
print(f"{Fore.LIGHTGREEN_EX}====================================")
|
||||
bd.get_path(folder)
|
||||
thread_map(
|
||||
bd.download_episodes, download_urls, ncols=75, total=len(download_urls)
|
||||
)
|
||||
os.startfile(folder)
|
||||
use_again = input("Do you want to download other anime? (y|n) >> ").lower()
|
||||
if use_again == "y":
|
||||
again = True
|
||||
os.system("cls")
|
||||
else:
|
||||
again = False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
bitanime()
|
Loading…
x
Reference in New Issue
Block a user