File size: 2,805 Bytes
511f7f8
 
d4b4554
511f7f8
 
 
 
 
4596576
 
 
d4b4554
 
 
511f7f8
 
d4b4554
511f7f8
 
4596576
511f7f8
d4b4554
 
 
 
 
4596576
511f7f8
4596576
 
 
511f7f8
4596576
 
 
 
 
 
 
 
 
 
d4b4554
4596576
 
a801bc2
 
d4b4554
 
 
 
 
 
 
 
 
 
4596576
 
511f7f8
 
4596576
511f7f8
4596576
511f7f8
d4b4554
4596576
a801bc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from pathlib import Path
import json
import py_compile
import sys
from PIL import Image

ROOT = Path(__file__).resolve().parent
REQUIRED = [
    'app.py', 'requirements.txt', 'packages.txt', 'README.md',
    'template.jpg', 'template_lossless.png', 'template.json',
    'marker_config.json', 'template_A4_print.pdf', 'marker_reference.png',
    'samples/sample_phone_perspective.jpg',
    'samples/sample_phone_shadow_rescue.jpg',
    'samples/sample_phone_missing_tl.jpg',
]
errors = []

for filename in REQUIRED:
    if not (ROOT / filename).is_file():
        errors.append(f'Missing: {filename}')

try:
    py_compile.compile(str(ROOT / 'app.py'), doraise=True)
except Exception as error:
    errors.append(f'app.py syntax validation failed: {error}')

for image_name in ('template.jpg', 'template_lossless.png'):
    try:
        image = Image.open(ROOT / image_name)
        if image.size != (3093, 4374):
            errors.append(f'{image_name} size is {image.size}, expected (3093, 4374)')
    except Exception as error:
        errors.append(f'{image_name} cannot be read: {error}')

try:
    template = json.loads((ROOT / 'template.json').read_text(encoding='utf-8'))
    markers = json.loads((ROOT / 'marker_config.json').read_text(encoding='utf-8'))
    if template.get('pageDimensions') != [3093, 4374]:
        errors.append('template.json pageDimensions mismatch')
    if markers.get('pageDimensions') != [3093, 4374]:
        errors.append('marker_config.json pageDimensions mismatch')
    if markers.get('largeMarkerOuterSize') != 144:
        errors.append('V3.1 largeMarkerOuterSize must remain 144')
    if markers.get('strictMarkerMode') is not True:
        errors.append('strictMarkerMode must default to true')
    if 'smallGroupMarkers' in markers or 'smallMarkerOuterSize' in markers:
        errors.append('Small group marker settings must not exist in this variant')
    rescue = markers.get('localRescue') or {}
    if rescue.get('enabled') is not True:
        errors.append('V3.1 localRescue.enabled must be true')
    if int(rescue.get('minimumGlobalCandidates', 0)) < 2:
        errors.append('minimumGlobalCandidates must be at least 2')
    if int(rescue.get('maxRescueCorners', 99)) > 2:
        errors.append('maxRescueCorners must not exceed 2')
    threshold = float(rescue.get('templateMatchThreshold', 0))
    if not 0.35 <= threshold <= 0.65:
        errors.append('templateMatchThreshold outside expected safe range')
except Exception as error:
    errors.append(f'JSON validation failed: {error}')

if errors:
    print('PROJECT VALIDATION FAILED')
    for error in errors:
        print('-', error)
    sys.exit(1)

print('PROJECT VALIDATION PASSED')
print('V3.1 four-large-marker-only template, local-shadow rescue settings and required files are present.')