Skip to main content

Introduction to Writing Plugins

Writing Plugins for Unmanic should be easy.

All that is required to get started is a basic knowledge of writing Python scripts.

Directory Structure

The basic directory structure of a Plugin should be:

my_new_plugin
├── changelog.md
├── description.md
├── info.json
├── lib
├── package.json
├── plugin.py
├── requirements.txt
└── static

File: changelog.md

This file should be used to record changes made to the Plugin.


File: description.json (optional)

This file can be used to extend the description provided within the info.json file.


File: info.json

A JSON file containing the metadata of your Plugin. This JSON file should contain the following data:

  • author - Your name.
  • compatibility - A list of Unmanic Plugin Handler versions that this Plugin is compatible with (see table below).
  • description - A long description of your Plugin detailing what it does. To include line-breaks, insert a \n.
  • icon - A URI to an image. If no icon is provided, the default Plugin icon will be used in the WebUI.
  • id - A string identifier for your Plugin. Should only contain lowercase a-z or _ characters.
  • name - A very short name for your Plugin.
  • platform - Platform compatibility of this plugin. Can be any combination of ["all", "linux", "windows", "mac"].
  • priorities - A dictionary of the initial priority that this Plugin's runners within the Plugin flow.
  • tags - A comma separated list able to be used as keywords when searching for Plugins.
  • version - The version of your Plugin.
Example:
{
"author": "Josh.5",
"compatibility": [
1,
2
],
"description": "Specify a language tag for Unmanic to try and put as 1st subtitle track.",
"icon": "https://raw.githubusercontent.com/Josh5/unmanic.plugin.reorder_subtitle_streams_by_language/master/icon.png",
"id": "reorder_subtitle_streams_by_language",
"name": "Re-order subtitle streams by language",
"platform": [
"all"
],
"priorities": {
"on_library_management_file_test": 99,
"on_worker_process": 2
},
"tags": "subtitle,ffmpeg,library file test",
"version": "1.0.4"
}
Plugin handler compatibility:
Plugin handlerUnmanic versions
v1v0.1.0 - v0.1.4
v2v0.2.0 - current

Directory: lib (optional)

Location of any additional Python modules imported by this plugin. Use this directory if you are including files from another project on GitHub, etc.


File: package.json (optional)

This file will be read during the plugin build in GitHub. Any nodeJS packages listed will be installed and packaged with the plugin.

Python modules will be installed to {plugin root}/node_modules.


File: plugin.py

The main Pugin Python module.

This file will be imported and it's functions called by the main Unmanic process.


File: requirements.txt (optional)

This file will be read during the plugin build in GitHub. Any Python modules listed will be installed and packaged with the plugin.

Python modules will be installed to {plugin root}/site-packages.


Directory: static (optional)

Location of any static assets to be served via the webserver.

Assets located in this directory will be available via the webserver at /unmanic/panel/{plugin ID}/static/(.*).

Plugin Module

The plugin.py file is a stand-alone Python module. From this module you may import other modules as you see fit. There is no limitation on what may be executed within the runner of your Plugin.


Runners

The Plugin module is made up of defined runner functions. A Plugin may include multiple runner functions such that it is executed at multiple stages of the library optimisation process.

A data parameter is provided to the runner functions. This data parameter is a dictionary object of information pertaining to that stage of the library optimisation process. This data object's schema that is provided to a plugin runner should still exist once the plugin runner function has completed execution. During the function, that data may be manipulated as you see fit. A plugin runner may fail if data is removed from that data dictionary.

Plugins should be tested with the Plugin Manager CLI before publishing changes to ensure that the returned data matches the required schema for all included runner functions.

Example:
def on_worker_process(data):
...
return
Runner TypeDocumentation
on_library_management_file_testLINK
on_worker_processLINK
on_postprocessor_file_movementLINK
on_postprocessor_task_resultsLINK
render_frontend_panelLINK
render_plugin_apiLINK