6 Commits
0.1.1 ... dev

7 changed files with 174 additions and 57 deletions

View File

@@ -1,21 +0,0 @@
[tool.bumpversion]
current_version = "0.1.0"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
replace = "{new_version}"
regex = false
ignore_missing_version = false
ignore_missing_files = false
tag = false
sign_tags = false
tag_name = "v{new_version}"
tag_message = "Bump version: {current_version} → {new_version}"
allow_dirty = false
commit = false
message = "Bump version: {current_version} → {new_version}"
moveable_tags = []
commit_args = ""
setup_hooks = []
pre_commit_hooks = []
post_commit_hooks = []

View File

@@ -25,10 +25,16 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@master
with:
fetch-depth: 0
fetch-tags: true
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Set up Python
run: uv python install
with:
python-version-file: "pyproject.toml"
- name: Set Git identity
run: |
git config user.name "Gitea CI"

View File

@@ -1,6 +1,6 @@
[project]
name = "komsuite-nyaapy"
version = "0.1.0"
version = "0.1.2"
description = "A rewritten hard fork of the original NyaaPy library."
license = "MIT"
readme = "README.md"
@@ -8,6 +8,8 @@ authors = [{ name = "WorldTeacher", email = "coding_contact@pm.me" }]
requires-python = ">=3.13"
dependencies = [
"bencodepy>=0.9.5",
"httpx>=0.28.1",
"httpx-retries>=0.3.2",
"lxml>=5.3.1",
"regex>=2024.11.6",
]
@@ -16,3 +18,25 @@ dependencies = [
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.bumpversion]
current_version = "0.1.2"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
replace = "{new_version}"
regex = false
ignore_missing_version = false
ignore_missing_files = false
tag = true
sign_tags = false
tag_name = "v{new_version}"
tag_message = "Bump version: {current_version} → {new_version}"
allow_dirty = true
commit = true
message = "Bump version: {current_version} → {new_version}"
moveable_tags = []
commit_args = ""
setup_hooks = []
pre_commit_hooks = []
post_commit_hooks = []

View File

@@ -1,4 +1,4 @@
from .modules.anime_site import AnimeTorrentSite
from .modules.anime_site import AnimeTorrentSite, AnimeTorrentSiteAsync
from .modules.torrent import TorrentSite
from .sites.nyaa import Nyaa, SukebeiNyaa
from .modules.torrent import Torrent

View File

