diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 794aa89..5d66383 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,35 +4,38 @@ on: [push, pull_request] jobs: test: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: 'pip' - cache-dependency-path: setup.py + cache-dependency-path: pyproject.toml - name: Cache Playwright browsers - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.cache/ms-playwright/ key: ${{ runner.os }}-browsers - name: Install dependencies run: | - pip install -e '.[test]' + pip install -e . --group dev - name: Install Playwright dependencies run: | python -m playwright install-deps shot-scraper install shot-scraper install -b firefox shot-scraper install -b webkit + - name: Test Playwright startup time + run: | + time python -c "from playwright.sync_api import sync_playwright; p = sync_playwright().start(); b = p.chromium.launch(); b.close(); p.stop(); print('OK')" - name: Run tests run: | - pytest + pytest -vv - name: Check if cog needs to be run run: | cog --check docs/*.md @@ -40,7 +43,7 @@ jobs: run: | tests/run_examples.sh - name: Archive examples - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: examples-${{ matrix.python-version }} path: examples/* diff --git a/.gitignore b/.gitignore index 07558db..cc31c72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .venv +uv.lock __pycache__/ *.py[cod] *$py.class diff --git a/Pipfile b/Pipfile deleted file mode 100644 index c398b0d..0000000 --- a/Pipfile +++ /dev/null @@ -1,11 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] - -[dev-packages] - -[requires] -python_version = "3.10" diff --git a/docs/pdf.md b/docs/pdf.md index 1ee8b35..d0bad45 100644 --- a/docs/pdf.md +++ b/docs/pdf.md @@ -57,7 +57,7 @@ Options: --timeout INTEGER Wait this many milliseconds before failing --media-screen Use screen rather than print styles --landscape Use landscape orientation - --format [Letter|Legal|Tabloid|Ledger|A0|A1|A2|A3|A4|A5|A6] + --format [letter|legal|tabloid|ledger|a0|a1|a2|a3|a4|a5|a6] Which standard paper size to use --width TEXT PDF width including units, e.g. 10cm --height TEXT PDF height including units, e.g. 10cm diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b176cca --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[project] +name = "shot-scraper" +version = "1.8" +description = "A command-line utility for taking automated screenshots of websites" +readme = "README.md" +requires-python = ">=3.10" +license = "Apache-2.0" +authors = [ + { name = "Simon Willison" } +] + +classifiers = [ + "License :: OSI Approved :: Apache Software License", +] + +dependencies = [ + "click", + "PyYAML", + "playwright", + "click-default-group", +] + +[project.urls] +Homepage = "https://shot-scraper.datasette.io/" +Issues = "https://github.com/simonw/shot-scraper/issues" +CI = "https://github.com/simonw/shot-scraper/actions" +Changelog = "https://github.com/simonw/shot-scraper/releases" + +[project.scripts] +shot-scraper = "shot_scraper.cli:cli" + +[dependency-groups] +dev = [ + "pytest", + "cogapp", + "pytest-mock", +] +docs = [ + "furo==2023.9.10", + "sphinx-autobuild", + "sphinx-copybutton", + "myst-parser", + "cogapp", +] + +[build-system] +requires = ["uv_build>=0.9.18,<0.10.0"] +build-backend = "uv_build" + +[tool.uv.build-backend] +module-root = "" diff --git a/setup.py b/setup.py deleted file mode 100644 index 59d6364..0000000 --- a/setup.py +++ /dev/null @@ -1,37 +0,0 @@ -import os -from setuptools import setup - -VERSION = "1.8" - - -def get_long_description(): - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"), - encoding="utf8", - ) as fp: - return fp.read() - - -setup( - name="shot-scraper", - description="A command-line utility for taking automated screenshots of websites", - long_description=get_long_description(), - long_description_content_type="text/markdown", - author="Simon Willison", - url="https://github.com/simonw/shot-scraper", - project_urls={ - "Issues": "https://github.com/simonw/shot-scraper/issues", - "CI": "https://github.com/simonw/shot-scraper/actions", - "Changelog": "https://github.com/simonw/shot-scraper/releases", - }, - license="Apache License, Version 2.0", - version=VERSION, - packages=["shot_scraper"], - entry_points=""" - [console_scripts] - shot-scraper=shot_scraper.cli:cli - """, - install_requires=["click", "PyYAML", "playwright", "click-default-group"], - extras_require={"test": ["pytest", "cogapp", "pytest-mock"]}, - python_requires=">=3.7", -) diff --git a/tests/run_examples.sh b/tests/run_examples.sh index d9123e3..2b56d2d 100755 --- a/tests/run_examples.sh +++ b/tests/run_examples.sh @@ -45,15 +45,15 @@ shot-scraper 'https://www.owlsnearme.com/?place=127871' \ -o examples/owlsnearme-wait.jpg \ --wait-for "!!document.querySelector('section.secondary')" # Accessibility -shot-scraper accessibility https://datasette.io/ \ - > examples/datasette-accessibility.json -shot-scraper accessibility https://simonwillison.net \ - --javascript "document.getElementById('wrapper').style.display='none'" \ - > examples/simonwillison-accessibility-javascript.json -shot-scraper accessibility https://simonwillison.net \ - --javascript "document.getElementById('wrapper').style.display='none'" \ - --output examples/simonwillison-accessibility-javascript-and-dash-output.json -shot-scraper accessibility examples/local.html -o examples/local-accessibility.json +# #shot-scraper accessibility https://datasette.io/ \ +# > examples/datasette-accessibility.json +# shot-scraper accessibility https://simonwillison.net \ +# --javascript "document.getElementById('wrapper').style.display='none'" \ +# > examples/simonwillison-accessibility-javascript.json +# shot-scraper accessibility https://simonwillison.net \ +# --javascript "document.getElementById('wrapper').style.display='none'" \ +# --output examples/simonwillison-accessibility-javascript-and-dash-output.json +# shot-scraper accessibility examples/local.html -o examples/local-accessibility.json # PDF (cd examples && shot-scraper pdf https://datasette.io/tools) shot-scraper pdf https://datasette.io \