OpenScrub 1.0.3__tar.gz → 1.0.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenScrub
3
- Version: 1.0.3
3
+ Version: 1.0.4
4
4
  Summary: Local, GPU-accelerated redaction for video and screen recordings — blur, black-box, or mosaic faces, names, and any regex-matchable PII, with human review.
5
5
  Project-URL: Homepage, https://github.com/austinmabry/OpenScrub
6
6
  Project-URL: Repository, https://github.com/austinmabry/OpenScrub
@@ -349,18 +349,49 @@ gives you two commands: `openscrub` (the CLI engine) and `openscrub-web`
349
349
  (the web interface). The YuNet face model (~230 KB) downloads
350
350
  automatically on first run.
351
351
 
352
+ ### Fresh Windows 11 PC — complete setup (copy-paste)
353
+
354
+ ```
355
+ winget install -e --id Python.Python.3.12
356
+ ```
357
+ Close and reopen the terminal (so PATH updates), then:
358
+ ```
359
+ pip install OpenScrub
360
+ openscrub-setup
361
+ ```
362
+
363
+ `openscrub-setup` detects what's missing and installs Tesseract and FFmpeg
364
+ for you via winget (asking first; `--yes` to skip prompts, `--check` to
365
+ only report). Prefer manual control? The equivalent commands:
366
+
367
+ ```
368
+ winget install -e --id UB-Mannheim.TesseractOCR
369
+ winget install -e --id Gyan.FFmpeg
370
+ ```
371
+
372
+ ### Fresh Linux (Debian/Ubuntu)
373
+
374
+ ```
375
+ sudo apt install python3-pip
376
+ pip install OpenScrub
377
+ openscrub-setup # offers: sudo apt install tesseract-ocr ffmpeg
378
+ ```
379
+
380
+ Then run `openscrub-web` and open the URL it prints.
381
+
352
382
  Two system tools are **not** pip-installable and must be present for full
353
383
  functionality:
354
384
 
355
385
  1. **Tesseract OCR** — required for every text category (names, SSNs,
356
386
  emails, …). Face and plate detection work without it; text detection
357
387
  does not.
