subliminal 2.7.1__tar.gz → 2.8.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 (335) hide show
  1. {subliminal-2.7.1 → subliminal-2.8.0}/.github/actions/prepare-tests/action.yaml +4 -4
  2. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/CI.yaml +31 -31
  3. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/coverage.yaml +1 -1
  4. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/docker-build.yaml +8 -8
  5. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/prepare-release-pr.yaml +2 -2
  6. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/publish-release.yaml +6 -6
  7. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/publish.yaml +4 -4
  8. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/scheduled-tests.yaml +2 -2
  9. {subliminal-2.7.1 → subliminal-2.8.0}/.github/workflows/tag-release.yaml +3 -3
  10. {subliminal-2.7.1 → subliminal-2.8.0}/HISTORY.rst +33 -0
  11. {subliminal-2.7.1 → subliminal-2.8.0}/PKG-INFO +3 -2
  12. subliminal-2.8.0/docs/assets/demo.gif +0 -0
  13. {subliminal-2.7.1 → subliminal-2.8.0}/docs/conf.py +5 -2
  14. {subliminal-2.7.1 → subliminal-2.8.0}/pyproject.toml +1 -0
  15. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/commands/_format.py +20 -1
  16. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/commands/download_best.py +9 -5
  17. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/core.py +82 -32
  18. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/opensubtitles.py +12 -7
  19. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/opensubtitlescom.py +50 -11
  20. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/hash.py +4 -2
  21. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/metadata.py +15 -11
  22. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/omdb.py +53 -22
  23. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/tmdb.py +58 -41
  24. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/tvdb.py +70 -54
  25. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/utils.py +2 -2
  26. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/video.py +83 -129
  27. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_download_subtitle.yaml +58 -58
  28. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_download_with_bom.yaml +60 -56
  29. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_get_title_and_show_id_alternative_name.yaml +34 -36
  30. subliminal-2.8.0/tests/cassettes/gestdown/test_get_title_and_show_id_no_year.yaml +61 -0
  31. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_get_title_and_show_id_only_title.yaml +19 -19
  32. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_get_title_and_show_id_with_tvdb_id.yaml +18 -18
  33. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_list_subtitles.yaml +59 -57
  34. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_list_subtitles_episode_alternative_series.yaml +41 -41
  35. subliminal-2.8.0/tests/cassettes/gestdown/test_query.yaml +116 -0
  36. subliminal-2.8.0/tests/cassettes/gestdown/test_query_all_series.yaml +140 -0
  37. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_query_no_language.yaml +20 -20
  38. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_query_parsing.yaml +37 -39
  39. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_query_parsing_colon.yaml +35 -35
  40. subliminal-2.8.0/tests/cassettes/gestdown/test_query_parsing_dash.yaml +114 -0
  41. subliminal-2.8.0/tests/cassettes/gestdown/test_query_parsing_quote_dots_mixed_case.yaml +117 -0
  42. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_query_wrong_series.yaml +13 -13
  43. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_search_show_id.yaml +17 -17
  44. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_search_show_id_error.yaml +16 -16
  45. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_search_show_id_incomplete.yaml +17 -17
  46. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_search_show_id_no_year.yaml +19 -18
  47. subliminal-2.8.0/tests/cassettes/gestdown/test_search_show_id_quote.yaml +58 -0
  48. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_search_show_series_tvdb_id.yaml +19 -19
  49. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/gestdown/test_show_with_asterisk.yaml +56 -52
  50. subliminal-2.8.0/tests/cassettes/omdb/test_refine_episode_from_series_imdb_id.yaml +57 -0
  51. subliminal-2.8.0/tests/cassettes/omdb/test_refine_episode_from_unknown_series_imdb_id.yaml +50 -0
  52. subliminal-2.8.0/tests/cassettes/omdb/test_refine_movie_from_imdb_id.yaml +58 -0
  53. subliminal-2.8.0/tests/cassettes/omdb/test_refine_movie_from_unknown_imdb_id.yaml +50 -0
  54. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_download_subtitle.yaml +242 -234
  55. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_list_subtitles_episode.yaml +84 -103
  56. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_list_subtitles_movie.yaml +226 -213
  57. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_list_subtitles_movie_no_hash.yaml +82 -101
  58. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_login_bad_password.yaml +20 -25
  59. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_login_vip_bad_password.yaml +20 -25
  60. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_login_vip_login.yaml +21 -26
  61. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_no_operation.yaml +78 -97
  62. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_hash_size.yaml +103 -118
  63. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_imdb_id.yaml +106 -117
  64. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_not_enough_information.yaml +57 -71
  65. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_query_episode.yaml +80 -99
  66. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_query_movie.yaml +105 -121
  67. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_query_season_episode.yaml +82 -101
  68. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitles/test_query_wrong_hash_wrong_size.yaml +80 -99
  69. subliminal-2.8.0/tests/cassettes/opensubtitlescom/test_list_subtitles_episode_series_imdb_id.yaml +560 -0
  70. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/providers/test_download_best_subtitles.yaml +514 -506
  71. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/providers/test_list_subtitles_providers_download.yaml +3590 -5465
  72. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cli/test_download.py +31 -1
  73. subliminal-2.8.0/tests/cli/test_format.py +48 -0
  74. {subliminal-2.7.1 → subliminal-2.8.0}/tests/conftest.py +103 -64
  75. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_gestdown.py +1 -0
  76. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_opensubtitles.py +2 -1
  77. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_opensubtitlescom.py +83 -16
  78. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_providers.py +0 -18
  79. {subliminal-2.7.1 → subliminal-2.8.0}/tests/refiners/test_metadata.py +21 -20
  80. {subliminal-2.7.1 → subliminal-2.8.0}/tests/refiners/test_omdb.py +62 -7
  81. {subliminal-2.7.1 → subliminal-2.8.0}/tests/refiners/test_tmdb.py +10 -10
  82. {subliminal-2.7.1 → subliminal-2.8.0}/tests/refiners/test_tvdb.py +10 -40
  83. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_core.py +6 -8
  84. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_provider_pool.py +73 -19
  85. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_utils.py +1 -1
  86. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_video.py +152 -9
  87. subliminal-2.7.1/docs/assets/demo.gif +0 -0
  88. subliminal-2.7.1/tests/cassettes/gestdown/test_get_title_and_show_id_no_year.yaml +0 -57
  89. subliminal-2.7.1/tests/cassettes/gestdown/test_query.yaml +0 -116
  90. subliminal-2.7.1/tests/cassettes/gestdown/test_query_all_series.yaml +0 -140
  91. subliminal-2.7.1/tests/cassettes/gestdown/test_query_parsing_dash.yaml +0 -114
  92. subliminal-2.7.1/tests/cassettes/gestdown/test_query_parsing_quote_dots_mixed_case.yaml +0 -115
  93. subliminal-2.7.1/tests/cassettes/gestdown/test_search_show_id_quote.yaml +0 -58
  94. subliminal-2.7.1/tests/cassettes/opensubtitlescom/test_tag_match.yaml +0 -595
  95. {subliminal-2.7.1 → subliminal-2.8.0}/.dockerignore +0 -0
  96. {subliminal-2.7.1 → subliminal-2.8.0}/.github/zizmor.yml +0 -0
  97. {subliminal-2.7.1 → subliminal-2.8.0}/.gitignore +0 -0
  98. {subliminal-2.7.1 → subliminal-2.8.0}/.pre-commit-config.yaml +0 -0
  99. {subliminal-2.7.1 → subliminal-2.8.0}/.python-version-default +0 -0
  100. {subliminal-2.7.1 → subliminal-2.8.0}/.readthedocs.yaml +0 -0
  101. {subliminal-2.7.1 → subliminal-2.8.0}/CONTRIBUTING.md +0 -0
  102. {subliminal-2.7.1 → subliminal-2.8.0}/Dockerfile +0 -0
  103. {subliminal-2.7.1 → subliminal-2.8.0}/LICENSE +0 -0
  104. {subliminal-2.7.1 → subliminal-2.8.0}/MANIFEST.in +0 -0
  105. {subliminal-2.7.1 → subliminal-2.8.0}/README.rst +0 -0
  106. {subliminal-2.7.1 → subliminal-2.8.0}/RELEASING.md +0 -0
  107. {subliminal-2.7.1 → subliminal-2.8.0}/changelog.d/.gitignore +0 -0
  108. {subliminal-2.7.1 → subliminal-2.8.0}/docs/Makefile +0 -0
  109. {subliminal-2.7.1 → subliminal-2.8.0}/docs/_intersphinx/README.md +0 -0
  110. {subliminal-2.7.1 → subliminal-2.8.0}/docs/_intersphinx/importlib_metadata_objects.inv +0 -0
  111. {subliminal-2.7.1 → subliminal-2.8.0}/docs/_intersphinx/importlib_metadata_objects.txt +0 -0
  112. {subliminal-2.7.1 → subliminal-2.8.0}/docs/_static/.gitignore +0 -0
  113. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/cache.rst +0 -0
  114. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/cli.rst +0 -0
  115. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/core.rst +0 -0
  116. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/exceptions.rst +0 -0
  117. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/extensions.rst +0 -0
  118. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/providers.rst +0 -0
  119. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/refiners.rst +0 -0
  120. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/score.rst +0 -0
  121. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/subtitle.rst +0 -0
  122. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/utils.rst +0 -0
  123. {subliminal-2.7.1 → subliminal-2.8.0}/docs/api/video.rst +0 -0
  124. {subliminal-2.7.1 → subliminal-2.8.0}/docs/assets/config.toml +0 -0
  125. {subliminal-2.7.1 → subliminal-2.8.0}/docs/cassettes/test_usage.yaml +0 -0
  126. {subliminal-2.7.1 → subliminal-2.8.0}/docs/conftest.py +0 -0
  127. {subliminal-2.7.1 → subliminal-2.8.0}/docs/index.rst +0 -0
  128. {subliminal-2.7.1 → subliminal-2.8.0}/docs/make.bat +0 -0
  129. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/changelog.rst +0 -0
  130. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/cli.rst +0 -0
  131. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/configuration_file.rst +0 -0
  132. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/how_it_works.rst +0 -0
  133. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/installation.rst +0 -0
  134. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/provider_guide.rst +0 -0
  135. {subliminal-2.7.1 → subliminal-2.8.0}/docs/user/usage.rst +0 -0
  136. {subliminal-2.7.1 → subliminal-2.8.0}/hatch.toml +0 -0
  137. {subliminal-2.7.1 → subliminal-2.8.0}/scripts/.gitignore +0 -0
  138. {subliminal-2.7.1 → subliminal-2.8.0}/scripts/prepare-release-pr.py +0 -0
  139. {subliminal-2.7.1 → subliminal-2.8.0}/scripts/prepare_tests.py +0 -0
  140. {subliminal-2.7.1 → subliminal-2.8.0}/scripts/release.py +0 -0
  141. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/__init__.py +0 -0
  142. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/__main__.py +0 -0
  143. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/archives.py +0 -0
  144. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cache.py +0 -0
  145. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/__init__.py +0 -0
  146. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/cli.py +0 -0
  147. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/commands/__init__.py +0 -0
  148. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/generate_config.py +0 -0
  149. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/cli/helpers.py +0 -0
  150. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/__init__.py +0 -0
  151. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/addic7ed.py +0 -0
  152. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/opensubtitles.py +0 -0
  153. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/opensubtitlescom.py +0 -0
  154. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/subtitulamos.py +0 -0
  155. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/converters/tvsubtitles.py +0 -0
  156. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/exceptions.py +0 -0
  157. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/extensions.py +0 -0
  158. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/matches.py +0 -0
  159. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/__init__.py +0 -0
  160. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/addic7ed.py +0 -0
  161. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/bsplayer.py +0 -0
  162. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/gestdown.py +0 -0
  163. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/mock.py +0 -0
  164. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/napiprojekt.py +0 -0
  165. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/podnapisi.py +0 -0
  166. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/subtis.py +0 -0
  167. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/subtitulamos.py +0 -0
  168. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/providers/tvsubtitles.py +0 -0
  169. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/py.typed +0 -0
  170. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/refiners/__init__.py +0 -0
  171. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/score.py +0 -0
  172. {subliminal-2.7.1 → subliminal-2.8.0}/src/subliminal/subtitle.py +0 -0
  173. {subliminal-2.7.1 → subliminal-2.8.0}/tests/__init__.py +0 -0
  174. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_download_subtitle.yaml +0 -0
  175. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_id.yaml +0 -0
  176. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_id_country.yaml +0 -0
  177. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_id_quote_dots_mixed_case.yaml +0 -0
  178. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_id_with_comma.yaml +0 -0
  179. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_id_year.yaml +0 -0
  180. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_get_show_ids.yaml +0 -0
  181. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_list_subtitles.yaml +0 -0
  182. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_list_subtitles_episode_alternative_series.yaml +0 -0
  183. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_list_subtitles_show_with_asterisk.yaml +0 -0
  184. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query.yaml +0 -0
  185. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_no_year.yaml +0 -0
  186. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_parsing.yaml +0 -0
  187. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_parsing_colon.yaml +0 -0
  188. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_parsing_dash.yaml +0 -0
  189. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_parsing_quote_dots_mixed_case.yaml +0 -0
  190. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_wrong_series.yaml +0 -0
  191. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/addic7ed/test_query_year.yaml +0 -0
  192. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/bsplayer/test_download_subtitle.yaml +0 -0
  193. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/bsplayer/test_list_subtitles_hash.yaml +0 -0
  194. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/bsplayer/test_login.yaml +0 -0
  195. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/bsplayer/test_logout.yaml +0 -0
  196. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/bsplayer/test_query_hash_size.yaml +0 -0
  197. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/cli/test_cli_download.yaml +0 -0
  198. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_download_subtitles.yaml +0 -0
  199. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_list_subtitles.yaml +0 -0
  200. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_query_microdvd.yaml +0 -0
  201. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_query_srt.yaml +0 -0
  202. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_query_srt_reencode.yaml +0 -0
  203. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/napiprojekt/test_query_wrong_hash.yaml +0 -0
  204. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_get_id.yaml +0 -0
  205. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_get_title.yaml +0 -0
  206. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_get_wrong_id.yaml +0 -0
  207. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_get_wrong_title.yaml +0 -0
  208. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_episode.yaml +0 -0
  209. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_episode_original_series.yaml +0 -0
  210. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_episode_with_country.yaml +0 -0
  211. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_episode_with_country_hoc_us.yaml +0 -0
  212. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_episode_year.yaml +0 -0
  213. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_movie.yaml +0 -0
  214. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_refine_movie_guess_alternative_title.yaml +0 -0
  215. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_search.yaml +0 -0
  216. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_search_page.yaml +0 -0
  217. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_search_type.yaml +0 -0
  218. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_search_wrong_title.yaml +0 -0
  219. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/omdb/test_search_year.yaml +0 -0
  220. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_download_subtitle.yaml +0 -0
  221. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_episode.yaml +0 -0
  222. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie.yaml +0 -0
  223. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_list_subtitles_movie_no_hash.yaml +0 -0
  224. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_login.yaml +0 -0
  225. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_login_bad_password.yaml +0 -0
  226. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_logout.yaml +0 -0
  227. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_hash_size.yaml +0 -0
  228. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_imdb_id.yaml +0 -0
  229. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_max_result_pages.yaml +0 -0
  230. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_query_episode.yaml +0 -0
  231. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_query_movie.yaml +0 -0
  232. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_query_season_episode.yaml +0 -0
  233. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_tag_movie.yaml +0 -0
  234. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_query_wrong_hash_wrong_size.yaml +0 -0
  235. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/opensubtitlescom/test_user_infos.yaml +0 -0
  236. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_download_subtitle.yaml +0 -0
  237. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_download_subtitles_with_title_unicode.yaml +0 -0
  238. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_list_subtitles_episode.yaml +0 -0
  239. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_list_subtitles_episode_alternative_series.yaml +0 -0
  240. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_list_subtitles_movie.yaml +0 -0
  241. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_query_episode.yaml +0 -0
  242. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/podnapisi/test_query_movie.yaml +0 -0
  243. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/providers/test_download_best_subtitles_min_score.yaml +0 -0
  244. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/providers/test_download_best_subtitles_only_one.yaml +0 -0
  245. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_download_subtitle.yaml +0 -0
  246. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_list_subtitles_hash.yaml +0 -0
  247. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_list_subtitles_movie.yaml +0 -0
  248. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_list_subtitles_movie_alternative.yaml +0 -0
  249. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_list_subtitles_movie_with_size.yaml +0 -0
  250. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtis/test_list_subtitles_no_match.yaml +0 -0
  251. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_download_subtitle.yaml +0 -0
  252. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_download_subtitle_first_episode.yaml +0 -0
  253. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_download_subtitle_foo.yaml +0 -0
  254. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_download_subtitle_last_season.yaml +0 -0
  255. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_download_subtitle_year.yaml +0 -0
  256. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_episode.yaml +0 -0
  257. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_language.yaml +0 -0
  258. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_season.yaml +0 -0
  259. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_list_subtitles_not_exist_series.yaml +0 -0
  260. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/subtitulamos/test_list_subtitles_with_spanish_non_mx_search.yaml +0 -0
  261. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_get_movie_id.yaml +0 -0
  262. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_get_movie_id_failed.yaml +0 -0
  263. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_get_series_id.yaml +0 -0
  264. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_get_series_wrong_id.yaml +0 -0
  265. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_episode.yaml +0 -0
  266. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_episode_original_series.yaml +0 -0
  267. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_episode_with_country.yaml +0 -0
  268. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_episode_with_country_hoc_us.yaml +0 -0
  269. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_episode_year.yaml +0 -0
  270. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_movie.yaml +0 -0
  271. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_refine_movie_guess_alternative_title.yaml +0 -0
  272. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_movie.yaml +0 -0
  273. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_movie_page.yaml +0 -0
  274. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_movie_wrong_title.yaml +0 -0
  275. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_movie_year.yaml +0 -0
  276. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_series.yaml +0 -0
  277. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tmdb/test_search_series_wrong_name.yaml +0 -0
  278. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_get_series.yaml +0 -0
  279. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_get_series_actors.yaml +0 -0
  280. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_get_series_actors_wrong_id.yaml +0 -0
  281. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_get_series_wrong_id.yaml +0 -0
  282. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_login.yaml +0 -0
  283. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_login_error.yaml +0 -0
  284. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_query_series_episodes.yaml +0 -0
  285. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_query_series_episodes_wrong_season.yaml +0 -0
  286. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine.yaml +0 -0
  287. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_ambiguous.yaml +0 -0
  288. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_ambiguous_2.yaml +0 -0
  289. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_alternative_series.yaml +0 -0
  290. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_no_year.yaml +0 -0
  291. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_partial.yaml +0 -0
  292. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_with_comma.yaml +0 -0
  293. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_with_country.yaml +0 -0
  294. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_with_country_hoc_us.yaml +0 -0
  295. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_refine_episode_year.yaml +0 -0
  296. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_search_series.yaml +0 -0
  297. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvdb/test_search_series_wrong_name.yaml +0 -0
  298. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_download_subtitle.yaml +0 -0
  299. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_download_subtitle_with_quote.yaml +0 -0
  300. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_get_episode_ids.yaml +0 -0
  301. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_get_episode_ids_wrong_season.yaml +0 -0
  302. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_list_subtitles.yaml +0 -0
  303. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_list_subtitles_episode_alternative_series.yaml +0 -0
  304. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_query.yaml +0 -0
  305. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_query_no_year.yaml +0 -0
  306. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_query_with_quote.yaml +0 -0
  307. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_query_wrong_episode.yaml +0 -0
  308. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_query_wrong_series.yaml +0 -0
  309. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id.yaml +0 -0
  310. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_ambiguous.yaml +0 -0
  311. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_error.yaml +0 -0
  312. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_incomplete.yaml +0 -0
  313. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_no_year.yaml +0 -0
  314. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_uk.yaml +0 -0
  315. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_us.yaml +0 -0
  316. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cassettes/tvsubtitles/test_search_show_id_year_in_title.yaml +0 -0
  317. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cli/test_cli.py +0 -0
  318. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cli/test_generate_config.py +0 -0
  319. {subliminal-2.7.1 → subliminal-2.8.0}/tests/cli/test_helpers.py +0 -0
  320. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_addic7ed.py +0 -0
  321. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_bsplayer.py +0 -0
  322. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_napiprojekt.py +0 -0
  323. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_podnapisi.py +0 -0
  324. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_subtis.py +0 -0
  325. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_subtitulamos.py +0 -0
  326. {subliminal-2.7.1 → subliminal-2.8.0}/tests/providers/test_tvsubtitles.py +0 -0
  327. {subliminal-2.7.1 → subliminal-2.8.0}/tests/refiners/test_hash.py +0 -0
  328. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_archives.py +0 -0
  329. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_cache.py +0 -0
  330. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_extensions.py +0 -0
  331. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_matches.py +0 -0
  332. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_provider.py +0 -0
  333. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_score.py +0 -0
  334. {subliminal-2.7.1 → subliminal-2.8.0}/tests/test_subtitle.py +0 -0
  335. {subliminal-2.7.1 → subliminal-2.8.0}/tox.ini +0 -0
