From 513f5d4bd30c475232d2182d2de0369079d90a66 Mon Sep 17 00:00:00 2001 From: mmenanno <1358708+mmenanno@users.noreply.github.com> Date: Sun, 16 Jun 2024 02:18:22 -0400 Subject: [PATCH] [mkvpropedit] 0.0.2 --- source/mkvpropedit/.gitignore | 4 + source/mkvpropedit/changelog.md | 3 + source/mkvpropedit/description.md | 25 +++++ source/mkvpropedit/info.json | 15 +++ source/mkvpropedit/plugin.py | 144 ++++++++++++++++++++++++++++ source/mkvpropedit/requirements.txt | 0 6 files changed, 191 insertions(+) create mode 100644 source/mkvpropedit/.gitignore create mode 100644 source/mkvpropedit/changelog.md create mode 100644 source/mkvpropedit/description.md create mode 100644 source/mkvpropedit/info.json create mode 100644 source/mkvpropedit/plugin.py create mode 100644 source/mkvpropedit/requirements.txt diff --git a/source/mkvpropedit/.gitignore b/source/mkvpropedit/.gitignore new file mode 100644 index 000000000..499ca09c3 --- /dev/null +++ b/source/mkvpropedit/.gitignore @@ -0,0 +1,4 @@ +**/__pycache__ +*.py[cod] +**/site-packages +settings.json diff --git a/source/mkvpropedit/changelog.md b/source/mkvpropedit/changelog.md new file mode 100644 index 000000000..40527a93c --- /dev/null +++ b/source/mkvpropedit/changelog.md @@ -0,0 +1,3 @@ + +**0.0.1** +- Initial version diff --git a/source/mkvpropedit/description.md b/source/mkvpropedit/description.md new file mode 100644 index 000000000..7d4f614ce --- /dev/null +++ b/source/mkvpropedit/description.md @@ -0,0 +1,25 @@ +The plugin allows you to run mkvpropedit on a file. + +There are some pre-build arguments that you can turn on with a checkbox like: + +- Add Track Statistics Tags: This adds `--add-track-statistics-tags` to your arguments +- Remove Title Tag: This adds `-d title` to your arguments +- Add Encode Source To Global Tags: This takes the original file name passed into unmanic, and adds it as a global tag to the mkv file + +Anything not built in can be added to the Other Arguments section. + +--- + +#### Important Note + +You must make sure that mkvpropedit is installed and available in the PATH so that this plugin can use it. To do that you can do something like this: + +1. reate a file inside the container `/config/startup.sh` +2. Inside this file append the following contents: + +```sh +#!/bin/bash + +/usr/bin/apt-get update ; +/usr/bin/apt-get install -y mkvtoolnix +``` diff --git a/source/mkvpropedit/info.json b/source/mkvpropedit/info.json new file mode 100644 index 000000000..af48b751b --- /dev/null +++ b/source/mkvpropedit/info.json @@ -0,0 +1,15 @@ +{ + "author": "halorrr", + "compatibility": [ + 2 + ], + "description": "Run MKVPropEdit on a file", + "icon": "https://upload.wikimedia.org/wikipedia/commons/2/21/Mkvmerge256.png", + "id": "mkvpropedit", + "name": "MKVPropEdit", + "priorities": { + "on_worker_process": 0 + }, + "tags": ["command", "mkv", "tweaks"], + "version": "0.0.2" +} diff --git a/source/mkvpropedit/plugin.py b/source/mkvpropedit/plugin.py new file mode 100644 index 000000000..d4a886117 --- /dev/null +++ b/source/mkvpropedit/plugin.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import logging +import os +import subprocess +import xml.etree.cElementTree as ET + +from unmanic.libs.unplugins.settings import PluginSettings + +# Configure plugin logger +logger = logging.getLogger("Unmanic.Plugin.mkvpropedit") + + +class Settings(PluginSettings): + settings = { + "add_track_statistics_tags": True, + "add_encode_source_to_global_tags": False, + "remove_title_tag": False, + "other_args": "" + } + + def __init__(self, *args, **kwargs): + super(Settings, self).__init__(*args, **kwargs) + self.form_settings = { + "add_track_statistics_tags": { + "label": "Add Track Statistics Tags", + }, + "add_encode_source_to_global_tags": { + "label": "Add Encode Source To Global Tags", + }, + "remove_title_tag": { + "label": "Remove Title Tag", + }, + "other_args": { + "label": "Other Arguments", + }, + } + + +def on_worker_process(data): + """ + Runner function - enables additional configured processing jobs during the worker stages of a task. + + The 'data' object argument includes: + worker_log - Array, the log lines that are being tailed by the frontend. Can be left empty. + library_id - Number, the library that the current task is associated with. + exec_command - Array, a subprocess command that Unmanic should execute. Can be empty. + command_progress_parser - Function, a function that Unmanic can use to parse the STDOUT of the command to collect progress stats. Can be empty. + file_in - String, the source file to be processed by the command. + file_out - String, the destination that the command should output (may be the same as the file_in if necessary). + original_file_path - String, the absolute path to the original file. + repeat - Boolean, should this runner be executed again once completed with the same variables. + + :param data: + :return: + + """ + # Get required settings and filenames + settings = Settings(library_id=data.get('library_id')) + original_filename = os.path.basename(data.get('original_file_path')) + tags_filename = os.path.splitext(data.get('file_in'))[0] + '_tags.xml' + add_track_statistics_tags = settings.get_setting('add_track_statistics_tags') + remove_title_tag = settings.get_setting('remove_title_tag') + add_encode_source_to_global_tags = settings.get_setting('add_encode_source_to_global_tags') + other_args = settings.get_setting('other_args') + + def is_mkv_file(): + # Check if the filename ends with '.mkv' (case-insensitive) + return original_filename.lower().endswith('.mkv') + + def is_mkvpropedit_installed(): + try: + # Run the command 'mkvpropedit --version' and capture the output + result = subprocess.run(['mkvpropedit', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + + # Check if the command was successful + if result.returncode == 0: + logger.debug(result.stdout) # Print the version information + return True + + logger.error("mkvpropedit is not installed or not available in the PATH.") + logger.error(result.stderr) # Print the error message + return False + except FileNotFoundError: + logger.error("mkvpropedit is not installed or not available in the PATH.") + return False + + def create_xml_tags_file(): + # Building an XML file structured like this to use for global tag creation: + # + # + # + # Encode source + # Very.Fake.Movie.2020.REMUX.1080p.Blu-ray.AVC.DTS-HD.MA.5.1-Group + # + # + # + xml_tags = ET.Element("Tags") + xml_tag = ET.SubElement(xml_tags, "Tag") + xml_simple = ET.SubElement(xml_tag, "Simple") + ET.SubElement(xml_simple, "Name").text = "Encode source" + ET.SubElement(xml_simple, "String").text = original_filename + + tree = ET.ElementTree(xml_tags) + logger.debug(f'Creating file for global tag creation: {tags_filename}') + tree.write(tags_filename) + + def process_file(): + # Start off with calling mkvpropedit + command = ['mkvpropedit'] + + # Assemble args + if add_track_statistics_tags: + command.append('--add-track-statistics-tags') + if remove_title_tag: + command.extend(['-d', 'title']) + if add_encode_source_to_global_tags: + create_xml_tags_file() + command.extend(['--tags', f'global:{tags_filename}']) + if other_args: + command.extend(other_args.split()) + + # Pass in working file name + command.append(data.get('file_in')) + + # Execute the command + if command == ['mkvpropedit', data.get('file_in')]: + logger.error("No arguments provided for mkvpropedit, skipping...") + return + + data['exec_command'] = command + + if not is_mkv_file(): + logger.info("File is not an mkv file, skipping mkvpropedit...") + elif not is_mkvpropedit_installed(): + logger.error("Please install mkvpropedit to proceed.") + else: + process_file() + + # mkvpropedit doesn't output to a new file, so pass on the same file we started with + data['file_out'] = data.get('file_in') + + return data diff --git a/source/mkvpropedit/requirements.txt b/source/mkvpropedit/requirements.txt new file mode 100644 index 000000000..e69de29bb