photo-stack-finder 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl

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.
Files changed (68) hide show
  1. orchestrator/__init__.py +2 -2
  2. orchestrator/app.py +6 -11
  3. orchestrator/build_pipeline.py +19 -21
  4. orchestrator/orchestrator_runner.py +11 -8
  5. orchestrator/pipeline_builder.py +126 -126
  6. orchestrator/pipeline_orchestrator.py +604 -604
  7. orchestrator/review_persistence.py +162 -162
  8. orchestrator/static/orchestrator.css +76 -76
  9. orchestrator/static/orchestrator.html +11 -5
  10. orchestrator/static/orchestrator.js +3 -1
  11. overlap_metrics/__init__.py +1 -1
  12. overlap_metrics/config.py +135 -135
  13. overlap_metrics/core.py +284 -284
  14. overlap_metrics/estimators.py +292 -292
  15. overlap_metrics/metrics.py +307 -307
  16. overlap_metrics/registry.py +99 -99
  17. overlap_metrics/utils.py +104 -104
  18. photo_compare/__init__.py +1 -1
  19. photo_compare/base.py +285 -285
  20. photo_compare/config.py +225 -225
  21. photo_compare/distance.py +15 -15
  22. photo_compare/feature_methods.py +173 -173
  23. photo_compare/file_hash.py +29 -29
  24. photo_compare/hash_methods.py +99 -99
  25. photo_compare/histogram_methods.py +118 -118
  26. photo_compare/pixel_methods.py +58 -58
  27. photo_compare/structural_methods.py +104 -104
  28. photo_compare/types.py +28 -28
  29. {photo_stack_finder-0.1.7.dist-info → photo_stack_finder-0.1.8.dist-info}/METADATA +21 -22
  30. photo_stack_finder-0.1.8.dist-info/RECORD +75 -0
  31. scripts/orchestrate.py +12 -10
  32. utils/__init__.py +4 -3
  33. utils/base_pipeline_stage.py +171 -171
  34. utils/base_ports.py +176 -176
  35. utils/benchmark_utils.py +823 -823
  36. utils/channel.py +74 -74
  37. utils/comparison_gates.py +40 -21
  38. utils/compute_benchmarks.py +355 -355
  39. utils/compute_identical.py +94 -24
  40. utils/compute_indices.py +235 -235
  41. utils/compute_perceptual_hash.py +127 -127
  42. utils/compute_perceptual_match.py +240 -240
  43. utils/compute_sha_bins.py +64 -20
  44. utils/compute_template_similarity.py +1 -1
  45. utils/compute_versions.py +483 -483
  46. utils/config.py +8 -5
  47. utils/data_io.py +83 -83
  48. utils/graph_context.py +44 -44
  49. utils/logger.py +2 -2
  50. utils/models.py +2 -2
  51. utils/photo_file.py +90 -91
  52. utils/pipeline_graph.py +334 -334
  53. utils/pipeline_stage.py +408 -408
  54. utils/plot_helpers.py +123 -123
  55. utils/ports.py +136 -136
  56. utils/progress.py +415 -415
  57. utils/report_builder.py +139 -139
  58. utils/review_types.py +55 -55
  59. utils/review_utils.py +10 -19
  60. utils/sequence.py +10 -8
  61. utils/sequence_clustering.py +1 -1
  62. utils/template.py +57 -57
  63. utils/template_parsing.py +71 -0
  64. photo_stack_finder-0.1.7.dist-info/RECORD +0 -74
  65. {photo_stack_finder-0.1.7.dist-info → photo_stack_finder-0.1.8.dist-info}/WHEEL +0 -0
  66. {photo_stack_finder-0.1.7.dist-info → photo_stack_finder-0.1.8.dist-info}/entry_points.txt +0 -0
  67. {photo_stack_finder-0.1.7.dist-info → photo_stack_finder-0.1.8.dist-info}/licenses/LICENSE +0 -0
  68. {photo_stack_finder-0.1.7.dist-info → photo_stack_finder-0.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,71 @@
1
+ """Template parsing utilities for filename pattern extraction.
2
+
3
+ This module provides utilities for extracting template patterns from filenames
4
+ by replacing digit sequences with placeholders. This enables grouping files
5
+ that follow the same naming pattern (e.g., IMG_0001.jpg, IMG_0002.jpg).
6
+
7
+ The template extraction happens early in the pipeline (during SHA binning) and
8
+ is cached on PhotoFile objects for use in later stages.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import re
14
+
15
+ # Type alias for digit sequence indices extracted from filenames
16
+ # Example: "IMG_1234_5678.jpg" → ("1234", "5678")
17
+ INDEX_T = tuple[str, ...]
18
+
19
+
20
+ def extract_template(text: str) -> tuple[str, INDEX_T]:
21
+ """Extract template and digit groups from text.
22
+
23
+ Replaces all digit sequences with placeholders {P0}, {P1}, etc.
24
+ This enables grouping files with similar naming patterns.
25
+
26
+ The function scans the input text for consecutive digit sequences and
27
+ replaces each with a placeholder of the form {P0}, {P1}, etc. The
28
+ original digit sequences are returned as a tuple for later reconstruction.
29
+
30
+ Args:
31
+ text: Text to parse (typically filename stem without extension)
32
+
33
+ Returns:
34
+ Tuple of (template_string, digit_sequences) where:
35
+ - template_string: Text with digit sequences replaced by {P0}, {P1}, etc.
36
+ - digit_sequences: Tuple of original digit strings in order of appearance
37
+
38
+ Examples:
39
+ >>> template, digits = extract_template("IMG_1234")
40
+ >>> print(template)
41
+ IMG_{P0}
42
+ >>> print(digits)
43
+ ('1234',)
44
+
45
+ >>> template, digits = extract_template("2023_05_IMG_1234_5678")
46
+ >>> print(template)
47
+ {P0}_{P1}_IMG_{P2}_{P3}
48
+ >>> print(digits)
49
+ ('2023', '05', '1234', '5678')
50
+
51
+ >>> template, digits = extract_template("no_digits_here")
52
+ >>> print(template)
53
+ no_digits_here
54
+ >>> print(digits)
55
+ ()
56
+
57
+ >>> template, digits = extract_template("12345")
58
+ >>> print(template)
59
+ {P0}
60
+ >>> print(digits)
61
+ ('12345',)
62
+ """
63
+ digits: list[str] = []
64
+
65
+ def repl(m: re.Match[str]) -> str:
66
+ """Replace matched digit sequence with placeholder {PN} and capture digits."""
67
+ digits.append(m.group(0))
68
+ return f"{{P{len(digits) - 1}}}"
69
+
70
+ template: str = re.sub(r"\d+", repl, text)
71
+ return template, tuple(digits)
@@ -1,74 +0,0 @@
1
- orchestrator/__init__.py,sha256=DtoeLEhNbKfBp-JuFx-4DUFrLFrO8HUV0lSov1sYfxE,1315
2
- orchestrator/app.py,sha256=ZqlJ_ZE0gC2P7Nd3mGNu9jMwENQOboNoRV5ZRfCM0BM,34302
3
- orchestrator/build_pipeline.py,sha256=MTkrG5nV_a3xe8P4doKWRN2-_4ew5HzsFJHfKuChytk,4385
4
- orchestrator/orchestrator_runner.py,sha256=dV_5cuQxZvXiSkj7s0Y_ScD5u2af0UusvuksBXjmOsI,20062
5
- orchestrator/pipeline_builder.py,sha256=R-Y92GjDsBYz5wX5jYgzeKUmXEWjSJIRJ5mj6oDHQ6U,4675
6
- orchestrator/pipeline_orchestrator.py,sha256=vvqI85TZNHSaxeCDeAn3oSZl8BObORp9ofMhg9ZoTAo,25932
7
- orchestrator/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- orchestrator/review_persistence.py,sha256=MGRTEmEVfVQNbo_VycXW98a92OeexyS-TmGN8vBiTVA,5913
9
- orchestrator/static/favicon.svg,sha256=TVNER-nLkPBBb9lZRaruak9jvyXyyfIKgyD2koQcyqk,622
10
- orchestrator/static/orchestrator.css,sha256=PKeb4qYWpXukbUfZuVeNqQnQc1OlqdwPUGIkEqq77Jo,11590
11
- orchestrator/static/orchestrator.html,sha256=6OmxtX3Un-1Ru6sWtL_I49Q4gplwuwG07hXYrTMvCDc,13510
12
- orchestrator/static/orchestrator.js,sha256=Hz5DPEwl0FbCTMhLDOwFHvxAWCN4MGcb1FVzsUyaPlY,32313
13
- orchestrator/static/review_common.js,sha256=t8-AI4ohQbtqSC1iWvR5x0FNlwIxl8gVO2qZsI-VtnI,5875
14
- orchestrator/static/review_identical.html,sha256=Pq8TYbDSBbajC3p_XvlIOC1lbv0eJN_TcymGUw1lDE8,31487
15
- orchestrator/static/review_sequences.html,sha256=oEWRtcMfEvu09F3r-hw8rRfECjcE48BHtht2CdGlw3E,54681
16
- overlap_metrics/__init__.py,sha256=uUZORsoNBeLrl9w7eNtsaz-mEl_dX8oB1Ivp4hI1l6E,11185
17
- overlap_metrics/config.py,sha256=kfCIVJpE4TLrrjeLh4Dk4BIYw8zVqYzCyCvhXMMYN40,3967
18
- overlap_metrics/core.py,sha256=a3s4_NR8nvVp3HVmXhCppG5tIZsTMciplp9UYR08YnM,9656
19
- overlap_metrics/estimators.py,sha256=qVHGpKi7HaLXVI5J0dJjl5Ml0dejP8Vfv048M9PUJFg,11033
20
- overlap_metrics/metrics.py,sha256=eo9DtQRG2QTkKXYeXaXybJMyysHteQwzVrNoIPpbcA8,10180
21
- overlap_metrics/registry.py,sha256=bDgakoh_sxDOv2wMh_-iFgIKCe7td-kOGHwo5hnQMGE,3651
22
- overlap_metrics/utils.py,sha256=0WQxaRfjtxmEOjnJHXsq3PkWhxICkwoY-jG9sNqbBLY,4625
23
- photo_compare/__init__.py,sha256=g8e1wex31_Ku5Lry75xOlFSzRLPqCSPBPxgiLwsxer0,4877
24
- photo_compare/base.py,sha256=oxBR6VEwOXjw8_Jd6PgQtiv4qHpxU4zMRDl4QMOnnv4,9641
25
- photo_compare/config.py,sha256=qrhJvmx9Io9gxlZWB7GHynBxTGBep8Y9SoZXM2sIviY,7781
26
- photo_compare/distance.py,sha256=fcsitsn9MyA2o4UhMz5PguIGyJAbeh3wXFgKdvQp2d4,581
27
- photo_compare/feature_methods.py,sha256=zwKkPP1q8jw4iVUtTTPn3CnJOZXiCjMQL0lL3rxjNC8,7077
28
- photo_compare/file_hash.py,sha256=dr42d3XLMJ6rjCXSwWXLknpZ__PLiOC-Bx3t7tPugeM,1006
29
- photo_compare/hash_methods.py,sha256=yJGj8dqJ-ugguptKIarM9ot9dzbiHKkErwg6BnQArbc,3783
30
- photo_compare/histogram_methods.py,sha256=QVKCWJ2rLp52mMVJphbEJ1RCN935hPQSWXaRwnn7t9Q,5136
31
- photo_compare/pixel_methods.py,sha256=9uOl2qRiPrNgNNcP0B1a21EGHmSA9SUXguegmg0bVME,2421
32
- photo_compare/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- photo_compare/structural_methods.py,sha256=GGigVlxLgApHg2Zj4x9kZf-9IBymQMkkRR_yIeG0qHc,4359
34
- photo_compare/types.py,sha256=oru4zQdA43FhCtgV8BSiJrsS7gIuVtRoaDxh_BLaOtQ,999
35
- photo_stack_finder-0.1.7.dist-info/licenses/LICENSE,sha256=bmBV3PYoSFRs600gmAehqmuaIZIVUl8kGQoZWhapVnM,1468
36
- scripts/orchestrate.py,sha256=DYcBTxaJLzMGE4KAwsyimcXlw4nPgN3BTQNdnFeKxSs,9215
37
- utils/__init__.py,sha256=nCUhcOaBdOmc57VwLwRNrzzQqxPAjNI6H01-kKvoGuE,5141
38
- utils/base_pipeline_stage.py,sha256=PbYBJ25Q8gPHvLwbtaJXkVyiLT99QP9l4b_W3CyBlnc,6540
39
- utils/base_ports.py,sha256=WbR38BlcAkbQaOtX06yDd2pDOx09pB0Mh4OkWvcxfEY,5416
40
- utils/benchmark_utils.py,sha256=aBt_LyrCXgO3Z98bX9DXmpJW-HwhSEs43MZyoHxrL5M,30849
41
- utils/channel.py,sha256=cSmP2y5_vS0YNHPm1CFOTACGeeTxwfbv0u5y_AfhIrw,2660
42
- utils/comparison_gates.py,sha256=FMUCQq4tHEx5WGpTgdq5bHYatI-VjIEcDoFA-DU2n5s,23468
43
- utils/compute_benchmarks.py,sha256=gnqMdgecP23AmlK7mdGrdHLd1S7Ks3zm6-UvuKUkgSs,14223
44
- utils/compute_identical.py,sha256=3a6GiwInaEglduy_dn-8zMhlePf7oJ9VeIvQ5Bw5BqY,7111
45
- utils/compute_indices.py,sha256=1iYTgl9uTVY8k2xaSXSKgR1voDK88LRCAqdCPlMYKX4,9539
46
- utils/compute_perceptual_hash.py,sha256=DP_19r0sBDHcsDIsPoGGFtalbSmyjCJpbti7c6i7DhI,5042
47
- utils/compute_perceptual_match.py,sha256=1XBmBt0H8IeeITDUjjOgpm-Y3Eu7AwZEi4hecl9qIzI,10498
48
- utils/compute_sha_bins.py,sha256=yjPoYPfl-BV9Wo8HM8pCZe_Abxw1sztuWoKM2uuUClA,5423
49
- utils/compute_template_similarity.py,sha256=n_5ogh-0icwT01YCqgX4wXEzp8HTgBYCthY8ceR_GX0,21448
50
- utils/compute_templates.py,sha256=yVYfmaJlfOgeDJ2tdJ5iLd-n4SnPbjepl7eUBP3N1Js,5079
51
- utils/compute_versions.py,sha256=5ihwycoNo4uf8YsVmfEvmWJN1hOxCA-1HXDFS7pQjP0,20819
52
- utils/config.py,sha256=TRPFe_4-20hXkNS3lnGHTVv7vuyp3fxmoKqg12jsCVQ,15485
53
- utils/data_io.py,sha256=S1lJxGLa-uxLYNrIwf3Md9_672jA18U98l24qOYkIQM,2495
54
- utils/graph_context.py,sha256=ubosGjtE0XrADw5x9CYxJ6cebynqhGQ7dcetZy8ZXpY,1602
55
- utils/logger.py,sha256=AaidxSlr4S1wr2J5lXo3hV4fEAht2skzft5yFVJdzuY,1873
56
- utils/models.py,sha256=oaWVyLRMSM7hKMjkaGYXaFWC0uAqqnUHQBNp6Gj0JO4,15300
57
- utils/photo_file.py,sha256=uxX37yiuzqUQ32jIuaqE6LyaRv-WqWiRyrzmeL3nXGI,21411
58
- utils/pipeline_graph.py,sha256=-w3N43_GSQUb21lYVDSxmi-y6bbLF98m5hdduka1eQk,13596
59
- utils/pipeline_stage.py,sha256=iI7pluzUxgjqGW7J822sR8J77iYdOYWWqQODQWXXUBw,17386
60
- utils/plot_helpers.py,sha256=H3Ll4IfocUITLrDW8P_qKuhUrbJN4213ZpBQA41OJwQ,4574
61
- utils/ports.py,sha256=45yTUzoghSFb2uHq05lAmlLkOIM-TBt3e4boBjpJaOA,4454
62
- utils/progress.py,sha256=lH6aorgRxz-cYmkrIS3L8OKxH_Na9Nq59alrXKGphFs,15351
63
- utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- utils/report_builder.py,sha256=eYxrYym6uZj719dKMkGm-eDrUNg8zEosn20hhLsSI6I,4079
65
- utils/review_types.py,sha256=UDzyPKrm-6ICMKo51YbQUJWolFK01mBEbNS0ziocYi8,1768
66
- utils/review_utils.py,sha256=CA4vSVrHTKB8-v7Xj5OJk4u1bcb3qCnIVspZVkWo4IA,8999
67
- utils/sequence.py,sha256=WTM8L8if4KD2yqXhQFnJuNXeRFpF39vAiG1fU2IaBTQ,34879
68
- utils/sequence_clustering.py,sha256=QyqYXHvnzuoknjpyImOFB9D4qEk7WDekP-C4kjXaPqw,5754
69
- utils/template.py,sha256=pRJqlf4QyzdHC0ea3L0o_sAVq_awtP34nYBvYhL2Vb8,1761
70
- photo_stack_finder-0.1.7.dist-info/METADATA,sha256=sPXgLHR4hvS7hy-urNKNikPRo-FuQmY3lJbrgAGiz2U,17117
71
- photo_stack_finder-0.1.7.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
72
- photo_stack_finder-0.1.7.dist-info/entry_points.txt,sha256=ZHWJIeylUGZYa_8Rjt3QxbWiCCVZZx3FQShTNg91zNQ,64
73
- photo_stack_finder-0.1.7.dist-info/top_level.txt,sha256=VmNqTeDiNgCj3LZJICyRF2Uc4buZQ7LxgSob-BoImk0,57
74
- photo_stack_finder-0.1.7.dist-info/RECORD,,