subliminal 2.2.1__tar.gz → 2.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 (372) hide show
  1. {subliminal-2.2.1 → subliminal-2.4.0}/.dockerignore +0 -3
  2. subliminal-2.4.0/.github/actions/prepare-tests/action.yaml +62 -0
  3. subliminal-2.4.0/.github/workflows/CI.yaml +318 -0
  4. subliminal-2.4.0/.github/workflows/coverage.yaml +39 -0
  5. subliminal-2.4.0/.github/workflows/docker-build.yaml +103 -0
  6. subliminal-2.4.0/.github/workflows/prepare-release-pr.yaml +58 -0
  7. subliminal-2.4.0/.github/workflows/publish-release.yaml +82 -0
  8. subliminal-2.4.0/.github/workflows/publish.yaml +53 -0
  9. subliminal-2.4.0/.github/workflows/scheduled-tests.yaml +46 -0
  10. subliminal-2.4.0/.github/workflows/tag-release.yaml +108 -0
  11. subliminal-2.4.0/.github/zizmor.yml +13 -0
  12. subliminal-2.4.0/.gitignore +65 -0
  13. {subliminal-2.2.1 → subliminal-2.4.0}/.pre-commit-config.yaml +21 -6
  14. subliminal-2.4.0/.python-version-default +1 -0
  15. {subliminal-2.2.1 → subliminal-2.4.0}/.readthedocs.yaml +1 -0
  16. subliminal-2.4.0/CONTRIBUTING.md +201 -0
  17. {subliminal-2.2.1 → subliminal-2.4.0}/Dockerfile +9 -5
  18. subliminal-2.2.1/PKG-INFO → subliminal-2.4.0/HISTORY.rst +121 -137
  19. {subliminal-2.2.1 → subliminal-2.4.0}/MANIFEST.in +4 -0
  20. subliminal-2.4.0/PKG-INFO +208 -0
  21. subliminal-2.4.0/README.rst +136 -0
  22. subliminal-2.4.0/RELEASING.md +100 -0
  23. subliminal-2.4.0/changelog.d/.gitignore +1 -0
  24. {subliminal-2.2.1 → subliminal-2.4.0}/docs/Makefile +1 -1
  25. subliminal-2.4.0/docs/_intersphinx/README.md +82 -0
  26. subliminal-2.4.0/docs/_intersphinx/importlib_metadata_objects.inv +0 -0
  27. subliminal-2.4.0/docs/_intersphinx/importlib_metadata_objects.txt +6 -0
  28. subliminal-2.4.0/docs/_static/.gitignore +1 -0
  29. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/cache.rst +2 -1
  30. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/providers.rst +10 -7
  31. {subliminal-2.2.1 → subliminal-2.4.0}/docs/cassettes/test_usage.yaml +206 -162
  32. {subliminal-2.2.1 → subliminal-2.4.0}/docs/conf.py +19 -9
  33. {subliminal-2.2.1 → subliminal-2.4.0}/docs/config.toml +3 -1
  34. {subliminal-2.2.1 → subliminal-2.4.0}/docs/conftest.py +8 -5
  35. {subliminal-2.2.1 → subliminal-2.4.0}/docs/index.rst +8 -0
  36. {subliminal-2.2.1 → subliminal-2.4.0}/docs/make.bat +1 -1
  37. subliminal-2.4.0/docs/user/changelog.rst +7 -0
  38. {subliminal-2.2.1 → subliminal-2.4.0}/docs/user/cli.rst +4 -0
  39. subliminal-2.4.0/docs/user/configuration_file.rst +44 -0
  40. {subliminal-2.2.1 → subliminal-2.4.0}/docs/user/how_it_works.rst +11 -9
  41. subliminal-2.4.0/docs/user/installation.rst +30 -0
  42. {subliminal-2.2.1 → subliminal-2.4.0}/docs/user/provider_guide.rst +2 -2
  43. {subliminal-2.2.1 → subliminal-2.4.0}/docs/user/usage.rst +58 -13
  44. subliminal-2.4.0/hatch.toml +128 -0
  45. {subliminal-2.2.1 → subliminal-2.4.0}/pyproject.toml +142 -69
  46. subliminal-2.4.0/scripts/.gitignore +1 -0
  47. subliminal-2.4.0/scripts/prepare-release-pr.py +193 -0
  48. subliminal-2.4.0/scripts/prepare_tests.py +137 -0
  49. subliminal-2.4.0/scripts/release.py +148 -0
  50. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/__init__.py +23 -17
  51. subliminal-2.4.0/src/subliminal/__main__.py +26 -0
  52. subliminal-2.4.0/src/subliminal/archives.py +139 -0
  53. subliminal-2.4.0/src/subliminal/cli/__init__.py +6 -0
  54. subliminal-2.4.0/src/subliminal/cli/cli.py +241 -0
  55. subliminal-2.4.0/src/subliminal/cli/commands/__init__.py +5 -0
  56. subliminal-2.4.0/src/subliminal/cli/commands/_format.py +63 -0
  57. subliminal-2.4.0/src/subliminal/cli/commands/download_best.py +632 -0
  58. subliminal-2.4.0/src/subliminal/cli/generate_config.py +131 -0
  59. subliminal-2.4.0/src/subliminal/cli/helpers.py +230 -0
  60. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/converters/__init__.py +1 -1
  61. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/converters/addic7ed.py +20 -22
  62. subliminal-2.4.0/src/subliminal/converters/opensubtitles.py +77 -0
  63. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/converters/opensubtitlescom.py +8 -8
  64. subliminal-2.4.0/src/subliminal/converters/subtitulamos.py +69 -0
  65. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/converters/tvsubtitles.py +8 -10
  66. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/core.py +238 -127
  67. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/exceptions.py +22 -4
  68. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/extensions.py +30 -10
  69. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/matches.py +31 -5
  70. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/__init__.py +25 -18
  71. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/addic7ed.py +44 -36
  72. subliminal-2.4.0/src/subliminal/providers/bsplayer.py +364 -0
  73. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/gestdown.py +3 -3
  74. subliminal-2.4.0/src/subliminal/providers/mock.py +214 -0
  75. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/napiprojekt.py +18 -3
  76. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/opensubtitles.py +12 -18
  77. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/opensubtitlescom.py +28 -8
  78. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/podnapisi.py +4 -4
  79. subliminal-2.4.0/src/subliminal/providers/subtitulamos.py +348 -0
  80. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/providers/tvsubtitles.py +4 -4
  81. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/refiners/hash.py +18 -66
  82. subliminal-2.4.0/src/subliminal/refiners/metadata.py +211 -0
  83. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/refiners/omdb.py +43 -35
  84. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/refiners/tmdb.py +10 -5
  85. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/refiners/tvdb.py +20 -10
  86. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/score.py +74 -97
  87. subliminal-2.4.0/src/subliminal/subtitle.py +899 -0
  88. subliminal-2.4.0/src/subliminal/utils.py +399 -0
  89. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/video.py +67 -43
  90. subliminal-2.4.0/tests/__init__.py +0 -0
  91. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_download_subtitle.yaml +1968 -1869
  92. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_get_show_id.yaml +1956 -1855
  93. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_get_show_id_country.yaml +1956 -1855
  94. subliminal-2.2.1/tests/cassettes/addic7ed/test_get_show_id_with_comma.yaml → subliminal-2.4.0/tests/cassettes/addic7ed/test_get_show_id_quote_dots_mixed_case.yaml +1955 -1853
  95. subliminal-2.2.1/tests/cassettes/addic7ed/test_get_show_ids.yaml → subliminal-2.4.0/tests/cassettes/addic7ed/test_get_show_id_with_comma.yaml +1956 -1854
  96. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_get_show_id_year.yaml +1956 -1855
  97. subliminal-2.2.1/tests/cassettes/addic7ed/test_get_show_id_quote_dots_mixed_case.yaml → subliminal-2.4.0/tests/cassettes/addic7ed/test_get_show_ids.yaml +1955 -1853
  98. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_list_subtitles.yaml +1965 -1861
  99. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_list_subtitles_episode_alternative_series.yaml +3922 -4076
  100. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_list_subtitles_show_with_asterisk.yaml +3922 -4076
  101. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query.yaml +1961 -1859
  102. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_no_year.yaml +1965 -1861
  103. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_parsing.yaml +1965 -1861
  104. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_parsing_colon.yaml +1965 -1863
  105. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_parsing_dash.yaml +1963 -1863
  106. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_parsing_quote_dots_mixed_case.yaml +8 -7
  107. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_wrong_series.yaml +8 -7
  108. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/addic7ed/test_query_year.yaml +1961 -1859
  109. subliminal-2.4.0/tests/cassettes/bsplayer/test_download_subtitle.yaml +1356 -0
  110. subliminal-2.4.0/tests/cassettes/bsplayer/test_list_subtitles_hash.yaml +197 -0
  111. subliminal-2.4.0/tests/cassettes/bsplayer/test_login.yaml +55 -0
  112. subliminal-2.4.0/tests/cassettes/bsplayer/test_logout.yaml +107 -0
  113. subliminal-2.4.0/tests/cassettes/bsplayer/test_query_hash_size.yaml +353 -0
  114. subliminal-2.4.0/tests/cassettes/cli/test_cli_download.yaml +767 -0
  115. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_download_subtitle.yaml +36 -27
  116. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_download_with_bom.yaml +33 -30
  117. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_get_title_and_show_id_alternative_name.yaml +28 -20
  118. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_get_title_and_show_id_no_year.yaml +15 -12
  119. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_get_title_and_show_id_only_title.yaml +14 -11
  120. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_get_title_and_show_id_with_tvdb_id.yaml +11 -8
  121. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_list_subtitles.yaml +39 -34
  122. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_list_subtitles_episode_alternative_series.yaml +36 -27
  123. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query.yaml +28 -22
  124. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_all_series.yaml +45 -39
  125. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_no_language.yaml +15 -12
  126. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_parsing.yaml +29 -21
  127. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_parsing_colon.yaml +25 -19
  128. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_parsing_dash.yaml +24 -18
  129. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_parsing_quote_dots_mixed_case.yaml +26 -20
  130. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_query_wrong_series.yaml +10 -8
  131. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_id.yaml +11 -8
  132. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_id_error.yaml +10 -7
  133. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_id_incomplete.yaml +12 -9
  134. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_id_no_year.yaml +13 -10
  135. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_id_quote.yaml +13 -10
  136. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_search_show_series_tvdb_id.yaml +15 -12
  137. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/gestdown/test_show_with_asterisk.yaml +38 -33
  138. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/napiprojekt/test_download_subtitles.yaml +7 -9
  139. subliminal-2.4.0/tests/cassettes/napiprojekt/test_list_subtitles.yaml +863 -0
  140. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/napiprojekt/test_query_microdvd.yaml +6 -8
  141. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/napiprojekt/test_query_srt.yaml +6 -8
  142. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/napiprojekt/test_query_srt_reencode.yaml +6 -8
  143. subliminal-2.4.0/tests/cassettes/napiprojekt/test_query_wrong_hash.yaml +40 -0
  144. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_get_id.yaml +9 -10
  145. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_get_title.yaml +9 -10
  146. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_get_wrong_id.yaml +8 -8
  147. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_get_wrong_title.yaml +6 -6
  148. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_episode.yaml +9 -9
  149. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_episode_original_series.yaml +112 -61
  150. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_episode_with_country_hoc_us.yaml +1 -0
  151. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_episode_year.yaml +8 -8
  152. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_search.yaml +10 -10
  153. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_search_page.yaml +12 -12
  154. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_search_type.yaml +10 -10
  155. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_search_wrong_title.yaml +6 -6
  156. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_search_year.yaml +9 -9
  157. subliminal-2.4.0/tests/cassettes/opensubtitles/test_download_subtitle.yaml +751 -0
  158. subliminal-2.4.0/tests/cassettes/opensubtitles/test_list_subtitles_episode.yaml +458 -0
  159. subliminal-2.4.0/tests/cassettes/opensubtitles/test_list_subtitles_movie.yaml +647 -0
  160. subliminal-2.4.0/tests/cassettes/opensubtitles/test_list_subtitles_movie_no_hash.yaml +439 -0
  161. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_login_bad_password.yaml +20 -23
  162. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_login_vip_bad_password.yaml +21 -24
  163. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_login_vip_login.yaml +21 -24
  164. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_no_operation.yaml +87 -94
  165. subliminal-2.4.0/tests/cassettes/opensubtitles/test_query_hash_size.yaml +458 -0
  166. subliminal-2.4.0/tests/cassettes/opensubtitles/test_query_imdb_id.yaml +431 -0
  167. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_query_not_enough_information.yaml +66 -70
  168. subliminal-2.4.0/tests/cassettes/opensubtitles/test_query_query_episode.yaml +429 -0
  169. subliminal-2.4.0/tests/cassettes/opensubtitles/test_query_query_movie.yaml +448 -0
  170. subliminal-2.4.0/tests/cassettes/opensubtitles/test_query_query_season_episode.yaml +432 -0
  171. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitles/test_query_wrong_hash_wrong_size.yaml +89 -94
  172. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_download_subtitle.yaml +391 -320
  173. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_episode.yaml +109 -67
  174. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie.yaml +313 -230
  175. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie_no_hash.yaml +46 -24
  176. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_login.yaml +20 -20
  177. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_login_bad_password.yaml +20 -20
  178. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_logout.yaml +23 -21
  179. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_query_hash_size.yaml +80 -56
  180. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_query_imdb_id.yaml +70 -46
  181. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_query_query_episode.yaml +138 -102
  182. subliminal-2.4.0/tests/cassettes/opensubtitlescom/test_query_query_movie.yaml +195 -0
  183. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_query_query_season_episode.yaml +99 -57
  184. subliminal-2.4.0/tests/cassettes/opensubtitlescom/test_query_tag_movie.yaml +184 -0
  185. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_query_wrong_hash_wrong_size.yaml +51 -19
  186. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_tag_match.yaml +182 -116
  187. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/opensubtitlescom/test_user_infos.yaml +37 -37
  188. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/podnapisi/test_download_subtitle.yaml +393 -407
  189. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/podnapisi/test_download_subtitles_with_title_unicode.yaml +8 -8
  190. subliminal-2.4.0/tests/cassettes/podnapisi/test_list_subtitles_episode.yaml +488 -0
  191. subliminal-2.4.0/tests/cassettes/podnapisi/test_list_subtitles_episode_alternative_series.yaml +349 -0
  192. subliminal-2.4.0/tests/cassettes/podnapisi/test_list_subtitles_movie.yaml +424 -0
  193. subliminal-2.4.0/tests/cassettes/podnapisi/test_query_episode.yaml +161 -0
  194. subliminal-2.4.0/tests/cassettes/podnapisi/test_query_movie.yaml +344 -0
  195. {subliminal-2.2.1/tests/cassettes/core → subliminal-2.4.0/tests/cassettes/providers}/test_download_best_subtitles.yaml +62 -49
  196. subliminal-2.4.0/tests/cassettes/providers/test_download_best_subtitles_min_score.yaml +118 -0
  197. {subliminal-2.2.1/tests/cassettes/core → subliminal-2.4.0/tests/cassettes/providers}/test_download_best_subtitles_only_one.yaml +70 -64
  198. subliminal-2.4.0/tests/cassettes/providers/test_list_subtitles_providers_download.yaml +13063 -0
  199. subliminal-2.4.0/tests/cassettes/subtitulamos/test_download_subtitle.yaml +2013 -0
  200. subliminal-2.4.0/tests/cassettes/subtitulamos/test_download_subtitle_first_episode.yaml +1882 -0
  201. subliminal-2.4.0/tests/cassettes/subtitulamos/test_download_subtitle_foo.yaml +1952 -0
  202. subliminal-2.4.0/tests/cassettes/subtitulamos/test_download_subtitle_last_season.yaml +1952 -0
  203. subliminal-2.4.0/tests/cassettes/subtitulamos/test_download_subtitle_year.yaml +1882 -0
  204. subliminal-2.4.0/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_episode.yaml +837 -0
  205. subliminal-2.4.0/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_language.yaml +1071 -0
  206. subliminal-2.4.0/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_season.yaml +618 -0
  207. subliminal-2.4.0/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_series.yaml +114 -0
  208. subliminal-2.4.0/tests/cassettes/subtitulamos/test_list_subtitles_with_spanish_non_mx_search.yaml +1568 -0
  209. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_get_movie_id.yaml +55 -55
  210. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_get_movie_id_failed.yaml +10 -10
  211. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_get_series_id.yaml +17 -18
  212. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_get_series_wrong_id.yaml +9 -11
  213. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_episode.yaml +73 -75
  214. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_episode_original_series.yaml +94 -97
  215. subliminal-2.4.0/tests/cassettes/tmdb/test_refine_episode_with_country.yaml +345 -0
  216. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_episode_with_country_hoc_us.yaml +63 -65
  217. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_episode_year.yaml +49 -49
  218. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_movie.yaml +69 -73
  219. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_refine_movie_guess_alternative_title.yaml +39 -34
  220. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_movie.yaml +55 -57
  221. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_movie_page.yaml +51 -53
  222. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_movie_wrong_title.yaml +10 -12
  223. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_movie_year.yaml +15 -17
  224. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_series.yaml +17 -20
  225. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tmdb/test_search_series_wrong_name.yaml +10 -12
  226. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_get_series.yaml +17 -17
  227. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_get_series_actors.yaml +15 -15
  228. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_get_series_actors_wrong_id.yaml +14 -14
  229. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_get_series_wrong_id.yaml +14 -14
  230. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_login.yaml +7 -7
  231. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_login_error.yaml +6 -6
  232. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_query_series_episodes.yaml +17 -17
  233. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_query_series_episodes_wrong_season.yaml +14 -14
  234. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine.yaml +47 -46
  235. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_ambiguous.yaml +101 -59
  236. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_ambiguous_2.yaml +171 -126
  237. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_alternative_series.yaml +81 -39
  238. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_no_year.yaml +153 -74
  239. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_partial.yaml +139 -78
  240. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_with_comma.yaml +83 -39
  241. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_with_country.yaml +124 -68
  242. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_with_country_hoc_us.yaml +83 -35
  243. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refine_episode_year.yaml +149 -73
  244. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_refresh_token.yaml +15 -15
  245. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_search_series.yaml +17 -16
  246. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_search_series_wrong_name.yaml +14 -14
  247. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvdb/test_token_needs_refresh.yaml +7 -7
  248. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_download_subtitle.yaml +408 -473
  249. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_download_subtitle_with_quote.yaml +359 -393
  250. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_get_episode_ids.yaml +141 -156
  251. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_get_episode_ids_wrong_season.yaml +98 -111
  252. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_list_subtitles.yaml +399 -464
  253. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_list_subtitles_episode_alternative_series.yaml +409 -456
  254. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_query.yaml +398 -463
  255. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_query_no_year.yaml +288 -328
  256. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_query_with_quote.yaml +344 -378
  257. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_query_wrong_episode.yaml +240 -293
  258. subliminal-2.4.0/tests/cassettes/tvsubtitles/test_query_wrong_series.yaml +206 -0
  259. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id.yaml +85 -98
  260. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_ambiguous.yaml +182 -186
  261. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_error.yaml +86 -99
  262. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_incomplete.yaml +85 -99
  263. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_no_year.yaml +85 -98
  264. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_uk.yaml +85 -98
  265. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_us.yaml +129 -106
  266. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/tvsubtitles/test_search_show_id_year_in_title.yaml +85 -98
  267. subliminal-2.4.0/tests/cli/test_cli.py +32 -0
  268. subliminal-2.4.0/tests/cli/test_download.py +485 -0
  269. subliminal-2.4.0/tests/cli/test_generate_config.py +33 -0
  270. subliminal-2.4.0/tests/cli/test_helpers.py +95 -0
  271. subliminal-2.4.0/tests/conftest.py +974 -0
  272. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_addic7ed.py +111 -109
  273. subliminal-2.4.0/tests/providers/test_bsplayer.py +134 -0
  274. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_gestdown.py +58 -56
  275. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_napiprojekt.py +22 -16
  276. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_opensubtitles.py +61 -49
  277. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_opensubtitlescom.py +46 -44
  278. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_podnapisi.py +21 -19
  279. subliminal-2.4.0/tests/providers/test_providers.py +373 -0
  280. subliminal-2.4.0/tests/providers/test_subtitulamos.py +312 -0
  281. {subliminal-2.2.1 → subliminal-2.4.0}/tests/providers/test_tvsubtitles.py +57 -55
  282. subliminal-2.4.0/tests/refiners/test_hash.py +58 -0
  283. subliminal-2.4.0/tests/refiners/test_metadata.py +143 -0
  284. {subliminal-2.2.1 → subliminal-2.4.0}/tests/refiners/test_omdb.py +55 -52
  285. {subliminal-2.2.1 → subliminal-2.4.0}/tests/refiners/test_tmdb.py +42 -41
  286. {subliminal-2.2.1 → subliminal-2.4.0}/tests/refiners/test_tvdb.py +57 -56
  287. subliminal-2.4.0/tests/test_archives.py +98 -0
  288. {subliminal-2.2.1 → subliminal-2.4.0}/tests/test_cache.py +11 -7
  289. subliminal-2.4.0/tests/test_core.py +481 -0
  290. {subliminal-2.2.1 → subliminal-2.4.0}/tests/test_extensions.py +64 -11
  291. {subliminal-2.2.1 → subliminal-2.4.0}/tests/test_matches.py +22 -38
  292. {subliminal-2.2.1 → subliminal-2.4.0}/tests/test_provider.py +12 -8
  293. subliminal-2.4.0/tests/test_provider_pool.py +575 -0
  294. subliminal-2.4.0/tests/test_score.py +124 -0
  295. subliminal-2.4.0/tests/test_subtitle.py +672 -0
  296. subliminal-2.4.0/tests/test_utils.py +296 -0
  297. {subliminal-2.2.1 → subliminal-2.4.0}/tests/test_video.py +100 -26
  298. subliminal-2.4.0/tox.ini +133 -0
  299. subliminal-2.2.1/CONTRIBUTING.md +0 -19
  300. subliminal-2.2.1/HISTORY.rst +0 -373
  301. subliminal-2.2.1/README.rst +0 -89
  302. subliminal-2.2.1/setup.cfg +0 -4
  303. subliminal-2.2.1/subliminal/cli.py +0 -602
  304. subliminal-2.2.1/subliminal/converters/shooter.py +0 -37
  305. subliminal-2.2.1/subliminal/converters/thesubdb.py +0 -50
  306. subliminal-2.2.1/subliminal/refiners/metadata.py +0 -113
  307. subliminal-2.2.1/subliminal/subtitle.py +0 -478
  308. subliminal-2.2.1/subliminal/utils.py +0 -183
  309. subliminal-2.2.1/subliminal.egg-info/PKG-INFO +0 -526
  310. subliminal-2.2.1/subliminal.egg-info/SOURCES.txt +0 -268
  311. subliminal-2.2.1/subliminal.egg-info/dependency_links.txt +0 -1
  312. subliminal-2.2.1/subliminal.egg-info/entry_points.txt +0 -26
  313. subliminal-2.2.1/subliminal.egg-info/requires.txt +0 -40
  314. subliminal-2.2.1/subliminal.egg-info/top_level.txt +0 -1
  315. subliminal-2.2.1/tests/cassettes/addic7ed/test_login.yaml +0 -60
  316. subliminal-2.2.1/tests/cassettes/addic7ed/test_logout.yaml +0 -61
  317. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id.yaml +0 -637
  318. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id_error.yaml +0 -120
  319. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id_incomplete.yaml +0 -640
  320. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id_no_year.yaml +0 -584
  321. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id_quote.yaml +0 -611
  322. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_id_year.yaml +0 -311
  323. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_ids_quote_dots_mixed_case.yaml +0 -634
  324. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_ids_with_comma.yaml +0 -287
  325. subliminal-2.2.1/tests/cassettes/addic7ed/test_search_show_ids_with_country.yaml +0 -826
  326. subliminal-2.2.1/tests/cassettes/core/test_download_bad_subtitle.yaml +0 -790
  327. subliminal-2.2.1/tests/cassettes/core/test_download_best_subtitles_min_score.yaml +0 -116
  328. subliminal-2.2.1/tests/cassettes/napiprojekt/test_list_subtitles.yaml +0 -439
  329. subliminal-2.2.1/tests/cassettes/napiprojekt/test_query_wrong_hash.yaml +0 -43
  330. subliminal-2.2.1/tests/cassettes/opensubtitles/test_download_subtitle.yaml +0 -1370
  331. subliminal-2.2.1/tests/cassettes/opensubtitles/test_list_subtitles_episode.yaml +0 -473
  332. subliminal-2.2.1/tests/cassettes/opensubtitles/test_list_subtitles_movie.yaml +0 -689
  333. subliminal-2.2.1/tests/cassettes/opensubtitles/test_list_subtitles_movie_no_hash.yaml +0 -458
  334. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_hash_size.yaml +0 -474
  335. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_imdb_id.yaml +0 -452
  336. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_query_episode.yaml +0 -446
  337. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_query_movie.yaml +0 -471
  338. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_query_season_episode.yaml +0 -450
  339. subliminal-2.2.1/tests/cassettes/opensubtitles/test_query_tag_movie.yaml +0 -414
  340. subliminal-2.2.1/tests/cassettes/opensubtitles/test_tag_match.yaml +0 -532
  341. subliminal-2.2.1/tests/cassettes/opensubtitlescom/test_query_query_movie.yaml +0 -173
  342. subliminal-2.2.1/tests/cassettes/opensubtitlescom/test_query_tag_movie.yaml +0 -164
  343. subliminal-2.2.1/tests/cassettes/podnapisi/test_list_subtitles_episode.yaml +0 -515
  344. subliminal-2.2.1/tests/cassettes/podnapisi/test_list_subtitles_episode_alternative_series.yaml +0 -367
  345. subliminal-2.2.1/tests/cassettes/podnapisi/test_list_subtitles_movie.yaml +0 -438
  346. subliminal-2.2.1/tests/cassettes/podnapisi/test_query_episode.yaml +0 -174
  347. subliminal-2.2.1/tests/cassettes/podnapisi/test_query_movie.yaml +0 -362
  348. subliminal-2.2.1/tests/cassettes/tmdb/test_refine_episode_with_country.yaml +0 -302
  349. subliminal-2.2.1/tests/cassettes/tvsubtitles/test_query_wrong_series.yaml +0 -219
  350. subliminal-2.2.1/tests/conftest.py +0 -492
  351. subliminal-2.2.1/tests/refiners/test_hash.py +0 -19
  352. subliminal-2.2.1/tests/test_core.py +0 -704
  353. subliminal-2.2.1/tests/test_score.py +0 -142
  354. subliminal-2.2.1/tests/test_subtitle.py +0 -163
  355. subliminal-2.2.1/tests/test_utils.py +0 -5
  356. subliminal-2.2.1/tox.ini +0 -7
  357. {subliminal-2.2.1 → subliminal-2.4.0}/LICENSE +0 -0
  358. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/cli.rst +0 -0
  359. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/core.rst +0 -0
  360. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/exceptions.rst +0 -0
  361. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/extensions.rst +0 -0
  362. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/refiners.rst +0 -0
  363. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/score.rst +0 -0
  364. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/subtitle.rst +0 -0
  365. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/utils.rst +0 -0
  366. {subliminal-2.2.1 → subliminal-2.4.0}/docs/api/video.rst +0 -0
  367. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/cache.py +0 -0
  368. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/py.typed +0 -0
  369. {subliminal-2.2.1 → subliminal-2.4.0/src}/subliminal/refiners/__init__.py +0 -0
  370. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_episode_with_country.yaml +0 -0
  371. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_movie.yaml +0 -0
  372. {subliminal-2.2.1 → subliminal-2.4.0}/tests/cassettes/omdb/test_refine_movie_guess_alternative_title.yaml +0 -0
