comicbox 5.3.2__tar.gz → 5.4.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.
Files changed (629) hide show
  1. {comicbox-5.3.2 → comicbox-5.4.0}/.gitignore +0 -1
  2. {comicbox-5.3.2 → comicbox-5.4.0}/NEWS.md +11 -0
  3. {comicbox-5.3.2 → comicbox-5.4.0}/PKG-INFO +1 -1
  4. comicbox-5.4.0/bin/fix-complexity.sh +8 -0
  5. {comicbox-5.3.2 → comicbox-5.4.0}/bin/fix-python.sh +1 -0
  6. {comicbox-5.3.2 → comicbox-5.4.0}/bin/release-tag.sh +5 -2
  7. {comicbox-5.3.2 → comicbox-5.4.0}/bun.lock +54 -26
  8. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/python.mk +6 -0
  9. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/online_lookup.py +1 -0
  10. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/comicbox.py +9 -0
  11. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/enum_fields.py +7 -1
  12. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/profile.py +23 -0
  13. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/prompt.py +35 -10
  14. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/selector.py +4 -0
  15. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/sources/base.py +18 -0
  16. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/__init__.py +3 -0
  17. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/publishing.py +5 -1
  18. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicvine_api/online_source.py +86 -42
  19. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicvine_api/transform.py +31 -3
  20. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_api/online_source.py +165 -7
  21. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_api/transform.py +43 -7
  22. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/identifiers/identifiers.py +1 -0
  23. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/online_session.py +7 -1
  24. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/series.schema.json +10 -0
  25. {comicbox-5.3.2 → comicbox-5.4.0}/docs/NEWS.md +11 -0
  26. {comicbox-5.3.2 → comicbox-5.4.0}/docs/SCHEMAS.md +9 -0
  27. {comicbox-5.3.2 → comicbox-5.4.0}/docs/TAGS.md +4 -0
  28. {comicbox-5.3.2 → comicbox-5.4.0}/package.json +2 -2
  29. {comicbox-5.3.2 → comicbox-5.4.0}/pyproject.toml +2 -2
  30. {comicbox-5.3.2 → comicbox-5.4.0}/pyproject.toml.orig +2 -2
  31. comicbox-5.4.0/tests/schemas/test_series_fields.py +97 -0
  32. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_comicvine.py +117 -2
  33. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_defer_prompts.py +84 -2
  34. comicbox-5.4.0/tests/unit/test_metron_get.py +153 -0
  35. comicbox-5.4.0/tests/unit/test_metron_prompt_enrichment.py +237 -0
  36. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_source.py +23 -1
  37. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_transform.py +69 -0
  38. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_events.py +3 -0
  39. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_prompt.py +43 -0
  40. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_prompt_loops.py +30 -0
  41. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_result_contract.py +3 -0
  42. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_selector.py +27 -0
  43. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_session.py +3 -0
  44. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rich_transforms.py +56 -3
  45. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/metron_transport.py +49 -0
  46. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/online_prompt.py +4 -0
  47. {comicbox-5.3.2 → comicbox-5.4.0}/uv.lock +92 -80
  48. {comicbox-5.3.2 → comicbox-5.4.0}/.dockerignore +0 -0
  49. {comicbox-5.3.2 → comicbox-5.4.0}/.prettierignore +0 -0
  50. {comicbox-5.3.2 → comicbox-5.4.0}/.readthedocs.yaml +0 -0
  51. {comicbox-5.3.2 → comicbox-5.4.0}/.shellcheckrc +0 -0
  52. {comicbox-5.3.2 → comicbox-5.4.0}/.shellignore +0 -0
  53. {comicbox-5.3.2 → comicbox-5.4.0}/Makefile +0 -0
  54. {comicbox-5.3.2 → comicbox-5.4.0}/README.md +0 -0
  55. {comicbox-5.3.2 → comicbox-5.4.0}/bin/_lib.sh +0 -0
  56. {comicbox-5.3.2 → comicbox-5.4.0}/bin/ci-reuse-dist.sh +0 -0
  57. {comicbox-5.3.2 → comicbox-5.4.0}/bin/clean-pycache.sh +0 -0
  58. {comicbox-5.3.2 → comicbox-5.4.0}/bin/cleanup-pypi-alpha.sh +0 -0
  59. {comicbox-5.3.2 → comicbox-5.4.0}/bin/dev-module.sh +0 -0
  60. {comicbox-5.3.2 → comicbox-5.4.0}/bin/docker-compose-exit.sh +0 -0
  61. {comicbox-5.3.2 → comicbox-5.4.0}/bin/docker-tag-latest.sh +0 -0
  62. {comicbox-5.3.2 → comicbox-5.4.0}/bin/find-files.sh +0 -0
  63. {comicbox-5.3.2 → comicbox-5.4.0}/bin/find-sh.sh +0 -0
  64. {comicbox-5.3.2 → comicbox-5.4.0}/bin/fix-docker.sh +0 -0
  65. {comicbox-5.3.2 → comicbox-5.4.0}/bin/fix.sh +0 -0
  66. {comicbox-5.3.2 → comicbox-5.4.0}/bin/hub_prune_stale.py +0 -0
  67. {comicbox-5.3.2 → comicbox-5.4.0}/bin/kill-eslint_d.sh +0 -0
  68. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint-ci.sh +0 -0
  69. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint-complexity.sh +0 -0
  70. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint-docker.sh +0 -0
  71. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint-python.sh +0 -0
  72. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint-vulture.sh +0 -0
  73. {comicbox-5.3.2 → comicbox-5.4.0}/bin/lint.sh +0 -0
  74. {comicbox-5.3.2 → comicbox-5.4.0}/bin/prettier-nginx.sh +0 -0
  75. {comicbox-5.3.2 → comicbox-5.4.0}/bin/publish-pypi.sh +0 -0
  76. {comicbox-5.3.2 → comicbox-5.4.0}/bin/regenerate-pdf-test-pages.py +0 -0
  77. {comicbox-5.3.2 → comicbox-5.4.0}/bin/release_info.py +0 -0
  78. {comicbox-5.3.2 → comicbox-5.4.0}/bin/roman.py +0 -0
  79. {comicbox-5.3.2 → comicbox-5.4.0}/bin/sh-tools.sh +0 -0
  80. {comicbox-5.3.2 → comicbox-5.4.0}/bin/sort-ignore.sh +0 -0
  81. {comicbox-5.3.2 → comicbox-5.4.0}/bin/test-docker.sh +0 -0
  82. {comicbox-5.3.2 → comicbox-5.4.0}/bin/test-python.sh +0 -0
  83. {comicbox-5.3.2 → comicbox-5.4.0}/bin/uml.sh +0 -0
  84. {comicbox-5.3.2 → comicbox-5.4.0}/bin/update-deps-node.sh +0 -0
  85. {comicbox-5.3.2 → comicbox-5.4.0}/bin/update-deps-python.sh +0 -0
  86. {comicbox-5.3.2 → comicbox-5.4.0}/bin/version-node.sh +0 -0
  87. {comicbox-5.3.2 → comicbox-5.4.0}/bin/version-python.sh +0 -0
  88. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/ci.mk +0 -0
  89. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/common.mk +0 -0
  90. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/docker.mk +0 -0
  91. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/docs.mk +0 -0
  92. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/eslint.config.base.js +0 -0
  93. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/gha_std.mk +0 -0
  94. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/help.mk +0 -0
  95. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/node.mk +0 -0
  96. {comicbox-5.3.2 → comicbox-5.4.0}/cfg/node_root.mk +0 -0
  97. {comicbox-5.3.2 → comicbox-5.4.0}/check-jsonschema.sh +0 -0
  98. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/__init__.py +0 -0
  99. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/_pdf.py +0 -0
  100. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/_rar.py +0 -0
  101. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/_rar_probe.rar +0 -0
  102. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/__init__.py +0 -0
  103. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/__init__.py +0 -0
  104. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/archive.py +0 -0
  105. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/archiveinfo.py +0 -0
  106. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/filenames.py +0 -0
  107. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/init.py +0 -0
  108. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/mtime.py +0 -0
  109. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/pages.py +0 -0
  110. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/read.py +0 -0
  111. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/sniff.py +0 -0
  112. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/archive/write.py +0 -0
  113. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/__init__.py +0 -0
  114. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/date.py +0 -0
  115. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/identifiers.py +0 -0
  116. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/issue.py +0 -0
  117. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/notes.py +0 -0
  118. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/pages.py +0 -0
  119. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/stamp.py +0 -0
  120. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/stories_title.py +0 -0
  121. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/url_identifiers.py +0 -0
  122. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/computed/urls.py +0 -0
  123. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/dump.py +0 -0
  124. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/dump_files.py +0 -0
  125. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/init.py +0 -0
  126. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/load.py +0 -0
  127. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/merge.py +0 -0
  128. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/metadata.py +0 -0
  129. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/normalize.py +0 -0
  130. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/online_covers.py +0 -0
  131. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/pages/__init__.py +0 -0
  132. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/pages/covers.py +0 -0
  133. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/pages/extract.py +0 -0
  134. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/print.py +0 -0
  135. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/sources.py +0 -0
  136. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/types.py +0 -0
  137. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/validate/__init__.py +0 -0
  138. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/box/validate/guess_format.py +0 -0
  139. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/cli/__init__.py +0 -0
  140. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/cli/__main__.py +0 -0
  141. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/cli/epilog.py +0 -0
  142. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/cli/parser.py +0 -0
  143. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/__init__.py +0 -0
  144. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/computed.py +0 -0
  145. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/formats.py +0 -0
  146. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/online/__init__.py +0 -0
  147. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/online/build.py +0 -0
  148. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/online/settings.py +0 -0
  149. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/online/template.py +0 -0
  150. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/paths.py +0 -0
  151. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/read.py +0 -0
  152. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config/settings.py +0 -0
  153. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/config_default.yaml +0 -0
  154. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/constants.py +0 -0
  155. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/__init__.py +0 -0
  156. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/archives.py +0 -0
  157. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/context.py +0 -0
  158. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/images.py +0 -0
  159. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/online.py +0 -0
  160. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/packages.py +0 -0
  161. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/render.py +0 -0
  162. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/result.py +0 -0
  163. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/doctor/settings.py +0 -0
  164. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/empty.py +0 -0
  165. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/__init__.py +0 -0
  166. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/comet.py +0 -0
  167. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/comicbookinfo.py +0 -0
  168. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/comicinfo.py +0 -0
  169. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/generic/__init__.py +0 -0
  170. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/generic/age_rating.py +0 -0
  171. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/generic/role.py +0 -0
  172. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/__init__.py +0 -0
  173. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/age_rating.py +0 -0
  174. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/formats.py +0 -0
  175. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/identifiers.py +0 -0
  176. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/reading_direction.py +0 -0
  177. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/maps/roles.py +0 -0
  178. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/enums/metroninfo.py +0 -0
  179. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/events.py +0 -0
  180. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/exceptions.py +0 -0
  181. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/__init__.py +0 -0
  182. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/_base.py +0 -0
  183. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/__init__.py +0 -0
  184. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/__init__.py +0 -0
  185. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/collection_fields.py +0 -0
  186. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/comicbox.py +0 -0
  187. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/comicinfo.py +0 -0
  188. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/fields.py +0 -0
  189. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/metroninfo.py +0 -0
  190. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/number_fields.py +0 -0
  191. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/pdf.py +0 -0
  192. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/pycountry.py +0 -0
  193. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/time_fields.py +0 -0
  194. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/union.py +0 -0
  195. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/fields/xml_fields.py +0 -0
  196. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/__init__.py +0 -0
  197. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/auto_engage.py +0 -0
  198. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/cli_overrides.py +0 -0
  199. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/cover_hash.py +0 -0
  200. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/credentials.py +0 -0
  201. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/matcher.py +0 -0
  202. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/outcome_stats.py +0 -0
  203. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/rate_gate.py +0 -0
  204. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/rate_limits.py +0 -0
  205. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/retry.py +0 -0
  206. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/sanitize.py +0 -0
  207. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/series_cache.py +0 -0
  208. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/series_filter.py +0 -0
  209. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/session_state.py +0 -0
  210. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/signals.py +0 -0
  211. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/sources/__init__.py +0 -0
  212. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/transform_helpers.py +0 -0
  213. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/vacuum.py +0 -0
  214. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/online/warn_once.py +0 -0
  215. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/__init__.py +0 -0
  216. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/base.py +0 -0
  217. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/cache.py +0 -0
  218. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/decorators.py +0 -0
  219. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/error_store.py +0 -0
  220. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/json_schemas.py +0 -0
  221. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/xml_schemas.py +0 -0
  222. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/schemas/yaml.py +0 -0
  223. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/__init__.py +0 -0
  224. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/base.py +0 -0
  225. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/identifiers.py +0 -0
  226. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/price.py +0 -0
  227. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/publishing_tags.py +0 -0
  228. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/spec.py +0 -0
  229. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/xml_credits.py +0 -0
  230. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/base/transforms/xml_reprints.py +0 -0
  231. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comet/__init__.py +0 -0
  232. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comet/schema.py +0 -0
  233. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comet/transform/__init__.py +0 -0
  234. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comet/transform/reprints.py +0 -0
  235. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_book_info/__init__.py +0 -0
  236. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_book_info/schema.py +0 -0
  237. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_book_info/transform/__init__.py +0 -0
  238. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_book_info/transform/credits.py +0 -0
  239. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_book_info/transform/rating.py +0 -0
  240. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/__init__.py +0 -0
  241. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/schema.py +0 -0
  242. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/transform/__init__.py +0 -0
  243. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/transform/identifiers.py +0 -0
  244. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/transform/manga.py +0 -0
  245. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/transform/pages.py +0 -0
  246. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comic_info/transform/storyarcs.py +0 -0
  247. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/__init__.py +0 -0
  248. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/README.md +0 -0
  249. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/cli.py +0 -0
  250. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/identifiers.py +0 -0
  251. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/json_schema.py +0 -0
  252. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/pages.py +0 -0
  253. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/schema/yaml.py +0 -0
  254. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/__init__.py +0 -0
  255. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/cli.py +0 -0
  256. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/credits.py +0 -0
  257. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/json.py +0 -0
  258. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/name_objs.py +0 -0
  259. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicbox/transform/yaml.py +0 -0
  260. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicvine_api/__init__.py +0 -0
  261. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/comicvine_api/schema.py +0 -0
  262. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/filename/__init__.py +0 -0
  263. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/filename/schema.py +0 -0
  264. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/filename/transform.py +0 -0
  265. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_api/__init__.py +0 -0
  266. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_api/paced_session.py +0 -0
  267. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_api/schema.py +0 -0
  268. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/__init__.py +0 -0
  269. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/__init__.py +0 -0
  270. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/credits.py +0 -0
  271. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/identifiers.py +0 -0
  272. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/price.py +0 -0
  273. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/publishing.py +0 -0
  274. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/rating.py +0 -0
  275. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/schema/resource.py +0 -0
  276. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/__init__.py +0 -0
  277. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/const.py +0 -0
  278. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/credits.py +0 -0
  279. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/identified_name.py +0 -0
  280. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/identifier_attribute.py +0 -0
  281. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/identifiers.py +0 -0
  282. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/publishing_tags.py +0 -0
  283. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/rating.py +0 -0
  284. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/reprints.py +0 -0
  285. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/metron_info/transform/resources.py +0 -0
  286. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/pdf/__init__.py +0 -0
  287. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/pdf/schema.py +0 -0
  288. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/pdf/transform/__init__.py +0 -0
  289. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/pdf/transform/credits.py +0 -0
  290. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/formats/sources.py +0 -0
  291. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/identifiers/__init__.py +0 -0
  292. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/identifiers/other.py +0 -0
  293. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/identifiers/urns.py +0 -0
  294. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/logger.py +0 -0
  295. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/merge/__init__.py +0 -0
  296. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/merge/mergedeep.py +0 -0
  297. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/online_estimate.py +0 -0
  298. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/predict.py +0 -0
  299. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/print.py +0 -0
  300. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/process.py +0 -0
  301. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/py.typed +0 -0
  302. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/run.py +0 -0
  303. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/CoMet-v1.1.xsd +0 -0
  304. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/ComicInfo-v2.1-Draft.xsd +0 -0
  305. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/MetronInfo-v1.1.xsd +0 -0
  306. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/comic-book-info-v1.0.schema.json +0 -0
  307. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v1.0/comicbox-v1.0.schema.json +0 -0
  308. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v1.0/page.schema.json +0 -0
  309. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v1.0/reprint.schema.json +0 -0
  310. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v1.0/series.schema.json +0 -0
  311. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v1.0/volume.schema.json +0 -0
  312. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/comicbox-v2.0.schema.json +0 -0
  313. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/comicbox.example.yaml +0 -0
  314. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/credit.schema.json +0 -0
  315. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/date.schema.json +0 -0
  316. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/identified-object.schema.json +0 -0
  317. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/identified-objects.schema.json +0 -0
  318. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/identifiers.schema.json +0 -0
  319. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/named-identified-object.schema.json +0 -0
  320. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/page.schema.json +0 -0
  321. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/reprint.schema.json +0 -0
  322. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/series.schema.json +0 -0
  323. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v2.0/volume.schema.json +0 -0
  324. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/alternative-name.schema.json +0 -0
  325. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/comicbox-v3.0.schema.json +0 -0
  326. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/comicbox.example.yaml +0 -0
  327. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/credit.schema.json +0 -0
  328. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/date.schema.json +0 -0
  329. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/identified-object.schema.json +0 -0
  330. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/identified-objects.schema.json +0 -0
  331. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/identifiers.schema.json +0 -0
  332. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/named-identified-object.schema.json +0 -0
  333. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/page.schema.json +0 -0
  334. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/reprint.schema.json +0 -0
  335. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/role.schema.json +0 -0
  336. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/schemas/v3.0/volume.schema.json +0 -0
  337. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/__init__.py +0 -0
  338. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/base.py +0 -0
  339. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/json_validator.py +0 -0
  340. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/spec.py +0 -0
  341. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/xml_validator.py +0 -0
  342. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/validate/yaml_validator.py +0 -0
  343. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/version.py +0 -0
  344. {comicbox-5.3.2 → comicbox-5.4.0}/comicbox/write.py +0 -0
  345. {comicbox-5.3.2 → comicbox-5.4.0}/compose.yaml +0 -0
  346. {comicbox-5.3.2 → comicbox-5.4.0}/docs/README.md +0 -0
  347. {comicbox-5.3.2 → comicbox-5.4.0}/docs/requirements.txt +0 -0
  348. {comicbox-5.3.2 → comicbox-5.4.0}/docs/style.css +0 -0
  349. {comicbox-5.3.2 → comicbox-5.4.0}/docs/style.mkdocs.css +0 -0
  350. {comicbox-5.3.2 → comicbox-5.4.0}/eslint.config.js +0 -0
  351. {comicbox-5.3.2 → comicbox-5.4.0}/generate-schema/gen-schema-docs.sh +0 -0
  352. {comicbox-5.3.2 → comicbox-5.4.0}/generate-schema/gen-schema.sh +0 -0
  353. {comicbox-5.3.2 → comicbox-5.4.0}/generate-schema/mjs.py +0 -0
  354. {comicbox-5.3.2 → comicbox-5.4.0}/mkdocs.yml +0 -0
  355. {comicbox-5.3.2 → comicbox-5.4.0}/tests/__init__.py +0 -0
  356. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/.gitignore +0 -0
  357. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/README.md +0 -0
  358. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/__init__.py +0 -0
  359. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/_harness_helpers.py +0 -0
  360. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/bootstrap.py +0 -0
  361. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/compare.py +0 -0
  362. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/debug_search.py +0 -0
  363. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/fixtures.example.json +0 -0
  364. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/label_metron.py +0 -0
  365. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/run.py +0 -0
  366. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/sample.py +0 -0
  367. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/summarize.py +0 -0
  368. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_bootstrap.py +0 -0
  369. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_compare.py +0 -0
  370. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_harness.py +0 -0
  371. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_harness_checkpoint.py +0 -0
  372. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_harness_diagnostics.py +0 -0
  373. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_harness_filter.py +0 -0
  374. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_harness_resume.py +0 -0
  375. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_label_metron.py +0 -0
  376. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_sample.py +0 -0
  377. {comicbox-5.3.2 → comicbox-5.4.0}/tests/calibration/test_summarize.py +0 -0
  378. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/__init__.py +0 -0
  379. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_doctor.py +0 -0
  380. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_exit_code.py +0 -0
  381. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_export.py +0 -0
  382. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_extract.py +0 -0
  383. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_online.py +0 -0
  384. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_print.py +0 -0
  385. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_rename.py +0 -0
  386. {comicbox-5.3.2 → comicbox-5.4.0}/tests/cli/test_cli_write.py +0 -0
  387. {comicbox-5.3.2 → comicbox-5.4.0}/tests/conftest.py +0 -0
  388. {comicbox-5.3.2 → comicbox-5.4.0}/tests/const.py +0 -0
  389. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001 (1950) The Beginning - multi.cbz +0 -0
  390. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001 (1950) The Beginning - nothing.cbz +0 -0
  391. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-cbi.cbr +0 -0
  392. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-cix-cbi.cbr +0 -0
  393. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-cix.cbt +0 -0
  394. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-cix.cbz +0 -0
  395. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-comet.cbz +0 -0
  396. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001-metron.cbz +0 -0
  397. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001.cb7 +0 -0
  398. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science #001.cbz +0 -0
  399. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CaptainScience#1_01.jpg +0 -0
  400. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CaptainScience#1_02.jpg +0 -0
  401. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CaptainScience#1_03.jpg +0 -0
  402. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CaptainScience#1_04.jpg +0 -0
  403. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CaptainScience#1_05.jpg +0 -0
  404. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/CoMet.xml +0 -0
  405. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/comic-book-info.json +0 -0
  406. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/comicinfo-original.xml +0 -0
  407. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/comicinfo.xml +0 -0
  408. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/metroninfo-full.xml +0 -0
  409. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/Captain Science 001/metroninfo.xml +0 -0
  410. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/comicbox-cli.cbz +0 -0
  411. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/comicbox.cbz +0 -0
  412. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/create-archive.sh +0 -0
  413. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/create_cs_archives.py +0 -0
  414. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/create_macos_resource_fork.py +0 -0
  415. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/empty.cbz +0 -0
  416. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/examples/comic-book-info-example.json +0 -0
  417. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/examples/metroninfo-v1.1-valid.xml +0 -0
  418. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comet.xml +0 -0
  419. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comic-book-info.json +0 -0
  420. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comicbox-cli.yaml +0 -0
  421. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comicbox.json +0 -0
  422. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comicbox.yaml +0 -0
  423. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/comicinfo.xml +0 -0
  424. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/create-export-archive.sh +0 -0
  425. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/metroninfo.xml +0 -0
  426. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/mupdf.json +0 -0
  427. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export/pdf-metadata.xml +0 -0
  428. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/export.cbz +0 -0
  429. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/list_recurse_output.txt +0 -0
  430. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/macos_resource_fork.cbz +0 -0
  431. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comet-cover-path-list.xml +0 -0
  432. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comet-write.xml +0 -0
  433. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comet.xml +0 -0
  434. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comic-book-info-example.json +0 -0
  435. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comic-book-info.json +0 -0
  436. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox-cli.yaml +0 -0
  437. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox-filename.txt +0 -0
  438. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox-write.json +0 -0
  439. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox-write.yaml +0 -0
  440. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox.json +0 -0
  441. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox.xml +0 -0
  442. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicbox.yaml +0 -0
  443. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-bad-multiple.xml +0 -0
  444. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-cover-path-list.xml +0 -0
  445. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-ids-from-tags.xml +0 -0
  446. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-metron-origin.xml +0 -0
  447. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-notes-date.xml +0 -0
  448. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-validation.xml +0 -0
  449. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo-write.xml +0 -0
  450. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/comicinfo.xml +0 -0
  451. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/create-archives.sh +0 -0
  452. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/metroninfo-no-primary-id.xml +0 -0
  453. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/metroninfo-v1.1-valid.xml +0 -0
  454. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/metroninfo-write.xml +0 -0
  455. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/metroninfo.xml +0 -0
  456. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/mupdf-nested.json +0 -0
  457. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/mupdf.json +0 -0
  458. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/pdf-cix.xml +0 -0
  459. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/pdf-nested.xml +0 -0
  460. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/metadata/pdf.xml +0 -0
  461. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comet.xml +0 -0
  462. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comic-book-info.json +0 -0
  463. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comicbox-filename.txt +0 -0
  464. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comicbox.json +0 -0
  465. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comicbox.yaml +0 -0
  466. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/comicinfo.xml +0 -0
  467. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/multi/create-multi-archive.sh +0 -0
  468. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/patchme.cbz +0 -0
  469. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/pdf/0.pdf +0 -0
  470. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/pdf/1.pdf +0 -0
  471. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/pdf/2.pdf +0 -0
  472. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/pdf/3.pdf +0 -0
  473. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/test_cix.pdf +0 -0
  474. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/test_pdf.pdf +0 -0
  475. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/test_pdf_legacy_keywords.pdf +0 -0
  476. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/xml.cbz +0 -0
  477. {comicbox-5.3.2 → comicbox-5.4.0}/tests/files/yaml.cbz +0 -0
  478. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/__init__.py +0 -0
  479. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_cbi.py +0 -0
  480. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_cix.py +0 -0
  481. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_comet.py +0 -0
  482. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_filename.py +0 -0
  483. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_json.py +0 -0
  484. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_json_schema_drift.py +0 -0
  485. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_metron.py +0 -0
  486. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_multi.py +0 -0
  487. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_pdf_json.py +0 -0
  488. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_pdf_xml.py +0 -0
  489. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_validation.py +0 -0
  490. {comicbox-5.3.2 → comicbox-5.4.0}/tests/schemas/test_yaml.py +0 -0
  491. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/.gitignore +0 -0
  492. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/README.md +0 -0
  493. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/__init__.py +0 -0
  494. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/jobs_accuracy.py +0 -0
  495. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/prompt_ux.py +0 -0
  496. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/run.py +0 -0
  497. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/test_jobs_accuracy.py +0 -0
  498. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/test_prompt_ux.py +0 -0
  499. {comicbox-5.3.2 → comicbox-5.4.0}/tests/stress/test_run.py +0 -0
  500. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_codex_api.py +0 -0
  501. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_compute.py +0 -0
  502. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_convert_pdf.py +0 -0
  503. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_extract.py +0 -0
  504. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_import_export.py +0 -0
  505. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_mtime.py +0 -0
  506. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_pages.py +0 -0
  507. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_stories_title.py +0 -0
  508. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_validate_testfiles.py +0 -0
  509. {comicbox-5.3.2 → comicbox-5.4.0}/tests/test_writing.py +0 -0
  510. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/__init__.py +0 -0
  511. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/cover_hash_golden.json +0 -0
  512. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_archive_errors.py +0 -0
  513. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_archive_read.py +0 -0
  514. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_archiveinfo_mtime.py +0 -0
  515. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_auto_engage.py +0 -0
  516. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_box_cache_invalidation.py +0 -0
  517. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cbi_rating_normalize.py +0 -0
  518. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cli_choices_enum_drift.py +0 -0
  519. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cli_dest_folds.py +0 -0
  520. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cli_dest_template_drift.py +0 -0
  521. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_comicinfo_alternates.py +0 -0
  522. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_comicinfo_series_groups.py +0 -0
  523. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_comicvine_client.py +0 -0
  524. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_comicvine_session_lifecycle.py +0 -0
  525. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_computed_pipeline.py +0 -0
  526. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_computed_reprints.py +0 -0
  527. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_container_inputs.py +0 -0
  528. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_defaults_drift.py +0 -0
  529. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_enum_inputs.py +0 -0
  530. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_env_tree.py +0 -0
  531. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_errors.py +0 -0
  532. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_file_option.py +0 -0
  533. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_layering.py +0 -0
  534. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_no_path_guard.py +0 -0
  535. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_online_leaf.py +0 -0
  536. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_config_online_sources.py +0 -0
  537. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cover_hash.py +0 -0
  538. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_cover_hash_parity.py +0 -0
  539. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_credit_primary.py +0 -0
  540. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_destination_occupied_error.py +0 -0
  541. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_archives.py +0 -0
  542. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_images.py +0 -0
  543. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_online.py +0 -0
  544. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_online_verify.py +0 -0
  545. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_packages.py +0 -0
  546. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_render.py +0 -0
  547. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_doctor_settings.py +0 -0
  548. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_error_store_visibility.py +0 -0
  549. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_exceptions.py +0 -0
  550. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_identifiers.py +0 -0
  551. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_lazy_startup.py +0 -0
  552. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_library_logging.py +0 -0
  553. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_list_field_dedupe.py +0 -0
  554. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_list_field_sort_key_types.py +0 -0
  555. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_manga_and_age_rating.py +0 -0
  556. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_manga_volume.py +0 -0
  557. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_merge_mode_config.py +0 -0
  558. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_merge_order.py +0 -0
  559. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_merge_precedence.py +0 -0
  560. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_mergedeep.py +0 -0
  561. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_community_rating.py +0 -0
  562. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_id_attribute_fallback.py +0 -0
  563. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_prefetch.py +0 -0
  564. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_metron_session_lifecycle.py +0 -0
  565. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online.py +0 -0
  566. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_abort_propagation.py +0 -0
  567. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_degradation.py +0 -0
  568. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_estimate.py +0 -0
  569. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_lookup.py +0 -0
  570. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_matcher.py +0 -0
  571. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_matcher_resolution.py +0 -0
  572. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_matcher_scoring.py +0 -0
  573. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_retry.py +0 -0
  574. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_online_session_state.py +0 -0
  575. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_outcome_stats.py +0 -0
  576. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_paced_session.py +0 -0
  577. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_parse_decimal.py +0 -0
  578. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_parse_issue.py +0 -0
  579. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_pdf_date_field.py +0 -0
  580. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_pdf_import_guard.py +0 -0
  581. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_pdf_pages_help.py +0 -0
  582. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_process.py +0 -0
  583. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_process_archive_errors.py +0 -0
  584. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_prompt_dedup.py +0 -0
  585. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_quota_reserved_skip.py +0 -0
  586. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rar_time_overflow.py +0 -0
  587. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rar_tool_probe.py +0 -0
  588. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rate_gate.py +0 -0
  589. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rate_gate_concurrency.py +0 -0
  590. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rate_limits.py +0 -0
  591. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_read_events.py +0 -0
  592. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_refresh_cache.py +0 -0
  593. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_rename_and_convert_safety.py +0 -0
  594. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_reprints_and_alternative_names.py +0 -0
  595. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_role_vocabulary.py +0 -0
  596. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_run_parallel.py +0 -0
  597. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_run_recurse.py +0 -0
  598. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_series_cache.py +0 -0
  599. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_series_filter.py +0 -0
  600. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_series_single_flight.py +0 -0
  601. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_session_series_batching.py +0 -0
  602. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_single_valued_tags.py +0 -0
  603. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_sniff.py +0 -0
  604. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_sources.py +0 -0
  605. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_to_metron_age_rating.py +0 -0
  606. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_transform_spec_dest_collisions.py +0 -0
  607. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_transform_spec_missing_keys.py +0 -0
  608. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_transform_spec_scope_phases.py +0 -0
  609. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_urls_and_identifiers.py +0 -0
  610. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_vacuum.py +0 -0
  611. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_validate.py +0 -0
  612. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_write_api.py +0 -0
  613. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_write_destination_prediction.py +0 -0
  614. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_write_destination_safety.py +0 -0
  615. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_write_order_and_claims.py +0 -0
  616. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_xml_cdata_fields.py +0 -0
  617. {comicbox-5.3.2 → comicbox-5.4.0}/tests/unit/test_yes_no_field.py +0 -0
  618. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/__init__.py +0 -0
  619. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/compare.py +0 -0
  620. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/cover_images.py +0 -0
  621. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/diff.py +0 -0
  622. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/metadata.py +0 -0
  623. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/online_client.py +0 -0
  624. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/online_matcher.py +0 -0
  625. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/parser.py +0 -0
  626. {comicbox-5.3.2 → comicbox-5.4.0}/tests/util/tmp.py +0 -0
  627. {comicbox-5.3.2 → comicbox-5.4.0}/tests/validate_cli.py +0 -0
  628. {comicbox-5.3.2 → comicbox-5.4.0}/validate-schema.sh +0 -0
  629. {comicbox-5.3.2 → comicbox-5.4.0}/vulture_ignorelist.py +0 -0
