From 8ce99ab58f0353750116b97e179b710e02e0a269 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:47:16 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=F0=9F=93=A6=20chore(github):=20add=20pub?= =?UTF-8?q?lish.yml=20and=20python=5Ftest.yml=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added publish.yml workflow for publishing releases to PyPI. - Added python_test.yml workflow for running tests on multiple Python versions. --- .github/workflows/publish.yml | 24 +++++++++++++++++ .github/workflows/python-publish.yml | 39 ---------------------------- .github/workflows/python_test.yml | 32 +++++++++++++++++++++++ .github/workflows/test.yml | 38 --------------------------- 4 files changed, 56 insertions(+), 77 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/python-publish.yml create mode 100644 .github/workflows/python_test.yml delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..1cdaa09 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,24 @@ +name: publish +on: + workflow_dispatch: + push: + tags: + - pypi* + +permissions: + contents: read + +jobs: + pypi-publish: + name: upload release to PyPI + runs-on: ubuntu-latest + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + steps: + - uses: actions/checkout@v3 + + - uses: pdm-project/setup-pdm@v3 + + - name: Publish package distributions to PyPI + run: pdm publish diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml deleted file mode 100644 index bdaab28..0000000 --- a/.github/workflows/python-publish.yml +++ /dev/null @@ -1,39 +0,0 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: Upload Python Package - -on: - release: - types: [published] - -permissions: - contents: read - -jobs: - deploy: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build - - name: Build package - run: python -m build - - name: Publish package - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml new file mode 100644 index 0000000..22da9a6 --- /dev/null +++ b/.github/workflows/python_test.yml @@ -0,0 +1,32 @@ +name: Run tests + +on: + workflow_dispatch: + push: + branches: + - main + - dev + - develop + - '**-develop' + +jobs: + Testing: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [ '3.8', '3.9', '3.10', '3.11' ] + os: [ ubuntu-latest ] # , windows-latest, macos-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up PDM + uses: pdm-project/setup-pdm@v3 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + pdm install --no-lock -G testing + - name: Run Tests + run: | + pdm run -v pytest tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 3f19064..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Run tests - -on: - push: - branches: - - main - - develop - - '**-develop' - pull_request: - branches: - - main - - develop - workflow_dispatch: - -jobs: - test: - - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: [ 3.7.x, 3.8.x, 3.9.x,3.10.x ] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - architecture: "x64" - - name: Install dependencies - run: | - pip install -r subtitle_utils/requirements.txt - python -m pip install pytest - - - name: Run tests - run: | - cd test - pytest \ No newline at end of file From 130bc3a1901a81275468536a412e55a649c99bde Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:47:55 +0800 Subject: [PATCH 02/13] :sparkles: feat: update version to 1.0.0 and add additional author --- .gitignore | 1 + .pre-commit-config.yaml | 14 +++ poetry.lock | 185 ---------------------------------------- pyproject.toml | 49 +++++++---- test/main.py | 15 ---- test/test.bcc | 1 - test/test_method.py | 54 ------------ 7 files changed, 47 insertions(+), 272 deletions(-) create mode 100644 .pre-commit-config.yaml delete mode 100644 poetry.lock delete mode 100644 test/main.py delete mode 100644 test/test.bcc delete mode 100644 test/test_method.py diff --git a/.gitignore b/.gitignore index 71d8221..59fe119 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,4 @@ dmypy.json # Pyre type checker .pyre/ +/.pdm-python diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..ff2065a --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + # check python requirements + - repo: https://github.com/pdm-project/pdm + rev: 2.11.2 # a PDM release exposing the hook + hooks: + - id: pdm-lock-check diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index f00973d..0000000 --- a/poetry.lock +++ /dev/null @@ -1,185 +0,0 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. - -[[package]] -name = "chardet" -version = "5.1.0" -description = "Universal encoding detector for Python 3" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"}, - {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "loguru" -version = "0.6.0" -description = "Python logging made (stupidly) simple" -category = "main" -optional = false -python-versions = ">=3.5" -files = [ - {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, - {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"}, -] - -[package.dependencies] -colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} -win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} - -[package.extras] -dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"] - -[[package]] -name = "pathlib" -version = "1.0.1" -description = "Object-oriented filesystem paths" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pathlib-1.0.1-py3-none-any.whl", hash = "sha256:f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147"}, - {file = "pathlib-1.0.1.tar.gz", hash = "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f"}, -] - -[[package]] -name = "pyasstosrt" -version = "1.3.1" -description = "Convert ASS subtitle to SRT format" -category = "main" -optional = false -python-versions = ">=3.6,<4.0" -files = [ - {file = "pyasstosrt-1.3.1-py3-none-any.whl", hash = "sha256:e708f3a6289d374688b82d4f7b44b9b0c61a225ceb1cf8c4c46e20e3ec4067cb"}, - {file = "pyasstosrt-1.3.1.tar.gz", hash = "sha256:88b7dd4a0da4bfe1fb4aacda67a3db8b51575d5609eaf66212b2a7fa27c10d7f"}, -] - -[package.extras] -cli = ["fire (>=0.3.1)", "pyfiglet"] - -[[package]] -name = "pydantic" -version = "1.10.4" -description = "Data validation and settings management using python type hints" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854"}, - {file = "pydantic-1.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817"}, - {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c"}, - {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e"}, - {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85"}, - {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6"}, - {file = "pydantic-1.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d"}, - {file = "pydantic-1.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53"}, - {file = "pydantic-1.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3"}, - {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a"}, - {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d"}, - {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72"}, - {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857"}, - {file = "pydantic-1.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3"}, - {file = "pydantic-1.10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00"}, - {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978"}, - {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e"}, - {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa"}, - {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8"}, - {file = "pydantic-1.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903"}, - {file = "pydantic-1.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423"}, - {file = "pydantic-1.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f"}, - {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06"}, - {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15"}, - {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c"}, - {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416"}, - {file = "pydantic-1.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6"}, - {file = "pydantic-1.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d"}, - {file = "pydantic-1.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f"}, - {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024"}, - {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c"}, - {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28"}, - {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f"}, - {file = "pydantic-1.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4"}, - {file = "pydantic-1.10.4-py3-none-any.whl", hash = "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774"}, - {file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pysrt" -version = "1.1.2" -description = "SubRip (.srt) subtitle parser and writer" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pysrt-1.1.2.tar.gz", hash = "sha256:b4f844ba33e4e7743e9db746492f3a193dc0bc112b153914698e7c1cdeb9b0b9"}, -] - -[package.dependencies] -chardet = "*" - -[[package]] -name = "pyvtt" -version = "0.0.4" -description = "WebVTT (.vtt) subtitle parser and writer" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pyvtt-0.0.4-py3-none-any.whl", hash = "sha256:7a69403b04697b027ed67899d8268a5cbc04206d64235cee665df9f4f474b531"}, - {file = "pyvtt-0.0.4.tar.gz", hash = "sha256:ae21a77ae74494895784cee5e05b81cc968afd949886eeb3fe97b118cff38127"}, -] - -[package.dependencies] -chardet = "*" - -[[package]] -name = "typing-extensions" -version = "4.4.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, - {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, -] - -[[package]] -name = "win32-setctime" -version = "1.1.0" -description = "A small Python utility to set file creation time on Windows" -category = "main" -optional = false -python-versions = ">=3.5" -files = [ - {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, - {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, -] - -[package.extras] -dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.7" -content-hash = "cbd27e4f04209f7be808b209a33916702c2deca9a7b4d10567ed343a1816c766" diff --git a/pyproject.toml b/pyproject.toml index edbf159..4a48115 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,24 +1,39 @@ -[tool.poetry] +[project] name = "subtitle-utils" -version = "0.1.4" +version = "1.0.0" description = "Subtilte Conversion utils - ass2srt vtt2bcc srt2bcc ass2bcc and more" -authors = ["sudoskys "] -license = "BSD" +authors = [ + { name = "sudoskys", email = "coldlando@hotmail.com" }, + { name = "KimmyXYC", email = "kimmyxyc@gmail.com" } +] +dependencies = [ + "pathlib<2.0.0,>=1.0.1", + "loguru<1.0.0,>=0.6.0", + "pysrt<2.0.0,>=1.1.2", + "pyvtt<1.0.0,>=0.0.4", + "chardet<6.0.0,>=5.1.0", + "pyasstosrt<2.0.0,>=1.3.1", + "pydantic>2.0.0", + "pydantic-settings>=2.0.3", +] +requires-python = ">=3.8,<3.12" readme = "README.md" -packages = [{include = "subtitle_utils"}] -repository = "https://github.com/sudoskys/subtitle_utils" +license = { text = "MIT" } -[tool.poetry.dependencies] -python = "^3.7" -pathlib = "^1.0.1" -loguru = "^0.6.0" -pysrt = "^1.1.2" -pyvtt = "^0.0.4" -chardet = "^5.1.0" -pyasstosrt = "^1.3.1" -pydantic = "<2.0.0" +[tool.pdm] +package-type = "library" +[tool.pdm.build] +includes = ["subtitle_utils"] +[tool.pdm.dev-dependencies] +dev = [ + "pre-commit>=3.5.0", +] [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["pdm-backend"] +build-backend = "pdm.backend" + + +[project.urls] +repository = "https://github.com/sudoskys/subtitle_utils" diff --git a/test/main.py b/test/main.py deleted file mode 100644 index bcf74b4..0000000 --- a/test/main.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 1/2/23 11:48 AM -# @FileName: main.py -# @Software: PyCharm -# @Github :sudoskys -from test_method_get import get_convert - -if __name__ == "__main__": - name = "srt2bcc" - pre = name.split("2")[0] - aft = name.split("2")[1] - with open(f"test.{pre}", "r") as f: - pre_content = f.read() - result = get_convert(pre=pre, aft=aft, input_str=pre_content) - print(result) diff --git a/test/test.bcc b/test/test.bcc deleted file mode 100644 index da871c7..0000000 --- a/test/test.bcc +++ /dev/null @@ -1 +0,0 @@ -{"font_size": 0.4, "font_color": "#FFFFFF", "background_alpha": 0.5, "background_color": "#9C27B0", "Stroke": "none", "body": [{"from": 0, "to": 5.36, "location": 2, "content": "字幕001"}, {"from": 6.45, "to": 9.49, "location": 2, "content": "字幕002"}, {"from": 17.49, "to": 20.36, "location": 2, "content": "字幕003"}, {"from": 25.36, "to": 27.2, "location": 2, "content": "字幕004"}]} diff --git a/test/test_method.py b/test/test_method.py deleted file mode 100644 index 0c3215b..0000000 --- a/test/test_method.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 1/2/23 11:13 AM -# @FileName: test.py -# @Software: PyCharm -# @Github :sudoskys -import sys - -sys.path.append("..") - -import subtitle_utils - - -def get_test_subtitle(pre, aft): - with open(f"test.{pre}", "r") as f: - pre_content = f.read() - with open(f"test.{aft}", "r") as f: - aft_content = f.read() - return pre_content, aft_content - - -def get_convert(pre: str = "ass", aft: str = "srt", input_str: str = None) -> str: - _result_group = subtitle_utils.FormatConverter(pre=pre, aft=aft, strs=input_str) - _result_group: subtitle_utils.Returner - if not _result_group.status: - print(_result_group.dict()) - return "" - result: str - result = _result_group.data - print(f"{_result_group.pre}->{print(_result_group.aft)}") - print(_result_group.msg) - return result - - -class TestClass: - def test_SeeAvailableMethods(self): - method = subtitle_utils.SeeAvailableMethods() - assert type(method) == list - - def test_module(self): - names = ["bcc2srt"] - for name in names: - pre = name.split("2")[0] - aft = name.split("2")[1] - pre_content, aft_content = get_test_subtitle(pre=pre, aft=aft) - result = get_convert(pre=pre, aft=aft, input_str=pre_content) - print(result) - assert aft_content == result - - -if __name__ == '__main__': - import pytest - - # 相当于在命令行当前目录中执行了 pytest - pytest.main() From 4cf5d542f633f22570f777aed6b4ecf9eeb5bdba Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:48:14 +0800 Subject: [PATCH 03/13] :rocket: feat: Update cover image URL in README.md --- README.md | 15 ++++++++++----- subtitle_utils/utils.py | 20 -------------------- 2 files changed, 10 insertions(+), 25 deletions(-) delete mode 100644 subtitle_utils/utils.py diff --git a/README.md b/README.md index 9e21865..7439151 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,21 @@ # subtitle_utils -![cover](https://raw.githubusercontent.com/sudoskys/subtitle_utils/main/cover.jpg) +![cover](https://raw.githubusercontent.com/sudoskys/subtitle_utils/main/src/cover.jpg)

