forked from DRMTalks/devine
Overhaul tooling, linting, editor configs, and README
This commit is contained in:
parent
c159672181
commit
959590a6bb
|
@ -1,9 +1,5 @@
|
||||||
version = 1
|
version = 1
|
||||||
|
|
||||||
exclude_patterns = [
|
|
||||||
"**_pb2.py" # protobuf files
|
|
||||||
]
|
|
||||||
|
|
||||||
[[analyzers]]
|
[[analyzers]]
|
||||||
name = "python"
|
name = "python"
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{feature,json,md,yaml,yml,toml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
3
.flake8
3
.flake8
|
@ -1,3 +0,0 @@
|
||||||
[flake8]
|
|
||||||
exclude = .venv,build,dist,*_pb2.py,*.pyi
|
|
||||||
max-line-length = 120
|
|
|
@ -0,0 +1 @@
|
||||||
|
* text=auto eol=lf
|
|
@ -15,32 +15,32 @@ jobs:
|
||||||
name: Tagged Release
|
name: Tagged Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: '3.10.x'
|
python-version: "3.11"
|
||||||
- name: Install Poetry
|
- name: Install Poetry
|
||||||
uses: abatilo/actions-poetry@v2.3.0
|
uses: abatilo/actions-poetry@v2
|
||||||
with:
|
with:
|
||||||
poetry-version: '1.4.2'
|
poetry-version: 1.6.1
|
||||||
- name: Install dependencies
|
- name: Install project
|
||||||
run: poetry install
|
run: poetry install --only main
|
||||||
- name: Build project
|
- name: Build project
|
||||||
run: poetry build
|
run: poetry build
|
||||||
- name: Upload wheel
|
- name: Upload wheel
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: Python Wheel
|
name: Python Wheel
|
||||||
path: "dist/*.whl"
|
path: "dist/*.whl"
|
||||||
- name: Deploy release
|
- name: Deploy release
|
||||||
uses: marvinpinto/action-automatic-releases@latest
|
uses: marvinpinto/action-automatic-releases@latest
|
||||||
with:
|
with:
|
||||||
prerelease: false
|
prerelease: false
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
files: |
|
files: |
|
||||||
dist/*.whl
|
dist/*.whl
|
||||||
- name: Publish to PyPI
|
- name: Publish to PyPI
|
||||||
env:
|
env:
|
||||||
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
|
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
|
||||||
run: poetry publish
|
run: poetry publish
|
||||||
|
|
|
@ -7,32 +7,38 @@ on:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: "3.11"
|
||||||
|
- name: Install poetry
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: 1.6.1
|
||||||
|
- name: Install project
|
||||||
|
run: poetry install --all-extras
|
||||||
|
- name: Run pre-commit which does various checks
|
||||||
|
run: poetry run pre-commit run --all-files --show-diff-on-failure
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ['3.9', '3.10', '3.11']
|
python-version: ["3.9", "3.10", "3.11"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install flake8
|
- name: Install poetry
|
||||||
run: python -m pip install flake8
|
uses: abatilo/actions-poetry@v2
|
||||||
- name: Lint with flake8
|
with:
|
||||||
run: |
|
poetry-version: 1.6.1
|
||||||
# stop the build if there are Python syntax errors or undefined names
|
- name: Install project
|
||||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
run: poetry install --all-extras --only main
|
||||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
- name: Build project
|
||||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
run: poetry build
|
||||||
- name: Install poetry
|
|
||||||
uses: abatilo/actions-poetry@v2.3.0
|
|
||||||
with:
|
|
||||||
poetry-version: 1.4.2
|
|
||||||
- name: Install project
|
|
||||||
run: poetry install --no-dev
|
|
||||||
- name: Build project
|
|
||||||
run: poetry build
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ parts/
|
||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
|
@ -54,14 +55,17 @@ pip-delete-this-directory.txt
|
||||||
# Unit test / coverage reports
|
# Unit test / coverage reports
|
||||||
htmlcov/
|
htmlcov/
|
||||||
.tox/
|
.tox/
|
||||||
|
.nox/
|
||||||
.coverage
|
.coverage
|
||||||
.coverage.*
|
.coverage.*
|
||||||
.cache
|
.cache
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
*.cover
|
*.cover
|
||||||
|
*.py,cover
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
|
@ -71,6 +75,7 @@ coverage.xml
|
||||||
*.log
|
*.log
|
||||||
local_settings.py
|
local_settings.py
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
# Flask stuff:
|
# Flask stuff:
|
||||||
instance/
|
instance/
|
||||||
|
@ -83,16 +88,49 @@ instance/
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Jupyter Notebook
|
# Jupyter Notebook
|
||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
|
|
||||||
# pyenv
|
# IPython
|
||||||
.python-version
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
# celery beat schedule file
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
#pdm.lock
|
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||||
|
# in version control.
|
||||||
|
# https://pdm.fming.dev/#use-with-ide
|
||||||
|
.pdm.toml
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
# SageMath parsed files
|
# SageMath parsed files
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
@ -113,13 +151,26 @@ venv.bak/
|
||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
# JetBrains project settings
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.directory
|
.dmypy.json
|
||||||
.idea/dataSources.local.xml
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
.idea/
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
# See https://pre-commit.com/hooks.html for more hooks
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
|
- repo: https://github.com/mtkennerly/pre-commit-hooks
|
||||||
|
rev: v0.3.0
|
||||||
|
hooks:
|
||||||
|
- id: poetry-ruff
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
rev: 5.12.0
|
rev: 5.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
- repo: https://github.com/pycqa/flake8
|
|
||||||
rev: 6.0.0
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.4.0
|
rev: v4.5.0
|
||||||
hooks:
|
hooks:
|
||||||
|
- id: end-of-file-fixer
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
args: [--markdown-linebreak-ext=md]
|
args: [--markdown-linebreak-ext=md]
|
||||||
- id: end-of-file-fixer
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"EditorConfig.EditorConfig",
|
||||||
|
"streetsidesoftware.code-spell-checker",
|
||||||
|
"ms-python.python",
|
||||||
|
"ms-python.vscode-pylance",
|
||||||
|
"charliermarsh.ruff",
|
||||||
|
"ms-python.isort",
|
||||||
|
"ms-python.mypy-type-checker",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"tamasfe.even-better-toml"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Development
|
||||||
|
|
||||||
|
This project is managed using [Poetry](https://python-poetry.org), a fantastic Python packaging and dependency manager.
|
||||||
|
Install the latest version of Poetry before continuing. Development currently requires Python 3.9+.
|
||||||
|
|
||||||
|
## Set up
|
||||||
|
|
||||||
|
Starting from Zero? Not sure where to begin? Here's steps on setting up this Python project using Poetry. Note that
|
||||||
|
Poetry installation instructions should be followed from the Poetry Docs: https://python-poetry.org/docs/#installation
|
||||||
|
|
||||||
|
1. While optional, It's recommended to configure Poetry to install Virtual environments within project folders:
|
||||||
|
```shell
|
||||||
|
poetry config virtualenvs.in-project true
|
||||||
|
```
|
||||||
|
This makes it easier for Visual Studio Code to detect the Virtual Environment, as well as other IDEs and systems.
|
||||||
|
I've also had issues with Poetry creating duplicate Virtual environments in the default folder for an unknown
|
||||||
|
reason which quickly filled up my System storage.
|
||||||
|
2. Clone the Repository:
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/devine-dl/devine
|
||||||
|
cd devine
|
||||||
|
```
|
||||||
|
3. Install the Project with Poetry:
|
||||||
|
```shell
|
||||||
|
poetry install
|
||||||
|
```
|
||||||
|
This creates a Virtual environment and then installs all project dependencies and executables into the Virtual
|
||||||
|
environment. Your System Python environment is not affected at all.
|
||||||
|
4. Now activate the Virtual environment:
|
||||||
|
```shell
|
||||||
|
poetry shell
|
||||||
|
```
|
||||||
|
Note:
|
||||||
|
- You can alternatively just prefix `poetry run` to any command you wish to run under the Virtual environment.
|
||||||
|
- I recommend entering the Virtual environment and all further instructions will have assumed you did.
|
||||||
|
- JetBrains PyCharm has integrated support for Poetry and automatically enters Poetry Virtual environments, assuming
|
||||||
|
the Python Interpreter on the bottom right is set up correctly.
|
||||||
|
- For more information, see: https://python-poetry.org/docs/basic-usage/#using-your-virtual-environment
|
||||||
|
5. Install Pre-commit tooling to ensure safe and quality commits:
|
||||||
|
```shell
|
||||||
|
pre-commit install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Source and Wheel distributions
|
||||||
|
|
||||||
|
poetry build
|
||||||
|
|
||||||
|
You can optionally specify `-f` to build `sdist` or `wheel` only.
|
||||||
|
Built files can be found in the `/dist` directory.
|
309
README.md
309
README.md
|
@ -3,6 +3,10 @@
|
||||||
<a href="https://github.com/devine-dl/devine">Devine</a>
|
<a href="https://github.com/devine-dl/devine">Devine</a>
|
||||||
<br/>
|
<br/>
|
||||||
<sup><em>Open-Source Movie, TV, and Music Downloading Solution</em></sup>
|
<sup><em>Open-Source Movie, TV, and Music Downloading Solution</em></sup>
|
||||||
|
<br/>
|
||||||
|
<a href="https://discord.gg/34K2MGDrBN">
|
||||||
|
<img src="https://img.shields.io/discord/841055398240059422?label=&logo=discord&logoColor=ffffff&color=7289DA&labelColor=7289DA" alt="Discord">
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -15,34 +19,43 @@
|
||||||
<a href="https://deepsource.io/gh/devine-dl/devine/?ref=repository-badge">
|
<a href="https://deepsource.io/gh/devine-dl/devine/?ref=repository-badge">
|
||||||
<img src="https://deepsource.io/gh/devine-dl/devine.svg/?label=active+issues&token=1ADCbjJ3FPiGT_s0Y0rlugGU" alt="DeepSource">
|
<img src="https://deepsource.io/gh/devine-dl/devine.svg/?label=active+issues&token=1ADCbjJ3FPiGT_s0Y0rlugGU" alt="DeepSource">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/34K2MGDrBN">
|
<br/>
|
||||||
<img src="https://img.shields.io/discord/841055398240059422?label=&logo=discord&logoColor=ffffff&color=7289DA&labelColor=7289DA" alt="Discord">
|
<a href="https://github.com/astral-sh/ruff">
|
||||||
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Linter: Ruff">
|
||||||
|
</a>
|
||||||
|
<a href="https://python-poetry.org">
|
||||||
|
<img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Dependency management: Poetry">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 🎥 Supports Movies, TV shows, and Music
|
- 🚀 Seamless Installation via [pip](#installation)
|
||||||
- 🧩 Easy installation via PIP/PyPI
|
- 🎥 Movie, Episode, and Song Service Frameworks
|
||||||
- 👥 Multi-profile authentication per-service with credentials or cookies
|
- 🛠️ Built-in [DASH] and [HLS] Parsers
|
||||||
|
- 🔒 Widevine DRM integration via [pywidevine](https://github.com/devine-dl/pywidevine)
|
||||||
|
- 💾 Local & Remote DRM Key-vaults
|
||||||
|
- 🌍 Local & Remote Widevine CDMs
|
||||||
|
- 👥 Multi-profile Authentication per-service with Credentials and/or Cookies
|
||||||
- 🤖 Automatic P2P filename structure with Group Tag
|
- 🤖 Automatic P2P filename structure with Group Tag
|
||||||
- 🛠️ Flexible Service framework system
|
|
||||||
- 📦 Portable Installations
|
|
||||||
- 🗃️ Local and Remote SQL-based Key Vault database
|
|
||||||
- ⚙️ YAML for Configuration
|
- ⚙️ YAML for Configuration
|
||||||
- 🌍 Local and Remote Widevine CDMs
|
|
||||||
- ❤️ Fully Open-Source! Pull Requests Welcome
|
- ❤️ Fully Open-Source! Pull Requests Welcome
|
||||||
|
|
||||||
|
[DASH]: <devine/core/manifests/dash.py>
|
||||||
|
[HLS]: <devine/core/manifests/hls.py>
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ pip install devine
|
$ pip install devine
|
||||||
```
|
```
|
||||||
|
|
||||||
> __Note__ If you see warnings about a path not being in your PATH environment variable, add it, or `devine` won't run.
|
> [!NOTE]
|
||||||
|
> If pip gives you a warning about a path not being in your PATH environment variable then promptly add that path then
|
||||||
|
> close all open command prompt/terminal windows, or `devine` won't work as it will not be found.
|
||||||
|
|
||||||
Voilà 🎉! You now have the `devine` package installed and a `devine` executable is now available.
|
Voilà 🎉 — You now have the `devine` package installed!
|
||||||
Check it out with `devine --help`!
|
A command-line interface is now available, try `devine --help`.
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
|
@ -68,77 +81,165 @@ able to be found.
|
||||||
[MKVToolNix]: <https://mkvtoolnix.download/downloads.html>
|
[MKVToolNix]: <https://mkvtoolnix.download/downloads.html>
|
||||||
[shaka-packager]: <https://github.com/google/shaka-packager/releases/latest>
|
[shaka-packager]: <https://github.com/google/shaka-packager/releases/latest>
|
||||||
|
|
||||||
### Services
|
## Usage
|
||||||
|
|
||||||
Devine does not come with any infringing Service code. You must develop your own Service code and place them in
|
First, take a look at `devine --help` for a full help document, listing all commands available and giving you more
|
||||||
the `/devine/services` directory. There are different ways the add services depending on your installation type.
|
information on what can be done with Devine.
|
||||||
In some cases you may use multiple of these methods to have separate copies.
|
|
||||||
|
|
||||||
Please refrain from making or using Service code unless you have full rights to do so. I also recommend ensuring that
|
Here's a checklist on what I recommend getting started with, in no particular order,
|
||||||
you keep the Service code private and secure, i.e. a private repository or keeping it offline.
|
|
||||||
|
|
||||||
No matter which method you use, make sure that you install any further dependencies needed by the services. There's
|
- [ ] Add [Services](#services), these will be used in `devine dl`.
|
||||||
currently no way to have these dependencies automatically install apart from within the Fork method.
|
- [ ] Add [Profiles](#profiles-cookies--credentials), these are your cookies and credentials.
|
||||||
|
- [ ] Add [Widevine Provisions](#widevine-provisions), also known as CDMs, these are used for DRM-protected content.
|
||||||
|
- [ ] Set your Group Tag, the text at the end of the final filename, e.g., `devine cfg tag NOGRP` for `...-NOGRP`.
|
||||||
|
- [ ] Set Up a Local Key Vault, take a look at the [Key Vaults Config](CONFIG.md#keyvaults-listdict).
|
||||||
|
|
||||||
> __Warning__ Please be careful with who you trust and what you run. The users you collaborate with on Service
|
And here's some more advanced things you could take a look at,
|
||||||
|
|
||||||
|
- [ ] Setting default Headers that the Request Session uses.
|
||||||
|
- [ ] Setting default Profiles and CDM Provisions to use for services.
|
||||||
|
- [ ] NordVPN and Hola Proxy Providers for automatic proxies.
|
||||||
|
- [ ] Hosting and/or Using Remote Key Vaults.
|
||||||
|
- [ ] Serving and/or Using Remote CDM Provisions.
|
||||||
|
|
||||||
|
Documentation on the config is available in the [CONFIG.md](CONFIG.md) file, it has a lot of handy settings.
|
||||||
|
If you start to get sick of putting something in your CLI call, then I recommend taking a look at it!
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
Unlike similar project's such as [youtube-dl], Devine does not currently come with any Services. You must develop your
|
||||||
|
own Services and only use Devine with Services you have the legal right to do so.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If you made a Service for Devine that does not use Widevine or any other DRM systems, feel free to make a Pull Request
|
||||||
|
> and make your service available to others. Any Service on [youtube-dl] (or [yt-dlp]) would be able to be added to the
|
||||||
|
> Devine repository as they both use the [Unlicense license] therefore direct reading and porting of their code would be
|
||||||
|
> legal.
|
||||||
|
|
||||||
|
[youtube-dl]: <https://github.com/ytdl-org/youtube-dl>
|
||||||
|
[yt-dlp]: <https://github.com/yt-dlp/yt-dlp>
|
||||||
|
[Unlicense license]: <https://choosealicense.com/licenses/unlicense>
|
||||||
|
|
||||||
|
### Creating a Service
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Only create or use Service Code with Services you have full legal right to do so.
|
||||||
|
|
||||||
|
A Service consists of a folder with an `__init__.py` file. The file must contain a class of the same name as the folder.
|
||||||
|
The class must inherit the [Service] class and implement all the abstracted methods. It must finally implement a new
|
||||||
|
method named `cli` where you define CLI arguments.
|
||||||
|
|
||||||
|
1. Make a new folder within `/devine/services`. The folder name you choose will be what's known as the [Service Tag].
|
||||||
|
This "tag" is used in the final output filename of downloaded files, for various code-checks, lookup keys in
|
||||||
|
key-vault databases, and more.
|
||||||
|
2. Within the new folder create an `__init__.py` file and write a class inheriting the [Service] class. It must be named
|
||||||
|
the exact same as the folder. It is case-sensitive.
|
||||||
|
3. Implement all the methods of the Service class you are inheriting that are marked as abstract.
|
||||||
|
4. Define CLI arguments by implementing a `cli` method. This method must be static (i.e. `@staticmethod`). For example
|
||||||
|
to implement the bare minimum to receive a Title ID of sorts:
|
||||||
|
```python
|
||||||
|
@staticmethod
|
||||||
|
@click.command(name="YT", short_help="https://youtube.com", help=__doc__)
|
||||||
|
@click.argument("title", type=str)
|
||||||
|
@click.pass_context
|
||||||
|
def cli(ctx, **kwargs):
|
||||||
|
return YT(ctx, **kwargs)
|
||||||
|
```
|
||||||
|
You must implement this `cli` method, even if you do not want or need any CLI arguments. It is required for the core
|
||||||
|
CLI functionality to be able to find and call the class.
|
||||||
|
5. Accept the CLI arguments by overriding the constructor (the `__init__()` method):
|
||||||
|
```python
|
||||||
|
def __init__(self, ctx, title):
|
||||||
|
self.title = title
|
||||||
|
super().__init__(ctx) # important
|
||||||
|
# ... the title is now available across all methods by calling self.title
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> - All methods of your class inherited from `Service` marked as abstract (`@abstractmethod`) MUST be implemented by
|
||||||
|
> your class.
|
||||||
|
> - When overriding any method (e.g., `__init__()` method) you MUST super call it, e.g., `super().__init__()` at the
|
||||||
|
> top of the override. This does not apply to any abstract methods, as they are unimplemented.
|
||||||
|
> - If preparing your Requests Session with global headers or such, then you should override the `get_session` method,
|
||||||
|
> then modify `self.session`. Do not manually make `self.session` from scratch.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> 1. To make web requests use the `self.session` class instance variable, e.g. `self.session.get(url)`.
|
||||||
|
> 2. If you make a `config.yaml` file next to your `__init__.py`, you can access it with `self.config`.
|
||||||
|
> 3. You can include any arbitrary file within your Service folder for use by your Service. For example TLS certificate
|
||||||
|
> files, or other python files with helper functions and classes.
|
||||||
|
|
||||||
|
[Service]: <devine/core/service.py>
|
||||||
|
[Service Tag]: <#service-tags>
|
||||||
|
|
||||||
|
### Service Tags
|
||||||
|
|
||||||
|
Service tags generally follow these rules:
|
||||||
|
|
||||||
|
- Tag must be between 2-4 characters long, consisting of just `[A-Z0-9i]{2,4}`.
|
||||||
|
- Lower-case `i` is only used for select services. Specifically BBC iPlayer and iTunes.
|
||||||
|
- If the Service's commercial name has a `+` or `Plus`, the last character should be a `P`.
|
||||||
|
E.g., `ATVP` for `Apple TV+`, `DSCP` for `Discovery+`, `DSNP` for `Disney+`, and `PMTP` for `Paramount+`.
|
||||||
|
|
||||||
|
These rules are not exhaustive and should only be used as a guide. You don't strictly have to follow these rules, but
|
||||||
|
I recommend doing so for consistency.
|
||||||
|
|
||||||
|
### Sharing Services
|
||||||
|
|
||||||
|
Sending and receiving zipped Service folders is quite cumbersome. Let's explore alternative routes to collaborating on
|
||||||
|
Service Code.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Please be careful with who you trust and what you run. The users you collaborate with on Service
|
||||||
> code could update it with malicious code that you would run via devine on the next call.
|
> code could update it with malicious code that you would run via devine on the next call.
|
||||||
|
|
||||||
#### via Copy & Paste
|
#### Forking
|
||||||
|
|
||||||
If you have service code already and wish to just install and use it locally, then simply putting it into the Services
|
If you are collaborating with a team on multiple services then forking the project is the best way to go.
|
||||||
directory of your local pip installation will do the job. However, this method is the worst in terms of collaboration.
|
|
||||||
|
|
||||||
1. Get the installation directory by running the following in terminal,
|
1. [Fork the project](https://github.com/devine-dl/devine/fork) and make sure it is Private.
|
||||||
`python -c 'import os,devine.__main__ as a;print(os.path.dirname(a.__file__))'`
|
2. (optionally) Hard reset to the latest stable version by tag. E.g., `git reset --hard v1.0.0`.
|
||||||
2. Head to the installation directory and create a `services` folder if one is not yet created.
|
3. Add all your Services to the `/devine/services` folder and commit them to your fork.
|
||||||
3. Within that `services` folder you may install or create service code.
|
|
||||||
|
|
||||||
> __Warning__ Uninstalling Python or Devine may result in the Services you installed being deleted. Make sure you back
|
Now commit changes or additions within that services folder to your forked repository.
|
||||||
> up the services before uninstalling.
|
Once committed all your other team members can easily pull changes as well as push new changes.
|
||||||
|
|
||||||
#### via a Forked Repository
|
When a new update comes out you can easily rebase your fork to that commit to update. However, please make sure you
|
||||||
|
look at changes between each version before rebasing and resolve any breaking changes and deprecations when rebasing to
|
||||||
|
a new version.
|
||||||
|
|
||||||
If you are collaborating with a team on multiple services then forking the project is the best way to go. I recommend
|
If you are new to `git` then take a look at [GitHub Desktop](https://desktop.github.com).
|
||||||
forking the project then hard resetting to the latest stable update by tag. Once a new stable update comes out you can
|
|
||||||
easily rebase your fork to that commit to update.
|
|
||||||
|
|
||||||
However, please make sure you look at changes between each version before rebasing and resolve any breaking changes and
|
> [!TIP]
|
||||||
deprecations when rebasing to a new version.
|
> A huge benefit with this method is that you can also sync dependencies by your own Services as well!
|
||||||
|
> Just use `poetry` to add or modify dependencies appropriately and commit the changed `poetry.lock`.
|
||||||
|
> However, if the core project also has dependency changes your `poetry.lock` changes will conflict and you
|
||||||
|
> will need to learn how to do conflict resolution/rebasing. It is worth it though!
|
||||||
|
|
||||||
1. Fork the project with `git` or GitHub [(fork)](https://github.com/devine-dl/devine/fork).
|
#### Symlinking
|
||||||
2. Head inside the root `devine` directory and create a `services` directory.
|
|
||||||
3. Within that `services` folder you may install or create service code.
|
|
||||||
|
|
||||||
You may now commit changes or additions within that services folder to your forked repository.
|
This is a great option for those who wish to do something like the forking method, but may not care what changes
|
||||||
Once committed all your other team members can easily sync and contribute changes.
|
happened or when and just want changes synced across a team.
|
||||||
|
|
||||||
> __Note__ You may add Service-specific Python dependencies using `poetry` that can install alongside the project.
|
|
||||||
> Just do note that this will complicate rebasing when even the `poetry.lock` gets updates in the upstream project.
|
|
||||||
|
|
||||||
#### via Cloud storage (symlink)
|
|
||||||
|
|
||||||
This is a great option for those who wish to do something like the forking method, but without the need of constantly
|
|
||||||
rebasing their fork to the latest version. Overall less knowledge on git would be required, but each user would need
|
|
||||||
to do a bit of symlinking compared to the fork method.
|
|
||||||
|
|
||||||
This also opens up the ways you can host or collaborate on Service code. As long as you can receive a directory that
|
This also opens up the ways you can host or collaborate on Service code. As long as you can receive a directory that
|
||||||
updates with just the services within it, then you're good to go. Options could include an FTP server, Shared Google
|
updates with just the services within it, then you're good to go. Options could include an FTP server, Shared Google
|
||||||
Drive, a non-fork repository with just services, and more.
|
Drive, a non-fork repository with just services, and more.
|
||||||
|
|
||||||
1. Follow the steps in the [Copy & Paste method](#via-copy--paste) to create the `services` folder.
|
1. Use any Cloud Source that gives you a pseudo-directory to access the Service files like a normal drive. E.g., rclone,
|
||||||
2. Use any Cloud Source that gives you a pseudo-directory to access the Service files. E.g., rclone or google drive fs.
|
Google Drive Desktop (aka File Stream), Air Drive, CloudPool, etc.
|
||||||
3. Symlink the services directory from your Cloud Source to the new services folder you made.
|
2. Create a `services` directory somewhere in it and have all your services within it.
|
||||||
(you may need to delete it first)
|
3. [Symlink](https://en.wikipedia.org/wiki/Symbolic_link) the `services` directory to the `/devine` folder. You should
|
||||||
|
end up with `/devine/services` folder containing services, not `/devine/services/services`.
|
||||||
|
|
||||||
Of course, you have to make sure the original folder keeps receiving and downloading/streaming those changes, or that
|
You have to make sure the original folder keeps receiving and downloading/streaming those changes. You must also make
|
||||||
you keep git pulling those changes. You must also make sure that the version of devine you have locally is supported by
|
sure that the version of devine you have locally is supported by the Service code.
|
||||||
the Services code.
|
|
||||||
|
|
||||||
> __Note__ If you're using a cloud source that downloads the file once it gets opened, you don't have to worry as those
|
> [!NOTE]
|
||||||
> will automatically download. Python importing the files triggers the download to begin. However, it may cause a delay
|
> If you're using a cloud source that downloads the file once it gets opened, you don't have to worry as those will
|
||||||
> on startup.
|
> automatically download. Python importing the files triggers the download to begin. However, it may cause a delay on
|
||||||
|
> startup.
|
||||||
|
|
||||||
### Profiles (Cookies & Credentials)
|
## Profiles (Cookies & Credentials)
|
||||||
|
|
||||||
Just like a streaming service, devine associates both a cookie and/or credential as a Profile. You can associate up to
|
Just like a streaming service, devine associates both a cookie and/or credential as a Profile. You can associate up to
|
||||||
one cookie and one credential per-profile, depending on which (or both) are needed by the Service. This system allows
|
one cookie and one credential per-profile, depending on which (or both) are needed by the Service. This system allows
|
||||||
|
@ -155,7 +256,7 @@ You can also delete a credential with `devine auth delete`. E.g., to delete the
|
||||||
> __Note__ Profile names are case-sensitive and unique per-service. They also have no arbitrary character or length
|
> __Note__ Profile names are case-sensitive and unique per-service. They also have no arbitrary character or length
|
||||||
> limit, but for convenience I don't recommend using any special characters as your terminal may get confused.
|
> limit, but for convenience I don't recommend using any special characters as your terminal may get confused.
|
||||||
|
|
||||||
#### Cookie file format and Extensions
|
### Cookie file format and Extensions
|
||||||
|
|
||||||
Cookies must be in the standard Netscape cookies file format.
|
Cookies must be in the standard Netscape cookies file format.
|
||||||
Recommended Cookie exporter extensions:
|
Recommended Cookie exporter extensions:
|
||||||
|
@ -172,7 +273,7 @@ Any other extension that exports to the standard Netscape format should theoreti
|
||||||
> versions floating around (usually just older versions of the extension), but since there are safe alternatives I'd
|
> versions floating around (usually just older versions of the extension), but since there are safe alternatives I'd
|
||||||
> just avoid it altogether. Source: https://reddit.com/r/youtubedl/comments/10ar7o7
|
> just avoid it altogether. Source: https://reddit.com/r/youtubedl/comments/10ar7o7
|
||||||
|
|
||||||
### Widevine Provisions
|
## Widevine Provisions
|
||||||
|
|
||||||
A Widevine Provision is needed for acquiring licenses containing decryption keys for DRM-protected content.
|
A Widevine Provision is needed for acquiring licenses containing decryption keys for DRM-protected content.
|
||||||
They are not needed if you will be using devine on DRM-free services. Please do not ask for any Widevine Device Files,
|
They are not needed if you will be using devine on DRM-free services. Please do not ask for any Widevine Device Files,
|
||||||
|
@ -188,50 +289,9 @@ From here you can then set which WVD to use for each specific service. It's best
|
||||||
provision where possible.
|
provision where possible.
|
||||||
|
|
||||||
An alternative would be using a pywidevine Serve-compliant CDM API. Of course, you would need to know someone who is
|
An alternative would be using a pywidevine Serve-compliant CDM API. Of course, you would need to know someone who is
|
||||||
serving one, and they would need to give you access. Take a look at the [remote_cdm](CONFIG.md#remotecdm--listdict--)
|
serving one, and they would need to give you access. Take a look at the [remote_cdm](CONFIG.md#remotecdm-listdict)
|
||||||
config option for setup information. For further information on it see the pywidevine repository.
|
config option for setup information. For further information on it see the pywidevine repository.
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
First, take a look at `devine --help` for a full help document, listing all commands available and giving you more
|
|
||||||
information on what can be done with Devine.
|
|
||||||
|
|
||||||
Here's a checklist on what I recommend getting started with, in no particular order,
|
|
||||||
|
|
||||||
- [ ] Add [Services](#services), these will be used in `devine dl`.
|
|
||||||
- [ ] Add [Profiles](#profiles--cookies--credentials-), these are your cookies and credentials.
|
|
||||||
- [ ] Add [Widevine Provisions](#widevine-provisions), also known as CDMs, these are used for DRM-protected content.
|
|
||||||
- [ ] Set your Group Tag, the text at the end of the final filename, e.g., `devine cfg tag NOGRP` for ...-NOGRP.
|
|
||||||
- [ ] Set Up a Local Key Vault, take a look at the [Key Vaults Config](CONFIG.md#keyvaults--listdict--).
|
|
||||||
|
|
||||||
And here's some more advanced things you could take a look at,
|
|
||||||
|
|
||||||
- [ ] Setting default Headers that the Request Session uses.
|
|
||||||
- [ ] Setting default Profiles and CDM Provisions to use for services.
|
|
||||||
- [ ] NordVPN and Hola Proxy Providers for automatic proxies.
|
|
||||||
- [ ] Hosting and/or Using Remote Key Vaults.
|
|
||||||
- [ ] Serving and/or Using Remote CDM Provisions.
|
|
||||||
|
|
||||||
Documentation on the config is available in the [CONFIG.md](CONFIG.md) file, it has a lot of handy settings.
|
|
||||||
If you start to get sick of putting something in your CLI call, then I recommend taking a look at it!
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
The following steps are instructions on downloading, preparing, and running the code under a [Poetry] environment.
|
|
||||||
You can skip steps 3-5 with a simple `pip install .` call instead, but you miss out on a wide array of benefits.
|
|
||||||
|
|
||||||
1. `git clone https://github.com/devine-dl/devine`
|
|
||||||
2. `cd devine`
|
|
||||||
3. (optional) `poetry config virtualenvs.in-project true`
|
|
||||||
4. `poetry install`
|
|
||||||
5. `poetry run devine --help`
|
|
||||||
|
|
||||||
As seen in Step 5, running the `devine` executable is somewhat different to a normal PIP installation.
|
|
||||||
See [Poetry's Docs] on various ways of making calls under the virtual-environment.
|
|
||||||
|
|
||||||
[Poetry]: <https://python-poetry.org>
|
|
||||||
[Poetry's Docs]: <https://python-poetry.org/docs/basic-usage/#using-your-virtual-environment>
|
|
||||||
|
|
||||||
## End User License Agreement
|
## End User License Agreement
|
||||||
|
|
||||||
Devine and it's community pages should be treated with the same kindness as other projects.
|
Devine and it's community pages should be treated with the same kindness as other projects.
|
||||||
|
@ -246,31 +306,22 @@ Please refrain from spam or asking for questions that infringe upon a Service's
|
||||||
back immediately.
|
back immediately.
|
||||||
5. Be kind to one another and do not single anyone out.
|
5. Be kind to one another and do not single anyone out.
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
1. This project requires a valid Google-provisioned Private/Public Keypair and a Device-specific Client Identification
|
|
||||||
blob; neither of which are included with this project.
|
|
||||||
2. Public testing provisions are available and provided by Google to use for testing projects such as this one.
|
|
||||||
3. License Servers have the ability to block requests from any provision, and are likely already blocking test provisions
|
|
||||||
on production endpoints. Therefore, have the ability to block the usage of Devine by themselves.
|
|
||||||
4. This project does not condone piracy or any action against the terms of the Service or DRM system.
|
|
||||||
5. All efforts in this project have been the result of Reverse-Engineering and Publicly available research.
|
|
||||||
|
|
||||||
## Credit
|
|
||||||
|
|
||||||
- The awesome community for their shared research and insight into the Widevine Protocol and Key Derivation.
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
<a href="https://github.com/rlaphoenix"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/17136956?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/rlaphoenix"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/17136956?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="rlaphoenix"/></a>
|
||||||
<a href="https://github.com/mnmll"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/22942379?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/mnmll"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/22942379?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="mnmll"/></a>
|
||||||
<a href="https://github.com/shirt-dev"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/2660574?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/shirt-dev"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/2660574?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="shirt-dev"/></a>
|
||||||
<a href="https://github.com/nyuszika7h"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/482367?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/nyuszika7h"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/482367?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="nyuszika7h"/></a>
|
||||||
<a href="https://github.com/bccornfo"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/98013276?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/bccornfo"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/98013276?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="bccornfo"/></a>
|
||||||
<a href="https://github.com/Arias800"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/24809312?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/Arias800"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/24809312?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="Arias800"/></a>
|
||||||
<a href="https://github.com/varyg1001"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/88599103?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/varyg1001"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/88599103?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="varyg1001"/></a>
|
||||||
<a href="https://github.com/Hollander-1908"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/93162595?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt=""/></a>
|
<a href="https://github.com/Hollander-1908"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/93162595?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="Hollander-1908"/></a>
|
||||||
|
|
||||||
## License
|
## Licensing
|
||||||
|
|
||||||
© 2019-2023 rlaphoenix — [GNU General Public License, Version 3.0](LICENSE)
|
This software is licensed under the terms of [GNU General Public License, Version 3.0](LICENSE).
|
||||||
|
You can find a copy of the license in the LICENSE file in the root folder.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
|
||||||
|
© rlaphoenix 2019-2023
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,76 +1,91 @@
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ['poetry-core>=1.0.0']
|
requires = ["poetry-core>=1.0.0"]
|
||||||
build-backend = 'poetry.core.masonry.api'
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = 'devine'
|
name = "devine"
|
||||||
version = '2.2.0'
|
version = "2.2.0"
|
||||||
description = 'Open-Source Movie, TV, and Music Downloading Solution'
|
description = "Open-Source Movie, TV, and Music Downloading Solution."
|
||||||
license = 'GPL-3.0-only'
|
license = "GPL-3.0-only"
|
||||||
authors = ['rlaphoenix <rlaphoenix@pm.me>']
|
authors = ["rlaphoenix <rlaphoenix@pm.me>"]
|
||||||
readme = 'README.md'
|
readme = "README.md"
|
||||||
homepage = 'https://github.com/devine-dl/devine'
|
homepage = "https://github.com/devine-dl/devine"
|
||||||
repository = 'https://github.com/devine-dl/devine'
|
repository = "https://github.com/devine-dl/devine"
|
||||||
keywords = ['widevine', 'drm', 'downloader']
|
keywords = ["python", "downloader", "drm", "widevine"]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
'Development Status :: 4 - Beta',
|
"Development Status :: 4 - Beta",
|
||||||
'Environment :: Console',
|
"Environment :: Console",
|
||||||
'Intended Audience :: End Users/Desktop',
|
"Intended Audience :: End Users/Desktop",
|
||||||
'Natural Language :: English',
|
"Natural Language :: English",
|
||||||
'Operating System :: OS Independent',
|
"Operating System :: OS Independent",
|
||||||
'Topic :: Multimedia :: Video',
|
"Topic :: Multimedia :: Video",
|
||||||
'Topic :: Security :: Cryptography',
|
"Topic :: Security :: Cryptography",
|
||||||
]
|
]
|
||||||
|
include = [
|
||||||
|
{ path = "CHANGELOG.md", format = "sdist" },
|
||||||
|
{ path = "README.md", format = "sdist" },
|
||||||
|
{ path = "LICENSE", format = "sdist" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.poetry.urls]
|
||||||
|
"Issues" = "https://github.com/devine-dl/devine/issues"
|
||||||
|
"Discussions" = "https://github.com/devine-dl/devine/discussions"
|
||||||
|
"Changelog" = "https://github.com/devine-dl/devine/blob/master/CHANGELOG.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.9.0,<3.12"
|
python = ">=3.9.0,<3.12"
|
||||||
appdirs = "^1.4.4"
|
appdirs = "^1.4.4"
|
||||||
Brotli = "^1.0.9"
|
Brotli = "^1.1.0"
|
||||||
click = "^8.1.4"
|
click = "^8.1.7"
|
||||||
construct = "^2.8.8"
|
construct = "^2.8.8"
|
||||||
crccheck = "^1.3.0"
|
crccheck = "^1.3.0"
|
||||||
jsonpickle = "^3.0.1"
|
jsonpickle = "^3.0.2"
|
||||||
langcodes = { extras = ["data"], version = "^3.3.0" }
|
langcodes = { extras = ["data"], version = "^3.3.0" }
|
||||||
lxml = "^4.9.3"
|
lxml = "^4.9.3"
|
||||||
pproxy = "^2.7.8"
|
pproxy = "^2.7.8"
|
||||||
protobuf = "4.21.6"
|
protobuf = "4.21.6"
|
||||||
pycaption = "^2.1.1"
|
pycaption = "^2.1.1"
|
||||||
pycryptodomex = "^3.18.0"
|
pycryptodomex = "^3.19.0"
|
||||||
pyjwt = "^2.7.0"
|
pyjwt = "^2.8.0"
|
||||||
pymediainfo = "^6.0.1"
|
pymediainfo = "^6.0.1"
|
||||||
pymp4 = "^1.4.0"
|
pymp4 = "^1.4.0"
|
||||||
pymysql = "^1.1.0"
|
pymysql = "^1.1.0"
|
||||||
pywidevine = { extras = ["serve"], version = "^1.6.0" }
|
pywidevine = { extras = ["serve"], version = "^1.6.0" }
|
||||||
PyYAML = "^6.0"
|
PyYAML = "^6.0.1"
|
||||||
requests = { extras = ["socks"], version = "^2.31.0" }
|
requests = { extras = ["socks"], version = "^2.31.0" }
|
||||||
rich = "^13.4.2"
|
rich = "^13.5.3"
|
||||||
"rlaphoenix.m3u8" = "^3.4.0"
|
"rlaphoenix.m3u8" = "^3.4.0"
|
||||||
"ruamel.yaml" = "^0.17.32"
|
"ruamel.yaml" = "^0.17.32"
|
||||||
sortedcontainers = "^2.4.0"
|
sortedcontainers = "^2.4.0"
|
||||||
subtitle-filter = "^1.4.6"
|
subtitle-filter = "^1.4.6"
|
||||||
Unidecode = "^1.3.6"
|
Unidecode = "^1.3.6"
|
||||||
urllib3 = "^2.0.3"
|
urllib3 = "^2.0.4"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pre-commit = "^3.3.3"
|
pre-commit = "^3.4.0"
|
||||||
mypy = "^1.4.1"
|
mypy = "^1.5.1"
|
||||||
mypy-protobuf = "^3.3.0"
|
mypy-protobuf = "^3.3.0"
|
||||||
types-protobuf = "^3.19.22"
|
types-protobuf = "^4.24.0.1"
|
||||||
types-PyMySQL = "^1.1.0.0"
|
types-PyMySQL = "^1.1.0.1"
|
||||||
types-requests = "^2.31.0.1"
|
types-requests = "^2.31.0.2"
|
||||||
isort = "^5.12.0"
|
isort = "^5.12.0"
|
||||||
|
ruff = "^0.0.292"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
devine = 'devine.core.__main__:main'
|
devine = "devine.core.__main__:main"
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
force-exclude = true
|
||||||
|
line-length = 120
|
||||||
|
select = ["E4", "E7", "E9", "F", "W"]
|
||||||
|
|
||||||
[tool.isort]
|
[tool.isort]
|
||||||
line_length = 120
|
line_length = 118
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
exclude = '_pb2\.pyi?$'
|
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
disallow_untyped_defs = true
|
disallow_untyped_defs = true
|
||||||
follow_imports = 'silent'
|
follow_imports = "silent"
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
no_implicit_optional = true
|
no_implicit_optional = true
|
||||||
|
|
Loading…
Reference in New Issue