@@ -10,13 +10,13 @@ runs:
10
10
  run: |
11
11
  echo "::error title=⛔ error hint::Support Linux, Windows, and macOS Only"
12
12
  exit 1
13
- - uses: actions/checkout@v7
13
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
14
14
  with:
15
15
  persist-credentials: false
16
16
  fetch-depth: 0
17
17
  - name: Cache test data
18
18
  id: cache-test-data
19
- uses: actions/cache@v5
19
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
20
20
  with:
21
21
  path: tests/data/
22
22
  enableCrossOsArchive: true
@@ -30,11 +30,11 @@ runs:
30
30
  exit 1
31
31
  - name: Install other test software (on Linux only)
32
32
  if: steps.cache-test-data.outputs.cache-hit != 'true'
33
- uses: awalsh128/cache-apt-pkgs-action@v1
33
+ uses: awalsh128/cache-apt-pkgs-action@553a35bb8ebd9fcabcb1c9451aa4c98e1b4ca8a9 # v1.6.3
34
34
  with:
35
35
  packages: rar
36
36
  version: 1.0
37
- - uses: actions/setup-python@v6
37
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
38
38
  if: steps.cache-test-data.outputs.cache-hit != 'true'
39
39
  with:
40
40
  python-version-file: .python-version-default
@@ -20,7 +20,7 @@ jobs:
20
20
  check-manifest:
