diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index f04f5ef..561981c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.9, "3.10", 3.11] + python-version: [3.9, "3.10", 3.11, 3.12, 3.13] steps: - uses: actions/checkout@v2 @@ -28,10 +28,10 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install deps run: | - python -m pip install pytest coverage coveralls + python -m pip install -r requirements.dev.txt coveralls - name: Run tests env: GITHUB_TOKEN: ${{ secrets.github_token }} run: | - coverage run --source=torrt setup.py test + pytest --cov=torrt --cov-report=term-missing coveralls --service=github diff --git a/.gitignore b/.gitignore index 450a9f3..0181bcd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ __pycache__ docs/_build/ build/ dist/ +.eggs +.coverage \ No newline at end of file diff --git a/requirements.dev.txt b/requirements.dev.txt new file mode 100644 index 0000000..dd3c677 --- /dev/null +++ b/requirements.dev.txt @@ -0,0 +1,4 @@ +pytest +pytest-cov +pytest-datafixtures +pytest-responsemock>=1.1.0 \ No newline at end of file diff --git a/setup.py b/setup.py index 79ebd6f..332e445 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,6 @@ import io import os import re -import sys from setuptools import setup, find_packages @@ -44,18 +43,12 @@ def get_version(): 'beautifulsoup4', 'torrentool', 'lxml', + 'cloudscraper', ], - setup_requires=[] + (['pytest-runner'] if 'test' in sys.argv else []) + [], extras_require={ 'telegram': ['python-telegram-bot >=13.10, <14.0.0a0'] }, - test_suite='tests', - tests_require=[ - 'pytest', - 'pytest-datafixtures', - 'pytest-responsemock>=1.1.0', - ], entry_points={ 'console_scripts': ['torrt = torrt.main:process_commands'], diff --git a/tests/test_main.py b/tests/test_main.py index 7fa141e..9df7935 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,7 +1,9 @@ -from os.path import dirname, realpath, join +from os.path import dirname, realpath from torrentool.torrent import Torrent +import cloudscraper + from torrt.base_rpc import BaseRPC from torrt.base_tracker import GenericPublicTracker from torrt.toolbox import bootstrap, TrackerClassesRegistry, NotifierClassesRegistry, RPCClassesRegistry, \ @@ -90,8 +92,11 @@ def load(cls): def save(cls, settings_dict): cls.cfg = settings_dict + scraper = cloudscraper.create_scraper() + monkeypatch.setattr('torrt.utils.create_scraper', lambda: scraper) + def patch_requests(response_contents): - monkeypatch.setattr('torrt.utils.Session.get', lambda self, url, **kwargs: DummyResponse(url, response_contents)) + monkeypatch.setattr(scraper, "get", lambda url, **kwargs: DummyResponse(url, response_contents)) torrent_one_hash = 'c815be93f20bf8b12fed14bee35c14b19b1d1984' torrent_one_data = (datafix_dir / 'torr_one.torrent').read_bytes() diff --git a/torrt/trackers/rutracker.py b/torrt/trackers/rutracker.py index 9e8001e..8b53c8a 100644 --- a/torrt/trackers/rutracker.py +++ b/torrt/trackers/rutracker.py @@ -22,7 +22,8 @@ def get_id_from_link(self, url: str) -> str: def get_login_form_data(self, login: str, password: str) -> dict: """Returns a dictionary with data to be pushed to authorization form.""" - return {'login_username': login, 'login_password': password, 'login': 'pushed', 'redirect': 'index.php'} + # %E2%F5%EE%E4 is Russian "вход" in cp1251 encoding + return {'login_username': login, 'login_password': password, 'login': '%E2%F5%EE%E4'} def before_download(self, url: str): """Used to perform some required actions right before .torrent download.""" diff --git a/torrt/utils.py b/torrt/utils.py index 8a6e6b4..ae27073 100644 --- a/torrt/utils.py +++ b/torrt/utils.py @@ -19,7 +19,8 @@ from typing import Any, Optional, Union, Generator, Tuple, Callable from bs4 import BeautifulSoup -from requests import Response, Session, RequestException +from requests import Response, RequestException +from cloudscraper import create_scraper from torrentool.api import Torrent from torrentool.exceptions import BencodeDecodingError @@ -44,9 +45,6 @@ class HttpClient: timeout: int = 10 - user_agent: str = ( - 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36') - def __init__( self, silence_exceptions: bool = False, @@ -54,11 +52,7 @@ def __init__( json: bool = False, tunnel: bool = True, ): - session = Session() - - session.headers.update({ - 'User-agent': self.user_agent, - }) + session = create_scraper() self.session = session self.silence_exceptions = silence_exceptions, diff --git a/tox.ini b/tox.ini index c449fda..e628299 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,11 @@ # See http://tox.readthedocs.org/en/latest/examples.html for samples. [tox] -envlist = py{39,310,311} +envlist = py{39,310,311,312,313} skip_missing_interpreters = True [testenv] +deps = -r requirements.dev.txt commands = - python setup.py test + pytest {tty:--color=yes} {posargs}