adb-scrollshot 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ name: Checks
2
+ on:
3
+ push:
4
+ pull_request:
5
+ permissions:
6
+ contents: read
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python: ['3.11', '3.14']
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: astral-sh/setup-uv@v6
16
+ with:
17
+ python-version: ${{ matrix.python }}
18
+ - run: uv sync --locked
19
+ - run: uv run ruff check .
20
+ - run: uv run ruff format --check .
21
+ - run: uv run pytest
22
+ - run: uv run adb-scrollshot --help
23
+ - run: uv build
24
+ - run: uv run python scripts/package_release.py
25
+ - uses: actions/upload-artifact@v4
26
+ with:
27
+ name: adb-scrollshot-python-${{ matrix.python }}
28
+ path: dist/
@@ -0,0 +1,45 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ workflow_dispatch:
4
+ permissions:
5
+ contents: read
6
+ concurrency:
7
+ group: pypi-publish
8
+ cancel-in-progress: false
9
+ jobs:
10
+ build:
11
+ if: github.ref == 'refs/heads/main'
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ persist-credentials: false
17
+ - uses: astral-sh/setup-uv@v6
18
+ with:
19
+ python-version: '3.14'
20
+ - run: uv sync --locked
21
+ - run: uv run ruff check .
22
+ - run: uv run ruff format --check .
23
+ - run: uv run pytest
24
+ - run: uv build
25
+ - uses: actions/upload-artifact@v4
26
+ with:
27
+ name: pypi-distributions
28
+ path: |
29
+ dist/*.whl
30
+ dist/*.tar.gz
31
+ if-no-files-found: error
32
+ publish:
33
+ needs: build
34
+ runs-on: ubuntu-latest
35
+ environment:
36
+ name: pypi
37
+ url: https://pypi.org/p/adb-scrollshot
38
+ permissions:
39
+ id-token: write
40
+ steps:
41
+ - uses: actions/download-artifact@v4
42
+ with:
43
+ name: pypi-distributions
44
+ path: dist/
45
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,37 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Tool caches
13
+ .pytest_cache/
14
+ .ruff_cache/
15
+ .coverage
16
+ htmlcov/
17
+ .DS_Store
18
+
19
+ # Local credentials and settings
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+ .idea/
24
+ .vscode/
25
+
26
+ # Captures may contain private phone content; never ship these.
27
+ captures/
28
+ *_frames/
29
+ *_pages/
30
+ *.png
31
+ *.jpg
32
+ *.jpeg
33
+ *.webp
34
+ *.mkv
35
+ *.mp4
36
+ *.mov
37
+ *.zip
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Add public Python functions for lossless screenshot capture, offline stitching,
6
+ and full-resolution page export, with device-free regression tests.
7
+ - Prepare a manually triggered PyPI Trusted Publishing workflow and setup guide.
8
+ - Support importing the library from the checkout alongside the legacy launcher.
9
+ - Package automatic ADB scrolling screenshots as the `adb-scrollshot` command.
10
+ - Separate device access, region selection, matching, and image export modules.
11
+ - Preserve native-resolution PNG output and optional full-resolution page export.
12
+ - Keep the original Python launcher for compatibility.
13
+ - Save captured progress on device-command failure during scrolling.
14
+ - Add locked dependencies, device-free regression tests, CI, and source delivery tooling.
15
+ - Exclude screen captures, recordings, local settings, and caches from Git and releases.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vishal Nagda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.5
2
+ Name: adb-scrollshot
3
+ Version: 0.1.0
4
+ Summary: Lossless Android scrolling screenshots with automatic capture and overlap removal
5
+ Project-URL: Repository, https://github.com/vishalnagda1/adb-scrollshot
6
+ Project-URL: Documentation, https://github.com/vishalnagda1/adb-scrollshot/blob/main/README.md
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: adb,android,image-stitching,screenshot,scrolling
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Topic :: Multimedia :: Graphics :: Capture :: Screen Capture
14
+ Requires-Python: >=3.11
15
+ Requires-Dist: numpy<3,>=2
16
+ Requires-Dist: opencv-python<6,>=4.10
17
+ Description-Content-Type: text/markdown
18
+
19
+ # ADB Scrollshot
20
+
21
+ Capture a sharp, continuous scrolling screenshot from an Android phone. The
22
+ command automatically swipes, captures lossless PNG screenshots, removes
23
+ matching overlap, and stops when the selected content stops moving.
24
+
25
+ The final image keeps the original captured pixel resolution. Optional shorter
26
+ PNG pages make long captures easier to view and share.
27
+
28
+ ## Requirements
29
+
30
+ - Python 3.11 or newer and [uv](https://docs.astral.sh/uv/).
31
+ - Android Platform Tools (`adb`) on your PATH.
32
+ - An unlocked Android phone with USB debugging enabled and this computer authorized.
33
+ - A desktop session for interactive area selection; use `--roi` otherwise.
34
+
35
+ On macOS, install ADB with `brew install android-platform-tools`. On other
36
+ platforms, install Android Platform Tools and add it to PATH. Confirm that
37
+ `adb devices` lists your phone with the state `device`, not `unauthorized`.
38
+ `adb` is a separate system prerequisite and is not included in this package.
39
+
40
+ ## Install from PyPI
41
+
42
+ ```sh
43
+ python -m pip install adb-scrollshot
44
+ adb-scrollshot --select --keep-frames --tile-height 3120 --output captures/high_quality.png
45
+ ```
46
+
47
+ For an isolated command-line installation, use `uv tool install adb-scrollshot`.
48
+ For Python programs, install into your project's virtual environment and import
49
+ `adb_scrollshot`. Python 3.11 or newer is required.
50
+
51
+ ## Quick start
52
+
53
+ From this project directory:
54
+
55
+ ```sh
56
+ uv sync --locked
57
+ uv run adb-scrollshot --select --keep-frames --tile-height 3120 --output captures/high_quality.png
58
+ ```
59
+
60
+ 1. Open the desired page on your phone and return to its top.
61
+ 2. Run the command. Draw a rectangle around **only the scrolling content**,
62
+ excluding fixed toolbars, status bars, navigation bars, and sticky headers.
63
+ 3. Press **Enter**. Leave the phone untouched while it scrolls and captures.
64
+ 4. Find `captures/high_quality.png`, its original screenshots in
65
+ `captures/high_quality_frames/`, and shorter PNGs in `captures/high_quality_pages/`.
66
+
67
+ `scrcpy` is optional; it can mirror the phone while ADB captures directly.
68
+ Without `--output`, the destination is `captures/long_screenshot.png`.
69
+ Use a fresh output name for each run; existing output files may be overwritten.
70
+ Use a fresh name especially with frame/page export to avoid leftover files
71
+ from a previous, longer capture.
72
+
73
+ The original launcher still works:
74
+
75
+ ```sh
76
+ uv run python adb_scrollshot.py --select --keep-frames --tile-height 3120
77
+ ```
78
+
79
+ You can also use `uv run python -m adb_scrollshot --help`.
80
+
81
+ ## Common options
82
+
83
+ Run `uv run adb-scrollshot --help` for all options.
84
+
85
+ | Option | Purpose |
86
+ | --- | --- |
87
+ | `--select` | Draw the scrolling area; this is the default selection mode. |
88
+ | `--roi 0,250,1440,2500` | Specify x, y, width, height in source screenshot pixels. |
89
+ | `--whole-screen` | Use only if the entire screen scrolls without fixed UI. |
90
+ | `--serial DEVICE_ID` | Choose one device when several are connected. |
91
+ | `--keep-frames` | Keep original PNGs for inspection or troubleshooting. |
92
+ | `--tile-height 3120` | Also export native-resolution sections, at most 3120 pixels tall. |
93
+ | `--pause 1.5` | Wait longer for rendering after each swipe. |
94
+ | `--swipe-duration 900` | Make the upward swipe slower, in milliseconds. |
95
+ | `--max-swipes 80` | Raise the safety limit; the default is 45. |
96
+ | `--layout full-first` | Preserve the entire initial screen, including its footer, before appended content. |
97
+
98
+ The default `continuous` layout places the initial fixed header at the top and
99
+ its fixed footer at the end. When the selected region is narrower than the
100
+ screen, appended side margins are copied from the first screenshot; select the
101
+ full content width to avoid repeating unrelated side content.
102
+
103
+ ## Quality and limits
104
+
105
+ View the PNG at **Actual Size / 100%** in your image viewer. Fitting a very tall
106
+ image into a window can make sharp text appear blurry. Some messaging apps
107
+ also shrink images; send the PNG as a file or share the shorter pages.
108
+
109
+ The area-selection preview is reduced for convenience, but the saved content
110
+ is not resized. PNG compression is lossless. Upscaling or recording at a higher
111
+ video bitrate cannot add detail missing from the source screenshots.
112
+
113
+ Overlap matching assumes vertically translating, static content. Animations,
114
+ video, sticky elements inside the selection, repeated patterns, or app layout
115
+ changes can prevent reliable matching. The tool stops and saves a partial PNG
116
+ when it cannot match safely. Page boundaries may cut through a line of text;
117
+ the continuous PNG remains available. Very long captures consume memory.
118
+
119
+ - **Ctrl+C:** saves progress captured so far.
120
+ - **Connection loss during scrolling:** attempts to save progress and exits with code 2.
121
+ - **Exit 0:** normal end, user interruption, or swipe limit reached; read the
122
+ terminal message to see whether the bottom was actually detected.
123
+ - **Exit 1:** setup or output error; **exit 2:** invalid arguments or a partial
124
+ capture caused by unreliable matching, display changes, or connection failure.
125
+
126
+ No image is uploaded by this application. Captures can contain private screen
127
+ content; they and recordings are excluded from Git and release archives.
128
+
129
+ ## Development
130
+
131
+ ```sh
132
+ uv sync --locked
133
+ uv run pytest
134
+ uv run ruff check .
135
+ uv run ruff format --check .
136
+ uv build
137
+ uv run python scripts/package_release.py
138
+ ```
139
+
140
+ The lockfile pins dependencies. CI checks Python 3.11 and 3.14 on Linux and builds
141
+ artifacts. The automated tests use synthetic screenshots and simulated ADB;
142
+ physical-device behavior still needs a manual smoke test.
143
+
144
+ ```text
145
+ src/adb_scrollshot/
146
+ adb.py Device discovery, commands, and lossless screen capture
147
+ cli.py Argument parsing and automatic capture loop
148
+ images.py PNG composition and page export
149
+ matching.py Overlap matching and end detection
150
+ selection.py Interactive region selection and validation
151
+ __main__.py Python module entry point
152
+ tests/ Device-free regression tests
153
+ scripts/ Source-delivery ZIP builder
154
+ docs/ Delivery, installation, and manual validation guide
155
+ .github/workflows/ci.yml
156
+ ```
157
+
158
+ See [docs/DELIVERY.md](docs/DELIVERY.md) for installation from a wheel, release
159
+ contents, a manual acceptance checklist, and Git handoff commands.
160
+
161
+ ## Use as a Python library
162
+
163
+ Install with `python -m pip install adb-scrollshot` and import `adb_scrollshot`.
164
+ You can also install the supplied wheel with
165
+ `python -m pip install ./dist/adb_scrollshot-0.1.0-py3-none-any.whl`, or run these
166
+ examples inside this checkout with `uv run python`.
167
+
168
+ Capture a single lossless screen, without scrolling:
169
+
170
+ ```python
171
+ from adb_scrollshot import capture_screenshot
172
+
173
+ image = capture_screenshot("captures/screen.png")
174
+ print(image.shape) # (height, width, 3), uint8 BGR pixels
175
+ ```
176
+
177
+ Stitch screenshots captured in top-to-bottom order (each must overlap the last):
178
+
179
+ ```python
180
+ import cv2
181
+ from adb_scrollshot import export_pages, stitch_screenshots
182
+
183
+ frames = [cv2.imread(path) for path in ["screen1.png", "screen2.png", "screen3.png"]]
184
+ output = stitch_screenshots(
185
+ frames,
186
+ "captures/stitched.png",
187
+ roi=(0, 250, 1440, 2500), # adapt to your screenshots; exclude fixed UI
188
+ )
189
+ pages = export_pages(cv2.imread(str(output)), output, tile_height=3120)
190
+ ```
191
+
192
+ `stitch_screenshots` accepts an iterable of OpenCV BGR arrays, skips unchanged
193
+ captures, and raises `ValueError` on invalid input or unreliable overlap. It
194
+ writes only after all frames have been accepted. `capture_screenshot` raises
195
+ `RuntimeError` for ADB errors; filesystem errors propagate as `OSError`.
196
+ For automatic scrolling, use the `adb-scrollshot` CLI. ADB is required for live
197
+ capture, but not for stitching existing frames or exporting pages.
198
+
199
+ Public PyPI publishing is configured separately. See
200
+ [docs/PUBLISHING.md](docs/PUBLISHING.md) for the one-time account setup and release procedure.
201
+
202
+ ## License
203
+
204
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,186 @@
1
+ # ADB Scrollshot
2
+
3
+ Capture a sharp, continuous scrolling screenshot from an Android phone. The
4
+ command automatically swipes, captures lossless PNG screenshots, removes
5
+ matching overlap, and stops when the selected content stops moving.
6
+
7
+ The final image keeps the original captured pixel resolution. Optional shorter
8
+ PNG pages make long captures easier to view and share.
9
+
10
+ ## Requirements
11
+
12
+ - Python 3.11 or newer and [uv](https://docs.astral.sh/uv/).
13
+ - Android Platform Tools (`adb`) on your PATH.
14
+ - An unlocked Android phone with USB debugging enabled and this computer authorized.
15
+ - A desktop session for interactive area selection; use `--roi` otherwise.
16
+
17
+ On macOS, install ADB with `brew install android-platform-tools`. On other
18
+ platforms, install Android Platform Tools and add it to PATH. Confirm that
19
+ `adb devices` lists your phone with the state `device`, not `unauthorized`.
20
+ `adb` is a separate system prerequisite and is not included in this package.
21
+
22
+ ## Install from PyPI
23
+
24
+ ```sh
25
+ python -m pip install adb-scrollshot
26
+ adb-scrollshot --select --keep-frames --tile-height 3120 --output captures/high_quality.png
27
+ ```
28
+
29
+ For an isolated command-line installation, use `uv tool install adb-scrollshot`.
30
+ For Python programs, install into your project's virtual environment and import
31
+ `adb_scrollshot`. Python 3.11 or newer is required.
32
+
33
+ ## Quick start
34
+
35
+ From this project directory:
36
+
37
+ ```sh
38
+ uv sync --locked
39
+ uv run adb-scrollshot --select --keep-frames --tile-height 3120 --output captures/high_quality.png
40
+ ```
41
+
42
+ 1. Open the desired page on your phone and return to its top.
43
+ 2. Run the command. Draw a rectangle around **only the scrolling content**,
44
+ excluding fixed toolbars, status bars, navigation bars, and sticky headers.
45
+ 3. Press **Enter**. Leave the phone untouched while it scrolls and captures.
46
+ 4. Find `captures/high_quality.png`, its original screenshots in
47
+ `captures/high_quality_frames/`, and shorter PNGs in `captures/high_quality_pages/`.
48
+
49
+ `scrcpy` is optional; it can mirror the phone while ADB captures directly.
50
+ Without `--output`, the destination is `captures/long_screenshot.png`.
51
+ Use a fresh output name for each run; existing output files may be overwritten.
52
+ Use a fresh name especially with frame/page export to avoid leftover files
53
+ from a previous, longer capture.
54
+
55
+ The original launcher still works:
56
+
57
+ ```sh
58
+ uv run python adb_scrollshot.py --select --keep-frames --tile-height 3120
59
+ ```
60
+
61
+ You can also use `uv run python -m adb_scrollshot --help`.
62
+
63
+ ## Common options
64
+
65
+ Run `uv run adb-scrollshot --help` for all options.
66
+
67
+ | Option | Purpose |
68
+ | --- | --- |
69
+ | `--select` | Draw the scrolling area; this is the default selection mode. |
70
+ | `--roi 0,250,1440,2500` | Specify x, y, width, height in source screenshot pixels. |
71
+ | `--whole-screen` | Use only if the entire screen scrolls without fixed UI. |
72
+ | `--serial DEVICE_ID` | Choose one device when several are connected. |
73
+ | `--keep-frames` | Keep original PNGs for inspection or troubleshooting. |
74
+ | `--tile-height 3120` | Also export native-resolution sections, at most 3120 pixels tall. |
75
+ | `--pause 1.5` | Wait longer for rendering after each swipe. |
76
+ | `--swipe-duration 900` | Make the upward swipe slower, in milliseconds. |
77
+ | `--max-swipes 80` | Raise the safety limit; the default is 45. |
78
+ | `--layout full-first` | Preserve the entire initial screen, including its footer, before appended content. |
79
+
80
+ The default `continuous` layout places the initial fixed header at the top and
81
+ its fixed footer at the end. When the selected region is narrower than the
82
+ screen, appended side margins are copied from the first screenshot; select the
83
+ full content width to avoid repeating unrelated side content.
84
+
85
+ ## Quality and limits
86
+
87
+ View the PNG at **Actual Size / 100%** in your image viewer. Fitting a very tall
88
+ image into a window can make sharp text appear blurry. Some messaging apps
89
+ also shrink images; send the PNG as a file or share the shorter pages.
90
+
91
+ The area-selection preview is reduced for convenience, but the saved content
92
+ is not resized. PNG compression is lossless. Upscaling or recording at a higher
93
+ video bitrate cannot add detail missing from the source screenshots.
94
+
95
+ Overlap matching assumes vertically translating, static content. Animations,
96
+ video, sticky elements inside the selection, repeated patterns, or app layout
97
+ changes can prevent reliable matching. The tool stops and saves a partial PNG
98
+ when it cannot match safely. Page boundaries may cut through a line of text;
99
+ the continuous PNG remains available. Very long captures consume memory.
100
+
101
+ - **Ctrl+C:** saves progress captured so far.
102
+ - **Connection loss during scrolling:** attempts to save progress and exits with code 2.
103
+ - **Exit 0:** normal end, user interruption, or swipe limit reached; read the
104
+ terminal message to see whether the bottom was actually detected.
105
+ - **Exit 1:** setup or output error; **exit 2:** invalid arguments or a partial
106
+ capture caused by unreliable matching, display changes, or connection failure.
107
+
108
+ No image is uploaded by this application. Captures can contain private screen
109
+ content; they and recordings are excluded from Git and release archives.
110
+
111
+ ## Development
112
+
113
+ ```sh
114
+ uv sync --locked
115
+ uv run pytest
116
+ uv run ruff check .
117
+ uv run ruff format --check .
118
+ uv build
119
+ uv run python scripts/package_release.py
120
+ ```
121
+
122
+ The lockfile pins dependencies. CI checks Python 3.11 and 3.14 on Linux and builds
123
+ artifacts. The automated tests use synthetic screenshots and simulated ADB;
124
+ physical-device behavior still needs a manual smoke test.
125
+
126
+ ```text
127
+ src/adb_scrollshot/
128
+ adb.py Device discovery, commands, and lossless screen capture
129
+ cli.py Argument parsing and automatic capture loop
130
+ images.py PNG composition and page export
131
+ matching.py Overlap matching and end detection
132
+ selection.py Interactive region selection and validation
133
+ __main__.py Python module entry point
134
+ tests/ Device-free regression tests
135
+ scripts/ Source-delivery ZIP builder
136
+ docs/ Delivery, installation, and manual validation guide
137
+ .github/workflows/ci.yml
138
+ ```
139
+
140
+ See [docs/DELIVERY.md](docs/DELIVERY.md) for installation from a wheel, release
141
+ contents, a manual acceptance checklist, and Git handoff commands.
142
+
143
+ ## Use as a Python library
144
+
145
+ Install with `python -m pip install adb-scrollshot` and import `adb_scrollshot`.
146
+ You can also install the supplied wheel with
147
+ `python -m pip install ./dist/adb_scrollshot-0.1.0-py3-none-any.whl`, or run these
148
+ examples inside this checkout with `uv run python`.
149
+
150
+ Capture a single lossless screen, without scrolling:
151
+
152
+ ```python
153
+ from adb_scrollshot import capture_screenshot
154
+
155
+ image = capture_screenshot("captures/screen.png")
156
+ print(image.shape) # (height, width, 3), uint8 BGR pixels
157
+ ```
158
+
159
+ Stitch screenshots captured in top-to-bottom order (each must overlap the last):
160
+
161
+ ```python
162
+ import cv2
163
+ from adb_scrollshot import export_pages, stitch_screenshots
164
+
165
+ frames = [cv2.imread(path) for path in ["screen1.png", "screen2.png", "screen3.png"]]
166
+ output = stitch_screenshots(
167
+ frames,
168
+ "captures/stitched.png",
169
+ roi=(0, 250, 1440, 2500), # adapt to your screenshots; exclude fixed UI
170
+ )
171
+ pages = export_pages(cv2.imread(str(output)), output, tile_height=3120)
172
+ ```
173
+
174
+ `stitch_screenshots` accepts an iterable of OpenCV BGR arrays, skips unchanged
175
+ captures, and raises `ValueError` on invalid input or unreliable overlap. It
176
+ writes only after all frames have been accepted. `capture_screenshot` raises
177
+ `RuntimeError` for ADB errors; filesystem errors propagate as `OSError`.
178
+ For automatic scrolling, use the `adb-scrollshot` CLI. ADB is required for live
179
+ capture, but not for stitching existing frames or exporting pages.
180
+
181
+ Public PyPI publishing is configured separately. See
182
+ [docs/PUBLISHING.md](docs/PUBLISHING.md) for the one-time account setup and release procedure.
183
+
184
+ ## License
185
+
186
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python3
2
+ """Compatibility launcher; preferred usage: uv run adb-scrollshot --select."""
3
+
4
+ import importlib.util
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ source = Path(__file__).resolve().parent / "src"
9
+
10
+ if __name__ == "__main__":
11
+ # Keep the original direct-script command working from a source release.
12
+ sys.path.insert(0, str(source))
13
+ from adb_scrollshot.cli import entrypoint
14
+
15
+ raise SystemExit(entrypoint())
16
+ else:
17
+ # A checkout-level launcher must not mask the importable src package.
18
+ spec = importlib.util.spec_from_file_location(
19
+ __name__,
20
+ source / "adb_scrollshot" / "__init__.py",
21
+ submodule_search_locations=[str(source / "adb_scrollshot")],
22
+ )
23
+ assert spec is not None and spec.loader is not None
24
+ package = importlib.util.module_from_spec(spec)
25
+ sys.modules[__name__] = package
26
+ spec.loader.exec_module(package)
@@ -0,0 +1,78 @@
1
+ # Delivery and handoff
2
+
3
+ ## Build
4
+
5
+ From a checkout or extracted source ZIP:
6
+
7
+ ```sh
8
+ uv sync --locked
9
+ uv run ruff check .
10
+ uv run ruff format --check .
11
+ uv run pytest
12
+ uv build
13
+ uv run python scripts/package_release.py
14
+ ```
15
+
16
+ `dist/` contains an installable wheel, a source distribution (`.tar.gz`), a
17
+ source-project ZIP, and its SHA256 checksum. The ZIP includes source, tests,
18
+ CI configuration, documentation, and the lockfile. It excludes screenshots,
19
+ recordings, credentials, virtual environments, caches, and Git history.
20
+
21
+ These are Python deliverables, not a standalone macOS app. Recipients need
22
+ Python, ADB, and a phone with USB debugging authorized. Installing Python
23
+ packages may require network access. The wheel includes the CLI and runtime
24
+ package; tests and development tools are in the source deliverables.
25
+
26
+ ## Install the wheel
27
+
28
+ ```sh
29
+ uv tool install ./adb_scrollshot-0.1.0-py3-none-any.whl
30
+ adb-scrollshot --help
31
+ adb-scrollshot --select --keep-frames --tile-height 3120 --output captures/result.png
32
+ ```
33
+
34
+ Use the wheel's actual location, for example `./dist/adb_scrollshot-0.1.0-py3-none-any.whl`
35
+ when installing from the checkout. If the command is not on PATH after tool
36
+ installation, follow uv's PATH instructions or run `uv tool update-shell` and
37
+ open a new terminal.
38
+
39
+ Alternatively, unzip the source release, change into its directory, and use
40
+ `uv sync --locked` followed by `uv run adb-scrollshot ...`.
41
+
42
+ ## Manual acceptance checklist
43
+
44
+ 1. Confirm `adb devices` reports an authorized device.
45
+ 2. Open a static page at its top and select only the scrolling viewport.
46
+ 3. Capture several screens with `--keep-frames --tile-height 3120`.
47
+ 4. Confirm headers/footers appear as intended, joins have no missing or repeated
48
+ content, and the final PNG width matches the original frame width.
49
+ 5. Inspect text at Actual Size; confirm shorter pages retain the same detail.
50
+ 6. Confirm the terminal reports bottom detection rather than a safety-limit stop.
51
+ 7. On a disposable capture, press Ctrl+C and verify progress is saved.
52
+
53
+ Automated tests verify native-pixel overlap, lossless PNG round trips, device
54
+ selection errors, automatic end detection, and saving progress on interruption,
55
+ connection loss, or failed matching. They do not establish compatibility with
56
+ every app or physical phone. Linux CI is configured but must run on the hosting
57
+ service after push; macOS is the local development environment.
58
+
59
+ ## Git handoff
60
+
61
+ The repository is initialized locally. Review and create your initial commit:
62
+
63
+ ```sh
64
+ git status --short
65
+ git add .gitignore .python-version pyproject.toml uv.lock README.md CHANGELOG.md adb_scrollshot.py src tests scripts docs .github
66
+ git diff --cached --stat
67
+ git commit -m "Package ADB Scrollshot with CLI, tests, and delivery tooling"
68
+ ```
69
+
70
+ After creating a remote repository under your account, add its URL and push:
71
+
72
+ ```sh
73
+ git remote add origin YOUR_REPOSITORY_URL
74
+ git push -u origin main
75
+ ```
76
+
77
+ The project uses the MIT license, with copyright attributed to Vishal Nagda.
78
+ See [PUBLISHING.md](PUBLISHING.md) for public PyPI release instructions.