21
21
  runs-on: ubuntu-latest
22
22
  steps:
23
- - uses: actions/checkout@v7
23
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
24
24
  with:
25
25
  persist-credentials: false
26
26
  - run: pipx run check-manifest --ignore "_version.py"
@@ -28,23 +28,23 @@ jobs:
28
28
  pre-commit:
29
29
  runs-on: ubuntu-latest
30
30
  steps:
31
- - uses: actions/checkout@v7
31
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
32
32
  with:
33
33
  persist-credentials: false
34
- - uses: actions/setup-python@v6
34
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
35
35
  with:
36
36
  python-version-file: .python-version-default
37
- - uses: pre-commit/action@v3.0.1
37
+ - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
38
38
 
39
39
  typing:
40
40
  runs-on: ubuntu-latest
41
41
  permissions:
42
42
  contents: read
43
43
  steps:
44
- - uses: actions/checkout@v7
44
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
45
45
  with:
46
46
  persist-credentials: false
47
- - uses: actions/setup-python@v6
47
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
48
48
  with:
49
49
  python-version-file: .python-version-default
50
50
  - name: Install hatch
@@ -58,10 +58,10 @@ jobs:
58
58
  name: Build docs and run doctests
59
59
  runs-on: ubuntu-latest
60
60
  steps:
61
- - uses: actions/checkout@v7
61
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
62
62
  with:
63
63
  persist-credentials: false
64
- - uses: actions/setup-python@v6
64
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
65
65
  with:
66
66
  # Keep in sync with tox/docs, hatch.toml and .readthedocs.yaml.
67
67
  python-version-file: .python-version-default
@@ -76,7 +76,7 @@ jobs:
76
76
  - name: Check changelog
77
77
  run: hatch run changelog:run
78
78
 
79
- - uses: actions/upload-artifact@v7
79
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
80
80
  with:
81
81
  name: docs
82
82
  path: docs/_build/
@@ -86,10 +86,10 @@ jobs:
86
86
  runs-on: ubuntu-latest
87
87
 
88
88
  steps:
89
- - uses: actions/checkout@v7
89
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
90
90
  with:
91
91
  persist-credentials: false
92
- - uses: actions/setup-python@v6
92
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
93
93
  with:
94
94
  python-version-file: .python-version-default
95
95
  cache: pip
@@ -104,12 +104,12 @@ jobs:
104
104
  runs-on: ubuntu-latest
105
105
 
106
106
  steps:
107
- - uses: actions/checkout@v7
107
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
108
108
  with:
109
109
  persist-credentials: false
110
110
  fetch-depth: 0