358
- - Windows: installer from https://github.com/UB-Mannheim/tesseract/wiki
388
+ - Windows: `winget install -e --id UB-Mannheim.TesseractOCR`
389
+ (or the installer from https://github.com/UB-Mannheim/tesseract/wiki)
359
390
  - Linux: `sudo apt install tesseract-ocr`
360
391
  2. **ffmpeg** (ffprobe ships with it) — strongly recommended: audio
361
392
  passthrough, H.264 output, and VFR screen-recording normalization all
362
393
  depend on it.
363
- - Windows: `winget install ffmpeg`
394
+ - Windows: `winget install -e --id Gyan.FFmpeg`
364
395
  - Linux: `sudo apt install ffmpeg`
365
396
 
366
397
  Optional extras:
@@ -117,18 +117,49 @@ gives you two commands: `openscrub` (the CLI engine) and `openscrub-web`
117
117
  (the web interface). The YuNet face model (~230 KB) downloads
118
118
  automatically on first run.
119
119
 
120
+ ### Fresh Windows 11 PC — complete setup (copy-paste)
121
+
122
+ ```
123
+ winget install -e --id Python.Python.3.12
124
+ ```
125
+ Close and reopen the terminal (so PATH updates), then:
126
+ ```
127
+ pip install OpenScrub
128
+ openscrub-setup
129
+ ```
130
+
131
+ `openscrub-setup` detects what's missing and installs Tesseract and FFmpeg
132
+ for you via winget (asking first; `--yes` to skip prompts, `--check` to
133
+ only report). Prefer manual control? The equivalent commands:
134
+
135
+ ```
136
+ winget install -e --id UB-Mannheim.TesseractOCR
137
+ winget install -e --id Gyan.FFmpeg
138
+ ```
139
+
140
+ ### Fresh Linux (Debian/Ubuntu)
141
+
142
+ ```
143
+ sudo apt install python3-pip
144
+ pip install OpenScrub
145
+ openscrub-setup # offers: sudo apt install tesseract-ocr ffmpeg
146
+ ```
147
+
148
+ Then run `openscrub-web` and open the URL it prints.
149
+
120
150
  Two system tools are **not** pip-installable and must be present for full
121
151
  functionality:
122
152
 
123
153
  1. **Tesseract OCR** — required for every text category (names, SSNs,
124
154
  emails, …). Face and plate detection work without it; text detection
125
155
  does not.
126
- - Windows: installer from https://github.com/UB-Mannheim/tesseract/wiki
156
+ - Windows: `winget install -e --id UB-Mannheim.TesseractOCR`
157
+ (or the installer from https://github.com/UB-Mannheim/tesseract/wiki)
127
158
  - Linux: `sudo apt install tesseract-ocr`
128
159
  2. **ffmpeg** (ffprobe ships with it) — strongly recommended: audio
129
160
  passthrough, H.264 output, and VFR screen-recording normalization all
130
161
  depend on it.
131
- - Windows: `winget install ffmpeg`
162
+ - Windows: `winget install -e --id Gyan.FFmpeg`
132
163
  - Linux: `sudo apt install ffmpeg`
133
164
 
134
165
  Optional extras:
@@ -34,7 +34,7 @@ from dataclasses import dataclass, asdict
34
34
  import cv2
35
35
  import numpy as np
36
36
 
37
- VERSION = "1.0.3"
37
+ VERSION = "1.0.4"
38
38
 
39
39
  # ----------------------------------------------------------------------------
40
40
  # OCR backends
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ """openscrub-setup — one command to finish a fresh install.
3
+
4
+ `pip install OpenScrub` covers every Python dependency, but two system
5
+ tools live outside pip's world: Tesseract (OCR for all text categories)
6
+ and FFmpeg (audio passthrough, H.264 output, VFR normalization). This
7
+ command detects what's missing and installs it for you — with your
8
+ consent — using winget on Windows or apt on Debian/Ubuntu.
9
+
10
+ openscrub-setup interactive: shows status, asks before installing
11
+ openscrub-setup --check report only, change nothing
12
+ openscrub-setup --yes install anything missing without prompting
13
+ openscrub-setup --with-plates also download the recommended
14
+ license-plate model (SHA-256 verified)
15
+
16
+ Why these aren't bundled into the pip package: they're standalone
17
+ programs, not Python libraries — bundling would exceed PyPI size limits,
18
+ freeze security updates, and (for FFmpeg's H.264 encoder) create a GPL
19
+ licensing conflict with OpenScrub's Apache-2.0 license. Installing them
20
+ at the system level keeps them patched by your package manager.
21
+ """
22
+
23
+ import argparse
24
+ import os
25
+ import shutil
26
+ import subprocess
27
+ import sys
28
+
29
+
30
+ GREEN, YELLOW, RED, END = "\033[92m", "\033[93m", "\033[91m", "\033[0m"
31
+ if os.name == "nt":
32
+ os.system("") # enable ANSI colors on Windows 10+ consoles
33
+
34
+
35
+ def _ok(msg): print(f" {GREEN}[ok]{END} {msg}")
36
+ def _miss(msg): print(f" {RED}[missing]{END} {msg}")
37
+ def _note(msg): print(f" {YELLOW}[note]{END} {msg}")
38
+
39
+
40
+ def find_tesseract():
41
+ """Same search the engine performs: PATH, then known Windows installs."""
42
+ p = shutil.which("tesseract")
43
+ if p:
44
+ return p
45
+ if os.name == "nt":
46
+ try:
47
+ from openscrub import WINDOWS_TESSERACT_PATHS
48
+ except Exception:
49
+ WINDOWS_TESSERACT_PATHS = [
50
+ r"C:\Program Files\Tesseract-OCR\tesseract.exe",
51
+ r"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe",
52
+ os.path.expandvars(
53
+ r"%LOCALAPPDATA%\Programs\Tesseract-OCR\tesseract.exe"),
54
+ ]
55
+ for c in WINDOWS_TESSERACT_PATHS:
56
+ if os.path.exists(c):
57
+ return c
58
+ return None
59
+
60
+
61
+ def find_ffmpeg():
62
+ return shutil.which("ffmpeg")
63
+
64
+
65
+ def _confirm(question, assume_yes):
66
+ if assume_yes:
67
+ return True
68
+ try:
69
+ return input(f"{question} [y/N] ").strip().lower() == "y"
70
+ except EOFError:
71
+ return False
72
+
73
+
74
+ def _run(cmd):
75
+ print(f" $ {' '.join(cmd)}")
76
+ try:
77
+ return subprocess.run(cmd).returncode == 0
78
+ except FileNotFoundError:
79
+ return False
80
+
81
+
82
+ def install_windows(pkg_id, assume_yes):
83
+ if not shutil.which("winget"):
84
+ _note("winget not found (it ships with Windows 10 21H2+ / 11).")
85
+ _note(f"Install manually, or run: winget install -e --id {pkg_id}")
86
+ return False
87
+ if not _confirm(f"Install {pkg_id} via winget now?", assume_yes):
88
+ _note(f"Skipped. Manual command: winget install -e --id {pkg_id}")
89
+ return False
90
+ return _run(["winget", "install", "-e", "--id", pkg_id,
91
+ "--accept-source-agreements", "--accept-package-agreements"])
92
+
93
+
94
+ def install_apt(packages, assume_yes):
95
+ if not shutil.which("apt-get"):
96
+ _note("No apt available — install via your distro's package manager: "
97
+ + " ".join(packages))
98
+ return False
99
+ if not _confirm(f"Run 'sudo apt-get install -y {' '.join(packages)}' now?",
100
+ assume_yes):
101
+ _note("Skipped. Manual command: sudo apt-get install -y "
102
+ + " ".join(packages))
103
+ return False
104
+ return _run(["sudo", "apt-get", "install", "-y"] + packages)
105
+
106
+
107
+ def setup_plates(assume_yes, check_only):
108
+ try:
109
+ import openscrub
110
+ except ImportError:
111
+ _miss("openscrub package not importable — is it installed?")
112
+ return
113
+ models = openscrub.load_plate_registry()
114
+ here = os.path.dirname(os.path.abspath(openscrub.__file__))
115
+ installed = [m["id"] for m in models if os.path.exists(
116
+ os.path.join(here, "models", f"{m['id']}.onnx"))]
117
+ if installed:
118
+ _ok(f"license-plate model installed: {installed[0]}")
119
+ return
120
+ rec = next((m for m in models if m.get("recommended")), None)
121
+ if rec is None:
122
+ _note("no recommended plate model in registry; see PLATES.md")
123
+ return
124
+ _miss(f"license-plate model (optional) — recommended: {rec['label']} "
125
+ f"[{rec.get('license')}]")
126
+ if check_only:
127
+ return
128
+ if not _confirm("Download it now (SHA-256 verified)?", assume_yes):
129
+ _note("Skipped. The web UI's plate panel can download it later.")
130
+ return
131
+ try:
132
+ path = openscrub.download_plate_model(rec)
133
+ _ok(f"plate model saved: {path}")
134
+ except Exception as e:
135
+ _miss(f"plate model download failed: {e}")
136
+
137
+
138
+ def main(argv=None):
139
+ ap = argparse.ArgumentParser(
140
+ prog="openscrub-setup",
141
+ description="Detect and install OpenScrub's system prerequisites "
142
+ "(Tesseract OCR, FFmpeg).")
143
+ ap.add_argument("--check", action="store_true",
144
+ help="report status only; install nothing")
145
+ ap.add_argument("--yes", "-y", action="store_true",
146
+ help="install anything missing without prompting")
147
+ ap.add_argument("--with-plates", action="store_true",
148
+ help="also offer the optional license-plate model")
149
+ args = ap.parse_args(argv)
150
+
151
+ print("OpenScrub setup — system prerequisites")
152
+ print("=" * 46)
153
+
154
+ changed = False
155
+
156
+ # Python-side sanity (pip already handled these; verify imports work)
157
+ try:
158
+ import cv2, flask # noqa: F401
159
+ _ok("python dependencies (opencv, flask, ...)")
160
+ except ImportError as e:
161
+ _miss(f"python dependency broken: {e} — try: pip install --force-reinstall OpenScrub")
162
+
163
+ # Tesseract
164
+ t = find_tesseract()
165
+ if t:
166
+ _ok(f"Tesseract OCR: {t}")
167
+ else:
168
+ _miss("Tesseract OCR — required for ALL text categories "
169
+ "(names, SSNs, addresses, ...)")
170
+ if not args.check:
171
+ if os.name == "nt":
172
+ changed |= install_windows("UB-Mannheim.TesseractOCR", args.yes)
173
+ else:
174
+ changed |= install_apt(["tesseract-ocr"], args.yes)
175
+
176
+ # FFmpeg
177
+ f = find_ffmpeg()
178
+ if f:
179
+ _ok(f"FFmpeg: {f}")
180
+ else:
181
+ _miss("FFmpeg — needed for audio passthrough, H.264 output, and "
182
+ "screen-recording (VFR) normalization")
183
+ if not args.check:
184
+ if os.name == "nt":
185
+ changed |= install_windows("Gyan.FFmpeg", args.yes)
186
+ else:
187
+ changed |= install_apt(["ffmpeg"], args.yes)
188
+
189
+ # Optional: spaCy NER model
190
+ try:
191
+ import spacy
192
+ try:
193
+ spacy.load("en_core_web_sm")
194
+ _ok("spaCy NER model (en_core_web_sm)")
195
+ except OSError:
196
+ _miss("spaCy is installed but its model isn't")
197
+ if not args.check and _confirm(
198
+ "Download en_core_web_sm now?", args.yes):
199
+ _run([sys.executable, "-m", "spacy", "download",
200
+ "en_core_web_sm"])
201
+ except ImportError:
202
+ _note('name detection uses heuristics; for better accuracy: '
203
+ 'pip install "OpenScrub[ner]" then re-run openscrub-setup')
204
+
205
+ # Optional: plate model
206
+ if args.with_plates:
207
+ setup_plates(args.yes, args.check)
208
+
209
+ print("=" * 46)
210
+ if changed and os.name == "nt":
211
+ _note("winget installs update PATH for NEW terminals only:")
212
+ _note("close this window, open a fresh one, then run: openscrub-web")
213
+ else:
214
+ print("Done. Start the web app with: openscrub-web")
215
+ return 0
216
+
217
+
218
+ if __name__ == "__main__":
219
+ sys.exit(main())
@@ -62,6 +62,7 @@ Issues = "https://github.com/austinmabry/OpenScrub/issues"
62
62
  # `openscrub` runs the CLI engine; `openscrub-web` starts the web UI.
63
63
  openscrub = "openscrub:main"
64
64
  openscrub-web = "openscrub_web:main"
65
+ openscrub-setup = "openscrub_setup:main"
65
66
 
66
67
  [tool.hatch.version]
67
68
  # Single source of truth: the VERSION = "x.y.z" line in openscrub.py. A release
@@ -77,12 +78,14 @@ include = [
77
78
  "openscrub.py",
78
79
  "openscrub_web.py",
79
80
  "zones_ui.py",
81
+ "openscrub_setup.py",
80
82
  ]
81
83
 
82
84
  [tool.hatch.build.targets.sdist]
83
85
  include = [
84
86
  "plate_models.json",
85
87
  "openscrub.py",
88
+ "openscrub_setup.py",
86
89
  "openscrub_web.py",
87
90
  "zones_ui.py",
88
91
  "install.py",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes