mirror of
https://github.com/LukeHagar/plexpy.git
synced 2025-12-06 12:47:44 +00:00
Cleanup previous implementations leftover code
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/python
|
|
||||||
{
|
|
||||||
"name": "Python SDK",
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
|
|
||||||
"postCreateCommand": "pip3 install --user -r requirements.txt && cd examples && sh install.sh",
|
|
||||||
"customizations": {
|
|
||||||
"codespaces":{
|
|
||||||
"openFiles": ["examples/sample.py", "examples/README.md"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
PLEXSDK_API_KEY=
|
|
||||||
160
.gitignore
vendored
160
.gitignore
vendored
@@ -1,160 +0,0 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
wheels/
|
|
||||||
share/python-wheels/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
MANIFEST
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.nox/
|
|
||||||
.coverage
|
|
||||||
.coverage.*
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
*.cover
|
|
||||||
*.py,cover
|
|
||||||
.hypothesis/
|
|
||||||
.pytest_cache/
|
|
||||||
cover/
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
local_settings.py
|
|
||||||
db.sqlite3
|
|
||||||
db.sqlite3-journal
|
|
||||||
|
|
||||||
# Flask stuff:
|
|
||||||
instance/
|
|
||||||
.webassets-cache
|
|
||||||
|
|
||||||
# Scrapy stuff:
|
|
||||||
.scrapy
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
.pybuilder/
|
|
||||||
target/
|
|
||||||
|
|
||||||
# Jupyter Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
# IPython
|
|
||||||
profile_default/
|
|
||||||
ipython_config.py
|
|
||||||
|
|
||||||
# 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.pid
|
|
||||||
|
|
||||||
# SageMath parsed files
|
|
||||||
*.sage.py
|
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# Spyder project settings
|
|
||||||
.spyderproject
|
|
||||||
.spyproject
|
|
||||||
|
|
||||||
# Rope project settings
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# mkdocs documentation
|
|
||||||
/site
|
|
||||||
|
|
||||||
# mypy
|
|
||||||
.mypy_cache/
|
|
||||||
.dmypy.json
|
|
||||||
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/
|
|
||||||
19
LICENSE
19
LICENSE
@@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2023
|
|
||||||
|
|
||||||
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.
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# plexpy-example
|
|
||||||
A basic example of how to use the plexpy package.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
If `plexpy` is published to pypi:
|
|
||||||
```sh
|
|
||||||
pip install plexpy==0.0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
In the event `plexpy` is not published to pypi, you can install it locally by running the following command in the example folder:
|
|
||||||
```sh
|
|
||||||
. ./install.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create and start a virtual environment and install the package locally in it.
|
|
||||||
|
|
||||||
To close the virtual environment run:
|
|
||||||
```sh
|
|
||||||
deactivate
|
|
||||||
```
|
|
||||||
|
|
||||||
To re-activate the virtual environment once it is installed run:
|
|
||||||
```sh
|
|
||||||
source .venv/bin/activate
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To run the example, run the following command in the examples folder:
|
|
||||||
```sh
|
|
||||||
python sample.py
|
|
||||||
```
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
python -m venv .venv
|
|
||||||
source .venv/bin/activate
|
|
||||||
pip install build
|
|
||||||
python -m build --outdir dist ../
|
|
||||||
pip install dist/plexpy-0.0.1-py3-none-any.whl
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
python3 -m venv .venv
|
|
||||||
source .venv/bin/activate
|
|
||||||
pip3 install build
|
|
||||||
python3 -m build --outdir dist ../
|
|
||||||
pip3 install dist/plexpy-0.0.1-py3-none-any.whl
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from os import getenv
|
|
||||||
from pprint import pprint
|
|
||||||
from plexsdk import PlexSDK
|
|
||||||
|
|
||||||
sdk = PlexSDK()
|
|
||||||
sdk.set_api_key(getenv("PLEXSDK_API_KEY"))
|
|
||||||
|
|
||||||
results = sdk.server.get_server_capabilities()
|
|
||||||
|
|
||||||
pprint(vars(results))
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
pip3 install -r requirements.txt
|
|
||||||
pip3 install -e src/plexsdk/
|
|
||||||
python3 -m unittest discover -p "test*.py"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
[build-system]
|
|
||||||
requires = ["setuptools>=61.0"]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
||||||
|
|
||||||
[project]
|
|
||||||
name = "plexpy"
|
|
||||||
version = "0.0.1"
|
|
||||||
license = { text = "MIT" }
|
|
||||||
authors = [
|
|
||||||
{ name="Luke Hagar", email="lukeslakemail@gmail.com" }
|
|
||||||
]
|
|
||||||
description = """An Open API Spec for interacting with Plex.tv and Plex Servers"""
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.7"
|
|
||||||
dependencies = [
|
|
||||||
"requests",
|
|
||||||
"http-exceptions",
|
|
||||||
"pytest",
|
|
||||||
"responses"
|
|
||||||
]
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
requests
|
|
||||||
http-exceptions
|
|
||||||
pytest
|
|
||||||
responses
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
|||||||
from .sdk import PlexSDK
|
|
||||||
from .net.environment import Environment
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Download(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Download._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Force(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Force._member_map_.values()))
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(self, size: float = None, Server: list = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
Server: list of dict
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if Server is not None:
|
|
||||||
self.Server = Server
|
|
||||||
|
|
||||||
|
|
||||||
class GetAvailableClientsResponseItem(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetAvailableClientsResponseItem
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
|
|
||||||
|
|
||||||
GetAvailableClientsResponse = List[GetAvailableClientsResponseItem]
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class ButlerTasksButlerTask(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: str = None,
|
|
||||||
interval: float = None,
|
|
||||||
scheduleRandomized: bool = None,
|
|
||||||
enabled: bool = None,
|
|
||||||
title: str = None,
|
|
||||||
description: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize ButlerTasksButlerTask
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
name: str
|
|
||||||
interval: float
|
|
||||||
scheduleRandomized: bool
|
|
||||||
enabled: bool
|
|
||||||
title: str
|
|
||||||
description: str
|
|
||||||
"""
|
|
||||||
if name is not None:
|
|
||||||
self.name = name
|
|
||||||
if interval is not None:
|
|
||||||
self.interval = interval
|
|
||||||
if scheduleRandomized is not None:
|
|
||||||
self.scheduleRandomized = scheduleRandomized
|
|
||||||
if enabled is not None:
|
|
||||||
self.enabled = enabled
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if description is not None:
|
|
||||||
self.description = description
|
|
||||||
|
|
||||||
|
|
||||||
class ButlerTasks(BaseModel):
|
|
||||||
def __init__(self, ButlerTask: List[ButlerTasksButlerTask] = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize ButlerTasks
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
ButlerTask: list of ButlerTasksButlerTask
|
|
||||||
"""
|
|
||||||
if ButlerTask is not None:
|
|
||||||
self.ButlerTask = ButlerTask
|
|
||||||
|
|
||||||
|
|
||||||
class GetButlerTasksResponse(BaseModel):
|
|
||||||
def __init__(self, ButlerTasks: ButlerTasks = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetButlerTasksResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
ButlerTasks: ButlerTasks
|
|
||||||
"""
|
|
||||||
if ButlerTasks is not None:
|
|
||||||
self.ButlerTasks = ButlerTasks
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerDevice(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
name: str = None,
|
|
||||||
platform: str = None,
|
|
||||||
clientIdentifier: str = None,
|
|
||||||
createdAt: float = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerDevice
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
name: str
|
|
||||||
platform: str
|
|
||||||
clientIdentifier: str
|
|
||||||
createdAt: float
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if name is not None:
|
|
||||||
self.name = name
|
|
||||||
if platform is not None:
|
|
||||||
self.platform = platform
|
|
||||||
if clientIdentifier is not None:
|
|
||||||
self.clientIdentifier = clientIdentifier
|
|
||||||
if createdAt is not None:
|
|
||||||
self.createdAt = createdAt
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
identifier: str = None,
|
|
||||||
Device: List[MediaContainerDevice] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
identifier: str
|
|
||||||
Device: list of MediaContainerDevice
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if identifier is not None:
|
|
||||||
self.identifier = identifier
|
|
||||||
if Device is not None:
|
|
||||||
self.Device = Device
|
|
||||||
|
|
||||||
|
|
||||||
class GetDevicesResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetDevicesResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class MyPlex(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
authToken: str = None,
|
|
||||||
username: str = None,
|
|
||||||
mappingState: str = None,
|
|
||||||
mappingError: str = None,
|
|
||||||
signInState: str = None,
|
|
||||||
publicAddress: str = None,
|
|
||||||
publicPort: float = None,
|
|
||||||
privateAddress: str = None,
|
|
||||||
privatePort: float = None,
|
|
||||||
subscriptionFeatures: str = None,
|
|
||||||
subscriptionActive: bool = None,
|
|
||||||
subscriptionState: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MyPlex
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
authToken: str
|
|
||||||
username: str
|
|
||||||
mappingState: str
|
|
||||||
mappingError: str
|
|
||||||
signInState: str
|
|
||||||
publicAddress: str
|
|
||||||
publicPort: float
|
|
||||||
privateAddress: str
|
|
||||||
privatePort: float
|
|
||||||
subscriptionFeatures: str
|
|
||||||
subscriptionActive: bool
|
|
||||||
subscriptionState: str
|
|
||||||
"""
|
|
||||||
if authToken is not None:
|
|
||||||
self.authToken = authToken
|
|
||||||
if username is not None:
|
|
||||||
self.username = username
|
|
||||||
if mappingState is not None:
|
|
||||||
self.mappingState = mappingState
|
|
||||||
if mappingError is not None:
|
|
||||||
self.mappingError = mappingError
|
|
||||||
if signInState is not None:
|
|
||||||
self.signInState = signInState
|
|
||||||
if publicAddress is not None:
|
|
||||||
self.publicAddress = publicAddress
|
|
||||||
if publicPort is not None:
|
|
||||||
self.publicPort = publicPort
|
|
||||||
if privateAddress is not None:
|
|
||||||
self.privateAddress = privateAddress
|
|
||||||
if privatePort is not None:
|
|
||||||
self.privatePort = privatePort
|
|
||||||
if subscriptionFeatures is not None:
|
|
||||||
self.subscriptionFeatures = subscriptionFeatures
|
|
||||||
if subscriptionActive is not None:
|
|
||||||
self.subscriptionActive = subscriptionActive
|
|
||||||
if subscriptionState is not None:
|
|
||||||
self.subscriptionState = subscriptionState
|
|
||||||
|
|
||||||
|
|
||||||
class GetMyPlexAccountResponse(BaseModel):
|
|
||||||
def __init__(self, MyPlex: MyPlex = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetMyPlexAccountResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MyPlex: MyPlex
|
|
||||||
"""
|
|
||||||
if MyPlex is not None:
|
|
||||||
self.MyPlex = MyPlex
|
|
||||||
@@ -1,446 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMediaPartStream(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
streamType: float = None,
|
|
||||||
default: bool = None,
|
|
||||||
codec: str = None,
|
|
||||||
index: float = None,
|
|
||||||
bitrate: float = None,
|
|
||||||
language: str = None,
|
|
||||||
languageTag: str = None,
|
|
||||||
languageCode: str = None,
|
|
||||||
bitDepth: float = None,
|
|
||||||
chromaLocation: str = None,
|
|
||||||
chromaSubsampling: str = None,
|
|
||||||
codedHeight: float = None,
|
|
||||||
codedWidth: float = None,
|
|
||||||
colorRange: str = None,
|
|
||||||
frameRate: float = None,
|
|
||||||
height: float = None,
|
|
||||||
level: float = None,
|
|
||||||
profile: str = None,
|
|
||||||
refFrames: float = None,
|
|
||||||
width: float = None,
|
|
||||||
displayTitle: str = None,
|
|
||||||
extendedDisplayTitle: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMediaPartStream
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
streamType: float
|
|
||||||
default: bool
|
|
||||||
codec: str
|
|
||||||
index: float
|
|
||||||
bitrate: float
|
|
||||||
language: str
|
|
||||||
languageTag: str
|
|
||||||
languageCode: str
|
|
||||||
bitDepth: float
|
|
||||||
chromaLocation: str
|
|
||||||
chromaSubsampling: str
|
|
||||||
codedHeight: float
|
|
||||||
codedWidth: float
|
|
||||||
colorRange: str
|
|
||||||
frameRate: float
|
|
||||||
height: float
|
|
||||||
level: float
|
|
||||||
profile: str
|
|
||||||
refFrames: float
|
|
||||||
width: float
|
|
||||||
displayTitle: str
|
|
||||||
extendedDisplayTitle: str
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if streamType is not None:
|
|
||||||
self.streamType = streamType
|
|
||||||
if default is not None:
|
|
||||||
self.default = default
|
|
||||||
if codec is not None:
|
|
||||||
self.codec = codec
|
|
||||||
if index is not None:
|
|
||||||
self.index = index
|
|
||||||
if bitrate is not None:
|
|
||||||
self.bitrate = bitrate
|
|
||||||
if language is not None:
|
|
||||||
self.language = language
|
|
||||||
if languageTag is not None:
|
|
||||||
self.languageTag = languageTag
|
|
||||||
if languageCode is not None:
|
|
||||||
self.languageCode = languageCode
|
|
||||||
if bitDepth is not None:
|
|
||||||
self.bitDepth = bitDepth
|
|
||||||
if chromaLocation is not None:
|
|
||||||
self.chromaLocation = chromaLocation
|
|
||||||
if chromaSubsampling is not None:
|
|
||||||
self.chromaSubsampling = chromaSubsampling
|
|
||||||
if codedHeight is not None:
|
|
||||||
self.codedHeight = codedHeight
|
|
||||||
if codedWidth is not None:
|
|
||||||
self.codedWidth = codedWidth
|
|
||||||
if colorRange is not None:
|
|
||||||
self.colorRange = colorRange
|
|
||||||
if frameRate is not None:
|
|
||||||
self.frameRate = frameRate
|
|
||||||
if height is not None:
|
|
||||||
self.height = height
|
|
||||||
if level is not None:
|
|
||||||
self.level = level
|
|
||||||
if profile is not None:
|
|
||||||
self.profile = profile
|
|
||||||
if refFrames is not None:
|
|
||||||
self.refFrames = refFrames
|
|
||||||
if width is not None:
|
|
||||||
self.width = width
|
|
||||||
if displayTitle is not None:
|
|
||||||
self.displayTitle = displayTitle
|
|
||||||
if extendedDisplayTitle is not None:
|
|
||||||
self.extendedDisplayTitle = extendedDisplayTitle
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMediaPart(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
key: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
file: str = None,
|
|
||||||
size: float = None,
|
|
||||||
audioProfile: str = None,
|
|
||||||
container: str = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
Stream: List[MediaContainerMetadataMediaPartStream] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMediaPart
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
key: str
|
|
||||||
duration: float
|
|
||||||
file: str
|
|
||||||
size: float
|
|
||||||
audioProfile: str
|
|
||||||
container: str
|
|
||||||
videoProfile: str
|
|
||||||
Stream: list of MediaContainerMetadataMediaPartStream
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if file is not None:
|
|
||||||
self.file = file
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if audioProfile is not None:
|
|
||||||
self.audioProfile = audioProfile
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
if Stream is not None:
|
|
||||||
self.Stream = Stream
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMedia(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
duration: float = None,
|
|
||||||
bitrate: float = None,
|
|
||||||
width: float = None,
|
|
||||||
height: float = None,
|
|
||||||
aspectRatio: float = None,
|
|
||||||
audioChannels: float = None,
|
|
||||||
audioCodec: str = None,
|
|
||||||
videoCodec: str = None,
|
|
||||||
videoResolution: str = None,
|
|
||||||
container: str = None,
|
|
||||||
videoFrameRate: str = None,
|
|
||||||
audioProfile: str = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
Part: List[MediaContainerMetadataMediaPart] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMedia
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
duration: float
|
|
||||||
bitrate: float
|
|
||||||
width: float
|
|
||||||
height: float
|
|
||||||
aspectRatio: float
|
|
||||||
audioChannels: float
|
|
||||||
audioCodec: str
|
|
||||||
videoCodec: str
|
|
||||||
videoResolution: str
|
|
||||||
container: str
|
|
||||||
videoFrameRate: str
|
|
||||||
audioProfile: str
|
|
||||||
videoProfile: str
|
|
||||||
Part: list of MediaContainerMetadataMediaPart
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if bitrate is not None:
|
|
||||||
self.bitrate = bitrate
|
|
||||||
if width is not None:
|
|
||||||
self.width = width
|
|
||||||
if height is not None:
|
|
||||||
self.height = height
|
|
||||||
if aspectRatio is not None:
|
|
||||||
self.aspectRatio = aspectRatio
|
|
||||||
if audioChannels is not None:
|
|
||||||
self.audioChannels = audioChannels
|
|
||||||
if audioCodec is not None:
|
|
||||||
self.audioCodec = audioCodec
|
|
||||||
if videoCodec is not None:
|
|
||||||
self.videoCodec = videoCodec
|
|
||||||
if videoResolution is not None:
|
|
||||||
self.videoResolution = videoResolution
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoFrameRate is not None:
|
|
||||||
self.videoFrameRate = videoFrameRate
|
|
||||||
if audioProfile is not None:
|
|
||||||
self.audioProfile = audioProfile
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
if Part is not None:
|
|
||||||
self.Part = Part
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataGuid(BaseModel):
|
|
||||||
def __init__(self, id: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataGuid
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: str
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadata(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
allowSync: bool = None,
|
|
||||||
librarySectionID: float = None,
|
|
||||||
librarySectionTitle: str = None,
|
|
||||||
librarySectionUUID: str = None,
|
|
||||||
ratingKey: float = None,
|
|
||||||
key: str = None,
|
|
||||||
parentRatingKey: float = None,
|
|
||||||
grandparentRatingKey: float = None,
|
|
||||||
guid: str = None,
|
|
||||||
parentGuid: str = None,
|
|
||||||
grandparentGuid: str = None,
|
|
||||||
title: str = None,
|
|
||||||
grandparentKey: str = None,
|
|
||||||
parentKey: str = None,
|
|
||||||
librarySectionKey: str = None,
|
|
||||||
grandparentTitle: str = None,
|
|
||||||
parentTitle: str = None,
|
|
||||||
contentRating: str = None,
|
|
||||||
summary: str = None,
|
|
||||||
index: float = None,
|
|
||||||
parentIndex: float = None,
|
|
||||||
lastViewedAt: float = None,
|
|
||||||
year: float = None,
|
|
||||||
thumb: str = None,
|
|
||||||
art: str = None,
|
|
||||||
parentThumb: str = None,
|
|
||||||
grandparentThumb: str = None,
|
|
||||||
grandparentArt: str = None,
|
|
||||||
grandparentTheme: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
originallyAvailableAt: str = None,
|
|
||||||
addedAt: float = None,
|
|
||||||
updatedAt: float = None,
|
|
||||||
Media: List[MediaContainerMetadataMedia] = None,
|
|
||||||
Guid: List[MediaContainerMetadataGuid] = None,
|
|
||||||
type_: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadata
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
allowSync: bool
|
|
||||||
librarySectionID: float
|
|
||||||
librarySectionTitle: str
|
|
||||||
librarySectionUUID: str
|
|
||||||
ratingKey: float
|
|
||||||
key: str
|
|
||||||
parentRatingKey: float
|
|
||||||
grandparentRatingKey: float
|
|
||||||
guid: str
|
|
||||||
parentGuid: str
|
|
||||||
grandparentGuid: str
|
|
||||||
title: str
|
|
||||||
grandparentKey: str
|
|
||||||
parentKey: str
|
|
||||||
librarySectionKey: str
|
|
||||||
grandparentTitle: str
|
|
||||||
parentTitle: str
|
|
||||||
contentRating: str
|
|
||||||
summary: str
|
|
||||||
index: float
|
|
||||||
parentIndex: float
|
|
||||||
lastViewedAt: float
|
|
||||||
year: float
|
|
||||||
thumb: str
|
|
||||||
art: str
|
|
||||||
parentThumb: str
|
|
||||||
grandparentThumb: str
|
|
||||||
grandparentArt: str
|
|
||||||
grandparentTheme: str
|
|
||||||
duration: float
|
|
||||||
originallyAvailableAt: str
|
|
||||||
addedAt: float
|
|
||||||
updatedAt: float
|
|
||||||
Media: list of MediaContainerMetadataMedia
|
|
||||||
Guid: list of MediaContainerMetadataGuid
|
|
||||||
type_: str
|
|
||||||
"""
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if librarySectionID is not None:
|
|
||||||
self.librarySectionID = librarySectionID
|
|
||||||
if librarySectionTitle is not None:
|
|
||||||
self.librarySectionTitle = librarySectionTitle
|
|
||||||
if librarySectionUUID is not None:
|
|
||||||
self.librarySectionUUID = librarySectionUUID
|
|
||||||
if ratingKey is not None:
|
|
||||||
self.ratingKey = ratingKey
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if parentRatingKey is not None:
|
|
||||||
self.parentRatingKey = parentRatingKey
|
|
||||||
if grandparentRatingKey is not None:
|
|
||||||
self.grandparentRatingKey = grandparentRatingKey
|
|
||||||
if guid is not None:
|
|
||||||
self.guid = guid
|
|
||||||
if parentGuid is not None:
|
|
||||||
self.parentGuid = parentGuid
|
|
||||||
if grandparentGuid is not None:
|
|
||||||
self.grandparentGuid = grandparentGuid
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if grandparentKey is not None:
|
|
||||||
self.grandparentKey = grandparentKey
|
|
||||||
if parentKey is not None:
|
|
||||||
self.parentKey = parentKey
|
|
||||||
if librarySectionKey is not None:
|
|
||||||
self.librarySectionKey = librarySectionKey
|
|
||||||
if grandparentTitle is not None:
|
|
||||||
self.grandparentTitle = grandparentTitle
|
|
||||||
if parentTitle is not None:
|
|
||||||
self.parentTitle = parentTitle
|
|
||||||
if contentRating is not None:
|
|
||||||
self.contentRating = contentRating
|
|
||||||
if summary is not None:
|
|
||||||
self.summary = summary
|
|
||||||
if index is not None:
|
|
||||||
self.index = index
|
|
||||||
if parentIndex is not None:
|
|
||||||
self.parentIndex = parentIndex
|
|
||||||
if lastViewedAt is not None:
|
|
||||||
self.lastViewedAt = lastViewedAt
|
|
||||||
if year is not None:
|
|
||||||
self.year = year
|
|
||||||
if thumb is not None:
|
|
||||||
self.thumb = thumb
|
|
||||||
if art is not None:
|
|
||||||
self.art = art
|
|
||||||
if parentThumb is not None:
|
|
||||||
self.parentThumb = parentThumb
|
|
||||||
if grandparentThumb is not None:
|
|
||||||
self.grandparentThumb = grandparentThumb
|
|
||||||
if grandparentArt is not None:
|
|
||||||
self.grandparentArt = grandparentArt
|
|
||||||
if grandparentTheme is not None:
|
|
||||||
self.grandparentTheme = grandparentTheme
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if originallyAvailableAt is not None:
|
|
||||||
self.originallyAvailableAt = originallyAvailableAt
|
|
||||||
if addedAt is not None:
|
|
||||||
self.addedAt = addedAt
|
|
||||||
if updatedAt is not None:
|
|
||||||
self.updatedAt = updatedAt
|
|
||||||
if Media is not None:
|
|
||||||
self.Media = Media
|
|
||||||
if Guid is not None:
|
|
||||||
self.Guid = Guid
|
|
||||||
if type_ is not None:
|
|
||||||
self.type_ = type_
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
allowSync: bool = None,
|
|
||||||
identifier: str = None,
|
|
||||||
mediaTagPrefix: str = None,
|
|
||||||
mediaTagVersion: float = None,
|
|
||||||
mixedParents: bool = None,
|
|
||||||
Metadata: List[MediaContainerMetadata] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
allowSync: bool
|
|
||||||
identifier: str
|
|
||||||
mediaTagPrefix: str
|
|
||||||
mediaTagVersion: float
|
|
||||||
mixedParents: bool
|
|
||||||
Metadata: list of MediaContainerMetadata
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if identifier is not None:
|
|
||||||
self.identifier = identifier
|
|
||||||
if mediaTagPrefix is not None:
|
|
||||||
self.mediaTagPrefix = mediaTagPrefix
|
|
||||||
if mediaTagVersion is not None:
|
|
||||||
self.mediaTagVersion = mediaTagVersion
|
|
||||||
if mixedParents is not None:
|
|
||||||
self.mixedParents = mixedParents
|
|
||||||
if Metadata is not None:
|
|
||||||
self.Metadata = Metadata
|
|
||||||
|
|
||||||
|
|
||||||
class GetOnDeckResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetOnDeckResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,382 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMediaPart(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
key: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
file: str = None,
|
|
||||||
size: float = None,
|
|
||||||
container: str = None,
|
|
||||||
has64bitOffsets: bool = None,
|
|
||||||
hasThumbnail: float = None,
|
|
||||||
optimizedForStreaming: bool = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMediaPart
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
key: str
|
|
||||||
duration: float
|
|
||||||
file: str
|
|
||||||
size: float
|
|
||||||
container: str
|
|
||||||
has64bitOffsets: bool
|
|
||||||
hasThumbnail: float
|
|
||||||
optimizedForStreaming: bool
|
|
||||||
videoProfile: str
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if file is not None:
|
|
||||||
self.file = file
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if has64bitOffsets is not None:
|
|
||||||
self.has64bitOffsets = has64bitOffsets
|
|
||||||
if hasThumbnail is not None:
|
|
||||||
self.hasThumbnail = hasThumbnail
|
|
||||||
if optimizedForStreaming is not None:
|
|
||||||
self.optimizedForStreaming = optimizedForStreaming
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMedia(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
duration: float = None,
|
|
||||||
bitrate: float = None,
|
|
||||||
width: float = None,
|
|
||||||
height: float = None,
|
|
||||||
aspectRatio: float = None,
|
|
||||||
audioChannels: float = None,
|
|
||||||
audioCodec: str = None,
|
|
||||||
videoCodec: str = None,
|
|
||||||
videoResolution: float = None,
|
|
||||||
container: str = None,
|
|
||||||
videoFrameRate: str = None,
|
|
||||||
optimizedForStreaming: float = None,
|
|
||||||
has64bitOffsets: bool = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
Part: List[MediaContainerMetadataMediaPart] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMedia
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
duration: float
|
|
||||||
bitrate: float
|
|
||||||
width: float
|
|
||||||
height: float
|
|
||||||
aspectRatio: float
|
|
||||||
audioChannels: float
|
|
||||||
audioCodec: str
|
|
||||||
videoCodec: str
|
|
||||||
videoResolution: float
|
|
||||||
container: str
|
|
||||||
videoFrameRate: str
|
|
||||||
optimizedForStreaming: float
|
|
||||||
has64bitOffsets: bool
|
|
||||||
videoProfile: str
|
|
||||||
Part: list of MediaContainerMetadataMediaPart
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if bitrate is not None:
|
|
||||||
self.bitrate = bitrate
|
|
||||||
if width is not None:
|
|
||||||
self.width = width
|
|
||||||
if height is not None:
|
|
||||||
self.height = height
|
|
||||||
if aspectRatio is not None:
|
|
||||||
self.aspectRatio = aspectRatio
|
|
||||||
if audioChannels is not None:
|
|
||||||
self.audioChannels = audioChannels
|
|
||||||
if audioCodec is not None:
|
|
||||||
self.audioCodec = audioCodec
|
|
||||||
if videoCodec is not None:
|
|
||||||
self.videoCodec = videoCodec
|
|
||||||
if videoResolution is not None:
|
|
||||||
self.videoResolution = videoResolution
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoFrameRate is not None:
|
|
||||||
self.videoFrameRate = videoFrameRate
|
|
||||||
if optimizedForStreaming is not None:
|
|
||||||
self.optimizedForStreaming = optimizedForStreaming
|
|
||||||
if has64bitOffsets is not None:
|
|
||||||
self.has64bitOffsets = has64bitOffsets
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
if Part is not None:
|
|
||||||
self.Part = Part
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataGenre(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataGenre
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataDirector(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataDirector
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataWriter(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataWriter
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataCountry(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataCountry
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataRole(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataRole
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadata(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
allowSync: bool = None,
|
|
||||||
librarySectionID: float = None,
|
|
||||||
librarySectionTitle: str = None,
|
|
||||||
librarySectionUUID: str = None,
|
|
||||||
ratingKey: float = None,
|
|
||||||
key: str = None,
|
|
||||||
guid: str = None,
|
|
||||||
studio: str = None,
|
|
||||||
title: str = None,
|
|
||||||
contentRating: str = None,
|
|
||||||
summary: str = None,
|
|
||||||
rating: float = None,
|
|
||||||
audienceRating: float = None,
|
|
||||||
year: float = None,
|
|
||||||
tagline: str = None,
|
|
||||||
thumb: str = None,
|
|
||||||
art: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
originallyAvailableAt: str = None,
|
|
||||||
addedAt: float = None,
|
|
||||||
updatedAt: float = None,
|
|
||||||
audienceRatingImage: str = None,
|
|
||||||
chapterSource: str = None,
|
|
||||||
primaryExtraKey: str = None,
|
|
||||||
ratingImage: str = None,
|
|
||||||
Media: List[MediaContainerMetadataMedia] = None,
|
|
||||||
Genre: List[MediaContainerMetadataGenre] = None,
|
|
||||||
Director: List[MediaContainerMetadataDirector] = None,
|
|
||||||
Writer: List[MediaContainerMetadataWriter] = None,
|
|
||||||
Country: List[MediaContainerMetadataCountry] = None,
|
|
||||||
Role: List[MediaContainerMetadataRole] = None,
|
|
||||||
type_: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadata
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
allowSync: bool
|
|
||||||
librarySectionID: float
|
|
||||||
librarySectionTitle: str
|
|
||||||
librarySectionUUID: str
|
|
||||||
ratingKey: float
|
|
||||||
key: str
|
|
||||||
guid: str
|
|
||||||
studio: str
|
|
||||||
title: str
|
|
||||||
contentRating: str
|
|
||||||
summary: str
|
|
||||||
rating: float
|
|
||||||
audienceRating: float
|
|
||||||
year: float
|
|
||||||
tagline: str
|
|
||||||
thumb: str
|
|
||||||
art: str
|
|
||||||
duration: float
|
|
||||||
originallyAvailableAt: str
|
|
||||||
addedAt: float
|
|
||||||
updatedAt: float
|
|
||||||
audienceRatingImage: str
|
|
||||||
chapterSource: str
|
|
||||||
primaryExtraKey: str
|
|
||||||
ratingImage: str
|
|
||||||
Media: list of MediaContainerMetadataMedia
|
|
||||||
Genre: list of MediaContainerMetadataGenre
|
|
||||||
Director: list of MediaContainerMetadataDirector
|
|
||||||
Writer: list of MediaContainerMetadataWriter
|
|
||||||
Country: list of MediaContainerMetadataCountry
|
|
||||||
Role: list of MediaContainerMetadataRole
|
|
||||||
type_: str
|
|
||||||
"""
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if librarySectionID is not None:
|
|
||||||
self.librarySectionID = librarySectionID
|
|
||||||
if librarySectionTitle is not None:
|
|
||||||
self.librarySectionTitle = librarySectionTitle
|
|
||||||
if librarySectionUUID is not None:
|
|
||||||
self.librarySectionUUID = librarySectionUUID
|
|
||||||
if ratingKey is not None:
|
|
||||||
self.ratingKey = ratingKey
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if guid is not None:
|
|
||||||
self.guid = guid
|
|
||||||
if studio is not None:
|
|
||||||
self.studio = studio
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if contentRating is not None:
|
|
||||||
self.contentRating = contentRating
|
|
||||||
if summary is not None:
|
|
||||||
self.summary = summary
|
|
||||||
if rating is not None:
|
|
||||||
self.rating = rating
|
|
||||||
if audienceRating is not None:
|
|
||||||
self.audienceRating = audienceRating
|
|
||||||
if year is not None:
|
|
||||||
self.year = year
|
|
||||||
if tagline is not None:
|
|
||||||
self.tagline = tagline
|
|
||||||
if thumb is not None:
|
|
||||||
self.thumb = thumb
|
|
||||||
if art is not None:
|
|
||||||
self.art = art
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if originallyAvailableAt is not None:
|
|
||||||
self.originallyAvailableAt = originallyAvailableAt
|
|
||||||
if addedAt is not None:
|
|
||||||
self.addedAt = addedAt
|
|
||||||
if updatedAt is not None:
|
|
||||||
self.updatedAt = updatedAt
|
|
||||||
if audienceRatingImage is not None:
|
|
||||||
self.audienceRatingImage = audienceRatingImage
|
|
||||||
if chapterSource is not None:
|
|
||||||
self.chapterSource = chapterSource
|
|
||||||
if primaryExtraKey is not None:
|
|
||||||
self.primaryExtraKey = primaryExtraKey
|
|
||||||
if ratingImage is not None:
|
|
||||||
self.ratingImage = ratingImage
|
|
||||||
if Media is not None:
|
|
||||||
self.Media = Media
|
|
||||||
if Genre is not None:
|
|
||||||
self.Genre = Genre
|
|
||||||
if Director is not None:
|
|
||||||
self.Director = Director
|
|
||||||
if Writer is not None:
|
|
||||||
self.Writer = Writer
|
|
||||||
if Country is not None:
|
|
||||||
self.Country = Country
|
|
||||||
if Role is not None:
|
|
||||||
self.Role = Role
|
|
||||||
if type_ is not None:
|
|
||||||
self.type_ = type_
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
allowSync: bool = None,
|
|
||||||
identifier: str = None,
|
|
||||||
mediaTagPrefix: str = None,
|
|
||||||
mediaTagVersion: float = None,
|
|
||||||
mixedParents: bool = None,
|
|
||||||
Metadata: List[MediaContainerMetadata] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
allowSync: bool
|
|
||||||
identifier: str
|
|
||||||
mediaTagPrefix: str
|
|
||||||
mediaTagVersion: float
|
|
||||||
mixedParents: bool
|
|
||||||
Metadata: list of MediaContainerMetadata
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if identifier is not None:
|
|
||||||
self.identifier = identifier
|
|
||||||
if mediaTagPrefix is not None:
|
|
||||||
self.mediaTagPrefix = mediaTagPrefix
|
|
||||||
if mediaTagVersion is not None:
|
|
||||||
self.mediaTagVersion = mediaTagVersion
|
|
||||||
if mixedParents is not None:
|
|
||||||
self.mixedParents = mixedParents
|
|
||||||
if Metadata is not None:
|
|
||||||
self.Metadata = Metadata
|
|
||||||
|
|
||||||
|
|
||||||
class GetRecentlyAddedResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetRecentlyAddedResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,392 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMediaPart(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
key: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
file: str = None,
|
|
||||||
size: float = None,
|
|
||||||
audioProfile: str = None,
|
|
||||||
container: str = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMediaPart
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
key: str
|
|
||||||
duration: float
|
|
||||||
file: str
|
|
||||||
size: float
|
|
||||||
audioProfile: str
|
|
||||||
container: str
|
|
||||||
videoProfile: str
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if file is not None:
|
|
||||||
self.file = file
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if audioProfile is not None:
|
|
||||||
self.audioProfile = audioProfile
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataMedia(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
id: float = None,
|
|
||||||
duration: float = None,
|
|
||||||
bitrate: float = None,
|
|
||||||
width: float = None,
|
|
||||||
height: float = None,
|
|
||||||
aspectRatio: float = None,
|
|
||||||
audioChannels: float = None,
|
|
||||||
audioCodec: str = None,
|
|
||||||
videoCodec: str = None,
|
|
||||||
videoResolution: float = None,
|
|
||||||
container: str = None,
|
|
||||||
videoFrameRate: str = None,
|
|
||||||
audioProfile: str = None,
|
|
||||||
videoProfile: str = None,
|
|
||||||
Part: List[MediaContainerMetadataMediaPart] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataMedia
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
id: float
|
|
||||||
duration: float
|
|
||||||
bitrate: float
|
|
||||||
width: float
|
|
||||||
height: float
|
|
||||||
aspectRatio: float
|
|
||||||
audioChannels: float
|
|
||||||
audioCodec: str
|
|
||||||
videoCodec: str
|
|
||||||
videoResolution: float
|
|
||||||
container: str
|
|
||||||
videoFrameRate: str
|
|
||||||
audioProfile: str
|
|
||||||
videoProfile: str
|
|
||||||
Part: list of MediaContainerMetadataMediaPart
|
|
||||||
"""
|
|
||||||
if id is not None:
|
|
||||||
self.id = id
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if bitrate is not None:
|
|
||||||
self.bitrate = bitrate
|
|
||||||
if width is not None:
|
|
||||||
self.width = width
|
|
||||||
if height is not None:
|
|
||||||
self.height = height
|
|
||||||
if aspectRatio is not None:
|
|
||||||
self.aspectRatio = aspectRatio
|
|
||||||
if audioChannels is not None:
|
|
||||||
self.audioChannels = audioChannels
|
|
||||||
if audioCodec is not None:
|
|
||||||
self.audioCodec = audioCodec
|
|
||||||
if videoCodec is not None:
|
|
||||||
self.videoCodec = videoCodec
|
|
||||||
if videoResolution is not None:
|
|
||||||
self.videoResolution = videoResolution
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoFrameRate is not None:
|
|
||||||
self.videoFrameRate = videoFrameRate
|
|
||||||
if audioProfile is not None:
|
|
||||||
self.audioProfile = audioProfile
|
|
||||||
if videoProfile is not None:
|
|
||||||
self.videoProfile = videoProfile
|
|
||||||
if Part is not None:
|
|
||||||
self.Part = Part
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataGenre(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataGenre
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataDirector(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataDirector
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataWriter(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataWriter
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataCountry(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataCountry
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadataRole(BaseModel):
|
|
||||||
def __init__(self, tag: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadataRole
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tag: str
|
|
||||||
"""
|
|
||||||
if tag is not None:
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerMetadata(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
allowSync: bool = None,
|
|
||||||
librarySectionID: float = None,
|
|
||||||
librarySectionTitle: str = None,
|
|
||||||
librarySectionUUID: str = None,
|
|
||||||
personal: bool = None,
|
|
||||||
sourceTitle: str = None,
|
|
||||||
ratingKey: float = None,
|
|
||||||
key: str = None,
|
|
||||||
guid: str = None,
|
|
||||||
studio: str = None,
|
|
||||||
title: str = None,
|
|
||||||
contentRating: str = None,
|
|
||||||
summary: str = None,
|
|
||||||
rating: float = None,
|
|
||||||
audienceRating: float = None,
|
|
||||||
year: float = None,
|
|
||||||
tagline: str = None,
|
|
||||||
thumb: str = None,
|
|
||||||
art: str = None,
|
|
||||||
duration: float = None,
|
|
||||||
originallyAvailableAt: str = None,
|
|
||||||
addedAt: float = None,
|
|
||||||
updatedAt: float = None,
|
|
||||||
audienceRatingImage: str = None,
|
|
||||||
chapterSource: str = None,
|
|
||||||
primaryExtraKey: str = None,
|
|
||||||
ratingImage: str = None,
|
|
||||||
Media: List[MediaContainerMetadataMedia] = None,
|
|
||||||
Genre: List[MediaContainerMetadataGenre] = None,
|
|
||||||
Director: List[MediaContainerMetadataDirector] = None,
|
|
||||||
Writer: List[MediaContainerMetadataWriter] = None,
|
|
||||||
Country: List[MediaContainerMetadataCountry] = None,
|
|
||||||
Role: List[MediaContainerMetadataRole] = None,
|
|
||||||
type_: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerMetadata
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
allowSync: bool
|
|
||||||
librarySectionID: float
|
|
||||||
librarySectionTitle: str
|
|
||||||
librarySectionUUID: str
|
|
||||||
personal: bool
|
|
||||||
sourceTitle: str
|
|
||||||
ratingKey: float
|
|
||||||
key: str
|
|
||||||
guid: str
|
|
||||||
studio: str
|
|
||||||
title: str
|
|
||||||
contentRating: str
|
|
||||||
summary: str
|
|
||||||
rating: float
|
|
||||||
audienceRating: float
|
|
||||||
year: float
|
|
||||||
tagline: str
|
|
||||||
thumb: str
|
|
||||||
art: str
|
|
||||||
duration: float
|
|
||||||
originallyAvailableAt: str
|
|
||||||
addedAt: float
|
|
||||||
updatedAt: float
|
|
||||||
audienceRatingImage: str
|
|
||||||
chapterSource: str
|
|
||||||
primaryExtraKey: str
|
|
||||||
ratingImage: str
|
|
||||||
Media: list of MediaContainerMetadataMedia
|
|
||||||
Genre: list of MediaContainerMetadataGenre
|
|
||||||
Director: list of MediaContainerMetadataDirector
|
|
||||||
Writer: list of MediaContainerMetadataWriter
|
|
||||||
Country: list of MediaContainerMetadataCountry
|
|
||||||
Role: list of MediaContainerMetadataRole
|
|
||||||
type_: str
|
|
||||||
"""
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if librarySectionID is not None:
|
|
||||||
self.librarySectionID = librarySectionID
|
|
||||||
if librarySectionTitle is not None:
|
|
||||||
self.librarySectionTitle = librarySectionTitle
|
|
||||||
if librarySectionUUID is not None:
|
|
||||||
self.librarySectionUUID = librarySectionUUID
|
|
||||||
if personal is not None:
|
|
||||||
self.personal = personal
|
|
||||||
if sourceTitle is not None:
|
|
||||||
self.sourceTitle = sourceTitle
|
|
||||||
if ratingKey is not None:
|
|
||||||
self.ratingKey = ratingKey
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if guid is not None:
|
|
||||||
self.guid = guid
|
|
||||||
if studio is not None:
|
|
||||||
self.studio = studio
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if contentRating is not None:
|
|
||||||
self.contentRating = contentRating
|
|
||||||
if summary is not None:
|
|
||||||
self.summary = summary
|
|
||||||
if rating is not None:
|
|
||||||
self.rating = rating
|
|
||||||
if audienceRating is not None:
|
|
||||||
self.audienceRating = audienceRating
|
|
||||||
if year is not None:
|
|
||||||
self.year = year
|
|
||||||
if tagline is not None:
|
|
||||||
self.tagline = tagline
|
|
||||||
if thumb is not None:
|
|
||||||
self.thumb = thumb
|
|
||||||
if art is not None:
|
|
||||||
self.art = art
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if originallyAvailableAt is not None:
|
|
||||||
self.originallyAvailableAt = originallyAvailableAt
|
|
||||||
if addedAt is not None:
|
|
||||||
self.addedAt = addedAt
|
|
||||||
if updatedAt is not None:
|
|
||||||
self.updatedAt = updatedAt
|
|
||||||
if audienceRatingImage is not None:
|
|
||||||
self.audienceRatingImage = audienceRatingImage
|
|
||||||
if chapterSource is not None:
|
|
||||||
self.chapterSource = chapterSource
|
|
||||||
if primaryExtraKey is not None:
|
|
||||||
self.primaryExtraKey = primaryExtraKey
|
|
||||||
if ratingImage is not None:
|
|
||||||
self.ratingImage = ratingImage
|
|
||||||
if Media is not None:
|
|
||||||
self.Media = Media
|
|
||||||
if Genre is not None:
|
|
||||||
self.Genre = Genre
|
|
||||||
if Director is not None:
|
|
||||||
self.Director = Director
|
|
||||||
if Writer is not None:
|
|
||||||
self.Writer = Writer
|
|
||||||
if Country is not None:
|
|
||||||
self.Country = Country
|
|
||||||
if Role is not None:
|
|
||||||
self.Role = Role
|
|
||||||
if type_ is not None:
|
|
||||||
self.type_ = type_
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerProvider(BaseModel):
|
|
||||||
def __init__(self, key: str = None, title: str = None, type_: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerProvider
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
key: str
|
|
||||||
title: str
|
|
||||||
type_: str
|
|
||||||
"""
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if type_ is not None:
|
|
||||||
self.type_ = type_
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
identifier: str = None,
|
|
||||||
mediaTagPrefix: str = None,
|
|
||||||
mediaTagVersion: float = None,
|
|
||||||
Metadata: List[MediaContainerMetadata] = None,
|
|
||||||
Provider: List[MediaContainerProvider] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
identifier: str
|
|
||||||
mediaTagPrefix: str
|
|
||||||
mediaTagVersion: float
|
|
||||||
Metadata: list of MediaContainerMetadata
|
|
||||||
Provider: list of MediaContainerProvider
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if identifier is not None:
|
|
||||||
self.identifier = identifier
|
|
||||||
if mediaTagPrefix is not None:
|
|
||||||
self.mediaTagPrefix = mediaTagPrefix
|
|
||||||
if mediaTagVersion is not None:
|
|
||||||
self.mediaTagVersion = mediaTagVersion
|
|
||||||
if Metadata is not None:
|
|
||||||
self.Metadata = Metadata
|
|
||||||
if Provider is not None:
|
|
||||||
self.Provider = Provider
|
|
||||||
|
|
||||||
|
|
||||||
class GetSearchResultsResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetSearchResultsResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class Context(BaseModel):
|
|
||||||
def __init__(self, librarySectionID: str = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize Context
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
librarySectionID: str
|
|
||||||
"""
|
|
||||||
if librarySectionID is not None:
|
|
||||||
self.librarySectionID = librarySectionID
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerActivity(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
uuid: str = None,
|
|
||||||
cancellable: bool = None,
|
|
||||||
userID: float = None,
|
|
||||||
title: str = None,
|
|
||||||
subtitle: str = None,
|
|
||||||
progress: float = None,
|
|
||||||
Context: Context = None,
|
|
||||||
type_: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerActivity
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
uuid: str
|
|
||||||
cancellable: bool
|
|
||||||
userID: float
|
|
||||||
title: str
|
|
||||||
subtitle: str
|
|
||||||
progress: float
|
|
||||||
Context: Context
|
|
||||||
type_: str
|
|
||||||
"""
|
|
||||||
if uuid is not None:
|
|
||||||
self.uuid = uuid
|
|
||||||
if cancellable is not None:
|
|
||||||
self.cancellable = cancellable
|
|
||||||
if userID is not None:
|
|
||||||
self.userID = userID
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
if subtitle is not None:
|
|
||||||
self.subtitle = subtitle
|
|
||||||
if progress is not None:
|
|
||||||
self.progress = progress
|
|
||||||
if Context is not None:
|
|
||||||
self.Context = Context
|
|
||||||
if type_ is not None:
|
|
||||||
self.type_ = type_
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
Activity: List[MediaContainerActivity] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
Activity: list of MediaContainerActivity
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if Activity is not None:
|
|
||||||
self.Activity = Activity
|
|
||||||
|
|
||||||
|
|
||||||
class GetServerActivitiesResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetServerActivitiesResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerDirectory(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self, count: float = None, key: str = None, title: str = None, **kwargs
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerDirectory
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
count: float
|
|
||||||
key: str
|
|
||||||
title: str
|
|
||||||
"""
|
|
||||||
if count is not None:
|
|
||||||
self.count = count
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if title is not None:
|
|
||||||
self.title = title
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
allowCameraUpload: bool = None,
|
|
||||||
allowChannelAccess: bool = None,
|
|
||||||
allowMediaDeletion: bool = None,
|
|
||||||
allowSharing: bool = None,
|
|
||||||
allowSync: bool = None,
|
|
||||||
allowTuners: bool = None,
|
|
||||||
backgroundProcessing: bool = None,
|
|
||||||
certificate: bool = None,
|
|
||||||
companionProxy: bool = None,
|
|
||||||
countryCode: str = None,
|
|
||||||
diagnostics: str = None,
|
|
||||||
eventStream: bool = None,
|
|
||||||
friendlyName: str = None,
|
|
||||||
hubSearch: bool = None,
|
|
||||||
itemClusters: bool = None,
|
|
||||||
livetv: float = None,
|
|
||||||
machineIdentifier: str = None,
|
|
||||||
mediaProviders: bool = None,
|
|
||||||
multiuser: bool = None,
|
|
||||||
musicAnalysis: float = None,
|
|
||||||
myPlex: bool = None,
|
|
||||||
myPlexMappingState: str = None,
|
|
||||||
myPlexSigninState: str = None,
|
|
||||||
myPlexSubscription: bool = None,
|
|
||||||
myPlexUsername: str = None,
|
|
||||||
offlineTranscode: float = None,
|
|
||||||
ownerFeatures: str = None,
|
|
||||||
photoAutoTag: bool = None,
|
|
||||||
platform: str = None,
|
|
||||||
platformVersion: str = None,
|
|
||||||
pluginHost: bool = None,
|
|
||||||
pushNotifications: bool = None,
|
|
||||||
readOnlyLibraries: bool = None,
|
|
||||||
streamingBrainABRVersion: float = None,
|
|
||||||
streamingBrainVersion: float = None,
|
|
||||||
sync: bool = None,
|
|
||||||
transcoderActiveVideoSessions: float = None,
|
|
||||||
transcoderAudio: bool = None,
|
|
||||||
transcoderLyrics: bool = None,
|
|
||||||
transcoderPhoto: bool = None,
|
|
||||||
transcoderSubtitles: bool = None,
|
|
||||||
transcoderVideo: bool = None,
|
|
||||||
transcoderVideoBitrates: str = None,
|
|
||||||
transcoderVideoQualities: str = None,
|
|
||||||
transcoderVideoResolutions: str = None,
|
|
||||||
updatedAt: float = None,
|
|
||||||
updater: bool = None,
|
|
||||||
version: str = None,
|
|
||||||
voiceSearch: bool = None,
|
|
||||||
Directory: List[MediaContainerDirectory] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
allowCameraUpload: bool
|
|
||||||
allowChannelAccess: bool
|
|
||||||
allowMediaDeletion: bool
|
|
||||||
allowSharing: bool
|
|
||||||
allowSync: bool
|
|
||||||
allowTuners: bool
|
|
||||||
backgroundProcessing: bool
|
|
||||||
certificate: bool
|
|
||||||
companionProxy: bool
|
|
||||||
countryCode: str
|
|
||||||
diagnostics: str
|
|
||||||
eventStream: bool
|
|
||||||
friendlyName: str
|
|
||||||
hubSearch: bool
|
|
||||||
itemClusters: bool
|
|
||||||
livetv: float
|
|
||||||
machineIdentifier: str
|
|
||||||
mediaProviders: bool
|
|
||||||
multiuser: bool
|
|
||||||
musicAnalysis: float
|
|
||||||
myPlex: bool
|
|
||||||
myPlexMappingState: str
|
|
||||||
myPlexSigninState: str
|
|
||||||
myPlexSubscription: bool
|
|
||||||
myPlexUsername: str
|
|
||||||
offlineTranscode: float
|
|
||||||
ownerFeatures: str
|
|
||||||
photoAutoTag: bool
|
|
||||||
platform: str
|
|
||||||
platformVersion: str
|
|
||||||
pluginHost: bool
|
|
||||||
pushNotifications: bool
|
|
||||||
readOnlyLibraries: bool
|
|
||||||
streamingBrainABRVersion: float
|
|
||||||
streamingBrainVersion: float
|
|
||||||
sync: bool
|
|
||||||
transcoderActiveVideoSessions: float
|
|
||||||
transcoderAudio: bool
|
|
||||||
transcoderLyrics: bool
|
|
||||||
transcoderPhoto: bool
|
|
||||||
transcoderSubtitles: bool
|
|
||||||
transcoderVideo: bool
|
|
||||||
transcoderVideoBitrates: str
|
|
||||||
transcoderVideoQualities: str
|
|
||||||
transcoderVideoResolutions: str
|
|
||||||
updatedAt: float
|
|
||||||
updater: bool
|
|
||||||
version: str
|
|
||||||
voiceSearch: bool
|
|
||||||
Directory: list of MediaContainerDirectory
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if allowCameraUpload is not None:
|
|
||||||
self.allowCameraUpload = allowCameraUpload
|
|
||||||
if allowChannelAccess is not None:
|
|
||||||
self.allowChannelAccess = allowChannelAccess
|
|
||||||
if allowMediaDeletion is not None:
|
|
||||||
self.allowMediaDeletion = allowMediaDeletion
|
|
||||||
if allowSharing is not None:
|
|
||||||
self.allowSharing = allowSharing
|
|
||||||
if allowSync is not None:
|
|
||||||
self.allowSync = allowSync
|
|
||||||
if allowTuners is not None:
|
|
||||||
self.allowTuners = allowTuners
|
|
||||||
if backgroundProcessing is not None:
|
|
||||||
self.backgroundProcessing = backgroundProcessing
|
|
||||||
if certificate is not None:
|
|
||||||
self.certificate = certificate
|
|
||||||
if companionProxy is not None:
|
|
||||||
self.companionProxy = companionProxy
|
|
||||||
if countryCode is not None:
|
|
||||||
self.countryCode = countryCode
|
|
||||||
if diagnostics is not None:
|
|
||||||
self.diagnostics = diagnostics
|
|
||||||
if eventStream is not None:
|
|
||||||
self.eventStream = eventStream
|
|
||||||
if friendlyName is not None:
|
|
||||||
self.friendlyName = friendlyName
|
|
||||||
if hubSearch is not None:
|
|
||||||
self.hubSearch = hubSearch
|
|
||||||
if itemClusters is not None:
|
|
||||||
self.itemClusters = itemClusters
|
|
||||||
if livetv is not None:
|
|
||||||
self.livetv = livetv
|
|
||||||
if machineIdentifier is not None:
|
|
||||||
self.machineIdentifier = machineIdentifier
|
|
||||||
if mediaProviders is not None:
|
|
||||||
self.mediaProviders = mediaProviders
|
|
||||||
if multiuser is not None:
|
|
||||||
self.multiuser = multiuser
|
|
||||||
if musicAnalysis is not None:
|
|
||||||
self.musicAnalysis = musicAnalysis
|
|
||||||
if myPlex is not None:
|
|
||||||
self.myPlex = myPlex
|
|
||||||
if myPlexMappingState is not None:
|
|
||||||
self.myPlexMappingState = myPlexMappingState
|
|
||||||
if myPlexSigninState is not None:
|
|
||||||
self.myPlexSigninState = myPlexSigninState
|
|
||||||
if myPlexSubscription is not None:
|
|
||||||
self.myPlexSubscription = myPlexSubscription
|
|
||||||
if myPlexUsername is not None:
|
|
||||||
self.myPlexUsername = myPlexUsername
|
|
||||||
if offlineTranscode is not None:
|
|
||||||
self.offlineTranscode = offlineTranscode
|
|
||||||
if ownerFeatures is not None:
|
|
||||||
self.ownerFeatures = ownerFeatures
|
|
||||||
if photoAutoTag is not None:
|
|
||||||
self.photoAutoTag = photoAutoTag
|
|
||||||
if platform is not None:
|
|
||||||
self.platform = platform
|
|
||||||
if platformVersion is not None:
|
|
||||||
self.platformVersion = platformVersion
|
|
||||||
if pluginHost is not None:
|
|
||||||
self.pluginHost = pluginHost
|
|
||||||
if pushNotifications is not None:
|
|
||||||
self.pushNotifications = pushNotifications
|
|
||||||
if readOnlyLibraries is not None:
|
|
||||||
self.readOnlyLibraries = readOnlyLibraries
|
|
||||||
if streamingBrainABRVersion is not None:
|
|
||||||
self.streamingBrainABRVersion = streamingBrainABRVersion
|
|
||||||
if streamingBrainVersion is not None:
|
|
||||||
self.streamingBrainVersion = streamingBrainVersion
|
|
||||||
if sync is not None:
|
|
||||||
self.sync = sync
|
|
||||||
if transcoderActiveVideoSessions is not None:
|
|
||||||
self.transcoderActiveVideoSessions = transcoderActiveVideoSessions
|
|
||||||
if transcoderAudio is not None:
|
|
||||||
self.transcoderAudio = transcoderAudio
|
|
||||||
if transcoderLyrics is not None:
|
|
||||||
self.transcoderLyrics = transcoderLyrics
|
|
||||||
if transcoderPhoto is not None:
|
|
||||||
self.transcoderPhoto = transcoderPhoto
|
|
||||||
if transcoderSubtitles is not None:
|
|
||||||
self.transcoderSubtitles = transcoderSubtitles
|
|
||||||
if transcoderVideo is not None:
|
|
||||||
self.transcoderVideo = transcoderVideo
|
|
||||||
if transcoderVideoBitrates is not None:
|
|
||||||
self.transcoderVideoBitrates = transcoderVideoBitrates
|
|
||||||
if transcoderVideoQualities is not None:
|
|
||||||
self.transcoderVideoQualities = transcoderVideoQualities
|
|
||||||
if transcoderVideoResolutions is not None:
|
|
||||||
self.transcoderVideoResolutions = transcoderVideoResolutions
|
|
||||||
if updatedAt is not None:
|
|
||||||
self.updatedAt = updatedAt
|
|
||||||
if updater is not None:
|
|
||||||
self.updater = updater
|
|
||||||
if version is not None:
|
|
||||||
self.version = version
|
|
||||||
if voiceSearch is not None:
|
|
||||||
self.voiceSearch = voiceSearch
|
|
||||||
if Directory is not None:
|
|
||||||
self.Directory = Directory
|
|
||||||
|
|
||||||
|
|
||||||
class GetServerCapabilitiesResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetServerCapabilitiesResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
claimed: bool = None,
|
|
||||||
machineIdentifier: str = None,
|
|
||||||
version: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
claimed: bool
|
|
||||||
machineIdentifier: str
|
|
||||||
version: str
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if claimed is not None:
|
|
||||||
self.claimed = claimed
|
|
||||||
if machineIdentifier is not None:
|
|
||||||
self.machineIdentifier = machineIdentifier
|
|
||||||
if version is not None:
|
|
||||||
self.version = version
|
|
||||||
|
|
||||||
|
|
||||||
class GetServerIdentityResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetServerIdentityResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerServer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: str = None,
|
|
||||||
host: str = None,
|
|
||||||
address: str = None,
|
|
||||||
port: float = None,
|
|
||||||
machineIdentifier: str = None,
|
|
||||||
version: str = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerServer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
name: str
|
|
||||||
host: str
|
|
||||||
address: str
|
|
||||||
port: float
|
|
||||||
machineIdentifier: str
|
|
||||||
version: str
|
|
||||||
"""
|
|
||||||
if name is not None:
|
|
||||||
self.name = name
|
|
||||||
if host is not None:
|
|
||||||
self.host = host
|
|
||||||
if address is not None:
|
|
||||||
self.address = address
|
|
||||||
if port is not None:
|
|
||||||
self.port = port
|
|
||||||
if machineIdentifier is not None:
|
|
||||||
self.machineIdentifier = machineIdentifier
|
|
||||||
if version is not None:
|
|
||||||
self.version = version
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self, size: float = None, Server: List[MediaContainerServer] = None, **kwargs
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
Server: list of MediaContainerServer
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if Server is not None:
|
|
||||||
self.Server = Server
|
|
||||||
|
|
||||||
|
|
||||||
class GetServerListResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetServerListResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
from .base import BaseModel
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainerTranscodeSession(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
key: str = None,
|
|
||||||
throttled: bool = None,
|
|
||||||
complete: bool = None,
|
|
||||||
progress: float = None,
|
|
||||||
size: float = None,
|
|
||||||
speed: float = None,
|
|
||||||
error: bool = None,
|
|
||||||
duration: float = None,
|
|
||||||
context: str = None,
|
|
||||||
sourceVideoCodec: str = None,
|
|
||||||
sourceAudioCodec: str = None,
|
|
||||||
videoDecision: str = None,
|
|
||||||
audioDecision: str = None,
|
|
||||||
protocol: str = None,
|
|
||||||
container: str = None,
|
|
||||||
videoCodec: str = None,
|
|
||||||
audioCodec: str = None,
|
|
||||||
audioChannels: float = None,
|
|
||||||
transcodeHwRequested: bool = None,
|
|
||||||
timeStamp: float = None,
|
|
||||||
maxOffsetAvailable: float = None,
|
|
||||||
minOffsetAvailable: float = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainerTranscodeSession
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
key: str
|
|
||||||
throttled: bool
|
|
||||||
complete: bool
|
|
||||||
progress: float
|
|
||||||
size: float
|
|
||||||
speed: float
|
|
||||||
error: bool
|
|
||||||
duration: float
|
|
||||||
context: str
|
|
||||||
sourceVideoCodec: str
|
|
||||||
sourceAudioCodec: str
|
|
||||||
videoDecision: str
|
|
||||||
audioDecision: str
|
|
||||||
protocol: str
|
|
||||||
container: str
|
|
||||||
videoCodec: str
|
|
||||||
audioCodec: str
|
|
||||||
audioChannels: float
|
|
||||||
transcodeHwRequested: bool
|
|
||||||
timeStamp: float
|
|
||||||
maxOffsetAvailable: float
|
|
||||||
minOffsetAvailable: float
|
|
||||||
"""
|
|
||||||
if key is not None:
|
|
||||||
self.key = key
|
|
||||||
if throttled is not None:
|
|
||||||
self.throttled = throttled
|
|
||||||
if complete is not None:
|
|
||||||
self.complete = complete
|
|
||||||
if progress is not None:
|
|
||||||
self.progress = progress
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if speed is not None:
|
|
||||||
self.speed = speed
|
|
||||||
if error is not None:
|
|
||||||
self.error = error
|
|
||||||
if duration is not None:
|
|
||||||
self.duration = duration
|
|
||||||
if context is not None:
|
|
||||||
self.context = context
|
|
||||||
if sourceVideoCodec is not None:
|
|
||||||
self.sourceVideoCodec = sourceVideoCodec
|
|
||||||
if sourceAudioCodec is not None:
|
|
||||||
self.sourceAudioCodec = sourceAudioCodec
|
|
||||||
if videoDecision is not None:
|
|
||||||
self.videoDecision = videoDecision
|
|
||||||
if audioDecision is not None:
|
|
||||||
self.audioDecision = audioDecision
|
|
||||||
if protocol is not None:
|
|
||||||
self.protocol = protocol
|
|
||||||
if container is not None:
|
|
||||||
self.container = container
|
|
||||||
if videoCodec is not None:
|
|
||||||
self.videoCodec = videoCodec
|
|
||||||
if audioCodec is not None:
|
|
||||||
self.audioCodec = audioCodec
|
|
||||||
if audioChannels is not None:
|
|
||||||
self.audioChannels = audioChannels
|
|
||||||
if transcodeHwRequested is not None:
|
|
||||||
self.transcodeHwRequested = transcodeHwRequested
|
|
||||||
if timeStamp is not None:
|
|
||||||
self.timeStamp = timeStamp
|
|
||||||
if maxOffsetAvailable is not None:
|
|
||||||
self.maxOffsetAvailable = maxOffsetAvailable
|
|
||||||
if minOffsetAvailable is not None:
|
|
||||||
self.minOffsetAvailable = minOffsetAvailable
|
|
||||||
|
|
||||||
|
|
||||||
class MediaContainer(BaseModel):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
size: float = None,
|
|
||||||
TranscodeSession: List[MediaContainerTranscodeSession] = None,
|
|
||||||
**kwargs,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Initialize MediaContainer
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
size: float
|
|
||||||
TranscodeSession: list of MediaContainerTranscodeSession
|
|
||||||
"""
|
|
||||||
if size is not None:
|
|
||||||
self.size = size
|
|
||||||
if TranscodeSession is not None:
|
|
||||||
self.TranscodeSession = TranscodeSession
|
|
||||||
|
|
||||||
|
|
||||||
class GetTranscodeSessionsResponse(BaseModel):
|
|
||||||
def __init__(self, MediaContainer: MediaContainer = None, **kwargs):
|
|
||||||
"""
|
|
||||||
Initialize GetTranscodeSessionsResponse
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
MediaContainer: MediaContainer
|
|
||||||
"""
|
|
||||||
if MediaContainer is not None:
|
|
||||||
self.MediaContainer = MediaContainer
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class IncludeDetails(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, IncludeDetails._member_map_.values()))
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Level(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
V2 = "2"
|
|
||||||
V3 = "3"
|
|
||||||
V4 = "4"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Level._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MinSize(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, MinSize._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class OnlyTransient(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, OnlyTransient._member_map_.values()))
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class PlaylistType(Enum):
|
|
||||||
AUDIO = "audio"
|
|
||||||
VIDEO = "video"
|
|
||||||
PHOTO = "photo"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, PlaylistType._member_map_.values()))
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
# PlexSDK Models
|
|
||||||
|
|
||||||
A list of all models.
|
|
||||||
- [Level](#level)
|
|
||||||
- [Upscale](#upscale)
|
|
||||||
- [Type](#type)
|
|
||||||
- [Smart](#smart)
|
|
||||||
- [Force](#force)
|
|
||||||
- [SecurityType](#securitytype)
|
|
||||||
- [Scope](#scope)
|
|
||||||
- [Download](#download)
|
|
||||||
- [Tonight](#tonight)
|
|
||||||
- [Skip](#skip)
|
|
||||||
- [State](#state)
|
|
||||||
- [GetServerCapabilitiesResponse](#getservercapabilitiesresponse)
|
|
||||||
- [GetServerActivitiesResponse](#getserveractivitiesresponse)
|
|
||||||
- [GetButlerTasksResponse](#getbutlertasksresponse)
|
|
||||||
- [GetAvailableClientsResponse](#getavailableclientsresponse)
|
|
||||||
- [GetDevicesResponse](#getdevicesresponse)
|
|
||||||
- [GetServerIdentityResponse](#getserveridentityresponse)
|
|
||||||
- [GetRecentlyAddedResponse](#getrecentlyaddedresponse)
|
|
||||||
- [GetOnDeckResponse](#getondeckresponse)
|
|
||||||
- [GetMyPlexAccountResponse](#getmyplexaccountresponse)
|
|
||||||
- [GetSearchResultsResponse](#getsearchresultsresponse)
|
|
||||||
- [GetServerListResponse](#getserverlistresponse)
|
|
||||||
- [GetTranscodeSessionsResponse](#gettranscodesessionsresponse)
|
|
||||||
- [TaskName](#taskname)
|
|
||||||
- [OnlyTransient](#onlytransient)
|
|
||||||
- [IncludeDetails](#includedetails)
|
|
||||||
- [MinSize](#minsize)
|
|
||||||
- [PlaylistType](#playlisttype)
|
|
||||||
|
|
||||||
## Level
|
|
||||||
|
|
||||||
## Upscale
|
|
||||||
|
|
||||||
## Type
|
|
||||||
|
|
||||||
## Smart
|
|
||||||
|
|
||||||
## Force
|
|
||||||
|
|
||||||
## SecurityType
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
## Download
|
|
||||||
|
|
||||||
## Tonight
|
|
||||||
|
|
||||||
## Skip
|
|
||||||
|
|
||||||
## State
|
|
||||||
|
|
||||||
## GetServerCapabilitiesResponse
|
|
||||||
|
|
||||||
## GetServerActivitiesResponse
|
|
||||||
|
|
||||||
## GetButlerTasksResponse
|
|
||||||
|
|
||||||
## GetAvailableClientsResponse
|
|
||||||
|
|
||||||
## GetDevicesResponse
|
|
||||||
|
|
||||||
## GetServerIdentityResponse
|
|
||||||
|
|
||||||
## GetRecentlyAddedResponse
|
|
||||||
|
|
||||||
## GetOnDeckResponse
|
|
||||||
|
|
||||||
## GetMyPlexAccountResponse
|
|
||||||
|
|
||||||
## GetSearchResultsResponse
|
|
||||||
|
|
||||||
## GetServerListResponse
|
|
||||||
|
|
||||||
## GetTranscodeSessionsResponse
|
|
||||||
|
|
||||||
## TaskName
|
|
||||||
|
|
||||||
## OnlyTransient
|
|
||||||
|
|
||||||
## IncludeDetails
|
|
||||||
|
|
||||||
## MinSize
|
|
||||||
|
|
||||||
## PlaylistType
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Scope(Enum):
|
|
||||||
ALL = "all"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Scope._member_map_.values()))
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class SecurityType(Enum):
|
|
||||||
DELEGATION = "delegation"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, SecurityType._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Skip(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Skip._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Smart(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Smart._member_map_.values()))
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class State(Enum):
|
|
||||||
PLAYING = "playing"
|
|
||||||
PAUSED = "paused"
|
|
||||||
STOPPED = "stopped"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, State._member_map_.values()))
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class TaskName(Enum):
|
|
||||||
BACKUPDATABASE = "BackupDatabase"
|
|
||||||
BUILDGRACENOTECOLLECTIONS = "BuildGracenoteCollections"
|
|
||||||
CHECKFORUPDATES = "CheckForUpdates"
|
|
||||||
CLEANOLDBUNDLES = "CleanOldBundles"
|
|
||||||
CLEANOLDCACHEFILES = "CleanOldCacheFiles"
|
|
||||||
DEEPMEDIAANALYSIS = "DeepMediaAnalysis"
|
|
||||||
GENERATEAUTOTAGS = "GenerateAutoTags"
|
|
||||||
GENERATECHAPTERTHUMBS = "GenerateChapterThumbs"
|
|
||||||
GENERATEMEDIAINDEXFILES = "GenerateMediaIndexFiles"
|
|
||||||
OPTIMIZEDATABASE = "OptimizeDatabase"
|
|
||||||
REFRESHLIBRARIES = "RefreshLibraries"
|
|
||||||
REFRESHLOCALMEDIA = "RefreshLocalMedia"
|
|
||||||
REFRESHPERIODICMETADATA = "RefreshPeriodicMetadata"
|
|
||||||
UPGRADEMEDIAANALYSIS = "UpgradeMediaAnalysis"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, TaskName._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Tonight(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Tonight._member_map_.values()))
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Type(Enum):
|
|
||||||
AUDIO = "audio"
|
|
||||||
VIDEO = "video"
|
|
||||||
PHOTO = "photo"
|
|
||||||
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Type._member_map_.values()))
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
class Upscale(Enum):
|
|
||||||
= "0"
|
|
||||||
V1 = "1"
|
|
||||||
def list():
|
|
||||||
return list(map(lambda x: x.value, Upscale._member_map_.values()))
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
from .Level import Level
|
|
||||||
from .Upscale import Upscale
|
|
||||||
from .Type import Type
|
|
||||||
from .Smart import Smart
|
|
||||||
from .Force import Force
|
|
||||||
from .SecurityType import SecurityType
|
|
||||||
from .Scope import Scope
|
|
||||||
from .Download import Download
|
|
||||||
from .Tonight import Tonight
|
|
||||||
from .Skip import Skip
|
|
||||||
from .State import State
|
|
||||||
from .GetServerCapabilitiesResponse import GetServerCapabilitiesResponse
|
|
||||||
from .GetServerActivitiesResponse import GetServerActivitiesResponse
|
|
||||||
from .GetButlerTasksResponse import GetButlerTasksResponse
|
|
||||||
from .GetAvailableClientsResponse import GetAvailableClientsResponse
|
|
||||||
from .GetDevicesResponse import GetDevicesResponse
|
|
||||||
from .GetServerIdentityResponse import GetServerIdentityResponse
|
|
||||||
from .GetRecentlyAddedResponse import GetRecentlyAddedResponse
|
|
||||||
from .GetOnDeckResponse import GetOnDeckResponse
|
|
||||||
from .GetMyPlexAccountResponse import GetMyPlexAccountResponse
|
|
||||||
from .GetSearchResultsResponse import GetSearchResultsResponse
|
|
||||||
from .GetServerListResponse import GetServerListResponse
|
|
||||||
from .GetTranscodeSessionsResponse import GetTranscodeSessionsResponse
|
|
||||||
from .TaskName import TaskName
|
|
||||||
from .OnlyTransient import OnlyTransient
|
|
||||||
from .IncludeDetails import IncludeDetails
|
|
||||||
from .MinSize import MinSize
|
|
||||||
from .PlaylistType import PlaylistType
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import re
|
|
||||||
from typing import List, Union
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class BaseModel:
|
|
||||||
"""
|
|
||||||
A base class that all models in the SDK inherit from (expect for Enum models).
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
_pattern_matching(cls, value: str, pattern: str, variable_name: str) -> str:
|
|
||||||
Checks if a value matches a regex pattern.
|
|
||||||
Returns the value if there's a match, otherwise throws an error.
|
|
||||||
_enum_matching(cls, value: Union[str,Enum], enum_values: List[str], variable_name: str) -> str:
|
|
||||||
Checks if a value (str or enum) matches the required enum values.
|
|
||||||
Returns the value if there's a match, otherwise throws an error.
|
|
||||||
_one_of(cls, required_array, all_array, functions_array, input_data):
|
|
||||||
Validates whether an input_data satisfies the oneOf requirements.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _pattern_matching(cls, value: str, pattern: str, variable_name: str):
|
|
||||||
if re.match(r"{}".format(pattern), value):
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Invalid value for {variable_name}: must match {pattern}")
|
|
||||||
|
|
||||||
def _enum_matching(
|
|
||||||
cls, value: Union[str, Enum], enum_values: List[str], variable_name: str
|
|
||||||
):
|
|
||||||
str_value = value.value if isinstance(value, Enum) else value
|
|
||||||
if str_value in enum_values:
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
f"Invalid value for {variable_name}: must match one of {enum_values}"
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _one_of(cls, required_array, all_array, functions_array, input_data):
|
|
||||||
input_array = list(input_data.keys())
|
|
||||||
for model, fields in required_array.items():
|
|
||||||
input_copy = input_array.copy()
|
|
||||||
matches_required = True
|
|
||||||
for param in fields:
|
|
||||||
if param not in input_copy:
|
|
||||||
matches_required = False
|
|
||||||
break
|
|
||||||
input_copy.remove(param)
|
|
||||||
if matches_required:
|
|
||||||
matches_all = True
|
|
||||||
for input in input_copy:
|
|
||||||
if input not in all_array[model]:
|
|
||||||
matches_all = False
|
|
||||||
break
|
|
||||||
if matches_all:
|
|
||||||
return functions_array[model](input_data)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
"""
|
|
||||||
An enum class containing all the possible environments that
|
|
||||||
a user can switch between in this SDK.
|
|
||||||
"""
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Environment(Enum):
|
|
||||||
"""The environments available for this SDK"""
|
|
||||||
|
|
||||||
DEFAULT = "http://10.10.10.47:32400"
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
from time import sleep
|
|
||||||
import requests
|
|
||||||
from http_exceptions import HTTPException, client_exceptions, server_exceptions
|
|
||||||
from json import JSONDecodeError
|
|
||||||
from .http_content_types import multipart_form_data_request
|
|
||||||
from .utils import to_serialize, rename_reserved_keys, rename_to_reserved_keys
|
|
||||||
|
|
||||||
|
|
||||||
from .response import ResponseWithHeaders
|
|
||||||
|
|
||||||
|
|
||||||
class HTTPClient:
|
|
||||||
"""
|
|
||||||
Provides functionality for invoking HTTP-based API calls to web services.
|
|
||||||
"""
|
|
||||||
|
|
||||||
_retry_codes = [500, 503, 504]
|
|
||||||
"""list[int]: A list of status codes that invoke a retry."""
|
|
||||||
|
|
||||||
_initial_delay = 150
|
|
||||||
"""int: The delay (in milliseconds) before performing a retry."""
|
|
||||||
|
|
||||||
_max_retries = 3
|
|
||||||
"""int: The maximum number of retries."""
|
|
||||||
|
|
||||||
def __init__(self, hook):
|
|
||||||
self._hook = hook
|
|
||||||
|
|
||||||
def _make_http_request(self, method, endpoint_url, headers, body_input):
|
|
||||||
"""
|
|
||||||
Places API calls according to the HTTP method and content type.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
method : str
|
|
||||||
The type of http call to perform
|
|
||||||
endpoint_url : url
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
body_input : Any
|
|
||||||
The request's body
|
|
||||||
"""
|
|
||||||
request_method = getattr(requests, method)
|
|
||||||
serialized_body = rename_to_reserved_keys(to_serialize(body_input))
|
|
||||||
if "Content-type" in headers:
|
|
||||||
data_type, subtype = headers["Content-type"].split("/")
|
|
||||||
if data_type == "multipart":
|
|
||||||
return multipart_form_data_request(
|
|
||||||
method, endpoint_url, headers, serialized_body
|
|
||||||
)
|
|
||||||
if data_type in ["text", "image"]:
|
|
||||||
return request_method(
|
|
||||||
endpoint_url, headers=headers, data=serialized_body
|
|
||||||
)
|
|
||||||
if not serialized_body or method in {"get", "delete"}:
|
|
||||||
return request_method(endpoint_url, headers=headers)
|
|
||||||
return request_method(endpoint_url, headers=headers, json=serialized_body)
|
|
||||||
|
|
||||||
def delete(self, endpoint_url: str, headers: dict, retry: bool = True):
|
|
||||||
"""
|
|
||||||
Places API DELETE request and handles errors
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
endpoint_url : str
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
retry : bool
|
|
||||||
A boolean representing wether to attempt a retry
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = self._make_http_request("delete", endpoint_url, headers, None)
|
|
||||||
if response.status_code in self._retry_codes and retry:
|
|
||||||
try_cnt = 1
|
|
||||||
while (
|
|
||||||
response.status_code in self._retry_codes
|
|
||||||
and try_cnt - 1 < self._max_retries
|
|
||||||
):
|
|
||||||
sleep(self._initial_delay ** (try_cnt - 1) / 1000)
|
|
||||||
response = self._make_http_request(
|
|
||||||
"delete", endpoint_url, headers, None
|
|
||||||
)
|
|
||||||
try_cnt += 1
|
|
||||||
|
|
||||||
return self._handle_response(response)
|
|
||||||
|
|
||||||
def get(self, endpoint_url: str, headers: dict, retry: bool = True):
|
|
||||||
"""
|
|
||||||
Places an API GET request and handles errors
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
endpoint_url : str
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
retry : bool
|
|
||||||
A boolean representing wether to attempt a retry
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = self._make_http_request("get", endpoint_url, headers, None)
|
|
||||||
if response.status_code in self._retry_codes and retry:
|
|
||||||
try_cnt = 1
|
|
||||||
while (
|
|
||||||
response.status_code in self._retry_codes
|
|
||||||
and try_cnt - 1 < self._max_retries
|
|
||||||
):
|
|
||||||
sleep(self._initial_delay ** (try_cnt - 1) / 1000)
|
|
||||||
response = self._make_http_request("get", endpoint_url, headers, None)
|
|
||||||
try_cnt += 1
|
|
||||||
|
|
||||||
return self._handle_response(response)
|
|
||||||
|
|
||||||
def patch(self, endpoint_url: str, headers: dict, body_input, retry: bool = True):
|
|
||||||
"""
|
|
||||||
Places an API PATCH request and handles errors
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
endpoint_url : str
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
body_input:
|
|
||||||
The patch request body
|
|
||||||
retry : bool
|
|
||||||
A boolean representing wether to attempt a retry
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = self._make_http_request("patch", endpoint_url, headers, body_input)
|
|
||||||
if response.status_code in self._retry_codes and retry:
|
|
||||||
try_cnt = 1
|
|
||||||
while (
|
|
||||||
response.status_code in self._retry_codes
|
|
||||||
and try_cnt - 1 < self._max_retries
|
|
||||||
):
|
|
||||||
sleep(self._initial_delay ** (try_cnt - 1) / 1000)
|
|
||||||
response = self._make_http_request(
|
|
||||||
"patch", endpoint_url, headers, body_input
|
|
||||||
)
|
|
||||||
try_cnt += 1
|
|
||||||
|
|
||||||
return self._handle_response(response)
|
|
||||||
|
|
||||||
def post(self, endpoint_url: str, headers: dict, body_input, retry: bool = True):
|
|
||||||
"""
|
|
||||||
Places an API POST request and handles errors
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
endpoint_url : str
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
body_input:
|
|
||||||
The post request body
|
|
||||||
retry : bool
|
|
||||||
A boolean representing wether to attempt a retry
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = self._make_http_request("post", endpoint_url, headers, body_input)
|
|
||||||
if response.status_code in self._retry_codes and retry:
|
|
||||||
try_cnt = 1
|
|
||||||
while (
|
|
||||||
response.status_code in self._retry_codes
|
|
||||||
and try_cnt - 1 < self._max_retries
|
|
||||||
):
|
|
||||||
sleep(self._initial_delay ** (try_cnt - 1) / 1000)
|
|
||||||
response = self._make_http_request(
|
|
||||||
"post", endpoint_url, headers, body_input
|
|
||||||
)
|
|
||||||
try_cnt += 1
|
|
||||||
|
|
||||||
return self._handle_response(response)
|
|
||||||
|
|
||||||
def put(self, endpoint_url: str, headers: dict, body_input, retry: bool = True):
|
|
||||||
"""
|
|
||||||
Places an API PUT request and handles errors
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
endpoint_url : str
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
body_input:
|
|
||||||
The put request body
|
|
||||||
retry : bool
|
|
||||||
A boolean representing whether to attempt a retry
|
|
||||||
"""
|
|
||||||
|
|
||||||
response = self._make_http_request("put", endpoint_url, headers, body_input)
|
|
||||||
if response.status_code in self._retry_codes and retry:
|
|
||||||
try_cnt = 1
|
|
||||||
while (
|
|
||||||
response.status_code in self._retry_codes
|
|
||||||
and try_cnt - 1 < self._max_retries
|
|
||||||
):
|
|
||||||
sleep(self._initial_delay ** (try_cnt - 1) / 1000)
|
|
||||||
response = self._make_http_request(
|
|
||||||
"put", endpoint_url, headers, body_input
|
|
||||||
)
|
|
||||||
try_cnt += 1
|
|
||||||
|
|
||||||
return self._handle_response(response)
|
|
||||||
|
|
||||||
def _create_exception_message(self, response, header: str) -> str:
|
|
||||||
"""
|
|
||||||
Creates an exception message using a specific header
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
response:
|
|
||||||
Response data received from an http request
|
|
||||||
header : str
|
|
||||||
Header name for the created exception
|
|
||||||
"""
|
|
||||||
if header in response.headers:
|
|
||||||
return f"{response.text}, Headers {header}: {response.headers[header]}"
|
|
||||||
return response.text
|
|
||||||
|
|
||||||
def _handle_response(self, response: dict):
|
|
||||||
"""
|
|
||||||
Handles a response from an API call
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
response:
|
|
||||||
Response data received from an http request
|
|
||||||
"""
|
|
||||||
if response.status_code >= 200 and response.status_code < 400:
|
|
||||||
try:
|
|
||||||
return ResponseWithHeaders(
|
|
||||||
rename_reserved_keys(response.json()), response.headers
|
|
||||||
)
|
|
||||||
except JSONDecodeError:
|
|
||||||
return response
|
|
||||||
else:
|
|
||||||
self._raise_from_status(response)
|
|
||||||
|
|
||||||
def _raise_from_status(self, response) -> None:
|
|
||||||
"""
|
|
||||||
Raises exception based response status, with additional information appended if useful
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
response:
|
|
||||||
Response data received from an http request
|
|
||||||
"""
|
|
||||||
if response.status_code == 401:
|
|
||||||
raise client_exceptions.UnauthorizedException(
|
|
||||||
message=self._create_exception_message(response, "WWW-Authenticate")
|
|
||||||
)
|
|
||||||
elif response.status_code == 405:
|
|
||||||
# this indicates a bug in the spec if it allows a method that the server rejects
|
|
||||||
raise client_exceptions.MethodNotAllowedException(
|
|
||||||
message=self._create_exception_message(response, "Allow")
|
|
||||||
)
|
|
||||||
elif response.status_code == 407:
|
|
||||||
raise client_exceptions.ProxyAuthenticationRequiredException(
|
|
||||||
message=self._create_exception_message(response, "Proxy-Authenticate")
|
|
||||||
)
|
|
||||||
elif response.status_code == 413:
|
|
||||||
raise client_exceptions.PayloadTooLargeException(
|
|
||||||
message=self._create_exception_message(response, "Retry-After")
|
|
||||||
)
|
|
||||||
elif response.status_code == 429:
|
|
||||||
raise client_exceptions.TooManyRequestsException(
|
|
||||||
message=self._create_exception_message(response, "Retry-After")
|
|
||||||
)
|
|
||||||
elif response.status_code == 503:
|
|
||||||
raise server_exceptions.ServiceUnavailableException(
|
|
||||||
message=self._create_exception_message(response, "Retry-After")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise HTTPException.from_status_code(status_code=response.status_code)(
|
|
||||||
message=response.text
|
|
||||||
)
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
"""
|
|
||||||
Collection of API calls according to the HTTP method and content type.
|
|
||||||
|
|
||||||
Functions:
|
|
||||||
multipart_form_data_request
|
|
||||||
"""
|
|
||||||
import requests
|
|
||||||
import io
|
|
||||||
from mimetypes import guess_type
|
|
||||||
|
|
||||||
|
|
||||||
def multipart_form_data_request(method, endpoint_url, headers, body_input):
|
|
||||||
"""
|
|
||||||
Places a multipart/formdata http request.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
method : str
|
|
||||||
The type of http call to perform
|
|
||||||
endpoint_url : url
|
|
||||||
The endpoint url to make the http call on
|
|
||||||
headers : dict
|
|
||||||
The http call's headers
|
|
||||||
body_input : Any
|
|
||||||
The request's body
|
|
||||||
"""
|
|
||||||
data = {}
|
|
||||||
files = {}
|
|
||||||
request_method = getattr(requests, method)
|
|
||||||
del headers["Content-type"]
|
|
||||||
for key, value in body_input.items():
|
|
||||||
if isinstance(value, (io.TextIOWrapper, io.BufferedIOBase)):
|
|
||||||
mime_type, encoding = guess_type(value.name)
|
|
||||||
file_tuple = (
|
|
||||||
(value.name, value, mime_type) if mime_type else (value.name, value)
|
|
||||||
)
|
|
||||||
files[key] = file_tuple
|
|
||||||
else:
|
|
||||||
data[key] = value
|
|
||||||
if files:
|
|
||||||
return request_method(endpoint_url, headers=headers, files=files, data=data)
|
|
||||||
return request_method(endpoint_url, headers=headers, data=data)
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
from typing import Any, Dict, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
explode = bool
|
|
||||||
|
|
||||||
|
|
||||||
def simple(value: Any, explode: bool) -> str:
|
|
||||||
if isinstance(value, Enum):
|
|
||||||
return str(value.value)
|
|
||||||
|
|
||||||
# Check if the value is a list
|
|
||||||
if isinstance(value, list):
|
|
||||||
return ",".join(value) if explode else "".join(value)
|
|
||||||
|
|
||||||
if isinstance(value, dict):
|
|
||||||
if explode:
|
|
||||||
# Serialize object with exploded format: "key=value,key2=value2"
|
|
||||||
return ",".join([f"{k}={v}" for k, v in value.items()])
|
|
||||||
else:
|
|
||||||
# Serialize object with non-exploded format: "key,value,key2,value2"
|
|
||||||
return ",".join(
|
|
||||||
[str(item) for sublist in value.items() for item in sublist]
|
|
||||||
)
|
|
||||||
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
|
|
||||||
def form(parameter_name: str, parameter_value: Any, explode: bool) -> str:
|
|
||||||
if isinstance(parameter_value, Enum):
|
|
||||||
return f"{parameter_name}=" + str(parameter_value.value)
|
|
||||||
|
|
||||||
if isinstance(parameter_value, list):
|
|
||||||
return (
|
|
||||||
"&".join([f"{parameter_name}={v}" for v in parameter_value])
|
|
||||||
if explode
|
|
||||||
else f"{parameter_name}=" + ",".join([str(v) for v in parameter_value])
|
|
||||||
)
|
|
||||||
|
|
||||||
if isinstance(parameter_value, dict):
|
|
||||||
if explode:
|
|
||||||
# Serialize object with exploded format: "key1=value1&key2=value2"
|
|
||||||
return "&".join([f"{k}={v}" for k, v in parameter_value.items()])
|
|
||||||
else:
|
|
||||||
# Serialize object with non-exploded format: "key=key1,value1,key2,value2"
|
|
||||||
return f"{parameter_name}=" + ",".join(
|
|
||||||
[str(item) for sublist in parameter_value.items() for item in sublist]
|
|
||||||
)
|
|
||||||
|
|
||||||
return f"{parameter_name}=" + str(parameter_value)
|
|
||||||
|
|
||||||
|
|
||||||
style_methods = {
|
|
||||||
"simple": simple,
|
|
||||||
"form": form,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def serialize_query(parameter_style, explode, key: str, parameter_value: Any) -> str:
|
|
||||||
method = style_methods.get(parameter_style)
|
|
||||||
return method(key, parameter_value, explode) if method else ""
|
|
||||||
|
|
||||||
|
|
||||||
def serialize_path(
|
|
||||||
parameter_style, explode: bool, parameter_value: Any, parameter_key=None
|
|
||||||
):
|
|
||||||
method = style_methods.get(parameter_style)
|
|
||||||
if not method:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# The `simple` and `label` styles do not require a `parameter_key`
|
|
||||||
if not parameter_key:
|
|
||||||
return method(parameter_value, explode)
|
|
||||||
else:
|
|
||||||
return method(parameter_key, parameter_value, explode)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
class ResponseWithHeaders:
|
|
||||||
def __init__(self, data, headers):
|
|
||||||
self.data = data
|
|
||||||
self.headers = headers
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
"""
|
|
||||||
Helper functions for http calls.
|
|
||||||
|
|
||||||
Functions:
|
|
||||||
to_serialize
|
|
||||||
"""
|
|
||||||
|
|
||||||
import io
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
def to_serialize(obj):
|
|
||||||
"""
|
|
||||||
Recursively converts objects into dictionaries.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
obj:
|
|
||||||
The object to transform into a dictionary.
|
|
||||||
"""
|
|
||||||
result = {}
|
|
||||||
if not hasattr(obj, "__dict__") or isinstance(
|
|
||||||
obj, (io.TextIOWrapper, io.BufferedIOBase)
|
|
||||||
):
|
|
||||||
return obj
|
|
||||||
iter_obj = obj.__dict__.items() if hasattr(obj, "__dict__") else obj.items()
|
|
||||||
for key, value in iter_obj:
|
|
||||||
if isinstance(value, (io.TextIOWrapper, io.BufferedIOBase)):
|
|
||||||
result[key] = value
|
|
||||||
elif isinstance(value, Enum):
|
|
||||||
result[key] = value.value
|
|
||||||
elif isinstance(value, (list, set, tuple)):
|
|
||||||
for i in range(len(value)):
|
|
||||||
value[i] = to_serialize(value[i])
|
|
||||||
result[key] = value
|
|
||||||
elif hasattr(value, "__dict__"):
|
|
||||||
result[key] = to_serialize(value)
|
|
||||||
else:
|
|
||||||
result[key] = value
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
response_mapper = {"type": "type_"}
|
|
||||||
request_mapper = {"type_": "type"}
|
|
||||||
|
|
||||||
|
|
||||||
def rename_keys(data, mapper):
|
|
||||||
if isinstance(data, dict):
|
|
||||||
new_data = {}
|
|
||||||
for key, value in data.items():
|
|
||||||
new_key = mapper[key] if key in mapper else key
|
|
||||||
new_data[new_key] = rename_keys(value, mapper)
|
|
||||||
return new_data
|
|
||||||
elif isinstance(data, list):
|
|
||||||
return [rename_keys(item, mapper) for item in data]
|
|
||||||
else:
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def rename_reserved_keys(data):
|
|
||||||
return rename_keys(data, response_mapper)
|
|
||||||
|
|
||||||
|
|
||||||
def rename_to_reserved_keys(data):
|
|
||||||
return rename_keys(data, request_mapper)
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
"""
|
|
||||||
Creates a PlexSDK class.
|
|
||||||
Generates the main SDK with all available queries as attributes.
|
|
||||||
|
|
||||||
Class:
|
|
||||||
PlexSDK
|
|
||||||
"""
|
|
||||||
from .net.environment import Environment
|
|
||||||
|
|
||||||
from .services.activities import Activities
|
|
||||||
from .services.butler import Butler
|
|
||||||
from .services.hubs import Hubs
|
|
||||||
from .services.library import Library
|
|
||||||
from .services.log import Log
|
|
||||||
from .services.media import Media
|
|
||||||
from .services.playlists import Playlists
|
|
||||||
from .services.search import Search
|
|
||||||
from .services.security import Security
|
|
||||||
from .services.server import Server
|
|
||||||
from .services.sessions import Sessions
|
|
||||||
from .services.updater import Updater
|
|
||||||
from .services.video import Video
|
|
||||||
|
|
||||||
|
|
||||||
class PlexSDK:
|
|
||||||
"""
|
|
||||||
A class representing the full PlexSDK SDK
|
|
||||||
|
|
||||||
Attributes
|
|
||||||
----------
|
|
||||||
activities : Activities
|
|
||||||
butler : Butler
|
|
||||||
hubs : Hubs
|
|
||||||
library : Library
|
|
||||||
log : Log
|
|
||||||
media : Media
|
|
||||||
playlists : Playlists
|
|
||||||
search : Search
|
|
||||||
security : Security
|
|
||||||
server : Server
|
|
||||||
sessions : Sessions
|
|
||||||
updater : Updater
|
|
||||||
video : Video
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
set_base_url(url: str)
|
|
||||||
Sets the end URL
|
|
||||||
set_api_key(api_key, api_key_header))
|
|
||||||
Set the api key
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, api_key="", api_key_header="X-Plex-Token", environment=Environment.DEFAULT
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Initializes the PlexSDK SDK class.
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
environment: str
|
|
||||||
The environment that the SDK is accessing
|
|
||||||
api_key : str
|
|
||||||
The api key
|
|
||||||
api_key_header : str
|
|
||||||
The API key header
|
|
||||||
"""
|
|
||||||
self.activities = Activities(api_key, api_key_header)
|
|
||||||
self.butler = Butler(api_key, api_key_header)
|
|
||||||
self.hubs = Hubs(api_key, api_key_header)
|
|
||||||
self.library = Library(api_key, api_key_header)
|
|
||||||
self.log = Log(api_key, api_key_header)
|
|
||||||
self.media = Media(api_key, api_key_header)
|
|
||||||
self.playlists = Playlists(api_key, api_key_header)
|
|
||||||
self.search = Search(api_key, api_key_header)
|
|
||||||
self.security = Security(api_key, api_key_header)
|
|
||||||
self.server = Server(api_key, api_key_header)
|
|
||||||
self.sessions = Sessions(api_key, api_key_header)
|
|
||||||
self.updater = Updater(api_key, api_key_header)
|
|
||||||
self.video = Video(api_key, api_key_header)
|
|
||||||
|
|
||||||
self.set_base_url(environment.value)
|
|
||||||
|
|
||||||
def set_base_url(self, url: str) -> None:
|
|
||||||
"""
|
|
||||||
Sets the end URL
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
url:
|
|
||||||
The end URL
|
|
||||||
"""
|
|
||||||
self.activities.set_base_url(url)
|
|
||||||
self.butler.set_base_url(url)
|
|
||||||
self.hubs.set_base_url(url)
|
|
||||||
self.library.set_base_url(url)
|
|
||||||
self.log.set_base_url(url)
|
|
||||||
self.media.set_base_url(url)
|
|
||||||
self.playlists.set_base_url(url)
|
|
||||||
self.search.set_base_url(url)
|
|
||||||
self.security.set_base_url(url)
|
|
||||||
self.server.set_base_url(url)
|
|
||||||
self.sessions.set_base_url(url)
|
|
||||||
self.updater.set_base_url(url)
|
|
||||||
self.video.set_base_url(url)
|
|
||||||
|
|
||||||
def set_api_key(self, api_key: str, api_key_header: str = None) -> None:
|
|
||||||
"""
|
|
||||||
Sets api key and api key header name
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
api_key: string
|
|
||||||
API Key value
|
|
||||||
api_key_header: string
|
|
||||||
Name of API Key
|
|
||||||
"""
|
|
||||||
self.activities.set_api_key(api_key, api_key_header)
|
|
||||||
self.butler.set_api_key(api_key, api_key_header)
|
|
||||||
self.hubs.set_api_key(api_key, api_key_header)
|
|
||||||
self.library.set_api_key(api_key, api_key_header)
|
|
||||||
self.log.set_api_key(api_key, api_key_header)
|
|
||||||
self.media.set_api_key(api_key, api_key_header)
|
|
||||||
self.playlists.set_api_key(api_key, api_key_header)
|
|
||||||
self.search.set_api_key(api_key, api_key_header)
|
|
||||||
self.security.set_api_key(api_key, api_key_header)
|
|
||||||
self.server.set_api_key(api_key, api_key_header)
|
|
||||||
self.sessions.set_api_key(api_key, api_key_header)
|
|
||||||
self.updater.set_api_key(api_key, api_key_header)
|
|
||||||
self.video.set_api_key(api_key, api_key_header)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetServerActivitiesResponse import (
|
|
||||||
GetServerActivitiesResponse as GetServerActivitiesResponseModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Activities(BaseService):
|
|
||||||
def get_server_activities(self) -> GetServerActivitiesResponseModel:
|
|
||||||
"""
|
|
||||||
Get Server Activities
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/activities"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetServerActivitiesResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def cancel_server_activities(self, activity_uuid: str):
|
|
||||||
"""
|
|
||||||
Cancel Server Activities
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
activity_uuid: str
|
|
||||||
The UUID of the activity to cancel.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/activities/{activity_uuid}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not activity_uuid:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter activity_uuid is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{activity_uuid}",
|
|
||||||
quote(
|
|
||||||
str(
|
|
||||||
query_serializer.serialize_path(
|
|
||||||
"simple", False, activity_uuid, None
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
"""
|
|
||||||
Creates a BaseService class.
|
|
||||||
Performs API calls,sets authentication tokens and handles http exceptions.
|
|
||||||
|
|
||||||
Class:
|
|
||||||
BaseService
|
|
||||||
"""
|
|
||||||
from typing import List, Union
|
|
||||||
from enum import Enum
|
|
||||||
import re
|
|
||||||
from ..net.http_client import HTTPClient
|
|
||||||
|
|
||||||
|
|
||||||
class BaseService:
|
|
||||||
"""
|
|
||||||
A class to represent a base serivce
|
|
||||||
|
|
||||||
Attributes
|
|
||||||
----------
|
|
||||||
_url_prefix : str
|
|
||||||
The base URL
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
|
|
||||||
set_api_key(api_key: str, api_key_header: str = None) -> None:
|
|
||||||
Sets api key and api key header name
|
|
||||||
def _add_required_headers(headers: dict):
|
|
||||||
Request authorization headers
|
|
||||||
def set_base_url(url: str):
|
|
||||||
Sets the base url
|
|
||||||
"""
|
|
||||||
|
|
||||||
_url_prefix = "http://10.10.10.47:32400"
|
|
||||||
|
|
||||||
_http = HTTPClient(None)
|
|
||||||
|
|
||||||
def __init__(self, api_key: str = "", api_key_header: str = "X-Plex-Token") -> None:
|
|
||||||
"""
|
|
||||||
Initialize client
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
api_key : str
|
|
||||||
The API Key access token
|
|
||||||
api_key_header : str
|
|
||||||
The API Key header name
|
|
||||||
"""
|
|
||||||
self._api_key = api_key
|
|
||||||
self._api_key_header = api_key_header
|
|
||||||
|
|
||||||
def _pattern_matching(cls, value: str, pattern: str, variable_name: str):
|
|
||||||
if re.match(r"{}".format(pattern), value):
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Invalid value for {variable_name}: must match {pattern}")
|
|
||||||
|
|
||||||
def _enum_matching(
|
|
||||||
cls, value: Union[str, Enum], enum_values: List[str], variable_name: str
|
|
||||||
):
|
|
||||||
str_value = value.value if isinstance(value, Enum) else value
|
|
||||||
if str_value in enum_values:
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
f"Invalid value for {variable_name}: must match one of {enum_values}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_base_url(self, url: str) -> None:
|
|
||||||
"""
|
|
||||||
Sets the base URL
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
url:
|
|
||||||
The base URL
|
|
||||||
"""
|
|
||||||
self._url_prefix = url
|
|
||||||
|
|
||||||
def set_api_key(self, api_key: str, api_key_header: str = None) -> None:
|
|
||||||
"""
|
|
||||||
Sets api key and api key header name
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
api_key: string
|
|
||||||
API Key value
|
|
||||||
api_key_header: string
|
|
||||||
Name of API Key
|
|
||||||
"""
|
|
||||||
self._api_key = api_key
|
|
||||||
if api_key_header is not None:
|
|
||||||
self._api_key_header = api_key_header
|
|
||||||
|
|
||||||
def _add_required_headers(self, headers: dict):
|
|
||||||
"""
|
|
||||||
Request authorization headers
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
headers: dict
|
|
||||||
Headers dict to add auth headers to
|
|
||||||
"""
|
|
||||||
headers["User-Agent"] = "liblab/0.1.25 PlexSDK/0.0.1 python/2.7"
|
|
||||||
headers[f"{self._api_key_header}"] = f"{self._api_key}"
|
|
||||||
return headers
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetButlerTasksResponse import (
|
|
||||||
GetButlerTasksResponse as GetButlerTasksResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.TaskName import TaskName as TaskNameModel
|
|
||||||
|
|
||||||
|
|
||||||
class Butler(BaseService):
|
|
||||||
def get_butler_tasks(self) -> GetButlerTasksResponseModel:
|
|
||||||
"""
|
|
||||||
Get Butler tasks
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/butler"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetButlerTasksResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def start_all_tasks(self):
|
|
||||||
"""
|
|
||||||
Start all Butler tasks
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/butler"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def stop_all_tasks(self):
|
|
||||||
"""
|
|
||||||
Stop all Butler tasks
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/butler"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def start_task(self, task_name: TaskNameModel):
|
|
||||||
"""
|
|
||||||
Start a single Butler task
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
task_name: TaskName
|
|
||||||
the name of the task to be started.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/butler/{task_name}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not task_name:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter task_name is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
validated_task_name = self._enum_matching(
|
|
||||||
task_name, TaskNameModel.list(), "task_name"
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{task_name}",
|
|
||||||
quote(
|
|
||||||
str(
|
|
||||||
query_serializer.serialize_path(
|
|
||||||
"simple", False, validated_task_name, None
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def stop_task(self, task_name: TaskNameModel):
|
|
||||||
"""
|
|
||||||
Stop a single Butler task
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
task_name: TaskName
|
|
||||||
The name of the task to be started.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/butler/{task_name}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not task_name:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter task_name is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
validated_task_name = self._enum_matching(
|
|
||||||
task_name, TaskNameModel.list(), "task_name"
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{task_name}",
|
|
||||||
quote(
|
|
||||||
str(
|
|
||||||
query_serializer.serialize_path(
|
|
||||||
"simple", False, validated_task_name, None
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.OnlyTransient import OnlyTransient as OnlyTransientModel
|
|
||||||
|
|
||||||
|
|
||||||
class Hubs(BaseService):
|
|
||||||
def get_global_hubs(
|
|
||||||
self, count: float = None, only_transient: OnlyTransientModel = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get Global Hubs
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
count: float
|
|
||||||
The number of items to return with each hub.
|
|
||||||
only_transient: OnlyTransient
|
|
||||||
Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added).
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/hubs"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if count:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "count", count)
|
|
||||||
)
|
|
||||||
if only_transient:
|
|
||||||
validated_only_transient = self._enum_matching(
|
|
||||||
only_transient, OnlyTransientModel.list(), "only_transient"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "onlyTransient", validated_only_transient
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_library_hubs(
|
|
||||||
self,
|
|
||||||
section_id: float,
|
|
||||||
count: float = None,
|
|
||||||
only_transient: OnlyTransientModel = None,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get library specific hubs
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
count: float
|
|
||||||
The number of items to return with each hub.
|
|
||||||
only_transient: OnlyTransient
|
|
||||||
Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added).
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/hubs/sections/{section_id}"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if count:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "count", count)
|
|
||||||
)
|
|
||||||
if only_transient:
|
|
||||||
validated_only_transient = self._enum_matching(
|
|
||||||
only_transient, OnlyTransientModel.list(), "only_transient"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "onlyTransient", validated_only_transient
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetRecentlyAddedResponse import (
|
|
||||||
GetRecentlyAddedResponse as GetRecentlyAddedResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.IncludeDetails import IncludeDetails as IncludeDetailsModel
|
|
||||||
from ..models.GetOnDeckResponse import GetOnDeckResponse as GetOnDeckResponseModel
|
|
||||||
|
|
||||||
|
|
||||||
class Library(BaseService):
|
|
||||||
def get_file_hash(self, url: str, type_: float = None):
|
|
||||||
"""
|
|
||||||
Get Hash Value
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
url: str
|
|
||||||
This is the path to the local file, must be prefixed by `file://`
|
|
||||||
type: float
|
|
||||||
Item type
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/hashes"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not url:
|
|
||||||
raise ValueError("Parameter url is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "url", url))
|
|
||||||
if type_:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", type_)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_recently_added(self) -> GetRecentlyAddedResponseModel:
|
|
||||||
"""
|
|
||||||
Get Recently Added
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/recentlyAdded"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetRecentlyAddedResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_libraries(self):
|
|
||||||
"""
|
|
||||||
Get All Libraries
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_library(
|
|
||||||
self, section_id: float, include_details: IncludeDetailsModel = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get Library Details
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
include_details: IncludeDetails
|
|
||||||
Whether or not to include details for a section (types, filters, and sorts).
|
|
||||||
Only exists for backwards compatibility, media providers other than the server libraries have it on always.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if include_details:
|
|
||||||
validated_include_details = self._enum_matching(
|
|
||||||
include_details, IncludeDetailsModel.list(), "include_details"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "includeDetails", validated_include_details
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def delete_library(self, section_id: float):
|
|
||||||
"""
|
|
||||||
Delete Library Section
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_library_items(
|
|
||||||
self, section_id: float, type_: float = None, filter: str = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get Library Items
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
type: float
|
|
||||||
item type
|
|
||||||
filter: str
|
|
||||||
the filter parameter
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}/all"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if type_:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", type_)
|
|
||||||
)
|
|
||||||
if filter:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "filter", filter)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def refresh_library(self, section_id: float):
|
|
||||||
"""
|
|
||||||
Refresh Library
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to refresh
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}/refresh"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_latest_library_items(
|
|
||||||
self, type_: float, section_id: float, filter: str = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get Latest Library Items
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
type: float
|
|
||||||
item type
|
|
||||||
filter: str
|
|
||||||
the filter parameter
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}/latest"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if not type_:
|
|
||||||
raise ValueError("Parameter type_ is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", type_)
|
|
||||||
)
|
|
||||||
if filter:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "filter", filter)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_common_library_items(
|
|
||||||
self, type_: float, section_id: float, filter: str = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get Common Library Items
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
section_id: float
|
|
||||||
the Id of the library to query
|
|
||||||
type: float
|
|
||||||
item type
|
|
||||||
filter: str
|
|
||||||
the filter parameter
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/sections/{section_id}/common"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not section_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter section_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{section_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, section_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if not type_:
|
|
||||||
raise ValueError("Parameter type_ is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", type_)
|
|
||||||
)
|
|
||||||
if filter:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "filter", filter)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_metadata(self, rating_key: float):
|
|
||||||
"""
|
|
||||||
Get Items Metadata
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
rating_key: float
|
|
||||||
the id of the library item to return the children of.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/metadata/{rating_key}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not rating_key:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter rating_key is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{rating_key}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, rating_key, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_metadata_children(self, rating_key: float):
|
|
||||||
"""
|
|
||||||
Get Items Children
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
rating_key: float
|
|
||||||
the id of the library item to return the children of.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/metadata/{rating_key}/children"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not rating_key:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter rating_key is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{rating_key}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, rating_key, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_on_deck(self) -> GetOnDeckResponseModel:
|
|
||||||
"""
|
|
||||||
Get On Deck
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/library/onDeck"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetOnDeckResponseModel(**res)
|
|
||||||
return res
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.Level import Level as LevelModel
|
|
||||||
|
|
||||||
|
|
||||||
class Log(BaseService):
|
|
||||||
def log_line(self, source: str, message: str, level: LevelModel):
|
|
||||||
"""
|
|
||||||
Logging a single line message.
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
level: Level
|
|
||||||
An integer log level to write to the PMS log with.
|
|
||||||
0: Error
|
|
||||||
1: Warning
|
|
||||||
2: Info
|
|
||||||
3: Debug
|
|
||||||
4: Verbose
|
|
||||||
|
|
||||||
message: str
|
|
||||||
The text of the message to write to the log.
|
|
||||||
source: str
|
|
||||||
a string indicating the source of the message.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/log"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not level:
|
|
||||||
raise ValueError("Parameter level is required, cannot be empty or blank.")
|
|
||||||
validated_level = self._enum_matching(level, LevelModel.list(), "level")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "level", validated_level)
|
|
||||||
)
|
|
||||||
if not message:
|
|
||||||
raise ValueError("Parameter message is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "message", message)
|
|
||||||
)
|
|
||||||
if not source:
|
|
||||||
raise ValueError("Parameter source is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "source", source)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def log_multi_line(self):
|
|
||||||
"""
|
|
||||||
Logging a multi-line message
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/log"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def enable_paper_trail(self):
|
|
||||||
"""
|
|
||||||
Enabling Papertrail
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/log/networked"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
|
|
||||||
|
|
||||||
class Media(BaseService):
|
|
||||||
def mark_played(self, key: float):
|
|
||||||
"""
|
|
||||||
Mark Media Played
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
key: float
|
|
||||||
The media key to mark as played
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/:/scrobble"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not key:
|
|
||||||
raise ValueError("Parameter key is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "key", key))
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def mark_unplayed(self, key: float):
|
|
||||||
"""
|
|
||||||
Mark Media Unplayed
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
key: float
|
|
||||||
The media key to mark as Unplayed
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/:/unscrobble"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not key:
|
|
||||||
raise ValueError("Parameter key is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "key", key))
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def update_play_progress(self, state: str, time: float, key: str):
|
|
||||||
"""
|
|
||||||
Update Media Play Progress
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
key: str
|
|
||||||
the media key
|
|
||||||
time: float
|
|
||||||
The time, in milliseconds, used to set the media playback progress.
|
|
||||||
state: str
|
|
||||||
The playback state of the media item.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/:/progress"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not key:
|
|
||||||
raise ValueError("Parameter key is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "key", key))
|
|
||||||
if not time:
|
|
||||||
raise ValueError("Parameter time is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "time", time)
|
|
||||||
)
|
|
||||||
if not state:
|
|
||||||
raise ValueError("Parameter state is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "state", state)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.Type import Type as TypeModel
|
|
||||||
from ..models.Smart import Smart as SmartModel
|
|
||||||
from ..models.PlaylistType import PlaylistType as PlaylistTypeModel
|
|
||||||
from ..models.Force import Force as ForceModel
|
|
||||||
|
|
||||||
|
|
||||||
class Playlists(BaseService):
|
|
||||||
def create_playlist(
|
|
||||||
self,
|
|
||||||
smart: SmartModel,
|
|
||||||
type_: TypeModel,
|
|
||||||
title: str,
|
|
||||||
uri: str = None,
|
|
||||||
play_queue_id: float = None,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Create a Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
title: str
|
|
||||||
name of the playlist
|
|
||||||
type: Type
|
|
||||||
type of playlist to create
|
|
||||||
smart: Smart
|
|
||||||
whether the playlist is smart or not
|
|
||||||
uri: str
|
|
||||||
the content URI for the playlist
|
|
||||||
play_queue_id: float
|
|
||||||
the play queue to copy to a playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not title:
|
|
||||||
raise ValueError("Parameter title is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "title", title)
|
|
||||||
)
|
|
||||||
if not type_:
|
|
||||||
raise ValueError("Parameter type_ is required, cannot be empty or blank.")
|
|
||||||
validated_type_ = self._enum_matching(type_, TypeModel.list(), "type_")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", validated_type_)
|
|
||||||
)
|
|
||||||
if not smart:
|
|
||||||
raise ValueError("Parameter smart is required, cannot be empty or blank.")
|
|
||||||
validated_smart = self._enum_matching(smart, SmartModel.list(), "smart")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "smart", validated_smart)
|
|
||||||
)
|
|
||||||
if uri:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "uri", uri)
|
|
||||||
)
|
|
||||||
if play_queue_id:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "playQueueID", play_queue_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_playlists(
|
|
||||||
self, playlist_type: PlaylistTypeModel = None, smart: SmartModel = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get All Playlists
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_type: PlaylistType
|
|
||||||
limit to a type of playlist.
|
|
||||||
smart: Smart
|
|
||||||
type of playlists to return (default is all).
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/all"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if playlist_type:
|
|
||||||
validated_playlist_type = self._enum_matching(
|
|
||||||
playlist_type, PlaylistTypeModel.list(), "playlist_type"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "playlistType", validated_playlist_type
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if smart:
|
|
||||||
validated_smart = self._enum_matching(smart, SmartModel.list(), "smart")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "smart", validated_smart
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_playlist(self, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Retrieve Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def update_playlist(self, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Update a Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.put(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def delete_playlist(self, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Deletes a Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_playlist_contents(self, type_: float, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Retrieve Playlist Contents
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
type: float
|
|
||||||
the metadata type of the item to return
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}/items"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if not type_:
|
|
||||||
raise ValueError("Parameter type_ is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", type_)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def add_playlist_contents(self, play_queue_id: float, uri: str, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Adding to a Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
uri: str
|
|
||||||
the content URI for the playlist
|
|
||||||
play_queue_id: float
|
|
||||||
the play queue to add to a playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}/items"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if not uri:
|
|
||||||
raise ValueError("Parameter uri is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "uri", uri))
|
|
||||||
if not play_queue_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter play_queue_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "playQueueID", play_queue_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.put(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def clear_playlist_contents(self, playlist_id: float):
|
|
||||||
"""
|
|
||||||
Delete Playlist Contents
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
playlist_id: float
|
|
||||||
the ID of the playlist
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/{playlist_id}/items"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not playlist_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter playlist_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{playlist_id}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, playlist_id, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def upload_playlist(self, force: ForceModel, path: str):
|
|
||||||
"""
|
|
||||||
Upload Playlist
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
path: str
|
|
||||||
absolute path to a directory on the server where m3u files are stored, or the absolute path to a playlist file on the server.
|
|
||||||
If the `path` argument is a directory, that path will be scanned for playlist files to be processed.
|
|
||||||
Each file in that directory creates a separate playlist, with a name based on the filename of the file that created it.
|
|
||||||
The GUID of each playlist is based on the filename.
|
|
||||||
If the `path` argument is a file, that file will be used to create a new playlist, with the name based on the filename of the file that created it.
|
|
||||||
The GUID of each playlist is based on the filename.
|
|
||||||
|
|
||||||
force: Force
|
|
||||||
force overwriting of duplicate playlists. By default, a playlist file uploaded with the same path will overwrite the existing playlist.
|
|
||||||
The `force` argument is used to disable overwriting. If the `force` argument is set to 0, a new playlist will be created suffixed with the date and time that the duplicate was uploaded.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/playlists/upload"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not path:
|
|
||||||
raise ValueError("Parameter path is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "path", path)
|
|
||||||
)
|
|
||||||
if not force:
|
|
||||||
raise ValueError("Parameter force is required, cannot be empty or blank.")
|
|
||||||
validated_force = self._enum_matching(force, ForceModel.list(), "force")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "force", validated_force)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.post(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetSearchResultsResponse import (
|
|
||||||
GetSearchResultsResponse as GetSearchResultsResponseModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Search(BaseService):
|
|
||||||
def perform_search(self, query: str, section_id: float = None, limit: float = None):
|
|
||||||
"""
|
|
||||||
Perform a search
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
query: str
|
|
||||||
The query term
|
|
||||||
section_id: float
|
|
||||||
This gives context to the search, and can result in re-ordering of search result hubs
|
|
||||||
limit: float
|
|
||||||
The number of items to return per hub
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/hubs/search"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not query:
|
|
||||||
raise ValueError("Parameter query is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "query", query)
|
|
||||||
)
|
|
||||||
if section_id:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "sectionId", section_id)
|
|
||||||
)
|
|
||||||
if limit:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "limit", limit)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def perform_voice_search(
|
|
||||||
self, query: str, section_id: float = None, limit: float = None
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Perform a voice search
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
query: str
|
|
||||||
The query term
|
|
||||||
section_id: float
|
|
||||||
This gives context to the search, and can result in re-ordering of search result hubs
|
|
||||||
limit: float
|
|
||||||
The number of items to return per hub
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/hubs/search/voice"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not query:
|
|
||||||
raise ValueError("Parameter query is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "query", query)
|
|
||||||
)
|
|
||||||
if section_id:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "sectionId", section_id)
|
|
||||||
)
|
|
||||||
if limit:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "limit", limit)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_search_results(self, query: str) -> GetSearchResultsResponseModel:
|
|
||||||
"""
|
|
||||||
Get Search Results
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
query: str
|
|
||||||
The search query string to use
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/search"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not query:
|
|
||||||
raise ValueError("Parameter query is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "query", query)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetSearchResultsResponseModel(**res)
|
|
||||||
return res
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.SecurityType import SecurityType as SecurityTypeModel
|
|
||||||
from ..models.Scope import Scope as ScopeModel
|
|
||||||
|
|
||||||
|
|
||||||
class Security(BaseService):
|
|
||||||
def get_transient_token(self, scope: ScopeModel, type_: SecurityTypeModel):
|
|
||||||
"""
|
|
||||||
Get a Transient Token.
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
type: SecurityType
|
|
||||||
`delegation` - This is the only supported `type` parameter.
|
|
||||||
scope: Scope
|
|
||||||
`all` - This is the only supported `scope` parameter.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/security/token"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not type_:
|
|
||||||
raise ValueError("Parameter type_ is required, cannot be empty or blank.")
|
|
||||||
validated_type_ = self._enum_matching(type_, SecurityTypeModel.list(), "type_")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "type_", validated_type_)
|
|
||||||
)
|
|
||||||
if not scope:
|
|
||||||
raise ValueError("Parameter scope is required, cannot be empty or blank.")
|
|
||||||
validated_scope = self._enum_matching(scope, ScopeModel.list(), "scope")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "scope", validated_scope)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_source_connection_information(self, source: str):
|
|
||||||
"""
|
|
||||||
Get Source Connection Information
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
source: str
|
|
||||||
The source identifier with an included prefix.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/security/resources"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not source:
|
|
||||||
raise ValueError("Parameter source is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "source", source)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetServerCapabilitiesResponse import (
|
|
||||||
GetServerCapabilitiesResponse as GetServerCapabilitiesResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.GetAvailableClientsResponse import (
|
|
||||||
GetAvailableClientsResponse as GetAvailableClientsResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.GetAvailableClientsResponse import (
|
|
||||||
GetAvailableClientsResponseItem as GetAvailableClientsResponseItemModel,
|
|
||||||
)
|
|
||||||
from ..models.GetDevicesResponse import GetDevicesResponse as GetDevicesResponseModel
|
|
||||||
from ..models.GetServerIdentityResponse import (
|
|
||||||
GetServerIdentityResponse as GetServerIdentityResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.GetMyPlexAccountResponse import (
|
|
||||||
GetMyPlexAccountResponse as GetMyPlexAccountResponseModel,
|
|
||||||
)
|
|
||||||
from ..models.MinSize import MinSize as MinSizeModel
|
|
||||||
from ..models.Upscale import Upscale as UpscaleModel
|
|
||||||
from ..models.GetServerListResponse import (
|
|
||||||
GetServerListResponse as GetServerListResponseModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Server(BaseService):
|
|
||||||
def get_server_capabilities(self) -> GetServerCapabilitiesResponseModel:
|
|
||||||
"""
|
|
||||||
Server Capabilities
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetServerCapabilitiesResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_server_preferences(self):
|
|
||||||
"""
|
|
||||||
Get Server Preferences
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/:/prefs"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_available_clients(self) -> GetAvailableClientsResponseModel:
|
|
||||||
"""
|
|
||||||
Get Available Clients
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/clients"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, list):
|
|
||||||
return [GetAvailableClientsResponseItemModel(**model) for model in res]
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_devices(self) -> GetDevicesResponseModel:
|
|
||||||
"""
|
|
||||||
Get Devices
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/devices"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetDevicesResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_server_identity(self) -> GetServerIdentityResponseModel:
|
|
||||||
"""
|
|
||||||
Get Server Identity
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/identity"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetServerIdentityResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_my_plex_account(self) -> GetMyPlexAccountResponseModel:
|
|
||||||
"""
|
|
||||||
Get MyPlex Account
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/myplex/account"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetMyPlexAccountResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_resized_photo(
|
|
||||||
self,
|
|
||||||
url: str,
|
|
||||||
upscale: UpscaleModel,
|
|
||||||
min_size: MinSizeModel,
|
|
||||||
blur: float,
|
|
||||||
opacity: int,
|
|
||||||
height: float,
|
|
||||||
width: float,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get a Resized Photo
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
width: float
|
|
||||||
The width for the resized photo
|
|
||||||
height: float
|
|
||||||
The height for the resized photo
|
|
||||||
opacity: int
|
|
||||||
The opacity for the resized photo
|
|
||||||
blur: float
|
|
||||||
The width for the resized photo
|
|
||||||
min_size: MinSize
|
|
||||||
images are always scaled proportionally. A value of '1' in minSize will make the smaller native dimension the dimension resized against.
|
|
||||||
upscale: Upscale
|
|
||||||
allow images to be resized beyond native dimensions.
|
|
||||||
url: str
|
|
||||||
path to image within Plex
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/photo/:/transcode"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not width:
|
|
||||||
raise ValueError("Parameter width is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "width", width)
|
|
||||||
)
|
|
||||||
if not height:
|
|
||||||
raise ValueError("Parameter height is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "height", height)
|
|
||||||
)
|
|
||||||
if not opacity:
|
|
||||||
raise ValueError("Parameter opacity is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "opacity", opacity)
|
|
||||||
)
|
|
||||||
if not blur:
|
|
||||||
raise ValueError("Parameter blur is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "blur", blur)
|
|
||||||
)
|
|
||||||
if not min_size:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter min_size is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
validated_min_size = self._enum_matching(
|
|
||||||
min_size, MinSizeModel.list(), "min_size"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "minSize", validated_min_size
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if not upscale:
|
|
||||||
raise ValueError("Parameter upscale is required, cannot be empty or blank.")
|
|
||||||
validated_upscale = self._enum_matching(upscale, UpscaleModel.list(), "upscale")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "upscale", validated_upscale
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if not url:
|
|
||||||
raise ValueError("Parameter url is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "url", url))
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_server_list(self) -> GetServerListResponseModel:
|
|
||||||
"""
|
|
||||||
Get Server List
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/servers"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetServerListResponseModel(**res)
|
|
||||||
return res
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.GetTranscodeSessionsResponse import (
|
|
||||||
GetTranscodeSessionsResponse as GetTranscodeSessionsResponseModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Sessions(BaseService):
|
|
||||||
def get_sessions(self):
|
|
||||||
"""
|
|
||||||
Get Active Sessions
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/status/sessions"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_session_history(self):
|
|
||||||
"""
|
|
||||||
Get Session History
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/status/sessions/history/all"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_transcode_sessions(self) -> GetTranscodeSessionsResponseModel:
|
|
||||||
"""
|
|
||||||
Get Transcode Sessions
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/transcode/sessions"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
if res and isinstance(res, dict):
|
|
||||||
return GetTranscodeSessionsResponseModel(**res)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def stop_transcode_session(self, session_key: str):
|
|
||||||
"""
|
|
||||||
Stop a Transcode Session
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
session_key: str
|
|
||||||
the Key of the transcode session to stop
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/transcode/sessions/{session_key}"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not session_key:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter session_key is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
url_endpoint = url_endpoint.replace(
|
|
||||||
"{session_key}",
|
|
||||||
quote(
|
|
||||||
str(query_serializer.serialize_path("simple", False, session_key, None))
|
|
||||||
),
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.delete(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.Download import Download as DownloadModel
|
|
||||||
from ..models.Tonight import Tonight as TonightModel
|
|
||||||
from ..models.Skip import Skip as SkipModel
|
|
||||||
|
|
||||||
|
|
||||||
class Updater(BaseService):
|
|
||||||
def get_update_status(self):
|
|
||||||
"""
|
|
||||||
Querying status of updates
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/updater/status"
|
|
||||||
headers = {}
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def check_for_updates(self, download: DownloadModel = None):
|
|
||||||
"""
|
|
||||||
Checking for updates
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
download: Download
|
|
||||||
Indicate that you want to start download any updates found.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/updater/check"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if download:
|
|
||||||
validated_download = self._enum_matching(
|
|
||||||
download, DownloadModel.list(), "download"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "download", validated_download
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.put(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def apply_updates(self, tonight: TonightModel = None, skip: SkipModel = None):
|
|
||||||
"""
|
|
||||||
Apply Updates
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
tonight: Tonight
|
|
||||||
Indicate that you want the update to run during the next Butler execution. Omitting this or setting it to false indicates that the update should install
|
|
||||||
skip: Skip
|
|
||||||
Indicate that the latest version should be marked as skipped. The <Release> entry for this version will have the `state` set to `skipped`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/updater/apply"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if tonight:
|
|
||||||
validated_tonight = self._enum_matching(
|
|
||||||
tonight, TonightModel.list(), "tonight"
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "tonight", validated_tonight
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if skip:
|
|
||||||
validated_skip = self._enum_matching(skip, SkipModel.list(), "skip")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "skip", validated_skip)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint
|
|
||||||
if len(query_params) > 0:
|
|
||||||
final_url += "?" + "&".join(query_params)
|
|
||||||
res = self._http.put(final_url, headers, {}, True)
|
|
||||||
return res
|
|
||||||
@@ -1,266 +0,0 @@
|
|||||||
from urllib.parse import quote
|
|
||||||
from ..net import query_serializer
|
|
||||||
from .base import BaseService
|
|
||||||
from ..models.State import State as StateModel
|
|
||||||
|
|
||||||
|
|
||||||
class Video(BaseService):
|
|
||||||
def start_universal_transcode(
|
|
||||||
self,
|
|
||||||
protocol: str,
|
|
||||||
part_index: float,
|
|
||||||
media_index: float,
|
|
||||||
path: str,
|
|
||||||
has_mde: float,
|
|
||||||
fast_seek: float = None,
|
|
||||||
direct_play: float = None,
|
|
||||||
direct_stream: float = None,
|
|
||||||
subtitle_size: float = None,
|
|
||||||
subtites: str = None,
|
|
||||||
audio_boost: float = None,
|
|
||||||
location: str = None,
|
|
||||||
media_buffer_size: float = None,
|
|
||||||
session: str = None,
|
|
||||||
add_debug_overlay: float = None,
|
|
||||||
auto_adjust_quality: float = None,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Start Universal Transcode
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
has_mde: float
|
|
||||||
Whether the media item has MDE
|
|
||||||
path: str
|
|
||||||
The path to the media item to transcode
|
|
||||||
media_index: float
|
|
||||||
The index of the media item to transcode
|
|
||||||
part_index: float
|
|
||||||
The index of the part to transcode
|
|
||||||
protocol: str
|
|
||||||
The protocol to use for the transcode session
|
|
||||||
fast_seek: float
|
|
||||||
Whether to use fast seek or not
|
|
||||||
direct_play: float
|
|
||||||
Whether to use direct play or not
|
|
||||||
direct_stream: float
|
|
||||||
Whether to use direct stream or not
|
|
||||||
subtitle_size: float
|
|
||||||
The size of the subtitles
|
|
||||||
subtites: str
|
|
||||||
The subtitles
|
|
||||||
audio_boost: float
|
|
||||||
The audio boost
|
|
||||||
location: str
|
|
||||||
The location of the transcode session
|
|
||||||
media_buffer_size: float
|
|
||||||
The size of the media buffer
|
|
||||||
session: str
|
|
||||||
The session ID
|
|
||||||
add_debug_overlay: float
|
|
||||||
Whether to add a debug overlay or not
|
|
||||||
auto_adjust_quality: float
|
|
||||||
Whether to auto adjust quality or not
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/video/:/transcode/universal/start.mpd"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not has_mde:
|
|
||||||
raise ValueError("Parameter has_mde is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "hasMDE", has_mde)
|
|
||||||
)
|
|
||||||
if not path:
|
|
||||||
raise ValueError("Parameter path is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "path", path)
|
|
||||||
)
|
|
||||||
if not media_index:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter media_index is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "mediaIndex", media_index)
|
|
||||||
)
|
|
||||||
if not part_index:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter part_index is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "partIndex", part_index)
|
|
||||||
)
|
|
||||||
if not protocol:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter protocol is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "protocol", protocol)
|
|
||||||
)
|
|
||||||
if fast_seek:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "fastSeek", fast_seek)
|
|
||||||
)
|
|
||||||
if direct_play:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "directPlay", direct_play
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if direct_stream:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "directStream", direct_stream
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if subtitle_size:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "subtitleSize", subtitle_size
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if subtites:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "subtites", subtites)
|
|
||||||
)
|
|
||||||
if audio_boost:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "audioBoost", audio_boost
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if location:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "location", location)
|
|
||||||
)
|
|
||||||
if media_buffer_size:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "mediaBufferSize", media_buffer_size
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if session:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "session", session)
|
|
||||||
)
|
|
||||||
if add_debug_overlay:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "addDebugOverlay", add_debug_overlay
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if auto_adjust_quality:
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "autoAdjustQuality", auto_adjust_quality
|
|
||||||
)
|
|
||||||
)
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_timeline(
|
|
||||||
self,
|
|
||||||
row: float,
|
|
||||||
play_back_time: float,
|
|
||||||
play_queue_item_id: float,
|
|
||||||
context: str,
|
|
||||||
duration: float,
|
|
||||||
time: float,
|
|
||||||
has_mde: float,
|
|
||||||
state: StateModel,
|
|
||||||
key: str,
|
|
||||||
rating_key: float,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Get the timeline for a media item
|
|
||||||
Parameters:
|
|
||||||
----------
|
|
||||||
rating_key: float
|
|
||||||
The rating key of the media item
|
|
||||||
key: str
|
|
||||||
The key of the media item to get the timeline for
|
|
||||||
state: State
|
|
||||||
The state of the media item
|
|
||||||
has_mde: float
|
|
||||||
Whether the media item has MDE
|
|
||||||
time: float
|
|
||||||
The time of the media item
|
|
||||||
duration: float
|
|
||||||
The duration of the media item
|
|
||||||
context: str
|
|
||||||
The context of the media item
|
|
||||||
play_queue_item_id: float
|
|
||||||
The play queue item ID of the media item
|
|
||||||
play_back_time: float
|
|
||||||
The playback time of the media item
|
|
||||||
row: float
|
|
||||||
The row of the media item
|
|
||||||
"""
|
|
||||||
|
|
||||||
url_endpoint = "/:/timeline"
|
|
||||||
headers = {}
|
|
||||||
query_params = []
|
|
||||||
self._add_required_headers(headers)
|
|
||||||
if not rating_key:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter rating_key is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "ratingKey", rating_key)
|
|
||||||
)
|
|
||||||
if not key:
|
|
||||||
raise ValueError("Parameter key is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "key", key))
|
|
||||||
if not state:
|
|
||||||
raise ValueError("Parameter state is required, cannot be empty or blank.")
|
|
||||||
validated_state = self._enum_matching(state, StateModel.list(), "state")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "state", validated_state)
|
|
||||||
)
|
|
||||||
if not has_mde:
|
|
||||||
raise ValueError("Parameter has_mde is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "hasMDE", has_mde)
|
|
||||||
)
|
|
||||||
if not time:
|
|
||||||
raise ValueError("Parameter time is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "time", time)
|
|
||||||
)
|
|
||||||
if not duration:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter duration is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "duration", duration)
|
|
||||||
)
|
|
||||||
if not context:
|
|
||||||
raise ValueError("Parameter context is required, cannot be empty or blank.")
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query("form", False, "context", context)
|
|
||||||
)
|
|
||||||
if not play_queue_item_id:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter play_queue_item_id is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "playQueueItemID", play_queue_item_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if not play_back_time:
|
|
||||||
raise ValueError(
|
|
||||||
"Parameter play_back_time is required, cannot be empty or blank."
|
|
||||||
)
|
|
||||||
query_params.append(
|
|
||||||
query_serializer.serialize_query(
|
|
||||||
"form", False, "playBackTime", play_back_time
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if not row:
|
|
||||||
raise ValueError("Parameter row is required, cannot be empty or blank.")
|
|
||||||
query_params.append(query_serializer.serialize_query("form", False, "row", row))
|
|
||||||
final_url = self._url_prefix + url_endpoint + "?" + "&".join(query_params)
|
|
||||||
res = self._http.get(final_url, headers, True)
|
|
||||||
return res
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import setuptools
|
|
||||||
|
|
||||||
setuptools.setup(
|
|
||||||
name="PlexSDK",
|
|
||||||
version="0.0.1",
|
|
||||||
description="""An Open API Spec for interacting with Plex.tv and Plex Servers""",
|
|
||||||
license="MIT",
|
|
||||||
packages=setuptools.find_packages(),
|
|
||||||
)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from http import HTTPStatus
|
|
||||||
from src.plexsdk.models.base import BaseModel
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
|
|
||||||
|
|
||||||
class TestBaseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetButlerTasksResponse import GetButlerTasksResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetButlerTasksResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_butler_tasks_response(self):
|
|
||||||
# Create GetButlerTasksResponse class instance
|
|
||||||
test_model = GetButlerTasksResponse(ButlerTasks={"libero": 4})
|
|
||||||
self.assertEqual(test_model.ButlerTasks, {"libero": 4})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetDevicesResponse import GetDevicesResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetDevicesResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_devices_response(self):
|
|
||||||
# Create GetDevicesResponse class instance
|
|
||||||
test_model = GetDevicesResponse(MediaContainer={"est": 3})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"est": 3})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetMyPlexAccountResponse import GetMyPlexAccountResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetMyPlexAccountResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_my_plex_account_response(self):
|
|
||||||
# Create GetMyPlexAccountResponse class instance
|
|
||||||
test_model = GetMyPlexAccountResponse(MyPlex={"at": 7})
|
|
||||||
self.assertEqual(test_model.MyPlex, {"at": 7})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetOnDeckResponse import GetOnDeckResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetOnDeckResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_on_deck_response(self):
|
|
||||||
# Create GetOnDeckResponse class instance
|
|
||||||
test_model = GetOnDeckResponse(MediaContainer={"doloremque": 5})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"doloremque": 5})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetRecentlyAddedResponse import GetRecentlyAddedResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetRecentlyAddedResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_recently_added_response(self):
|
|
||||||
# Create GetRecentlyAddedResponse class instance
|
|
||||||
test_model = GetRecentlyAddedResponse(MediaContainer={"possimus": 4})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"possimus": 4})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetSearchResultsResponse import GetSearchResultsResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetSearchResultsResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_search_results_response(self):
|
|
||||||
# Create GetSearchResultsResponse class instance
|
|
||||||
test_model = GetSearchResultsResponse(MediaContainer={"tenetur": 8})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"tenetur": 8})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetServerActivitiesResponse import GetServerActivitiesResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetServerActivitiesResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_server_activities_response(self):
|
|
||||||
# Create GetServerActivitiesResponse class instance
|
|
||||||
test_model = GetServerActivitiesResponse(MediaContainer={"enim": 8})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"enim": 8})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetServerCapabilitiesResponse import (
|
|
||||||
GetServerCapabilitiesResponse,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetServerCapabilitiesResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_server_capabilities_response(self):
|
|
||||||
# Create GetServerCapabilitiesResponse class instance
|
|
||||||
test_model = GetServerCapabilitiesResponse(MediaContainer={"nam": 5})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"nam": 5})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetServerIdentityResponse import GetServerIdentityResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetServerIdentityResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_server_identity_response(self):
|
|
||||||
# Create GetServerIdentityResponse class instance
|
|
||||||
test_model = GetServerIdentityResponse(MediaContainer={"similique": 3})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"similique": 3})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetServerListResponse import GetServerListResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetServerListResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_server_list_response(self):
|
|
||||||
# Create GetServerListResponse class instance
|
|
||||||
test_model = GetServerListResponse(MediaContainer={"dicta": 1})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"dicta": 1})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import unittest
|
|
||||||
from src.plexsdk.models.GetTranscodeSessionsResponse import GetTranscodeSessionsResponse
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetTranscodeSessionsResponseModel(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
def test_get_transcode_sessions_response(self):
|
|
||||||
# Create GetTranscodeSessionsResponse class instance
|
|
||||||
test_model = GetTranscodeSessionsResponse(MediaContainer={"ab": 3})
|
|
||||||
self.assertEqual(test_model.MediaContainer, {"ab": 3})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.activities import Activities
|
|
||||||
|
|
||||||
|
|
||||||
class TestActivities_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_activities(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/activities", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Activities("testkey")
|
|
||||||
response = test_service.get_server_activities()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_activities_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/activities", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Activities("testkey")
|
|
||||||
test_service.get_server_activities()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_cancel_server_activities(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/activities/9191455277", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Activities("testkey")
|
|
||||||
response = test_service.cancel_server_activities("9191455277")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_cancel_server_activities_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/activities/6359244154", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Activities("testkey")
|
|
||||||
test_service.cancel_server_activities()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_cancel_server_activities_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/activities/1590369420", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Activities("testkey")
|
|
||||||
test_service.cancel_server_activities("1590369420")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from http import HTTPStatus
|
|
||||||
from src.plexsdk.services.base import BaseService
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
|
|
||||||
|
|
||||||
class TestBaseService(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.butler import Butler
|
|
||||||
|
|
||||||
|
|
||||||
class TestButler_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_butler_tasks(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/butler", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
response = test_service.get_butler_tasks()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_butler_tasks_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/butler", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.get_butler_tasks()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_start_all_tasks(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/butler", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
response = test_service.start_all_tasks()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_start_all_tasks_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/butler", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.start_all_tasks()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_all_tasks(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete("http://10.10.10.47:32400/butler", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
response = test_service.stop_all_tasks()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_all_tasks_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete("http://10.10.10.47:32400/butler", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.stop_all_tasks()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_start_task(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
response = test_service.start_task("BackupDatabase")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_start_task_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.start_task()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_start_task_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.start_task("BackupDatabase")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_task(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
response = test_service.stop_task("BackupDatabase")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_task_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.stop_task()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_task_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/butler/BackupDatabase", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Butler("testkey")
|
|
||||||
test_service.stop_task("BackupDatabase")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.hubs import Hubs
|
|
||||||
|
|
||||||
|
|
||||||
class TestHubs_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_global_hubs(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Hubs("testkey")
|
|
||||||
response = test_service.get_global_hubs(2, 2)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_global_hubs_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Hubs("testkey")
|
|
||||||
test_service.get_global_hubs(7, 5)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_hubs(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/hubs/sections/7302320686", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Hubs("testkey")
|
|
||||||
response = test_service.get_library_hubs(7302320686, 4, 1)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_hubs_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/hubs/sections/8066749835", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Hubs("testkey")
|
|
||||||
test_service.get_library_hubs()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_hubs_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/hubs/sections/4815305500", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Hubs("testkey")
|
|
||||||
test_service.get_library_hubs(4815305500, 9, 9)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,399 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.library import Library
|
|
||||||
|
|
||||||
|
|
||||||
class TestLibrary_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_file_hash(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/hashes", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_file_hash("harum", 3)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_file_hash_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/hashes", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_file_hash()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_file_hash_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/hashes", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_file_hash("debitis", 9)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_recently_added(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/recentlyAdded", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_recently_added()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_recently_added_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/recentlyAdded", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_recently_added()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_libraries(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/sections", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_libraries()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_libraries_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/sections", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_libraries()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/1902657001", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_library(1902657001, 6)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/3167481710", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_library()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/4877467839", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_library(4877467839, 5)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_library(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/library/sections/8087858304", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.delete_library(8087858304)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_library_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/library/sections/3795773112", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.delete_library()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_library_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/library/sections/6227875135", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.delete_library(6227875135)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_items(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/6046339919/all",
|
|
||||||
json={},
|
|
||||||
status=200,
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_library_items(6046339919, 8, "error")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_items_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/4081463593/all",
|
|
||||||
json={},
|
|
||||||
status=202,
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_library_items()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_library_items_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/8084937448/all",
|
|
||||||
json={},
|
|
||||||
status=404,
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_library_items(8084937448, 2, "sint")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_refresh_library(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/5454812191/refresh",
|
|
||||||
json={},
|
|
||||||
status=200,
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.refresh_library(5454812191)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_refresh_library_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/7285849503/refresh",
|
|
||||||
json={},
|
|
||||||
status=202,
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.refresh_library()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_refresh_library_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/3253419710/refresh",
|
|
||||||
json={},
|
|
||||||
status=404,
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.refresh_library(3253419710)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_latest_library_items(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/5633500181/latest",
|
|
||||||
json={},
|
|
||||||
status=200,
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_latest_library_items(2, 5633500181, "similique")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_latest_library_items_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/8744481339/latest",
|
|
||||||
json={},
|
|
||||||
status=202,
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_latest_library_items()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_latest_library_items_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/1338044693/latest",
|
|
||||||
json={},
|
|
||||||
status=404,
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_latest_library_items(4, 1338044693, "quo")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_common_library_items(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/3556695926/common",
|
|
||||||
json={},
|
|
||||||
status=200,
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_common_library_items(7, 3556695926, "id")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_common_library_items_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/5226642550/common",
|
|
||||||
json={},
|
|
||||||
status=202,
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_common_library_items()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_common_library_items_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/sections/2153034771/common",
|
|
||||||
json={},
|
|
||||||
status=404,
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_common_library_items(2, 2153034771, "eos")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/5", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_metadata(5)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/9", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_metadata()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/2", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_metadata(2)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata_children(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/7/children", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_metadata_children(7)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata_children_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/8/children", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_metadata_children()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_metadata_children_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/library/metadata/2/children", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_metadata_children(2)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_on_deck(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/onDeck", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Library("testkey")
|
|
||||||
response = test_service.get_on_deck()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_on_deck_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/library/onDeck", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Library("testkey")
|
|
||||||
test_service.get_on_deck()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.log import Log
|
|
||||||
|
|
||||||
|
|
||||||
class TestLog_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_log_line(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/log", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Log("testkey")
|
|
||||||
response = test_service.log_line("recusandae", "quos", 2)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_log_line_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/log", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Log("testkey")
|
|
||||||
test_service.log_line()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_log_line_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/log", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Log("testkey")
|
|
||||||
test_service.log_line("labore", "aliquid", 3)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_log_multi_line(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/log", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Log("testkey")
|
|
||||||
response = test_service.log_multi_line()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_log_multi_line_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/log", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Log("testkey")
|
|
||||||
test_service.log_multi_line()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_enable_paper_trail(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/log/networked", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Log("testkey")
|
|
||||||
response = test_service.enable_paper_trail()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_enable_paper_trail_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/log/networked", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Log("testkey")
|
|
||||||
test_service.enable_paper_trail()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.media import Media
|
|
||||||
|
|
||||||
|
|
||||||
class TestMedia_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_played(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/scrobble", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Media("testkey")
|
|
||||||
response = test_service.mark_played(6)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_played_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/scrobble", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.mark_played()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_played_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/scrobble", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.mark_played(8)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_unplayed(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/unscrobble", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Media("testkey")
|
|
||||||
response = test_service.mark_unplayed(8)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_unplayed_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/unscrobble", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.mark_unplayed()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_mark_unplayed_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/unscrobble", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.mark_unplayed(8)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_play_progress(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/:/progress", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Media("testkey")
|
|
||||||
response = test_service.update_play_progress("eos", 6, "vitae")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_play_progress_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/:/progress", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.update_play_progress()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_play_progress_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/:/progress", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Media("testkey")
|
|
||||||
test_service.update_play_progress("praesentium", 5, "asperiores")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.playlists import Playlists
|
|
||||||
|
|
||||||
|
|
||||||
class TestPlaylists_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_create_playlist(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.create_playlist(
|
|
||||||
6, "audio", "similique", "corporis", 9231398604
|
|
||||||
)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_create_playlist_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.create_playlist()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_create_playlist_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.create_playlist(3, "audio", "dolor", "eius", 2118287307)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlists(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/playlists/all", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.get_playlists("audio", 7)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlists_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/playlists/all", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.get_playlists("audio", 7)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/1365108722", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.get_playlist(1365108722)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/5774434055", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.get_playlist()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/9191760374", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.get_playlist(9191760374)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_playlist(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/5518621092", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.update_playlist(5518621092)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_playlist_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/9186005034", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.update_playlist()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_update_playlist_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/9820265225", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.update_playlist(9820265225)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_playlist(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/5260240376", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.delete_playlist(5260240376)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_playlist_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/1740225155", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.delete_playlist()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_delete_playlist_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/6145805352", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.delete_playlist(6145805352)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist_contents(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/2828620637/items", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.get_playlist_contents(9, 2828620637)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist_contents_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/2652525666/items", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.get_playlist_contents()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_playlist_contents_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/playlists/1352187138/items", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.get_playlist_contents(3, 1352187138)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_add_playlist_contents(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/9135301877/items", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.add_playlist_contents(3575196026, "sit", 9135301877)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_add_playlist_contents_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/6481139604/items", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.add_playlist_contents()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_add_playlist_contents_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put(
|
|
||||||
"http://10.10.10.47:32400/playlists/2575042558/items", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.add_playlist_contents(6992293922, "excepturi", 2575042558)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_clear_playlist_contents(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/5408893231/items", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.clear_playlist_contents(5408893231)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_clear_playlist_contents_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/1483530897/items", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.clear_playlist_contents()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_clear_playlist_contents_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/playlists/7836623831/items", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.clear_playlist_contents(7836623831)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_upload_playlist(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists/upload", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
response = test_service.upload_playlist(6, "ipsam")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_upload_playlist_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists/upload", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.upload_playlist()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_upload_playlist_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.post("http://10.10.10.47:32400/playlists/upload", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Playlists("testkey")
|
|
||||||
test_service.upload_playlist(6, "animi")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.search import Search
|
|
||||||
|
|
||||||
|
|
||||||
class TestSearch_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_search(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Search("testkey")
|
|
||||||
response = test_service.perform_search("consequatur", 9679770792, 1)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_search_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.perform_search()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_search_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.perform_search("facere", 7396523904, 9)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_voice_search(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search/voice", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Search("testkey")
|
|
||||||
response = test_service.perform_voice_search("ipsa", 7448923108, 3)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_voice_search_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search/voice", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.perform_voice_search()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_perform_voice_search_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/hubs/search/voice", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.perform_voice_search("tempore", 1862858310, 2)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_search_results(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/search", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Search("testkey")
|
|
||||||
response = test_service.get_search_results("tempore")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_search_results_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/search", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.get_search_results()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_search_results_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/search", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Search("testkey")
|
|
||||||
test_service.get_search_results("accusantium")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.security import Security
|
|
||||||
|
|
||||||
|
|
||||||
class TestSecurity_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_transient_token(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/security/token", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Security("testkey")
|
|
||||||
response = test_service.get_transient_token("all", "delegation")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_transient_token_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/security/token", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Security("testkey")
|
|
||||||
test_service.get_transient_token()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_transient_token_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/security/token", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Security("testkey")
|
|
||||||
test_service.get_transient_token("all", "delegation")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_source_connection_information(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/security/resources", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Security("testkey")
|
|
||||||
response = test_service.get_source_connection_information("similique")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_source_connection_information_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/security/resources", json={}, status=202
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Security("testkey")
|
|
||||||
test_service.get_source_connection_information()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_source_connection_information_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/security/resources", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Security("testkey")
|
|
||||||
test_service.get_source_connection_information("facere")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.server import Server
|
|
||||||
|
|
||||||
|
|
||||||
class TestServer_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_capabilities(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_server_capabilities()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_capabilities_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_server_capabilities()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_preferences(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/prefs", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_server_preferences()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_preferences_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/:/prefs", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_server_preferences()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_available_clients(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/clients", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_available_clients()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_available_clients_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/clients", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_available_clients()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_devices(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/devices", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_devices()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_devices_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/devices", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_devices()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_identity(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/identity", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_server_identity()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_identity_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/identity", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_server_identity()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_my_plex_account(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/myplex/account", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_my_plex_account()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_my_plex_account_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/myplex/account", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_my_plex_account()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_resized_photo(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/photo/:/transcode", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_resized_photo(
|
|
||||||
"exercitationem", 3, 7, 6, 4, 6, 8564501568
|
|
||||||
)
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_resized_photo_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/photo/:/transcode", json={}, status=202)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_resized_photo()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_resized_photo_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/photo/:/transcode", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_resized_photo("eos", 5, 4, 2, 3, 7, 1237684478)
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_list(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/servers", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Server("testkey")
|
|
||||||
response = test_service.get_server_list()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_server_list_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/servers", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Server("testkey")
|
|
||||||
test_service.get_server_list()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.sessions import Sessions
|
|
||||||
|
|
||||||
|
|
||||||
class TestSessions_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_sessions(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/status/sessions", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
response = test_service.get_sessions()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_sessions_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/status/sessions", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
test_service.get_sessions()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_session_history(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/status/sessions/history/all", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
response = test_service.get_session_history()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_session_history_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/status/sessions/history/all", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
test_service.get_session_history()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_transcode_sessions(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/transcode/sessions", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
response = test_service.get_transcode_sessions()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_transcode_sessions_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get(
|
|
||||||
"http://10.10.10.47:32400/transcode/sessions", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
test_service.get_transcode_sessions()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_transcode_session(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/transcode/sessions/nostrum", json={}, status=200
|
|
||||||
)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
response = test_service.stop_transcode_session("nostrum")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_transcode_session_required_fields_missing(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/transcode/sessions/blanditiis",
|
|
||||||
json={},
|
|
||||||
status=202,
|
|
||||||
)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
test_service.stop_transcode_session()
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_stop_transcode_session_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.delete(
|
|
||||||
"http://10.10.10.47:32400/transcode/sessions/quaerat", json={}, status=404
|
|
||||||
)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Sessions("testkey")
|
|
||||||
test_service.stop_transcode_session("quaerat")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
import unittest
|
|
||||||
import responses
|
|
||||||
from src.plexsdk.net.http_client import HTTPClient
|
|
||||||
from http_exceptions import ClientException
|
|
||||||
from src.plexsdk.services.updater import Updater
|
|
||||||
|
|
||||||
|
|
||||||
class TestUpdater_(unittest.TestCase):
|
|
||||||
def test_true(self):
|
|
||||||
self.assertTrue(True)
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_update_status(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/updater/status", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
response = test_service.get_update_status()
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_get_update_status_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.get("http://10.10.10.47:32400/updater/status", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
test_service.get_update_status()
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_check_for_updates(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put("http://10.10.10.47:32400/updater/check", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
response = test_service.check_for_updates("foo")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_check_for_updates_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put("http://10.10.10.47:32400/updater/check", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
test_service.check_for_updates("foo")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_apply_updates(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put("http://10.10.10.47:32400/updater/apply", json={}, status=200)
|
|
||||||
# call the method to test
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
response = test_service.apply_updates("foo", "foo")
|
|
||||||
self.assertEqual(response.data, {})
|
|
||||||
responses.reset(),
|
|
||||||
|
|
||||||
@responses.activate
|
|
||||||
def test_apply_updates_error_on_non_200(self):
|
|
||||||
# Mock the API response
|
|
||||||
responses.put("http://10.10.10.47:32400/updater/apply", json={}, status=404)
|
|
||||||
with self.assertRaises(ClientException):
|
|
||||||
test_service = Updater("testkey")
|
|
||||||
test_service.apply_updates("foo", "foo")
|
|
||||||
responses.reset()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user