- Python + Python + Download

Subtilte Conversion utils - ass2srt vtt2bcc srt2bcc ass2bcc and more -`pip install -U subtitle_utils` +## Install -## 使用 +``` +pip install -U subtitle_utils +``` + +## Usage ```python import subtitle_utils @@ -30,4 +35,4 @@ def get_convert(pre: str = "ass", aft: str = "srt", input_str: str = None) -> st print(f"{_result_group.pre}->{print(_result_group.aft)}") print(_result_group.msg) return result -``` \ No newline at end of file +``` diff --git a/subtitle_utils/utils.py b/subtitle_utils/utils.py deleted file mode 100644 index 1a8a384..0000000 --- a/subtitle_utils/utils.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 12/31/22 9:53 AM -# @FileName: utils.py -# @Software: PyCharm -# @Github :sudoskys -import os -import pysrt - - -class SrtParse(object): - def __init__(self): - pass - - def parse(self, files: str = "", strs: str = ""): - if not any([files, strs]): - raise Exception("Missing srt?") - if files: - return pysrt.open(path=files) - if strs: - return pysrt.from_string(source=strs) From 485c83b6a9b9437c364d036f7454bb5bb71f23a7 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:48:17 +0800 Subject: [PATCH 04/13] :rocket: feat: Update cover image URL in README.md --- pdm.lock | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 pdm.lock diff --git a/pdm.lock b/pdm.lock new file mode 100644 index 0000000..cca0b9a --- /dev/null +++ b/pdm.lock @@ -0,0 +1,442 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "dev"] +strategy = ["cross_platform", "inherit_metadata"] +lock_version = "4.4.1" +content_hash = "sha256:5eefb7ad385db4de63e6c0390e9556ce4eb8c6e1cef95b1fcbe9fc741f621553" + +[[package]] +name = "annotated-types" +version = "0.5.0" +requires_python = ">=3.7" +summary = "Reusable constraint types to use with typing.Annotated" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0.0; python_version < \"3.9\"", +] +files = [ + {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, + {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +requires_python = ">=3.8" +summary = "Validate configuration and produce human readable error messages." +groups = ["dev"] +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[[package]] +name = "chardet" +version = "5.2.0" +requires_python = ">=3.7" +summary = "Universal encoding detector for Python 3" +groups = ["default"] +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["default"] +marker = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "distlib" +version = "0.3.8" +summary = "Distribution utilities" +groups = ["dev"] +files = [ + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, +] + +[[package]] +name = "filelock" +version = "3.13.1" +requires_python = ">=3.8" +summary = "A platform independent file lock." +groups = ["dev"] +files = [ + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, +] + +[[package]] +name = "identify" +version = "2.5.33" +requires_python = ">=3.8" +summary = "File identification library for Python" +groups = ["dev"] +files = [ + {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, + {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, +] + +[[package]] +name = "loguru" +version = "0.7.2" +requires_python = ">=3.5" +summary = "Python logging made (stupidly) simple" +groups = ["default"] +dependencies = [ + "colorama>=0.3.4; sys_platform == \"win32\"", + "win32-setctime>=1.0.0; sys_platform == \"win32\"", +] +files = [ + {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, + {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, +] + +[[package]] +name = "nodeenv" +version = "1.8.0" +requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +summary = "Node.js virtual environment builder" +groups = ["dev"] +dependencies = [ + "setuptools", +] +files = [ + {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, + {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, +] + +[[package]] +name = "pathlib" +version = "1.0.1" +summary = "Object-oriented filesystem paths" +groups = ["default"] +files = [ + {file = "pathlib-1.0.1-py3-none-any.whl", hash = "sha256:f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147"}, + {file = "pathlib-1.0.1.tar.gz", hash = "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f"}, +] + +[[package]] +name = "platformdirs" +version = "4.1.0" +requires_python = ">=3.8" +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +groups = ["dev"] +files = [ + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, +] + +[[package]] +name = "pre-commit" +version = "3.5.0" +requires_python = ">=3.8" +summary = "A framework for managing and maintaining multi-language pre-commit hooks." +groups = ["dev"] +dependencies = [ + "cfgv>=2.0.0", + "identify>=1.0.0", + "nodeenv>=0.11.1", + "pyyaml>=5.1", + "virtualenv>=20.10.0", +] +files = [ + {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, + {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, +] + +[[package]] +name = "pyasstosrt" +version = "1.4.0" +requires_python = ">=3.7,<4.0" +summary = "Convert ASS subtitle to SRT format" +groups = ["default"] +files = [ + {file = "pyasstosrt-1.4.0-py3-none-any.whl", hash = "sha256:77ee51872eab846492586a6d0876e8a4e76d4fe1c97acb7a4fcf158bb88914d2"}, + {file = "pyasstosrt-1.4.0.tar.gz", hash = "sha256:e9d5daa013538d12dcbc8ace9a2ec3f87adc5dde9a8349c4b2e5bd33644fe1c3"}, +] + +[[package]] +name = "pydantic" +version = "2.5.3" +requires_python = ">=3.7" +summary = "Data validation using Python type hints" +groups = ["default"] +dependencies = [ + "annotated-types>=0.4.0", + "pydantic-core==2.14.6", + "typing-extensions>=4.6.1", +] +files = [ + {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, + {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, +] + +[[package]] +name = "pydantic-core" +version = "2.14.6" +requires_python = ">=3.7" +summary = "" +groups = ["default"] +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] +files = [ + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, + {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, + {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, + {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, + {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, + {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, + {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, + {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, + {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, + {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, + {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, + {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, + {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, + {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, + {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, + {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, + {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, + {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, + {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, + {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, + {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, + {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, + {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, + {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, + {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, + {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, + {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, + {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, + {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, + {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, + {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, + {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, + {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, + {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, + {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, +] + +[[package]] +name = "pydantic-settings" +version = "2.0.3" +requires_python = ">=3.7" +summary = "Settings management using Pydantic" +groups = ["default"] +dependencies = [ + "pydantic>=2.0.1", + "python-dotenv>=0.21.0", +] +files = [ + {file = "pydantic_settings-2.0.3-py3-none-any.whl", hash = "sha256:ddd907b066622bd67603b75e2ff791875540dc485b7307c4fffc015719da8625"}, + {file = "pydantic_settings-2.0.3.tar.gz", hash = "sha256:962dc3672495aad6ae96a4390fac7e593591e144625e5112d359f8f67fb75945"}, +] + +[[package]] +name = "pysrt" +version = "1.1.2" +summary = "SubRip (.srt) subtitle parser and writer" +groups = ["default"] +dependencies = [ + "chardet", +] +files = [ + {file = "pysrt-1.1.2.tar.gz", hash = "sha256:b4f844ba33e4e7743e9db746492f3a193dc0bc112b153914698e7c1cdeb9b0b9"}, +] + +[[package]] +name = "python-dotenv" +version = "0.21.1" +requires_python = ">=3.7" +summary = "Read key-value pairs from a .env file and set them as environment variables" +groups = ["default"] +files = [ + {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"}, + {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, +] + +[[package]] +name = "pyvtt" +version = "0.0.4" +summary = "WebVTT (.vtt) subtitle parser and writer" +groups = ["default"] +dependencies = [ + "chardet", +] +files = [ + {file = "pyvtt-0.0.4-py3-none-any.whl", hash = "sha256:7a69403b04697b027ed67899d8268a5cbc04206d64235cee665df9f4f474b531"}, + {file = "pyvtt-0.0.4.tar.gz", hash = "sha256:ae21a77ae74494895784cee5e05b81cc968afd949886eeb3fe97b118cff38127"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +requires_python = ">=3.6" +summary = "YAML parser and emitter for Python" +groups = ["dev"] +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "setuptools" +version = "69.0.3" +requires_python = ">=3.8" +summary = "Easily download, build, install, upgrade, and uninstall Python packages" +groups = ["dev"] +files = [ + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, +] + +[[package]] +name = "typing-extensions" +version = "4.7.1" +requires_python = ">=3.7" +summary = "Backported and Experimental Type Hints for Python 3.7+" +groups = ["default"] +files = [ + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, +] + +[[package]] +name = "virtualenv" +version = "20.25.0" +requires_python = ">=3.7" +summary = "Virtual Python Environment builder" +groups = ["dev"] +dependencies = [ + "distlib<1,>=0.3.7", + "filelock<4,>=3.12.2", + "platformdirs<5,>=3.9.1", +] +files = [ + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, +] + +[[package]] +name = "win32-setctime" +version = "1.1.0" +requires_python = ">=3.5" +summary = "A small Python utility to set file creation time on Windows" +groups = ["default"] +marker = "sys_platform == \"win32\"" +files = [ + {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, + {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, +] From 35ce21f06181afb2086991a1fd0fa2c7e93977ea Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:48:23 +0800 Subject: [PATCH 05/13] :rocket: feat: Update cover image URL in README.md --- tests/test.bcc | 1 + {test => tests}/test.srt | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) create mode 100755 tests/test.bcc rename {test => tests}/test.srt (60%) mode change 100644 => 100755 diff --git a/tests/test.bcc b/tests/test.bcc new file mode 100755 index 0000000..08ae82f --- /dev/null +++ b/tests/test.bcc @@ -0,0 +1 @@ +{"font_size": 0.4, "font_color": "#FFFFFF", "background_alpha": 0.5, "background_color": "#9C27B0", "Stroke": "none", "body": [{"from": 0.0, "to": 5.36, "location": 2, "content": "字幕001"}, {"from": 6.45, "to": 9.49, "location": 2, "content": "字幕003\n字幕004"}, {"from": 9.49, "to": 17.49, "location": 2, "content": "字幕004"}, {"from": 17.49, "to": 18.36, "location": 2, "content": "字幕005"}, {"from": 18.36, "to": 20.36, "location": 2, "content": "字幕005\n字幕006"}, {"from": 20.36, "to": 22.2, "location": 2, "content": "字幕006"}]} diff --git a/test/test.srt b/tests/test.srt old mode 100644 new mode 100755 similarity index 60% rename from test/test.srt rename to tests/test.srt index cc8019f..8cd08b7 --- a/test/test.srt +++ b/tests/test.srt @@ -2,14 +2,18 @@ 00:00:00,000 --> 00:00:05,360 字幕001 -2 -00:00:06,450 --> 00:00:09,490 -字幕002 - 3 -00:00:17,490 --> 00:00:20,360 +00:00:06,450 --> 00:00:09,490 字幕003 4 -00:00:25,360 --> 00:00:27,200 +00:00:06,450 --> 00:00:17,490 字幕004 + +5 +00:00:17,490 --> 00:00:20,360 +字幕005 + +6 +00:00:18,360 --> 00:00:22,200 +字幕006 From 5132bfe5daf526cc76da71c522f7167f9db84120 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 16:48:34 +0800 Subject: [PATCH 06/13] :rocket: feat: Update cover image URL in README.md --- cover.jpg => src/cover.jpg | Bin {subtitle_utils => src}/cover.png | Bin {subtitle_utils => src}/requirements.txt | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename cover.jpg => src/cover.jpg (100%) mode change 100644 => 100755 rename {subtitle_utils => src}/cover.png (100%) mode change 100644 => 100755 rename {subtitle_utils => src}/requirements.txt (100%) diff --git a/cover.jpg b/src/cover.jpg old mode 100644 new mode 100755 similarity index 100% rename from cover.jpg rename to src/cover.jpg diff --git a/subtitle_utils/cover.png b/src/cover.png old mode 100644 new mode 100755 similarity index 100% rename from subtitle_utils/cover.png rename to src/cover.png diff --git a/subtitle_utils/requirements.txt b/src/requirements.txt similarity index 100% rename from subtitle_utils/requirements.txt rename to src/requirements.txt From 25975dbb2e76aca88a2d9e4791eb2daa02398f4a Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:38:15 +0800 Subject: [PATCH 07/13] :sparkles: chore: update dependencies in pyproject.toml --- pdm.lock | 246 ++++++++++++++----------------------------------- pyproject.toml | 2 - 2 files changed, 69 insertions(+), 179 deletions(-) diff --git a/pdm.lock b/pdm.lock index cca0b9a..90c7825 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,24 +2,10 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "dev"] +groups = ["default", "dev", "testing"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:5eefb7ad385db4de63e6c0390e9556ce4eb8c6e1cef95b1fcbe9fc741f621553" - -[[package]] -name = "annotated-types" -version = "0.5.0" -requires_python = ">=3.7" -summary = "Reusable constraint types to use with typing.Annotated" -groups = ["default"] -dependencies = [ - "typing-extensions>=4.0.0; python_version < \"3.9\"", -] -files = [ - {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, - {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, -] +content_hash = "sha256:d68a922a7ecbfed8395edac0015ad8be02e99ddde17f07879911d0d7b6b3294d" [[package]] name = "cfgv" @@ -48,7 +34,7 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." -groups = ["default"] +groups = ["default", "testing"] marker = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, @@ -65,6 +51,18 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] +[[package]] +name = "exceptiongroup" +version = "1.2.0" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" +groups = ["testing"] +marker = "python_version < \"3.11\"" +files = [ + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, +] + [[package]] name = "filelock" version = "3.13.1" @@ -87,6 +85,17 @@ files = [ {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, ] +[[package]] +name = "iniconfig" +version = "2.0.0" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" +groups = ["testing"] +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + [[package]] name = "loguru" version = "0.7.2" @@ -116,6 +125,17 @@ files = [ {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, ] +[[package]] +name = "packaging" +version = "23.2" +requires_python = ">=3.7" +summary = "Core utilities for Python packages" +groups = ["testing"] +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + [[package]] name = "pathlib" version = "1.0.1" @@ -137,6 +157,17 @@ files = [ {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] +[[package]] +name = "pluggy" +version = "1.3.0" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +groups = ["testing"] +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + [[package]] name = "pre-commit" version = "3.5.0" @@ -166,154 +197,6 @@ files = [ {file = "pyasstosrt-1.4.0.tar.gz", hash = "sha256:e9d5daa013538d12dcbc8ace9a2ec3f87adc5dde9a8349c4b2e5bd33644fe1c3"}, ] -[[package]] -name = "pydantic" -version = "2.5.3" -requires_python = ">=3.7" -summary = "Data validation using Python type hints" -groups = ["default"] -dependencies = [ - "annotated-types>=0.4.0", - "pydantic-core==2.14.6", - "typing-extensions>=4.6.1", -] -files = [ - {file = "pydantic-2.5.3-py3-none-any.whl", hash = "sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4"}, - {file = "pydantic-2.5.3.tar.gz", hash = "sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a"}, -] - -[[package]] -name = "pydantic-core" -version = "2.14.6" -requires_python = ">=3.7" -summary = "" -groups = ["default"] -dependencies = [ - "typing-extensions!=4.7.0,>=4.6.0", -] -files = [ - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9"}, - {file = "pydantic_core-2.14.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245"}, - {file = "pydantic_core-2.14.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66"}, - {file = "pydantic_core-2.14.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590"}, - {file = "pydantic_core-2.14.6-cp310-none-win32.whl", hash = "sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7"}, - {file = "pydantic_core-2.14.6-cp310-none-win_amd64.whl", hash = "sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4"}, - {file = "pydantic_core-2.14.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1"}, - {file = "pydantic_core-2.14.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622"}, - {file = "pydantic_core-2.14.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2"}, - {file = "pydantic_core-2.14.6-cp311-none-win32.whl", hash = "sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2"}, - {file = "pydantic_core-2.14.6-cp311-none-win_amd64.whl", hash = "sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23"}, - {file = "pydantic_core-2.14.6-cp311-none-win_arm64.whl", hash = "sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec"}, - {file = "pydantic_core-2.14.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b"}, - {file = "pydantic_core-2.14.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91"}, - {file = "pydantic_core-2.14.6-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c"}, - {file = "pydantic_core-2.14.6-cp312-none-win32.whl", hash = "sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786"}, - {file = "pydantic_core-2.14.6-cp312-none-win_amd64.whl", hash = "sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40"}, - {file = "pydantic_core-2.14.6-cp312-none-win_arm64.whl", hash = "sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8"}, - {file = "pydantic_core-2.14.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e"}, - {file = "pydantic_core-2.14.6-cp37-none-win32.whl", hash = "sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6"}, - {file = "pydantic_core-2.14.6-cp37-none-win_amd64.whl", hash = "sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149"}, - {file = "pydantic_core-2.14.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80"}, - {file = "pydantic_core-2.14.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1"}, - {file = "pydantic_core-2.14.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60"}, - {file = "pydantic_core-2.14.6-cp38-none-win32.whl", hash = "sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe"}, - {file = "pydantic_core-2.14.6-cp38-none-win_amd64.whl", hash = "sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab"}, - {file = "pydantic_core-2.14.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9"}, - {file = "pydantic_core-2.14.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411"}, - {file = "pydantic_core-2.14.6-cp39-none-win32.whl", hash = "sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975"}, - {file = "pydantic_core-2.14.6-cp39-none-win_amd64.whl", hash = "sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94"}, - {file = "pydantic_core-2.14.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f"}, - {file = "pydantic_core-2.14.6-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4"}, - {file = "pydantic_core-2.14.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341"}, - {file = "pydantic_core-2.14.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e"}, - {file = "pydantic_core-2.14.6.tar.gz", hash = "sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948"}, -] - -[[package]] -name = "pydantic-settings" -version = "2.0.3" -requires_python = ">=3.7" -summary = "Settings management using Pydantic" -groups = ["default"] -dependencies = [ - "pydantic>=2.0.1", - "python-dotenv>=0.21.0", -] -files = [ - {file = "pydantic_settings-2.0.3-py3-none-any.whl", hash = "sha256:ddd907b066622bd67603b75e2ff791875540dc485b7307c4fffc015719da8625"}, - {file = "pydantic_settings-2.0.3.tar.gz", hash = "sha256:962dc3672495aad6ae96a4390fac7e593591e144625e5112d359f8f67fb75945"}, -] - [[package]] name = "pysrt" version = "1.1.2" @@ -327,14 +210,22 @@ files = [ ] [[package]] -name = "python-dotenv" -version = "0.21.1" +name = "pytest" +version = "7.4.4" requires_python = ">=3.7" -summary = "Read key-value pairs from a .env file and set them as environment variables" -groups = ["default"] +summary = "pytest: simple powerful testing with Python" +groups = ["testing"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2.0,>=0.12", + "tomli>=1.0.0; python_version < \"3.11\"", +] files = [ - {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"}, - {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [[package]] @@ -403,14 +294,15 @@ files = [ ] [[package]] -name = "typing-extensions" -version = "4.7.1" +name = "tomli" +version = "2.0.1" requires_python = ">=3.7" -summary = "Backported and Experimental Type Hints for Python 3.7+" -groups = ["default"] +summary = "A lil' TOML parser" +groups = ["testing"] +marker = "python_version < \"3.11\"" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 4a48115..611f378 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,8 +13,6 @@ dependencies = [ "pyvtt<1.0.0,>=0.0.4", "chardet<6.0.0,>=5.1.0", "pyasstosrt<2.0.0,>=1.3.1", - "pydantic>2.0.0", - "pydantic-settings>=2.0.3", ] requires-python = ">=3.8,<3.12" readme = "README.md" From 8f2d1576104c12e68e801081ad2891b5e1cc2586 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:38:40 +0800 Subject: [PATCH 08/13] :sparkles: feat(tests): add test_function.py with test cases for subtitle_utils The commit adds a new file, test_function.py, which contains test cases for the functions in the subtitle_utils module. The tests include checking the show list and the srt2ass method. --- subtitle_utils/__init__.py | 164 ------------------------------------- tests/test_function.py | 21 +++++ 2 files changed, 21 insertions(+), 164 deletions(-) delete mode 100644 subtitle_utils/__init__.py create mode 100644 tests/test_function.py diff --git a/subtitle_utils/__init__.py b/subtitle_utils/__init__.py deleted file mode 100644 index 5233496..0000000 --- a/subtitle_utils/__init__.py +++ /dev/null @@ -1,164 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 12/29/22 10:06 PM -# @FileName: convert.py -# @Software: PyCharm -# @Github :sudoskys -import json -import pathlib -from typing import Union -from loguru import logger - -# Child -from .BccConverter import BccConvert -from .AssConverter import AssConvert -from pydantic import BaseModel - -about = None - - -class _Converter(object): - def __init__(self): - pass - - def srt2bcc(self, - strs: Union[str], - **kwargs - ) -> str: - result = BccConvert().srt2bcc(files=strs, about=about) - result = json.dumps(result, ensure_ascii=False, indent=None) - return result - - def vtt2bcc(self, - strs: Union[str], - **kwargs - ) -> str: - result = BccConvert().vtt2bcc(files=strs, about=about) - result = json.dumps(result, ensure_ascii=False, indent=None) - return result - - def ass2bcc(self, - files: Union[str], - **kwargs - ) -> str: - result = AssConvert().ass2srt(files=files) - result = BccConvert().srt2bcc(files=result, about=about) - result = json.dumps(result, ensure_ascii=False, indent=None) - return result - - def ass2srt(self, - files: Union[str], - **kwargs - ) -> str: - result = AssConvert().ass2srt(files=files) - return result - - def srt2ass(self, - strs: Union[str], - header: str = "", - **kwargs - ) -> str: - result = AssConvert().srt2ass(strs=strs, header=header) - return result - - def bcc2srt(self, - strs: Union[str], - **kwargs - ) -> str: - result = BccConvert().bcc2srt(files=strs) - return result - - def bcc2ass(self, - strs: Union[str], - **kwargs - ) -> str: - result = BccConvert().bcc2srt(files=strs) - result = AssConvert().srt2ass(strs=result) - return result - - -class Returner(BaseModel): - status: bool = False - pre: str - aft: str - msg: str = "Unknown" - data: str = None - - -__kira = _Converter() - -_to_table = { - "2srt": { - "ass": __kira.ass2srt, - "bcc": __kira.bcc2srt, - }, - "2bcc": { - "vtt": __kira.vtt2bcc, - "srt": __kira.srt2bcc, - "ass": __kira.ass2bcc, - }, - "2ass": { - "srt": __kira.srt2ass, - "bcc": __kira.bcc2ass, - }, -} - - -def SeeAvailableMethods() -> list: - """ - 查询可用方法,返回功能列表 - :return: - """ - _method = [] - for it in _to_table.keys(): - _child = _to_table[it] - if not isinstance(_child, dict): - continue - _from = _child.keys() - for ti in _from: - _method.append(f"{ti}{it}") - return _method - - -def FormatConverter(pre: str, aft: str, - files: str = "", - strs: str = "", - **kwargs - ) -> Returner: - """ - 转换管线 - :param strs: 必须是字符串 - :param pre: 先前的格式 - :param aft: 转换为什么 - :param files: 必须是文件绝对路径 - :return: class Returner - """ - _aft = f"2{aft}" - if not strs and not files: - return Returner(status=False, pre=pre, aft=aft, msg="Miss arg") - # 检查类型 - if not _to_table.get(_aft): - return Returner(status=False, pre=pre, aft=aft, msg="Unsupported to format") - if not _to_table.get(_aft).get(pre): - return Returner(status=False, pre=pre, aft=aft, msg="Unsupported from format") - # 同步数据 - import tempfile - tmp = tempfile.NamedTemporaryFile(delete=True) - # 调用函数 - func = _to_table[_aft][pre] - try: - if not files: - _b = bytes(strs, 'utf8') - tmp.write(_b) - tmp.seek(0) - files = tmp.name - if not strs: - with pathlib.Path(files).open("r") as ori: - strs = ori.read() - _result = func(strs=strs, files=files, **kwargs) - except Exception as e: - logger.error(f"{pre}->{aft}:{e}") - return Returner(status=False, pre=pre, aft=aft, msg="Error occur") - else: - return Returner(status=True, pre=pre, aft=aft, data=_result, msg="") - finally: - tmp.close() diff --git a/tests/test_function.py b/tests/test_function.py new file mode 100644 index 0000000..ac97dc5 --- /dev/null +++ b/tests/test_function.py @@ -0,0 +1,21 @@ +from subtitle_utils import show_available, get_method + + +def get_test_subtitle(pre, aft): + with open(f"test.{pre}", "r") as f: + pre_content = f.read() + with open(f"test.{aft}", "r") as f: + aft_content = f.read() + return pre_content, aft_content + + +def test_show_available(): + assert isinstance(show_available()[0], str), "Error Checking show list" + + +def test_srt2ass(): + with open("test.bcc", "r") as f: + bcc_exp = f.read() + with open("test.srt", 'r') as file_io: + test_result = get_method(method="srt2ass")(content=file_io) + assert test_result == bcc_exp, f"Error Checking srt2ass \n{test_result}" From 0d65f43ded9662b34b3da44ffe393e6ee26602eb Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:39:03 +0800 Subject: [PATCH 09/13] feat: Add subtitle conversion functions - Added functions for converting SRT to BCC format - Added functions for converting VTT to BCC format - Added functions for converting ASS to BCC format - Added functions for converting ASS to SRT format - Added functions for converting SRT to ASS format - Added functions for converting BCC to SRT format - Added functions for converting BCC to ASS format The functions are implemented in the `srt2bcc`, `vtt2bcc`, `ass2bcc`, `ass2srt`, `srt2ass`, `bcc2srt`, and `bcc2ass` modules. These functions provide the capability to convert between different subtitle formats. --- src/requirements.txt | 1 - src/subtitle_utils/NOTICE.MD | 7 + src/subtitle_utils/__init__.py | 115 +++++++++++++ src/subtitle_utils/convert/LICENSE | 21 +++ .../subtitle_utils/convert/ass.py | 74 +++++---- .../subtitle_utils/convert/bcc.py | 156 ++++++------------ src/subtitle_utils/parse.py | 83 ++++++++++ src/subtitle_utils/schema.py | 18 ++ 8 files changed, 337 insertions(+), 138 deletions(-) create mode 100644 src/subtitle_utils/NOTICE.MD create mode 100644 src/subtitle_utils/__init__.py create mode 100644 src/subtitle_utils/convert/LICENSE rename subtitle_utils/AssConverter.py => src/subtitle_utils/convert/ass.py (57%) rename subtitle_utils/BccConverter.py => src/subtitle_utils/convert/bcc.py (69%) create mode 100644 src/subtitle_utils/parse.py create mode 100644 src/subtitle_utils/schema.py diff --git a/src/requirements.txt b/src/requirements.txt index 9ffeeaa..6c5e6af 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -4,4 +4,3 @@ pysrt pyvtt chardet pyasstosrt -pydantic diff --git a/src/subtitle_utils/NOTICE.MD b/src/subtitle_utils/NOTICE.MD new file mode 100644 index 0000000..20816e9 --- /dev/null +++ b/src/subtitle_utils/NOTICE.MD @@ -0,0 +1,7 @@ +# NOTICE OF THIS PROJECT + +## MIT License + +The MIT license applies to the files in: + + file: "subtitle_utils/convert/bcc.py" motify from https://github.com/FXTD-ODYSSEY/bilibili-subtile-uploader diff --git a/src/subtitle_utils/__init__.py b/src/subtitle_utils/__init__.py new file mode 100644 index 0000000..5c54462 --- /dev/null +++ b/src/subtitle_utils/__init__.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# @Time : 12/29/22 10:06 PM +# @FileName: convert.py +# @Software: PyCharm +# @Github :sudoskys +import json +from typing import Union, IO, Callable, Any + +from .convert.ass import AssConvert +from .convert.bcc import BccConvert + +FOOTNOTE = None + + +def srt2bcc(content: Union[str, IO] + ) -> str: + result = BccConvert().srt2bcc(content=content, about=FOOTNOTE) + result = json.dumps(result, ensure_ascii=False, indent=None) + return result + + +def vtt2bcc(content: Union[str, IO] + ) -> str: + result = BccConvert().vtt2bcc(content=content, about=FOOTNOTE) + result = json.dumps(result, ensure_ascii=False, indent=None) + return result + + +def ass2bcc(content: Union[str, IO] + ) -> str: + ass_result = AssConvert().ass2srt(content=content) + result = BccConvert().srt2bcc(content=ass_result, about=FOOTNOTE) + result = json.dumps(result, ensure_ascii=False, indent=None) + return result + + +def ass2srt(content: Union[str, IO] + ) -> str: + """ + :param content: + :return: result + """ + result = AssConvert().ass2srt(content=content) + return result + + +def srt2ass(content: Union[str, IO], + *, + header: str = None + ) -> str: + """ + :param content: srt str| IO + :param header: ass subtitle style + :return: + """ + result = AssConvert().srt2ass(content=content, header=header) + return result + + +def bcc2srt(content: Union[str, IO], + ) -> str: + result = BccConvert().bcc2srt(content=content) + return result + + +def bcc2ass(content: Union[str, IO] + ) -> str: + bcc_result = BccConvert().bcc2srt(content=content) + result = AssConvert().srt2ass(content=bcc_result) + return result + + +_to_table = { + "2srt": { + "ass": ass2srt, + "bcc": bcc2srt, + }, + "2bcc": { + "vtt": vtt2bcc, + "srt": srt2bcc, + "ass": ass2bcc, + }, + "2ass": { + "srt": srt2ass, + "bcc": bcc2ass, + }, +} + + +def get_method(method: str) -> Callable[..., Any]: + available_method = show_available() + assert method in available_method, f"Not available in {available_method}" + sub_key, key = method.split("2", maxsplit=1) + top_key = f"2{key}" + child = _to_table.get(top_key, None) + assert child, f"{method} NotImplemented for top class" + method_func = child.get(sub_key, None) + assert method_func, f"{method} NotImplemented for sub class" + return method_func + + +def show_available() -> list: + """ + 查询可用方法,返回功能列表 + :return: + """ + _method = [] + for it in _to_table.keys(): + _child = _to_table[it] + if not isinstance(_child, dict): + continue + _from = _child.keys() + for ti in _from: + _method.append(f"{ti}{it}") + return _method diff --git a/src/subtitle_utils/convert/LICENSE b/src/subtitle_utils/convert/LICENSE new file mode 100644 index 0000000..2849113 --- /dev/null +++ b/src/subtitle_utils/convert/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 智伤帝 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/subtitle_utils/AssConverter.py b/src/subtitle_utils/convert/ass.py similarity index 57% rename from subtitle_utils/AssConverter.py rename to src/subtitle_utils/convert/ass.py index 1503a48..49c0600 100644 --- a/subtitle_utils/AssConverter.py +++ b/src/subtitle_utils/convert/ass.py @@ -1,19 +1,17 @@ # -*- coding: utf-8 -*- -# @Time : 12/30/22 2:54 PM -# @FileName: AssConverter.py +# @Time : 2024/1/18 下午6:05 +# @Author : sudoskys +# @File : ass.py # @Software: PyCharm -# @Github :sudoskys -import re -from pathlib import Path -from pyasstosrt import Subtitle +import tempfile +from typing import Union, IO -from .utils import SrtParse +from pyasstosrt import Subtitle +from ..parse import SrtParse +from ..schema import Convert -class AssUtils(object): - @staticmethod - def defultHeader() -> str: - return """[V4+ Styles] +ASS_HEADER = """[V4+ Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding Style: Default,Arial,20,&H00FFFFFF,&HF0000000,&H00000000,&HF0000000,1,0,0,0,100,100,0,0.00,1,1,0,2,30,30,10,134 @@ -21,18 +19,24 @@ def defultHeader() -> str: Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text """ - def ass_content(self, content, header: str) -> str: + +class AssConvert(Convert): + @staticmethod + def srt2ass(content: Union[str, IO], + *, + header: str = None) -> str: """ - 字幕转换 - :param timestamps: 时间轴 - :param subtitles: 字幕 - :param header: 头 - :return: 合成字幕 + Subtitle Converter + :param content: subtitle path or content + :param header: ASS HEADER (Style) + :return: processed subtitle """ - subs = SrtParse().parse(strs=content) + assert isinstance(content, (str, IO)), "content must be str or IO" + subs = SrtParse().parse(content=content) timestamps = [[str(sub.start), str(sub.end)] for sub in subs] subtitles = [sub.text for sub in subs] - header = header if header else AssUtils.defultHeader() + if header is None: + header = ASS_HEADER content = header + '\n' body = { 'dialogue': 'Dialogue: ', @@ -63,21 +67,19 @@ def ass_content(self, content, header: str) -> str: content += '\n' return content - -class AssConvert(object): - - def ass2srt(self, files: str) -> str: - path = Path(files) - sub = Subtitle(path) - dialog = sub.export(output_dialogues=True) - _result = [] - for dialogue in dialog: - _result.append(str(dialogue)) + @staticmethod + def ass2srt(content: Union[str, IO]) -> str: + assert isinstance(content, (str, IO)), "content must be str or IO" + # write to temp file + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as f: + if isinstance(content, str): + f.write(content) + else: + f.write(content.read()) + f.close() + sub = Subtitle(filepath=f.name) + dialog = sub.export(output_dialogues=True) + _result = [] + for dialogue in dialog: + _result.append(str(dialogue)) return "".join(_result) - - def srt2ass(self, strs: str, header: str = "") -> str: - content = AssUtils().ass_content(content=strs, header=header) - return content - -# res = AssConvert().ass2srt(files="../test/sub.ass") -# print(res) diff --git a/subtitle_utils/BccConverter.py b/src/subtitle_utils/convert/bcc.py similarity index 69% rename from subtitle_utils/BccConverter.py rename to src/subtitle_utils/convert/bcc.py index c6ec226..f2a59c9 100644 --- a/subtitle_utils/BccConverter.py +++ b/src/subtitle_utils/convert/bcc.py @@ -1,19 +1,15 @@ # -*- coding: utf-8 -*- -# @Time : 12/30/22 2:39 PM -# @FileName: BccConvert.py -# @Software: PyCharm -# @Github :sudoskys +# @Author : sudoskys,智伤帝 +# @File : bcc.py import re -import os -import json -import pyvtt -import pysrt - -from typing import Union from datetime import datetime +from typing import Union, IO + from loguru import logger +from ..parse import VttParser, BccParser, SrtParse +from ..schema import Convert ##### # BCC2SRT @@ -21,51 +17,29 @@ # VTT2BCC ##### +item = { + "from": 0, + "to": 0, + "location": 2, + "content": "", +} -class BccParser(object): - def __init__(self): - pass - - def _parse(self, content: str): - try: - return json.loads(content) - except Exception as e: - raise Exception(e) - def parseFile(self, files): - path = files if files else "" - if not os.path.exists(path): - return - with open(files, "r") as f: - return self._parse(f.read()) +class BccConvert(Convert): - def parseStr(self, files): - strs = files if files else "" - return self._parse(strs) - - -class BccConvert(object): - def __init__(self): - self.item = { - "from": 0, - "to": 0, - "location": 2, - "content": "", - } - - def merge_timeline(self, time_line: list): + @staticmethod + def _merge_timeline(time_line: list): """ 防止时间码重合,压扁时间轴 - :param time_line: - :param additive: 附加字幕 - :return: + :param time_line: 时间轴 + :return: 压扁后的时间轴 """ # 制作爆破点 _time_dot = {} - for item in time_line: - _start = item["from"] - _end = item["to"] - _content = item["content"] + for items in time_line: + _start = items["from"] + _end = items["to"] + _content = items["content"] _uid = _start + _end import uuid uid1 = uuid.uuid1() @@ -75,11 +49,11 @@ def merge_timeline(self, time_line: list): _time_dot[uid2.hex] = {"time": _end, "type": "end", "content": _content, "group": uid} # 查找当前点的字幕。 - def sub_title_now(dot: float): + def sub_title_now(dot_: float): sub_title_n = [] rev = False for it in time_line: - if it["from"] <= dot < it["to"]: + if it["from"] <= dot_ < it["to"]: if "字幕" in it["content"] and len(it["content"]) > 7: rev = True sub_title_n.append(it["content"]) @@ -148,7 +122,14 @@ def merge_large(timeline: list): return merge_large(_result) - def process_body(self, subs, about: str = None): + def _process_body(self, subs, about: str = None): + """ + 处理字幕内容 + :param subs: 字幕列表 + :param about: 关于字幕 + :return: 处理后的字幕内容 + """ + _origin = [] if about: _origin.append({ @@ -166,23 +147,21 @@ def process_body(self, subs, about: str = None): } for sub in subs ]) - _fix = self.merge_timeline(_origin) + _fix = self._merge_timeline(_origin) return _fix - def time2str(self, time: float): + @staticmethod + def _time2str(time: float): return datetime.utcfromtimestamp(time).strftime("%H:%M:%S,%f")[:-3] - def srt2bcc(self, files: Union[str], about: str = None): + def srt2bcc(self, content: Union[str, IO], about: str = None): """ srt2bcc 将 srt 转换为 bcc B站字幕格式 + :param content: srt format :return: """ - path = files if files else "" - if os.path.exists(path): - subs = pysrt.open(path=files) - else: - subs = pysrt.from_string(source=files) - body = self.process_body(subs, about=about) + subs = SrtParse().parse(content) + body = self._process_body(subs, about=about) bcc = { "font_size": 0.4, "font_color": "#FFFFFF", @@ -193,17 +172,13 @@ def srt2bcc(self, files: Union[str], about: str = None): } return bcc if subs else {} - def bcc2srt(self, files: Union[str]): + def bcc2srt(self, content: Union[str, IO]): """ bcc2srt 将 bcc 转换为 srt 字幕格式 + :param content: bcc format :return: """ - path = files if files else "" - if os.path.exists(path): - with open(path, "r", encoding="utf-8") as f: - subs = json.load(f) - else: - subs = json.loads(path) + subs = BccParser().parse(content) srt = "" count = 0 for single_str in subs["body"]: @@ -212,16 +187,20 @@ def bcc2srt(self, files: Union[str]): from_str = single_str['from'] to_str = single_str['to'] srt += f"{count}\n" - srt += f"{self.time2str(from_str)} --> {self.time2str(to_str)}\n" + srt += f"{self._time2str(from_str)} --> {self._time2str(to_str)}\n" srt += f"{content_str}\n\n" return srt[:-1] if subs else "" - def vtt2bcc(self, files, threshold=0.1, word=True, about: str = None): - path = files if files else "" - if os.path.exists(path): - subs = pyvtt.open(path) - else: - subs = pyvtt.from_string(path) + def vtt2bcc(self, content: Union[str, IO], threshold=0.1, word=True, about: str = None): + """ + vtt2bcc 将 vtt 转换为 bcc B站字幕格式 + :param content: vtt format + :param threshold: 两个字幕之间的间隔时间 + :param word: 是否按照断词模式分隔字幕 + :param about: 关于字幕 + :return: bcc format + """ + subs = VttParser().parse(content) # NOTE 按照 vtt 的断词模式分隔 bcc caption_list = [] if not word: @@ -275,7 +254,8 @@ def vtt2bcc(self, files, threshold=0.1, word=True, about: str = None): } ) start = sec - except: + except Exception as e: + logger.trace(e) final_text = sub.text.split("\n")[-1] if caption_list and caption_list[-1]["content"] == final_text: caption_list[-1].update( @@ -300,7 +280,7 @@ def vtt2bcc(self, files, threshold=0.1, word=True, about: str = None): # NOTE 避免超出视频长度 last = caption_list[-1] last["to"] = last.get("from") + 0.1 - body = self.process_body(caption_list, about=about) + body = self._process_body(caption_list, about=about) bcc = { "font_size": 0.4, "font_color": "#FFFFFF", @@ -310,29 +290,3 @@ def vtt2bcc(self, files, threshold=0.1, word=True, about: str = None): "body": body, } return bcc if subs else {} - - -""" -# 部分原始代码协议:https://github.com/FXTD-ODYSSEY/bilibili-subtile-uploader/blob/main/LICENSE -MIT License - -Copyright (c) 2020 智伤帝 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -""" diff --git a/src/subtitle_utils/parse.py b/src/subtitle_utils/parse.py new file mode 100644 index 0000000..f15bdb4 --- /dev/null +++ b/src/subtitle_utils/parse.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# @Time : 12/31/22 9:53 AM +# @FileName: parse.py +# @Software: PyCharm +# @Github :sudoskys +import json +import os +import tempfile +from abc import ABC +from typing import Union, IO + +import pysrt +import pyvtt +from pysrt import SubRipFile +from pyvtt import WebVTTFile + + +class Parser(ABC): + """ + Base Parser + """ + + def parse(self, content: Union[str, IO]): + raise NotImplementedError + + +class SrtParse(Parser): + + def parse(self, content: Union[str, IO]) -> SubRipFile: + if isinstance(content, str): + return pysrt.from_string(content) + # write to temp file + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as f: + f.write(content.read()) + f.close() + return pysrt.open(f.name) + + +class BccParser(Parser): + + @staticmethod + def _parse(content: str): + try: + return json.loads(content) + except Exception as e: + raise e + + def parse_file(self, files): + path = files if files else "" + if not os.path.exists(path): + return + with open(files, "r") as f: + return self._parse(f.read()) + + def parse_str(self, sentence): + strs = sentence if sentence else "" + return self._parse(strs) + + def parse(self, content: Union[str, IO]) -> dict: + """ + Parse bcc + :param content: str or IO + :return: json + """ + if isinstance(content, str): + return self.parse_str(content) + return self.parse_file(content) + + +class VttParser(Parser): + + def parse(self, content: Union[str, IO]) -> WebVTTFile: + """ + :param content: str or IO + :return: pyvtt.WebVTTFile + """ + if isinstance(content, str): + return pyvtt.from_string(content) + # write to temp file + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as f: + f.write(content.read()) + f.close() + return pyvtt.open(f.name) diff --git a/src/subtitle_utils/schema.py b/src/subtitle_utils/schema.py new file mode 100644 index 0000000..b82384c --- /dev/null +++ b/src/subtitle_utils/schema.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/1/18 下午4:22 +# @Author : sudoskys +# @File : schema.py +# @Software: PyCharm +from abc import ABC +from enum import Enum + + +class SubtitleType(Enum): + ASS = "ass" + BCC = "bcc" + SRT = "srt" + VTT = "vtt" + + +class Convert(ABC): + pass From adec670a7c51a27604bd7845bced8a8166a38920 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:39:23 +0800 Subject: [PATCH 10/13] feat: add split_exp.py for testing split method This commit adds the file split_exp.py, which is used for testing the split method. The method splits a string using "2" as the delimiter and assigns the result to sub_key and key variables. The split_exp.py file also includes a print statement to display the values of sub_key and key. --- feature_test/split_exp.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 feature_test/split_exp.py diff --git a/feature_test/split_exp.py b/feature_test/split_exp.py new file mode 100644 index 0000000..6a1e8c4 --- /dev/null +++ b/feature_test/split_exp.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/1/18 下午11:09 +# @Author : sudoskys +# @File : split_exp.py + +method = "ass2srt" +sub_key, key = method.split("2", maxsplit=1) + +print(sub_key, key) From 6b5400ac7cd051c26cfb1b9f137c7bb2b94491b5 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:42:55 +0800 Subject: [PATCH 11/13] :hammer: chore(pyproject.toml): Update pdm dev dependencies - Removed "pre-commit" and added "pytest" as a dev dependency in the pdm configuration file. --- pdm.lock | 18 +++++++++--------- pyproject.toml | 12 +++++------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/pdm.lock b/pdm.lock index 90c7825..6470f44 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "dev", "testing"] +groups = ["default", "dev"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:d68a922a7ecbfed8395edac0015ad8be02e99ddde17f07879911d0d7b6b3294d" +content_hash = "sha256:d822b9cb9c00f101a91ca70accb8ff26dae4643880ecd730a5a16c443f0b470d" [[package]] name = "cfgv" @@ -34,7 +34,7 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." -groups = ["default", "testing"] +groups = ["default", "dev"] marker = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, @@ -56,7 +56,7 @@ name = "exceptiongroup" version = "1.2.0" requires_python = ">=3.7" summary = "Backport of PEP 654 (exception groups)" -groups = ["testing"] +groups = ["dev"] marker = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, @@ -90,7 +90,7 @@ name = "iniconfig" version = "2.0.0" requires_python = ">=3.7" summary = "brain-dead simple config-ini parsing" -groups = ["testing"] +groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -130,7 +130,7 @@ name = "packaging" version = "23.2" requires_python = ">=3.7" summary = "Core utilities for Python packages" -groups = ["testing"] +groups = ["dev"] files = [ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, @@ -162,7 +162,7 @@ name = "pluggy" version = "1.3.0" requires_python = ">=3.8" summary = "plugin and hook calling mechanisms for python" -groups = ["testing"] +groups = ["dev"] files = [ {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, @@ -214,7 +214,7 @@ name = "pytest" version = "7.4.4" requires_python = ">=3.7" summary = "pytest: simple powerful testing with Python" -groups = ["testing"] +groups = ["dev"] dependencies = [ "colorama; sys_platform == \"win32\"", "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", @@ -298,7 +298,7 @@ name = "tomli" version = "2.0.1" requires_python = ">=3.7" summary = "A lil' TOML parser" -groups = ["testing"] +groups = ["dev"] marker = "python_version < \"3.11\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, diff --git a/pyproject.toml b/pyproject.toml index 611f378..d43ef2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,20 +18,18 @@ requires-python = ">=3.8,<3.12" readme = "README.md" license = { text = "MIT" } +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" + [tool.pdm] package-type = "library" -[tool.pdm.build] -includes = ["subtitle_utils"] - [tool.pdm.dev-dependencies] dev = [ "pre-commit>=3.5.0", + "pytest>=7.4.4", ] -[build-system] -requires = ["pdm-backend"] -build-backend = "pdm.backend" - [project.urls] repository = "https://github.com/sudoskys/subtitle_utils" From d20f10c44369210a5843b97f669f88b5dc27966a Mon Sep 17 00:00:00 2001 From: sudoskys Date: Thu, 18 Jan 2024 23:59:47 +0800 Subject: [PATCH 12/13] :sparkles: feat: Add support for converting SRT to BCC --- src/subtitle_utils/__init__.py | 15 ++++++++------- src/subtitle_utils/convert/ass.py | 22 +++++++++++++--------- src/subtitle_utils/convert/bcc.py | 7 ++++--- src/subtitle_utils/parse.py | 23 +++++++++++++++-------- tests/__init__.py | 0 tests/test_function.py | 6 ++++-- 6 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 tests/__init__.py diff --git a/src/subtitle_utils/__init__.py b/src/subtitle_utils/__init__.py index 5c54462..b48a301 100644 --- a/src/subtitle_utils/__init__.py +++ b/src/subtitle_utils/__init__.py @@ -4,6 +4,7 @@ # @Software: PyCharm # @Github :sudoskys import json +from io import TextIOBase from typing import Union, IO, Callable, Any from .convert.ass import AssConvert @@ -12,21 +13,21 @@ FOOTNOTE = None -def srt2bcc(content: Union[str, IO] +def srt2bcc(content: Union[str, IO, TextIOBase] ) -> str: result = BccConvert().srt2bcc(content=content, about=FOOTNOTE) result = json.dumps(result, ensure_ascii=False, indent=None) return result -def vtt2bcc(content: Union[str, IO] +def vtt2bcc(content: Union[str, IO, TextIOBase] ) -> str: result = BccConvert().vtt2bcc(content=content, about=FOOTNOTE) result = json.dumps(result, ensure_ascii=False, indent=None) return result -def ass2bcc(content: Union[str, IO] +def ass2bcc(content: Union[str, IO, TextIOBase] ) -> str: ass_result = AssConvert().ass2srt(content=content) result = BccConvert().srt2bcc(content=ass_result, about=FOOTNOTE) @@ -34,7 +35,7 @@ def ass2bcc(content: Union[str, IO] return result -def ass2srt(content: Union[str, IO] +def ass2srt(content: Union[str, IO, TextIOBase] ) -> str: """ :param content: @@ -44,7 +45,7 @@ def ass2srt(content: Union[str, IO] return result -def srt2ass(content: Union[str, IO], +def srt2ass(content: Union[str, IO, TextIOBase], *, header: str = None ) -> str: @@ -57,13 +58,13 @@ def srt2ass(content: Union[str, IO], return result -def bcc2srt(content: Union[str, IO], +def bcc2srt(content: Union[str, IO, TextIOBase], ) -> str: result = BccConvert().bcc2srt(content=content) return result -def bcc2ass(content: Union[str, IO] +def bcc2ass(content: Union[str, IO, TextIOBase] ) -> str: bcc_result = BccConvert().bcc2srt(content=content) result = AssConvert().srt2ass(content=bcc_result) diff --git a/src/subtitle_utils/convert/ass.py b/src/subtitle_utils/convert/ass.py index 49c0600..2acf10d 100644 --- a/src/subtitle_utils/convert/ass.py +++ b/src/subtitle_utils/convert/ass.py @@ -4,6 +4,7 @@ # @File : ass.py # @Software: PyCharm import tempfile +from io import TextIOBase from typing import Union, IO from pyasstosrt import Subtitle @@ -22,7 +23,7 @@ class AssConvert(Convert): @staticmethod - def srt2ass(content: Union[str, IO], + def srt2ass(content: Union[str, IO, TextIOBase], *, header: str = None) -> str: """ @@ -31,7 +32,7 @@ def srt2ass(content: Union[str, IO], :param header: ASS HEADER (Style) :return: processed subtitle """ - assert isinstance(content, (str, IO)), "content must be str or IO" + assert isinstance(content, (str, IO, TextIOBase)), f"content must be str or IO but {type(content)}" subs = SrtParse().parse(content=content) timestamps = [[str(sub.start), str(sub.end)] for sub in subs] subtitles = [sub.text for sub in subs] @@ -68,18 +69,21 @@ def srt2ass(content: Union[str, IO], return content @staticmethod - def ass2srt(content: Union[str, IO]) -> str: + def ass2srt(content: Union[str, IO, TextIOBase]) -> str: assert isinstance(content, (str, IO)), "content must be str or IO" # write to temp file - with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as f: + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as f: if isinstance(content, str): f.write(content) else: f.write(content.read()) - f.close() - sub = Subtitle(filepath=f.name) - dialog = sub.export(output_dialogues=True) + f.seek(0) _result = [] - for dialogue in dialog: - _result.append(str(dialogue)) + try: + sub = Subtitle(filepath=f.name) + dialog = sub.export(output_dialogues=True) + for dialogue in dialog: + _result.append(str(dialogue)) + finally: + f.close() return "".join(_result) diff --git a/src/subtitle_utils/convert/bcc.py b/src/subtitle_utils/convert/bcc.py index f2a59c9..e764d80 100644 --- a/src/subtitle_utils/convert/bcc.py +++ b/src/subtitle_utils/convert/bcc.py @@ -4,6 +4,7 @@ import re from datetime import datetime +from io import TextIOBase from typing import Union, IO from loguru import logger @@ -154,7 +155,7 @@ def _process_body(self, subs, about: str = None): def _time2str(time: float): return datetime.utcfromtimestamp(time).strftime("%H:%M:%S,%f")[:-3] - def srt2bcc(self, content: Union[str, IO], about: str = None): + def srt2bcc(self, content: Union[str, IO, TextIOBase], about: str = None): """ srt2bcc 将 srt 转换为 bcc B站字幕格式 :param content: srt format @@ -172,7 +173,7 @@ def srt2bcc(self, content: Union[str, IO], about: str = None): } return bcc if subs else {} - def bcc2srt(self, content: Union[str, IO]): + def bcc2srt(self, content: Union[str, IO, TextIOBase]): """ bcc2srt 将 bcc 转换为 srt 字幕格式 :param content: bcc format @@ -191,7 +192,7 @@ def bcc2srt(self, content: Union[str, IO]): srt += f"{content_str}\n\n" return srt[:-1] if subs else "" - def vtt2bcc(self, content: Union[str, IO], threshold=0.1, word=True, about: str = None): + def vtt2bcc(self, content: Union[str, IO, TextIOBase], threshold=0.1, word=True, about: str = None): """ vtt2bcc 将 vtt 转换为 bcc B站字幕格式 :param content: vtt format diff --git a/src/subtitle_utils/parse.py b/src/subtitle_utils/parse.py index f15bdb4..5255ad5 100644 --- a/src/subtitle_utils/parse.py +++ b/src/subtitle_utils/parse.py @@ -7,6 +7,7 @@ import os import tempfile from abc import ABC +from io import TextIOBase from typing import Union, IO import pysrt @@ -20,20 +21,23 @@ class Parser(ABC): Base Parser """ - def parse(self, content: Union[str, IO]): + def parse(self, content: Union[str, IO, TextIOBase]): raise NotImplementedError class SrtParse(Parser): - def parse(self, content: Union[str, IO]) -> SubRipFile: + def parse(self, content: Union[str, IO, TextIOBase]) -> SubRipFile: if isinstance(content, str): return pysrt.from_string(content) # write to temp file with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as f: f.write(content.read()) - f.close() - return pysrt.open(f.name) + f.seek(0) + try: + return pysrt.open(path=f.name) + finally: + f.close() class BccParser(Parser): @@ -56,7 +60,7 @@ def parse_str(self, sentence): strs = sentence if sentence else "" return self._parse(strs) - def parse(self, content: Union[str, IO]) -> dict: + def parse(self, content: Union[str, IO, TextIOBase]) -> dict: """ Parse bcc :param content: str or IO @@ -69,7 +73,7 @@ def parse(self, content: Union[str, IO]) -> dict: class VttParser(Parser): - def parse(self, content: Union[str, IO]) -> WebVTTFile: + def parse(self, content: Union[str, IO, TextIOBase]) -> WebVTTFile: """ :param content: str or IO :return: pyvtt.WebVTTFile @@ -79,5 +83,8 @@ def parse(self, content: Union[str, IO]) -> WebVTTFile: # write to temp file with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=True) as f: f.write(content.read()) - f.close() - return pyvtt.open(f.name) + f.seek(0) + try: + return pyvtt.open(f.name) + finally: + f.close() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_function.py b/tests/test_function.py index ac97dc5..85ad96c 100644 --- a/tests/test_function.py +++ b/tests/test_function.py @@ -13,9 +13,11 @@ def test_show_available(): assert isinstance(show_available()[0], str), "Error Checking show list" -def test_srt2ass(): +def test_srt2bcc(): with open("test.bcc", "r") as f: bcc_exp = f.read() with open("test.srt", 'r') as file_io: - test_result = get_method(method="srt2ass")(content=file_io) + test_result = get_method(method="srt2bcc")(content=file_io) + test_result = test_result.replace("\n", "") + bcc_exp = bcc_exp.replace("\n", "") assert test_result == bcc_exp, f"Error Checking srt2ass \n{test_result}" From 095b9727ce7ae6f342a44ff4883a31713002d79e Mon Sep 17 00:00:00 2001 From: sudoskys Date: Fri, 19 Jan 2024 00:02:00 +0800 Subject: [PATCH 13/13] :sparkles: feat: Add support for converting SRT to BCC --- README.md | 28 +++++++++++----------------- feature_test/direct.py | 9 +++++++++ 2 files changed, 20 insertions(+), 17 deletions(-) create mode 100644 feature_test/direct.py diff --git a/README.md b/README.md index 7439151..05ae591 100644 --- a/README.md +++ b/README.md @@ -18,21 +18,15 @@ pip install -U subtitle_utils ## Usage ```python -import subtitle_utils - -method = subtitle_utils.SeeAvailableMethods() -print(method) - - -def get_convert(pre: str = "ass", aft: str = "srt", input_str: str = None) -> str: - _result_group = subtitle_utils.FormatConverter(pre=pre, aft=aft, strs=input_str) - _result_group: subtitle_utils.Returner - if not _result_group.status: - print(_result_group.dict()) - return "" - result: str - result = _result_group.data - print(f"{_result_group.pre}->{print(_result_group.aft)}") - print(_result_group.msg) - return result +from subtitle_utils import get_method, show_available, srt2bcc + +print("Available methods:") +print(show_available()) + +with open("test.srt", 'r') as file_io: + test_result = get_method(method="srt2bcc")(content=file_io) + print(test_result) + +_result = srt2bcc(content="1\n00:00:00,000 --> 00:00:01,000\nHello World") +print(_result) ``` diff --git a/feature_test/direct.py b/feature_test/direct.py new file mode 100644 index 0000000..869088a --- /dev/null +++ b/feature_test/direct.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/1/19 上午12:01 +# @Author : sudoskys +# @File : direct.py +# @Software: PyCharm +from subtitle_utils import srt2bcc + +_result = srt2bcc(content="1\n00:00:00,000 --> 00:00:01,000\nHello World") +print(_result)