├── .dockerignore ├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── integration_test_and_build_all_packages_ci.yml │ └── python_lint_and_run_unit_tests.yml ├── .gitignore ├── .gitmodules ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── dataSources.local.xml ├── dataSources.xml ├── dictionaries │ └── josh5.xml ├── fileTemplates │ └── internal │ │ ├── Python Script.py │ │ └── Python Unit Test.py ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── misc.xml ├── modules.xml ├── runConfigurations │ ├── Docker_Compose.xml │ ├── Run_Unmanic.xml │ └── Run_Unmanic_Dev.xml ├── unmanic.iml └── vcs.xml ├── .python-version ├── LICENSE ├── MANIFEST.in ├── README.md ├── devops ├── ffmpeg_comand.sh ├── frontend_install.sh ├── gitlab-runner.sh ├── local_dev_venv.sh ├── migrations.sh ├── remove_cached_files.sh ├── run_docker.sh ├── tail_dev_logs.sh └── update-docker-packages.sh ├── docker ├── Dockerfile ├── README.md ├── docker-compose-cifs.yml ├── docker-compose-nvidia.yml ├── docker-compose-test.yml ├── docker-compose-vaapi.yml └── root │ ├── .grc.conf.unmanic.logs │ ├── etc │ ├── cont-init.d │ │ ├── 20-config │ │ ├── 30-patch-nvidia │ │ └── 60-custom-setup-script │ └── services.d │ │ └── unmanic │ │ └── run │ └── usr │ └── bin │ ├── unmanic │ └── unmanic-tail-logs ├── docs ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DEVELOPING.md ├── GENERATING_MASTER_RELEASE.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── images │ ├── unmanic-dashboard-processing-anime.png │ ├── unmanic-file-size-data-panel-anime.png │ └── unmanic-list-installed-plugins.png ├── icon.png ├── logo-white_font.png ├── logo.png ├── pytest.ini ├── requirements-dev.txt ├── requirements.txt ├── setup.cfg ├── setup.py ├── tests ├── README.md ├── __init__.py ├── conftest.py ├── integration │ ├── __init__.py │ └── test_taskhandler.py ├── scripts_ │ ├── download_test_files.sh │ ├── library_scan.sh │ ├── run_py_tests.sh │ └── setup_tests.sh ├── support_ │ ├── __init__.py │ └── test_data │ │ ├── __init__.py │ │ ├── data_queues.py │ │ ├── ffprobe_mkv.py │ │ ├── ffprobe_mp4.py │ │ └── mock_jobqueue_class.py └── unit │ ├── __init__.py │ └── test_unlogger.py ├── unmanic ├── __init__.py ├── __main__.py ├── config.py ├── libs │ ├── __init__.py │ ├── common.py │ ├── db_migrate.py │ ├── directoryinfo.py │ ├── eventmonitor.py │ ├── fileinfo.py │ ├── filetest.py │ ├── foreman.py │ ├── history.py │ ├── installation_link.py │ ├── library.py │ ├── libraryscanner.py │ ├── notifications.py │ ├── plugins.py │ ├── postprocessor.py │ ├── scheduler.py │ ├── session.py │ ├── singleton.py │ ├── system.py │ ├── task.py │ ├── taskhandler.py │ ├── taskqueue.py │ ├── uiserver.py │ ├── unffmpeg │ │ ├── __init__.py │ │ ├── audio_codec_handle.py │ │ ├── audio_codecs │ │ │ ├── __init__.py │ │ │ ├── aac.py │ │ │ ├── ac3.py │ │ │ └── mp3.py │ │ ├── base_codecs.py │ │ ├── base_containers.py │ │ ├── containers │ │ │ ├── __init__.py │ │ │ ├── avi.py │ │ │ ├── flv.py │ │ │ ├── matroska.py │ │ │ ├── mov.py │ │ │ ├── mp4.py │ │ │ ├── mpeg.py │ │ │ ├── mpegts.py │ │ │ ├── ogv.py │ │ │ ├── psp.py │ │ │ └── vob.py │ │ ├── exceptions │ │ │ ├── __init__.py │ │ │ ├── ffmpeg.py │ │ │ └── ffprobe.py │ │ ├── hardware_acceleration_handle.py │ │ ├── info.py │ │ ├── lib │ │ │ ├── __init__.py │ │ │ ├── cli.py │ │ │ └── validation.py │ │ ├── subtitle_codecs │ │ │ ├── __init__.py │ │ │ ├── ass.py │ │ │ ├── mov_text.py │ │ │ ├── srt.py │ │ │ ├── ssa.py │ │ │ ├── subrip.py │ │ │ └── xsub.py │ │ ├── subtitle_handle.py │ │ ├── video_codec_handle.py │ │ └── video_codecs │ │ │ ├── __init__.py │ │ │ ├── h264.py │ │ │ └── hevc.py │ ├── unlogger.py │ ├── unmodels │ │ ├── __init__.py │ │ ├── completedtasks.py │ │ ├── completedtaskscommandlogs.py │ │ ├── enabledplugins.py │ │ ├── installation.py │ │ ├── lib │ │ │ ├── __init__.py │ │ │ └── basemodel.py │ │ ├── libraries.py │ │ ├── librarypluginflow.py │ │ ├── pluginrepos.py │ │ ├── plugins.py │ │ ├── tags.py │ │ ├── tasks.py │ │ ├── workergroups.py │ │ └── workerschedules.py │ ├── unplugins │ │ ├── __init__.py │ │ ├── executor.py │ │ ├── plugin_types │ │ │ ├── __init__.py │ │ │ ├── frontend │ │ │ │ ├── __init__.py │ │ │ │ ├── panel.py │ │ │ │ └── plugin_api.py │ │ │ ├── library_management │ │ │ │ ├── __init__.py │ │ │ │ └── file_test.py │ │ │ ├── plugin_type_base.py │ │ │ ├── postprocessor │ │ │ │ ├── __init__.py │ │ │ │ ├── file_move.py │ │ │ │ └── task_result.py │ │ │ └── worker │ │ │ │ ├── __init__.py │ │ │ │ └── process_item.py │ │ ├── pluginscli.py │ │ └── settings.py │ ├── worker_group.py │ └── workers.py ├── metadata.py ├── migrations_v1 │ ├── 001_rename_ffmpeg_log_to_log.py │ └── README.md ├── service.py ├── version └── webserver │ ├── .gitignore │ ├── __init__.py │ ├── api_request_router.py │ ├── api_v1 │ ├── __init__.py │ ├── base_api_handler.py │ ├── filebrowser_api.py │ ├── history_api.py │ ├── pending_api.py │ ├── plugins_api.py │ └── session_api.py │ ├── api_v2 │ ├── README.md │ ├── __init__.py │ ├── base_api_handler.py │ ├── docs_api.py │ ├── filebrowser_api.py │ ├── history_api.py │ ├── notifications_api.py │ ├── pending_api.py │ ├── plugins_api.py │ ├── schema │ │ ├── __init__.py │ │ ├── schemas.py │ │ ├── swagger.py │ │ └── unmanic.py │ ├── session_api.py │ ├── settings_api.py │ ├── upload_api.py │ ├── version_api.py │ └── workers_api.py │ ├── docs │ ├── api_schema_v2.json │ ├── api_schema_v2.yaml │ └── privacy_policy.md │ ├── downloads.py │ ├── helpers │ ├── __init__.py │ ├── completed_tasks.py │ ├── documents.py │ ├── filebrowser.py │ ├── pending_tasks.py │ ├── plugins.py │ ├── settings.py │ └── workers.py │ ├── main.py │ ├── package-lock.json │ ├── package.json │ ├── plugins.py │ ├── templates │ └── global │ │ ├── insufficient-permissions.html │ │ ├── login-popup.html │ │ └── support-future-development.html │ └── websocket.py └── versioninfo.py /.dockerignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | **/__pycache__ 3 | .git 4 | .gitignore 5 | .github 6 | .gitattributes 7 | README.md 8 | 9 | 10 | dev_environment 11 | config 12 | cache 13 | library 14 | tests 15 | venv 16 | videos 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = false 9 | max_line_length = 127 10 | 11 | [*.{yml,yaml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Josh5 4 | patreon: Josh5 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: josh5coffee 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/python_lint_and_run_unit_tests.yml: -------------------------------------------------------------------------------- 1 | name: Python Lint & Run Unit Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | branches: 9 | - 'master' 10 | - 'staging' 11 | 12 | jobs: 13 | py_lint_and_unit_test: 14 | 15 | name: Lint & Run Unit Tests Using Python 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | # Setup python environment 25 | - name: Set up Python ${{ matrix.python-version }} 26 | uses: actions/setup-python@v5 27 | with: 28 | python-version: ${{ matrix.python-version }} 29 | 30 | # Restore the python cache if it exists 31 | - name: Restore python cache 32 | uses: actions/cache@v4 33 | with: 34 | path: ~/.cache/pip 35 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 36 | restore-keys: | 37 | ${{ runner.os }}-pip- 38 | 39 | # Install dependencies for testing unmanic 40 | - name: Install dependencies 41 | run: | 42 | python -m pip install --upgrade pip 43 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 44 | if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi 45 | 46 | # Run flake8 formatting checks 47 | - name: Lint with flake8 48 | run: | 49 | # stop the build if there are Python syntax errors or undefined names 50 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 51 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 52 | flake8 . --count --exit-zero --max-line-length=127 --statistics 53 | 54 | # Run pytest unit tests 55 | - name: Test with pytest 56 | run: | 57 | pytest -m unittest 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE configs 2 | .vscode 3 | **/__pycache__ 4 | .idea/workspace.xml 5 | 6 | # Files used for testing 7 | dev_environment/** 8 | tests/support_/videos/* 9 | tests/tmp/* 10 | tests/.vstats_file 11 | 12 | # Files needed for development only 13 | venv/** 14 | 15 | # Files created during the build process 16 | .eggs/** 17 | build/** 18 | dist/** 19 | unmanic.egg-info/** 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "unmanic/webserver/frontend"] 2 | path = unmanic/webserver/frontend 3 | url = https://github.com/Unmanic/unmanic-frontend.git 4 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dataSources.local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | " 7 | 8 | 9 | master_key 10 | no-auth 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sqlite.xerial 6 | true 7 | org.sqlite.JDBC 8 | jdbc:sqlite:$PROJECT_DIR$/dev_environment/.unmanic/config/unmanic.db 9 | $ProjectFileDir$ 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/dictionaries/josh5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bitrate 5 | dirname 6 | ffmpeg 7 | ffprobe 8 | firstrun 9 | inotify 10 | inotifytasks 11 | loglevel 12 | matroska 13 | migrator 14 | mpeg 15 | mpegts 16 | scheduledtasks 17 | sunnex 18 | transcode 19 | transcoding 20 | uiserver 21 | unffmpeg 22 | unmanic 23 | vencoder 24 | webserver 25 | 26 | 27 | -------------------------------------------------------------------------------- /.idea/fileTemplates/internal/Python Script.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | ${PROJECT_NAME}.${FILE_NAME} 6 | 7 | Written by: Josh.5 8 | Date: ${DAY} ${MONTH_NAME_SHORT} ${YEAR}, (${TIME}) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /.idea/fileTemplates/internal/Python Unit Test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | ${PROJECT_NAME}.${FILE_NAME} 6 | 7 | Written by: Josh.5 8 | Date: ${DAY} ${MONTH_NAME_SHORT} ${YEAR}, (${TIME}) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import pytest 33 | 34 | 35 | class TestClass(object): 36 | """ 37 | TestClass 38 | 39 | """ 40 | 41 | def setup_class(self): 42 | """ 43 | Setup any state specific to the execution of the given class 44 | (which usually contains tests). 45 | 46 | :return: 47 | """ 48 | pass 49 | 50 | def teardown_class(self): 51 | """ 52 | Teardown any state that was previously setup with a call to 53 | setup_class. 54 | 55 | :return: 56 | """ 57 | pass 58 | 59 | def setup_method(self): 60 | """ 61 | Setup any state tied to the execution of the given method in a 62 | class. 63 | setup_method is invoked for every test method of a class. 64 | 65 | :return: 66 | """ 67 | pass 68 | 69 | def teardown_method(self): 70 | """ 71 | Teardown any state that was previously setup with a setup_method 72 | call. 73 | 74 | :return: 75 | """ 76 | pass 77 | 78 | @pytest.mark.unittest 79 | def test_something(self): 80 | assert ('condition' == 'expected') 81 | 82 | 83 | if __name__ == '__main__': 84 | pytest.main(['-s', '--log-cli-level=INFO', __file__]) 85 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/.idea/jsLibraryMappings.xml -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Docker_Compose.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Run_Unmanic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 27 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Run_Unmanic_Dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 26 | -------------------------------------------------------------------------------- /.idea/unmanic.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 21 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.10 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Include docs 2 | include README.md 3 | include LICENSE 4 | # Include some images 5 | include logo.png 6 | # Include requirements files 7 | include requirements.txt 8 | include requirements-dev.txt 9 | 10 | # Include module files 11 | recursive-include unmanic ** 12 | include versioninfo.py 13 | 14 | # Exclude compiled files 15 | global-exclude *.py[cod] 16 | 17 | # Exclude frontend development files 18 | recursive-exclude unmanic/webserver/frontend **/*.git* 19 | recursive-exclude unmanic/webserver/frontend **/dist/** 20 | recursive-exclude unmanic/webserver/frontend **/node_modules/** 21 | recursive-exclude unmanic/webserver/frontend **/.quasar/** 22 | # Exclude cordova related directories and files 23 | recursive-exclude unmanic/webserver/frontend **/src-cordova/node_modules/** 24 | recursive-exclude unmanic/webserver/frontend **/src-cordova/platforms/** 25 | recursive-exclude unmanic/webserver/frontend **/src-cordova/plugins/** 26 | recursive-exclude unmanic/webserver/frontend **/src-cordova/www/** 27 | # Exclude capacitor related directories and files 28 | recursive-exclude unmanic/webserver/frontend **/src-capacitor/www/** 29 | recursive-exclude unmanic/webserver/frontend **/src-capacitor/node_modules/** 30 | # Exclude BEX related directories and files 31 | recursive-exclude unmanic/webserver/frontend **/src-bex/www/** 32 | recursive-exclude unmanic/webserver/frontend **/src-bex/js/core/** 33 | # Exclude any log files 34 | recursive-exclude unmanic/webserver/frontend **/npm-debug.log* 35 | recursive-exclude unmanic/webserver/frontend **/yarn-debug.log* 36 | recursive-exclude unmanic/webserver/frontend **/yarn-error.log* 37 | # Exclude editor directories and files 38 | recursive-exclude unmanic/webserver/frontend **/*.suo 39 | recursive-exclude unmanic/webserver/frontend **/*.ntvs* 40 | recursive-exclude unmanic/webserver/frontend **/*.njsproj 41 | recursive-exclude unmanic/webserver/frontend **/*.sln 42 | recursive-exclude unmanic/webserver/frontend **/.idea/** 43 | # Exclude tests 44 | recursive-exclude tests ** 45 | # Exclude virtual env 46 | recursive-exclude venv ** 47 | 48 | # Remove all frontend compiled assets 49 | prune unmanic/webserver/public 50 | -------------------------------------------------------------------------------- /devops/ffmpeg_comand.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | SCRIPT_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ); 4 | OUT_DIR=${SCRIPT_PATH}/../tests/tmp/ffmpeg_tests; 5 | IN_FILE=${SCRIPT_PATH}/../tests/support_/videos/med/big_buck_bunny_720p_10mb.mp4; 6 | 7 | # Set the container 8 | CONTAINER_EXT="mkv" 9 | # Select video encoder: 10 | # - libx265 11 | # - hevc_nvenc 12 | # - h264_nvenc 13 | # - h264_vaapi 14 | # - hevc_vaapi 15 | V_ENCODER="hevc_vaapi" 16 | # Additional encoder args 17 | # EG: 18 | # -b:v 5M 19 | # -b:v 1M -maxrate 2M -bufsize 4M -preset slow 20 | # -vf 'format=nv12|vaapi,hwupload' 21 | V_ENCODER_ARGS="-b:v 4M -vaapi_device /dev/dri/renderD128 -vf 'format=nv12|vaapi,hwupload' " 22 | 23 | 24 | 25 | if [[ ! -z ${1} && "${1}" == "probe" ]]; then 26 | # Prove file first 27 | CMD="ffprobe \ 28 | -loglevel quiet \ 29 | -print_format json \ 30 | -show_format \ 31 | -show_streams \ 32 | -show_error \ 33 | ${IN_FILE}" 34 | 35 | echo "${CMD}" 36 | bash -c "${CMD}" 37 | elif [[ ! -z ${1} && "${1}" == "encoders" ]]; then 38 | # List encoders 39 | CMD="ffmpeg \ 40 | -loglevel quiet \ 41 | -encoders" 42 | 43 | echo "${CMD}" 44 | bash -c "${CMD}" 45 | else 46 | mkdir -p ${OUT_DIR} 47 | CMD="ffmpeg \ 48 | -loglevel info \ 49 | -i ${IN_FILE} \ 50 | ${V_ENCODER_ARGS} \ 51 | -c:v ${V_ENCODER} \ 52 | -c:a copy \ 53 | -y ${OUT_DIR}/outfile.${CONTAINER_EXT}" 54 | 55 | start_time=`date +%s` 56 | echo "${CMD}" 57 | bash -c "${CMD}" 58 | end_time=`date +%s` 59 | 60 | echo 61 | echo 62 | echo "Task took $((end_time-start_time)) seconds" 63 | echo 64 | echo "Input file:" 65 | du -h ${IN_FILE} 66 | echo 67 | echo "Output file:" 68 | du -h ${OUT_DIR}/*.${CONTAINER_EXT} 69 | echo 70 | fi 71 | 72 | # ls -la "${OUT_DIR}" 73 | # echo "${OUT_DIR}" 74 | -------------------------------------------------------------------------------- /devops/frontend_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- coding: utf-8 -*- 3 | ################################################################################################### 4 | # 5 | # Written by: Josh.5 6 | # Date: Thu Jul 03 2021, (18:39:00 PM) 7 | # 8 | # Copyright: 9 | # Copyright (C) Josh Sunnex - All Rights Reserved 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy 12 | # of this software and associated documentation files (the "Software"), to deal 13 | # in the Software without restriction, including without limitation the rights 14 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | # copies of the Software, and to permit persons to whom the Software is 16 | # furnished to do so, subject to the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be included in all 19 | # copies or substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 25 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 26 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 27 | # OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # 30 | ################################################################################################### 31 | 32 | project_root="$(readlink -e $(dirname $(readlink -e ${BASH_SOURCE[0]}))/../)" 33 | 34 | # Build backage 35 | pushd "${project_root}/unmanic/webserver/frontend" &> /dev/null 36 | npm install 37 | npm run build 38 | popd &> /dev/null 39 | 40 | # Copy dist package backage 41 | pushd "${project_root}/unmanic/webserver" &> /dev/null 42 | if [ ! -d "${project_root}/unmanic/webserver/frontend/dist/spa" ]; then 43 | echo "Cannot find built dist package for the frontend. Something must have gone wrong. Exit" 44 | exit 1 45 | fi 46 | rm -rf "${project_root}/unmanic/webserver/public" 47 | mv -v "${project_root}/unmanic/webserver/frontend/dist/spa" "${project_root}/unmanic/webserver/public" 48 | popd &> /dev/null 49 | -------------------------------------------------------------------------------- /devops/gitlab-runner.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # install gitlab-runner with `brew install gitlab-runner` 4 | 5 | CMD="gitlab-runner exec docker \ 6 | --docker-volumes /tmp/gitlab-runner/dist:/dist \ 7 | --docker-volumes /tmp/gitlab-runner/builds:/builds:rw \ 8 | --docker-volumes /tmp/gitlab-runner/cache:/cache:rw \ 9 | ${@}" 10 | 11 | echo "${CMD}" 12 | bash -c "${CMD}" 13 | 14 | -------------------------------------------------------------------------------- /devops/local_dev_venv.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ### 3 | # File: local_dev_denv.sh 4 | # Project: devops 5 | # File Created: Tuesday, 17th May 2022 6:55:32 pm 6 | # Author: Josh.5 (jsunnex@gmail.com) 7 | # ----- 8 | # Last Modified: Tuesday, 17th May 2022 8:05:25 pm 9 | # Modified By: Josh.5 (jsunnex@gmail.com) 10 | ### 11 | # 12 | # After running this script you can run unmanic with the following commands: 13 | # 14 | # source venv/bin/activate 15 | # export HOME_DIR="${PWD}/dev_environment" 16 | # unmanic 17 | # 18 | 19 | script_path=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 20 | project_root=$(readlink -e ${script_path}/..) 21 | 22 | pushd "${project_root}" || exit 1 23 | 24 | # Checkout all submodules 25 | git submodule update --init --recursive 26 | 27 | # Ensure we have created a venv 28 | if [[ ! -e venv/bin/activate ]]; then 29 | python3 -m venv venv 30 | fi 31 | 32 | # Active the venv 33 | source venv/bin/activate 34 | 35 | # Install all Unmanic requirements 36 | python3 -m pip install -r requirements.txt 37 | python3 -m pip install -r requirements-dev.txt 38 | 39 | # Install the project to the venv 40 | devops/frontend_install.sh 41 | python3 setup.py develop 42 | 43 | popd || exit 1 44 | -------------------------------------------------------------------------------- /devops/migrations.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; 4 | 5 | if [[ ! -x $(command -v pw_migrate) ]]; then 6 | echo "Missing dependency 'pw_migrate'."; 7 | echo "Ensure requirements.txt is satisfied first."; 8 | echo 9 | echo "Run:"; 10 | echo "python3 -m pip install --user --upgrade -r $(realpath ${SCRIPT_DIR}/../requirements.txt)"; 11 | echo 12 | exit 1; 13 | fi 14 | 15 | DATABASE_FILE=$(realpath "${HOME}/.unmanic/config/unmanic.db"); 16 | TEST_DATABASE_FILE=$(realpath "${SCRIPT_DIR}/../tests/tmp/config/.unmanic/config/unmanic.db"); 17 | if [[ -f ${TEST_DATABASE_FILE} ]]; then 18 | DATABASE_FILE=${TEST_DATABASE_FILE} 19 | fi 20 | MIGRATIONS_PATH=$(realpath "${SCRIPT_DIR}/../unmanic/migrations"); 21 | NAME=$(echo ${@} | awk '{print tolower($0)}' | tr ' ' '_'); 22 | 23 | 24 | # Parse args 25 | ARGS="--database=sqlite:///${DATABASE_FILE} --directory=${MIGRATIONS_PATH}" 26 | COMMAND="" 27 | for ARG in ${@}; do 28 | if [[ "${ARG}" == "--help" || "${ARG}" == "-h" ]]; then 29 | pw_migrate --help; 30 | echo 31 | exit 0; 32 | elif [[ "${ARG}" == "create" ]]; then 33 | COMMAND="create"; 34 | continue; 35 | elif [[ "${ARG}" == "list" ]]; then 36 | COMMAND="list"; 37 | continue; 38 | elif [[ "${ARG}" == "merge" ]]; then 39 | COMMAND="merge"; 40 | continue; 41 | elif [[ "${ARG}" == "migrate" || "${ARG}" == "run" ]]; then 42 | COMMAND="migrate"; 43 | continue; 44 | elif [[ "${ARG}" == "rollback" ]]; then 45 | COMMAND="rollback"; 46 | continue; 47 | fi 48 | ARGS="${ARGS} ${ARG}"; 49 | done 50 | 51 | echo "pw_migrate ${COMMAND} ${ARGS}"; 52 | pw_migrate ${COMMAND} ${ARGS}; 53 | -------------------------------------------------------------------------------- /devops/remove_cached_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- coding: utf-8 -*- 3 | ################################################################################################### 4 | # 5 | # Written by: Josh.5 6 | # Date: Thu Mar 05 2021, (23:42:00 PM) 7 | # 8 | # Copyright: 9 | # Copyright (C) Josh Sunnex - All Rights Reserved 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy 12 | # of this software and associated documentation files (the "Software"), to deal 13 | # in the Software without restriction, including without limitation the rights 14 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | # copies of the Software, and to permit persons to whom the Software is 16 | # furnished to do so, subject to the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be included in all 19 | # copies or substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 25 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 26 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 27 | # OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # 30 | ################################################################################################### 31 | 32 | 33 | SCRIPT_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ); 34 | PROJECT_ROOT=$(realpath ${SCRIPT_PATH}/../) 35 | 36 | find ${PROJECT_ROOT}/ -type f -name "*.pyc" -exec bash -c " 37 | rm -fv {}; 38 | " \; 39 | 40 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Unmanic Docker Image 2 | 3 | 4 | ### Building the Source 5 | Before building the image, you need to have built the unmanic python package: 6 | ```bash 7 | rm -rfv ./build && rm -fv ./dist/unmanic-* 8 | git submodule update --init --recursive 9 | python3 -m build --no-isolation --skip-dependency-check --wheel 10 | python3 -m build --no-isolation --skip-dependency-check --sdist 11 | ``` 12 | 13 | 14 | ### Building the image 15 | Simply run this command from the root of the project: 16 | ```bash 17 | docker build -f ./docker/Dockerfile -t josh5/unmanic:latest . 18 | ``` -------------------------------------------------------------------------------- /docker/docker-compose-cifs.yml: -------------------------------------------------------------------------------- 1 | ################ 2 | # Test environment Docker Compose file 3 | # 4 | # Use this compose file when mounting a network drive as your library 5 | # 6 | # Variables that will need to be changed: 7 | # - User id for folder/file permissions 8 | # - Group id for folder/file permissions 9 | # - Path where unmanic will store config files 10 | # - Cache path for in-progress encoding tasks 11 | # - Remote IP address of CIFS mount 12 | # - Path in remote machine to be mounted as your library 13 | # - Remote mount username 14 | # - Remote mount password 15 | # 16 | 17 | 18 | version: '1' 19 | 20 | services: 21 | unmanic: 22 | container_name: unmanic 23 | image: josh5/unmanic:latest 24 | ports: 25 | - 8888:8888 26 | environment: 27 | - PUID= 28 | - PGID= 29 | volumes: 30 | - :/config 31 | - cifs_mount:/library 32 | - :/tmp/unmanic 33 | 34 | volumes: 35 | cifs_mount: 36 | driver: local 37 | driver_opts: 38 | type: cifs 39 | device: /// 40 | o: "username=,password=,vers=3.0,uid=,gid=" 41 | -------------------------------------------------------------------------------- /docker/docker-compose-nvidia.yml: -------------------------------------------------------------------------------- 1 | ################ 2 | # Unmanic Docker Compose template 3 | # 4 | # Use this template when enabling NVENC Hardware accelerated encoding 5 | # 6 | # Variables that will need to be changed: 7 | # - User id for folder/file permissions 8 | # - Group id for folder/file permissions 9 | # - Your time zone, eg - Pacific/Auckland 10 | # - The GPUs that will be accessible to the container 11 | # Options: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/user-guide.html#gpu-enumeration 12 | # - Path where Unmanic will store config files 13 | # - Path where you store the files that Unmanic will scan 14 | # - Cache path for in-progress encoding tasks 15 | # 16 | 17 | 18 | version: '2.4' 19 | 20 | services: 21 | unmanic: 22 | container_name: unmanic 23 | image: josh5/unmanic:latest 24 | ports: 25 | - 8888:8888 26 | environment: 27 | - PUID= 28 | - PGID= 29 | - TZ= 30 | - NVIDIA_VISIBLE_DEVICES= 31 | volumes: 32 | - :/config 33 | - :/library 34 | - :/tmp/unmanic 35 | runtime: nvidia # For H/W transcoding using the NVENC encoder 36 | -------------------------------------------------------------------------------- /docker/docker-compose-test.yml: -------------------------------------------------------------------------------- 1 | ################ 2 | # Test environment Docker Compose file 3 | # 4 | # This compose file is only good for automated testing. 5 | # 6 | # docker exec --workdir=/app unmanic-testenv pytest --log-cli-level=INFO 7 | # 8 | 9 | 10 | version: '2' 11 | 12 | services: 13 | unmanic-testenv: 14 | container_name: unmanic-testenv 15 | image: josh5/unmanic:latest 16 | ports: 17 | - 8888:8888 18 | environment: 19 | - PUID=1000 20 | - PGID=1000 21 | - DEBUGGING=false 22 | - USE_TEST_SUPPORT_API=false 23 | - NUMBER_OF_WORKERS=2 24 | - SCHEDULE_FULL_SCAN_MINUTES=10 25 | - RUN_FULL_SCAN_ON_START=false 26 | - TZ=Pacific/Auckland 27 | volumes: 28 | - ../tests/tmp/cache:/tmp/unmanic 29 | - ../tests/tmp/library:/library 30 | - ../tests:/app/tests 31 | - ../:/app 32 | # Uncomment for debugging of tests within the docker container 33 | # Note that some tests are setup to only succeed with a particular configuration 34 | # and modifying the configuration may cause tests to fail unexpectedly. 35 | # - ../tests/tmp/config:/config 36 | -------------------------------------------------------------------------------- /docker/docker-compose-vaapi.yml: -------------------------------------------------------------------------------- 1 | ################ 2 | # Unmanic Docker Compose template 3 | # 4 | # Use this template when enabling VAAPI Hardware accelerated encoding 5 | # 6 | # Variables that will need to be changed: 7 | # - User id for folder/file permissions 8 | # - Group id for folder/file permissions 9 | # - Your time zone, eg - Pacific/Auckland 10 | # - Path where Unmanic will store config files 11 | # - Path where you store the files that Unmanic will scan 12 | # - Cache path for in-progress encoding tasks 13 | # 14 | 15 | 16 | version: '2.4' 17 | 18 | services: 19 | unmanic: 20 | container_name: unmanic 21 | image: josh5/unmanic:latest 22 | ports: 23 | - 8888:8888 24 | environment: 25 | - PUID= 26 | - PGID= 27 | - TZ= 28 | volumes: 29 | - :/config 30 | - :/library 31 | - :/tmp/unmanic 32 | devices: 33 | - /dev/dri:/dev/dri # For H/W transcoding using the VAAPI encoder 34 | -------------------------------------------------------------------------------- /docker/root/.grc.conf.unmanic.logs: -------------------------------------------------------------------------------- 1 | # this configuration file is suitable for displaying unmanic logs 2 | # pipe logs to this file. 3 | # Eg. `tail -f ~/.unmanic/logs/*.log | grcat .grc.conf.unmanic.logs` 4 | 5 | 6 | # this is probably a pathname 7 | regexp=\/[\s\w.-]+ 8 | colours=bold green 9 | count=more 10 | ====== 11 | # Ignore GET requests from tornado's log 12 | regexp=[\d]+ GET /.*$ 13 | colours=none 14 | count=more 15 | ====== 16 | # Info Debug 17 | regexp=[\d(\-|T|\:)]+\:DEBUG:[\w(\.|\-)]+ 18 | colours=bold blue 19 | count=stop 20 | ====== 21 | # Info Logs 22 | regexp=[\d(\-|T|\:)]+\:INFO:[\w(\.|\-)]+ 23 | colours=bold cyan 24 | count=stop 25 | ====== 26 | # Warning Logs 27 | regexp=[\d(\-|T|\:)]+\:WARNING:[\w(\.|\-)]+ 28 | colours=bold yellow 29 | count=stop 30 | ====== 31 | # Error Logs 32 | regexp=[\d(\-|T|\:)]+\:ERROR:[\w(\.|\-)]+ 33 | colours=bold red 34 | count=stop 35 | ====== 36 | # Switch logfile 37 | regexp=[=]+[>].*[<][=]+ 38 | colours=bold magenta on_black 39 | count=stop 40 | ====== 41 | -------------------------------------------------------------------------------- /docker/root/etc/cont-init.d/20-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | PUID=${PUID:-911} 4 | PGID=${PGID:-911} 5 | 6 | set_uidgid() { 7 | echo "**** (permissions_config) Setting run user uid=${PGID}(abc) gid=${PUID}(abc) ****"; 8 | groupmod -o -g "${PGID}" abc 9 | usermod -o -u "${PUID}" abc 10 | } 11 | 12 | permissions_config() { 13 | echo "**** (permissions_config) Setting permissions ****"; 14 | mkdir -p \ 15 | /tmp/unmanic \ 16 | /config/.unmanic 17 | chown -R ${PUID}:${PGID} \ 18 | /tmp/unmanic \ 19 | /config/.unmanic \ 20 | /app 21 | chmod -R a+w \ 22 | /tmp/unmanic\ 23 | /config/.unmanic \ 24 | /app 25 | } 26 | 27 | set_permissions_for_hardware_video_group() { 28 | # Taken from https://github.com/linuxserver/docker-ffmpeg/blob/master/root/ffmpegwrapper.sh 29 | # This is required in order to run Unmanic as a non-root user and give it permission to 30 | # access the hardware decoders/encoders 31 | echo "**** (permissions_config) Adding run user to video group ****"; 32 | FILES=$(find /dev/dri -type c -print 2>/dev/null) 33 | for i in $FILES 34 | do 35 | VIDEO_GID=$(stat -c '%g' "$i") 36 | if id -G abc | grep -qw "$VIDEO_GID"; then 37 | touch /groupadd 38 | else 39 | if [ ! "${VIDEO_GID}" == '0' ]; then 40 | VIDEO_NAME=$(getent group "${VIDEO_GID}" | awk -F: '{print $1}') 41 | if [ -z "${VIDEO_NAME}" ]; then 42 | VIDEO_NAME="video$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c8)" 43 | groupadd "$VIDEO_NAME" 44 | groupmod -g "$VIDEO_GID" "$VIDEO_NAME" 45 | fi 46 | usermod -a -G "$VIDEO_NAME" abc 47 | touch /groupadd 48 | fi 49 | fi 50 | done 51 | if [ -n "${FILES}" ] && [ ! -f "/groupadd" ]; then 52 | usermod -a -G root abc 53 | fi 54 | } 55 | 56 | set_uidgid; 57 | permissions_config; 58 | set_permissions_for_hardware_video_group; 59 | -------------------------------------------------------------------------------- /docker/root/etc/cont-init.d/30-patch-nvidia: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | # Taken from: 3 | # https://github.com/keylase/nvidia-patch/blob/master/docker-entrypoint.sh 4 | # 5 | 6 | 7 | # Install NVIDIA Patch 8 | # REF: https://github.com/keylase/nvidia-patch#docker-support 9 | if [[ ! -z ${NVIDIA_PATCH_VERSION} ]]; then 10 | 11 | echo "**** (patch-nvidia) Fetch NVIDIA Patch ****"; 12 | curl -sSLf \ 13 | -o /usr/local/bin/patch.sh \ 14 | "https://raw.githubusercontent.com/keylase/nvidia-patch/${NVIDIA_PATCH_VERSION}/patch.sh" 15 | chmod +x /usr/local/bin/patch.sh 16 | 17 | echo "**** (patch-nvidia) Exec NVIDIA Patch ****"; 18 | echo "/patched-lib" > /etc/ld.so.conf.d/000-patched-lib.conf && \ 19 | mkdir -p "/patched-lib" && \ 20 | PATCH_OUTPUT_DIR=/patched-lib /usr/local/bin/patch.sh && \ 21 | cd /patched-lib && \ 22 | for f in * ; do 23 | suffix="${f##*.so}" 24 | name="$(basename "$f" "$suffix")" 25 | [ -h "$name" ] || ln -sf "$f" "$name" 26 | [ -h "$name" ] || ln -sf "$f" "$name.1" 27 | done && \ 28 | ldconfig 29 | [ "$OLDPWD" ] && cd - 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /docker/root/etc/cont-init.d/60-custom-setup-script: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | 4 | if [[ -f /config/startup.sh ]]; then 5 | 6 | echo "**** (custom-setup-script) Calling custom user setup script ****"; 7 | sed -i 's/\r$//' /config/startup.sh 8 | source /config/startup.sh 9 | 10 | fi 11 | 12 | for plugin_script in /config/.unmanic/plugins/*/init.d/*.sh ; do 13 | 14 | if [[ -e "${plugin_script}" ]]; then 15 | 16 | echo "[60-custom-setup-script] ${plugin_script}: executing..." 17 | sed -i 's/\r$//' "${plugin_script}" 18 | source "${plugin_script}" 19 | 20 | fi 21 | 22 | done 23 | -------------------------------------------------------------------------------- /docker/root/etc/services.d/unmanic/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | RUN_USER=abc 4 | 5 | if [[ -e /app/unmanic/service.py ]]; then 6 | echo "Update container to running Unmanic from source" 7 | python_version=$(python3 --version 2>&1 | grep -oP 'Python \K\d+\.\d+') 8 | if [[ ! -L /usr/local/lib/python${python_version:?}/dist-packages/unmanic ]]; then 9 | echo "Move container unmanic install" 10 | mv /usr/local/lib/python${python_version:?}/dist-packages/unmanic /usr/local/lib/python${python_version:?}/dist-packages/unmanic-installed 11 | fi 12 | ln -sf /app/unmanic /usr/local/lib/python${python_version:?}/dist-packages/unmanic 13 | fi 14 | 15 | unmanic_params='' 16 | if [[ "${DEBUGGING}" == 'true' ]]; then 17 | unmanic_params="--dev ${unmanic_params}" 18 | fi 19 | if [[ "${USE_TEST_SUPPORT_API}" == 'true' ]]; then 20 | unmanic_params="--dev-api=https://support-api.test.streamingtech.co.nz ${unmanic_params}" 21 | fi 22 | 23 | chmod +x /usr/bin/unmanic 24 | exec s6-setuidgid root /usr/bin/unmanic "${unmanic_params}" 25 | -------------------------------------------------------------------------------- /docker/root/usr/bin/unmanic: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | RUN_USER=abc 4 | export HOME=/config 5 | exec s6-setuidgid ${RUN_USER} /usr/local/bin/unmanic-service ${@} 6 | -------------------------------------------------------------------------------- /docker/root/usr/bin/unmanic-tail-logs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | unmanic_dev_logs_dir=${config_dir}/.unmanic/logs 4 | 5 | args="-f" 6 | if [[ ! -z "${@}" ]]; then 7 | args="${args} ${@}" 8 | fi 9 | 10 | echo "tail ${args} /config/.unmanic/logs/unmanic.log | grcat /.grc.conf.unmanic.logs" 11 | tail ${args} /config/.unmanic/logs/unmanic.log | grcat /.grc.conf.unmanic.logs 12 | -------------------------------------------------------------------------------- /docs/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Attribution 56 | 57 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 58 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 59 | 60 | [homepage]: https://www.contributor-covenant.org -------------------------------------------------------------------------------- /docs/DEVELOPING.md: -------------------------------------------------------------------------------- 1 | # Unmanic development 2 | 3 | The development environment can be configured in 2 ways: 4 | 5 | 1. Using Docker 6 | 7 | 2. As a Pip develop installation 8 | 9 | 10 | Depending on what you are trying to develop, one way may work better than the other. 11 | 12 | Regardless of the method you use, you will need to pull in the frontend component and build it. 13 | 14 | 15 | 16 | ## Dev env 17 | 18 | ### Option 1: Docker 19 | 20 | Docker is by far the simplest way to develop. You can either pull the latest Docker image, or build 21 | the docker image by following the [Docker documentation](../docker/README.md) 22 | 23 | Once you have a Docker image, you can run it using the scripts in the `../devops/` directory. 24 | 25 | Examples: 26 | ``` 27 | # Enable VAAPI 28 | devops/run_docker.sh --debug --hw=vaapi --cpus=1 29 | 30 | # Enable NVIDIA 31 | devops/run_docker.sh --debug --hw=nvidia --cpus=1 32 | 33 | # Standard dev env 34 | devops/run_docker.sh --debug 35 | ``` 36 | 37 | The following folders are generated in the Docker environment: 38 | 39 | - `/dev_environment/config` - Contains the containers mutable config data 40 | - `/dev_environment/library` - A library in which media files can be placed for testing 41 | - `/dev_environment/cache` - The temporary location used by ffmpeg for converting file formats 42 | 43 | ### Option 2: Pip 44 | 45 | You can also just install the module natively in your home directory in "develop" mode. 46 | 47 | Start by creating a venv. 48 | ``` 49 | python3 -m venv venv 50 | echo 'export HOME_DIR=$(readlink -e ${VIRTUAL_ENV}/../)/dev_environment' >> ./venv/bin/activate 51 | source ./venv/bin/activate 52 | ``` 53 | 54 | Then install the dependencies into that venv 55 | ``` 56 | python3 -m pip install --upgrade pip 57 | python3 -m pip install --upgrade -r ./requirements.txt -r ./requirements-dev.txt 58 | ``` 59 | 60 | Then install the module: 61 | 62 | ``` 63 | python3 -m pip install --editable . 64 | ``` 65 | 66 | This creates an egg symlink to the project directory for development. 67 | 68 | To later uninstall the development symlink: 69 | 70 | ``` 71 | python3 -m pip uninstall unmanic 72 | ``` 73 | 74 | You should now be able to run unmanic from the commandline: 75 | ``` 76 | # In develop mode this should return "UNKNOWN" 77 | unmanic --version 78 | ``` 79 | 80 | 81 | 82 | ## Building the Frontend 83 | 84 | The Unmanic frontend UI exists in a submodule. 85 | 86 | Start by pulling the latest changes 87 | 88 | ``` 89 | git submodule update --init --recursive 90 | ``` 91 | 92 | Once you have done this, run the frontend_install.sh script. 93 | 94 | ``` 95 | devops/frontend_install.sh 96 | ``` 97 | 98 | This will install the NPM modules and build the frontend package. The end result will be located in `unmanic/webserver/public` 99 | 100 | 101 | 102 | ## Database upgrades 103 | 104 | This project uses Peewee migrations for managing the sqlite database. 105 | `devops/migrations.sh` provides a small wrapper for the cli tool. To get started, run: 106 | ``` 107 | devops/migrations.sh --help 108 | ``` 109 | -------------------------------------------------------------------------------- /docs/GENERATING_MASTER_RELEASE.md: -------------------------------------------------------------------------------- 1 | # Releasing staging into master 2 | 3 | If you are only merging changes into `master` without performing a release, just run through steps 1 and 2. 4 | 5 | If you are just going to release what is currently in the master branch, then skip to [Step 3](#step-3). 6 | 7 | ## Step 1: Compare commit history 8 | Compare the `staging` and `master` branch commit history: 9 | https://github.com/Unmanic/unmanic/compare/master...staging 10 | 11 | 12 | ## Step 2: Rebase merge into master 13 | Perform a rebase merge from `staging` into `master` on the checked out repo. Push this change to the official repo's `master` branch. 14 | 15 | > [!IMPORTANT] 16 | > If you are going to generate a tagged release, cancel the `Build All Packages CI` GitHub action for this push. This will be run again once we generate the release in the steps below. If you are not generating a release, let this action run. 17 | 18 | 19 | ## Step 3: Compare commit history since last release 20 | Compare the `master` branch commit history since the last release: 21 | https://github.com/Unmanic/unmanic/compare/0.2.7...master 22 | 23 | While here, draft a changelog for the next release. 24 | 25 | 26 | ## Step 4: Create a GitHub release 27 | Create a release in GitHub with these rules. 28 | - The release should target the `master` branch. 29 | - The release should tag the target when created. Use the format: `X.X.X` 30 | - The release header should follow this template: 31 | ``` 32 | [RELEASE] vX.X.X 33 | ``` 34 | - The release body should follow this template: 35 | ``` 36 | - [NOTE] Add release notes here. 37 | 38 | 39 | ## Service 40 | - [NEW] This is a new feature added to the main service. 41 | - This is a bullet point to the above mentioned feature. 42 | - [FIX] This is a fix for the main service. 43 | - This is a bullet point to the above mentioned fix. 44 | - [IMPR] This is an improvement to an existing feature in the main service. 45 | - This is a bullet point to the above mentioned improvement. 46 | 47 | ## Plugin executor 48 | - [NEW] ... 49 | - [FIX] ... 50 | - [IMPR] ... 51 | 52 | ## Docker 53 | - [NEW] ... 54 | - [FIX] ... 55 | - [IMPR] ... 56 | 57 | ## Front-end 58 | - [NEW] ... 59 | - [FIX] ... 60 | - [IMPR] ... 61 | ``` 62 | -------------------------------------------------------------------------------- /docs/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Have you read the [Code of Conduct](CODE_OF_CONDUCT.md)? By filing an Issue, you are expected 2 | to comply with it, including treating everyone with respect: 3 | 4 | 5 | Remember that these are some guidelines, use your best judgement. 6 | 7 | 8 | ### Description 9 | 10 | [Description of the issue] 11 | 12 | ### Steps to Reproduce 13 | 14 | 1. [First Step] 15 | 2. [Second Step] 16 | 3. [and so on...] 17 | 18 | **Expected behavior:** [What you expect to happen] 19 | 20 | **Actual behaviour:** [What actually happens] 21 | 22 | **Reproduces how often:** [What percentage of the time does it reproduce?] 23 | 24 | ### Versions 25 | 26 | The version can be found at the footer of the WebUI. Also, please include the OS details and what version you are running 27 | (e.g. `cat /etc/os-release`). 28 | 29 | ### Installation Method Used 30 | 31 | Manually installed and run or run through Docker? 32 | 33 | ### Additional Information 34 | 35 | Any additional information, configuration or data that might be necessary to 36 | reproduce the issue. 37 | -------------------------------------------------------------------------------- /docs/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Pull request 2 | 3 | ## CLA 4 | 5 | - [ ] I agree that by opening a pull requests I am handing over copyright ownership 6 | of my work contained in that pull request to the Unmanic project and the project 7 | owner. My contribution will become licensed under the same license as the overall project. 8 | This extends upon paragraph 11 of the Terms & Conditions stipulated in the GPL v3.0 9 | 10 | 11 | ## Checklist 12 | 13 | - [ ] I have ensured that my pull request is being opened to merge into the staging branch. 14 | 15 | - [ ] I have ensured that all new python file contributions contain the correct header as 16 | stipulated in the [Contributing Docs](CONTRIBUTING.md). 17 | 18 | 19 | ## Description of the pull request 20 | -------------------------------------------------------------------------------- /docs/images/unmanic-dashboard-processing-anime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/docs/images/unmanic-dashboard-processing-anime.png -------------------------------------------------------------------------------- /docs/images/unmanic-file-size-data-panel-anime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/docs/images/unmanic-file-size-data-panel-anime.png -------------------------------------------------------------------------------- /docs/images/unmanic-list-installed-plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/docs/images/unmanic-list-installed-plugins.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/icon.png -------------------------------------------------------------------------------- /logo-white_font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/logo-white_font.png -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Unmanic/unmanic/925008e16445e339937d7097d5306c63427be467/logo.png -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | python_files=tests/*.py 3 | 4 | pytest_plugins = ("test.configtest",) 5 | 6 | filterwarnings = 7 | ignore:.*invalid escape sequence.*:DeprecationWarning 8 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | flake8>=5.0.4 # Note: Highest supporting Py 3.7 2 | pycodestyle>=2.9.1 # Note: Highest supporting Py 3.7 3 | pytest>=7.4.3 # Note: Highest supporting Py 3.7 4 | wheel>=0.42.0 5 | setuptools>=68.0.0 # Note: Highest supporting Py 3.7 6 | build>=0.10.0 # Note: Highest supporting Py 3.7 7 | 8 | # API schema exporting 9 | apispec>=6.3.1 10 | apispec_webframeworks>=0.5.2 11 | pyyaml>=6.0.1 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Required 2 | schedule==0.6.0 3 | tornado==6.0.2 4 | marshmallow==3.13.0 5 | peewee>=3.14.4 6 | peewee_migrate==1.6.1 7 | psutil==5.8.0 8 | requests>=2.28.2 9 | requests_toolbelt>=0.9.1 10 | py-cpuinfo>=7.0.0 11 | 12 | # Optional requirements 13 | watchdog>=2.1.1 14 | 15 | # Required for CLI only 16 | inquirer>=2.7.0 17 | 18 | # Required for hosting the API docs 19 | swagger-ui-py 20 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = unmanic 3 | license = GPLv3 4 | long_description = file: README.md, LICENSE 5 | long_description_content_type = text/markdown 6 | 7 | [options] 8 | python_requires = >=3.7 9 | zip_safe = False 10 | include_package_data = True 11 | 12 | [pycodestyle] 13 | # TODO: Fix these errors 14 | ignore = E722,E241,W293 15 | max-line-length = 127 16 | statistics = True 17 | exclude = venv/**,.idea/** 18 | show-pep8 = False 19 | show-source = False 20 | 21 | [flake8] 22 | # TODO: Fix these errors 23 | ignore = E722,E241,W293,F401,F403,F405,F841 24 | max-line-length = 127 25 | exclude = venv/**,.idea/** 26 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Unit Testing 2 | 3 | 4 | 5 | ## Setup 6 | 7 | Before any tests can be run, you need to execute 8 | ``` 9 | tests/scripts/setup_tests.sh 10 | ``` 11 | 12 | 13 | ----------------------------------------------------------- 14 | 15 | 16 | ## Python PEP8 conformity 17 | 18 | Prior to committing code, it should be tested against PEP8 formatting standards 19 | ``` 20 | pycodestyle ./ 21 | ``` 22 | 23 | You can also specify the files to run individual. Eg. 24 | ``` 25 | pycodestyle ./lib/common.py 26 | ``` 27 | 28 | 29 | ----------------------------------------------------------- 30 | 31 | 32 | ## Python unit tests 33 | 34 | To run all tests execute from the project directory root: 35 | ``` 36 | pytest --log-cli-level=INFO 37 | ``` 38 | 39 | You can also specify the files to run individual. Eg. 40 | ``` 41 | pytest --log-cli-level=INFO lib/common.py 42 | ``` 43 | 44 | For more in-depth logging of tests, change the params to: 45 | ``` 46 | pytest --log-cli-level=DEBUG -s 47 | ``` 48 | 49 | 50 | ----------------------------------------------------------- 51 | 52 | 53 | ## WebUI acceptance tests 54 | 55 | This is still a WIP but the idea will be to have a series of API calls to determine successful functionality of the Web API 56 | 57 | To run the test first run a docker environment. You can do this by running 58 | ``` 59 | tests/scripts/library_scan.sh 60 | ``` 61 | You can export the following variables to configure the test container: 62 | ``` 63 | DEBUGGING=true 64 | NUMBER_OF_WORKERS=1 65 | SCHEDULE_FULL_SCAN_MINUTES=1 66 | RUN_FULL_SCAN_ON_START=true 67 | ``` 68 | To clean the config run 69 | ``` 70 | tests/scripts/library_scan.sh --clean 71 | ``` 72 | 73 | 74 | ----------------------------------------------------------- 75 | 76 | 77 | ## Python unit tests within docker 78 | 79 | To run the python unit tests within the test docker env 80 | (in order to test them in a controlled environment), run 81 | these commands: 82 | 83 | ``` 84 | docker-compose -f docker/docker-compose-test.yml up --force-recreate 85 | ``` 86 | 87 | Wait for the container to start, then run: 88 | 89 | ``` 90 | docker exec --workdir=/app unmanic-testenv pycodestyle ./ 91 | ``` 92 | 93 | and 94 | 95 | ``` 96 | docker exec --workdir=/app unmanic-testenv pytest --log-cli-level=INFO 97 | ``` 98 | 99 | When developing, if you wish to run only a single test, run: 100 | 101 | ``` 102 | docker exec --workdir=/app unmanic-testenv pytest --log-cli-level=INFO --maxfail 1 -s tests/test_.py 103 | ``` 104 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 May 2020, (6:37 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.conftest.py 6 | 7 | Written by: Josh.5 8 | Date: 05 May 2020, (7:09 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | def pytest_configure(config): 35 | """ 36 | Custom pytest markers to separate the tests 37 | 38 | :param config: 39 | :return: 40 | """ 41 | config.addinivalue_line("markers", "unittest: Unit tests.") 42 | config.addinivalue_line("markers", "integrationtest: Integration test.") 43 | -------------------------------------------------------------------------------- /tests/integration/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 May 2020, (6:37 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /tests/scripts_/setup_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- coding: utf-8 -*- 3 | ################################################################################################### 4 | # 5 | # Written by: Josh.5 6 | # Date: Thu Jan 07 2019, (17:52:42 PM) 7 | # 8 | # Copyright: 9 | # Copyright (C) Josh Sunnex - All Rights Reserved 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a copy 12 | # of this software and associated documentation files (the "Software"), to deal 13 | # in the Software without restriction, including without limitation the rights 14 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | # copies of the Software, and to permit persons to whom the Software is 16 | # furnished to do so, subject to the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be included in all 19 | # copies or substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 25 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 26 | # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 27 | # OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # 30 | ################################################################################################### 31 | 32 | # This script is to setup a series of tests for the application 33 | 34 | 35 | SCRIPT_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ); 36 | PROJECT_BASE=$(realpath ${SCRIPT_PATH}/../../); 37 | 38 | 39 | source "${SCRIPT_PATH}/download_test_files.sh" 40 | 41 | 42 | ### FUNCTIONS 43 | # Install script dependencies: 44 | setup_script_dependencies() { 45 | TO_INSTALL=""; 46 | [[ ! -x $(command -v curl) ]] && TO_INSTALL="${TO_INSTALL} curl"; 47 | if [[ "${TO_INSTALL}" != "" ]]; then 48 | echo "Missing dependencies - ${TO_INSTALL}"; 49 | exit 0; 50 | fi 51 | python3 -m pip install --user --upgrade -r ${PROJECT_BASE}/requirements-dev.txt 52 | python3 -m pip install --user --upgrade -r ${PROJECT_BASE}/requirements.txt 53 | } 54 | 55 | 56 | ### RUN 57 | setup_script_dependencies 58 | -------------------------------------------------------------------------------- /tests/support_/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 May 2020, (6:37 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /tests/support_/test_data/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 19 Sep 2019, (7:09 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /tests/support_/test_data/data_queues.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.data_queues.py 6 | 7 | Written by: Josh.5 8 | Date: 08 May 2020, (12:32 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import queue 33 | 34 | from unmanic.libs import unlogger 35 | 36 | unmanic_logging = unlogger.UnmanicLogger.__call__(False) 37 | unmanic_logging.get_logger() 38 | 39 | data_queues = { 40 | "scheduledtasks": queue.Queue(), 41 | "inotifytasks": queue.Queue(), 42 | "progress_reports": queue.Queue(), 43 | "logging": unmanic_logging 44 | } 45 | -------------------------------------------------------------------------------- /tests/support_/test_data/mock_jobqueue_class.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mock_jobqueue_class.py 6 | 7 | Written by: Josh.5 8 | Date: 08 May 2020, (1:00 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | class MockJobQueue(object): 35 | """ 36 | MockJobQueue 37 | 38 | A mock job queue object for unit testing 39 | 40 | """ 41 | 42 | def __init__(self): 43 | self.name = 'TaskQueue' 44 | self.added_item = None 45 | 46 | def add_item(self, pathname): 47 | self.added_item = pathname 48 | return True 49 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 May 2020, (6:38 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /tests/unit/test_unlogger.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.test_unlogger.py 6 | 7 | Written by: Josh.5 8 | Date: 08 Sep 2019, (8:45 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | import os 34 | import sys 35 | 36 | import pytest 37 | 38 | try: 39 | from unmanic.libs import unlogger 40 | except ImportError: 41 | project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 42 | sys.path.append(project_dir) 43 | from unmanic.libs import unlogger 44 | 45 | 46 | class SettingsObject(object): 47 | pass 48 | 49 | 50 | 51 | # TODO: Re-enable unit test once config object can be called without a DB connection 52 | class TestClass(object): 53 | """ 54 | TestClass 55 | 56 | Runs unit tests against the unlogger class 57 | 58 | """ 59 | 60 | def setup_class(self): 61 | """ 62 | Setup the class state for pytest 63 | :return: 64 | """ 65 | # Logging file handler is disabled for unit tests 66 | unmanic_logging = unlogger.UnmanicLogger.__call__(False) 67 | unmanic_logging.get_logger() 68 | 69 | @pytest.mark.unittest 70 | def test_logging_special_characters(self): 71 | unmanic_logging = unlogger.UnmanicLogger.__call__() 72 | main_logger = unmanic_logging.get_logger() 73 | main_logger.info("Check that these characters display correctly") 74 | main_logger.info("Success: \u251c – € ’ “ ” « » — à á ã ç ê é í ó õ ú") 75 | main_logger.info("Fails: \udce2\udc80\udc98") 76 | -------------------------------------------------------------------------------- /unmanic/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 04 May 2020, (11:20 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | import warnings 34 | 35 | from .metadata import __author__ 36 | from .metadata import __version__ 37 | from .metadata import __description__ 38 | from .metadata import __disclaimer__ 39 | from .metadata import __forum__ 40 | from .metadata import __video__ 41 | from .metadata import __website__ 42 | from .metadata import __copyright__ 43 | -------------------------------------------------------------------------------- /unmanic/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__main__.py 6 | 7 | Written by: Josh.5 8 | Date: 19 March 2022, (18:51 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from .service import main 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /unmanic/libs/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 21 February 2017, (11:11 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import sys 33 | import warnings 34 | 35 | from .unlogger import UnmanicLogger 36 | 37 | __all__ = ( 38 | 'UnmanicLogger', 39 | ) 40 | -------------------------------------------------------------------------------- /unmanic/libs/singleton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.singleton.py 6 | 7 | Written by: Josh.5 8 | Date: 26 Oct 2020, (2:51 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import threading 33 | 34 | lock = threading.Lock() 35 | 36 | 37 | class SingletonType(type): 38 | """Singleton metaclass""" 39 | _instances = {} 40 | 41 | def __call__(cls, *args, **kwargs): 42 | if cls not in cls._instances: 43 | with lock: 44 | if cls not in cls._instances: 45 | cls._instances[cls] = super(SingletonType, cls).__call__(*args, **kwargs) 46 | return cls._instances[cls] 47 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 10 Sep 2019, (8:05 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | import warnings 35 | 36 | from . import containers 37 | from . import exceptions 38 | from . import audio_codecs 39 | from . import subtitle_codecs 40 | from . import video_codecs 41 | from .info import Info 42 | from .audio_codec_handle import AudioCodecHandle 43 | from .hardware_acceleration_handle import HardwareAccelerationHandle 44 | from .subtitle_handle import SubtitleHandle 45 | from .video_codec_handle import VideoCodecHandle 46 | 47 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 48 | 49 | __all__ = ( 50 | 'containers', 51 | 'exceptions', 52 | 'audio_codecs', 53 | 'subtitle_codecs', 54 | 'video_codecs', 55 | 'Info', 56 | 'AudioCodecHandle', 57 | 'HardwareAccelerationHandle', 58 | 'SubtitleHandle', 59 | 'VideoCodecHandle', 60 | ) 61 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/audio_codecs/aac.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.aac.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (7:51 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Aac(Codecs): 37 | name = 'aac' 38 | encoders = ['aac'] 39 | default_encoder = 'aac' 40 | codec_long_name = 'AAC (Advanced Audio Coding)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/audio_codecs/ac3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ac3.py 6 | 7 | Written by: Josh.5 8 | Date: 24 Sep 2019, (9:43 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Ac3(Codecs): 37 | name = 'ac3' 38 | encoders = ['ac3'] 39 | default_encoder = 'ac3' 40 | codec_long_name = 'ATSC A/52A (AC-3)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/audio_codecs/mp3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mp3.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (8:45 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Mp3(Codecs): 37 | name = 'mp3' 38 | encoders = ['libmp3lame'] 39 | default_encoder = 'libmp3lame' 40 | codec_long_name = 'MP3 (MPEG audio layer 3)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/base_codecs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.base_codecs.py 6 | 7 | Written by: Josh.5 8 | Date: 20 Sep 2019, (5:38 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | class Codecs(object): 35 | """ 36 | Codecs 37 | 38 | Generic configuration and methods used across all codec classes 39 | """ 40 | name = '' 41 | encoders = [] 42 | default_encoder = '' 43 | codec_long_name = '' 44 | 45 | def codec_name(self): 46 | """ 47 | Return the codec name string 48 | 49 | :return: 50 | """ 51 | return self.name 52 | 53 | def codec_encoders(self): 54 | """ 55 | Return the codec encoders list 56 | 57 | :return: 58 | """ 59 | return self.encoders 60 | 61 | def codec_default_encoder(self): 62 | """ 63 | Return the codec encoders list 64 | 65 | :return: 66 | """ 67 | return self.default_encoder 68 | 69 | def codec_description(self): 70 | """ 71 | Return the codec description string 72 | 73 | :return: 74 | """ 75 | return self.codec_long_name 76 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/base_containers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.base_containers.py 6 | 7 | Written by: Josh.5 8 | Date: 10 Sep 2019, (8:13 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | class Containers(object): 35 | """ 36 | Containers 37 | 38 | Generic configuration and methods used across all Containers classes 39 | """ 40 | 41 | def container_extension(self): 42 | """ 43 | Return the container's extension string 44 | 45 | :return: 46 | """ 47 | return self.extension 48 | 49 | def container_description(self): 50 | """ 51 | Return the container's description string 52 | 53 | :return: 54 | """ 55 | return self.description 56 | 57 | def container_supports_subtitles(self): 58 | """ 59 | Check if this Container supports subtitles 60 | 61 | :return: 62 | """ 63 | if hasattr(self, 'supports_subtitles'): 64 | if self.supports_subtitles: 65 | return True 66 | return False 67 | 68 | def supported_subtitles(self): 69 | """ 70 | Check if this Container supports subtitles 71 | 72 | :return: 73 | """ 74 | if self.container_supports_subtitles(): 75 | return self.subtitle_codecs 76 | return [] 77 | 78 | def unsupported_subtitles(self): 79 | """ 80 | Check if this Container supports subtitles 81 | 82 | :return: 83 | """ 84 | if hasattr(self, 'unsupports_codecs'): 85 | return self.unsubtitle_codecs 86 | # HDMV streams cannot be written by FFMPEG 87 | return ['hdmv_pgs_subtitle'] 88 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/avi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.avi.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:44 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Avi(Containers): 37 | extension = 'avi' 38 | description = 'AVI (Audio Video Interleaved)' 39 | supports_subtitles = True 40 | subtitle_codecs = ['xsub'] 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/flv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.flv.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:53 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Flv(Containers): 37 | extension = 'flv' 38 | description = 'FLV (Flash Video)' 39 | supports_subtitles = False 40 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/matroska.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.matroska.py 6 | 7 | Written by: Josh.5 8 | Date: 10 Sep 2019, (8:07 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Matroska(Containers): 37 | extension = 'mkv' 38 | description = 'Matroska' 39 | supports_subtitles = True 40 | # TODO: When user selection of subtitle codec is available, re-order alphabetically 41 | subtitle_codecs = ['srt', 'ass', 'ssa', 'subrip', 'dvbsub', 'dvdsub', 'dvd_subtitle'] 42 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/mov.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mov.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:46 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Mov(Containers): 37 | extension = 'mov' 38 | description = 'QuickTime / MOV' 39 | supports_subtitles = True 40 | subtitle_codecs = ['mov_text'] 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/mp4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mp4.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:47 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Mp4(Containers): 37 | extension = 'mp4' 38 | description = 'MP4 (MPEG-4 Part 14)' 39 | supports_subtitles = True 40 | subtitle_codecs = ['mov_text', 'srt', 'ass', 'ssa', 'dvbsub', 'dvdsub'] 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/mpeg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mpeg.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:32 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Mpeg(Containers): 37 | extension = 'mpeg' 38 | description = 'MPEG-1 Systems / MPEG program stream' 39 | supports_subtitles = True 40 | subtitle_codecs = ['mov_text'] 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/mpegts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mpegts.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:51 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Mpegts(Containers): 37 | extension = 'ts' 38 | description = 'MPEG-TS (MPEG-2 Transport Stream)' 39 | supports_subtitles = False 40 | subtitle_codecs = ['mov_text'] 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/ogv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ogv.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:48 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Ogv(Containers): 37 | extension = 'ogv' 38 | description = 'Ogg Video' 39 | supports_subtitles = False 40 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/psp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.psp.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:49 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Psp(Containers): 37 | extension = 'psp' 38 | description = 'PSP MP4 (MPEG-4 Part 14)' 39 | supports_subtitles = False 40 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/containers/vob.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.vob.py 6 | 7 | Written by: Josh.5 8 | Date: 12 Sep 2019, (7:50 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from . import Containers 34 | 35 | 36 | class Vob(Containers): 37 | extension = 'vob' 38 | description = 'MPEG-2 PS (VOB)' 39 | supports_subtitles = False 40 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/exceptions/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 22 Sep 2019, (11:30 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | import warnings 35 | 36 | 37 | from . import ffmpeg 38 | from . import ffprobe 39 | 40 | 41 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 42 | 43 | __all__ = ( 44 | 'ffmpeg', 45 | 'ffprobe', 46 | ) 47 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/exceptions/ffmpeg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ffmpeg.py 6 | 7 | Written by: Josh.5 8 | Date: 22 Sep 2019, (11:30 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | class FFMpegError(Exception): 35 | def __init___(self, command, info): 36 | Exception.__init__(self, 37 | "Unable to fetch data from ffmpeg command - {}. Command: {}".format(info, " ".join(command))) 38 | self.path = command 39 | self.info = info 40 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/exceptions/ffprobe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ffprobe.py 6 | 7 | Written by: Josh.5 8 | Date: 22 Sep 2019, (11:30 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | 34 | class FFProbeError(Exception): 35 | def __init___(self, path, info): 36 | Exception.__init__(self, "Unable to fetch data from file {}. {}".format(path, info)) 37 | self.path = path 38 | self.info = info 39 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/lib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (2:30 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/lib/validation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.validation.py 6 | 7 | Written by: Josh.5 8 | Date: 22 Oct 2020, (7:45 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/ass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ass.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (8:50 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Ass(Codecs): 37 | name = 'ass' 38 | encoders = ['ass'] 39 | default_encoder = 'ass' 40 | codec_long_name = 'ASS (Advanced SubStation Alpha) subtitle' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/mov_text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.mov_text.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (8:51 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class MovText(Codecs): 37 | name = 'mov_text' 38 | encoders = ['mov_text'] 39 | default_encoder = 'mov_text' 40 | codec_long_name = '3GPP Timed Text subtitle' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/srt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.avi.py 6 | 7 | Written by: Josh.5 8 | Date: 19 Sep 2019, (5:10 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Srt(Codecs): 37 | name = 'srt' 38 | encoders = ['srt'] 39 | default_encoder = 'srt' 40 | codec_long_name = 'SubRip subtitle (codec subrip)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/ssa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.ssa.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (8:50 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Ssa(Codecs): 37 | codec = 'ssa' 38 | name = 'ssa' 39 | encoders = ['ssa'] 40 | default_encoder = 'ssa' 41 | codec_long_name = 'ASS (Advanced SubStation Alpha) subtitle (codec ass)' 42 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/subrip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.subrip.py 6 | 7 | Written by: Josh.5 8 | Date: 19 Sep 2019, (5:16 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Subrip(Codecs): 37 | name = 'subrip' 38 | encoders = ['subrip'] 39 | default_encoder = 'subrip' 40 | codec_long_name = 'SubRip subtitle' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/subtitle_codecs/xsub.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.xsub.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Sep 2019, (8:49 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Xsub(Codecs): 37 | name = 'xsub' 38 | encoders = ['xsub'] 39 | default_encoder = 'xsub' 40 | codec_long_name = 'DivX subtitles (XSUB)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/video_codecs/h264.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.h264.py 6 | 7 | Written by: Josh.5 8 | Date: 20 Sep 2019, (5:41 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class H264(Codecs): 37 | name = 'h264' 38 | encoders = ['h264_nvenc', 'h264_vaapi', 'libx264', 'libx264rgb'] 39 | default_encoder = 'libx264' 40 | codec_long_name = 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unffmpeg/video_codecs/hevc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.hevc.py 6 | 7 | Written by: Josh.5 8 | Date: 20 Sep 2019, (5:39 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..base_codecs import Codecs 34 | 35 | 36 | class Hevc(Codecs): 37 | name = 'hevc' 38 | encoders = ['hevc_nvenc', 'hevc_vaapi', 'libx265'] 39 | default_encoder = 'libx265' 40 | codec_long_name = 'HEVC (High Efficiency Video Coding)' 41 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 22 Jun 2019, (1:47 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | from .completedtaskscommandlogs import CompletedTasksCommandLogs 36 | from .completedtasks import CompletedTasks 37 | from .enabledplugins import EnabledPlugins 38 | from .installation import Installation 39 | from .pluginrepos import PluginRepos 40 | from .plugins import Plugins 41 | from .libraries import Libraries, LibraryTags 42 | from .librarypluginflow import LibraryPluginFlow 43 | from .tags import Tags 44 | from .tasks import Tasks 45 | from .workergroups import WorkerGroupTags, WorkerGroups 46 | from .workerschedules import WorkerSchedules 47 | 48 | __author__ = 'Josh.5 (jsunnex@gmail.com)' -------------------------------------------------------------------------------- /unmanic/libs/unmodels/completedtasks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.completedtasks.py 6 | 7 | Written by: Josh.5 8 | Date: 30 Sep 2019, (6:46 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | import datetime 34 | 35 | from peewee import * 36 | from unmanic.libs.unmodels.lib import BaseModel 37 | 38 | 39 | class CompletedTasks(BaseModel): 40 | """ 41 | CompletedTasks 42 | """ 43 | task_label = TextField(null=False) 44 | abspath = TextField(null=False, default='') 45 | task_success = BooleanField(null=False) 46 | start_time = DateTimeField(null=False, default=datetime.datetime.now) 47 | finish_time = DateTimeField(null=False, default=datetime.datetime.now) 48 | processed_by_worker = TextField(null=False) 49 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/completedtaskscommandlogs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.completedtaskscommandlogs.py 6 | 7 | Written by: Josh.5 8 | Date: 06 Oct 2019, (4:02 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | from unmanic.libs.unmodels.lib import BaseModel 35 | from unmanic.libs.unmodels.completedtasks import CompletedTasks 36 | 37 | 38 | class CompletedTasksCommandLogs(BaseModel): 39 | """ 40 | CompletedTasksCommandLogs 41 | """ 42 | completedtask_id = ForeignKeyField(CompletedTasks) 43 | dump = TextField(null=False, default='') 44 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/enabledplugins.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.enabledplugins.py 6 | 7 | Written by: Josh.5 8 | Date: 07 Feb 2022, (1:25 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | 35 | from unmanic.libs.unmodels.lib import BaseModel 36 | from unmanic.libs.unmodels.libraries import Libraries 37 | from unmanic.libs.unmodels.plugins import Plugins 38 | 39 | 40 | class EnabledPlugins(BaseModel): 41 | """ 42 | EnabledPlugins 43 | """ 44 | library_id = ForeignKeyField(Libraries, backref='enabled_plugins', on_delete='CASCADE', on_update='CASCADE') 45 | plugin_id = ForeignKeyField(Plugins, backref='enabled_libraries', on_delete='CASCADE', on_update='CASCADE') 46 | plugin_name = TextField(null=False) 47 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/installation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.installation.py 6 | 7 | Written by: Josh.5 8 | Date: 11 Mar 2021, (6:52 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import datetime 33 | import uuid 34 | from peewee import * 35 | 36 | from unmanic.libs.unmodels.lib import BaseModel 37 | 38 | 39 | class Installation(BaseModel): 40 | """ 41 | Installation 42 | 43 | All application installation data 44 | """ 45 | uuid = UUIDField(null=False, default=uuid.uuid4, unique=True) 46 | # Store session data here to persist restarts 47 | level = IntegerField(null=False, default=0) 48 | picture_uri = TextField(null=True) 49 | name = TextField(null=True) 50 | email = TextField(null=True) 51 | created = DateTimeField(null=True, default=datetime.datetime.now) 52 | 53 | # Store session tokens 54 | user_access_token = TextField(null=True) 55 | user_refresh_token = TextField(null=True) 56 | session_cookies = TextField(null=True) 57 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/lib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 14 Aug 2021, (11:58 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | from .basemodel import BaseModel 36 | from .basemodel import Database 37 | from .basemodel import db 38 | 39 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 40 | 41 | __all__ = ( 42 | 'BaseModel', 43 | 'Database', 44 | 'db', 45 | ) 46 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/libraries.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.libraries.py 6 | 7 | Written by: Josh.5 8 | Date: 06 Feb 2022, (9:44 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | 35 | from unmanic.libs.unmodels.lib import BaseModel 36 | from unmanic.libs.unmodels.tags import Tags 37 | 38 | 39 | class Libraries(BaseModel): 40 | """ 41 | Libraries 42 | """ 43 | name = TextField(null=False, unique=True) 44 | path = TextField(null=False) 45 | locked = BooleanField(null=False, default=False) 46 | enable_remote_only = BooleanField(null=False, default=False) 47 | enable_scanner = BooleanField(null=False, default=False) 48 | enable_inotify = BooleanField(null=False, default=False) 49 | priority_score = BigIntegerField(null=False, default=0) 50 | # ManyToMany Linking field. Does not create a column in the DB. See linking table below 51 | tags = ManyToManyField(Tags, backref='tags') 52 | 53 | 54 | # Generate linking table for the 'tags' field above 55 | # https://docs.peewee-orm.com/en/latest/peewee/relationships.html#manytomanyfield 56 | LibraryTags = Libraries.tags.get_through_model() 57 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/librarypluginflow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.librarypluginflow.py 6 | 7 | Written by: Josh.5 8 | Date: 13 Feb 2022, (11:27 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | 35 | from unmanic.libs.unmodels.lib import BaseModel 36 | from unmanic.libs.unmodels.libraries import Libraries 37 | from unmanic.libs.unmodels.plugins import Plugins 38 | 39 | 40 | class LibraryPluginFlow(BaseModel): 41 | """ 42 | LibraryPluginFlow 43 | """ 44 | plugin_id = ForeignKeyField(Plugins, backref='flow', on_delete='CASCADE', on_update='CASCADE') 45 | library_id = ForeignKeyField(Libraries, backref='plugin_flow', on_delete='CASCADE', on_update='CASCADE') 46 | plugin_name = TextField(null=False) 47 | plugin_type = TextField(null=False) 48 | position = IntegerField(null=False, default=9999) 49 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/pluginrepos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.pluginrepos.py 6 | 7 | Written by: Josh.5 8 | Date: 03 Mar 2021, (3:03 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | from unmanic.libs.unmodels.lib import BaseModel 35 | 36 | 37 | class PluginRepos(BaseModel): 38 | """ 39 | PluginRepos 40 | """ 41 | path = TextField(null=False) 42 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/plugins.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.plugins.py 6 | 7 | Written by: Josh.5 8 | Date: 05 Mar 2021, (2:11 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | from unmanic.libs.unmodels.lib import BaseModel 35 | 36 | 37 | class Plugins(BaseModel): 38 | """ 39 | Plugins 40 | """ 41 | plugin_id = TextField(null=False, unique=True) 42 | name = TextField(null=False) 43 | author = TextField(null=False) 44 | version = TextField(null=False) 45 | tags = TextField(null=False) 46 | description = TextField(null=False) 47 | icon = TextField(null=False) 48 | local_path = TextField(null=False) 49 | # NOTE: Enabled plugins here is deprecated. This is kept for compatibility with older DB 50 | enabled = BooleanField(null=True, default=False) 51 | update_available = BooleanField(null=False, default=False) 52 | position = IntegerField(null=False, default=9999) 53 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/tags.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.tags.py 6 | 7 | Written by: Josh.5 8 | Date: 16 Apr 2022, (7:01 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | import datetime 34 | 35 | from peewee import * 36 | 37 | from unmanic.libs.unmodels.lib import BaseModel 38 | 39 | 40 | class Tags(BaseModel): 41 | """ 42 | Tags 43 | """ 44 | name = TextField(null=False, unique=True) 45 | created = DateTimeField(null=False, default=datetime.datetime.now) 46 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/tasks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.tasks.py 6 | 7 | Written by: Josh.5 8 | Date: 08 May 2020, (3:27 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | import datetime 34 | 35 | from peewee import * 36 | from unmanic.libs.unmodels.lib import BaseModel 37 | 38 | 39 | class Tasks(BaseModel): 40 | """ 41 | Tasks 42 | """ 43 | abspath = TextField(null=False, unique=True) 44 | cache_path = TextField(null=True, unique=True) 45 | priority = BigIntegerField(null=True) 46 | type = TextField(null=False, default='local') # (local, remote) 47 | library_id = IntegerField(null=False, default=1) 48 | status = TextField(null=False) # (pending, in_progress, processed) 49 | success = BooleanField(null=True) 50 | start_time = DateTimeField(null=True, default=datetime.datetime.now) 51 | finish_time = DateTimeField(null=True, default=datetime.datetime.now) 52 | processed_by_worker = TextField(null=True) 53 | log = TextField(null=False, default='') 54 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/workergroups.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.workergroups.py 6 | 7 | Written by: Josh.5 8 | Date: 18 Apr 2022, (4:15 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | 35 | from unmanic.libs.unmodels.lib import BaseModel 36 | from unmanic.libs.unmodels.tags import Tags 37 | 38 | 39 | class WorkerGroups(BaseModel): 40 | """ 41 | WorkerGroups 42 | """ 43 | name = TextField(null=False) 44 | locked = BooleanField(null=False, default=False) 45 | number_of_workers = IntegerField(null=False, default=0) 46 | # ManyToMany Linking fields. Does not create a column in the DB. See linking table below 47 | tags = ManyToManyField(Tags, backref='tags') 48 | 49 | # Generate linking table for the 'tags' field above 50 | # https://docs.peewee-orm.com/en/latest/peewee/relationships.html#manytomanyfield 51 | WorkerGroupTags = WorkerGroups.tags.get_through_model() 52 | -------------------------------------------------------------------------------- /unmanic/libs/unmodels/workerschedules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.workerschedules.py 6 | 7 | Written by: Josh.5 8 | Date: 18 Apr 2022, (4:19 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from peewee import * 34 | 35 | from unmanic.libs.unmodels import WorkerGroups 36 | from unmanic.libs.unmodels.lib import BaseModel 37 | 38 | 39 | class WorkerSchedules(BaseModel): 40 | """ 41 | WorkerSchedules 42 | """ 43 | repetition = TextField(null=False) 44 | schedule_task = TextField(null=False) 45 | schedule_time = TextField(null=False) 46 | schedule_worker_count = IntegerField(null=True) 47 | # Link to Worker Groups 48 | worker_group_id = ForeignKeyField(WorkerGroups, backref='worker_schedules', on_delete='CASCADE', on_update='CASCADE') 49 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 Mar 2021, (6:53 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | from __future__ import absolute_import 33 | import warnings 34 | 35 | from . import plugin_types 36 | from .executor import PluginExecutor 37 | 38 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 39 | 40 | __all__ = ( 41 | 'plugin_types', 42 | 'PluginExecutor', 43 | ) 44 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/plugin_types/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 25 Aug 2021, (4:04 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | import os 36 | from importlib import import_module 37 | from pathlib import Path 38 | import sys 39 | import inspect 40 | import pkgutil 41 | 42 | from ..plugin_type_base import PluginType 43 | 44 | """ 45 | Import all submodules for this package 46 | 47 | """ 48 | for (_, name, _) in pkgutil.iter_modules([os.path.join(Path(__file__).parent)]): 49 | 50 | imported_module = import_module('.' + name, package=__name__) 51 | 52 | for i in dir(imported_module): 53 | attribute = getattr(imported_module, i) 54 | 55 | if inspect.isclass(attribute) and issubclass(attribute, PluginType) and attribute.__name__ != 'PluginType': 56 | setattr(sys.modules[__name__], name, attribute) 57 | 58 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 59 | 60 | __all__ = () 61 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/plugin_types/frontend/panel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.panel.py 6 | 7 | Written by: Josh.5 8 | Date: 26 Aug 2021, (4:24 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from ..plugin_type_base import PluginType 34 | 35 | 36 | class DataPanel(PluginType): 37 | name = "Frontend - Data Panel" 38 | runner = "render_frontend_panel" 39 | runner_docstring = """ 40 | Runner function - display a custom data panel in the frontend. 41 | 42 | The 'data' object argument includes: 43 | content_type - The content type to be set when writing back to the browser. 44 | content - The content to print to the browser. 45 | path - The path received after the '/unmanic/panel' path. 46 | arguments - A dictionary of GET arguments received. 47 | 48 | :param data: 49 | :return: 50 | """ 51 | data_schema = { 52 | "content_type": { 53 | "required": True, 54 | "type": str, 55 | }, 56 | "content": { 57 | "required": True, 58 | "type": str, 59 | }, 60 | "path": { 61 | "required": False, 62 | "type": str, 63 | }, 64 | "arguments": { 65 | "required": False, 66 | "type": dict, 67 | }, 68 | } 69 | test_data = { 70 | 'content_type': 'text/html', 71 | 'content': "" 72 | "" 73 | "" 74 | "" 75 | "", 76 | 'path': "/ui/ajax", 77 | 'arguments': {'param': [b'true'], 'foo': [b'ba']}, 78 | } 79 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/plugin_types/library_management/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 31 Mar 2021, (8:32 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | import os 36 | from importlib import import_module 37 | from pathlib import Path 38 | import sys 39 | import inspect 40 | import pkgutil 41 | 42 | from ..plugin_type_base import PluginType 43 | 44 | """ 45 | Import all submodules for this package 46 | 47 | """ 48 | for (_, name, _) in pkgutil.iter_modules([os.path.join(Path(__file__).parent)]): 49 | 50 | imported_module = import_module('.' + name, package=__name__) 51 | 52 | for i in dir(imported_module): 53 | attribute = getattr(imported_module, i) 54 | 55 | if inspect.isclass(attribute) and issubclass(attribute, PluginType) and attribute.__name__ != 'PluginType': 56 | setattr(sys.modules[__name__], name, attribute) 57 | 58 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 59 | 60 | __all__ = () 61 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/plugin_types/postprocessor/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 24 Mar 2021, (9:40 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | import os 36 | from importlib import import_module 37 | from pathlib import Path 38 | import sys 39 | import inspect 40 | import pkgutil 41 | 42 | from ..plugin_type_base import PluginType 43 | 44 | """ 45 | Import all submodules for this package 46 | 47 | """ 48 | for (_, name, _) in pkgutil.iter_modules([os.path.join(Path(__file__).parent)]): 49 | 50 | imported_module = import_module('.' + name, package=__name__) 51 | 52 | for i in dir(imported_module): 53 | attribute = getattr(imported_module, i) 54 | 55 | if inspect.isclass(attribute) and issubclass(attribute, PluginType) and attribute.__name__ != 'PluginType': 56 | setattr(sys.modules[__name__], name, attribute) 57 | 58 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 59 | 60 | __all__ = () 61 | -------------------------------------------------------------------------------- /unmanic/libs/unplugins/plugin_types/worker/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 05 Mar 2021, (6:54 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | 35 | import os 36 | from importlib import import_module 37 | from pathlib import Path 38 | import sys 39 | import inspect 40 | import pkgutil 41 | 42 | from ..plugin_type_base import PluginType 43 | 44 | """ 45 | Import all submodules for this package 46 | 47 | """ 48 | for (_, name, _) in pkgutil.iter_modules([os.path.join(Path(__file__).parent)]): 49 | 50 | imported_module = import_module('.' + name, package=__name__) 51 | 52 | for i in dir(imported_module): 53 | attribute = getattr(imported_module, i) 54 | 55 | if inspect.isclass(attribute) and issubclass(attribute, PluginType) and attribute.__name__ != 'PluginType': 56 | setattr(sys.modules[__name__], name, attribute) 57 | 58 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 59 | 60 | __all__ = () 61 | -------------------------------------------------------------------------------- /unmanic/migrations_v1/001_rename_ffmpeg_log_to_log.py: -------------------------------------------------------------------------------- 1 | """Peewee migrations -- 001_rename_ffmpeg_log_to_log.py. 2 | 3 | Some examples (model - class or model name):: 4 | 5 | > Model = migrator.orm['model_name'] # Return model in current state by name 6 | 7 | > migrator.sql(sql) # Run custom SQL 8 | > migrator.python(func, *args, **kwargs) # Run python code 9 | > migrator.create_model(Model) # Create a model (could be used as decorator) 10 | > migrator.remove_model(model, cascade=True) # Remove a model 11 | > migrator.add_fields(model, **fields) # Add fields to a model 12 | > migrator.change_fields(model, **fields) # Change fields 13 | > migrator.remove_fields(model, *field_names, cascade=True) 14 | > migrator.rename_field(model, old_field_name, new_field_name) 15 | > migrator.rename_table(model, new_table_name) 16 | > migrator.add_index(model, *col_names, unique=False) 17 | > migrator.drop_index(model, *col_names) 18 | > migrator.add_not_null(model, *field_names) 19 | > migrator.drop_not_null(model, *field_names) 20 | > migrator.add_default(model, field_name, default) 21 | 22 | """ 23 | 24 | import peewee as pw 25 | from decimal import ROUND_HALF_EVEN 26 | 27 | try: 28 | import playhouse.postgres_ext as pw_pext 29 | except ImportError: 30 | pass 31 | 32 | SQL = pw.SQL 33 | 34 | """NOTES: 35 | The migrator function 'rename_field' has a bug: https://github.com/klen/peewee_migrate/issues/99 36 | The simple work-around to this was to skip this method and just directly append a migration to the migrator's ops list. 37 | Eg. `migrator.ops.append(migrator.migrator.rename_column('tasks', 'ffmpeg_log', 'log'))` 38 | """ 39 | 40 | 41 | """Note: 42 | This migration is required for legacy installations. 43 | The old Unmanic had a ffmpeg_log column which had a NOT NULL contraint on it. 44 | If this column is left as is, no items will be able to be added to the task queue. 45 | """ 46 | def migrate(migrator, database, fake=False, **kwargs): 47 | """Write your migrations here.""" 48 | # Rename 'ffmpeg_log' field to 'log'' in Tasks model 49 | if any(cm for cm in database.get_columns('tasks') if cm.name == 'ffmpeg_log'): 50 | migrator.ops.append(migrator.migrator.rename_column('tasks', 'ffmpeg_log', 'log')) 51 | 52 | 53 | def rollback(migrator, database, fake=False, **kwargs): 54 | """Write your rollback migrations here.""" 55 | # Reverse rename 'ffmpeg_log' field to 'log'' in Tasks model 56 | if any(cm for cm in database.get_columns('tasks') if cm.name == 'log'): 57 | migrator.ops.append(migrator.migrator.rename_column('tasks', 'log', 'ffmpeg_log')) 58 | -------------------------------------------------------------------------------- /unmanic/migrations_v1/README.md: -------------------------------------------------------------------------------- 1 | # Unmanic migrations v1 2 | 3 | This directory contains DB migrations for Unmanic >= 0.1.0. 4 | -------------------------------------------------------------------------------- /unmanic/version: -------------------------------------------------------------------------------- 1 | {"short": "UNKNOWN", "long": "UNKNOWN"} -------------------------------------------------------------------------------- /unmanic/webserver/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public 3 | -------------------------------------------------------------------------------- /unmanic/webserver/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 04 May 2020, (5:37 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /unmanic/webserver/api_v1/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 25 Oct 2020, (9:07 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | import warnings 35 | 36 | from .filebrowser_api import ApiFilebrowserHandler 37 | from .history_api import ApiHistoryHandler 38 | from .pending_api import ApiPendingHandler 39 | from .plugins_api import ApiPluginsHandler 40 | from .session_api import ApiSessionHandler 41 | 42 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 43 | 44 | __all__ = ( 45 | 'ApiFilebrowserHandler', 46 | 'ApiHistoryHandler', 47 | 'ApiPendingHandler', 48 | 'ApiPluginsHandler', 49 | 'ApiSessionHandler', 50 | ) 51 | -------------------------------------------------------------------------------- /unmanic/webserver/api_v2/README.md: -------------------------------------------------------------------------------- 1 | # Unmanic API 2 | 3 | ## Rules regarding endpoint creation: 4 | 1. All data will be returned in JSON format. 5 | 1. The success status of the data will be returned using HTTP status codes. 6 | - 200: for all successfully returned data. 7 | - 400: for errors caused by the client request. (self.STATUS_ERROR_EXTERNAL) 8 | - 404: for an incorrectly structured API endpoint. (self.STATUS_ERROR_ENDPOINT_NOT_FOUND) 9 | - 405: for a request to an API endpoint with a disallowed method. (self.STATUS_ERROR_METHOD_NOT_ALLOWED) 10 | - 500: status for internal errors and exception handling. (self.STATUS_ERROR_INTERNAL) 11 | 1. All unsuccessful return codes listed above should be executed with: 12 | ``` 13 | self.set_status(self.STATUS_ERROR_INTERNAL, reason="Unable to read privacy policy.") 14 | self.write_error() 15 | ``` 16 | This will provide an error message in the format of: 17 | ``` 18 | { 19 | "error": "500: Unable to read privacy policy.", 20 | "messages": {}, 21 | "traceback": [] 22 | } 23 | ``` 24 | 1. The returned 'error' message should not be parsed by the client application. This message is subject to change. 25 | 1. Catch all exceptions with: 26 | ``` 27 | try: 28 | ... 29 | except BaseApiError as bae: 30 | tornado.log.app_log.error("BaseApiError.{}: {}".format(self.route.get('call_method'), str(bae))) 31 | return 32 | except Exception as e: 33 | self.set_status(self.ERROR_INTERNAL, reason=str(e)) 34 | self.write_error() 35 | ``` 36 | 1. All endpoint functions must be wrapped in a broad exception capture as in the example above. 37 | -------------------------------------------------------------------------------- /unmanic/webserver/api_v2/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 25 Oct 2020, (9:07 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | 33 | from __future__ import absolute_import 34 | import warnings 35 | 36 | from .docs_api import ApiDocsHandler 37 | from .filebrowser_api import ApiFilebrowserHandler 38 | from .history_api import ApiHistoryHandler 39 | from .notifications_api import ApiNotificationsHandler 40 | from .pending_api import ApiPendingHandler 41 | from .plugins_api import ApiPluginsHandler 42 | from .session_api import ApiSessionHandler 43 | from .settings_api import ApiSettingsHandler 44 | from .upload_api import ApiUploadHandler 45 | from .version_api import ApiVersionHandler 46 | from .workers_api import ApiWorkersHandler 47 | 48 | __author__ = 'Josh.5 (jsunnex@gmail.com)' 49 | 50 | __all__ = ( 51 | 'ApiDocsHandler', 52 | 'ApiFilebrowserHandler', 53 | 'ApiHistoryHandler', 54 | 'ApiNotificationsHandler', 55 | 'ApiPendingHandler', 56 | 'ApiPluginsHandler', 57 | 'ApiSessionHandler', 58 | 'ApiSettingsHandler', 59 | 'ApiUploadHandler', 60 | 'ApiVersionHandler', 61 | 'ApiWorkersHandler' 62 | ) 63 | 64 | 65 | def list_all_handlers(): 66 | return __all__ 67 | -------------------------------------------------------------------------------- /unmanic/webserver/api_v2/schema/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 01 Aug 2021, (10:35 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /unmanic/webserver/docs/privacy_policy.md: -------------------------------------------------------------------------------- 1 | Your privacy is important. I, Josh Sunnex, am committed to being transparent and open. This Privacy Policy 2 | explains generally how I receive information about you, and what I do with that information once I have it. 3 | 4 | ## Definition of “personal information”? 5 | 6 | For me, “personal information” means information which identifies you, like your name or email address. 7 | 8 | Any information that falls outside of this is “non-personal information”. 9 | 10 | If I store your personal information with information that is non-personal, I will consider the combination 11 | as personal information. If I remove all personal information from a set of data then the remaining is 12 | non-personal information. 13 | 14 | ## How do I learn information about you? 15 | 16 | I learn information about you when: 17 | 18 | - You give it to me directly (e.g., when you choose to send me logs in the forums) 19 | - I collect it automatically through my software and services (e.g., when your Unmanic installation registers with the Unmanic site, or when your Unmanic installation connects with my servers to download plugins) 20 | - You visit the Unmanic website 21 | 22 | ## What do I do with your information once I have it? 23 | 24 | Generally, I use your information to help me provide and improve my software and services for you (e.g., I 25 | use a log you send me to figure out why Unmanic isn’t working correctly, or I determine how many active 26 | users are using Unmanic and on what platforms it is being used in order to determine how to allocate 27 | resources per platform). 28 | 29 | ## When do I share your information with others? 30 | 31 | The information that you provide me is intended for me alone. The only time I will share this information 32 | with a third party is when I have asked and received your permission to share it. 33 | 34 | ## How do I store and protect your personal information? 35 | 36 | I am committed to protecting your personal information once I have it. All information will be securely 37 | stored using best practices. Despite these efforts, if I learn of a security breach, I’ll notify you so 38 | that you can take appropriate protective steps. 39 | 40 | ## What if I change this privacy policy? 41 | 42 | I may need to change this policy. Updates to the policy will be amended here with a changelog at the 43 | bottom. 44 | If the changes are substantive, I will announce the update through social media channels. Your continued 45 | use of my products or services after the effective date of such changes constitutes your acceptance of such 46 | changes. To make your review more convenient, I will post an effective date at the top of the page. 47 | 48 | --- 49 | 50 |
51 | Effective Date: 52 | 21 March, 2021 53 |
54 | 55 | --- 56 | 57 | ## Changelog 58 | 59 | **21 March, 2021** 60 | - Initial policy 61 | -------------------------------------------------------------------------------- /unmanic/webserver/helpers/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.__init__.py 6 | 7 | Written by: Josh.5 8 | Date: 21 Oct 2020, (2:42 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | -------------------------------------------------------------------------------- /unmanic/webserver/helpers/documents.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.documents.py 6 | 7 | Written by: Josh.5 8 | Date: 25 Aug 2021, (2:59 PM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import os 33 | import zipfile 34 | 35 | from unmanic import config 36 | 37 | 38 | def generate_log_files_zip(): 39 | settings = config.Config() 40 | 41 | cache_path = settings.get_cache_path() 42 | logs_path = settings.get_log_path() 43 | 44 | # Ensure the cache path exists 45 | if not os.path.exists(cache_path): 46 | os.makedirs(cache_path) 47 | 48 | # Ensure the logs path exists 49 | if not os.path.exists(logs_path): 50 | os.makedirs(logs_path) 51 | 52 | # Create zip of all log files 53 | out_file = os.path.join(cache_path, 'UnmanicLogs.zip') 54 | with zipfile.ZipFile(out_file, 'w') as zip_object: 55 | # Iterate over all the files in directory 56 | for dir_name, subdirectories, filenames in os.walk(logs_path): 57 | for filename in filenames: 58 | # create complete filepath of file in directory 59 | logfile_path = os.path.join(dir_name, filename) 60 | # Add file to zip 61 | zip_object.write(logfile_path, os.path.basename(logfile_path)) 62 | 63 | return out_file 64 | -------------------------------------------------------------------------------- /unmanic/webserver/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | unmanic.main.py 6 | 7 | Written by: Josh.5 8 | Date: 06 Dec 2018, (7:21 AM) 9 | 10 | Copyright: 11 | Copyright (C) Josh Sunnex - All Rights Reserved 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 27 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 28 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 29 | OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | """ 32 | import tornado.web 33 | import tornado.websocket 34 | 35 | from unmanic.libs import session 36 | 37 | 38 | class MainUIRequestHandler(tornado.web.RequestHandler): 39 | name = None 40 | config = None 41 | session = None 42 | data_queues = None 43 | foreman = None 44 | components = None 45 | 46 | def initialize(self): 47 | self.name = 'main' 48 | self.session = session.Session() 49 | 50 | def get(self, path): 51 | self.set_header("Content-Type", "text/html") 52 | self.render("index.html") 53 | 54 | def handle_ajax_call(self, query): 55 | self.set_header("Content-Type", "application/json") 56 | if query == 'login': 57 | self.session.register_unmanic(force=True) 58 | self.redirect("/unmanic/ui/dashboard/") 59 | -------------------------------------------------------------------------------- /unmanic/webserver/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unmanic-webui", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "unmanic-webui", 9 | "version": "1.0.0", 10 | "license": "GPL-3.0", 11 | "dependencies": { 12 | "vendor-copy": "^3.0.1" 13 | }, 14 | "devDependencies": {}, 15 | "engines": { 16 | "node": ">=14.17.2", 17 | "npm": ">=6.14.13" 18 | } 19 | }, 20 | "node_modules/ncp": { 21 | "version": "2.0.0", 22 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", 23 | "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", 24 | "bin": { 25 | "ncp": "bin/ncp" 26 | } 27 | }, 28 | "node_modules/vendor-copy": { 29 | "version": "3.0.1", 30 | "resolved": "https://registry.npmjs.org/vendor-copy/-/vendor-copy-3.0.1.tgz", 31 | "integrity": "sha512-XjQ707tDNDVR9HBH2XoDffBB6em2QmWmD52uh8mt+KbFjv94DjDtz/Sh9lXSEWU1POg/fWXnjswe8hW5fqgL+w==", 32 | "dependencies": { 33 | "ncp": "^2.0.0" 34 | }, 35 | "bin": { 36 | "vendor-copy": "cli.js" 37 | }, 38 | "engines": { 39 | "node": ">=12" 40 | } 41 | } 42 | }, 43 | "dependencies": { 44 | "ncp": { 45 | "version": "2.0.0", 46 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", 47 | "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=" 48 | }, 49 | "vendor-copy": { 50 | "version": "3.0.1", 51 | "resolved": "https://registry.npmjs.org/vendor-copy/-/vendor-copy-3.0.1.tgz", 52 | "integrity": "sha512-XjQ707tDNDVR9HBH2XoDffBB6em2QmWmD52uh8mt+KbFjv94DjDtz/Sh9lXSEWU1POg/fWXnjswe8hW5fqgL+w==", 53 | "requires": { 54 | "ncp": "^2.0.0" 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /unmanic/webserver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unmanic-webui", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "Unmanic webui.", 6 | "author": "Josh.5", 7 | "license": "GPL-3.0", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/Unmanic/unmanic.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/Unmanic/unmanic/issues" 14 | }, 15 | "homepage": "https://unmanic.app", 16 | "engines": { 17 | "node": ">=14.17.2", 18 | "npm": ">=6.14.13" 19 | }, 20 | "scripts": { 21 | "build": "npm --prefix frontend run build && vendor-copy", 22 | "clean": "rimraf public" 23 | }, 24 | "keywords": [ 25 | ], 26 | "dependencies": { 27 | "vendor-copy": "^3.0.1" 28 | }, 29 | "devDependencies": { 30 | }, 31 | "vendorCopy": [ 32 | { 33 | "from": "frontend/dist/spa", 34 | "to": "public" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /unmanic/webserver/templates/global/insufficient-permissions.html: -------------------------------------------------------------------------------- 1 | 49 | -------------------------------------------------------------------------------- /unmanic/webserver/templates/global/login-popup.html: -------------------------------------------------------------------------------- 1 | 48 | -------------------------------------------------------------------------------- /unmanic/webserver/templates/global/support-future-development.html: -------------------------------------------------------------------------------- 1 | 49 | --------------------------------------------------------------------------------