111
111
 
112
- - uses: hynek/build-and-inspect-python-package@v2
112
+ - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
113
113
  id: baipp
114
114
 
115
115
  outputs:
@@ -122,7 +122,7 @@ jobs:
122
122
  runs-on: ubuntu-latest
123
123
 
124
124
  steps:
125
- - uses: actions/checkout@v7
125
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
126
126
  with:
127
127
  persist-credentials: false
128
128
  fetch-depth: 0
@@ -142,10 +142,10 @@ jobs:
142
142
  # Created by the build-and-inspect-python-package action above.
143
143
  py: ${{ fromJson(needs.build-package.outputs.supported-python-versions) }}
144
144
  steps:
145
- - uses: actions/checkout@v7
145
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
146
146
  with:
147
147
  persist-credentials: false
148
- - uses: actions/setup-python@v6
148
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
149
149
  with:
150
150
  python-version: ${{ matrix.py }}
151
151
  allow-prereleases: true
@@ -181,7 +181,7 @@ jobs:
181
181
  shell: bash
182
182
 
183
183
  - name: Store coverage file
184
- uses: actions/upload-artifact@v7
184
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
185
185
  with:
186
186
  name: coverage-${{ matrix.os }}-${{ matrix.py }}
187
187
  path: .coverage*
@@ -195,7 +195,7 @@ jobs:
195
195
  timeout-minutes: 10
196
196
  if: github.event_name == 'push'
197
197
  steps:
198
- - uses: actions/checkout@v7
198
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
199
199
  with:
200
200
  persist-credentials: false
201
201
  fetch-depth: 0
@@ -204,7 +204,7 @@ jobs:
204
204
  - name: Display downloaded files
205
205
  run: ls -R tests/data
206
206
  - name: Test in FreeBSD
207
- uses: vmactions/freebsd-vm@v1
207
+ uses: vmactions/freebsd-vm@c46abacb49f09938ca4e1702d15d836285d694cc # v1.5.9
208
208
  with:
209
209
  release: "15.0"
210
210
  usesh: true
@@ -222,7 +222,7 @@ jobs:
222
222
  hatch -v run "${ENV}:test-cov"
223
223
 
224
224
  - name: Store coverage file
225
- uses: actions/upload-artifact@v7
225
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
226
226
  with:
227
227
  name: coverage-freebsd
228
228
  path: .coverage*
@@ -238,17 +238,17 @@ jobs:
238
238
  pull-requests: write
239
239
  contents: write
240
240
  steps:
241
- - uses: actions/checkout@v7
241
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
242
242
  with:
243
243
  # py-cov-action/python-coverage-comment-action needs git credentials
244
244
  persist-credentials: true
245
- - uses: actions/setup-python@v6
245
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
246
246
  with:
247
247
  python-version-file: .python-version-default
