subliminal 2.2.0__tar.gz → 2.3.2__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 (365) hide show
  1. {subliminal-2.2.0 → subliminal-2.3.2}/.dockerignore +0 -3
  2. subliminal-2.3.2/.github/actions/prepare-tests/action.yaml +62 -0
  3. subliminal-2.3.2/.github/workflows/CI.yaml +318 -0
  4. subliminal-2.3.2/.github/workflows/coverage.yaml +39 -0
  5. subliminal-2.3.2/.github/workflows/docker-build.yaml +103 -0
  6. subliminal-2.3.2/.github/workflows/prepare-release-pr.yaml +58 -0
  7. subliminal-2.3.2/.github/workflows/publish-release.yaml +110 -0
  8. subliminal-2.3.2/.github/workflows/publish.yaml +53 -0
  9. subliminal-2.3.2/.github/workflows/scheduled-tests.yaml +46 -0
  10. subliminal-2.3.2/.github/workflows/tag-release.yaml +108 -0
  11. subliminal-2.3.2/.github/zizmor.yml +4 -0
  12. subliminal-2.3.2/.gitignore +65 -0
  13. {subliminal-2.2.0 → subliminal-2.3.2}/.pre-commit-config.yaml +21 -6
  14. subliminal-2.3.2/.python-version-default +1 -0
  15. {subliminal-2.2.0 → subliminal-2.3.2}/.readthedocs.yaml +1 -0
  16. subliminal-2.3.2/CONTRIBUTING.md +201 -0
  17. {subliminal-2.2.0 → subliminal-2.3.2}/Dockerfile +9 -5
  18. subliminal-2.2.0/PKG-INFO → subliminal-2.3.2/HISTORY.rst +102 -137
  19. {subliminal-2.2.0 → subliminal-2.3.2}/MANIFEST.in +4 -0
  20. subliminal-2.3.2/PKG-INFO +201 -0
  21. subliminal-2.3.2/README.rst +128 -0
  22. subliminal-2.3.2/RELEASING.md +100 -0
  23. subliminal-2.3.2/changelog.d/.gitignore +1 -0
  24. {subliminal-2.2.0 → subliminal-2.3.2}/docs/Makefile +1 -1
  25. subliminal-2.3.2/docs/_intersphinx/README.md +82 -0
  26. subliminal-2.3.2/docs/_intersphinx/importlib_metadata_objects.inv +0 -0
  27. subliminal-2.3.2/docs/_intersphinx/importlib_metadata_objects.txt +6 -0
  28. subliminal-2.3.2/docs/_static/.gitignore +1 -0
  29. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/cache.rst +2 -1
  30. subliminal-2.3.2/docs/api/cli.rst +5 -0
  31. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/core.rst +1 -0
  32. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/exceptions.rst +1 -0
  33. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/extensions.rst +1 -0
  34. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/providers.rst +18 -7
  35. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/refiners.rst +5 -0
  36. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/score.rst +1 -0
  37. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/subtitle.rst +1 -0
  38. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/utils.rst +1 -0
  39. {subliminal-2.2.0 → subliminal-2.3.2}/docs/api/video.rst +1 -0
  40. {subliminal-2.2.0 → subliminal-2.3.2}/docs/cassettes/test_usage.yaml +206 -162
  41. {subliminal-2.2.0 → subliminal-2.3.2}/docs/conf.py +20 -11
  42. {subliminal-2.2.0 → subliminal-2.3.2}/docs/config.toml +5 -2
  43. {subliminal-2.2.0 → subliminal-2.3.2}/docs/conftest.py +8 -5
  44. {subliminal-2.2.0 → subliminal-2.3.2}/docs/index.rst +9 -1
  45. {subliminal-2.2.0 → subliminal-2.3.2}/docs/make.bat +1 -1
  46. subliminal-2.3.2/docs/user/changelog.rst +7 -0
  47. {subliminal-2.2.0 → subliminal-2.3.2}/docs/user/cli.rst +4 -0
  48. subliminal-2.3.2/docs/user/configuration_file.rst +44 -0
  49. {subliminal-2.2.0 → subliminal-2.3.2}/docs/user/how_it_works.rst +11 -9
  50. subliminal-2.3.2/docs/user/installation.rst +30 -0
  51. {subliminal-2.2.0 → subliminal-2.3.2}/docs/user/provider_guide.rst +2 -2
  52. {subliminal-2.2.0 → subliminal-2.3.2}/docs/user/usage.rst +57 -7
  53. subliminal-2.3.2/hatch.toml +128 -0
  54. {subliminal-2.2.0 → subliminal-2.3.2}/pyproject.toml +144 -70
  55. subliminal-2.3.2/scripts/.gitignore +1 -0
  56. subliminal-2.3.2/scripts/generate-gh-release-notes.py +86 -0
  57. subliminal-2.3.2/scripts/prepare-release-pr.py +193 -0
  58. subliminal-2.3.2/scripts/prepare_tests.py +137 -0
  59. subliminal-2.3.2/scripts/release.py +148 -0
  60. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/__init__.py +23 -17
  61. subliminal-2.3.2/src/subliminal/__main__.py +26 -0
  62. subliminal-2.3.2/src/subliminal/archives.py +139 -0
  63. subliminal-2.3.2/src/subliminal/cli.py +1169 -0
  64. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/converters/__init__.py +1 -1
  65. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/converters/addic7ed.py +20 -22
  66. subliminal-2.3.2/src/subliminal/converters/opensubtitles.py +77 -0
  67. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/converters/opensubtitlescom.py +8 -8
  68. subliminal-2.3.2/src/subliminal/converters/subtitulamos.py +69 -0
  69. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/converters/tvsubtitles.py +8 -10
  70. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/core.py +238 -127
  71. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/exceptions.py +22 -4
  72. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/extensions.py +30 -10
  73. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/matches.py +31 -5
  74. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/__init__.py +36 -35
  75. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/addic7ed.py +44 -36
  76. subliminal-2.3.2/src/subliminal/providers/bsplayer.py +364 -0
  77. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/gestdown.py +9 -8
  78. subliminal-2.3.2/src/subliminal/providers/mock.py +214 -0
  79. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/napiprojekt.py +18 -3
  80. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/opensubtitles.py +12 -18
  81. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/opensubtitlescom.py +28 -8
  82. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/podnapisi.py +4 -4
  83. subliminal-2.3.2/src/subliminal/providers/subtitulamos.py +347 -0
  84. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/providers/tvsubtitles.py +4 -4
  85. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/refiners/hash.py +18 -66
  86. subliminal-2.3.2/src/subliminal/refiners/metadata.py +211 -0
  87. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/refiners/omdb.py +27 -22
  88. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/refiners/tmdb.py +10 -5
  89. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/refiners/tvdb.py +12 -7
  90. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/score.py +28 -46
  91. subliminal-2.3.2/src/subliminal/subtitle.py +899 -0
  92. subliminal-2.3.2/src/subliminal/utils.py +433 -0
  93. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/video.py +68 -43
  94. subliminal-2.3.2/tests/__init__.py +0 -0
  95. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_download_subtitle.yaml +1968 -1869
  96. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_get_show_id.yaml +1956 -1855
  97. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_get_show_id_country.yaml +1956 -1855
  98. subliminal-2.2.0/tests/cassettes/addic7ed/test_get_show_id_with_comma.yaml → subliminal-2.3.2/tests/cassettes/addic7ed/test_get_show_id_quote_dots_mixed_case.yaml +1955 -1853
  99. subliminal-2.2.0/tests/cassettes/addic7ed/test_get_show_ids.yaml → subliminal-2.3.2/tests/cassettes/addic7ed/test_get_show_id_with_comma.yaml +1956 -1854
  100. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_get_show_id_year.yaml +1956 -1855
  101. subliminal-2.2.0/tests/cassettes/addic7ed/test_get_show_id_quote_dots_mixed_case.yaml → subliminal-2.3.2/tests/cassettes/addic7ed/test_get_show_ids.yaml +1955 -1853
  102. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_list_subtitles.yaml +1965 -1861
  103. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_list_subtitles_episode_alternative_series.yaml +3922 -4076
  104. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_list_subtitles_show_with_asterisk.yaml +3922 -4076
  105. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query.yaml +1961 -1859
  106. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_no_year.yaml +1965 -1861
  107. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_parsing.yaml +1965 -1861
  108. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_parsing_colon.yaml +1965 -1863
  109. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_parsing_dash.yaml +1963 -1863
  110. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_parsing_quote_dots_mixed_case.yaml +8 -7
  111. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_wrong_series.yaml +8 -7
  112. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/addic7ed/test_query_year.yaml +1961 -1859
  113. subliminal-2.3.2/tests/cassettes/bsplayer/test_download_subtitle.yaml +1356 -0
  114. subliminal-2.3.2/tests/cassettes/bsplayer/test_list_subtitles_hash.yaml +197 -0
  115. subliminal-2.3.2/tests/cassettes/bsplayer/test_login.yaml +55 -0
  116. subliminal-2.3.2/tests/cassettes/bsplayer/test_logout.yaml +107 -0
  117. subliminal-2.3.2/tests/cassettes/bsplayer/test_query_hash_size.yaml +353 -0
  118. subliminal-2.3.2/tests/cassettes/cli/test_cli_download.yaml +767 -0
  119. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_download_subtitle.yaml +36 -27
  120. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_download_with_bom.yaml +33 -30
  121. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_get_title_and_show_id_alternative_name.yaml +28 -20
  122. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_get_title_and_show_id_no_year.yaml +15 -12
  123. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_get_title_and_show_id_only_title.yaml +14 -11
  124. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_get_title_and_show_id_with_tvdb_id.yaml +11 -8
  125. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_list_subtitles.yaml +39 -34
  126. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_list_subtitles_episode_alternative_series.yaml +36 -27
  127. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query.yaml +28 -22
  128. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_all_series.yaml +45 -39
  129. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_no_language.yaml +15 -12
  130. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_parsing.yaml +29 -21
  131. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_parsing_colon.yaml +25 -19
  132. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_parsing_dash.yaml +24 -18
  133. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_parsing_quote_dots_mixed_case.yaml +26 -20
  134. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_query_wrong_series.yaml +10 -8
  135. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_id.yaml +11 -8
  136. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_id_error.yaml +10 -7
  137. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_id_incomplete.yaml +12 -9
  138. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_id_no_year.yaml +13 -10
  139. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_id_quote.yaml +13 -10
  140. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_search_show_series_tvdb_id.yaml +15 -12
  141. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/gestdown/test_show_with_asterisk.yaml +38 -33
  142. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/napiprojekt/test_download_subtitles.yaml +7 -9
  143. subliminal-2.3.2/tests/cassettes/napiprojekt/test_list_subtitles.yaml +863 -0
  144. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/napiprojekt/test_query_microdvd.yaml +6 -8
  145. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/napiprojekt/test_query_srt.yaml +6 -8
  146. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/napiprojekt/test_query_srt_reencode.yaml +6 -8
  147. subliminal-2.3.2/tests/cassettes/napiprojekt/test_query_wrong_hash.yaml +40 -0
  148. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_get_id.yaml +9 -10
  149. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_get_title.yaml +9 -10
  150. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_get_wrong_id.yaml +8 -8
  151. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_get_wrong_title.yaml +6 -6
  152. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_episode.yaml +9 -9
  153. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_episode_original_series.yaml +112 -61
  154. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_episode_with_country_hoc_us.yaml +1 -0
  155. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_episode_year.yaml +8 -8
  156. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_search.yaml +10 -10
  157. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_search_page.yaml +12 -12
  158. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_search_type.yaml +10 -10
  159. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_search_wrong_title.yaml +6 -6
  160. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_search_year.yaml +9 -9
  161. subliminal-2.3.2/tests/cassettes/opensubtitles/test_download_subtitle.yaml +751 -0
  162. subliminal-2.3.2/tests/cassettes/opensubtitles/test_list_subtitles_episode.yaml +458 -0
  163. subliminal-2.3.2/tests/cassettes/opensubtitles/test_list_subtitles_movie.yaml +647 -0
  164. subliminal-2.3.2/tests/cassettes/opensubtitles/test_list_subtitles_movie_no_hash.yaml +439 -0
  165. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_login_bad_password.yaml +21 -24
  166. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_login_vip_bad_password.yaml +22 -25
  167. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_login_vip_login.yaml +22 -25
  168. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_no_operation.yaml +88 -95
  169. subliminal-2.3.2/tests/cassettes/opensubtitles/test_query_hash_size.yaml +458 -0
  170. subliminal-2.3.2/tests/cassettes/opensubtitles/test_query_imdb_id.yaml +431 -0
  171. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_query_not_enough_information.yaml +67 -71
  172. subliminal-2.3.2/tests/cassettes/opensubtitles/test_query_query_episode.yaml +429 -0
  173. subliminal-2.3.2/tests/cassettes/opensubtitles/test_query_query_movie.yaml +448 -0
  174. subliminal-2.3.2/tests/cassettes/opensubtitles/test_query_query_season_episode.yaml +432 -0
  175. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitles/test_query_wrong_hash_wrong_size.yaml +90 -95
  176. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_download_subtitle.yaml +391 -320
  177. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_list_subtitles_episode.yaml +109 -67
  178. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie.yaml +313 -230
  179. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie_no_hash.yaml +46 -24
  180. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_login.yaml +20 -20
  181. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_login_bad_password.yaml +20 -20
  182. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_logout.yaml +23 -21
  183. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_query_hash_size.yaml +80 -56
  184. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_query_imdb_id.yaml +70 -46
  185. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_query_query_episode.yaml +138 -102
  186. subliminal-2.3.2/tests/cassettes/opensubtitlescom/test_query_query_movie.yaml +195 -0
  187. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_query_query_season_episode.yaml +99 -57
  188. subliminal-2.3.2/tests/cassettes/opensubtitlescom/test_query_tag_movie.yaml +184 -0
  189. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_query_wrong_hash_wrong_size.yaml +51 -19
  190. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_tag_match.yaml +182 -116
  191. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/opensubtitlescom/test_user_infos.yaml +37 -37
  192. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/podnapisi/test_download_subtitle.yaml +393 -407
  193. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/podnapisi/test_download_subtitles_with_title_unicode.yaml +8 -8
  194. subliminal-2.3.2/tests/cassettes/podnapisi/test_list_subtitles_episode.yaml +488 -0
  195. subliminal-2.3.2/tests/cassettes/podnapisi/test_list_subtitles_episode_alternative_series.yaml +349 -0
  196. subliminal-2.3.2/tests/cassettes/podnapisi/test_list_subtitles_movie.yaml +424 -0
  197. subliminal-2.3.2/tests/cassettes/podnapisi/test_query_episode.yaml +161 -0
  198. subliminal-2.3.2/tests/cassettes/podnapisi/test_query_movie.yaml +344 -0
  199. {subliminal-2.2.0/tests/cassettes/core → subliminal-2.3.2/tests/cassettes/providers}/test_download_best_subtitles.yaml +62 -49
  200. subliminal-2.3.2/tests/cassettes/providers/test_download_best_subtitles_min_score.yaml +118 -0
  201. {subliminal-2.2.0/tests/cassettes/core → subliminal-2.3.2/tests/cassettes/providers}/test_download_best_subtitles_only_one.yaml +70 -64
  202. subliminal-2.3.2/tests/cassettes/providers/test_list_subtitles_providers_download.yaml +13063 -0
  203. subliminal-2.3.2/tests/cassettes/subtitulamos/test_download_subtitle.yaml +2013 -0
  204. subliminal-2.3.2/tests/cassettes/subtitulamos/test_download_subtitle_first_episode.yaml +1882 -0
  205. subliminal-2.3.2/tests/cassettes/subtitulamos/test_download_subtitle_foo.yaml +1952 -0
  206. subliminal-2.3.2/tests/cassettes/subtitulamos/test_download_subtitle_last_season.yaml +1952 -0
  207. subliminal-2.3.2/tests/cassettes/subtitulamos/test_download_subtitle_year.yaml +1882 -0
  208. subliminal-2.3.2/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_episode.yaml +837 -0
  209. subliminal-2.3.2/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_language.yaml +1071 -0
  210. subliminal-2.3.2/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_season.yaml +618 -0
  211. subliminal-2.3.2/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_series.yaml +114 -0
  212. subliminal-2.3.2/tests/cassettes/subtitulamos/test_list_subtitles_with_spanish_non_mx_search.yaml +1568 -0
  213. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_get_movie_id.yaml +55 -55
  214. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_get_movie_id_failed.yaml +10 -10
  215. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_get_series_id.yaml +17 -18
  216. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_get_series_wrong_id.yaml +9 -11
  217. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_episode.yaml +73 -75
  218. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_episode_original_series.yaml +94 -97
  219. subliminal-2.3.2/tests/cassettes/tmdb/test_refine_episode_with_country.yaml +345 -0
  220. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_episode_with_country_hoc_us.yaml +63 -65
  221. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_episode_year.yaml +49 -49
  222. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_movie.yaml +69 -73
  223. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_refine_movie_guess_alternative_title.yaml +39 -34
  224. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_movie.yaml +55 -57
  225. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_movie_page.yaml +51 -53
  226. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_movie_wrong_title.yaml +10 -12
  227. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_movie_year.yaml +15 -17
  228. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_series.yaml +17 -20
  229. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tmdb/test_search_series_wrong_name.yaml +10 -12
  230. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_get_series.yaml +17 -17
  231. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_get_series_actors.yaml +15 -15
  232. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_get_series_actors_wrong_id.yaml +14 -14
  233. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_get_series_wrong_id.yaml +14 -14
  234. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_login.yaml +7 -7
  235. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_login_error.yaml +6 -6
  236. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_query_series_episodes.yaml +17 -17
  237. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_query_series_episodes_wrong_season.yaml +14 -14
  238. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine.yaml +47 -46
  239. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_ambiguous.yaml +101 -59
  240. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_ambiguous_2.yaml +171 -126
  241. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_alternative_series.yaml +81 -39
  242. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_no_year.yaml +153 -74
  243. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_partial.yaml +139 -78
  244. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_with_comma.yaml +83 -39
  245. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_with_country.yaml +124 -68
  246. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_with_country_hoc_us.yaml +83 -35
  247. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refine_episode_year.yaml +149 -73
  248. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_refresh_token.yaml +15 -15
  249. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_search_series.yaml +17 -16
  250. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_search_series_wrong_name.yaml +14 -14
  251. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvdb/test_token_needs_refresh.yaml +7 -7
  252. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_download_subtitle.yaml +408 -473
  253. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_download_subtitle_with_quote.yaml +359 -393
  254. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_get_episode_ids.yaml +141 -156
  255. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_get_episode_ids_wrong_season.yaml +98 -111
  256. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_list_subtitles.yaml +399 -464
  257. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_list_subtitles_episode_alternative_series.yaml +409 -456
  258. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_query.yaml +398 -463
  259. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_query_no_year.yaml +288 -328
  260. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_query_with_quote.yaml +344 -378
  261. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_query_wrong_episode.yaml +240 -293
  262. subliminal-2.3.2/tests/cassettes/tvsubtitles/test_query_wrong_series.yaml +206 -0
  263. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id.yaml +85 -98
  264. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_ambiguous.yaml +182 -186
  265. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_error.yaml +86 -99
  266. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_incomplete.yaml +85 -99
  267. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_no_year.yaml +85 -98
  268. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_uk.yaml +85 -98
  269. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_us.yaml +129 -106
  270. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/tvsubtitles/test_search_show_id_year_in_title.yaml +85 -98
  271. subliminal-2.3.2/tests/conftest.py +967 -0
  272. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_addic7ed.py +111 -109
  273. subliminal-2.3.2/tests/providers/test_bsplayer.py +134 -0
  274. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_gestdown.py +58 -56
  275. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_napiprojekt.py +22 -16
  276. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_opensubtitles.py +61 -49
  277. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_opensubtitlescom.py +46 -44
  278. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_podnapisi.py +21 -19
  279. subliminal-2.3.2/tests/providers/test_providers.py +373 -0
  280. subliminal-2.3.2/tests/providers/test_subtitulamos.py +312 -0
  281. {subliminal-2.2.0 → subliminal-2.3.2}/tests/providers/test_tvsubtitles.py +57 -55
  282. subliminal-2.3.2/tests/refiners/test_hash.py +58 -0
  283. subliminal-2.3.2/tests/refiners/test_metadata.py +143 -0
  284. {subliminal-2.2.0 → subliminal-2.3.2}/tests/refiners/test_omdb.py +55 -52
  285. {subliminal-2.2.0 → subliminal-2.3.2}/tests/refiners/test_tmdb.py +42 -41
  286. {subliminal-2.2.0 → subliminal-2.3.2}/tests/refiners/test_tvdb.py +57 -56
  287. subliminal-2.3.2/tests/test_archives.py +99 -0
  288. {subliminal-2.2.0 → subliminal-2.3.2}/tests/test_cache.py +11 -7
  289. subliminal-2.3.2/tests/test_cli.py +548 -0
  290. subliminal-2.3.2/tests/test_core.py +482 -0
  291. {subliminal-2.2.0 → subliminal-2.3.2}/tests/test_extensions.py +64 -11
  292. {subliminal-2.2.0 → subliminal-2.3.2}/tests/test_matches.py +22 -38
  293. {subliminal-2.2.0 → subliminal-2.3.2}/tests/test_provider.py +12 -8
  294. subliminal-2.3.2/tests/test_provider_pool.py +575 -0
  295. subliminal-2.3.2/tests/test_score.py +124 -0
  296. subliminal-2.3.2/tests/test_subtitle.py +672 -0
  297. subliminal-2.3.2/tests/test_utils.py +342 -0
  298. {subliminal-2.2.0 → subliminal-2.3.2}/tests/test_video.py +85 -26
  299. subliminal-2.3.2/tox.ini +141 -0
  300. subliminal-2.2.0/CONTRIBUTING.md +0 -19
  301. subliminal-2.2.0/HISTORY.rst +0 -365
  302. subliminal-2.2.0/README.rst +0 -89
  303. subliminal-2.2.0/docs/api/cli.rst +0 -3
  304. subliminal-2.2.0/setup.cfg +0 -4
  305. subliminal-2.2.0/subliminal/cli.py +0 -597
  306. subliminal-2.2.0/subliminal/converters/shooter.py +0 -37
  307. subliminal-2.2.0/subliminal/converters/thesubdb.py +0 -50
  308. subliminal-2.2.0/subliminal/refiners/metadata.py +0 -113
  309. subliminal-2.2.0/subliminal/subtitle.py +0 -478
  310. subliminal-2.2.0/subliminal/utils.py +0 -183
  311. subliminal-2.2.0/subliminal.egg-info/PKG-INFO +0 -518
  312. subliminal-2.2.0/subliminal.egg-info/SOURCES.txt +0 -268
  313. subliminal-2.2.0/subliminal.egg-info/dependency_links.txt +0 -1
  314. subliminal-2.2.0/subliminal.egg-info/entry_points.txt +0 -26
  315. subliminal-2.2.0/subliminal.egg-info/requires.txt +0 -40
  316. subliminal-2.2.0/subliminal.egg-info/top_level.txt +0 -1
  317. subliminal-2.2.0/tests/cassettes/addic7ed/test_login.yaml +0 -60
  318. subliminal-2.2.0/tests/cassettes/addic7ed/test_logout.yaml +0 -61
  319. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id.yaml +0 -637
  320. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id_error.yaml +0 -120
  321. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id_incomplete.yaml +0 -640
  322. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id_no_year.yaml +0 -584
  323. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id_quote.yaml +0 -611
  324. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_id_year.yaml +0 -311
  325. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_ids_quote_dots_mixed_case.yaml +0 -634
  326. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_ids_with_comma.yaml +0 -287
  327. subliminal-2.2.0/tests/cassettes/addic7ed/test_search_show_ids_with_country.yaml +0 -826
  328. subliminal-2.2.0/tests/cassettes/core/test_download_bad_subtitle.yaml +0 -790
  329. subliminal-2.2.0/tests/cassettes/core/test_download_best_subtitles_min_score.yaml +0 -116
  330. subliminal-2.2.0/tests/cassettes/napiprojekt/test_list_subtitles.yaml +0 -439
  331. subliminal-2.2.0/tests/cassettes/napiprojekt/test_query_wrong_hash.yaml +0 -43
  332. subliminal-2.2.0/tests/cassettes/opensubtitles/test_download_subtitle.yaml +0 -1370
  333. subliminal-2.2.0/tests/cassettes/opensubtitles/test_list_subtitles_episode.yaml +0 -473
  334. subliminal-2.2.0/tests/cassettes/opensubtitles/test_list_subtitles_movie.yaml +0 -689
  335. subliminal-2.2.0/tests/cassettes/opensubtitles/test_list_subtitles_movie_no_hash.yaml +0 -458
  336. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_hash_size.yaml +0 -474
  337. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_imdb_id.yaml +0 -452
  338. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_query_episode.yaml +0 -446
  339. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_query_movie.yaml +0 -471
  340. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_query_season_episode.yaml +0 -450
  341. subliminal-2.2.0/tests/cassettes/opensubtitles/test_query_tag_movie.yaml +0 -414
  342. subliminal-2.2.0/tests/cassettes/opensubtitles/test_tag_match.yaml +0 -532
  343. subliminal-2.2.0/tests/cassettes/opensubtitlescom/test_query_query_movie.yaml +0 -173
  344. subliminal-2.2.0/tests/cassettes/opensubtitlescom/test_query_tag_movie.yaml +0 -164
  345. subliminal-2.2.0/tests/cassettes/podnapisi/test_list_subtitles_episode.yaml +0 -515
  346. subliminal-2.2.0/tests/cassettes/podnapisi/test_list_subtitles_episode_alternative_series.yaml +0 -367
  347. subliminal-2.2.0/tests/cassettes/podnapisi/test_list_subtitles_movie.yaml +0 -438
  348. subliminal-2.2.0/tests/cassettes/podnapisi/test_query_episode.yaml +0 -174
  349. subliminal-2.2.0/tests/cassettes/podnapisi/test_query_movie.yaml +0 -362
  350. subliminal-2.2.0/tests/cassettes/tmdb/test_refine_episode_with_country.yaml +0 -302
  351. subliminal-2.2.0/tests/cassettes/tvsubtitles/test_query_wrong_series.yaml +0 -219
  352. subliminal-2.2.0/tests/conftest.py +0 -492
  353. subliminal-2.2.0/tests/refiners/test_hash.py +0 -19
  354. subliminal-2.2.0/tests/test_core.py +0 -704
  355. subliminal-2.2.0/tests/test_score.py +0 -142
  356. subliminal-2.2.0/tests/test_subtitle.py +0 -163
  357. subliminal-2.2.0/tests/test_utils.py +0 -5
  358. subliminal-2.2.0/tox.ini +0 -7
  359. {subliminal-2.2.0 → subliminal-2.3.2}/LICENSE +0 -0
  360. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/cache.py +0 -0
  361. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/py.typed +0 -0
  362. {subliminal-2.2.0 → subliminal-2.3.2/src}/subliminal/refiners/__init__.py +0 -0
  363. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_episode_with_country.yaml +0 -0
  364. {subliminal-2.2.0 → subliminal-2.3.2}/tests/cassettes/omdb/test_refine_movie.yaml +0 -0
  365. {subliminal-2.2.0 → subliminal-2.3.2}/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,110 @@
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
+
39
+ - name: Checkout
40
+ uses: actions/checkout@v4
41
+ if: |
42
+ github.event_name == 'workflow_dispatch'
43
+ || github.event_name == 'workflow_call'
44
+ with:
45
+ ref: ${{ inputs.tag-name }}
46
+ persist-credentials: false
47
+
48
+ - name: Build dist
49
+ uses: hynek/build-and-inspect-python-package@v2
50
+ id: baipp
51
+
52
+ - name: Install tox
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install --upgrade tox
56
+
57
+ - name: Generate Release Notes
58
+ env:
59
+ RELEASE_VERSION: ${{ steps.baipp.outputs.package_version }}
60
+ run: |
61
+ sudo apt-get install pandoc
62
+ # use package_version computed in step 'baipp'
63
+ tox -e generate-gh-release-notes -- "$RELEASE_VERSION" latest-release-notes.md
64
+
65
+ - name: Upload release notes
66
+ uses: actions/upload-artifact@v4
67
+ with:
68
+ name: latest-release-notes
69
+ path: latest-release-notes.md
70
+ include-hidden-files: false
71
+ if-no-files-found: error
72
+ outputs:
73
+ tag: ${{ steps.baipp.outputs.package_version }}
74
+
75
+ github-release:
76
+ name: Make a GitHub Release
77
+ needs: [build-package]
78
+ if: github.repository == 'Diaoul/subliminal'
79
+ runs-on: ubuntu-latest
80
+ permissions:
81
+ # IMPORTANT: mandatory for making GitHub Releases
82
+ contents: write
83
+ id-token: write
84
+
85
+ # Publish a Github release when a tag was pushed, or it's called with a tag.
86
+ steps:
87
+ - name: Checkout
88
+ uses: actions/checkout@v4
89
+ with:
90
+ fetch-tags: true
91
+ ref: ${{ needs.build-package.outputs.tag }}
92
+ persist-credentials: false
93
+
94
+ - name: Download packages built by build-and-inspect-python-package
95
+ uses: actions/download-artifact@v4
96
+ with:
97
+ name: Packages
98
+ path: dist
99
+ - name: Download release notes
100
+ uses: actions/download-artifact@v4
101
+ with:
102
+ name: latest-release-notes
103
+ path: latest-release-notes.md
104
+
105
+ - name: Publish GitHub Release
106
+ uses: softprops/action-gh-release@v2
107
+ with:
108
+ files: dist/*
109
+ body_path: latest-release-notes.md
110
+ draft: true