@@ -1,6 +1,3 @@
1
- # SCM
2
- .git/
3
-
4
1
  # Byte-compiled / optimized / DLL files
5
2
  __pycache__/
6
3
  *.py[cod]
@@ -0,0 +1,62 @@
1
+ name: 'Download data for tests'
2
+ description: 'Download .mkv and compress them with rar to be used in tests.'
3
+
4
+ runs:
5
+ using: "composite"
6
+ steps:
7
+ - name: Check Runner OS
8
+ if: ${{ runner.os != 'Linux' && runner.os != 'Windows' && runner.os != 'macOS'}}
9
+ shell: bash
10
+ run: |
11
+ echo "::error title=⛔ error hint::Support Linux, Windows, and macOS Only"
12
+ exit 1
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ persist-credentials: false
16
+ fetch-depth: 0
17
+ - name: Cache test data
18
+ id: cache-test-data
19
+ uses: actions/cache@v4
20
+ with:
21
+ path: tests/data/
22
+ enableCrossOsArchive: true
23
+ key: prepare-tests
24
+
25
+ - name: Download only from Linux Runner OS
26
+ if: ${{ steps.cache-test-data.outputs.cache-hit != 'true' && runner.os != 'Linux' }}
27
+ shell: bash
28
+ run: |
29
+ echo "::error title=⛔ error hint::Download cache only from Linux: ${{ runner.os }}."
30
+ exit 1
31
+ - name: Install other test software (on Linux only)
32
+ if: steps.cache-test-data.outputs.cache-hit != 'true'
33
+ uses: awalsh128/cache-apt-pkgs-action@v1
34
+ with:
35
+ packages: rar
36
+ version: 1.0
37
+ - uses: actions/setup-python@v5
38
+ if: steps.cache-test-data.outputs.cache-hit != 'true'
39
+ with:
40
+ python-version-file: .python-version-default
41
+ cache: pip
42
+ - name: Install dependencies
43
+ if: steps.cache-test-data.outputs.cache-hit != 'true'
44
+ shell: bash
45
+ run: |
46
+ python -Im pip install --upgrade pip
47
+ python -Im pip install tox requests
48
+ - name: Download tests data
49
+ if: steps.cache-test-data.outputs.cache-hit != 'true'
50
+ shell: bash
51
+ run: |
52
+ tox -e prepare-tests
53
+
54
+ # - name: Upload files for test
55
+ # uses: actions/upload-artifact@v4
56
+ # with:
57
+ # name: tests-data
58
+ # path: tests/data/
59
+ # include-hidden-files: false
60
+ # if-no-files-found: error
61
+ # # heavy artifact should be deleted asap
62
+ # retention-days: 1
@@ -0,0 +1,318 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+
8
+ permissions: {}
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ env:
15
+ FORCE_COLOR: "1"
16
+ PIP_DISABLE_PIP_VERSION_CHECK: "1"
17
+ PIP_NO_PYTHON_VERSION_WARNING: "1"
18
+
19
+ jobs:
20
+ check-manifest:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ persist-credentials: false
26
+ - run: pipx run check-manifest --ignore "_version.py"
27
+
28
+ pre-commit:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+ with:
33
+ persist-credentials: false
34
+ - uses: actions/setup-python@v5
35
+ with:
36
+ python-version-file: .python-version-default
37
+ - uses: pre-commit/action@v3.0.1
38
+
39
+ typing:
40
+ runs-on: ubuntu-latest
41
+ permissions:
42
+ contents: read
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ with:
46
+ persist-credentials: false
47
+ - uses: actions/setup-python@v5
48
+ with:
49
+ python-version-file: .python-version-default
50
+ - name: Install hatch
51
+ run: python -Im pip install hatch
52
+ - name: Setup types environment
53
+ run: hatch -v env create types
54
+ - name: Type check
55
+ run: hatch run types:run
56
+
57
+ docs:
58
+ name: Build docs and run doctests
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - uses: actions/checkout@v4
62
+ with:
63
+ persist-credentials: false
64
+ - uses: actions/setup-python@v5
65
+ with:
66
+ # Keep in sync with tox/docs, hatch.toml and .readthedocs.yaml.
67
+ python-version-file: .python-version-default
68
+ cache: pip
69
+
70
+ - name: Install hatch
71
+ run: python -Im pip install hatch
72
+ - name: Build and check docs
73
+ run: hatch run docs:run
74
+ - name: Run doctests
75
+ run: hatch run docs:doctest
76
+ - name: Check changelog
77
+ run: hatch run changelog:run
78
+
79
+ - uses: actions/upload-artifact@v4
80
+ with:
81
+ name: docs
82
+ path: docs/_build/
83
+
84
+ install-dev:
85
+ name: Verify install env
86
+ runs-on: ubuntu-latest
87
+
88
+ steps:
89
+ - uses: actions/checkout@v4
90
+ with:
91
+ persist-credentials: false
92
+ - uses: actions/setup-python@v5
93
+ with:
94
+ python-version-file: .python-version-default
95
+ cache: pip
96
+
97
+ - name: Install in dev mode & import
98
+ run: |
99
+ python -Im pip install -e .[dev]
100
+ python -Ic 'import subliminal; print(subliminal.__version__)'
101
+
102
+ build-package:
103
+ name: Build & verify package
104
+ runs-on: ubuntu-latest
105
+
106
+ steps:
107
+ - uses: actions/checkout@v4
108
+ with:
109
+ persist-credentials: false
110
+ fetch-depth: 0
111
+
112
+ - uses: hynek/build-and-inspect-python-package@v2
113
+ id: baipp
114
+
115
+ outputs:
116
+ # Used to define the matrix for tests below. The value is based on
117
+ # packaging metadata (trove classifiers).
118
+ supported-python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
119
+
120
+ prepare-test:
121
+ name: Download data for tests
122
+ runs-on: ubuntu-latest
123
+
124
+ steps:
125
+ - uses: actions/checkout@v4
126
+ with:
127
+ persist-credentials: false
128
+ fetch-depth: 0
129
+ - name: Prepare tests
130
+ uses: ./.github/actions/prepare-tests
131
+ - name: Display downloaded files
132
+ run: ls -R tests/data
133
+
134
+ test:
135
+ name: Test
136
+ runs-on: ${{ matrix.os }}
137
+ needs: [build-package, prepare-test]
138
+ strategy:
139
+ fail-fast: false
140
+ matrix:
141
+ os: [ubuntu-latest, macos-latest, windows-latest]
142
+ # Created by the build-and-inspect-python-package action above.
143
+ py: ${{ fromJson(needs.build-package.outputs.supported-python-versions) }}
144
+ steps:
145
+ - uses: actions/checkout@v4
146
+ with:
147
+ persist-credentials: false
148
+ - uses: actions/setup-python@v5
149
+ with:
150
+ python-version: ${{ matrix.py }}
151
+ allow-prereleases: true
152
+ - name: Prepare tests
153
+ uses: ./.github/actions/prepare-tests
154
+ - name: Display downloaded files
155
+ run: ls -R tests/data
156
+
157
+ - name: Install hatch
158
+ run: python -Im pip install hatch
159
+
160
+ - name: Pick environment to run
161
+ env:
162
+ PYTHON_VERSION: ${{ matrix.py }}
163
+ run: |
164
+ import codecs; import os
165
+ py = f"tests.py{os.environ.get('PYTHON_VERSION')}"
166
+ print(f"Picked {py}")
167
+ with codecs.open(os.environ["GITHUB_ENV"], mode="a", encoding="utf-8") as file_handler:
168
+ file_handler.write(f"FORCE_COLOR=1\nENV={py}\n")
169
+ shell: python
170
+ - name: Setup test environment
171
+ run: |
172
+ hatch -v env create ${ENV}
173
+ shell: bash
174
+ - name: Run test suite
175
+ env:
176
+ # Make sure to add `passenv=COVERAGE_FILE` to `[testenv]` in tox.ini
177
+ # Make sure to add `overrides = { env.COVERAGE_FILE.env-vars = "COVERAGE_FILE" }` to `[tests]` in hatch.toml
178
+ COVERAGE_FILE: ".coverage.${{ matrix.os }}.${{ matrix.py }}"
179
+ CI_RUN: "yes"
180
+ run: hatch -v run ${ENV}:test-cov
181
+ shell: bash
182
+
183
+ - name: Store coverage file
184
+ uses: actions/upload-artifact@v4
185
+ with:
186
+ name: coverage-${{ matrix.os }}-${{ matrix.py }}
187
+ path: .coverage*
188
+ include-hidden-files: true
189
+ if-no-files-found: error
190
+
191
+ coverage:
192
+ name: Coverage
193
+ runs-on: ubuntu-latest
194
+ needs: test
195
+ permissions:
196
+ pull-requests: write
197
+ contents: write
198
+ steps:
199
+ - uses: actions/checkout@v4
200
+ with:
201
+ # py-cov-action/python-coverage-comment-action needs git credentials
202
+ persist-credentials: true
203
+ - uses: actions/setup-python@v5
204
+ with:
205
+ python-version-file: .python-version-default
206
+ - uses: hynek/setup-cached-uv@v2
207
+
208
+ - name: Download coverage data
209
+ uses: actions/download-artifact@v4
210
+ with:
211
+ pattern: coverage-*
212
+ merge-multiple: true
213
+
214
+ - name: Combine coverage
215
+ run: |
216
+ uv tool install 'coverage[toml]>7'
217
+
218
+ coverage combine
219
+ coverage html --skip-covered --skip-empty
220
+
221
+ # Report and write to summary.
222
+ coverage report --skip-covered --skip-empty --show-missing --format=markdown >> $GITHUB_STEP_SUMMARY
223
+
224
+ - name: Upload HTML report if check failed.
225
+ uses: actions/upload-artifact@v4
226
+ with:
227
+ name: html-report
228
+ path: htmlcov
229
+
230
+ - name: Coverage comment
231
+ id: coverage_comment
232
+ uses: py-cov-action/python-coverage-comment-action@v3
233
+ with:
234
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
235
+
236
+ - name: Store Pull Request comment to be posted
237
+ uses: actions/upload-artifact@v4
238
+ if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
239
+ with:
240
+ # If you use a different name, update COMMENT_ARTIFACT_NAME accordingly
241
+ name: python-coverage-comment-action
242
+ # If you use a different name, update COMMENT_FILENAME accordingly
243
+ path: python-coverage-comment-action.txt
244
+
245
+ core-coverage:
246
+ name: Core Coverage
247
+ runs-on: ubuntu-latest
248
+ needs: [build-package, prepare-test]
249
+ steps:
250
+ - uses: actions/checkout@v4
251
+ with:
252
+ persist-credentials: false
253
+ - uses: actions/setup-python@v5
254
+ id: setup
255
+ with:
256
+ python-version-file: .python-version-default
257
+ - name: Prepare tests
258
+ uses: ./.github/actions/prepare-tests
259
+ - name: Display downloaded files
260
+ run: ls -R tests/data
261
+ - name: Install hatch
262
+ run: python -Im pip install hatch
263
+
264
+ - name: Pick environment to run
265
+ env:
266
+ PYTHON_VERSION: ${{ steps.setup.outputs.python-version }}
267
+ run: |
268
+ import codecs; import os
269
+ py = os.environ.get('PYTHON_VERSION')
270
+ py = ".".join(py.split(".")[:2])
271
+ test_env = f"tests.py{py}"
272
+ print(f"Picked {test_env}")
273
+ with codecs.open(os.environ["GITHUB_ENV"], mode="a", encoding="utf-8") as file_handler:
274
+ file_handler.write(f"ENV={test_env}\n")
275
+ shell: python
276
+ - name: Setup test environment
277
+ run: |
278
+ hatch -v env create ${ENV}
279
+ shell: bash
280
+ - name: Run test suite
281
+ env:
282
+ # Make sure to add `passenv=COVERAGE_FILE` to `[testenv]` in tox.ini
283
+ # Make sure to add `overrides = { env.COVERAGE_FILE.env-vars = "COVERAGE_FILE" }` to `[tests]` in hatch.toml
284
+ COVERAGE_FILE: ".core-coverage"
285
+ CI_RUN: "yes"
286
+ run: hatch -v run ${ENV}:run-cov-core
287
+ shell: bash
288
+
289
+ - name: Store coverage file
290
+ uses: actions/upload-artifact@v4
291
+ if: ${{ failure() }}
292
+ with:
293
+ name: core-coverage
294
+ path: .core-coverage
295
+ include-hidden-files: true
296
+ if-no-files-found: error
297
+
298
+
299
+ # Ensure everything required is passing for branch protection.
300
+ required-checks-pass:
301
+ if: always()
302
+
303
+ needs:
304
+ - coverage
305
+ - core-coverage
306
+ - docs
307
+ - install-dev
308
+ - typing
309
+ - pre-commit
310
+ - check-manifest
311
+
312
+ runs-on: ubuntu-latest
313
+
314
+ steps:
315
+ - name: Decide whether the needed jobs succeeded or failed
316
+ uses: re-actors/alls-green@release/v1
317
+ with:
318
+ jobs: ${{ toJSON(needs) }}
@@ -0,0 +1,39 @@
1
+ name: Post coverage comment
2
+
3
+ on:
4
+ workflow_run:
5
+ workflows: ["CI"]
6
+ types:
7
+ - completed
8
+
9
+ permissions: {}
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ env:
16
+ FORCE_COLOR: "1"
17
+ PIP_DISABLE_PIP_VERSION_CHECK: "1"
18
+ PIP_NO_PYTHON_VERSION_WARNING: "1"
19
+
20
+ jobs:
21
+ display-coverage:
22
+ name: Display coverage comment
23
+ runs-on: ubuntu-latest
24
+ if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
25
+ permissions:
26
+ pull-requests: write
27
+ contents: write
28
+ actions: read
29
+ steps:
30
+ # DO NOT run actions/checkout here, for security reasons
31
+ # For details, refer to https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
32
+ - name: Post comment
33
+ uses: py-cov-action/python-coverage-comment-action@v3
34
+ with:
35
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
+ GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
37
+ # Update those if you changed the default values:
38
+ # COMMENT_ARTIFACT_NAME: python-coverage-comment-action
39
+ # COMMENT_FILENAME: python-coverage-comment-action.txt
@@ -0,0 +1,103 @@
1
+ name: Publish Docker image
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - "*.*.*"
9
+ workflow_call:
10
+ inputs:
11
+ tag-name:
12
+ description: 'Tag name'
13
+ required: true
14
+ type: 'string'
15
+ workflow_dispatch:
16
+ inputs:
17
+ tag-name:
18
+ description: 'Tag name'
19
+ required: true
20
+ type: 'string'
21
+ pull_request:
22
+
23
+ env:
24
+ REGISTRY: ghcr.io
25
+ IMAGE_NAME: ${{ github.repository }}
26
+ TEST_IMAGE: subliminal
27
+
28
+ jobs:
29
+ build-docker:
30
+ runs-on: ubuntu-latest
31
+ permissions:
32
+ contents: read
33
+ packages: write
34
+
35
+ steps:
36
+ - name: Checkout repository
37
+ if: github.event_name == 'push' || github.event_name == 'pull_request'
38
+ uses: actions/checkout@v4
39
+ with:
40
+ persist-credentials: false
41
+ - name: Checkout repository
42
+ if: github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch'
43
+ uses: actions/checkout@v4
44
+ with:
45
+ ref: ${{ inputs.tag-name }}
46
+ persist-credentials: false
47
+
48
+ - name: Set up QEMU
49
+ if: |
50
+ github.event_name == 'push'
51
+ || github.event_name == 'workflow_call'
52
+ || github.event_name == 'workflow_dispatch'
53
+ uses: docker/setup-qemu-action@v3
54
+
55
+ - name: Set up Docker Buildx
56
+ uses: docker/setup-buildx-action@v3
57
+ with:
58
+ cache-binary: false
59
+
60
+ - name: Log in to the Container registry
61
+ uses: docker/login-action@v3
62
+ with:
63
+ registry: ${{ env.REGISTRY }}
64
+ username: ${{ github.actor }}
65
+ password: ${{ secrets.GITHUB_TOKEN }}
66
+
67
+ - name: Extract metadata (tags, labels) for Docker
68
+ id: meta
69
+ uses: docker/metadata-action@v5
70
+ with:
71
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
72
+ tags: |
73
+ type=ref,event=branch
74
+ type=semver,pattern={{version}}
75
+ type=semver,pattern={{major}}.{{minor}}
76
+ type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/0.') }}
77
+
78
+ - name: Test building Docker image
79
+ uses: docker/build-push-action@v6
80
+ if: github.event_name == 'pull_request'
81
+ with:
82
+ context: .
83
+ load: true
84
+ tags: ${{ env.TEST_IMAGE }}
85
+ cache-from: type=gha
86
+ cache-to: type=gha,mode=max
87
+
88
+ - name: Build and push Docker image
89
+ uses: docker/build-push-action@v6
90
+ if: |
91
+ github.event_name == 'push'
92
+ || github.event_name == 'workflow_call'
93
+ || github.event_name == 'workflow_dispatch'
94
+ with:
95
+ context: .
96
+ platforms: linux/amd64,linux/arm64,linux/arm/v7
97
+ push: true
98
+ tags: ${{ steps.meta.outputs.tags }}
99
+ labels: ${{ steps.meta.outputs.labels }}
100
+ cache-from: type=gha
101
+ cache-to: type=gha,mode=max
102
+
103
+ # vim:ts=2:sw=2:et
@@ -0,0 +1,58 @@
1
+ name: Prepare release PR
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ branch:
7
+ description: 'Branch to base the release from'
8
+ required: false
9
+ default: 'main'
10
+ bump:
11
+ description: |
12
+ 'Release type: major, minor or patch. '
13
+ 'Leave empty for autommatic detection based on changelog segments.'
14
+ required: false
15
+ default: ''
16
+ prerelease:
17
+ description: 'Prerelease (ex: rc1). Leave empty if not a pre-release.'
18
+ required: false
19
+ default: ''
20
+
21
+ env:
22
+ FORCE_COLOR: "1"
23
+
24
+ jobs:
25
+ build:
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ contents: write
29
+ pull-requests: write
30
+
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ with:
34
+ fetch-depth: 0
35
+ # persist-credentials is needed in order for us to push the release branch.
36
+ persist-credentials: true
37
+
38
+ - name: Set up Python
39
+ uses: actions/setup-python@v5
40
+ with:
41
+ python-version-file: .python-version-default
42
+ cache: pip
43
+
44
+ - name: Install dependencies
45
+ run: |
46
+ python -m pip install --upgrade pip
47
+ pip install --upgrade setuptools tox
48
+
49
+ - name: Prepare release PR
50
+ env:
51
+ BRANCH: ${{ github.event.inputs.branch }}
52
+ BUMP: ${{ github.event.inputs.bump }}
53
+ PRERELEASE: ${{ github.event.inputs.prerelease }}
54
+ GH_TOKEN: ${{ github.token }}
55
+ run: |
56
+ git config user.name 'github-actions[bot]'
57
+ git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
58
+ tox -e prepare-release-pr -- ${BRANCH} --bump=${BUMP} --prerelease=${PRERELEASE}
@@ -0,0 +1,82 @@
1
+ name: Publish Github release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "*.*.*"
7
+ workflow_call:
8
+ inputs:
9
+ tag-name:
10
+ description: 'Tag name'
11
+ required: true
12
+ type: 'string'
13
+ workflow_dispatch:
14
+ inputs:
15
+ tag-name:
16
+ description: 'Tag name'
17
+ required: true
18
+ type: 'string'
19
+
20
+ permissions: {}
21
+
22
+ env:
23
+ FORCE_COLOR: "1"
24
+ PIP_DISABLE_PIP_VERSION_CHECK: "1"
25
+ PIP_NO_PYTHON_VERSION_WARNING: "1"
26
+
27
+ jobs:
28
+ # Always build & lint package.
29
+ build-package:
30
+ name: Build & verify package
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - name: Checkout
34
+ uses: actions/checkout@v4
35
+ if: github.event_name == 'push'
36
+ with:
37
+ persist-credentials: false
38
+ - name: Checkout
39
+ uses: actions/checkout@v4
40
+ if: |
41
+ github.event_name == 'workflow_dispatch'
42
+ || github.event_name == 'workflow_call'
43
+ with:
44
+ ref: ${{ inputs.tag-name }}
45
+ persist-credentials: false
46
+ - name: Build dist
47
+ uses: hynek/build-and-inspect-python-package@v2
48
+ id: baipp
49
+ outputs:
50
+ tag: ${{ steps.baipp.outputs.package_version }}
51
+
52
+
53
+ github-release:
54
+ name: Make a GitHub Release
55
+ needs: [build-package]
56
+ if: github.repository == 'Diaoul/subliminal'
57
+ runs-on: ubuntu-latest
58
+ permissions:
59
+ # IMPORTANT: mandatory for making GitHub Releases
60
+ contents: write
61
+ id-token: write
62
+
63
+ # Publish a Github release when a tag was pushed, or it's called with a tag.
64
+ steps:
65
+ - name: Checkout
66
+ uses: actions/checkout@v4
67
+ with:
68
+ fetch-tags: true
69
+ ref: ${{ needs.build-package.outputs.tag }}
70
+ persist-credentials: false
71
+
72
+ - name: Download packages built by build-and-inspect-python-package
73
+ uses: actions/download-artifact@v4
74
+ with:
75
+ name: Packages
76
+ path: dist
77
+ - name: Publish GitHub Release
78
+ uses: softprops/action-gh-release@v2
79
+ with:
80
+ files: dist/*
81
+ generate_release_notes: true
82
+ draft: true