diff --git a/.circleci/config.yml b/.circleci/config.yml index 78fb5e1a..0aeb7889 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,18 +24,7 @@ shared: &shared if [ $UPLOAD_COV ]; then codecov fi - jobs: - py37: - <<: *shared - docker: - - image: circleci/python:3.7 - - py38: - <<: *shared - docker: - - image: circleci/python:3.8 - py39: <<: *shared docker: @@ -45,6 +34,11 @@ jobs: <<: *shared docker: - image: circleci/python:3.10 + + py313: + <<: *shared + docker: + - image: circleci/python:3.13 environment: UPLOAD_COV: "true" @@ -52,7 +46,6 @@ workflows: version: 2.1 main: jobs: - - py37 - - py38 - py39 - py310 + - py313 \ No newline at end of file diff --git a/.gitignore b/.gitignore index df01005c..d3d075e3 100644 --- a/.gitignore +++ b/.gitignore @@ -113,6 +113,7 @@ venv/ ENV/ env.bak/ venv.bak/ +.idea # Spyder project settings .spyderproject diff --git a/.readthedocs.yml b/.readthedocs.yml index 1c6ca479..96dfca16 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,8 +4,11 @@ version: 2 sphinx: configuration: docs/conf.py -# Optionally set the version of Python and requirements required to build your docs +build: + os: "ubuntu-22.04" + tools: + python: "3.13" + python: - version: 3.7 install: - requirements: docs/requirements-docs.txt diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..d081036e --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +.PHONY: all install nopyc clean test docs local + +SHELL := /usr/bin/env bash +PYTHON_BIN ?= python +PROJECT_VENV ?= venv + +all: local test + +venv: + $(PYTHON_BIN) -m pip install virtualenv --user + $(PYTHON_BIN) -m virtualenv $(PROJECT_VENV) + +install: venv + @( \ + source $(PROJECT_VENV)/bin/activate; \ + python -m pip install .; \ + ) + +nopyc: + find . -name '*.pyc' | xargs rm -f || true + find . -name __pycache__ | xargs rm -rf || true + +clean: nopyc + rm -rf build dist *.egg-info $(PROJECT_VENV) + +test: install + @( \ + source $(PROJECT_VENV)/bin/activate; \ + python -m pip install -r ext/requirements-dev.txt -r docs/requirements-docs.txt; \ + coverage run -m unittest discover -s tests && coverage report && coverage xml && coverage html; \ + ) + +docs: install + @( \ + source $(PROJECT_VENV)/bin/activate; \ + python -m pip install -r ext/requirements-dev.txt; \ + sphinx-build -M html docs build/docs -n; \ + ) + +local: + @rm -rf *.egg-info dist + @( \ + $(PYTHON_BIN) -m pip install --upgrade pip; \ + $(PYTHON_BIN) -m pip install --upgrade build; \ + $(PYTHON_BIN) -m build; \ + $(PYTHON_BIN) -m pip install dist/*.tar.gz; \ + ) diff --git a/README.md b/README.md index 0917dd13..586d6025 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,11 @@ Pure Python, lightweight, [Pillow](https://github.com/python-pillow/Pillow)-base ![Timing](https://img.shields.io/badge/response%20time-0.2s-success) [![Size](https://img.shields.io/badge/wheel%20size-0.9%20MB-informational)](https://pypi.org/project/amazoncaptcha/) [![Version](https://img.shields.io/pypi/v/amazoncaptcha?color=informational)](https://pypi.org/project/amazoncaptcha/) -[![Python version](https://img.shields.io/badge/python-3.7%2B-informational)](https://pypi.org/project/amazoncaptcha/) +[![Python version](https://img.shields.io/badge/python-3.9%2B-informational)](https://pypi.org/project/amazoncaptcha/) [![Downloads](https://img.shields.io/pypi/dm/amazoncaptcha?color=success)](https://pypi.org/project/amazoncaptcha/) ## Recent News ++ *July 14, 2025*: dropped support for Python 3.7 and 3.8, added support through Python 3.13 and Pillow 11 + *May 5, 2023*: tested and approved compatibility with Pillow 9.5.0 + *January 25, 2022*: tested and approved compatibility with Python 3.10 + *January 25, 2022*: dropped support for Python 3.6 diff --git a/amazoncaptcha/__version__.py b/amazoncaptcha/__version__.py index 2f4ec5a8..23ca6e9c 100644 --- a/amazoncaptcha/__version__.py +++ b/amazoncaptcha/__version__.py @@ -1,7 +1,7 @@ __title__ = 'amazoncaptcha' __description__ = "Pure Python, lightweight, Pillow-based solver for the Amazon text captcha." __url__ = 'https://github.com/a-maliarov/amazoncaptcha' -__version__ = '0.5.11' +__version__ = '0.5.12' __author__ = 'Anatolii Maliarov' __author_email__ = 'tly.mov@gmail.com' __license__ = 'MIT' diff --git a/amazoncaptcha/devtools.py b/amazoncaptcha/devtools.py index 315c529e..2311900a 100644 --- a/amazoncaptcha/devtools.py +++ b/amazoncaptcha/devtools.py @@ -6,6 +6,7 @@ This module contains the set of amazoncaptcha's devtools. """ +from bs4 import BeautifulSoup from .solver import AmazonCaptcha from .exceptions import NotFolderError @@ -51,14 +52,14 @@ def _extract_captcha_link(self, captcha_page): """Extracts a captcha link from an html page. Args: - captcha_page (str): A page's html in string format. + captcha_page (Response): A page's html in string format. Returns: str: Captcha link. """ - return captcha_page.text.split('')[0] + return BeautifulSoup(captcha_page.text).select("img")[0]["src"] def _extract_captcha_id(self, captcha_link): """ diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cbb..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py index e211a139..a1e84100 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -63,13 +63,6 @@ # The full version, including alpha/beta/rc tags. release = 'v0.4.7' -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. @@ -89,7 +82,6 @@ # a list of builtin themes. html_theme = "sphinx_rtd_theme" -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/installation.rst b/docs/installation.rst index b0a8f9f0..b3790966 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -11,13 +11,15 @@ Python Support AmazonCaptcha supports the versions of Python according to the table below. -+-------------------------+--------+-------+-------+-------+-------+-------+ -| **Python** |**3.10**|**3.9**|**3.8**|**3.7**|**3.6**|**3.5**| -+-------------------------+--------+-------+-------+-------+-------+-------+ -| AmazonCaptcha >= 0.5.3 | Yes | Yes | Yes | Yes | No | No | -+-------------------------+--------+-------+-------+-------+-------+-------+ -| AmazonCaptcha <= 0.5.2 | Yes | Yes | Yes | Yes | Yes | No | -+-------------------------+--------+-------+-------+-------+-------+-------+ ++-------------------------+--------+--------+--------+--------+-------+-------+-------+-------+-------+ +| **Python** |**3.13**|**3.12**|**3.11**|**3.10**|**3.9**|**3.8**|**3.7**|**3.6**|**3.5**| ++-------------------------+--------+--------+--------+--------+-------+-------+-------+-------+-------+ +| AmazonCaptcha >= 0.5.12 | Yes | Yes | Yes | Yes | Yes | No | No | No | No | ++-------------------------+--------+--------+--------+--------+-------+-------+-------+-------+-------+ +| AmazonCaptcha >= 0.5.3 | No | No | No | Yes | Yes | Yes | Yes | No | No | ++-------------------------+--------+--------+--------+--------+-------+-------+-------+-------+-------+ +| AmazonCaptcha <= 0.5.2 | No | No | No | Yes | Yes | Yes | Yes | Yes | No | ++-------------------------+--------+--------+--------+--------+-------+-------+-------+-------+-------+ Basic Installation ------------------ diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 922152e9..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt index d6e1198b..2543925c 100644 --- a/docs/requirements-docs.txt +++ b/docs/requirements-docs.txt @@ -1 +1,2 @@ --e . +Sphinx +sphinx-rtd-theme \ No newline at end of file diff --git a/ext/requirements-dev.txt b/ext/requirements-dev.txt index e1c2b878..eaa7f7cb 100644 --- a/ext/requirements-dev.txt +++ b/ext/requirements-dev.txt @@ -1,6 +1,7 @@ -pillow ~= 9.5.0 -requests ~= 2.30.0 +pillow ~= 11.3 +requests ~= 2.30 coverage >= 6.3.1 codecov >= 2.1.12 -webdriver_manager ~= 3.8.6 -selenium ~= 4.9.1 +webdriver_manager ~= 4.0 +selenium >= 4.34 +beautifulsoup4 >= 4.13 \ No newline at end of file diff --git a/setup.py b/setup.py index 8dbcc8fd..691daac9 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import setuptools import os -#-------------------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------------------- here = os.path.abspath(os.path.dirname(__file__)) @@ -11,6 +11,7 @@ file_data = [i.replace('\n', '').replace('\'', '').split(' = ') for i in f.readlines()] about = {k: v for k, v in file_data} + def readme(logo_end_line=14): """Extracts the logo from README file before pushing to PyPi.""" @@ -19,12 +20,14 @@ def readme(logo_end_line=14): return long_description +license = "MIT" + classifiers = [ - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Development Status :: 5 - Production/Stable", "Natural Language :: English", @@ -33,12 +36,14 @@ def readme(logo_end_line=14): "Intended Audience :: Information Technology", ] +python_requires = ">=3.9" + requires = [ - "pillow >= 9.0.1,< 9.6.0", - "requests >= 2.27.1,< 2.31.0" + "pillow >= 9.0.1", + "requests >= 2.27.1" ] -#-------------------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------------------- setuptools.setup( name=about['__title__'], @@ -61,4 +66,4 @@ def readme(logo_end_line=14): }, ) -#-------------------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------------------- diff --git a/tests/test_main.py b/tests/test_main.py index 7838c8c0..c70939e0 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- +from selenium.webdriver.chrome.service import Service from amazoncaptcha import AmazonCaptcha, AmazonCaptchaCollector, ContentTypeError, NotFolderError, __version__ from webdriver_manager.chrome import ChromeDriverManager from selenium import webdriver import unittest -import sys import os #-------------------------------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ def test_fromdriver(self): options = webdriver.ChromeOptions() options.add_argument('no-sandbox') options.add_argument('headless') - driver = webdriver.Chrome(ChromeDriverManager().install(), options=options) + driver = webdriver.Chrome(service=Service(executable_path=ChromeDriverManager().install()), options=options) solutions = list() for i in range(5):