Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
d29938bcf5
|
|||
|
df256f5be2
|
|||
|
|
126747a77e | ||
|
a6ffbd59f8
|
|||
|
bfaad4de0d
|
|||
|
b5cdabf0f6
|
@@ -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 = []
|
|
||||||
@@ -25,10 +25,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@v5
|
uses: astral-sh/setup-uv@v5
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
run: uv python install
|
run: uv python install
|
||||||
|
with:
|
||||||
|
python-version-file: "pyproject.toml"
|
||||||
|
|
||||||
- name: Set Git identity
|
- name: Set Git identity
|
||||||
run: |
|
run: |
|
||||||
git config user.name "Gitea CI"
|
git config user.name "Gitea CI"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "komsuite-nyaapy"
|
name = "komsuite-nyaapy"
|
||||||
version = "0.1.0"
|
version = "0.1.2"
|
||||||
description = "A rewritten hard fork of the original NyaaPy library."
|
description = "A rewritten hard fork of the original NyaaPy library."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -8,6 +8,8 @@ authors = [{ name = "WorldTeacher", email = "coding_contact@pm.me" }]
|
|||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bencodepy>=0.9.5",
|
"bencodepy>=0.9.5",
|
||||||
|
"httpx>=0.28.1",
|
||||||
|
"httpx-retries>=0.3.2",
|
||||||
"lxml>=5.3.1",
|
"lxml>=5.3.1",
|
||||||
"regex>=2024.11.6",
|
"regex>=2024.11.6",
|
||||||
]
|
]
|
||||||
@@ -16,3 +18,25 @@ dependencies = [
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
build-backend = "hatchling.build"
|
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 = []
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from .modules.anime_site import AnimeTorrentSite
|
from .modules.anime_site import AnimeTorrentSite, AnimeTorrentSiteAsync
|
||||||
from .modules.torrent import TorrentSite
|
from .modules.torrent import TorrentSite
|
||||||
from .sites.nyaa import Nyaa, SukebeiNyaa
|
from .sites.nyaa import Nyaa, SukebeiNyaa
|
||||||
from .modules.torrent import Torrent
|
from .modules.torrent import Torrent
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import requests
|
import httpx
|
||||||
from komsuite_nyaapy.modules import torrent
|
from komsuite_nyaapy.modules import torrent
|
||||||
from komsuite_nyaapy.modules.parser import parse_nyaa, parse_single, parse_nyaa_rss
|
from komsuite_nyaapy.modules.parser import parse_nyaa, parse_single, parse_nyaa_rss
|
||||||
|
|
||||||
@@ -8,21 +8,20 @@ class AnimeTorrentSite:
|
|||||||
URL = SITE
|
URL = SITE
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def last_uploads(self, number_of_results: int):
|
def last_uploads(cls, number_of_results: int):
|
||||||
r = requests.get(self.URL)
|
with httpx.Client() as client:
|
||||||
|
r = client.get(cls.URL)
|
||||||
|
r.raise_for_status()
|
||||||
|
|
||||||
# If anything up with nyaa servers let the user know.
|
json_data = parse_nyaa(
|
||||||
r.raise_for_status()
|
request_text=r.text, limit=number_of_results, site=cls.SITE
|
||||||
|
)
|
||||||
json_data = parse_nyaa(
|
|
||||||
request_text=r.text, limit=number_of_results, site=self.SITE
|
|
||||||
)
|
|
||||||
|
|
||||||
return torrent.json_to_class(json_data)
|
return torrent.json_to_class(json_data)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(
|
def search(
|
||||||
self,
|
cls,
|
||||||
keyword: str,
|
keyword: str,
|
||||||
category: int = 0,
|
category: int = 0,
|
||||||
subcategory: int = 0,
|
subcategory: int = 0,
|
||||||
@@ -32,10 +31,9 @@ class AnimeTorrentSite:
|
|||||||
order: str = "desc",
|
order: str = "desc",
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
base_url = self.URL
|
base_url = cls.URL
|
||||||
|
|
||||||
user = kwargs.get("user", None)
|
user = kwargs.get("user", None)
|
||||||
|
|
||||||
user_uri = f"user/{user}" if user else ""
|
user_uri = f"user/{user}" if user else ""
|
||||||
|
|
||||||
if page > 0:
|
if page > 0:
|
||||||
@@ -64,34 +62,134 @@ class AnimeTorrentSite:
|
|||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
search_uri += "&page=rss"
|
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(
|
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:
|
else:
|
||||||
json_data = parse_nyaa_rss(
|
search_uri = "{}/{}?f={}&c={}_{}&q={}&s={}&o={}".format(
|
||||||
request_text=http_response.content, limit=None, site=self.SITE
|
base_url,
|
||||||
|
user_uri,
|
||||||
|
filters,
|
||||||
|
category,
|
||||||
|
subcategory,
|
||||||
|
keyword,
|
||||||
|
sorting,
|
||||||
|
order,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Convert JSON data to a class object
|
if not user:
|
||||||
return torrent.json_to_class(json_data)
|
search_uri += "&page=rss"
|
||||||
|
|
||||||
@classmethod
|
async with httpx.AsyncClient() as client:
|
||||||
def get(self, view_id: int):
|
http_response = await client.get(search_uri)
|
||||||
r = requests.get(f"{self.URL}/view/{view_id}")
|
http_response.raise_for_status()
|
||||||
r.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)
|
return torrent.json_to_class(json_data)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_from_user(self, username):
|
async def get(cls, view_id: int):
|
||||||
r = requests.get(f"{self.URL}/user/{username}")
|
async with httpx.AsyncClient() as client:
|
||||||
r.raise_for_status()
|
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)
|
return torrent.json_to_class(json_data)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import regex
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
import loguru
|
import loguru
|
||||||
import sys
|
import sys
|
||||||
|
import requests
|
||||||
|
|
||||||
log = loguru.logger
|
log = loguru.logger
|
||||||
log.remove()
|
log.remove()
|
||||||
@@ -66,10 +67,11 @@ class Torrent:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
os.system(f"wget {self.download_url}> /dev/null 2>&1")
|
resp = requests.get(self.download_url, timeout=15)
|
||||||
with open(f"{self.download_url.split('/')[-1]}", "rb") as f:
|
resp.raise_for_status() # raises for HTTP 4xx/5xx
|
||||||
data = bencodepy.decode(f.read())
|
|
||||||
|
|
||||||
|
# 2. Decode directly from bytes
|
||||||
|
data = bencodepy.decode(resp.content)
|
||||||
info = data[b"info"]
|
info = data[b"info"]
|
||||||
filetypes: list[str] = []
|
filetypes: list[str] = []
|
||||||
|
|
||||||
@@ -120,7 +122,6 @@ class Torrent:
|
|||||||
else:
|
else:
|
||||||
self.volumes = [0]
|
self.volumes = [0]
|
||||||
# log.debug("Filetypes: {}, Volumes: {}".format(self.filetypes, self.volumes)) #! enable for debug
|
# log.debug("Filetypes: {}, Volumes: {}".format(self.filetypes, self.volumes)) #! enable for debug
|
||||||
os.remove(f"{self.download_url.split('/')[-1]}")
|
|
||||||
|
|
||||||
|
|
||||||
class TorrentSite(Enum):
|
class TorrentSite(Enum):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from komsuite_nyaapy import AnimeTorrentSite, TorrentSite
|
from komsuite_nyaapy import AnimeTorrentSite, TorrentSite, AnimeTorrentSiteAsync
|
||||||
|
|
||||||
|
|
||||||
class SukebeiNyaa(AnimeTorrentSite):
|
class SukebeiNyaa(AnimeTorrentSite):
|
||||||
@@ -9,3 +9,12 @@ class SukebeiNyaa(AnimeTorrentSite):
|
|||||||
class Nyaa(AnimeTorrentSite):
|
class Nyaa(AnimeTorrentSite):
|
||||||
SITE = TorrentSite.NYAASI
|
SITE = TorrentSite.NYAASI
|
||||||
URL = TorrentSite.get_site(SITE)
|
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)
|
||||||
Reference in New Issue
Block a user