qop package
Submodules
qop.constants module
This module defines global constants and enums. The numeric values of the integer enums
are used to represent the respective value when serializing qop objects into a TaskQueue
sqlite3 database.
- class qop.constants.ConverterType(value)
Bases:
IntEnum
Types of converters. Corresponds to the subclasses of
Converter
.- COPY = 0
- PYDUB = 1
- class qop.constants.Command(value)
Bases:
IntEnum
Commands codes that can be sent to the
QopDaemon
via aCommandMessage
. SeeQopClient
for usage examples.- DAEMON_START = 101
- DAEMON_STOP = 102
- DAEMON_IS_ACTIVE = 103
- DAEMON_FACTS = 104
- QUEUE_START = 201
- QUEUE_STOP = 202
- QUEUE_IS_ACTIVE = 203
- QUEUE_PUT = 204
- QUEUE_FLUSH_PENDING = 205
- QUEUE_FLUSH_ALL = 206
- QUEUE_PROGRESS = 207
- QUEUE_ACTIVE_PROCESSES = 208
- QUEUE_SHOW = 209
- QUEUE_MAX_PROCESSES = 210
- class qop.constants.PayloadClass(value)
Bases:
IntEnum
Types of payloads that can be part of a
CommandMessage
or aStatusMessage
.- VALUE = 1
- TASK = 2
- QUEUE_PROGRESS = 3
- TASK_LIST = 4
- DAEMON_FACTS = 5
qop.converters module
Converters are used by ConvertTask
and SimpleConvertTask
to transcode audiofiles
- class qop.converters.Converter
Bases:
object
Abstract base class for Converters
- remove_art = False
- to_dict() Dict
- static from_dict(x: Dict) Converter
Create a Converter object from python dict that contains the necessary keys
- start(src: Path | str, dst: Path | str)
- class qop.converters.CopyConverter(remove_art: bool = False)
Bases:
Converter
Converter that copies a file without transcoding (but may modify the files tags!)
- start(src: Path | str, dst: Path | str)
- to_dict() Dict
- class qop.converters.PydubConverter(remove_art: bool = False, format: str = 'mp3', codec: str | None = None, bitrate: str | None = None, parameters: List[str] | Tuple[str] | None = ('-q:a', '0'), tags: str | None = None, id3v2_version='4')
Bases:
CopyConverter
Convert audio files using pydub. See
pydub.AudioSegment.export()
(link) for more details on the meaning of the parameters. Defaults to mp3 via lame with V0 quality (best possible VBR quality).- Param:
remove_art Remove all album art (image) tags during conversion
- Param:
parameters named arguments passed on to
pydub.AudioSegment.export()
(and from there to ffmpeg) when starting the conversion.
- property ext: str
- start(src: Path | str, dst: Path | str) None
- to_dict() Dict
qop.daemon module
This module defines classes for the daemon and the client that the command line programs provided by qop are based on.
The client sends
CommandMessages
via TCP to the daemon to enqueue new tasks, tell it to start/stop processing the queue, query information, etc… .The daemon manages a single
TaskQueue
that stores and processesTasks
. For every command it receives, it responds with aStatusMessage
that contains the status of the operation (ok, fail, skip) as well as an optional JSON payload.
Communication diagram:
+-------------+ +-------------+ +-------------+
| | ---[CommandMessage]--> | | | |
| QopClient | | QopDaemon |---| TaskQueue |
| | <--[StatusMessage]---- | | | |
+-------------+ +-------------+ +-------------+
- class qop.daemon.QopDaemon(port: int = 9393, queue_path: Path | str = PosixPath('/tmp/qop-temp.sqlite3'), persist_queue: bool = False)
Bases:
object
- stats = None
- queue = None
- port = None
- close()
- listen(port=9393)
- static handle_request(req)
- new_queue(path: Path)
- facts() Dict
- class qop.daemon.QopClient(ip: str = '127.0.0.1', port: int = 9393)
Bases:
object
A simple client for interacting with QopDaemon. Usage example:
tsk = tasks.EchoTask("foo") client = daemon.QopClient() client.send_command(Command.QUEUE_PUT, payload=tsk) client.send_command(Command.QUEUE_START)
- gather_facts(max_tries=10) Dict
- get_queue_progress(max_tries=10) QueueProgress
- is_daemon_active() bool
- property max_processes: list
- property active_tasks: list
- property active_processes: int
- is_queue_active() int
- class qop.daemon.Message(body: Dict, extra_headers: Dict | None = None)
Bases:
object
Container for messages sent between
QopDaemon
andQopClient
.- encode() bytes
qop.exceptions module
Exceptions
- exception qop.exceptions.AlreadyUnderEvaluationError
Bases:
Exception
This Task is already being processed by a different worker
- exception qop.exceptions.FileExistsAndShouldBeSkippedError
Bases:
Exception
- exception qop.exceptions.FileExistsAndIsIdenticalError
- exception qop.exceptions.FileExistsAndCannotBeComparedError
qop.scanners module
Used by qop.py to traverse the directory tree when looking for files to transfer
qop.tasks module
This module defines classes for working with Tasks
. A task is an atomic operation - such as
copying, moving or transcoding a file - that can be stored and executed at a later date (and usually only once).
TaskQueue
is a persistent (via sqlite3),
prioritized queue with multiprocessing support that can
store and execute an arbitrary number of tasks.
- class qop.tasks.TaskQueue(path: Path | str, max_transfer_processes=1, max_convert_processes=3)
Bases:
object
CONVERT_CACHE_DIR = Path(appdirs.user_cache_dir(“qop”)).joinpath(“convert_temp”) A persistent, prioritized queue with multi process support. Use sqlite3 as a storage backend.
- Parameters:
transfer_processes – A list of file transfer processes
convert_processes – A list of audio transcode processes
- transfer_processes = []
- convert_processes = []
- put(task: Task, priority: int = 10, parent: int | None = None) None
Enqueue a Task
- Parameters:
task – Task to be added to the queue
priority – (optional) priority for executing task (tasks with lower priority will be executed earlier)
parent – (optional) only for child tasks, oid/_ROWID_ of the task that spawned this task
- pop(task_type_include: TaskType | None = None, task_type_exclude: TaskType | None = None) Task
Retrieves a
Task
and sets its status in the queue toStatus.ACTIVE
- Raises:
AlreadyUnderEvaluationError – If trying to pop a tasks that is already being processed (i.e. if a race condition occurs if the queue is processed in parallel)
- print(status: Tuple | int | None = None, n: int = 10) None
Print an overview of the queue
- Parameters:
n – number of tasks to fetch
status – If not None, only fetch Tasks of the given status(es)
- fetch(status: Tuple | int | Status | None = None, n: int | None = None) List
Retrieve the queue
- Parameters:
n – number of tasks to fetch
status – If not None, only fetch Tasks of the given status(es)
:return a dict containing n queued tasks
- reset_active_tasks() None
Reset all active tasks to
Status.PENDING
- set_status(oid: int, status: Status, lock: str | None = None) None
Set the
Status
of the queued task with _ROWID_ oid- Parameters:
oid – _ROWID_ of the task to mark
status –
Status
to setlock – Unique ID for locking queued tasks. The lock value can be querried by the executing task to verify that it is the only tasks that attempts to run this specific task. Must be None except for switching tasks to active.
- start(ip=None, port=None) None
Execute all pending tasks
- stop() None
- facts() Dict
- is_active() bool
- active_processes(type=None)
- property n_total: int
Count of all tasks in queue (including failed and completed)
- property n_pending: int
Number of pending tasks
- property n_active: int
Count of currently active tasks
- property n_ok: int
count of completed tasks
- property n_fail: int
count of completed tasks
- progress(include_children: bool = False) QueueProgress
- class qop.tasks.Task
Bases:
object
Abstract class for qop Tasks. Should not be instantiated directly.
- oid = None
- parent_oid = None
- start() None
Run a task
- to_dict() Dict
- color_repr(color=True)
- to_json()
- class qop.tasks.EchoTask(msg: str)
Bases:
Task
Log a message
- start() None
Run a task
- color_repr(color=True)
- class qop.tasks.SleepTask(seconds: float)
Bases:
Task
Log a message
- start() None
Run a task
- color_repr(color=True)
- class qop.tasks.FileTask(src: Path | str)
Bases:
Task
Abstract class for all file-based tasks
- start() None
Run a task
- class qop.tasks.DeleteTask(src: Path | str, validate: bool = True)
Bases:
FileTask
Delete a file
- start() None
Run a task
- class qop.tasks.CopyTask(src: Path | str, dst: Path | str)
Bases:
FileTask
Copy a file
- color_repr(color=True) str
- start() None
Run a task
- class qop.tasks.MoveTask(src: Path | str, dst: Path | str, parent_oid=None)
Bases:
CopyTask
Move a file
- start() None
Run a task
- color_repr(color=True) str
- class qop.tasks.SimpleConvertTask(src: Path | str, dst: Path | str, converter: Converter)
Bases:
CopyTask
convert an audio file
- start() None
Run a task
- color_repr(color=True) str
- to_dict() Dict
- class qop.tasks.ConvertTask(src: Path | str, dst: Path | str, converter: Converter, tempdir=PosixPath('/home/runner/.cache/qop/convert_temp'))
Bases:
SimpleConvertTask
ConvertTask transcodes an audio file to a temporary directory and then adds a move task to the queue. This makes it possible to cleanly separate transcode and transfer processes.
- start() None
Run a task
- spawn() MoveTask
Spawns a follow-up task. If a task has a
spawn()
method,TaskQueue
calls it internally after fetching the original Task. The follow-up task is then enqueued with maximum priority. If this newly spawned task fails, the parent task will also be considered failed.
- color_repr(color=True) str
- to_dict() Dict
- class qop.tasks.TaskQueueElement(task: Task, priority: 1)
Bases:
object
An enqueued Task
- status = None
Status of the queued Task
- task = None
A Task
- priority = None
Priority of the queued Task
- class qop.tasks.QueueProgress(pending: int, ok: int, skip: int, fail: int, active: int)
Bases:
object
Info on the current status of the Queue
- property total
- static from_dict(x: Dict) QueueProgress
- static from_list(x: List) QueueProgress
Convert a list (for example as returned by an SQL SELECT statement) to a QueueProgress object
- to_dict() Dict
- fmt_summary()
- qop.tasks.hammer_commit(con, max_tries=10)
- exception qop.tasks.UnknownTaskTypeError
Bases:
ValueError