@@ -1,4 +1,4 @@
import requests
import httpx
from komsuite_nyaapy.modules import torrent
from komsuite_nyaapy.modules.parser import parse_nyaa, parse_single, parse_nyaa_rss
@@ -8,21 +8,20 @@ class AnimeTorrentSite:
URL = SITE
@classmethod
def last_uploads(self, number_of_results: int):
r = requests.get(self.URL)
def last_uploads(cls, number_of_results: int):
with httpx.Client() as client:
r = client.get(cls.URL)
r.raise_for_status()
# If anything up with nyaa servers let the user know.
r.raise_for_status()
json_data = parse_nyaa(
request_text=r.text, limit=number_of_results, site=self.SITE
)
json_data = parse_nyaa(
request_text=r.text, limit=number_of_results, site=cls.SITE
)
return torrent.json_to_class(json_data)
@classmethod
def search(
self,
cls,
keyword: str,
category: int = 0,
subcategory: int = 0,
@@ -32,10 +31,9 @@ class AnimeTorrentSite:
order: str = "desc",
**kwargs,
):
base_url = self.URL
base_url = cls.URL
user = kwargs.get("user", None)
user_uri = f"user/{user}" if user else ""
if page > 0:
@@ -64,34 +62,134 @@ class AnimeTorrentSite:
if not user:
search_uri += "&page=rss"
http_response = requests.get(search_uri)
http_response.raise_for_status()
if user:
with httpx.Client() as client:
http_response = client.get(search_uri)
http_response.raise_for_status()
if user:
json_data = parse_nyaa(
request_text=http_response.content, limit=None, site=cls.SITE
)
else:
json_data = parse_nyaa_rss(
request_text=http_response.content, limit=None, site=cls.SITE
)
return torrent.json_to_class(json_data)
@classmethod
def get(cls, view_id: int):
with httpx.Client() as client:
r = client.get(f"{cls.URL}/view/{view_id}")
r.raise_for_status()
json_data = parse_single(request_text=r.content, site=cls.SITE)
return torrent.json_to_class(json_data)
@classmethod
def get_from_user(cls, username):
with httpx.Client() as client:
r = client.get(f"{cls.URL}/user/{username}")
r.raise_for_status()
json_data = parse_nyaa(request_text=r.content, limit=None, site=cls.SITE)
return torrent.json_to_class(json_data)
class AnimeTorrentSiteAsync:
SITE = torrent.TorrentSite.NYAASI
URL = SITE
@classmethod
async def last_uploads(cls, number_of_results: int):
async with httpx.AsyncClient() as client:
r = await client.get(cls.URL)
r.raise_for_status()
json_data = parse_nyaa(
request_text=http_response.content, limit=None, site=self.SITE
request_text=r.text, limit=number_of_results, site=cls.SITE
)
return torrent.json_to_class(json_data)
@classmethod
async def search(
cls,
keyword: str,
category: int = 0,
subcategory: int = 0,
filters: int = 0,
page: int = 0,
sorting: str = "id",
order: str = "desc",
**kwargs,
):
base_url = cls.URL
user = kwargs.get("user", None)
user_uri = f"user/{user}" if user else ""
if page > 0:
search_uri = "{}/{}?f={}&c={}_{}&q={}&p={}&s={}&o={}".format(
base_url,
user_uri,
filters,
category,
subcategory,
keyword,
page,
sorting,
order,
)
else:
json_data = parse_nyaa_rss(
request_text=http_response.content, limit=None, site=self.SITE
search_uri = "{}/{}?f={}&c={}_{}&q={}&s={}&o={}".format(
base_url,
user_uri,
filters,
category,
subcategory,
keyword,
sorting,
order,
)
# Convert JSON data to a class object
return torrent.json_to_class(json_data)
if not user:
search_uri += "&page=rss"
@classmethod
def get(self, view_id: int):
r = requests.get(f"{self.URL}/view/{view_id}")
r.raise_for_status()
async with httpx.AsyncClient() as client:
http_response = await client.get(search_uri)
http_response.raise_for_status()
json_data = parse_single(request_text=r.content, site=self.SITE)
if user:
json_data = parse_nyaa(
request_text=http_response.content, limit=None, site=cls.SITE
)
else:
json_data = parse_nyaa_rss(
request_text=http_response.content, limit=None, site=cls.SITE
)
return torrent.json_to_class(json_data)
@classmethod
def get_from_user(self, username):
r = requests.get(f"{self.URL}/user/{username}")
r.raise_for_status()
async def get(cls, view_id: int):
async with httpx.AsyncClient() as client:
r = await client.get(f"{cls.URL}/view/{view_id}")
r.raise_for_status()
json_data = parse_single(request_text=r.content, site=cls.SITE)
return torrent.json_to_class(json_data)
@classmethod
async def get_from_user(cls, username):
async with httpx.AsyncClient() as client:
r = await client.get(f"{cls.URL}/user/{username}")
r.raise_for_status()
json_data = parse_nyaa(request_text=r.content, limit=None, site=cls.SITE)
json_data = parse_nyaa(request_text=r.content, limit=None, site=self.SITE)
return torrent.json_to_class(json_data)

View File

@@ -7,6 +7,7 @@ import regex
from typing import Optional
import loguru
import sys
import requests
log = loguru.logger
log.remove()
@@ -66,10 +67,11 @@ class Torrent:
@property
def get_contents(self):
os.system(f"wget {self.download_url}> /dev/null 2>&1")
with open(f"{self.download_url.split('/')[-1]}", "rb") as f:
data = bencodepy.decode(f.read())
resp = requests.get(self.download_url, timeout=15)
resp.raise_for_status() # raises for HTTP 4xx/5xx
# 2. Decode directly from bytes
data = bencodepy.decode(resp.content)
info = data[b"info"]
filetypes: list[str] = []
@@ -120,7 +122,6 @@ class Torrent:
else:
self.volumes = [0]
# log.debug("Filetypes: {}, Volumes: {}".format(self.filetypes, self.volumes)) #! enable for debug
os.remove(f"{self.download_url.split('/')[-1]}")
class TorrentSite(Enum):

View File

@@ -1,4 +1,4 @@
from komsuite_nyaapy import AnimeTorrentSite, TorrentSite
from komsuite_nyaapy import AnimeTorrentSite, TorrentSite, AnimeTorrentSiteAsync
class SukebeiNyaa(AnimeTorrentSite):
@@ -9,3 +9,12 @@ class SukebeiNyaa(AnimeTorrentSite):
class Nyaa(AnimeTorrentSite):
SITE = TorrentSite.NYAASI
URL = TorrentSite.get_site(SITE)
class SukebiNyaaAsync(AnimeTorrentSiteAsync):
SITE = TorrentSite.SUKEBEINYAASI
URL = TorrentSite.get_site(SITE)
class NyaaAsync(AnimeTorrentSiteAsync):
SITE = TorrentSite.NYAASI
URL = TorrentSite.get_site(SITE)