Merge pull request #63 from JuanjoSalvador/master

Merge-back from master to dev
This commit is contained in:
Juanjo Salvador
2023-02-02 20:40:10 +01:00
committed by GitHub
5 changed files with 198 additions and 10 deletions

70
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '38 17 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

39
.github/workflows/python-publish.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

View File

@@ -30,6 +30,8 @@ class Nyaa:
subcategory = kwargs.get('subcategory', 0)
filters = kwargs.get('filters', 0)
page = kwargs.get('page', 0)
sorting = kwargs.get('sort', 'id') # Sorting by id = sorting by date, this is the default.
order = kwargs.get('order', 'desc')
if user:
user_uri = f"user/{user}"
@@ -37,20 +39,32 @@ class Nyaa:
user_uri = ""
if page > 0:
r = requests.get("{}/{}?f={}&c={}_{}&q={}&p={}".format(
r = requests.get("{}/{}?f={}&c={}_{}&q={}&p={}&s={}&o={}".format(
url, user_uri, filters, category, subcategory, keyword,
page))
page, sorting, order))
else:
r = requests.get("{}/{}?f={}&c={}_{}&q={}".format(
url, user_uri, filters, category, subcategory, keyword))
r = requests.get("{}/{}?f={}&c={}_{}&q={}&s={}&o={}".format(
url, user_uri, filters, category, subcategory, keyword, sorting, order))
r.raise_for_status()
if not user:
uri += "&page=rss"
json_data = utils.parse_nyaa(
request_text=r.text,
limit=None,
site=self.SITE
)
http_response = requests.get(uri)
http_response.raise_for_status()
if user:
json_data = utils.parse_nyaa(
request_text=http_response.text,
limit=None,
site=self.SITE
)
else:
json_data = utils.parse_nyaa_rss(
request_text=http_response.text,
limit=None,
site=self.SITE
)
return torrent.json_to_class(json_data)

View File

@@ -1,4 +1,7 @@
import urllib
from enum import Enum
from urllib.parse import urlencode
from lxml import etree
@@ -80,6 +83,48 @@ def nyaa_categories(b):
return category_name
def parse_nyaa_rss(request_text, limit, site):
"""
Extracts torrent information from a given rss response.
"""
root = etree.fromstring(request_text)
torrents = []
for item in root.xpath("channel/item")[:limit]:
# Decide category.
if site in [TorrentSite.NYAASI, TorrentSite.NYAANET]:
category = item.findtext("nyaa:categoryId", namespaces=item.nsmap)
elif site in [TorrentSite.SUKEBEINYAASI, TorrentSite.SUKEBEINYAANET]:
category = item.findtext("nyaa:categoryId", namespaces=item.nsmap)
else:
raise ValueError("Unknown TorrentSite received!")
try:
is_remake = item.findtext("nyaa:remake", namespaces=item.nsmap) == "Yes"
is_trusted = item.findtext("nyaa:trusted", namespaces=item.nsmap) == "Yes"
item_type = "remake" if is_remake else "trusted" if is_trusted else "default"
torrent = {
'id': item.findtext("guid").split("/")[-1],
'category': category,
'url': item.findtext("guid"),
'name': item.findtext("title"),
'download_url': item.findtext("link"),
'magnet': magnet_builder(item.findtext("nyaa:infoHash", namespaces=item.nsmap), item.findtext("title")),
'size': item.findtext("nyaa:size", namespaces=item.nsmap),
'date': item.findtext("pubDate"),
'seeders': item.findtext("nyaa:seeders", namespaces=item.nsmap),
'leechers': item.findtext("nyaa:leechers", namespaces=item.nsmap),
'completed_downloads': None,
'type': item_type
}
torrents.append(torrent)
except IndexError:
pass
return torrents
def parse_nyaa(request_text, limit, site):
parser = etree.HTMLParser()
tree = etree.fromstring(request_text, parser)
@@ -230,6 +275,25 @@ def sukebei_categories(b):
return category_name
def magnet_builder(info_hash, title):
"""
Generates a magnet link using the info_hash and title of a given file.
"""
known_trackers = [
"http://nyaa.tracker.wf:7777/announce",
"udp://open.stealth.si:80/announce",
"udp://tracker.opentrackr.org:1337/announce",
"udp://exodus.desync.com:6969/announce",
"udp://tracker.torrent.eu.org:451/announce"
]
magnet_link = f"magnet:?xt=urn:btih:{info_hash}&" + urlencode({"dn": title}, quote_via=urllib.parse.quote)
for tracker in known_trackers:
magnet_link += f"&{urlencode({'tr': tracker})}"
return magnet_link
# Pantsu Utils
def query_builder(q, params):
available_params = ["category", "page", "limit", "userID", "fromID",

View File

@@ -10,6 +10,7 @@ setup(name='nyaapy',
install_requires=[
"requests",
"beautifulsoup4",
"lxml",
],
url='https://github.com/juanjosalvador/nyaapy',
long_description=long_desc,