248
- - uses: hynek/setup-cached-uv@v2
248
+ - uses: hynek/setup-cached-uv@34e35d30f1ebc7421a5cc733bca38dcc62603960 # v2.6.0
249
249
 
250
250
  - name: Download coverage data
251
- uses: actions/download-artifact@v8
251
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
252
252
  with:
253
253
  pattern: coverage-*
254
254
  merge-multiple: true
@@ -264,19 +264,19 @@ jobs:
264
264
  coverage report --skip-covered --skip-empty --show-missing --format=markdown >> $GITHUB_STEP_SUMMARY
265
265
 
266
266
  - name: Upload HTML report if check failed.
267
- uses: actions/upload-artifact@v7
267
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
268
268
  with:
269
269
  name: html-report
270
270
  path: htmlcov
271
271
 
272
272
  - name: Coverage comment
273
273
  id: coverage_comment
274
- uses: py-cov-action/python-coverage-comment-action@v3
274
+ uses: py-cov-action/python-coverage-comment-action@e5fb2218463c3377f3504b0c5b5646ed53da7a2f # v4.5
275
275
  with:
276
276
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
277
277
 
278
278
  - name: Store Pull Request comment to be posted
279
- uses: actions/upload-artifact@v7
279
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
280
280
  if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
281
281
  with:
282
282
  # If you use a different name, update COMMENT_ARTIFACT_NAME accordingly
@@ -289,10 +289,10 @@ jobs:
289
289
  runs-on: ubuntu-latest
290
290
  needs: [build-package, prepare-test]
291
291
  steps:
292
- - uses: actions/checkout@v7
292
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
293
293
  with:
294
294
  persist-credentials: false
295
- - uses: actions/setup-python@v6
295
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
296
296
  id: setup
297
297
  with:
298
298
  python-version-file: .python-version-default
@@ -329,7 +329,7 @@ jobs:
329
329
  shell: bash
330
330
 
331
331
  - name: Store coverage file
332
- uses: actions/upload-artifact@v7
332
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
333
333
  if: ${{ failure() }}
334
334
  with:
335
335
  name: core-coverage
@@ -355,6 +355,6 @@ jobs:
355
355
 
356
356
  steps:
357
357
  - name: Decide whether the needed jobs succeeded or failed
358
- uses: re-actors/alls-green@release/v1
358
+ uses: re-actors/alls-green@b5b5b37504aa4183270bd3d855c52a67f212be35 # v1.3.0
359
359
  with:
360
360
  jobs: ${{ toJSON(needs) }}
@@ -30,7 +30,7 @@ jobs:
30
30
  # DO NOT run actions/checkout here, for security reasons
31
31
  # For details, refer to https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
32
32
  - name: Post comment
33
- uses: py-cov-action/python-coverage-comment-action@v3
33
+ uses: py-cov-action/python-coverage-comment-action@e5fb2218463c3377f3504b0c5b5646ed53da7a2f # v4.5
34
34
  with:
35
35
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
36
  GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
@@ -35,12 +35,12 @@ jobs:
35
35
  steps:
36
36
  - name: Checkout repository
37
37
  if: github.event_name == 'push' || github.event_name == 'pull_request'
38
- uses: actions/checkout@v7
38
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
39
39
  with:
40
40
  persist-credentials: false
41
41
  - name: Checkout repository
42
42
  if: github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch'
43
- uses: actions/checkout@v7
43
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
44
44
  with:
45
45
  ref: ${{ inputs.tag-name }}
46
46
  persist-credentials: false
@@ -50,15 +50,15 @@ jobs:
50
50
  github.event_name == 'push'
51
51
  || github.event_name == 'workflow_call'
52
52
  || github.event_name == 'workflow_dispatch'
53
- uses: docker/setup-qemu-action@v4
53
+ uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
54
54
 
55
55
  - name: Set up Docker Buildx
56
- uses: docker/setup-buildx-action@v4
56
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
57
57
  with:
58
58
  cache-binary: false
59
59
 
60
60
  - name: Log in to the Container registry
61
- uses: docker/login-action@v4
61
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
62
62
  with:
63
63
  registry: ${{ env.REGISTRY }}
64
64
  username: ${{ github.actor }}
@@ -66,7 +66,7 @@ jobs:
66
66
 
67
67
  - name: Extract metadata (tags, labels) for Docker
68
68
  id: meta
69
- uses: docker/metadata-action@v6
69
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
70
70
  with:
71
71
  images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
72
72
  tags: |
@@ -76,7 +76,7 @@ jobs:
76
76
  type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/0.') }}
77
77
 
78
78
  - name: Test building Docker image
79
- uses: docker/build-push-action@v7
79
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
80
80
  if: github.event_name == 'pull_request'
81
81
  with:
82
82
  context: .
@@ -86,7 +86,7 @@ jobs:
86
86
  cache-to: type=gha,mode=max
87
87
 
88
88
  - name: Build and push Docker image
89
- uses: docker/build-push-action@v7
89
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
90
90
  if: |
91
91
  github.event_name == 'push'
92
92
  || github.event_name == 'workflow_call'
@@ -29,14 +29,14 @@ jobs:
29
29
  pull-requests: write
30
30
 
31
31
  steps:
32
- - uses: actions/checkout@v7
32
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
33
33
  with:
34
34
  fetch-depth: 0
35
35
  # persist-credentials is needed in order for us to push the release branch.
36
36
  persist-credentials: true
37
37
 
38
38
  - name: Set up Python
39
- uses: actions/setup-python@v6
39
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
40
40
  with:
41
41
  python-version-file: .python-version-default
42
42
  cache: pip
@@ -31,12 +31,12 @@ jobs:
31
31
  runs-on: ubuntu-latest
32
32
  steps:
33
33
  - name: Checkout