@@ -45,7 +45,6 @@ MANIFEST
45
45
  TODO.md
46
46
  __pycache__
47
47
  __pypackages__
48
- __snapshots__
49
48
  build
50
49
  celerybeat-schedule
51
50
  celerybeat.pid
@@ -1,5 +1,16 @@
1
1
  # 📰 News
2
2
 
3
+ ## v5.4.0
4
+
5
+ - Features
6
+ - Series end year, status and summary in comicbox.json and comicbox.yaml.
7
+ - Online tagging fills series years, status, summary and issue count, the
8
+ publication format from Metron, and tags from Comic Vine concepts and
9
+ objects.
10
+ - Match prompts show each candidate's series start year, publisher, issue
11
+ count, issue title and description, and Metron's publication format when
12
+ titles would otherwise read the same.
13
+
3
14
  ## v5.3.2
4
15
 
5
16
  - Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comicbox
3
- Version: 5.3.2
3
+ Version: 5.4.0
4
4
  Summary: Comic book archive multi format metadata read/write/transform tool and image extractor.
5
5
  Keywords: cb7,cbr,cbt,cbz,comet,comic,comicbookinfo,comicinfo,metroninfo,pdf
6
6
  Author: AJ Slater
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ # Fix complexity
3
+ # Rewrites only functions over the complexity limit; lint-complexity.sh fails on
4
+ # what it leaves. --quiet would undo --ignore-complexity (complexipy 8.1.0).
5
+ # ruff formats its rewrites.
6
+ set -euxo pipefail
7
+ uv run --group lint complexipy --fix --ignore-complexity
8
+ uv run --group lint ruff format .
@@ -3,5 +3,6 @@
3
3
  set -euxo pipefail
4
4
 
5
5
  # Python
6
+ bin/fix-complexity.sh
6
7
  uv run --group lint ruff check --fix .
7
8
  uv run --group lint ruff format .
@@ -280,8 +280,11 @@ cmd_publish() {
280
280
  return 0
281
281
  ;;
282
282
  esac
283
- latest=$(git ls-remote --tags --refs "$REMOTE" 'v*' |
284
- python3 "$RELEASE_INFO" is-latest --version "$VERSION") ||
283
+ # A file, not a pipe: is-latest may stop reading early (always for an
284
+ # alpha), and under pipefail the SIGPIPE it gives ls-remote fails the run.
285
+ git ls-remote --tags --refs "$REMOTE" 'v*' >"$TMP/tags" ||
286
+ die "could not list tags on $REMOTE"
287
+ latest=$(python3 "$RELEASE_INFO" is-latest --version "$VERSION" <"$TMP/tags") ||
285
288
  die "could not work out whether $TAG is the latest release"
286
289
  if [ "$FINAL" != true ]; then
287
290
  flags=(--prerelease --latest=false)
@@ -35,7 +35,7 @@
35
35
  "prettier": "^3.9.10",
36
36
  "prettier-plugin-nginx": "^2.0.0",
37
37
  "prettier-plugin-packagejson": "^3.0.2",
38
- "prettier-plugin-toml": "^4.0.0",
38
+ "prettier-plugin-toml": "^4.1.0",
39
39
  },
40
40
  },
41
41
  },
@@ -116,23 +116,51 @@
116
116
 
117
117
  "@stylistic/eslint-plugin": ["@stylistic/eslint-plugin@5.10.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/types": "^8.56.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "estraverse": "^5.3.0", "picomatch": "^4.0.3" }, "peerDependencies": { "eslint": "^9.0.0 || ^10.0.0" } }, "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ=="],
118
118
 
119
- "@tombi-toml/lib": ["@tombi-toml/lib@1.8.7", "", { "optionalDependencies": { "@tombi-toml/lib-darwin-arm64": "1.8.7", "@tombi-toml/lib-darwin-x64": "1.8.7", "@tombi-toml/lib-linux-arm64": "1.8.7", "@tombi-toml/lib-linux-arm64-musl": "1.8.7", "@tombi-toml/lib-linux-x64": "1.8.7", "@tombi-toml/lib-linux-x64-musl": "1.8.7", "@tombi-toml/lib-win32-arm64": "1.8.7", "@tombi-toml/lib-win32-x64": "1.8.7" } }, "sha512-rVTSFYJHjE4uU/HbrOtgoeiTvzjM0mzVNp8XHK0TIobHkXL4BM26b82lkAH+UNEXWBj8ua7i9x+Cvs4u4lVBZg=="],
119
+ "@tombit/binding-android-arm-eabi": ["@tombit/binding-android-arm-eabi@0.1.5", "", { "os": "android", "cpu": "arm" }, "sha512-3JH3GZbVTTekI+9gMimjK+6iFIO63F6apfhnKAenFfmoXHPR2kvkL65AawggWMFQ62IPU5HGU1lrJSneQwKioA=="],
120
120
 
121
- "@tombi-toml/lib-darwin-arm64": ["@tombi-toml/lib-darwin-arm64@1.8.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/xevJm/okKzkpHxnkxijRbkfyu9EHnIhrs9J0gcQYEa/Rt569VBKa/SZYY1YjvxLf1w6IxpUnBi2fmRsj9wNHA=="],
121
+ "@tombit/binding-android-arm64": ["@tombit/binding-android-arm64@0.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-iUmxa+OBE5gY/uFzBt4AOjWI1YB7tjnxbIGYpcRMaso8ftwcVigExiLzikUHQQS7AmqtOIdHM6v6QcU9+wg/qQ=="],
122
122
 
123
- "@tombi-toml/lib-darwin-x64": ["@tombi-toml/lib-darwin-x64@1.8.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-YGoaDou/a8PL17lmdoeP6pJzI95t6m5r+8WBGaeh5NDfbcVvEcorrfvk4R/x1beY/LRB9xm0S7BUYcTzUqeCdw=="],
123
+ "@tombit/binding-darwin-arm64": ["@tombit/binding-darwin-arm64@0.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-x7LRqoGuvV/cfSVQrc06BPk0S6CwRZkKzvHguGFXsAIyGBfUA9DHTvOI5WSJKrz788F9CSWiKjLxey+zEj1wYg=="],
124
124
 
125
- "@tombi-toml/lib-linux-arm64": ["@tombi-toml/lib-linux-arm64@1.8.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-jylp2XGl04TDaw5agWoIebJuUITiCox+CCM6lp1apcfdn4s2EI0izWwDWk0vfOmnGqFutZnEtzIc7iPq5PzwsQ=="],
125
+ "@tombit/binding-darwin-x64": ["@tombit/binding-darwin-x64@0.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-+LValJITWhuNFQEfP62a1Rl/idbengROFIH6Xwcpw1YSXnyk9DjTpiXz2mxJ1JofIxU9QbsBLXlF76sYxwNIMA=="],
126
126
 
127
- "@tombi-toml/lib-linux-arm64-musl": ["@tombi-toml/lib-linux-arm64-musl@1.8.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xh644o98wqwwyqdyi8eh3z932194mtIEbdSrqX9tOXM5OjwXKGlgi8v0HMD56bcMVl+AOhjT3Jiq9ARmkismUQ=="],
127
+ "@tombit/binding-freebsd-x64": ["@tombit/binding-freebsd-x64@0.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-bSt6UHk4L12iVwZVXgdu8zy9DggsWMTug1Td5+ila8GOlUpTzd+7mgqx9054TLjO/ilsc21jLisU8/qCbfi3jQ=="],
128
128
 
129
- "@tombi-toml/lib-linux-x64": ["@tombi-toml/lib-linux-x64@1.8.7", "", { "os": "linux", "cpu": "x64" }, "sha512-05fyRWH2XSdVw5G2sokiTd7S/l4WhzDALSUNrZPYw0pga3GHQ8a5RhfY7C2WKCOKL5LYn8k2yHTdS6wyQziHLw=="],
129
+ "@tombit/binding-linux-arm-gnueabihf": ["@tombit/binding-linux-arm-gnueabihf@0.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-5AfdesZufQNvdnDfVutAdY+MNdaD8E8n31iuoMXzaFUxQYsv6m2Ch3MP86k3vfJRMT6KUMuHC0ZiyehPbxGL+g=="],
130
130
 
131
- "@tombi-toml/lib-linux-x64-musl": ["@tombi-toml/lib-linux-x64-musl@1.8.7", "", { "os": "linux", "cpu": "x64" }, "sha512-qCGCTnvQDFTl8osi+2H9XL7UplVRB87QynEojO8NKTyxId1imdh6zGZL5Kp1nWFwxMopQSFLTI73MgNlQhEoQA=="],
131
+ "@tombit/binding-linux-arm-musleabihf": ["@tombit/binding-linux-arm-musleabihf@0.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-pqq0H6zyV1RLHLLSv5f/5McZ6Kwc2sM426KJJEuN/hq6wwNQ/9wdPYif8HIfTbOs2OxXmDkTCMcbXRM2O9Zkyw=="],
132
132
 
133
- "@tombi-toml/lib-win32-arm64": ["@tombi-toml/lib-win32-arm64@1.8.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-0o8b71xe/HZ3b7Kxt5BQqPQyWXnLl+prJRSocuwQ0VX1zrCsyPpAaZgOYacshu9H0f2p9daGKSo8+GD4ra+vnw=="],
133
+ "@tombit/binding-linux-arm64-gnu": ["@tombit/binding-linux-arm64-gnu@0.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-NYdPD51rnPrwrQFk66vk6MDm1EdBzAgRtmk37IpGi2sRDCzemyFSk3D/E4mgMvk1eFzqACa4LBcjpfxCU/4Qzg=="],
134
134
 
135
- "@tombi-toml/lib-win32-x64": ["@tombi-toml/lib-win32-x64@1.8.7", "", { "os": "win32", "cpu": "x64" }, "sha512-6YX5dUS34zgapTy9vyLErqjS9wlhF/780m2gl9q5nJQGitzByMT4sqEsr9v6blOAfAeTlYU3cHyZq7qbBHixzA=="],
135
+ "@tombit/binding-linux-arm64-musl": ["@tombit/binding-linux-arm64-musl@0.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-VTTHJQVJHXAvbUqiAIZsDGBrW6wCXYk/XL4FR1XKFBLww1rAqaP1TNqk7Yf33IFnLFlPwZCiWB3E6b1usRGwEA=="],
136
+
137
+ "@tombit/binding-linux-loong64-gnu": ["@tombit/binding-linux-loong64-gnu@0.1.5", "", { "os": "linux", "cpu": "none" }, "sha512-6R2YxCBcA1PBT0aYBeXKDA8f7EY9h4flPlHUjpBDDW1mUDnJueJ78IlvmEogWA8mwg1C+jq+dMjC8tGR1L0tew=="],
138
+
139
+ "@tombit/binding-linux-loong64-musl": ["@tombit/binding-linux-loong64-musl@0.1.5", "", { "os": "linux", "cpu": "none" }, "sha512-Qh58HFWqQtfZvTuLMU3L0sjY2QWJ+4sY0m8EVYBxmHJzedFiWnm/eUULIzbS5GxDQ89J9TZTD0Ma0xaerlfwnw=="],
140
+
141
+ "@tombit/binding-linux-ppc64-gnu": ["@tombit/binding-linux-ppc64-gnu@0.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fI4BaLPZqm3hEMpVDR0atameS7WXP69pW+Se81+UL3c59v4kuZ9ezbUQxB0EtEwLilfq/Ia7boS699GhEHk41A=="],
142
+
143
+ "@tombit/binding-linux-ppc64-musl": ["@tombit/binding-linux-ppc64-musl@0.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-l0cIwDJvaVICrVuBxkc8/9MxPX7qXNvFqSUnIXIT/RvG9RVNiopG9yt4JOiIroxdd51UEpLO/rw1EyEH/KTtsg=="],
144
+
145
+ "@tombit/binding-linux-riscv64-gnu": ["@tombit/binding-linux-riscv64-gnu@0.1.5", "", { "os": "linux", "cpu": "none" }, "sha512-1cRv4TpoRWN+L3my+wab55EfQKnepo/1Xabv9g6wCjtgeKDqAUy9ALrD4Fg7rNtMCI214dU1EIEjlRyBJaZ0pw=="],
146
+
147
+ "@tombit/binding-linux-riscv64-musl": ["@tombit/binding-linux-riscv64-musl@0.1.5", "", { "os": "linux", "cpu": "none" }, "sha512-3YDRSyH15ZEcv5l8GyrUcvYuS2PNs2tAL/ZAcC24rofGwRvaorWLSgQ0NekZVrfNp/+4k+Pxam7sNDIIukhcgw=="],
148
+
149
+ "@tombit/binding-linux-s390x-gnu": ["@tombit/binding-linux-s390x-gnu@0.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-Gk/M/EF8uBZkcgD3maMSEVEQDuHsAPf2Bu4uLJgYQsftZZIEMsCnsYtIeH3WAmdizR5Wg+IcCOXBcmv71703NQ=="],
150
+
151
+ "@tombit/binding-linux-x64-gnu": ["@tombit/binding-linux-x64-gnu@0.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-aFz1BX46waZWrBYUappjHssrD3FL00IKuzk+kqFBhP9etdXZGTxDtnA5pa4+bDwVgHHzJYumEtwguSoH3VqvcA=="],
152
+
153
+ "@tombit/binding-linux-x64-musl": ["@tombit/binding-linux-x64-musl@0.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-PSUZqzy9tHkoBOFTiC6Vzv/RzuKo6D3rhgH8xWV91frPODC3zB/rR2KPxHv4n+meS9tCyKHiVEBJLTWxOGf3zA=="],
154
+
155
+ "@tombit/binding-openharmony-arm64": ["@tombit/binding-openharmony-arm64@0.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-ZGW6BjXimOBfWgvKQ+llJhOvKQONE6Q4hhYMvw6IUec+U+ScTnWGRckhfzuu3VSdPMH5vSPcvGlUlajMf9JB7A=="],
156
+
157
+ "@tombit/binding-openharmony-x64": ["@tombit/binding-openharmony-x64@0.1.5", "", { "os": "none", "cpu": "x64" }, "sha512-6+3JcVPYIbMfBgqTCZXkjQ9me9IpIoxHuJQGIvmAp7/QZBDhBihk8YF3uCX+t7ZB2ClDtIWXRaBaAJK2XPTYIg=="],
158
+
159
+ "@tombit/binding-win32-arm64-msvc": ["@tombit/binding-win32-arm64-msvc@0.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-30u9y6bONbeMsxpI2ikbtzfSZa5n/EG3jO1VTuNqz319obe9MK+3nj+BQz3avYLjDq5uMszCYSMm7yQK2vaYoA=="],
160
+
161
+ "@tombit/binding-win32-ia32-msvc": ["@tombit/binding-win32-ia32-msvc@0.1.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-fyrqcLVIjL0b+AXLK3gj+IQewbkYxihBJdG5k2INKgAzHB6kfBlf0/HtXTbPeqe72LYeAt/nBnX5IPfcpKqA8Q=="],
162
+
163
+ "@tombit/binding-win32-x64-msvc": ["@tombit/binding-win32-x64-msvc@0.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-EOIixNDdVxMgJzqViUXYzZIoXEteZvvftW+PxS5TSd+lCVMED2jW3R6uziYC61aY60hLBrhVFSs3J4MJ6DXv/A=="],
136
164
 
137
165
  "@tybys/wasm-util": ["@tybys/wasm-util@0.10.4", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A=="],
138
166
 
@@ -154,19 +182,19 @@
154
182
 
155
183
  "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
156
184
 
157
- "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.71.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.71.2", "@typescript-eslint/types": "^8.71.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw=="],
185
+ "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.72.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.72.0", "@typescript-eslint/types": "^8.72.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-bzHngBbmIgzj6TsTjVUCntGx6FFLgE7mPjpO0PzHycOaZHXqS43XnrkFIHRS16LLr/xO6FHSXG3GJFo/F4bSBQ=="],
158
186
 
159
- "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.71.2", "", { "dependencies": { "@typescript-eslint/types": "8.71.2", "@typescript-eslint/visitor-keys": "8.71.2" } }, "sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg=="],
187
+ "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.72.0", "", { "dependencies": { "@typescript-eslint/types": "8.72.0", "@typescript-eslint/visitor-keys": "8.72.0" } }, "sha512-JewPyJOYcXBSAS7PIgufscHOwZqhTGyBRiQJhhuDln66tMchxvvt7nJ90JKKIoOelmdHA3kAQbm9cEUHc4JSEA=="],
160
188
 
161
- "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.71.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg=="],
189
+ "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.72.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-0vbxCf7xLVPSjcOdm6eQbgViH8EDJ8xnl1laLT9yoqSz2YmcSfSg5Vdl0JUvZf6rcuJ0ZivJIuMD4edTg8obaA=="],
162
190
 
163
- "@typescript-eslint/types": ["@typescript-eslint/types@8.71.2", "", {}, "sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw=="],
191
+ "@typescript-eslint/types": ["@typescript-eslint/types@8.72.0", "", {}, "sha512-Adfoy59kxNEjT5E5fnyrp7GpHYuWs8ONbdohu4ez6IU46qDq8LltG90tLmkucZB2uhYL8mqBjtXqGd8yhfjXqQ=="],
164
192
 
165
- "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.71.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.71.2", "@typescript-eslint/tsconfig-utils": "8.71.2", "@typescript-eslint/types": "8.71.2", "@typescript-eslint/visitor-keys": "8.71.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA=="],
193
+ "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.72.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.72.0", "@typescript-eslint/tsconfig-utils": "8.72.0", "@typescript-eslint/types": "8.72.0", "@typescript-eslint/visitor-keys": "8.72.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-gwLfFgWcw15tN2KXDCJvxEOQjPn+P3j/n3eSqkZ5sX4VpW9Cosodr+tWwBZRvJT3TcKx6HnPRGZMCNAiP1Xhug=="],
166
194
 
167
- "@typescript-eslint/utils": ["@typescript-eslint/utils@8.71.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.71.2", "@typescript-eslint/types": "8.71.2", "@typescript-eslint/typescript-estree": "8.71.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw=="],
195
+ "@typescript-eslint/utils": ["@typescript-eslint/utils@8.72.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.72.0", "@typescript-eslint/types": "8.72.0", "@typescript-eslint/typescript-estree": "8.72.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-0up3oArJZBYnzOaEXKo8DmI43QvMZyPoFEt9LWzRJcyl/RcJjfKKPebknN1VbTgXBf3M/KggUh5uUMdURLnseg=="],
168
196
 
169
- "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.71.2", "", { "dependencies": { "@typescript-eslint/types": "8.71.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg=="],
197
+ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.72.0", "", { "dependencies": { "@typescript-eslint/types": "8.72.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-E2mroviasaWecDzTGiGMtuEguuLVOeRggnrIn93CJuxYJzQBHbyymlT08aVQydbBal5538o+JkBKXh2sRuCyIA=="],
170
198
 
171
199
  "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.12.2", "", { "os": "android", "cpu": "arm" }, "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w=="],
172
200
 
@@ -224,11 +252,11 @@
224
252
 
225
253
  "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
226
254
 
227
- "baseline-browser-mapping": ["baseline-browser-mapping@2.11.29", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-YeesxhUmR4h5y5V8KF8iBCqJb8YFrBJ++XBTeGcWIaQOYXGN19JM0FoiOjAhwuDoln8owMgXcWBmgHtYSkky2w=="],
255
+ "baseline-browser-mapping": ["baseline-browser-mapping@2.11.30", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA=="],
228
256
 
229
257
  "brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="],
230
258
 
231
- "browserslist": ["browserslist@4.29.3", "", { "dependencies": { "baseline-browser-mapping": "^2.11.26", "caniuse-lite": "^1.0.30001813", "electron-to-chromium": "^1.5.439", "node-releases": "^2.0.57", "update-browserslist-db": "^1.3.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA=="],
259
+ "browserslist": ["browserslist@4.29.4", "", { "dependencies": { "baseline-browser-mapping": "^2.11.29", "caniuse-lite": "^1.0.30001816", "electron-to-chromium": "^1.5.459", "node-releases": "^2.0.59", "update-browserslist-db": "^1.3.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA=="],
232
260
 
233
261
  "builtin-modules": ["builtin-modules@3.3.0", "", {}, "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw=="],
234
262
 
@@ -252,7 +280,7 @@
252
280
 
253
281
  "comment-parser": ["comment-parser@1.4.9", "", {}, "sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ=="],
254
282
 
255
- "core-js-compat": ["core-js-compat@3.50.0", "", { "dependencies": { "browserslist": "^4.28.7" } }, "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q=="],
283
+ "core-js-compat": ["core-js-compat@3.51.0", "", { "dependencies": { "browserslist": "^4.29.3" } }, "sha512-52r6fkXgxv4GLMjmFcMWRx7X9bw071xTTdrDcdyPGRqU2oE+9pCG0bAOMifSBdLw0JRBZKEF0q3B55qPlLuE8g=="],
256
284
 
257
285
  "core_d": ["core_d@6.1.1", "", { "dependencies": { "supports-color": "^8.1.0" } }, "sha512-96Pba8AFV6AjBwOz0PxHXkKm4CzmrNA2Im8NlPCsi70OefzgXxw3VDuKIMC18SXV1GF2oyNfIdh3w+JaNkSCCA=="],
258
286
 
@@ -400,7 +428,7 @@
400
428
 
401
429
  "identifier-regex": ["identifier-regex@1.1.0", "", { "dependencies": { "reserved-identifiers": "^1.0.0" } }, "sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA=="],
402
430
 
403
- "ignore": ["ignore@7.0.12", "", {}, "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg=="],
431
+ "ignore": ["ignore@7.0.13", "", {}, "sha512-2E8Q6rh+1RRSq/YdaGsNfXsEZy9FVqv6BSSrkmZJP7BnaoPnRfKL+YaofPvP+5rzdk144qSm6i4+hvPgUcbV4Q=="],
404
432
 
405
433
  "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
406
434
 
@@ -426,7 +454,7 @@
426
454
 
427
455
  "js-types": ["js-types@4.0.0", "", {}, "sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ=="],
428
456
 
429
- "jsdoc-type-pratt-parser": ["jsdoc-type-pratt-parser@9.2.3", "", { "dependencies": { "@types/estree": "^1.0.9" } }, "sha512-xsCb5EbmLWNlQ8v5zQIgSYSyf1rSyVPjh8p9G2xviOl1weHm8a611fHWUOGn7ISquCL6LoBKZvh0tcKmpVGgzw=="],
457
+ "jsdoc-type-pratt-parser": ["jsdoc-type-pratt-parser@9.3.0", "", { "dependencies": { "@types/estree": "^1.0.9" } }, "sha512-JZ8lKMCZXDlM1jAjAK5tTmtFJtgv6iFQQfjE3Fza6jBRACUueaEXLY17n1u05JO1lcPkNxgP+ddEDtiPsk5ktg=="],
430
458
 
431
459
  "jsesc": ["jsesc@3.1.0", "", { "bin": "bin/jsesc" }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
432
460
 
@@ -550,7 +578,7 @@
550
578
 
551
579
  "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
552
580
 
553
- "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": "lib/cli.js" }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="],
581
+ "napi-postinstall": ["napi-postinstall@0.3.5", "", { "bin": "./lib/cli.js" }, "sha512-NFMjXXkyodBJnRrM0A6qxFO1OLUbrYLDhP1ZLetlXnyx41gKOAmVyROibq85j7I8dda4aZMs9L7kmRvvjNf7Cg=="],
554
582
 
555
583
  "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
556
584
 
@@ -588,7 +616,7 @@
588
616
 
589
617
  "prettier-plugin-packagejson": ["prettier-plugin-packagejson@3.0.2", "", { "dependencies": { "sort-package-json": "^3.6.0" }, "peerDependencies": { "prettier": "^3" } }, "sha512-kmoj3hEynXwoHDo8ZhmWAIjRBoQWCDUVackiWfSDWdgD0rS3LGB61T9zoVbume/cotYdCoadUh4sqViAmXvpBQ=="],
590
618
 
591
- "prettier-plugin-toml": ["prettier-plugin-toml@4.0.0", "", { "dependencies": { "@tombi-toml/lib": "^1.8.4", "smol-toml": "^1.8.0" }, "peerDependencies": { "prettier": "^3.0.3" } }, "sha512-kx4a0gdNKH40/NOj/gSkiRKqXmOq8hXb6fNWW6Txd3T0fyq+Wq8ly0qtjNoGGiLUPhvS/3PIRVyVJpzHw6RNwA=="],
619
+ "prettier-plugin-toml": ["prettier-plugin-toml@4.1.0", "", { "dependencies": { "tombit": "^0.1.3" }, "peerDependencies": { "prettier": "^3.0.3" } }, "sha512-6+qgmRqD79kSsincO3odPzMpteTCpeP+WxxYmI7vDrhfpiQMFeciozuqUcnWc4XfJ97OZiuWeUfVcDktvACIDg=="],
592
620
 
593
621
  "prototype-properties": ["prototype-properties@5.1.0", "", {}, "sha512-lq/vK1+nYV/bbjZ70pDmaTzin143xX9hVAU5CrsNQL57A8j4Q6AfjsY8kRFoUpCBncaUdfkz9MdsQ8PFtiKrUQ=="],
594
622
 
@@ -622,8 +650,6 @@
622
650
 
623
651
  "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
624
652
 
625
- "smol-toml": ["smol-toml@1.9.1", "", {}, "sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ=="],
626
-
627
653
  "sort-object-keys": ["sort-object-keys@2.1.0", "", {}, "sha512-SOiEnthkJKPv2L6ec6HMwhUcN0/lppkeYuN1x63PbyPRrgSPIuBJCiYxYyvWRTtjMlOi14vQUCGUJqS6PLVm8g=="],
628
654
 
629
655
  "sort-package-json": ["sort-package-json@3.7.1", "", { "dependencies": { "detect-indent": "^7.0.2", "detect-newline": "^4.0.1", "git-hooks-list": "^4.1.1", "is-plain-obj": "^4.1.0", "semver": "^7.7.3", "sort-object-keys": "^2.0.1", "tinyglobby": "^0.2.15" }, "bin": { "sort-package-json": "cli.js" } }, "sha512-ssk1HG7whF8N/T1IsNAQrtHG5Cbdi0rAgRJZXYBr9hF5xaHnBNzUx/W6LcthEW7FhOwvZssbESZuO+GxssqAyA=="],
@@ -640,6 +666,8 @@
640
666
 
641
667
  "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
642
668
 
669
+ "tombit": ["tombit@0.1.5", "", { "dependencies": { "napi-postinstall": "^0.3.5" }, "optionalDependencies": { "@tombit/binding-android-arm-eabi": "0.1.5", "@tombit/binding-android-arm64": "0.1.5", "@tombit/binding-darwin-arm64": "0.1.5", "@tombit/binding-darwin-x64": "0.1.5", "@tombit/binding-freebsd-x64": "0.1.5", "@tombit/binding-linux-arm-gnueabihf": "0.1.5", "@tombit/binding-linux-arm-musleabihf": "0.1.5", "@tombit/binding-linux-arm64-gnu": "0.1.5", "@tombit/binding-linux-arm64-musl": "0.1.5", "@tombit/binding-linux-loong64-gnu": "0.1.5", "@tombit/binding-linux-loong64-musl": "0.1.5", "@tombit/binding-linux-ppc64-gnu": "0.1.5", "@tombit/binding-linux-ppc64-musl": "0.1.5", "@tombit/binding-linux-riscv64-gnu": "0.1.5", "@tombit/binding-linux-riscv64-musl": "0.1.5", "@tombit/binding-linux-s390x-gnu": "0.1.5", "@tombit/binding-linux-x64-gnu": "0.1.5", "@tombit/binding-linux-x64-musl": "0.1.5", "@tombit/binding-openharmony-arm64": "0.1.5", "@tombit/binding-openharmony-x64": "0.1.5", "@tombit/binding-win32-arm64-msvc": "0.1.5", "@tombit/binding-win32-ia32-msvc": "0.1.5", "@tombit/binding-win32-x64-msvc": "0.1.5" } }, "sha512-pVltqjGZroTsKoWBiUcGipnNJHIrtd0A5N/Joi9q4kWw9hQv03UcC5Bw2/3QXgLGtN5qFR8fp2ZReGcJoZA0pQ=="],
670
+
643
671
  "toml-eslint-parser": ["toml-eslint-parser@1.0.3", "", { "dependencies": { "eslint-visitor-keys": "^5.0.0" } }, "sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw=="],
644
672
 
645
673
  "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
@@ -43,6 +43,12 @@ version::
43
43
  fix-python:
44
44
  ./bin/fix-python.sh
45
45
 
46
+ .PHONY: fix-complexity
47
+ ## Refactor python functions over the complexity limit
48
+ ## @category Fix
49
+ fix-complexity:
50
+ ./bin/fix-complexity.sh
51
+
46
52
  .PHONY: fix
47
53
  ## Fix python lint errors
48
54
  ## @category Fix
@@ -732,6 +732,7 @@ class ComicboxOnlineLookup(ComicboxOnlineCovers):
732
732
  # config resolution started the run with.
733
733
  settings=replace(self._config, online=self._session_online()),
734
734
  triggered_hashing=any(c.cover_score is not None for c in candidates),
735
+ enrich_candidates=source.enrich_prompt_candidates,
735
736
  )
736
737
  with type(self)._PROMPT_LOCK: # noqa: SLF001 — class-level lock by design
737
738
  return selector(self._build_profile(), candidates, ctx)
@@ -28,6 +28,15 @@ class MangaEnum(Enum):
28
28
  UNKNOWN = "Unknown"
29
29
 
30
30
 
31
+ class SeriesStatusEnum(Enum):
32
+ """Publication status of a series, as Metron's Series.Status names it."""
33
+
34
+ ONGOING = "Ongoing"
35
+ CANCELLED = "Cancelled"
36
+ COMPLETED = "Completed"
37
+ HIATUS = "Hiatus"
38
+
39
+
31
40
  class IdSources(Enum):
32
41
  """
33
42
  Comic Database Namespace Identifiers.
@@ -8,7 +8,7 @@ from caseconverter import snakecase, titlecase
8
8
  from marshmallow import fields
9
9
  from typing_extensions import override
10
10
 
11
- from comicbox.enums.comicbox import MangaEnum, ReadingDirectionEnum
11
+ from comicbox.enums.comicbox import MangaEnum, ReadingDirectionEnum, SeriesStatusEnum
12
12
  from comicbox.enums.comicinfo import ComicInfoPageTypeEnum
13
13
  from comicbox.enums.maps.age_rating import AGE_RATING_ENUM_MAP
14
14
  from comicbox.enums.maps.formats import GENERIC_FORMAT_MAP
@@ -129,6 +129,12 @@ class ReadingDirectionField(EnumField):
129
129
  ENUM_ALIAS_MAP = READING_DIRECTION_ENUM_MAP
130
130
 
131
131
 
132
+ class SeriesStatusField(EnumField):
133
+ """Series publication status enum."""
134
+
135
+ ENUM = SeriesStatusEnum # pyright: ignore[reportIncompatibleUnannotatedOverride]
136
+
137
+
132
138
  class EnumBooleanField(EnumField):
133
139
  """An Enum Field that also accepts boolean values."""
134
140
 
@@ -73,6 +73,29 @@ class CandidateSummary:
73
73
  # larger tier than `cover_url` already is, which is what a frontend
74
74
  # keys "no hover" on.
75
75
  cover_url_full: str | None = None
76
+ # The fields below are display only, for telling apart candidates
77
+ # whose covers and titles read identically: the same issue in a
78
+ # reprint volume, a foreign edition, or a collected edition. No
79
+ # signal reads them. `series_publisher` is deliberately not
80
+ # `publisher`: `s_publisher` scores that one, and filling it would
81
+ # move every score.
82
+ #
83
+ # The year the series began ("Batman (2016)"). Metron's issue rows
84
+ # carry it; ComicVine's come from the volume row the two-step search
85
+ # already fetched, so its id-only paths leave it None.
86
+ series_start_year: int | None = None
87
+ # The series' publisher, its issue count and its publication format
88
+ # ("Trade Paperback", "One-Shot"). ComicVine fills the first two from
89
+ # the volume row and has no format. Metron fills all three only from
90
+ # `enrich_prompt_candidates`, which pays for a series lookup only
91
+ # when titles would otherwise collide.
92
+ series_publisher: str | None = None
93
+ series_issue_count: int | None = None
94
+ series_type: str | None = None
95
+ # The issue's own title and one-line description (ComicVine's
96
+ # `name` and `deck`). Metron's search rows carry neither.
97
+ issue_title: str | None = None
98
+ issue_summary: str | None = None
76
99
 
77
100
 
78
101
  @dataclass(frozen=True, slots=True)
@@ -11,7 +11,8 @@ Layout matches the Phase 4 spec:
11
11
  Existing: series=<...> issue=#<...> year=<...> publisher=<...>
12
12
 
13
13
  1. <series> #<issue> (<year>) score=<X> [<source>:<id>]
14
- publisher=<...>, pages=<...>, cover_date=<...>
14
+ publisher=<...>, format=<...>, started=<...>, issues=<...>, pages=<...>, year=<...>
15
+ "<issue title>" — <deck>
15
16
  <url>
16
17
  ...
17
18
 
@@ -47,7 +48,11 @@ if TYPE_CHECKING:
47
48
  from collections.abc import Sequence
48
49
 
49
50
  from comicbox.config.settings import ComicboxSettings
50
- from comicbox.formats.base.online.profile import Candidate, ComicProfile
51
+ from comicbox.formats.base.online.profile import (
52
+ Candidate,
53
+ CandidateSummary,
54
+ ComicProfile,
55
+ )
51
56
  from comicbox.formats.base.online.selector import SelectorContext, SelectorResult
52
57
 
53
58
 
@@ -76,17 +81,34 @@ def _format_candidate_line(idx: int, c: Candidate) -> str:
76
81
  return " ".join(parts)
77
82
 
78
83
 
84
+ def _format_detail_parts(s: CandidateSummary) -> list[str]:
85
+ # The series fields tell apart candidates whose titles read the same:
86
+ # a reprint volume, a foreign edition, a collected edition.
87
+ values = (
88
+ ("publisher", s.publisher or s.series_publisher),
89
+ ("format", s.series_type),
90
+ ("started", s.series_start_year),
91
+ ("issues", s.series_issue_count),
92
+ ("pages", s.page_count),
93
+ ("year", s.year),
94
+ )
95
+ return [f"{label}={value!r}" for label, value in values if value not in (None, "")]
96
+
97
+
98
+ def _format_title_line(s: CandidateSummary) -> str:
99
+ title = (
100
+ f"\N{LEFT DOUBLE QUOTATION MARK}{s.issue_title}\N{RIGHT DOUBLE QUOTATION MARK}"
101
+ )
102
+ parts = (title if s.issue_title else "", s.issue_summary or "")
103
+ return " \N{EM DASH} ".join(part for part in parts if part)
104
+
105
+
79
106
  def _format_aux_lines(c: Candidate) -> list[str]:
80
107
  aux: list[str] = []
81
- detail_parts: list[str] = []
82
- if c.summary.publisher:
83
- detail_parts.append(f"publisher={c.summary.publisher!r}")
84
- if c.summary.page_count is not None:
85
- detail_parts.append(f"pages={c.summary.page_count}")
86
- if c.summary.year is not None:
87
- detail_parts.append(f"year={c.summary.year}")
88
- if detail_parts:
108
+ if detail_parts := _format_detail_parts(c.summary):
89
109
  aux.append(" " + ", ".join(detail_parts))
110
+ if title_line := _format_title_line(c.summary):
111
+ aux.append(f" {title_line}")
90
112
  if c.url:
91
113
  aux.append(f" {c.url}")
92
114
  return aux
@@ -321,6 +343,9 @@ def cli_selector(
321
343
  aborts.
322
344
  """
323
345
  terse = _resolve_terse(ctx.settings)
346
+ if not terse:
347
+ # Only the aux lines show what enrichment adds; terse hides them.
348
+ candidates = ctx.enrich_candidates(candidates)
324
349
 
325
350
  while True:
326
351
  for line in _build_lines(profile, candidates, ctx.file_path, terse=terse):
@@ -62,6 +62,10 @@ class SelectorContext:
62
62
  source: str
63
63
  settings: ComicboxSettings
64
64
  triggered_hashing: bool
65
+ # The source's `enrich_prompt_candidates`. A selector calls it only
66
+ # once it knows the prompt will really be shown or deferred, so a
67
+ # prompt answered from cache spends nothing. Identity by default.
68
+ enrich_candidates: Callable[[Sequence[Candidate]], tuple[Candidate, ...]] = tuple
65
69
 
66
70
 
67
71
  SelectorCallback: TypeAlias = (
@@ -282,6 +282,24 @@ class OnlineSource(ABC):
282
282
  per-comic path, never fail the comic. Implementations own that.
283
283
  """
284
284
 
285
+ def enrich_prompt_candidates(
286
+ self, candidates: Sequence[Candidate]
287
+ ) -> tuple[Candidate, ...]:
288
+ """
289
+ Optionally add display detail to the candidates of a prompt.
290
+
291
+ Called only for a prompt that will really be shown or deferred,
292
+ never for one answered from the prompt cache, so a source may
293
+ spend a request here that it would not spend on every search.
294
+ It runs after ranking, so nothing it adds can move a score.
295
+
296
+ Must return the same candidates in the same order: a selector's
297
+ ``choose`` answer indexes into the tuple the box holds. Best-effort
298
+ like `prefetch_volume`: a failure degrades to the candidates as
299
+ given. The default returns them unchanged.
300
+ """
301
+ return tuple(candidates)
302
+
285
303
  # -- shared scaffolding ---------------------------------------------------
286
304
 
287
305
  def _resolve_response_cache(self) -> tuple[Path, dt.timedelta] | None:
@@ -116,7 +116,10 @@ SERIES_GROUPS_KEY = "series_groups"
116
116
  SERIES_ALTERNATIVE_NAMES_KEY = "alternative_names"
117
117
  ALTERNATIVE_NAMES_KEYPATH = f"{SERIES_KEY}.{SERIES_ALTERNATIVE_NAMES_KEY}"
118
118
  SERIES_SORT_NAME_KEY = "sort_name"
119
+ SERIES_END_YEAR_KEY = "end_year"
119
120
  SERIES_START_YEAR_KEY = "start_year"
121
+ SERIES_STATUS_KEY = "status"
122
+ SERIES_SUMMARY_KEY = "summary"
120
123
  STORE_DATE_KEY = "store_date"
121
124
  STORIES_KEY = "stories"
122
125
  TITLE_KEY = "title"
@@ -3,6 +3,7 @@
3
3
  from marshmallow.fields import Nested
4
4
 
5
5
  from comicbox.formats.base.fields.collection_fields import ListField
6
+ from comicbox.formats.base.fields.enum_fields import SeriesStatusField
6
7
  from comicbox.formats.base.fields.fields import StringField
7
8
  from comicbox.formats.base.fields.number_fields import DecimalField, IntegerField
8
9
  from comicbox.formats.base.fields.pycountry import LanguageField
@@ -31,8 +32,11 @@ class SeriesSchema(IdentifiedNameSchema):
31
32
  alternative_names = ListField( # Metron ONLY
32
33
  Nested(AlternativeNameSchema), sort_keys=("language", "name")
33
34
  )
35
+ end_year = IntegerField() # Metron API ONLY
34
36
  sort_name = StringField() # Metron ONLY
35
- start_year = IntegerField() # Metron ONLY
37
+ start_year = IntegerField() # Metron, ComicVine API
38
+ status = SeriesStatusField() # Metron API ONLY
39
+ summary = StringField() # Metron API, ComicVine API
36
40
  volume_count = IntegerField(minimum=0) # CBI, CT, Metron
37
41
 
38
42