Skip to content

Commit

Permalink
Merge pull request #35 from SenZmaKi/v2.1.8
Browse files Browse the repository at this point in the history
v2.1.8
  • Loading branch information
SenZmaKi authored Apr 11, 2024
2 parents a7c2555 + 8f755f6 commit db353f0
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 99 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.setup-scripts/
.vscode/
.venv/
.venv-termux
tests/
test-downloads/
__pycache__/
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,23 @@ A blazingly fast desktop app for batch downloading anime and auto-downloading ne
<img align="center" src="https://raw.githubusercontent.com/SenZmaKi/Senpwai/master/.github/images/one-piece.png" alt="one-piece-screenshot">

## Installation

- **Cross-platform (Linux, Mac, Windows 10/11)**

Needs [Python 3.11](https://www.python.org/downloads/release/python-3111) installed.

```bash
pip install senpwai
```

- **Windows 10/11**

Download [the setup](https://github.com/SenZmaKi/Senpwai/releases/latest/download/Senpwai-setup.exe) then run it.

- **Android**

Check [Senpcli](https://github.com/SenZmaKi/Senpwai/blob/master/docs/senpcli-guide.md)

- **Other**

[Build from source](#building-from-source).
Expand Down Expand Up @@ -64,7 +71,6 @@ Open a terminal and run the following commands.
git clone https://github.com/SenZmaKi/Senpwai --depth 1 && cd Senpwai && pip install -r dev-requirements.txt && poetry install
```


2. **Build the app into an executable.**

```
Expand All @@ -86,6 +92,7 @@ poetry run senpwai
- Senpwai is open to pull requests, so if you have ideas for improvements, feel free to contribute!

## Sponsors

<p>
<a href="https://github.com/Adam1400"><img src="https://github.com/Adam1400.png" width="80px" alt="Adam1400"/></a>&nbsp;&nbsp;<a href="https://github.com/KeithBoehler"><img src="https://github.com/KeithBoehler.png" width="80px" alt="KeithBoehler" /></a>
</p>
Expand Down
5 changes: 3 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Bug fixes
# General Info

- pahe: Fix issue with alleged episode count exceeding actual number of episodes
- Add termux port, [senpcli](https://github.com/SenZmaKi/Senpwai/blob/master/docs/senpcli-guide.md) in now installable on android using [termux](https://github.com/termux/termux-app)
- Fix Gogoanime by updating domain name to anitaku.so
19 changes: 16 additions & 3 deletions docs/senpcli-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@ The CLI alternative for Senpwai.
Needs [Python 3.11](https://www.python.org/downloads/release/python-3111) installed.

Senpwai ships with the Senpcli pre-installed.

```bash
pip install senpwai
```


- **Windows 10/11**

You can install Senpcli as a completely separate package by downloading and running [the setup](https://github.com/SenZmaKi/Senpwai/releases/latest/download/Senpcli-setup.exe).

- **Android (Using [termux](https://github.com/termux/termux-app))**

```sh
pkg update -y && curl https://raw.githubusercontent.com/SenZmaKi/Senpwai/master/termux/install.sh | bash
```

- **Other**

[Build from source](#building-from-source).
Expand All @@ -36,19 +42,25 @@ senpcli [-h] [-v] [-sd {sub,dub}] [-s {pahe,gogo}] [-se START_EPISODE] [-ee END_

- `-h, --help`: Show help message and exit
- `-v, --version`: Show program's version number and exit
- `-sd {sub,dub}, --sub_or_dub {sub,dub}`: Whether to download the subbed or dubbed version of the anime
- `-c, --config` Show config file contents and location
- `-u, --update` Check for updates
- `-s {pahe,gogo}, --site {pahe,gogo}`: Site to download from
- `-se START_EPISODE, --start_episode START_EPISODE`: Episode to start downloading at
- `-ee END_EPISODE, --end_episode END_EPISODE`: Episode to stop downloading at
- `-q {1080p,720p,480p,360p}, --quality {1080p,720p,480p,360p}`: Quality to download the anime in
- `-sd {sub,dub}, --sub_or_dub {sub,dub}`: Whether to download the subbed or dubbed version of the anime
- `-hls, --hls`: Use HLS mode to download the anime (Gogo only and requires FFmpeg to be installed)
- `-sc, --skip_calculating`: Skip calculating the total download size (Gogo only)
- `-of, --open_folder`: Open the folder containing the downloaded anime once the download finishes
- `-msd MAX_SIMULTANEOUS_DOWNLOADS, --max_simultaneous_downloads MAX_SIMULTANEOUS_DOWNLOADS`: Maximum number of simultaneous downloads

### Settings

Senpcli by default uses your settings from Senpwai. If you don't have Senpwai installed and want to edit the settings you can find the settings.json at "%LOCALAPPDATA%\Senpwai\settings.json" on Windows and "~/.config/Senpwai/settings.json" on Linux/Mac.
Senpcli by default uses your settings from Senpwai. You can find the location of settings.json by running

```sh
senpcli --config
```

## Building from Source

Expand All @@ -61,6 +73,7 @@ Open a terminal and run the following commands.
```
git clone https://github.com/SenZmaKi/Senpwai --depth 1 && cd Senpwai && pip install -r dev-requirements.txt && poetry install
```

2. **Build the tool into an executable.**

```
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "senpwai"
version = "2.1.7"
version = "2.1.8"
description = "A desktop app for tracking and batch downloading anime"
authors = ["SenZmaKi <senzmaki@gmail.com>"]
license = "GPL v3"
Expand Down
4 changes: 2 additions & 2 deletions scripts/setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Senpwai"
#define MyAppVersion "2.1.7"
#define MyAppVersion "2.1.8"
#define MyAppPublisher "AkatsuKi Inc."
#define MyAppURL "https://github.com/SenZmaKi/Senpwai"
#define MyAppExeName "Senpwai.exe"
Expand All @@ -14,7 +14,7 @@
AppId={{B1AC746D-A6F0-44EF-B812.1.8-0DF4571B51}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
VersionInfoVersion=2.1.7.0
VersionInfoVersion=2.1.8.0
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
Expand Down
4 changes: 2 additions & 2 deletions scripts/setup_senpcli.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Senpcli"
#define MyAppVersion "2.1.7"
#define MyAppVersion "2.1.8"
#define MyAppPublisher "AkatsuKi Inc."
#define MyAppURL "https://github.com/SenZmaKi/Senpwai"
#define MyAppExeName "Senpcli.exe"
Expand All @@ -14,7 +14,7 @@
AppId={{7D4A0DD5-EACB-45-81FC-2.1.85FCFF05BB6}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
VersionInfoVersion=2.1.7.0
VersionInfoVersion=2.1.8.0
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
Expand Down
2 changes: 1 addition & 1 deletion senpwai/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3

import ctypes
import sys
Expand Down
1 change: 1 addition & 0 deletions senpwai/scrapers/gogo/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@

KEYS_REGEX = re.compile(rb"(?:container|videocontent)-(\d+)")
ENCRYPTED_DATA_REGEX = re.compile(rb'data-value="(.+?)"')
BASE_URL_REGEX = re.compile(r'(http[s]?://[a-zA-Z0-9\.\-]+)')
29 changes: 21 additions & 8 deletions senpwai/scrapers/gogo/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from random import choice as random_choice
import re
from typing import Callable, cast

from bs4 import BeautifulSoup, ResultSet, Tag
Expand All @@ -7,6 +8,7 @@
CLIENT,
IBYTES_TO_MBS_DIVISOR,
PARSER,
RESOURCE_MOVED_STATUS_CODES,
AnimeMetadata,
DomainNameError,
ProgressFunction,
Expand All @@ -16,6 +18,7 @@
)
from .constants import (
AJAX_SEARCH_URL,
BASE_URL_REGEX,
DUB_EXTENSION,
FULL_SITE_NAME,
AJAX_LOAD_EPS_URL,
Expand All @@ -24,7 +27,7 @@
)

SESSION_COOKIES: RequestsCookieJar | None = None
FIRST_REQUEST = False
FIRST_REQUEST = True


def search(keyword: str, ignore_dub=True) -> list[tuple[str, str]]:
Expand Down Expand Up @@ -131,25 +134,35 @@ def calculate_total_download_size(
return total_size


def get_anime_page_content(anime_page_link: str) -> bytes:
def get_anime_page_content(anime_page_link: str) -> tuple[bytes, str]:
global FIRST_REQUEST
global GOGO_HOME_URL
if FIRST_REQUEST:
try:
FIRST_REQUEST = False
return CLIENT.get(
response = CLIENT.get(
anime_page_link,
exceptions_to_raise=(DomainNameError, type(KeyboardInterrupt)),
).content
exceptions_to_raise=(DomainNameError, KeyboardInterrupt),
)
if response.status_code not in RESOURCE_MOVED_STATUS_CODES:
return response.content, anime_page_link
new_anime_page_link = response.headers.get("Location", GOGO_HOME_URL)
# The url in location seems to be in http instead of https but the http one doesn't work
if new_anime_page_link != GOGO_HOME_URL:
new_anime_page_link = new_anime_page_link.replace("http://", "https://")
match = cast(re.Match[str], BASE_URL_REGEX.search(new_anime_page_link))
GOGO_HOME_URL = match.group(1)
return get_anime_page_content(new_anime_page_link)
except DomainNameError:
global GOGO_HOME_URL
prev_home_url = GOGO_HOME_URL
GOGO_HOME_URL = get_new_home_url_from_readme(FULL_SITE_NAME)
return get_anime_page_content(
anime_page_link.replace(prev_home_url, GOGO_HOME_URL)
)
return CLIENT.get(
response = CLIENT.get(
anime_page_link,
).content
)
return response.content, anime_page_link


def extract_anime_metadata(anime_page_content: bytes) -> AnimeMetadata:
Expand Down
2 changes: 1 addition & 1 deletion senpwai/scrapers/pahe/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def site_request(url: str) -> Response:
response = CLIENT.get(
url,
cookies=COOKIES,
exceptions_to_raise=(DomainNameError, type(KeyboardInterrupt)),
exceptions_to_raise=(DomainNameError, KeyboardInterrupt),
)
else:
response = CLIENT.get(url, cookies=COOKIES)
Expand Down
31 changes: 12 additions & 19 deletions senpwai/scrapers/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ def pass_test(name: str, execution_time: float):
conditional_print(f"Passed: {name} Test\nTook: {round(execution_time, 2)}s\n")


def test_search(
anime_title: str, site: str
) -> list[tuple[str, str]] | list[tuple[str, str, str]]:
def test_search(anime_title: str, site: str) -> list[list[str]]:
test_name = "Search"
test_start(test_name)
run_time_getter = get_run_time_later()
Expand All @@ -85,16 +83,15 @@ def test_search(
test_name = "Parse search results"
test_start(test_name)
c = current_time()
parsed_results: list[tuple[str, str]] | list[tuple[str, str, str]] = []
parsed_results: list[list[str]] = []
if site == PAHE:
parsed_results = [
pahe.extract_anime_title_page_link_and_id(r)
list(pahe.extract_anime_title_page_link_and_id(r))
for r in cast(list[dict[str, str]], results)
]
else:
parsed_results = cast(list[tuple[str, str]], parsed_results)
for title, page_link in cast(list[tuple[str, str]], results):
parsed_results.append((title, page_link))
parsed_results.append([title, page_link])
run_timer = current_time() - c
if not parsed_results:
fail_test(test_name, "List of parsed results", "Empty list", run_timer)
Expand All @@ -109,8 +106,8 @@ def get_run_time_later() -> Callable[[], float]:

def test_check_results_for_anime(
anime_title: str,
results: list[tuple[str, str]] | list[tuple[str, str, str]],
) -> tuple[str, str] | tuple[str, str, str] | None:
results: list[list[str]] | list[list[str]],
) -> list[str] | None:
test_name = f"Matching results to {anime_title}"
test_start(test_name)
run_time = get_run_time_later()
Expand All @@ -130,17 +127,17 @@ def test_check_results_for_anime(


def test_get_metadata(
site: str, target_result: tuple[str, str] | tuple[str, str, str]
site: str, target_result: list[str]
) -> tuple[AnimeMetadata, bytes]:
test_name = "Get Metadata"
test_start(test_name)
run_time = get_run_time_later()
page_content = b""
if site == PAHE:
target_result = cast(tuple[str, str, str], target_result)
target_result = cast(list[str], target_result)
metadata = pahe.get_anime_metadata(target_result[2])
else:
page_content = gogo.get_anime_page_content(target_result[1])
page_content, target_result[1] = gogo.get_anime_page_content(target_result[1])
metadata = gogo.extract_anime_metadata(page_content)
pass_test(test_name, run_time())
return metadata, page_content
Expand Down Expand Up @@ -521,15 +518,12 @@ def arg_value_finder(
self.invalid_usage(f"Expected: {target_args}")


def test_dub_available(
site: str, target_result: tuple[str, str] | tuple[str, str, str]
) -> tuple[bool, str]:
def test_dub_available(site: str, target_result: list[str]) -> tuple[bool, str]:
test_name = "Dub availability checking"
test_start(test_name)
runtime_getter = get_run_time_later()
dub_link = ""
if site == PAHE:
target_result = cast(tuple[str, str, str], target_result)
dub_available = pahe.dub_available(target_result[1], target_result[2])
else:
dub_available, dub_link = gogo.dub_availability_and_link(target_result[0])
Expand All @@ -553,7 +547,7 @@ def run_tests(args: ArgParser):
if args.verbose:
conditional_print(f"Search Results: {results}\n")
target_result = cast(
tuple[str, str] | tuple[str, str, str],
list[str],
test_check_results_for_anime(args.anime_title, results),
)
if args.verbose:
Expand Down Expand Up @@ -593,13 +587,12 @@ def print_metadata(metadata: AnimeMetadata):
)
elif args.site == GOGO and dub_available:
metadata, page_content = test_get_metadata(
args.site, ("", dub_link)
args.site, ["", dub_link]
)
if args.verbose:
conditional_print("Dub metadata")
print_metadata(metadata) # type: ignore
if args.site == PAHE:
target_result = cast(tuple[str, str, str], target_result)
episode_page_links = test_get_episode_page_links(
target_result[2],
target_result[1],
Expand Down
Loading

0 comments on commit db353f0

Please sign in to comment.