34
- uses: actions/checkout@v7
34
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
35
35
  if: github.event_name == 'push'
36
36
  with:
37
37
  persist-credentials: false
38
38
  - name: Checkout
39
- uses: actions/checkout@v7
39
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
40
40
  if: |
41
41
  github.event_name == 'workflow_dispatch'
42
42
  || github.event_name == 'workflow_call'
@@ -44,7 +44,7 @@ jobs:
44
44
  ref: ${{ inputs.tag-name }}
45
45
  persist-credentials: false
46
46
  - name: Build dist
47
- uses: hynek/build-and-inspect-python-package@v2
47
+ uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
48
48
  id: baipp
49
49
  outputs:
50
50
  tag: ${{ steps.baipp.outputs.package_version }}
@@ -63,19 +63,19 @@ jobs:
63
63
  # Publish a Github release when a tag was pushed, or it's called with a tag.
64
64
  steps:
65
65
  - name: Checkout
66
- uses: actions/checkout@v7
66
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
67
67
  with:
68
68
  fetch-tags: true
69
69
  ref: ${{ needs.build-package.outputs.tag }}
70
70
  persist-credentials: false
71
71
 
72
72
  - name: Download packages built by build-and-inspect-python-package
73
- uses: actions/download-artifact@v8
73
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
74
74
  with:
75
75
  name: Packages
76
76
  path: dist
77
77
  - name: Publish GitHub Release
78
- uses: softprops/action-gh-release@v3
78
+ uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
79
79
  with:
