fs-ocr 1.0.1__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.
- fs_ocr-1.0.1/.github/workflows/release.yml +214 -0
- fs_ocr-1.0.1/.gitignore +32 -0
- fs_ocr-1.0.1/.pre-commit-config.yaml +20 -0
- fs_ocr-1.0.1/Cargo.lock +1709 -0
- fs_ocr-1.0.1/Cargo.toml +62 -0
- fs_ocr-1.0.1/LICENSE +21 -0
- fs_ocr-1.0.1/PKG-INFO +320 -0
- fs_ocr-1.0.1/README.md +295 -0
- fs_ocr-1.0.1/data/public_templates.bin +0 -0
- fs_ocr-1.0.1/data/text-recognition.rten +0 -0
- fs_ocr-1.0.1/data/type_templates.bin +0 -0
- fs_ocr-1.0.1/docs/CODEMAPS/api.md +128 -0
- fs_ocr-1.0.1/docs/CODEMAPS/architecture.md +131 -0
- fs_ocr-1.0.1/docs/CODEMAPS/dependencies.md +89 -0
- fs_ocr-1.0.1/docs/CODEMAPS/internals.md +150 -0
- fs_ocr-1.0.1/docs/CONTRIBUTING.md +145 -0
- fs_ocr-1.0.1/docs/RELEASING.md +59 -0
- fs_ocr-1.0.1/pyproject.toml +36 -0
- fs_ocr-1.0.1/python/fs_ocr/__init__.py +20 -0
- fs_ocr-1.0.1/src/bin/fs-ocr.rs +175 -0
- fs_ocr-1.0.1/src/config.rs +170 -0
- fs_ocr-1.0.1/src/constants.rs +149 -0
- fs_ocr-1.0.1/src/coordinator/debug_ocr.rs +122 -0
- fs_ocr-1.0.1/src/coordinator/metadata_parse.rs +290 -0
- fs_ocr-1.0.1/src/coordinator/mod.rs +10 -0
- fs_ocr-1.0.1/src/coordinator/pipeline.rs +1024 -0
- fs_ocr-1.0.1/src/coordinator/region_preprocess.rs +857 -0
- fs_ocr-1.0.1/src/coordinator/validation.rs +119 -0
- fs_ocr-1.0.1/src/detector/black_box.rs +420 -0
- fs_ocr-1.0.1/src/detector/geometry.rs +76 -0
- fs_ocr-1.0.1/src/detector/grey_mask/grouping.rs +200 -0
- fs_ocr-1.0.1/src/detector/grey_mask/mod.rs +684 -0
- fs_ocr-1.0.1/src/detector/grey_mask/morphology.rs +266 -0
- fs_ocr-1.0.1/src/detector/mod.rs +9 -0
- fs_ocr-1.0.1/src/enums/game_language.rs +41 -0
- fs_ocr-1.0.1/src/enums/item_category.rs +90 -0
- fs_ocr-1.0.1/src/enums/item_faction.rs +97 -0
- fs_ocr-1.0.1/src/enums/mod.rs +11 -0
- fs_ocr-1.0.1/src/enums/stockpile_type.rs +458 -0
- fs_ocr-1.0.1/src/error.rs +69 -0
- fs_ocr-1.0.1/src/image_utils.rs +53 -0
- fs_ocr-1.0.1/src/lib.rs +349 -0
- fs_ocr-1.0.1/src/models/mod.rs +9 -0
- fs_ocr-1.0.1/src/models/stockpile.rs +219 -0
- fs_ocr-1.0.1/src/models/stockpile_item.rs +186 -0
- fs_ocr-1.0.1/src/models/timing.rs +109 -0
- fs_ocr-1.0.1/src/ocr/basic.rs +241 -0
- fs_ocr-1.0.1/src/ocr/digit_matcher.rs +843 -0
- fs_ocr-1.0.1/src/ocr/engine.rs +70 -0
- fs_ocr-1.0.1/src/ocr/mod.rs +87 -0
- fs_ocr-1.0.1/src/ocr/preprocess.rs +67 -0
- fs_ocr-1.0.1/src/ocr/quantity.rs +32 -0
- fs_ocr-1.0.1/src/ocr/tesseract.rs +154 -0
- fs_ocr-1.0.1/src/template/database.rs +546 -0
- fs_ocr-1.0.1/src/template/label_match.rs +170 -0
- fs_ocr-1.0.1/src/template/matching.rs +488 -0
- fs_ocr-1.0.1/src/template/mod.rs +8 -0
- fs_ocr-1.0.1/src/template/phash.rs +321 -0
- fs_ocr-1.0.1/src/template/public_match.rs +75 -0
- fs_ocr-1.0.1/src/template/type_match.rs +76 -0
- fs_ocr-1.0.1/src/text_utils.rs +54 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
name: Build & publish wheels
|
|
2
|
+
|
|
3
|
+
# Produces the `fs-ocr` PyPI distribution (pure-Rust ocrs/rten backend) plus
|
|
4
|
+
# standalone CLI binaries, all from this one codebase.
|
|
5
|
+
#
|
|
6
|
+
# HDF5 is built from source and statically linked (feature `static-hdf5`) so the
|
|
7
|
+
# wheels carry no external libhdf5. There are no system OCR dependencies: text
|
|
8
|
+
# recognition is fully embedded. Chinese custom names are read via the system
|
|
9
|
+
# `tesseract` CLI when the user has it installed (detected at runtime), so
|
|
10
|
+
# nothing here needs to build or bundle Tesseract.
|
|
11
|
+
#
|
|
12
|
+
# Triggers: tag push `v*` (build + publish) and manual dispatch / workflow PRs
|
|
13
|
+
# (build only, no publish).
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
tags: ["v*"]
|
|
18
|
+
workflow_dispatch:
|
|
19
|
+
pull_request:
|
|
20
|
+
paths: [".github/workflows/release.yml"]
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
|
|
25
|
+
# Friendly OS/arch names and archive extensions for the standalone CLI assets.
|
|
26
|
+
env:
|
|
27
|
+
CLI_BIN: fs-ocr
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
# ===========================================================================
|
|
31
|
+
# WHEELS: fs-ocr (pure-Rust OCR, static HDF5, zero system libs)
|
|
32
|
+
# ===========================================================================
|
|
33
|
+
build-wheels:
|
|
34
|
+
name: wheels · ${{ matrix.platform.os }}-${{ matrix.platform.target }}
|
|
35
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
platform:
|
|
40
|
+
- { runner: ubuntu-latest, target: x86_64, os: linux }
|
|
41
|
+
- { runner: windows-latest, target: x64, os: windows }
|
|
42
|
+
# macOS is aarch64-only. The Intel macos-13 runner is being retired
|
|
43
|
+
# (jobs queue indefinitely), and x86_64 can't be cross-compiled on the
|
|
44
|
+
# arm64 runner because HDF5 is built from source and its CMake probes
|
|
45
|
+
# use try_run(), which can't execute x86_64 binaries on an arm64 host.
|
|
46
|
+
- { runner: macos-14, target: aarch64, os: macos }
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v5
|
|
49
|
+
- uses: actions/setup-python@v6
|
|
50
|
+
with:
|
|
51
|
+
python-version: "3.12"
|
|
52
|
+
|
|
53
|
+
# CMake is preinstalled on the Windows/macOS runners; Linux installs it
|
|
54
|
+
# inside the manylinux container via before-script-linux below.
|
|
55
|
+
- name: Build wheels
|
|
56
|
+
uses: PyO3/maturin-action@v1
|
|
57
|
+
with:
|
|
58
|
+
target: ${{ matrix.platform.target }}
|
|
59
|
+
# pyo3/extension-module is required so the wheel does NOT link libpython
|
|
60
|
+
# (abi3). Passing --features on the CLI overrides pyproject's
|
|
61
|
+
# [tool.maturin] features, so it must be repeated here explicitly.
|
|
62
|
+
args: --release --out dist --features static-hdf5,pyo3/extension-module
|
|
63
|
+
sccache: "true"
|
|
64
|
+
# manylinux_2_28 (AlmaLinux 8) ships a modern toolchain that can build
|
|
65
|
+
# HDF5 from source. before-script-linux runs INSIDE that container.
|
|
66
|
+
manylinux: "2_28"
|
|
67
|
+
before-script-linux: dnf install -y cmake gcc gcc-c++ make
|
|
68
|
+
|
|
69
|
+
# Install the freshly built wheel and import it to catch broken builds
|
|
70
|
+
# (missing symbols, bad abi3 tag, embedded model failures) before release.
|
|
71
|
+
- name: Smoke test wheel
|
|
72
|
+
shell: bash
|
|
73
|
+
run: |
|
|
74
|
+
python -m pip install --upgrade pip
|
|
75
|
+
python -m pip install --find-links dist --no-index fs-ocr
|
|
76
|
+
python -c "import fs_ocr; print('version', fs_ocr.__version__); print('backend', fs_ocr.OCR_BACKEND)"
|
|
77
|
+
|
|
78
|
+
- uses: actions/upload-artifact@v5
|
|
79
|
+
with:
|
|
80
|
+
name: wheels-${{ matrix.platform.os }}-${{ matrix.platform.target }}
|
|
81
|
+
path: dist/*.whl
|
|
82
|
+
|
|
83
|
+
build-sdist:
|
|
84
|
+
name: sdist
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/checkout@v5
|
|
88
|
+
- name: Build sdist
|
|
89
|
+
uses: PyO3/maturin-action@v1
|
|
90
|
+
with:
|
|
91
|
+
command: sdist
|
|
92
|
+
args: --out dist
|
|
93
|
+
- uses: actions/upload-artifact@v5
|
|
94
|
+
with:
|
|
95
|
+
name: sdist
|
|
96
|
+
path: dist/*.tar.gz
|
|
97
|
+
|
|
98
|
+
# ===========================================================================
|
|
99
|
+
# STANDALONE CLI — `fs-ocr` executable, no Python/libpython linkage.
|
|
100
|
+
# Built with `--no-default-features` (drops the `python` feature) so the
|
|
101
|
+
# binary links no libpython and runs on a machine without Python installed.
|
|
102
|
+
# HDF5 is statically linked (`static-hdf5`); zero system OCR libs.
|
|
103
|
+
# Each build is archived (.tar.gz on unix, .zip on Windows) and uploaded as a
|
|
104
|
+
# build artifact; the `release-cli` job attaches them to the GitHub Release.
|
|
105
|
+
# ===========================================================================
|
|
106
|
+
build-cli:
|
|
107
|
+
name: cli · ${{ matrix.platform.os }}-${{ matrix.platform.arch }}
|
|
108
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
109
|
+
strategy:
|
|
110
|
+
fail-fast: false
|
|
111
|
+
matrix:
|
|
112
|
+
platform:
|
|
113
|
+
- { runner: ubuntu-latest, arch: x86_64, os: linux, target: x86_64-unknown-linux-gnu }
|
|
114
|
+
- { runner: windows-latest, arch: x86_64, os: windows, target: x86_64-pc-windows-msvc }
|
|
115
|
+
# macOS is aarch64-only (see build-wheels: x86_64 can't be cross-built
|
|
116
|
+
# because HDF5 is compiled from source with try_run-based CMake probes).
|
|
117
|
+
- { runner: macos-14, arch: aarch64, os: macos, target: aarch64-apple-darwin }
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@v5
|
|
120
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
121
|
+
with:
|
|
122
|
+
targets: ${{ matrix.platform.target }}
|
|
123
|
+
- uses: Swatinem/rust-cache@v2
|
|
124
|
+
with:
|
|
125
|
+
key: cli-${{ matrix.platform.target }}
|
|
126
|
+
|
|
127
|
+
- name: Build CLI (no python feature, static HDF5)
|
|
128
|
+
shell: bash
|
|
129
|
+
run: |
|
|
130
|
+
cargo build --release --locked \
|
|
131
|
+
--no-default-features --features static-hdf5 \
|
|
132
|
+
--bin "$CLI_BIN" --target ${{ matrix.platform.target }}
|
|
133
|
+
|
|
134
|
+
- name: Package
|
|
135
|
+
id: pkg
|
|
136
|
+
shell: bash
|
|
137
|
+
run: |
|
|
138
|
+
name="fs-ocr-${{ matrix.platform.os }}-${{ matrix.platform.arch }}"
|
|
139
|
+
src="target/${{ matrix.platform.target }}/release/$CLI_BIN"
|
|
140
|
+
if [ "${{ matrix.platform.os }}" = "windows" ]; then
|
|
141
|
+
7z a "$name.zip" "$src.exe"
|
|
142
|
+
echo "asset=$name.zip" >> "$GITHUB_OUTPUT"
|
|
143
|
+
else
|
|
144
|
+
tar -C "target/${{ matrix.platform.target }}/release" -czf "$name.tar.gz" "$CLI_BIN"
|
|
145
|
+
echo "asset=$name.tar.gz" >> "$GITHUB_OUTPUT"
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
- uses: actions/upload-artifact@v5
|
|
149
|
+
with:
|
|
150
|
+
name: cli-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
|
|
151
|
+
path: ${{ steps.pkg.outputs.asset }}
|
|
152
|
+
|
|
153
|
+
# Attach every standalone CLI archive to the GitHub Release (tag pushes only).
|
|
154
|
+
release-cli:
|
|
155
|
+
name: release · attach CLI binaries
|
|
156
|
+
needs: [build-cli]
|
|
157
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
158
|
+
runs-on: ubuntu-latest
|
|
159
|
+
permissions:
|
|
160
|
+
contents: write
|
|
161
|
+
steps:
|
|
162
|
+
- uses: actions/download-artifact@v5
|
|
163
|
+
with:
|
|
164
|
+
pattern: "cli-*"
|
|
165
|
+
path: cli
|
|
166
|
+
merge-multiple: true
|
|
167
|
+
- uses: softprops/action-gh-release@v2
|
|
168
|
+
with:
|
|
169
|
+
files: cli/*
|
|
170
|
+
|
|
171
|
+
# ===========================================================================
|
|
172
|
+
# VERSION GUARD (tag pushes only) — the published version comes from
|
|
173
|
+
# Cargo.toml, NOT the tag. The tag is only the trigger. Guard against the
|
|
174
|
+
# silent failure of bumping the tag but forgetting Cargo.toml: strip the
|
|
175
|
+
# leading `v` from the tag and require an exact match.
|
|
176
|
+
# ===========================================================================
|
|
177
|
+
check-version:
|
|
178
|
+
name: check · tag matches Cargo.toml
|
|
179
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
180
|
+
runs-on: ubuntu-latest
|
|
181
|
+
steps:
|
|
182
|
+
- uses: actions/checkout@v5
|
|
183
|
+
- name: Compare tag to Cargo.toml version
|
|
184
|
+
shell: bash
|
|
185
|
+
run: |
|
|
186
|
+
tag_version="${GITHUB_REF_NAME#v}"
|
|
187
|
+
cargo_version="$(grep -m1 '^version = ' Cargo.toml | sed -E 's/^version = "([^"]+)".*/\1/')"
|
|
188
|
+
echo "tag (stripped): $tag_version"
|
|
189
|
+
echo "Cargo.toml: $cargo_version"
|
|
190
|
+
if [ "$tag_version" != "$cargo_version" ]; then
|
|
191
|
+
echo "::error::Tag $GITHUB_REF_NAME (-> $tag_version) does not match Cargo.toml version $cargo_version. Bump Cargo.toml or fix the tag." >&2
|
|
192
|
+
exit 1
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# ===========================================================================
|
|
196
|
+
# PUBLISH (tag pushes only) — trusted publishing via OIDC, no stored tokens.
|
|
197
|
+
# The PyPI project `fs-ocr` must list this repo+workflow as a trusted
|
|
198
|
+
# publisher for the `pypi` environment.
|
|
199
|
+
# ===========================================================================
|
|
200
|
+
publish:
|
|
201
|
+
name: publish · fs-ocr
|
|
202
|
+
needs: [check-version, build-wheels, build-sdist]
|
|
203
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
204
|
+
runs-on: ubuntu-latest
|
|
205
|
+
environment: pypi
|
|
206
|
+
permissions:
|
|
207
|
+
id-token: write
|
|
208
|
+
steps:
|
|
209
|
+
- uses: actions/download-artifact@v5
|
|
210
|
+
with:
|
|
211
|
+
pattern: "{wheels-*,sdist}"
|
|
212
|
+
path: dist
|
|
213
|
+
merge-multiple: true
|
|
214
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
fs_ocr-1.0.1/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Build artifacts
|
|
2
|
+
/target/
|
|
3
|
+
|
|
4
|
+
# Local Cargo config (machine-specific CPU tuning; not for CI/consumers)
|
|
5
|
+
.cargo/
|
|
6
|
+
|
|
7
|
+
# Debug images
|
|
8
|
+
*.png
|
|
9
|
+
|
|
10
|
+
# Python
|
|
11
|
+
__pycache__/
|
|
12
|
+
*.pyc
|
|
13
|
+
*.pyo
|
|
14
|
+
*.egg-info/
|
|
15
|
+
.eggs/
|
|
16
|
+
dist/
|
|
17
|
+
build/
|
|
18
|
+
|
|
19
|
+
# Compiled native extension built by `maturin develop` (platform-specific artifact)
|
|
20
|
+
python/fs_ocr/*.so
|
|
21
|
+
python/fs_ocr/*.pyd
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
|
|
29
|
+
# Environment
|
|
30
|
+
.env
|
|
31
|
+
.venv/
|
|
32
|
+
venv/
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Formatting-only pre-commit hooks. Any committed code is auto-formatted; if a
|
|
2
|
+
# hook reformats a file the commit aborts so you can re-stage the result.
|
|
3
|
+
# One-time setup per clone: pre-commit install
|
|
4
|
+
repos:
|
|
5
|
+
- repo: local
|
|
6
|
+
hooks:
|
|
7
|
+
- id: cargo-fmt
|
|
8
|
+
name: cargo fmt (Rust)
|
|
9
|
+
# cargo fmt formats the whole crate (it ignores per-file paths), which
|
|
10
|
+
# is why the repo is kept fully formatted — no unrelated-file churn.
|
|
11
|
+
entry: cargo fmt
|
|
12
|
+
language: system
|
|
13
|
+
types: [rust]
|
|
14
|
+
pass_filenames: false
|
|
15
|
+
|
|
16
|
+
- id: ruff-format
|
|
17
|
+
name: ruff format (Python)
|
|
18
|
+
entry: ruff format
|
|
19
|
+
language: system
|
|
20
|
+
types_or: [python, pyi]
|