80
80
  files: dist/*
81
81
  generate_release_notes: true
@@ -20,12 +20,12 @@ jobs:
20
20
  name: Build & verify package
21
21
  runs-on: ubuntu-latest
22
22
  steps:
23
- - uses: actions/checkout@v7
23
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
24
24
  with:
25
25
  fetch-depth: 0
26
26
  persist-credentials: false
27
27
 
28
- - uses: hynek/build-and-inspect-python-package@v2
28
+ - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
29
29
  id: baipp
30
30
 
31
31
  publish-to-pypi:
@@ -45,9 +45,9 @@ jobs:
45
45
  && github.event.action == 'published'
46
46
  steps:
47
47
  - name: Download packages built by build-and-inspect-python-package
48
- uses: actions/download-artifact@v8
48
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
49
49
  with:
50
50
  name: Packages
51
51
  path: dist
52
52
  - name: Publish package distributions to PyPI
53
- uses: pypa/gh-action-pypi-publish@release/v1
53
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -24,10 +24,10 @@ jobs:
24
24
  || github.event_name == 'workflow_dispatch'
25
25
  runs-on: ubuntu-latest
26
26
  steps:
27
- - uses: actions/checkout@v7
27
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
28
28
  with:
29
29
  persist-credentials: false
30
- - uses: actions/setup-python@v6
30
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
31
31
  with:
32
32
  python-version: "3.x"
33
33
  - name: Prepare tests
@@ -24,12 +24,12 @@ jobs:
24
24
  name: Build & verify package
25
25
  runs-on: ubuntu-latest
26
26
  steps:
27
- - uses: actions/checkout@v7
27
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
28
28
  with:
29
29
  fetch-depth: 0
30
30
  persist-credentials: false
31
31
 
32
- - uses: hynek/build-and-inspect-python-package@v2
32
+ - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
33
33
 
34
34
  define-tag:
35
35
  name: Define tag
@@ -72,7 +72,7 @@ jobs:
72
72
  env:
73
73
  RELEASE_VERSION: ${{ needs.define-tag.outputs.tag }}
74
74
  steps:
75
- - uses: actions/checkout@v7
75
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
76
76
  with:
77
77
  fetch-depth: 0
78
78
  # keep credentials to create a tag
@@ -2,6 +2,39 @@
2
2
 
3
3
  .. towncrier release notes start
4
4
 
5
+ 2.8.0 (2026-10-13)
6
+ ^^^^^^^^^^^^^^^^^^
7
+
8
+ Changes
9
+ -------
10
+
11
+ - Added `ProviderPool.failed_providers` - a set of providers that had an error.
12
+ Changed the user-facing error messages of the `download` command to explicitly distinguish
13
+ discarded providers, which are not used for the rest of the download, from those that errored
14
+ out but were still kept in the pool. (`#1374 <https://github.com/Diaoul/subliminal/issues/1374>`__)
15
+ - add ProviderResult class to keep track of queries to providers (`#1381 <https://github.com/Diaoul/subliminal/issues/1381>`__)
16
+
17
+
18
+ Provider Changes
19
+ ----------------
20
+
21
+ - Stop the opensubtitlescom pagination when a page fails and keep the subtitles already found (`#1373 <https://github.com/Diaoul/subliminal/issues/1373>`__)
22
+ - fix: OpenSubtitlesCom was not using hash if OpenSubtitles was not used also (`#1382 <https://github.com/Diaoul/subliminal/issues/1382>`__)
23
+ - Search episodes with OpenSubtitlesCom by the show's IMDb/TMDB id. (`#1384 <https://github.com/Diaoul/subliminal/issues/1384>`__)
24
+
25
+
26
+ Refiner Changes
27
+ ---------------
28
+
29
+ - omdb: use the IMDB id to backfill missing title and year metadata (`#1375 <https://github.com/Diaoul/subliminal/issues/1375>`__)
30
+
31
+
32
+ CLI Changes
33
+ -----------
34
+
35
+ - improve message for ignored videos (`#1387 <https://github.com/Diaoul/subliminal/issues/1387>`__)
36
+
37
+
5
38
  2.7.1 (2026-07-22)
6
39
  ^^^^^^^^^^^^^^^^^^
7
40
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: subliminal
3
- Version: 2.7.1
3
+ Version: 2.8.0
4
4
  Summary: Subtitles, faster than your thoughts
5
5
  Project-URL: homepage, https://github.com/Diaoul/subliminal
6
6
  Project-URL: repository, https://github.com/Diaoul/subliminal
@@ -39,6 +39,7 @@ Requires-Dist: requests>=2.0
39
39
  Requires-Dist: srt>=3.5
40
40
  Requires-Dist: stevedore>=3.0
41
41
  Requires-Dist: tomlkit>=0.13.2
42
+ Requires-Dist: typing-extensions>=4.10
42
43
  Provides-Extra: dev
43
44
  Requires-Dist: pre-commit>=2.9.3; extra == 'dev'
44
45
  Requires-Dist: tox; extra == 'dev'
Binary file
@@ -311,15 +311,18 @@ intersphinx_mapping = {
311
311
  }
312
312
 
313
313
 
314
- # -- Options for autodoc -----------------------------------------------------
314
+ # -- Options for autodoc -------------------------------------------------------
315
315
  autodoc_member_order = 'bysource'
316
316
 
317
317
  autodoc_default_flags = ['members']
318
318
 
319
319
 
320
- # -- Options for sphinx-autodoc-typehints ------------------------------------
320
+ # -- Options for sphinx-autodoc-typehints --------------------------------------
321
321
  # https://github.com/tox-dev/sphinx-autodoc-typehints
322
322
 
323
323
  always_use_bars_union = True
324
324
 
325
325
  set_type_checking_flag = False
326
+
327
+ # -- Options for the linkcheck builder -----------------------------------------
328
+ linkcheck_ignore = [r'https://stackoverflow.com/.*']
@@ -49,6 +49,7 @@ dependencies = [
49
49
  "srt>=3.5",
50
50
  "stevedore>=3.0",
51
51
  "tomlkit>=0.13.2",
52
+ "typing_extensions>=4.10", # TypedDict extra_items
52
53
  ]
53
54
 
54
55
  # extras
@@ -5,12 +5,15 @@ from __future__ import annotations
5
5
  import logging
6
6
  import re
7
7
  from datetime import timedelta
8
- from typing import Any
8
+ from typing import TYPE_CHECKING, Any
9
9
 
10
10
  import click
11
11
  from babelfish import Error as BabelfishError # type: ignore[import-untyped]
12
12
  from babelfish import Language
13
13
 
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Set
16
+
14
17
  logger = logging.getLogger(__name__)
15
18
 
16
19
 
@@ -54,6 +57,22 @@ class AgeParamType(click.ParamType):
54
57
  return timedelta(**{k: int(v) for k, v in match.groupdict(0).items()})
55
58
 
56
59
 
60
+ def format_provider_errors(failed_providers: Set[str], discarded_providers: Set[str], *, video_count: int) -> str:
61
+ """Tell the user which providers had an error, and how the error affected the end results.
62
+
63
+ With one video both kinds of error have the same result, so one sentence covers them.
64
+ """
65
+ if video_count == 1:
66
+ return f'These providers had an error and found no subtitles: {", ".join(sorted(failed_providers))}.'
67
+
68
+ groups = (
69
+ ('These providers had an error and were skipped for the rest of the download', sorted(discarded_providers)),
70
+ ('These providers had an error on some videos', sorted(failed_providers - discarded_providers)),
71
+ )
72
+ sentences = [f'{label}: {", ".join(names)}.' for label, names in groups if names]
73
+ return ' '.join([*sentences, 'Some subtitles can be missing.'])
74
+
75
+
57
76
  def plural(quantity: int, name: str, *, bold: bool = True, **kwargs: Any) -> str:
58
77
  """Format a quantity with plural."""
59
78
  return '{} {}{}'.format(
@@ -35,7 +35,7 @@ from subliminal.exceptions import GuessingError
35
35
  from subliminal.extensions import get_default_providers, get_default_refiners
36
36
  from subliminal.utils import NameResolver, merge_extend_and_ignore_unions
37
37
 
38
- from ._format import AgeParamType, LanguageParamType, plural
38
+ from ._format import AgeParamType, LanguageParamType, format_provider_errors, plural
39
39
 
40
40
  if TYPE_CHECKING:
41
41
  from collections.abc import Sequence
@@ -530,10 +530,14 @@ def download(
530
530
  for video in ignored_videos:
531
531
  video_name = os.path.split(video.name)[1]
532
532
  msg = f'{video_name!r} ignored'
533
+ # Add information about existing subtitle languages
534
+ langs = ', '.join(str(s) for s in video.subtitle_languages) or 'none'
535
+ days = f'{video.age.days:d} day{"s" if video.age.days > 1 else ""}'
536
+ msg += f' - existing subtitles: {langs}'
537
+ # Add information about the video age
533
538
  if video.exists:
534
- langs = ', '.join(str(s) for s in video.subtitle_languages) or 'none'
535
539
  days = f'{video.age.days:d} day{"s" if video.age.days > 1 else ""}'
536
- msg += f' - subtitles: {langs} / age: {days}'
540
+ msg += f' - age: {days}'
537
541
  else:
538
542
  msg += ' - not a video file'
539
543
  click.secho(msg, fg='yellow')
@@ -591,9 +595,9 @@ def download(
591
595
  )
592
596
  downloaded_subtitles[v] = subtitles
593
597
 
594
- if pp.discarded_providers: # pragma: no cover
598
+ if pp.failed_providers:
595
599
  click.secho(
596
- f'Some providers have been discarded due to unexpected errors: {", ".join(pp.discarded_providers)}',
600
+ format_provider_errors(pp.failed_providers, pp.discarded_providers, video_count=len(videos)),
597
601
  fg='yellow',
598
602
  )
599
603