diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml new file mode 100644 index 00000000..65dae581 --- /dev/null +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -0,0 +1,49 @@ +name: pre-commit + +permissions: + contents: write + pull-requests: write + +concurrency: + group: pre-commit-${{ github.ref }}-autoupdate + cancel-in-progress: true + +on: + schedule: + - cron: '0 3 * * 1' + workflow_dispatch: + +jobs: + autoupdate: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Cache asdf + uses: actions/cache@v4 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: | + ${{ runner.os }}-asdf- + - uses: asdf-vm/actions/install@v4 + - name: Run pre-commit autoupdate + id: pre_commit_autoupdate + run: | + pre-commit autoupdate + if git diff --quiet ".pre-commit-config.yaml"; then + echo "No changes to commit" + echo "autoupdate=false" >> "$GITHUB_ENV" + exit 0 + fi + echo "autoupdate=true" >> "$GITHUB_ENV" + - name: Create Pull Request + if: success() && steps.pre_commit_autoupdate.outcome == 'success' && env.autoupdate == 'true' + uses: peter-evans/create-pull-request@v7 + with: + title: "chore(pre-commit): autoupdate hooks" + body: "Automated pre-commit autoupdate." + commit-message: "chore(pre-commit): autoupdate hooks" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000..71f0488f --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,28 @@ +name: pre-commit + +concurrency: + group: pre-commit-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + push: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Cache asdf + uses: actions/cache@v4 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: | + ${{ runner.os }}-asdf- + - uses: asdf-vm/actions/install@v4 + - uses: pre-commit/action@v3.0.1 +# env: +# SKIP: hook-id-to-skip diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml deleted file mode 100644 index 1ca6a8ff..00000000 --- a/.github/workflows/test-deploy.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Test deployment -defaults: - run: - shell: bash - working-directory: ./documentation - -on: - pull_request: - branches: - - master - -jobs: - test-deploy: - name: Test deployment - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Get Node.js version from .tool-versions - id: node-version - run: echo "NODE_VERSION=$(cat .tool-versions | egrep nodejs | awk '{print $2}' | xargs)" >> $GITHUB_ENV - - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: npm - cache-dependency-path: ./documentation/package-lock.json - - - name: Install dependencies - run: npm ci - - name: Test build website - run: npm run build \ No newline at end of file diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml new file mode 100644 index 00000000..924a79ed --- /dev/null +++ b/.github/workflows/test-docs.yml @@ -0,0 +1,32 @@ +name: test-docs +defaults: + run: + shell: bash + +on: + pull_request: + branches: + - master + +jobs: + generate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Cache asdf + uses: actions/cache@v4 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('.tool-versions') }} + restore-keys: | + ${{ runner.os }}-asdf- + - uses: asdf-vm/actions/install@v4 + - name: Install Python dependencies + run: | + pip install --upgrade pip + pip install -r requirements.txt + pip install -r requirements-dev.txt + - run: task docs diff --git a/.gitignore b/.gitignore index dc74be3f..46964152 100644 --- a/.gitignore +++ b/.gitignore @@ -401,4 +401,4 @@ FodyWeavers.xsd *.sln.iml # Test resources -tests/resources/config-test.json \ No newline at end of file +tests/resources/config-test.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70a0b1a9..403aaca6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ ci: - skip: [ pytest ] + skip: [pytest] default_language_version: python: python3.13 -default_install_hook_types: [ pre-commit, pre-push, commit-msg ] -default_stages: [ pre-commit, pre-push, commit-msg ] +default_install_hook_types: [pre-commit, pre-push, commit-msg] +default_stages: [pre-commit, pre-push, commit-msg] repos: # general checks (see here: https://pre-commit.com/hooks.html) @@ -23,6 +23,7 @@ repos: - repo: https://github.com/numpy/numpydoc rev: v1.9.0 - stages: [ pre-commit ] hooks: - - id: numpydoc-validation \ No newline at end of file + - id: numpydoc-validation + stages: [pre-commit, manual] + files: ^synology_api/ diff --git a/.tool-versions b/.tool-versions index 5761f346..8eb21b90 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ nodejs 18.18.0 -python 3.9.6 +python 3.13.5 task 3.44.0 shfmt 3.11.0 shellcheck 0.10.0 diff --git a/Taskfile.yml b/Taskfile.yml index 7dc49a86..03b21bf5 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -36,7 +36,7 @@ tasks: dir: '{{.TASKFILE_DIR}}' cmds: - echo "Parsing the documentation files..." - - python3 docs_parser.py -a + - python3 docs_parser.py -a --exit-on-warning docs-build: desc: Build the documentation website @@ -96,3 +96,17 @@ tasks: cmds: - echo "Validating numpydoc format..." - pre-commit run numpydoc-validation -a + + numpydoc-lint: + desc: Lint the numpydoc format of the documentation + dir: '{{.TASKFILE_DIR}}' + cmds: + - echo "Linting numpydoc format..." + - pydocstringformatter -w ./synology_api/ + + numpydoc: + desc: Lint and validate the numpydoc format of the documentation + dir: '{{.TASKFILE_DIR}}' + cmds: + - task: numpydoc-lint + - task: numpydoc-validation diff --git a/docs_parser.py b/docs_parser.py index 7ce686ba..0ccf852c 100644 --- a/docs_parser.py +++ b/docs_parser.py @@ -178,6 +178,9 @@ def init_parser() -> argparse.ArgumentParser: parser.add_argument('-e', '--excluded', action='store_true', help='Show a list of the excluded files to parse.') + parser.add_argument('--exit-on-warning', + action='store_true', + help='Exit if a warning is encountered.') return parser @@ -388,13 +391,38 @@ def write(path: str, content: str): f.write(content) +class WarningCatcher: + def __init__(self): + self.warnings = [] + + def __call__(self, message, category, filename, lineno, file=None, line=None): + msg = warnings.formatwarning(message, category, filename, lineno, line) + self.warnings.append(msg) + + def has_warnings(self): + return bool(self.warnings) + + def print_warnings(self): + for w in self.warnings: + print(w, end='') + + def main(): parser = init_parser() files, parse_api_list, parse_docs = validate_args(parser) + # Setup warning catcher + warning_catcher = WarningCatcher() + warnings.showwarning = warning_catcher + # Generation for Getting Started/Supported APIs with all the APIs user per class. supported_apis = gen_supported_apis() + # Check if --exit-on-warning flag is set + exit_on_warning = any(arg in ('--exit-on-warning',) for arg in sys.argv) + + any_warning = False + for file_name in files: doc_content = '' file_path = join(PARSE_DIR, file_name) @@ -427,10 +455,18 @@ def main(): if parse_docs: write(DOCS_DIR + file_name.replace('.py', '.md'), doc_content) print('='*20) + + if warning_catcher.has_warnings(): + any_warning = True + # else: continue to process all files + # Write to md files if the args were set if parse_api_list: write(API_LIST_FILE, supported_apis) + if any_warning and exit_on_warning: + sys.exit(1) + if __name__ == "__main__": main() diff --git a/documentation/docs/apis/classes/abm.md b/documentation/docs/apis/classes/abm.md index e5f0b4af..d9b4812e 100644 --- a/documentation/docs/apis/classes/abm.md +++ b/documentation/docs/apis/classes/abm.md @@ -9,27 +9,27 @@ title: ✅ ActiveBackupMicrosoft # ActiveBackupMicrosoft ## Overview -Active Backup for Microsoft 365 Implementation. - -### Supported methods - -- **Getters** : - - Get all tasks info - - Get task settings - - Get task logs - - Get package logs - - Get worker settings - -- **Setters** : - - Set worker settings - - Set task schedule policy - - Set task retention policy - -- **Actions** : - - Run backup - - Cancel backup - - Delete task - - Relink task +Active Backup for Microsoft 365 Implementation. + + ### Supported methods + + - **Getters** : + - Get all tasks info + - Get task settings + - Get task logs + - Get package logs + - Get worker settings + + - **Setters** : + - Set worker settings + - Set task schedule policy + - Set task retention policy + + - **Actions** : + - Run backup + - Cancel backup + - Delete task + - Relink task ## Methods ### `get_tasks` Retrieve all tasks. @@ -49,202 +49,202 @@ A dictionary containing the list of tasks.
Click to expand ```json -{ - "data": { - event_log: [ - { - "description": "Backup task [test] completed.", - "error_code": 0, - "last_execution_time": 1733794236, - "log_type": 0, - "task_execution_id": 1, - "task_id": 1, - "timestamp": 1733794236 - }, - ], - service_usage: [ - { - "service_type": 0, - "storage_usage": 319196921578 - }, - { - "service_type": 1, - "storage_usage": 1211160588 - }, - { - "service_type": 4, - "storage_usage": 9704366035 - }, - { - "service_type": 2, - "storage_usage": 259976 - }, - { - "service_type": 3, - "storage_usage": 2561252 - }, - { - "service_type": 5, - "storage_usage": 21544726 - }, - { - "service_type": 8, - "storage_usage": 0 - }, - { - "service_type": 6, - "storage_usage": 0 - }, - { - "service_type": 7, - "storage_usage": 0 - }, - { - "service_type": 9, - "storage_usage": 46484 - } - ], - tasks: [ - { - "archive_mail_used_storage": 9704366035, - "attention_count": 0, - "backup_policy": 1, - "calendar_used_storage": 2561252, - "contact_used_storage": 259976, - "drive_used_storage": 319196921578, - "duration": 22553, - "enable_archive_mail": 1, - "enable_calendar": 1, - "enable_contact": 1, - "enable_drive": 1, - "enable_exchange": 1, - "enable_group": 0, - "enable_group_calendar": 0, - "enable_group_mail": 0, - "enable_mail": 1, - "enable_mysite": 0, - "enable_schedule": false, - "enable_site": 1, - "enable_teams": 1, - "error_archive_mail": 0, - "error_calendar": 0, - "error_contact": 0, - "error_drive": 0, - "error_group_calendar": 0, - "error_group_mail": 0, - "error_mail": 0, - "error_site": 0, - "error_teams": 0, - "group_calendar_used_storage": 0, - "group_mail_used_storage": 0, - "job_id": 0, - "last_execution_time": 1733794235, - "mail_used_storage": 1211160588, - "mysite_used_storage": 0, - "processed_archive_mail": 1, - "processed_calendar": 1, - "processed_contact": 1, - "processed_drive": 1, - "processed_group_calendar": 0, - "processed_group_mail": 0, - "processed_mail": 1, - "processed_site": 1, - "processed_teams": 1, - "progress_list": [], - "region": 0, - "schedule": { - "date": "2025/1/26", - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "minute": 0, - "monthly_week": [], - "repeat_date": 0, - "repeat_hour": 0, - "repeat_hour_store_config": null, - "repeat_min": 0, - "repeat_min_store_config": null, - "week_day": "0,1,2,3,4,5,6" + { + "data": { + event_log: [ + { + "description": "Backup task [test] completed.", + "error_code": 0, + "last_execution_time": 1733794236, + "log_type": 0, + "task_execution_id": 1, + "task_id": 1, + "timestamp": 1733794236 }, - "schedule_id": 4, - "site_used_storage": 21544726, - "status": 1, - "status_archive_mail": 1, - "status_calendar": 1, - "status_contact": 1, - "status_drive": 1, - "status_group_calendar": 0, - "status_group_mail": 0, - "status_mail": 1, - "status_site": 1, - "status_teams": 1, - "success_count": 3, - "task_execution_id": 1, - "task_id": 1, - "task_name": "test", - "task_status": 2, - "task_status_error_code": 0, - "teams_used_storage": 46484, - "transferred_size_archive_mail": 9704366035, - "transferred_size_calendar": 2561252, - "transferred_size_contact": 259976, - "transferred_size_drive": 319196921578, - "transferred_size_group_calendar": 0, - "transferred_size_group_mail": 0, - "transferred_size_mail": 1211160588, - "transferred_size_site": 21544726, - "transferred_size_teams": 46484, - "upgrade_progress": 0, - "warning_archive_mail": 0, - "warning_calendar": 0, - "warning_contact": 0, - "warning_drive": 0, - "warning_group_calendar": 0, - "warning_group_mail": 0, - "warning_mail": 0, - "warning_site": 0, - "warning_teams": 0 - } - ], - users: [ - { - "display_name": "username", - "original_name": "username@xxxx.onmicrosoft.com", - "service_list": [ - 0, - 1, - 4, - 2, - 3 - ], - "task_name": "test", - "type": 0, - "usage_percentage": 99.99345992145251, - "usage_total": 330115269429 - }, - { - "display_name": "sharepoint site", - "original_name": "https://xxx.sharepoint.com/sites/sharepointsite", - "service_list": [], - "task_name": "test", - "type": 1, - "usage_percentage": 0.006525998326360428, - "usage_total": 21544726 - }, - { - "display_name": "test team", - "original_name": "https://teams.microsoft.com/l/team/xxxx", - "service_list": [], - "task_name": "test", - "type": 4, - "usage_percentage": 0.000014080221127088742, - "usage_total": 46484 - } - ] - }, - "success": true -} -``` + ], + service_usage: [ + { + "service_type": 0, + "storage_usage": 319196921578 + }, + { + "service_type": 1, + "storage_usage": 1211160588 + }, + { + "service_type": 4, + "storage_usage": 9704366035 + }, + { + "service_type": 2, + "storage_usage": 259976 + }, + { + "service_type": 3, + "storage_usage": 2561252 + }, + { + "service_type": 5, + "storage_usage": 21544726 + }, + { + "service_type": 8, + "storage_usage": 0 + }, + { + "service_type": 6, + "storage_usage": 0 + }, + { + "service_type": 7, + "storage_usage": 0 + }, + { + "service_type": 9, + "storage_usage": 46484 + } + ], + tasks: [ + { + "archive_mail_used_storage": 9704366035, + "attention_count": 0, + "backup_policy": 1, + "calendar_used_storage": 2561252, + "contact_used_storage": 259976, + "drive_used_storage": 319196921578, + "duration": 22553, + "enable_archive_mail": 1, + "enable_calendar": 1, + "enable_contact": 1, + "enable_drive": 1, + "enable_exchange": 1, + "enable_group": 0, + "enable_group_calendar": 0, + "enable_group_mail": 0, + "enable_mail": 1, + "enable_mysite": 0, + "enable_schedule": false, + "enable_site": 1, + "enable_teams": 1, + "error_archive_mail": 0, + "error_calendar": 0, + "error_contact": 0, + "error_drive": 0, + "error_group_calendar": 0, + "error_group_mail": 0, + "error_mail": 0, + "error_site": 0, + "error_teams": 0, + "group_calendar_used_storage": 0, + "group_mail_used_storage": 0, + "job_id": 0, + "last_execution_time": 1733794235, + "mail_used_storage": 1211160588, + "mysite_used_storage": 0, + "processed_archive_mail": 1, + "processed_calendar": 1, + "processed_contact": 1, + "processed_drive": 1, + "processed_group_calendar": 0, + "processed_group_mail": 0, + "processed_mail": 1, + "processed_site": 1, + "processed_teams": 1, + "progress_list": [], + "region": 0, + "schedule": { + "date": "2025/1/26", + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "minute": 0, + "monthly_week": [], + "repeat_date": 0, + "repeat_hour": 0, + "repeat_hour_store_config": null, + "repeat_min": 0, + "repeat_min_store_config": null, + "week_day": "0,1,2,3,4,5,6" + }, + "schedule_id": 4, + "site_used_storage": 21544726, + "status": 1, + "status_archive_mail": 1, + "status_calendar": 1, + "status_contact": 1, + "status_drive": 1, + "status_group_calendar": 0, + "status_group_mail": 0, + "status_mail": 1, + "status_site": 1, + "status_teams": 1, + "success_count": 3, + "task_execution_id": 1, + "task_id": 1, + "task_name": "test", + "task_status": 2, + "task_status_error_code": 0, + "teams_used_storage": 46484, + "transferred_size_archive_mail": 9704366035, + "transferred_size_calendar": 2561252, + "transferred_size_contact": 259976, + "transferred_size_drive": 319196921578, + "transferred_size_group_calendar": 0, + "transferred_size_group_mail": 0, + "transferred_size_mail": 1211160588, + "transferred_size_site": 21544726, + "transferred_size_teams": 46484, + "upgrade_progress": 0, + "warning_archive_mail": 0, + "warning_calendar": 0, + "warning_contact": 0, + "warning_drive": 0, + "warning_group_calendar": 0, + "warning_group_mail": 0, + "warning_mail": 0, + "warning_site": 0, + "warning_teams": 0 + } + ], + users: [ + { + "display_name": "username", + "original_name": "username@xxxx.onmicrosoft.com", + "service_list": [ + 0, + 1, + 4, + 2, + 3 + ], + "task_name": "test", + "type": 0, + "usage_percentage": 99.99345992145251, + "usage_total": 330115269429 + }, + { + "display_name": "sharepoint site", + "original_name": "https://xxx.sharepoint.com/sites/sharepointsite", + "service_list": [], + "task_name": "test", + "type": 1, + "usage_percentage": 0.006525998326360428, + "usage_total": 21544726 + }, + { + "display_name": "test team", + "original_name": "https://teams.microsoft.com/l/team/xxxx", + "service_list": [], + "task_name": "test", + "type": 4, + "usage_percentage": 0.000014080221127088742, + "usage_total": 46484 + } + ] + }, + "success": true + } + ```
@@ -280,45 +280,45 @@ A dictionary containing the list of logs.
Click to expand ```json -{ - "data": { - "logs": [ - { - "category": 0, - "description": "Backup task [test] completed.", - "error_code": 0, - "log_type": 0, - "storage_remove_id": 0, - "task_execution_id": 1, - "task_id": 1, - "timestamp": 1733794236 - }, - { - "category": 3, - "description": "[user] ran backup task [test].", - "error_code": 0, - "log_type": 0, - "storage_remove_id": 0, - "task_execution_id": 0, - "task_id": 1, - "timestamp": 1733771681 - }, - { - "category": 3, - "description": "[user] created task [test].", - "error_code": 0, - "log_type": 0, - "storage_remove_id": 0, - "task_execution_id": 0, - "task_id": 1, - "timestamp": 1733771267 - } - ], - "offset": 0 - }, - "success": true -} -``` + { + "data": { + "logs": [ + { + "category": 0, + "description": "Backup task [test] completed.", + "error_code": 0, + "log_type": 0, + "storage_remove_id": 0, + "task_execution_id": 1, + "task_id": 1, + "timestamp": 1733794236 + }, + { + "category": 3, + "description": "[user] ran backup task [test].", + "error_code": 0, + "log_type": 0, + "storage_remove_id": 0, + "task_execution_id": 0, + "task_id": 1, + "timestamp": 1733771681 + }, + { + "category": 3, + "description": "[user] created task [test].", + "error_code": 0, + "log_type": 0, + "storage_remove_id": 0, + "task_execution_id": 0, + "task_id": 1, + "timestamp": 1733771267 + } + ], + "offset": 0 + }, + "success": true + } + ```
@@ -360,39 +360,39 @@ A dictionary containing the list of logs.
Click to expand ```json -{ - "data": { - "logs": [ - { - "description": "User [username@xxxx.onmicrosoft.com]'s OneDrive data was backed up (success: 34177; warning: 0; error: 0).", - "error_code": 0, - "log_type": 0, - "task_execution_id": 1, - "task_id": 1, - "timestamp": 1733780274 - }, - { - "description": "The data of site [test site] was backed up (List: success: 6, warning: 0, error: 0; Document library: success: 13, warning: 0, error: 0; Document library item: success: 288, warning: 0, error: 0).", - "error_code": 0, - "log_type": 0, - "task_execution_id": 1, - "task_id": 1, - "timestamp": 1733771918 - }, - { - "description": "The data of team [test team] was backed up (Channel: success: 3, warning: 0, error: 0; Post: success: 18, warning: 0, error: 0).", - "error_code": 0, - "log_type": 0, - "task_execution_id": 1, - "task_id": 1, - "timestamp": 1733771786 - } - ], - "offset": 0 - }, - "success": true -} -``` + { + "data": { + "logs": [ + { + "description": "User [username@xxxx.onmicrosoft.com]'s OneDrive data was backed up (success: 34177; warning: 0; error: 0).", + "error_code": 0, + "log_type": 0, + "task_execution_id": 1, + "task_id": 1, + "timestamp": 1733780274 + }, + { + "description": "The data of site [test site] was backed up (List: success: 6, warning: 0, error: 0; Document library: success: 13, warning: 0, error: 0; Document library item: success: 288, warning: 0, error: 0).", + "error_code": 0, + "log_type": 0, + "task_execution_id": 1, + "task_id": 1, + "timestamp": 1733771918 + }, + { + "description": "The data of team [test team] was backed up (Channel: success: 3, warning: 0, error: 0; Post: success: 18, warning: 0, error: 0).", + "error_code": 0, + "log_type": 0, + "task_execution_id": 1, + "task_id": 1, + "timestamp": 1733771786 + } + ], + "offset": 0 + }, + "success": true + } + ```
@@ -410,7 +410,7 @@ Retrieve the settings of a task. #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task. @@ -425,150 +425,150 @@ A dictionary containing the settings of the task.
Click to expand ```json -{ - "data": { - "task_info": { - "administrator_account_email": "username@xxxx.onmicrosoft.com", - "app_permissions": [...], - "application_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "backup_policy": 1, - "enable_auto_add_archive_mail": false, - "enable_auto_add_calendar": false, - "enable_auto_add_contact": false, - "enable_auto_add_drive": false, - "enable_auto_add_mail": false, - "enable_auto_discover_external_account": true, - "enable_auto_discover_general_site": false, - "enable_auto_discover_group_alias_archive_mail": false, - "enable_auto_discover_group_alias_calendar": false, - "enable_auto_discover_group_alias_contact": false, - "enable_auto_discover_group_alias_drive": false, - "enable_auto_discover_group_alias_mail": false, - "enable_auto_discover_group_calendar": false, - "enable_auto_discover_group_mail": false, - "enable_auto_discover_my_site": false, - "enable_auto_discover_teams": false, - "enable_auto_discover_unlicensed_account": true, - "enable_schedule": false, - "enable_user_restore": true, - "is_customized_app": true, - "is_team_list_ready": true, - "local_path": "/datastore/ActiveBackupForMicrosoft365/task_1", - "preserve_day_number": 30, - "region": 0, - "rotation_policy": 0, - "schedule": { - "date": "2025/1/26", - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "minute": 0, - "monthly_week": [], - "repeat_date": 0, - "repeat_hour": 0, - "repeat_hour_store_config": null, - "repeat_min": 0, - "repeat_min_store_config": null, - "week_day": "0,1,2,3,4,5,6" - }, - "schedule_id": 4, - "site_domain": "https://xxxx.sharepoint.com", - "task_id": 1, - "task_name": "test", - "task_status": 2, - "task_status_error_code": 0, - "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "user_list": [ - { - "account_status": 1, - "account_type": 2, - "email": "username@xxxx.onmicrosoft.com", - "enable_archive_mail": false, - "enable_calendar": false, - "enable_contact": false, - "enable_drive": false, - "enable_mail": false, - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "local_used_storage": 0, - "smtp_mail": "", - "user_name": "username" - } - ], - "group_list": [ - { - "description": "test group", - "display_name": "test group", - "enable_calendar": false, - "enable_group_alias_archive_mail": false, - "enable_group_alias_calendar": false, - "enable_group_alias_contact": false, - "enable_group_alias_drive": false, - "enable_group_alias_mail": false, - "enable_mail": false, - "group_status": 1, - "group_type": 0, - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "local_used_storage": 0, - "mail": "test_group@xxxx.onmicrosoft.com", - "mail_nickname": "test group", - "owners": [], - "title": "test group", - "visibility": "Private" - }, - ], - "team_list": [ - { - "description": "test team", - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "local_used_storage": 0, - "name": "test team", - "selected": false, - "team_status": 1, - "visibility": 0, - "web_url": "https://teams.microsoft.com/l/team/xxxx" - }, - ], - "my_site_list": [ - { - "description": "", - "id": 313, - "local_used_storage": 0, - "owner_type": 0, - "parent_id": "", - "primary_admin": "username@xxxx.onmicrosoft.com", - "selected": false, - "site_collection_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "site_name": "username", - "site_root": "https://xxxx-my.sharepoint.com", - "site_status": 1, - "site_type": 1, - "url": "https://xxxx-my.sharepoint.com/personal/username" - }, - ], - "general_site_list": [ - { - "description": "", - "id": 1, - "local_used_storage": 0, - "owner_type": 0, - "parent_id": "", - "primary_admin": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "selected": false, - "site_collection_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", - "site_name": "test sharepoint", - "site_root": "https://xxxx.sharepoint.com", - "site_status": 1, - "site_type": 0, - "url": "https://xxxx.sharepoint.com" + { + "data": { + "task_info": { + "administrator_account_email": "username@xxxx.onmicrosoft.com", + "app_permissions": [...], + "application_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "backup_policy": 1, + "enable_auto_add_archive_mail": false, + "enable_auto_add_calendar": false, + "enable_auto_add_contact": false, + "enable_auto_add_drive": false, + "enable_auto_add_mail": false, + "enable_auto_discover_external_account": true, + "enable_auto_discover_general_site": false, + "enable_auto_discover_group_alias_archive_mail": false, + "enable_auto_discover_group_alias_calendar": false, + "enable_auto_discover_group_alias_contact": false, + "enable_auto_discover_group_alias_drive": false, + "enable_auto_discover_group_alias_mail": false, + "enable_auto_discover_group_calendar": false, + "enable_auto_discover_group_mail": false, + "enable_auto_discover_my_site": false, + "enable_auto_discover_teams": false, + "enable_auto_discover_unlicensed_account": true, + "enable_schedule": false, + "enable_user_restore": true, + "is_customized_app": true, + "is_team_list_ready": true, + "local_path": "/datastore/ActiveBackupForMicrosoft365/task_1", + "preserve_day_number": 30, + "region": 0, + "rotation_policy": 0, + "schedule": { + "date": "2025/1/26", + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "minute": 0, + "monthly_week": [], + "repeat_date": 0, + "repeat_hour": 0, + "repeat_hour_store_config": null, + "repeat_min": 0, + "repeat_min_store_config": null, + "week_day": "0,1,2,3,4,5,6" }, - ], + "schedule_id": 4, + "site_domain": "https://xxxx.sharepoint.com", + "task_id": 1, + "task_name": "test", + "task_status": 2, + "task_status_error_code": 0, + "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "user_list": [ + { + "account_status": 1, + "account_type": 2, + "email": "username@xxxx.onmicrosoft.com", + "enable_archive_mail": false, + "enable_calendar": false, + "enable_contact": false, + "enable_drive": false, + "enable_mail": false, + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "local_used_storage": 0, + "smtp_mail": "", + "user_name": "username" + } + ], + "group_list": [ + { + "description": "test group", + "display_name": "test group", + "enable_calendar": false, + "enable_group_alias_archive_mail": false, + "enable_group_alias_calendar": false, + "enable_group_alias_contact": false, + "enable_group_alias_drive": false, + "enable_group_alias_mail": false, + "enable_mail": false, + "group_status": 1, + "group_type": 0, + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "local_used_storage": 0, + "mail": "test_group@xxxx.onmicrosoft.com", + "mail_nickname": "test group", + "owners": [], + "title": "test group", + "visibility": "Private" + }, + ], + "team_list": [ + { + "description": "test team", + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "local_used_storage": 0, + "name": "test team", + "selected": false, + "team_status": 1, + "visibility": 0, + "web_url": "https://teams.microsoft.com/l/team/xxxx" + }, + ], + "my_site_list": [ + { + "description": "", + "id": 313, + "local_used_storage": 0, + "owner_type": 0, + "parent_id": "", + "primary_admin": "username@xxxx.onmicrosoft.com", + "selected": false, + "site_collection_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "site_name": "username", + "site_root": "https://xxxx-my.sharepoint.com", + "site_status": 1, + "site_type": 1, + "url": "https://xxxx-my.sharepoint.com/personal/username" + }, + ], + "general_site_list": [ + { + "description": "", + "id": 1, + "local_used_storage": 0, + "owner_type": 0, + "parent_id": "", + "primary_admin": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "selected": false, + "site_collection_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx", + "site_name": "test sharepoint", + "site_root": "https://xxxx.sharepoint.com", + "site_status": 1, + "site_type": 0, + "url": "https://xxxx.sharepoint.com" + }, + ], + }, }, - }, - "success": true -} -``` + "success": true + } + ```
@@ -594,16 +594,16 @@ A dictionary containing the number of workers.
Click to expand ```json -{ - "data": { - "backup_job_worker_count": 40, - "event_worker_count": 40, - "max_backup_job_worker_count": 40, - "max_event_worker_count": 40 - }, - "success": true -} -``` + { + "data": { + "backup_job_worker_count": 40, + "event_worker_count": 40, + "max_backup_job_worker_count": 40, + "max_event_worker_count": 40 + }, + "success": true + } + ```
@@ -621,10 +621,10 @@ Set the number of workers for the Active Backup for Microsoft 365 package. #### Parameters
-**_backup_job_workers_** `int ` +**_backup_job_workers_** `int` Maximum number of concurrent backup accounts. Defaults to `40`. -**_event_workers_** `int ` +**_event_workers_** `int` Maximum number of concurrent backup files. Defaults to `40`. @@ -639,10 +639,10 @@ A dictionary containing the result of the worker count update.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -651,7 +651,7 @@ A dictionary containing the result of the worker count update. ### `set_task_schedule` -Set the schedule for a given task. +Set the schedule for a given task. #### Internal API
@@ -664,27 +664,27 @@ Set the schedule for a given task. The ID of the task. **_policy_** `int` -The schedule policy. -Possible values: -- 0 = continuous -- 1 = manual -- 2 = scheduled +The schedule policy. +Possible values: +- 0 = continuous +- 1 = manual +- 2 = scheduled. **_schedule_** `dict` -A dictionary containing the schedule settings. +A dictionary containing the schedule settings. Possible values: - `start_hour` (int): The start hour of the schedule. - `start_minute` (int): The start minute of the schedule. - `last_run_hour` (int): The last run hour of the schedule. - `repeat_every_hours` (int): Run the backup every X hours. -- `run_days` (list[int]): Run the backup at the specified days (Sunday = 0, Morning = 1, and so on...). +- `run_days` (list[int]): Run the backup at the specified days (Sunday = 0, Morning = 1, and so on...). :::note If `repeat_every_hours` is set to 0, the backup will run once a day. ::: -Example, to run the backup every day hourly starting at 08:30 until 23:30. +Examples, to run the backup every day hourly starting at 08:30 until 23:30. ```json { "start_hour": 8, @@ -706,11 +706,11 @@ A dictionary containing the result of the schedule update. #### Example return
Click to expand -```json -{ - "success": true -} -``` +```json + { + "success": true + } + ```
@@ -745,11 +745,11 @@ A dictionary containing the result of the rotation policy update. #### Example return
Click to expand -```json -{ - "success": true -} -``` +```json + { + "success": true + } + ```
@@ -782,10 +782,10 @@ A dictionary containing the result of the backup task.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -817,11 +817,11 @@ A dictionary containing the result of the task cancellation. #### Example return
Click to expand -```json -{ - "success": true -} -``` +```json + { + "success": true + } + ```
@@ -867,11 +867,11 @@ A dictionary containing the result of the task deletion. #### Example return
Click to expand -```json -{ - "success": true -} -``` +```json + { + "success": true + } + ```
@@ -892,19 +892,19 @@ Relink a task. **_task_name_** `str` The name of the task. -**_shared_folder_** `str` -The name of the shared folder where the task is stored. -Example: `ActiveBackupforBusiness` +**_local_shared_** `str` +The name of the shared folder where the task is stored. +Examples: `ActiveBackupforBusiness`. -**_task_path_** `str` -The relative path from the the shared folder where the task is stored. -Example: `/ActiveBackupForMicrosoft365/task_1` +**_local_path_** `str` +The relative path from the shared folder where the task is stored. +Examples: `/ActiveBackupForMicrosoft365/task_1`. **_admin_email_** `str` The email of the Microsoft 365 administrator. **_region_** `str` -The region of the Microsoft 365 account. Defaults to `Microsoft 365` +The region of the Microsoft 365 account. Defaults to `Microsoft 365`.
@@ -917,14 +917,14 @@ A dictionary containing the result of the task relinking. #### Example return
Click to expand -```json -{ - "data": { - "task_id": 3 - }, - "success": true -} -``` +```json + { + "data": { + "task_id": 3 + }, + "success": true + } + ```
diff --git a/documentation/docs/apis/classes/audiostation.md b/documentation/docs/apis/classes/audiostation.md index 4c0d220d..f90322fd 100644 --- a/documentation/docs/apis/classes/audiostation.md +++ b/documentation/docs/apis/classes/audiostation.md @@ -14,9 +14,22 @@ This API is not documented yet. ::: ## Overview - +A class to interact with Synology AudioStation API. ## Methods ### `get_info` +Retrieve general information about the AudioStation service. + +#### Internal API +
+`SYNO.AudioStation.Info` +
+ +#### Returns +
+`dict[str, object]` +A dictionary containing the service information or a string in case of an error. + +
@@ -24,6 +37,19 @@ This API is not documented yet. ### `get_playlist_info` +Retrieve information about playlists in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.Playlist` +
+ +#### Returns +
+`dict[str, object]` +A dictionary containing playlist information or a string in case of an error. + +
@@ -31,6 +57,19 @@ This API is not documented yet. ### `list_remote_player` +Retrieve a list of remote players available in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Returns +
+`dict[str, object]` +A dictionary containing information about remote players, or a string in case of an error. + +
@@ -38,6 +77,19 @@ This API is not documented yet. ### `list_pinned_song` +Retrieve a list of pinned songs in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.Pin` +
+ +#### Returns +
+`dict[str, object]` +A dictionary containing information about pinned songs, or a string in case of an error. + +
@@ -45,6 +97,26 @@ This API is not documented yet. ### `device_id` +Retrieve the playlist for a specific remote device in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Parameters +
+**_device_** `str` +The ID of the remote device. + + +
+#### Returns +
+`dict[str, object]` +A dictionary containing the playlist information for the specified device. + +
@@ -52,6 +124,26 @@ This API is not documented yet. ### `remote_play` +Start playback on a specified remote device in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Parameters +
+**_device_** `str` +The ID of the remote device on which to start playback. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the playback status or a string in case of an error. + +
@@ -59,6 +151,26 @@ This API is not documented yet. ### `remote_stop` +Stop playback on a specified remote device in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Parameters +
+**_device_** `str` +The ID of the remote device on which to stop playback. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the stop status or a string in case of an error. + +
@@ -66,6 +178,26 @@ This API is not documented yet. ### `remote_next` +Skip to the next track on a specified remote device in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Parameters +
+**_device_** `str` +The ID of the remote device on which to skip to the next track. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the status of the operation or a string in case of an error. + +
@@ -73,6 +205,26 @@ This API is not documented yet. ### `remote_prev` +Skip to the previous track on a specified remote device in AudioStation. + +#### Internal API +
+`SYNO.AudioStation.RemotePlayer` +
+ +#### Parameters +
+**_device_** `str` +The ID of the remote device on which to skip to the previous track. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the status of the operation or a string in case of an error. + +
diff --git a/documentation/docs/apis/classes/cloud_sync.md b/documentation/docs/apis/classes/cloud_sync.md index 3e6cf811..acf9795e 100644 --- a/documentation/docs/apis/classes/cloud_sync.md +++ b/documentation/docs/apis/classes/cloud_sync.md @@ -11,45 +11,44 @@ title: ✅ CloudSync ## Overview Cloud Sync API implementation. -This API provides the functionality to get information related to the package settings and current connections and tasks. -It also provides functionalities to set most of the settings for tasks and package configuration, as well as manage the current syncing processes. - -Due to the vast amount of public clouds available in the project, the API was not tested for every cloud scenario, so some params request may be missing in specific not tested clouds. - -The tested clouds so far are: -- Google Drive -- OneDrive -- DropBox -- Amazon S3 (task creation) - -### Supported methods - - - **Getters** : - - Get package settings - - Get connections - - Get connections settings - - Get connection information - - Get connection auth information - - Get connection logs - - Get connection tasks - - Get task filters - - Get task synced remote directories - - Get recently modified & currently syncing files - - **Setters** : - - Set package settings - - Set relink behavior - - Set connection settings - - Set connection schedule settings - - Set task settings - - Set task filters - - **Actions** : - - Pause connection - - Resume connection - - Delete connection - - Delete task - - Validate task settings - - Create S3 task - + This API provides the functionality to get information related to the package settings and current connections and tasks. + It also provides functionalities to set most of the settings for tasks and package configuration, as well as manage the current syncing processes. + + Due to the vast amount of public clouds available in the project, the API was not tested for every cloud scenario, so some params request may be missing in specific not tested clouds. + + The tested clouds so far are: + - Google Drive + - OneDrive + - DropBox + - Amazon S3 (task creation) + + ### Supported methods + + - **Getters** : + - Get package settings + - Get connections + - Get connections settings + - Get connection information + - Get connection auth information + - Get connection logs + - Get connection tasks + - Get task filters + - Get task synced remote directories + - Get recently modified & currently syncing files + - **Setters** : + - Set package settings + - Set relink behavior + - Set connection settings + - Set connection schedule settings + - Set task settings + - Set task filters + - **Actions** : + - Pause connection + - Resume connection + - Delete connection + - Delete task + - Validate task settings + - Create S3 task ## Methods ### `get_pkg_config` Retrieve package settings. @@ -69,38 +68,38 @@ A dictionary containing the result of package settings.
Click to expand ```json -{ - "data": { - "admin_mode": "enable", - "log_count": 20000, - "repo_vol_path": "/volume2", - "sync_mode": false, - "volume_count": 2, - "volume_list": [ - { - "desc": "", - "display": "Volume 1 (Available capacity: 715.84 GB )", - "mount_point": "/volume1", - "size_free": "768625090560", - "size_total": "955458760704", - "value": "1", - "vol_desc": "" - }, - { - "desc": "", - "display": "Volume 2 (Available capacity: 1841.73 GB )", - "mount_point": "/volume2", - "size_free": "1977547526144", - "size_total": "3835577597952", - "value": "2", - "vol_desc": "" - } - ], - "worker_count": 20 - }, - "success": true -} -``` + { + "data": { + "admin_mode": "enable", + "log_count": 20000, + "repo_vol_path": "/volume2", + "sync_mode": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 715.84 GB )", + "mount_point": "/volume1", + "size_free": "768625090560", + "size_total": "955458760704", + "value": "1", + "vol_desc": "" + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 1841.73 GB )", + "mount_point": "/volume2", + "size_free": "1977547526144", + "size_total": "3835577597952", + "value": "2", + "vol_desc": "" + } + ], + "worker_count": 20 + }, + "success": true + } + ```
@@ -118,8 +117,8 @@ Retrieve a list of current cloud connections. #### Parameters
-**_group_by_** `str, optional ` -How to group the connection list, by user or cloud type. Defaults to `"group_by_user"`. +**_group_by_** `str` +How to group the connection list, by user or cloud type. Defaults to `"group_by_user"`. Possible values: - `group_by_user`: Group connection by owner user. - `group_by_cloud_type`: Group connections by cloud provider. @@ -136,45 +135,45 @@ A dictionary containing the list of cloud connections.
Click to expand ```json -{ - "data": { - "conn": [ - { - "id": 3, - "link_status": 1, - "resource": "", - "status": "uptodate", - "task_display_name": "Dropbox", - "task_name": "Dropbox", - "type": "db", - "type_id": 2, - "unfinished_files": 0, - "user_id": "dbid:xxxxxxxxxxxxxxxxxx", - "user_name": "username" - }, - { - "id": 2, - "link_status": 1, - "resource": "", - "status": "syncing", - "task_display_name": "Microsoft OneDrive", - "task_name": "Microsoft OneDrive", - "type": "od_v1", - "type_id": 22, - "unfinished_files": 2, - "user_id": "xxxxxx", - "user_name": "username" - } - ], - "is_admin_mode": true, - "is_pause": false, - "notification": null, - "total": 2, - "tray_status": "syncing" - }, - "success": true -} -``` + { + "data": { + "conn": [ + { + "id": 3, + "link_status": 1, + "resource": "", + "status": "uptodate", + "task_display_name": "Dropbox", + "task_name": "Dropbox", + "type": "db", + "type_id": 2, + "unfinished_files": 0, + "user_id": "dbid:xxxxxxxxxxxxxxxxxx", + "user_name": "username" + }, + { + "id": 2, + "link_status": 1, + "resource": "", + "status": "syncing", + "task_display_name": "Microsoft OneDrive", + "task_name": "Microsoft OneDrive", + "type": "od_v1", + "type_id": 22, + "unfinished_files": 2, + "user_id": "xxxxxx", + "user_name": "username" + } + ], + "is_admin_mode": true, + "is_pause": false, + "notification": null, + "total": 2, + "tray_status": "syncing" + }, + "success": true + } + ```
@@ -192,7 +191,7 @@ Retrieve settings for a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. @@ -207,22 +206,22 @@ A dictionary containing the connection settings.
Click to expand ```json -{ - "data": { - "client_type": "db", - "isSSE": false, - "is_enabled_schedule": false, - "max_download_speed": 0, - "max_upload_speed": 0, - "part_size": 0, - "pull_event_period": 60, - "schedule_info": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", - "storage_class": "", - "task_name": "Dropbox" - }, - "success": true -} -``` + { + "data": { + "client_type": "db", + "isSSE": false, + "is_enabled_schedule": false, + "max_download_speed": 0, + "max_upload_speed": 0, + "part_size": 0, + "pull_event_period": 60, + "schedule_info": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "storage_class": "", + "task_name": "Dropbox" + }, + "success": true + } + ```
@@ -240,7 +239,7 @@ Retrieve cloud information for a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. @@ -255,26 +254,26 @@ A dictionary containing cloud information.
Click to expand ```json -{ - "data": { - "auth_version": "", - "bucket_name": "", - "container_name": "", - "project_id": "", - "public_url": "", - "quota_total": 2147483648, - "quota_used": 423330996, - "region": "", - "server_addr": "", - "shared_drive_name": "", - "storage_class": "", - "type": "db", - "type_id": 2, - "user_name": "username" - }, - "success": true -} -``` + { + "data": { + "auth_version": "", + "bucket_name": "", + "container_name": "", + "project_id": "", + "public_url": "", + "quota_total": 2147483648, + "quota_used": 423330996, + "region": "", + "server_addr": "", + "shared_drive_name": "", + "storage_class": "", + "type": "db", + "type_id": 2, + "user_name": "username" + }, + "success": true + } + ```
@@ -292,7 +291,7 @@ Retrieve authentication information for a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. @@ -307,45 +306,45 @@ A dictionary containing the connection authentication details.
Click to expand ```json -{ - "data": { - "access_key": "", - "access_token": "xxxxxxxx", - "auth_pass": "", - "auth_scheme": 0, - "auth_user": "", - "bucket_id": "", - "bucket_name": "", - "client_id": "xxxxxxxx", - "client_type": "db", - "conn_id": 3, - "container_name": "", - "download_url": "", - "openstack_api_key": "", - "openstack_domain_id": "", - "openstack_domain_name": "", - "openstack_identity_service_url": "", - "openstack_identity_service_version": "", - "openstack_password": "", - "openstack_proj_id": "", - "openstack_region": "", - "openstack_tenant_id": "", - "openstack_tenant_name": "", - "openstack_token": "", - "public_url": "", - "refresh_token": "xxxxxxxx", - "resource": "", - "root_folder_id": "", - "root_folder_path": "/", - "secret_key": "", - "server_addr": "", - "service_host": "", - "unique_id": "dbid:xxxxxxxx", - "user_name": "username" - }, - "success": true -} -``` + { + "data": { + "access_key": "", + "access_token": "xxxxxxxx", + "auth_pass": "", + "auth_scheme": 0, + "auth_user": "", + "bucket_id": "", + "bucket_name": "", + "client_id": "xxxxxxxx", + "client_type": "db", + "conn_id": 3, + "container_name": "", + "download_url": "", + "openstack_api_key": "", + "openstack_domain_id": "", + "openstack_domain_name": "", + "openstack_identity_service_url": "", + "openstack_identity_service_version": "", + "openstack_password": "", + "openstack_proj_id": "", + "openstack_region": "", + "openstack_tenant_id": "", + "openstack_tenant_name": "", + "openstack_token": "", + "public_url": "", + "refresh_token": "xxxxxxxx", + "resource": "", + "root_folder_id": "", + "root_folder_path": "/", + "secret_key": "", + "server_addr": "", + "service_host": "", + "unique_id": "dbid:xxxxxxxx", + "user_name": "username" + }, + "success": true + } + ```
@@ -363,28 +362,28 @@ Retrieve logs for a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. -**_keyword_** `str, optional ` +**_keyword_** `str` A keyword to filter logs. Defaults to `''`. -**_date_from_** `int, optional ` +**_date_from_** `int` The starting date in epoch format. Defaults to `0`. -**_date_to_** `int, optional ` +**_date_to_** `int` The ending date in epoch format. Defaults to `0`. **_log_level_** `int` -Log level filter. Defaults to `-1`. +Log level filter. Defaults to `-1`. Possible values: - `-1`: All - `0`: Info - `1`: Warning - `2`: Error -**_action_** `int, optional ` -Action filter. Defaults to `-1`. +**_action_** `int` +Action filter. Defaults to `-1`. Possible values: - `-1`: All - `0`: Delete Remote @@ -395,10 +394,10 @@ Possible values: - `8`: Merge - `9`: Merge Deletion -**_offset_** `int, optional ` +**_offset_** `int` Log offset for pagination. Defaults to `0`. -**_limit_** `int, optional ` +**_limit_** `int` Number of logs to retrieve. Defaults to `200`. @@ -413,35 +412,35 @@ A dictionary containing the connection logs.
Click to expand ```json -{ - "data": { - "items": [ - { - "action": 1, - "error_code": -36, - "file_name": "OCR Japanese extension.paper", - "file_type": "file", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/OCR Japanese extension.paper", - "session_id": 4, - "time": 1724418508 - }, - { - "action": 1, - "error_code": -36, - "file_name": "OCR Japanese extension.paper", - "file_type": "file", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/OCR Japanese extension.paper", - "session_id": 4, - "time": 1724418119 - } - ], - "total": 2 - }, - "success": true -} -``` + { + "data": { + "items": [ + { + "action": 1, + "error_code": -36, + "file_name": "OCR Japanese extension.paper", + "file_type": "file", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/OCR Japanese extension.paper", + "session_id": 4, + "time": 1724418508 + }, + { + "action": 1, + "error_code": -36, + "file_name": "OCR Japanese extension.paper", + "file_type": "file", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/OCR Japanese extension.paper", + "session_id": 4, + "time": 1724418119 + } + ], + "total": 2 + }, + "success": true + } + ```
@@ -459,7 +458,7 @@ Retrieve a list of tasks related to a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. @@ -474,28 +473,28 @@ A dictionary containing the list of tasks.
Click to expand ```json -{ - "data": { - "sess": [ - { - "cloud_type_str": "db", - "conn_id": 3, - "error": 0, - "error_desc": "", - "link_status": 1, - "local_sync_path": "/test_share/WebDAV test/subfolder", - "remote_folder_id": "id:xxxx", - "remote_sync_path": "/docs", - "sess_id": 4, - "sync_direction": "ONLY_DOWNLOAD", - "sync_status": "uptodate" - } - ], - "total": 1 - }, - "success": true -} -``` + { + "data": { + "sess": [ + { + "cloud_type_str": "db", + "conn_id": 3, + "error": 0, + "error_desc": "", + "link_status": 1, + "local_sync_path": "/test_share/WebDAV test/subfolder", + "remote_folder_id": "id:xxxx", + "remote_sync_path": "/docs", + "sess_id": 4, + "sync_direction": "ONLY_DOWNLOAD", + "sync_status": "uptodate" + } + ], + "total": 1 + }, + "success": true + } + ```
@@ -513,7 +512,7 @@ Retrieve filter information for a specific task. #### Parameters
-**_sess_id_** `int ` +**_sess_id_** `int` The ID of the task, obtained from `get_tasks()`. @@ -528,31 +527,31 @@ A dictionary containing task filter information.
Click to expand ```json -{ - "data": { - "filtered_extensions": [ - "wbmp", - "webdoc", - "x3f", - "xbm" - ], - "filtered_max_upload_size": 1048576, - "filtered_names": [ - "test" - ], - "filtered_paths": [ - "/subfolder_1" - ], - "user_defined_extensions": [ - "iso" - ], - "user_defined_names": [ - "test" - ] - }, - "success": true -} -``` + { + "data": { + "filtered_extensions": [ + "wbmp", + "webdoc", + "x3f", + "xbm" + ], + "filtered_max_upload_size": 1048576, + "filtered_names": [ + "test" + ], + "filtered_paths": [ + "/subfolder_1" + ], + "user_defined_extensions": [ + "iso" + ], + "user_defined_names": [ + "test" + ] + }, + "success": true + } + ```
@@ -570,13 +569,13 @@ Retrieve a list of children directories in the cloud for a specific task. #### Parameters
-**_sess_id_** `int ` +**_sess_id_** `int` The ID of the task, obtained from `get_tasks()`. -**_remote_folder_id_** `str ` +**_remote_folder_id_** `str` The ID of the remote folder, obtained from `get_tasks()`. -**_path_** `str, optional ` +**_path_** `str` The folder path to retrieve the child directories from. Defaults to root `'/'`. @@ -591,38 +590,38 @@ A dictionary containing the list of children directories.
Click to expand ```json -{ - "data": { - "children": [ - { - "exists_type": 1, - "file_id": "", - "path": "/subfolder_1", - "text": "subfolder_1" - }, - { - "exists_type": 1, - "file_id": "", - "path": "/new folder", - "text": "new folder" - }, - { - "exists_type": 3, - "file_id": "id:xxxx", - "path": "/test1", - "text": "test1" - }, - { - "exists_type": 3, - "file_id": "id:xxxx", - "path": "/test2", - "text": "test2" - } - ] - }, - "success": true -} -``` + { + "data": { + "children": [ + { + "exists_type": 1, + "file_id": "", + "path": "/subfolder_1", + "text": "subfolder_1" + }, + { + "exists_type": 1, + "file_id": "", + "path": "/new folder", + "text": "new folder" + }, + { + "exists_type": 3, + "file_id": "id:xxxx", + "path": "/test1", + "text": "test1" + }, + { + "exists_type": 3, + "file_id": "id:xxxx", + "path": "/test2", + "text": "test2" + } + ] + }, + "success": true + } + ```
@@ -648,78 +647,78 @@ A dictionary containing the recently modified files.
Click to expand ```json -{ - "data": { - "history_items": [ - { - "action": 1, - "base_name": "test_file.paper", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/test_file.paper", - "session_id": 4, - "syncfolder_basename": "subfolder" - }, - { - "action": 1, - "base_name": "perfect plan.paper", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/perfect plan.paper", - "session_id": 4, - "syncfolder_basename": "subfolder" - }, - { - "action": 1, - "base_name": "Untitled.paper", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/Untitled.paper", - "session_id": 4, - "syncfolder_basename": "subfolder" - }, - { - "action": 1, - "base_name": "translation hw.paper", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/translation hw.paper", - "session_id": 4, - "syncfolder_basename": "subfolder" - }, - { - "action": 1, - "base_name": "The Tao of Harp.paper", - "log_level": 2, - "path": "/test_share/WebDAV test/subfolder/song ideas/The Tao of Harp.paper", - "session_id": 4, - "syncfolder_basename": "subfolder" - } - ], - "is_admin_mode": true, - "processing_items": [ - { - "base_name": "1111111111111111111111125.jpg", - "bit_rate": 2114, - "current_size": 65535, - "path": "/test_share/WebDAV test/subfolder/test1/asd/1111111111111111.jpg", - "session_id": 3, - "status": "uploading", - "total_size": 295493, - "user_name": "username" - }, - { - "base_name": "ans1.3.png", - "bit_rate": 1047, - "current_size": 358122, - "path": "/test_share/WebDAV test/subfolder/test2/ans1.3.png", - "session_id": 3, - "status": "uploading", - "total_size": 358122, - "user_name": "username" - } - ], - "server_merge_items": [] - }, - "success": true -} -``` + { + "data": { + "history_items": [ + { + "action": 1, + "base_name": "test_file.paper", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/test_file.paper", + "session_id": 4, + "syncfolder_basename": "subfolder" + }, + { + "action": 1, + "base_name": "perfect plan.paper", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/perfect plan.paper", + "session_id": 4, + "syncfolder_basename": "subfolder" + }, + { + "action": 1, + "base_name": "Untitled.paper", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/Untitled.paper", + "session_id": 4, + "syncfolder_basename": "subfolder" + }, + { + "action": 1, + "base_name": "translation hw.paper", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/translation hw.paper", + "session_id": 4, + "syncfolder_basename": "subfolder" + }, + { + "action": 1, + "base_name": "The Tao of Harp.paper", + "log_level": 2, + "path": "/test_share/WebDAV test/subfolder/song ideas/The Tao of Harp.paper", + "session_id": 4, + "syncfolder_basename": "subfolder" + } + ], + "is_admin_mode": true, + "processing_items": [ + { + "base_name": "1111111111111111111111125.jpg", + "bit_rate": 2114, + "current_size": 65535, + "path": "/test_share/WebDAV test/subfolder/test1/asd/1111111111111111.jpg", + "session_id": 3, + "status": "uploading", + "total_size": 295493, + "user_name": "username" + }, + { + "base_name": "ans1.3.png", + "bit_rate": 1047, + "current_size": 358122, + "path": "/test_share/WebDAV test/subfolder/test2/ans1.3.png", + "session_id": 3, + "status": "uploading", + "total_size": 358122, + "user_name": "username" + } + ], + "server_merge_items": [] + }, + "success": true + } + ```
@@ -737,16 +736,16 @@ Set package configuration settings. #### Parameters
-**_pkg_volume_** `str ` +**_pkg_volume_** `str` The volume path where the package data will be stored (e.g., `/volume1`). -**_log_count_** `int, optional ` +**_log_count_** `int` Maximum number of logs retained per connection. Defaults to `20000`, max is `100000`. -**_workers_** `int, optional ` +**_workers_** `int` Number of concurrent uploads allowed. Defaults to `3`, max is `20`. -**_admin_mode_** `bool, optional ` +**_admin_mode_** `bool` Whether all users' tasks are retrieved or not. Defaults to `True`. @@ -761,10 +760,10 @@ A dictionary containing the result of the configuration update.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -787,7 +786,7 @@ Set the relinking behavior for personal user accounts. #### Parameters
-**_delete_from_cloud_** `bool ` +**_delete_from_cloud_** `bool` Set to `False` for "locally deleted files will be re-fetched from the cloud". Set to `True` for "locally deleted files will also be removed from the cloud". @@ -803,10 +802,10 @@ A dictionary containing the result of the relink behavior update.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -824,28 +823,28 @@ Set settings for a specific cloud connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. -**_task_name_** `str ` +**_task_name_** `str` The name of the cloud sync task. -**_pull_event_period_** `int, optional ` +**_pull_event_period_** `int` Frequency (in seconds) to pull event updates. Defaults to `60`. -**_max_upload_speed_** `int, optional ` +**_max_upload_speed_** `int` Maximum upload speed in bytes. Defaults to `0` (unlimited). -**_max_download_speed_** `int, optional ` +**_max_download_speed_** `int` Maximum download speed in bytes. Defaults to `0` (unlimited). -**_storage_class_** `str, optional ` +**_storage_class_** `str` Cloud-specific storage class. Defaults to `''`. -**_isSSE_** `bool, optional ` +**_isSSE_** `bool` Enable Security Service Edge (SSE) for compatible cloud storage. Defaults to `False`. -**_part_size_** `int, optional ` +**_part_size_** `int` Part size for file uploads, in megabytes. Defaults to `128`. @@ -860,10 +859,10 @@ A dictionary containing the updated connection settings.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -881,13 +880,13 @@ Set the schedule for a specific connection. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection, obtained from `get_connections()`. -**_enable_** `bool ` +**_enable_** `bool` Whether the scheduling is enabled (`True`) or disabled (`False`). -**_schedule_info_** `list[str], optional ` +**_schedule_info_** `list[str]` A list of 7 strings where each string represents a day of the week, going from Sunday to Saturday. Each string is composed of 24 characters, where each character is either '1' (enabled) or '0' (disabled) for the respective hour of the day. The default value (if `schedule_info` is not provided) enables all days and hours. @@ -918,10 +917,10 @@ A dictionary containing the schedule settings.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -939,23 +938,23 @@ Set the task settings for a specific session. #### Parameters
-**_sess_id_** `int ` +**_sess_id_** `int` The ID of the task, obtained from `get_tasks()`. -**_sync_direction_** `str ` -The synchronization direction. +**_sync_direction_** `str` +The synchronization direction. Possible values: - `ONLY_UPLOAD`: Upload local changes only. - `BIDIRECTION`: Sync both ways (upload and download). - `ONLY_DOWNLOAD`: Download remote changes only. -**_consistency_check_** `bool, optional ` +**_consistency_check_** `bool` If True, enables advanced consistency check (requires more resources). Defaults to `True`. -**_no_delete_on_cloud_** `bool, optional ` +**_no_delete_on_cloud_** `bool` If `True`, prevents deletion of files in the remote folder when removed from the local directory. Defaults to `True`. -**_convert_gd_** `bool, optional ` +**_convert_gd_** `bool` If `True`, converts Google Drive Online documents to Microsoft Office format. Defaults to `False`. @@ -970,10 +969,10 @@ A dictionary containing the result of the task settings configuration.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -991,19 +990,19 @@ Set task filters for selective synchronization in a specific session. #### Parameters
-**_sess_id_** `int ` +**_sess_id_** `int` The ID of the session, obtained from `get_tasks()`. -**_filtered_paths_** `list[str], optional ` +**_filtered_paths_** `list[str]` A list of paths (directories / subdirectories) to exclude from the synchronization process, e.g, `['/images', '/videos/movies']`. Defaults to `[]`. -**_filtered_filenames_** `list[str], optional ` +**_filtered_filenames_** `list[str]` A list of filenames to exclude from synchronization. Defaults to `[]`. -**_filtered_extensions_** `list[str], optional ` +**_filtered_extensions_** `list[str]` A list of file extensions to exclude from synchronization, e.g., `['mp3', 'iso', 'mkv']`. Defaults to `[]`. -**_max_upload_size_** `int, optional ` +**_max_upload_size_** `int` The maximum file size for uploads, in bytes. Files larger than this size will be excluded from synchronization. Defaults to `0` (no size limit). @@ -1018,10 +1017,10 @@ A dictionary containing the result of the task filters configuration.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1039,7 +1038,7 @@ Pause one or all connections. #### Parameters
-**_conn_id_** `int, optional ` +**_conn_id_** `int` The ID of the connection to pause. If not specified or set to `-1`, all connections will be paused. @@ -1054,10 +1053,10 @@ A dictionary containing the result of the pause action.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1075,7 +1074,7 @@ Resume one or all connections. #### Parameters
-**_conn_id_** `int, optional ` +**_conn_id_** `int` The ID of the connection to resume. If not specified or set to `-1`, all connections will be resumed. @@ -1090,10 +1089,10 @@ A dictionary containing the result of the resume action.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1111,7 +1110,7 @@ The data will remain in both the local and remote directories. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection to be removed, obtained from `get_connections()`. @@ -1126,10 +1125,10 @@ A dictionary containing the result of the remove action.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1147,10 +1146,10 @@ The data will remain in both the local and remote directories. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection associated with the task, obtained from `get_connections()`. -**_sess_id_** `int ` +**_sess_id_** `int` The ID of the task to be removed, obtained from `get_tasks()`. @@ -1165,10 +1164,10 @@ A dictionary containing the result of the task removal.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1176,8 +1175,8 @@ A dictionary containing the result of the task removal. --- -### `test_task_setting` -Test the task settings make sure they are valid. +### `create_sync_task_s3` +Add a new synchronization task. #### Internal API
@@ -1186,36 +1185,36 @@ Test the task settings make sure they are valid. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection. -**_local_path_** `str ` +**_local_path_** `str` The local path to sync. -**_cloud_path_** `str ` +**_cloud_path_** `str` The cloud path to sync. -**_sync_direction_** `str, optional ` +**_sync_direction_** `str` The synchronization direction. Defaults to `'BIDIRECTION'`. -**_storage_class_** `str, optional ` +**_storage_class_** `str` The storage class. Defaults to `'STANDARD'`. -**_file_filter_** `list[str], optional ` +**_file_filter_** `list[str]` List of file extensions to filter. Defaults to `[]`. -**_filter_max_upload_size_** `int, optional ` +**_filter_max_upload_size_** `int` Maximum upload size for files. Defaults to `0`. -**_filter_names_** `list[str], optional ` +**_filter_names_** `list[str]` List of file names to filter. Defaults to `[]`.
#### Returns
-`tuple[bool, dict[str, object] | str]` -A tuple containing a boolean indicating success, and a dictionary or string with the result. +`tuple[bool, Any]` +A tuple containing the result of the task creation.
@@ -1224,8 +1223,8 @@ A tuple containing a boolean indicating success, and a dictionary or string with --- -### `create_sync_task_s3` -Add a new synchronization task. +### `test_task_setting` +Test the task settings make sure they are valid. #### Internal API
@@ -1234,36 +1233,36 @@ Add a new synchronization task. #### Parameters
-**_conn_id_** `int ` +**_conn_id_** `int` The ID of the connection. -**_local_path_** `str ` +**_local_path_** `str` The local path to sync. -**_cloud_path_** `str ` +**_cloud_path_** `str` The cloud path to sync. -**_sync_direction_** `str, optional ` +**_sync_direction_** `str` The synchronization direction. Defaults to `'BIDIRECTION'`. -**_storage_class_** `str, optional ` +**_storage_class_** `str` The storage class. Defaults to `'STANDARD'`. -**_file_filter_** `list[str], optional ` +**_file_filter_** `list[str]` List of file extensions to filter. Defaults to `[]`. **_filter_max_upload_size_** `int` Maximum upload size for files. Defaults to `0`. -**_filter_names_** `list[str], optional ` +**_filter_names_** `list[str]` List of file names to filter. Defaults to `[]`.
#### Returns
-`tuple[bool, Any]` -A tuple containing the result of the task creation. +`tuple[bool, dict[str, object] | str]` +A tuple containing a boolean indicating success, and a dictionary or string with the result.
diff --git a/documentation/docs/apis/classes/core_active_backup.md b/documentation/docs/apis/classes/core_active_backup.md index 502304f6..5929019e 100644 --- a/documentation/docs/apis/classes/core_active_backup.md +++ b/documentation/docs/apis/classes/core_active_backup.md @@ -11,31 +11,31 @@ title: ✅ ActiveBackupBusiness ## Overview Active Backup for Business API Implementation. -This class provides methods to interact with the Active Backup for Business package. - -### Supported methods - - - **Getters** : - - Get package settings - - Get tasks information - - Get tasks versions information - - Get devices information - - Get devices transfer size - - Get hypervisors information - - Get package / devices / tasks logs - - Get task history - - Get task result details - - Get storage information - - **Setters** : - - Set maximum concurrent devices - - Set retention policy execution time - - Set bandwidth control - - Set use package certificate - - **Actions** : - - Run backup - - Cancel backup - - Remove task - - Remove version + This class provides methods to interact with the Active Backup for Business package. + + ### Supported methods + + - **Getters** : + - Get package settings + - Get tasks information + - Get tasks versions information + - Get devices information + - Get devices transfer size + - Get hypervisors information + - Get package / devices / tasks logs + - Get task history + - Get task result details + - Get storage information + - **Setters** : + - Set maximum concurrent devices + - Set retention policy execution time + - Set bandwidth control + - Set use package certificate + - **Actions** : + - Run backup + - Cancel backup + - Remove task + - Remove version ## Methods ### `get_settings` Get the package settings including certificate information. @@ -55,77 +55,77 @@ A dictionary containing the current settings.
Click to expand ```json -{ - "data": { - "cert_info": { - "cert_from_dsm": { - "cert_common_name": "xxxxx.myds.me", - "cert_issuer": "R10", - "cert_san": [ - "*.xxxxx.myds.me", - "xxxxx.myds.me" - ], - "cert_tillTime": "May 29 18:54:13 2025 GMT" - }, - "cert_from_package": { - "cert_common_name": "Active Backup for Business", - "cert_issuer": "Synology Active Backup for Business", - "cert_san": [ - "Active Backup for Business" - ], - "cert_tillTime": "Apr 17 19:14:52 2034 GMT" + { + "data": { + "cert_info": { + "cert_from_dsm": { + "cert_common_name": "xxxxx.myds.me", + "cert_issuer": "R10", + "cert_san": [ + "*.xxxxx.myds.me", + "xxxxx.myds.me" + ], + "cert_tillTime": "May 29 18:54:13 2025 GMT" + }, + "cert_from_package": { + "cert_common_name": "Active Backup for Business", + "cert_issuer": "Synology Active Backup for Business", + "cert_san": [ + "Active Backup for Business" + ], + "cert_tillTime": "Apr 17 19:14:52 2034 GMT" + }, + "cert_use_package": true }, - "cert_use_package": true + "settings": [ + { + "id": 1, + "name": "max_concurrent_devices", + "value": "5" + }, + { + "id": 2, + "name": "memory_usage_limit_percentage", + "value": "75" + }, + { + "id": 3, + "name": "package_cert_id", + "value": "dyAaL7" + }, + { + "id": 4, + "name": "enable_global_bandwidth_control", + "value": "false" + }, + { + "id": 5, + "name": "global_backup_bandwidth_number", + "value": "0" + }, + { + "id": 6, + "name": "enable_ip_range_bandwidth_control", + "value": "false" + }, + { + "id": 7, + "name": "full_backup_task_ids", + "value": "2" + }, + { + "name": "retention_run_hour", + "value": "14" + }, + { + "name": "retention_run_min", + "value": "50" + } + ] }, - "settings": [ - { - "id": 1, - "name": "max_concurrent_devices", - "value": "5" - }, - { - "id": 2, - "name": "memory_usage_limit_percentage", - "value": "75" - }, - { - "id": 3, - "name": "package_cert_id", - "value": "dyAaL7" - }, - { - "id": 4, - "name": "enable_global_bandwidth_control", - "value": "false" - }, - { - "id": 5, - "name": "global_backup_bandwidth_number", - "value": "0" - }, - { - "id": 6, - "name": "enable_ip_range_bandwidth_control", - "value": "false" - }, - { - "id": 7, - "name": "full_backup_task_ids", - "value": "2" - }, - { - "name": "retention_run_hour", - "value": "14" - }, - { - "name": "retention_run_min", - "value": "50" - } - ] - }, - "success": true -} -``` + "success": true + } + ```
@@ -169,10 +169,10 @@ A dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -194,7 +194,7 @@ Set the time of day when the retention policy will be executed. Hour in 24-hour format (0 - 23) when the retention policy will be executed. **_minute_** `int` -Minute (0 - 59) when the retention policy will be executed +Minute (0 - 59) when the retention policy will be executed.
@@ -208,10 +208,10 @@ A dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -223,7 +223,7 @@ A dictionary containing the result of the operation. Set the global bandwidth control and IP range bandwidth control. :::note - Applies only to PC, Physical Server and NAS devices. + Applies only to PC, Physical Server and NAS devices. ::: @@ -241,15 +241,15 @@ Set the global bandwidth control and IP range bandwidth control. #### Parameters
**_traffic_control_** `dict[str, object]` -Traffic control settings. +Traffic control settings. Defaults to `{ 'enable': False, 'bandwidth': 0 }` (disable traffic throttling). Bandwidth should be specified in MB/s. **_ip_range_** `list[str]` -If specified, traffic control will only be applied to this IP range. +If specified, traffic control will only be applied to this IP range. Defaults to `["", ""]` (disable IP range bandwidth control). First index should contain the IP range start, second index the IP range end. Only supports IPv4 format. -Example: +Example: ```python ["192.168.0.1", "192.168.0.10"] ``` @@ -266,10 +266,10 @@ A dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -302,10 +302,10 @@ A dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -361,107 +361,107 @@ A dictionary containing a list of devices and their transfer size.
Click to expand ```json -{ - "data" : { - "device_list" : [ - { - "device" : { - "agent_token" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "agentless_auth_policy" : 0, - "auto_discovery" : false, - "backup_type" : 2, - "create_time" : 1709413484, - "device_id" : 5, - "device_uuid" : "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", - "dsm_model" : "", - "dsm_unique" : "", - "host_ip" : "192.168.0.63", - "host_name" : "xxxxx", - "host_port" : 0, - "hypervisor_id" : "", - "inventory_id" : 0, - "login_password" : "", - "login_time" : 1709413493, - "login_user" : "xxxx", - "login_user_id" : 1026, - "os_name" : "Windows 11(64-bit)", - "vm_moid_path" : "" - }, - "transfer_list" : [ - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 342, - "processed_bytes" : 0, - "result_id" : 587, - "status" : 5, - "time_end" : 1741895385, - "time_start" : 1741894511, - "transfered_bytes" : 1523580928 - }, - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 343, - "processed_bytes" : 0, - "result_id" : 589, - "status" : 5, - "time_end" : 1741896408, - "time_start" : 1741896176, - "transfered_bytes" : 6909067264 - }, - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 344, - "processed_bytes" : 0, - "result_id" : 590, - "status" : 5, - "time_end" : 1741896716, - "time_start" : 1741896624, - "transfered_bytes" : 444596224 + { + "data" : { + "device_list" : [ + { + "device" : { + "agent_token" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "agentless_auth_policy" : 0, + "auto_discovery" : false, + "backup_type" : 2, + "create_time" : 1709413484, + "device_id" : 5, + "device_uuid" : "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx", + "dsm_model" : "", + "dsm_unique" : "", + "host_ip" : "192.168.0.63", + "host_name" : "xxxxx", + "host_port" : 0, + "hypervisor_id" : "", + "inventory_id" : 0, + "login_password" : "", + "login_time" : 1709413493, + "login_user" : "xxxx", + "login_user_id" : 1026, + "os_name" : "Windows 11(64-bit)", + "vm_moid_path" : "" }, - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 346, - "processed_bytes" : 0, - "result_id" : 591, - "status" : 2, - "time_end" : 1741901184, - "time_start" : 1741896737, - "transfered_bytes" : 482689236992 - }, - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 347, - "processed_bytes" : 0, - "result_id" : 593, - "status" : 2, - "time_end" : 1741946439, - "time_start" : 1741946267, - "transfered_bytes" : 2122801152 - }, - { - "config_device_id" : 5, - "device_name" : "xxxxx", - "device_result_id" : 348, - "processed_bytes" : 0, - "result_id" : 595, - "status" : 2, - "time_end" : 1741972250, - "time_start" : 1741971826, - "transfered_bytes" : 8208736256 - } - ] - }, - ], - "total" : 1 - }, - "success" : true -} -``` + "transfer_list" : [ + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 342, + "processed_bytes" : 0, + "result_id" : 587, + "status" : 5, + "time_end" : 1741895385, + "time_start" : 1741894511, + "transfered_bytes" : 1523580928 + }, + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 343, + "processed_bytes" : 0, + "result_id" : 589, + "status" : 5, + "time_end" : 1741896408, + "time_start" : 1741896176, + "transfered_bytes" : 6909067264 + }, + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 344, + "processed_bytes" : 0, + "result_id" : 590, + "status" : 5, + "time_end" : 1741896716, + "time_start" : 1741896624, + "transfered_bytes" : 444596224 + }, + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 346, + "processed_bytes" : 0, + "result_id" : 591, + "status" : 2, + "time_end" : 1741901184, + "time_start" : 1741896737, + "transfered_bytes" : 482689236992 + }, + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 347, + "processed_bytes" : 0, + "result_id" : 593, + "status" : 2, + "time_end" : 1741946439, + "time_start" : 1741946267, + "transfered_bytes" : 2122801152 + }, + { + "config_device_id" : 5, + "device_name" : "xxxxx", + "device_result_id" : 348, + "processed_bytes" : 0, + "result_id" : 595, + "status" : 2, + "time_end" : 1741972250, + "time_start" : 1741971826, + "transfered_bytes" : 8208736256 + } + ] + }, + ], + "total" : 1 + }, + "success" : true + } + ```
@@ -470,7 +470,7 @@ A dictionary containing a list of devices and their transfer size. ### `list_tasks` -Get information of one or all tasks. +Get information of one or all tasks. #### Internal API
@@ -480,7 +480,7 @@ Get information of one or all tasks. #### Parameters
**_task_id_** `int` -Get information of specific task. Defaults to `-1` (all tasks) +Get information of specific task. Defaults to `-1` (all tasks). **_backup_type_** `str` Return only tasks matching the device type provided. Defaults to `""` (all device types). @@ -490,8 +490,7 @@ Possible values: - `"physical_server"` - `"file_server"` - `"nas"` - -Note that values are different when returned by the API. +Note that values are different when returned by the API. Return values mappings: - `1` -> `vm` - `2` -> `pc` @@ -528,181 +527,181 @@ Dictionary containing a list of tasks.
Click to expand ```json -{ - "data": { - "has_devices": true, - "has_dsm_agent": false, - "has_hyperv_inventories": false, - "has_linux_agent": false, - "has_mac_agent": false, - "has_vmware_inventories": false, - "has_windows_agent": true, - "tasks": [{ - "agentless_backup_path" : "", - "agentless_backup_policy" : 0, - "agentless_enable_block_transfer" : false, - "agentless_enable_dedup" : false, - "agentless_enable_windows_vss" : false, - "allow_manual_backup" : true, - "backup_cache_content" : { - "cached_enabled" : false - }, - "backup_external" : false, - "backup_type" : 2, - "bandwidth" : 0, - "bandwidth_content" : { - "backup_bandwidth_base" : 0, - "backup_bandwidth_number" : 0, - "enable" : false - }, - "cbt_enable_mode" : 1, - "connection_timeout" : 0, - "custom_volume" : [], - "datastore_reserved_percentage" : 0, - "dedup_api_restore" : true, - "dedup_path" : "", - "device_count" : 1, - "devices" : [{ - "agent_can_backup" : true, - "agent_driver_status" : "enable", - "agent_status" : "online", - "agent_token" : "xxxxxxxxxxxxxxx", - "agentless_auth_policy" : 0, - "auto_discovery" : false, - "backup_type" : 2, - "create_time" : 1709413484, - "device_id" : 5, - "device_uuid" : "xxxxxxxxxxxx", - "driver_status" : null, - "dsm_model" : "", - "dsm_unique" : "", - "host_ip" : "192.168.0.63", - "host_name" : "xxxxxxxxx", - "host_port" : 0, - "hypervisor_id" : "", - "inventory_id" : 0, - "login_password" : "", - "login_time" : 1709413493, - "login_user" : "xxxx", - "login_user_id" : 1026, - "os_name" : "Windows 11(64-bit)", - "platform_type" : 1, - "vm_moid_path" : "" - }], - "enable_app_aware_bkp" : false, - "enable_compress_transfer" : true, - "enable_datastore_aware" : false, - "enable_dedup" : true, - "enable_encrypt_transfer" : true, - "enable_notify" : false, - "enable_shutdown_after_complete" : false, - "enable_verification" : false, - "enable_wake_up" : false, - "enable_windows_working_state" : false, - "last_result" : { + { + "data": { + "has_devices": true, + "has_dsm_agent": false, + "has_hyperv_inventories": false, + "has_linux_agent": false, + "has_mac_agent": false, + "has_vmware_inventories": false, + "has_windows_agent": true, + "tasks": [{ + "agentless_backup_path" : "", + "agentless_backup_policy" : 0, + "agentless_enable_block_transfer" : false, + "agentless_enable_dedup" : false, + "agentless_enable_windows_vss" : false, + "allow_manual_backup" : true, + "backup_cache_content" : { + "cached_enabled" : false + }, + "backup_external" : false, "backup_type" : 2, - "detail_path" : "", - "error_count" : 0, - "job_action" : 1, - "none_count" : 0, - "result_id" : 593, - "status" : 2, - "success_count" : 0, - "task_config" : { - "device_list" : [ - { - "device_id" : 5, - "host_name" : "xxxxxxxxxx" - } - ] + "bandwidth" : 0, + "bandwidth_content" : { + "backup_bandwidth_base" : 0, + "backup_bandwidth_number" : 0, + "enable" : false }, + "cbt_enable_mode" : 1, + "connection_timeout" : 0, + "custom_volume" : [], + "datastore_reserved_percentage" : 0, + "dedup_api_restore" : true, + "dedup_path" : "", + "device_count" : 1, + "devices" : [{ + "agent_can_backup" : true, + "agent_driver_status" : "enable", + "agent_status" : "online", + "agent_token" : "xxxxxxxxxxxxxxx", + "agentless_auth_policy" : 0, + "auto_discovery" : false, + "backup_type" : 2, + "create_time" : 1709413484, + "device_id" : 5, + "device_uuid" : "xxxxxxxxxxxx", + "driver_status" : null, + "dsm_model" : "", + "dsm_unique" : "", + "host_ip" : "192.168.0.63", + "host_name" : "xxxxxxxxx", + "host_port" : 0, + "hypervisor_id" : "", + "inventory_id" : 0, + "login_password" : "", + "login_time" : 1709413493, + "login_user" : "xxxx", + "login_user_id" : 1026, + "os_name" : "Windows 11(64-bit)", + "platform_type" : 1, + "vm_moid_path" : "" + }], + "enable_app_aware_bkp" : false, + "enable_compress_transfer" : true, + "enable_datastore_aware" : false, + "enable_dedup" : true, + "enable_encrypt_transfer" : true, + "enable_notify" : false, + "enable_shutdown_after_complete" : false, + "enable_verification" : false, + "enable_wake_up" : false, + "enable_windows_working_state" : false, + "last_result" : { + "backup_type" : 2, + "detail_path" : "", + "error_count" : 0, + "job_action" : 1, + "none_count" : 0, + "result_id" : 593, + "status" : 2, + "success_count" : 0, + "task_config" : { + "device_list" : [ + { + "device_id" : 5, + "host_name" : "xxxxxxxxxx" + } + ] + }, + "task_id" : 5, + "task_name" : "xxxxxxxxxxx", + "time_end" : 1741946439, + "time_start" : 1741946267, + "transfered_bytes" : 2122801152, + "warning_count" : 0 + }, + "last_version_id" : 163, + "max_concurrent_devices" : 0, + "next_trigger_time" : 1742176800, + "pre_post_script_setting" : { + "post_script_path" : "", + "pre_script_path" : "", + "script_exec_mode" : 0 + }, + "repo_dir" : "@ActiveBackup", + "retention_policy" : { + "gfs_days" : "7", + "gfs_months" : "12", + "gfs_weeks" : "4", + "gfs_years" : "3", + "keep_all" : false, + "keep_versions" : 10 + }, + "sched_content" : { + "backup_window" : "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "enable_backup_window" : false, + "is_continuous_paused" : false, + "repeat_hour" : 0, + "repeat_type" : "Weekly", + "run_hour" : 3, + "run_min" : 0, + "run_weekday" : [ 1, 2, 3, 4, 5 ], + "schedule_setting_type" : 1, + "start_day" : 0, + "start_month" : 0, + "start_year" : 0 + }, + "sched_id" : 0, + "sched_modify_time" : 1709413646, + "share_compressed" : false, + "share_name" : "ActiveBackupforBusiness", + "source_type" : 2, + "storage_compress_algorithm" : 0, + "storage_encrypt_algorithm" : 0, + "storage_id" : 1, + "target_dir" : "xxxxxxxxxxx", + "target_status" : "online", "task_id" : 5, - "task_name" : "xxxxxxxxxxx", - "time_end" : 1741946439, - "time_start" : 1741946267, - "transfered_bytes" : 2122801152, - "warning_count" : 0 - }, - "last_version_id" : 163, - "max_concurrent_devices" : 0, - "next_trigger_time" : 1742176800, - "pre_post_script_setting" : { - "post_script_path" : "", - "pre_script_path" : "", - "script_exec_mode" : 0 - }, - "repo_dir" : "@ActiveBackup", - "retention_policy" : { - "gfs_days" : "7", - "gfs_months" : "12", - "gfs_weeks" : "4", - "gfs_years" : "3", - "keep_all" : false, - "keep_versions" : 10 - }, - "sched_content" : { - "backup_window" : "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", - "enable_backup_window" : false, - "is_continuous_paused" : false, - "repeat_hour" : 0, - "repeat_type" : "Weekly", - "run_hour" : 3, - "run_min" : 0, - "run_weekday" : [ 1, 2, 3, 4, 5 ], - "schedule_setting_type" : 1, - "start_day" : 0, - "start_month" : 0, - "start_year" : 0 - }, - "sched_id" : 0, - "sched_modify_time" : 1709413646, - "share_compressed" : false, - "share_name" : "ActiveBackupforBusiness", - "source_type" : 2, - "storage_compress_algorithm" : 0, - "storage_encrypt_algorithm" : 0, - "storage_id" : 1, - "target_dir" : "xxxxxxxxxxx", - "target_status" : "online", - "task_id" : 5, - "task_name" : "xxx", - "unikey" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "verification_policy" : 120, - "version_count" : 2, - "versions" : [ - { - "crypto_key_id" : 0, - "data_format" : 1, - "folder_name" : "ActiveBackup_2025-03-14_105745", - "is_snapshot" : true, - "locked" : false, - "status" : 3, - "time_end" : 1741946439, - "time_start" : 1741946267, - "used_size" : 0, - "version_id" : 163 - }, - { - "crypto_key_id" : 0, - "data_format" : 1, - "folder_name" : "ActiveBackup_2025-03-13_211215", - "is_snapshot" : true, - "locked" : false, - "status" : 3, - "time_end" : 1741901184, - "time_start" : 1741896737, - "used_size" : 0, - "version_id" : 162 - }, - ], - "view_type" : "", - "vm_folder" : null - }], - "total": 1 - }, - "success": true -} -``` + "task_name" : "xxx", + "unikey" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "verification_policy" : 120, + "version_count" : 2, + "versions" : [ + { + "crypto_key_id" : 0, + "data_format" : 1, + "folder_name" : "ActiveBackup_2025-03-14_105745", + "is_snapshot" : true, + "locked" : false, + "status" : 3, + "time_end" : 1741946439, + "time_start" : 1741946267, + "used_size" : 0, + "version_id" : 163 + }, + { + "crypto_key_id" : 0, + "data_format" : 1, + "folder_name" : "ActiveBackup_2025-03-13_211215", + "is_snapshot" : true, + "locked" : false, + "status" : 3, + "time_end" : 1741901184, + "time_start" : 1741896737, + "used_size" : 0, + "version_id" : 162 + }, + ], + "view_type" : "", + "vm_folder" : null + }], + "total": 1 + }, + "success": true + } + ```
@@ -711,89 +710,48 @@ Dictionary containing a list of tasks. ### `list_logs` -Get logs from the package, tasks and devices. From `[Activities -> Log]` screen in ABB. -For specific task logs `[Task List -> Details -> Log]`, specify `task_id` parameter. +Get logs from the package, tasks and devices. + #### Internal API
`SYNO.ActiveBackup.Log`
-#### Parameters -
-**_task_id_** `int` -Get logs of specific task. Defaults to `-1` (all logs - package/tasks/devices) - -**_log_level_** `str` -Type of logs to return. Defaults to `""` (all types). -Possible values: -- `"error"` -- `"warning"` -- `"information"` - -Note that values are different when returned by the API. -Return values mappings: -- 0 -> `error` -- 1 -> `warning` -- 2 -> `information` - -**_keyword_** `str` -Keyword used to filter the results. Defaults to `""`. - -**_from_date_** `int` -Date from which the results will start. Format must be epoch date in seconds. Defaults to `0` (no time limit). - -**_to_date_** `int` -Date until which the results will start. Format must be epoch date in seconds. Defaults to `0` (no time limit). - -**_offset_** `int` -Offset results by this value. Defaults to `0`. - -**_limit_** `int` -Amount of results to be returned. Defaults to `200`. - - -
-#### Returns -
-`dict[str, object]` -Dictionary containing a list of logs. - -
#### Example return
Click to expand ```json -{ - "count": 1, - "logs": [ - { - "backup_type": 4, - "device_id": 6, - "device_name": "xxxx", - "error_code": 0, - "log_id": 5525, - "log_level": 0, - "log_time": 1741897498, - "log_type": 1104, - "other_params": { + { + "count": 1, + "logs": [ + { "backup_type": 4, "device_id": 6, "device_name": "xxxx", - "platform_type": 0, + "error_code": 0, + "log_id": 5525, + "log_level": 0, + "log_time": 1741897498, + "log_type": 1104, + "other_params": { + "backup_type": 4, + "device_id": 6, + "device_name": "xxxx", + "platform_type": 0, + "task_id": 8, + "task_name": "xxxxxxxx", + "user_id": 0, + "user_name": "" + }, + "result_id": 592, "task_id": 8, "task_name": "xxxxxxxx", "user_id": 0, "user_name": "" - }, - "result_id": 592, - "task_id": 8, - "task_name": "xxxxxxxx", - "user_id": 0, - "user_name": "" - } - ] -} -``` + } + ] + } + ```
@@ -812,33 +770,34 @@ Return the history of task execution. #### Parameters
**_task_id_** `int` -Get logs of specific task. Defaults to `-1` (all tasks) +Get logs of specific task. Defaults to `-1` (all tasks). **_status_** `str` Return only tasks matching the status provided. Defaults to `""` (all status). -Possible values: +Possible values: - `"success"` - `"partial_success"` - `"fail"` - `"cancel"` - -Note that values are different when returned by the API. +Note that values are different when returned by the API. Return values mappings: - `2` -> `success` - `3` -> `partial_success` - `4` -> `fail` - `5` -> `cancel` +**_keyword_** `str` +Keyword used to filter the results. Defaults to `""`. + **_backup_type_** `str` Return only tasks matching the device type provided. Defaults to `""` (all device types). -Possible values: +Possible values: - `"vm"` - `"pc"` - `"physical_server"` - `"file_server"` - `"nas"` - -Note that values are different when returned by the API. +Note that values are different when returned by the API. Return values mappings: - `1` -> `vm` - `2` -> `pc` @@ -848,7 +807,7 @@ Return values mappings: **_action_type_** `str` Return only tasks matching the task type provided. Defaults to `""` (all task types). -Possible values: +Possible values: - `"backup"` - `"dedup_data"` - `"restore"` @@ -858,8 +817,7 @@ Possible values: - `"delete_host"` - `"relink"` - `"create_task"` - -Note that values are different when returned by the API. +Note that values are different when returned by the API. Return values mappings: - `1` -> `backup` - `1048576` -> `dedup_data` @@ -871,9 +829,6 @@ Return values mappings: - `2097152` -> `relink` - `268435456` -> `create_task` -**_keyword_** `str` -Keyword used to filter the results. Defaults to `""`. - **_from_date_** `int` Date from which the results will start. Format must be epoch date in seconds. Defaults to `0` (no time limit). @@ -898,37 +853,37 @@ Dictionary containing a list of results.
Click to expand ```json -{ - "data": { - "count": 1, - "results": [ - { - "backup_type": 2, - "detail_path": "", - "error_count": 0, - "job_action": 131072, - "none_count": 0, - "result_id": 594, - "status": 2, - "success_count": 1, - "task_config": { - "device_list": [ - { - "host_name": "xxxxxxx" - } - ] + { + "data": { + "count": 1, + "results": [ + { + "backup_type": 2, + "detail_path": "", + "error_count": 0, + "job_action": 131072, + "none_count": 0, + "result_id": 594, + "status": 2, + "success_count": 1, + "task_config": { + "device_list": [ + { + "host_name": "xxxxxxx" + } + ] + }, + "task_id": 5, + "task_name": "xxxxxxxxxxx", + "time_end": 1741952422, + "time_start": 1741952402, + "warning_count": 0 }, - "task_id": 5, - "task_name": "xxxxxxxxxxx", - "time_end": 1741952422, - "time_start": 1741952402, - "warning_count": 0 - }, - ] - }, - "success": true -} -``` + ] + }, + "success": true + } + ```
@@ -937,7 +892,7 @@ Dictionary containing a list of results. ### `result_details` -Get details of a task result log. `result_id` can be retrieved from `list_logs()` function. +Get details of a task result log. #### Internal API
@@ -988,7 +943,7 @@ Dictionary containing a list of result details. "other_params": { "fs_error": -65, "os_name": "smb", - "path": "/D", + "path": "abc", "task_id": 8 }, "result_detail_id": 9526, @@ -1038,53 +993,53 @@ A dictionary containing a list of storage devices.
Click to expand ```json -{ - "data" : { - "storages" : [ - { - "automount_iv" : "", - "automount_location" : "", - "backup_tasks" : [], - "compacting" : false, - "compacting_percentage" : 0, - "compressed_size" : 0, - "dedup_size" : 1617010274304, - "delete_tasks" : [], - "delete_versions" : [], - "device_count" : 4, - "device_info" : { - "agentless_count" : 1, - "agentless_size" : 0, - "dsm_count" : 0, - "dsm_size" : 0, - "pc_count" : 2, - "pc_size" : 6128863440896, - "server_count" : 1, - "server_size" : 0, - "vm_count" : 0, - "vm_size" : 0 - }, - "fs_name" : "btrfs", - "fs_type" : 3, - "mounted" : true, - "relink_state" : { - "alive" : false, - "owner" : true, - "state" : 0 - }, - "repo_dir" : "@ActiveBackup", - "share_name" : "ActiveBackupforBusiness", - "storage_compress_algorithm" : 0, - "storage_encrypt_algorithm" : 0, - "storage_id" : 1, - "vol_name" : "Volume 3", - "volume_path" : "/volume3" - } - ] - }, - "success" : true - } -``` + { + "data" : { + "storages" : [ + { + "automount_iv" : "", + "automount_location" : "", + "backup_tasks" : [], + "compacting" : false, + "compacting_percentage" : 0, + "compressed_size" : 0, + "dedup_size" : 1617010274304, + "delete_tasks" : [], + "delete_versions" : [], + "device_count" : 4, + "device_info" : { + "agentless_count" : 1, + "agentless_size" : 0, + "dsm_count" : 0, + "dsm_size" : 0, + "pc_count" : 2, + "pc_size" : 6128863440896, + "server_count" : 1, + "server_size" : 0, + "vm_count" : 0, + "vm_size" : 0 + }, + "fs_name" : "btrfs", + "fs_type" : 3, + "mounted" : true, + "relink_state" : { + "alive" : false, + "owner" : true, + "state" : 0 + }, + "repo_dir" : "@ActiveBackup", + "share_name" : "ActiveBackupforBusiness", + "storage_compress_algorithm" : 0, + "storage_encrypt_algorithm" : 0, + "storage_id" : 1, + "vol_name" : "Volume 3", + "volume_path" : "/volume3" + } + ] + }, + "success" : true + } + ```
@@ -1093,7 +1048,7 @@ A dictionary containing a list of storage devices. ### `backup_task_run` -Trigger a backup event for the given tasks. +Trigger a backup event for the given tasks. #### Internal API
@@ -1103,7 +1058,7 @@ Trigger a backup event for the given tasks. #### Parameters
**_task_ids_** `list[int]` -List of task IDs to trigger the backup event. +List of task IDs to trigger the backup event. Even if only one task is specified, a list has to be passed as argument. @@ -1118,10 +1073,10 @@ Dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1140,7 +1095,7 @@ Cancel specified ongoing task. #### Parameters
**_task_ids_** `list[int]` -List of task IDs to trigger the cancellation event. +List of task IDs to trigger the cancellation event. Even if only one task is specified, a list has to be passed as argument. @@ -1155,10 +1110,10 @@ Dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1182,7 +1137,7 @@ Remove the given tasks from ABB. #### Parameters
**_task_ids_** `list[int]` -List of task IDs to remove. +List of task IDs to remove. Even if only one task is specified, a list has to be passed as argument. @@ -1197,10 +1152,10 @@ Dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -1241,10 +1196,10 @@ Dictionary containing the result of the operation.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
diff --git a/documentation/docs/apis/classes/core_backup.md b/documentation/docs/apis/classes/core_backup.md index 49c03d7b..246bd16c 100644 --- a/documentation/docs/apis/classes/core_backup.md +++ b/documentation/docs/apis/classes/core_backup.md @@ -14,16 +14,29 @@ This API is partially documented or under construction. ::: ## Overview - +Synology Hyper Backup API. ## Methods ### `backup_repository_get` -Get repository information for given task. +Get repository information for a given task. #### Internal API
`SYNO.Backup.Repository`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +Repository information. + +
@@ -38,6 +51,12 @@ Get a list of all present repositories in Hyper Backup. `SYNO.Backup.Repository`
+#### Returns +
+`dict[str, object] or str` +List of repositories. + +
@@ -52,6 +71,12 @@ Get current restoring information and a list of present tasks in Hyper Backup. `SYNO.Backup.Task`
+#### Returns +
+`dict[str, object] or str` +List of tasks and restoring information. + +
@@ -59,13 +84,26 @@ Get current restoring information and a list of present tasks in Hyper Backup. ### `backup_task_status` -Get status and state of task. +Get status and state of a task. #### Internal API
`SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +Status and state information. + +
@@ -73,13 +111,26 @@ Get status and state of task. ### `backup_task_get` -Get detailed task information. +Get detailed task information. #### Internal API
`SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +Task information. + +
@@ -94,6 +145,19 @@ Get last result summary information of a task. `SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +Last result summary. + +
@@ -108,6 +172,19 @@ If the task is not in backupable state, the API will return an error, usually 44 `SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -122,6 +199,19 @@ If the task is not running, the API will return an error, usually 44xx. `SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -136,6 +226,19 @@ If the task is not running or not yet suspendable, the API will return an error, `SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -150,6 +253,19 @@ If the task is not suspended, the request will not fail, and will fail to discar `SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -157,13 +273,26 @@ If the task is not suspended, the request will not fail, and will fail to discar ### `backup_task_resume` -Discard currently suspended backup task. +Resume currently suspended backup task. If the task is not suspended, the request will not fail, and will fail to resume the task, leaving the task state as "Failed". #### Internal API
`SYNO.Backup.Task`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -174,12 +303,25 @@ If the task is not suspended, the request will not fail, and will fail to resume Remove one or more backup tasks. Data in destination will not be removed. It is still possible to relink the task using the original .hbk file. The API requires an array of tasks to remove, it should be passed as a string with the following format: -`task_id_list = '[29]'` || `task_id_list = '[29,15]'` +`task_id_list = '[29]'` or `task_id_list = '[29,15]'` #### Internal API
`SYNO.Backup.Task`
+#### Parameters +
+**_task_id_list_** `str` +List of task IDs as a string. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -188,12 +330,25 @@ The API requires an array of tasks to remove, it should be passed as a string wi ### `integrity_check_run` Run integrity check for backup task. -If the task is running, the request will not fail, and will fail to perform the integrity check due to target is busy. +If the task is running, the request will not fail, and will fail to perform the integrity check due to target being busy. #### Internal API
`SYNO.Backup.Target`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -208,6 +363,19 @@ If integrity check is not running, the API will return an error, usually 44xx. `SYNO.Backup.Target`
+#### Parameters +
+**_task_id_** `str` +Task ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -222,6 +390,31 @@ Get Hyper Backup UI logs. `SYNO.SDS.Backup.Client.Common.Log`
+#### Parameters +
+**_limit_** `int` +Maximum number of logs to return (default is 1000). + +**_offset_** `int` +Offset for pagination (default is 0). + +**_filter_keyword_** `str` +Keyword to filter logs (default is ''). + +**_filter_date_from_** `int` +Start date in epoch format (default is 0). + +**_filter_date_to_** `int` +End date in epoch format (default is 0). + + +
+#### Returns +
+`dict[str, object] or str` +Logs information. + +
@@ -236,6 +429,12 @@ List all available targets in Vault. `SYNO.Backup.Service.VersionBackup.Target`
+#### Returns +
+`dict[str, object]` +List of available targets. + +
@@ -243,13 +442,19 @@ List all available targets in Vault. ### `vault_concurrency_get` -Get number of concurrent tasks allowed to run in HB Vault. Default value is 2. +Get number of concurrent tasks allowed to run in HB Vault. #### Internal API
`SYNO.Backup.Service.VersionBackup.Config`
+#### Returns +
+`dict[str, object]` +Number of concurrent tasks (default is 2). + +
@@ -257,13 +462,26 @@ Get number of concurrent tasks allowed to run in HB Vault. Default value is 2. ### `vault_concurrency_set` -Set number of concurrent tasks allowed to run in HB Vault. Default value is 2. +Set number of concurrent tasks allowed to run in HB Vault. #### Internal API
`SYNO.Backup.Service.VersionBackup.Config`
+#### Parameters +
+**_parallel_backup_limit_** `int` +Number of concurrent tasks (default is 2). + + +
+#### Returns +
+`dict[str, object]` +API response. + +
@@ -271,13 +489,26 @@ Set number of concurrent tasks allowed to run in HB Vault. Default value is 2. ### `vault_target_settings_get` -Get settings of target. +Get settings of a target. #### Internal API
`SYNO.Backup.Service.VersionBackup.Target`
+#### Parameters +
+**_target_id_** `int` +Target ID. + + +
+#### Returns +
+`dict[str, object]` +Target settings. + +
@@ -285,13 +516,26 @@ Get settings of target. ### `vault_task_statistics_get` -Get statistics for given task. +Get statistics for a given task. #### Internal API
`SYNO.SDS.Backup.Server.Common.Statistic`
+#### Parameters +
+**_task_id_** `int` +Task ID. + + +
+#### Returns +
+`dict[str, object]` +Task statistics. + +
@@ -299,13 +543,32 @@ Get statistics for given task. ### `vault_target_logs_get` -Get logs for given task. +Get logs for a given target. #### Internal API
`SYNO.SDS.Backup.Server.Common.Log`
+#### Parameters +
+**_target_id_** `int` +Target ID. + +**_limit_** `int` +Maximum number of logs to return (default is 1000). + +**_offset_** `int` +Offset for pagination (default is 0). + + +
+#### Returns +
+`dict[str, object]` +Logs information. + +
diff --git a/documentation/docs/apis/classes/core_certificate.md b/documentation/docs/apis/classes/core_certificate.md index db61e70e..736729ef 100644 --- a/documentation/docs/apis/classes/core_certificate.md +++ b/documentation/docs/apis/classes/core_certificate.md @@ -14,9 +14,46 @@ This API is not documented yet. ::: ## Overview - +Synology DSM Core Certificate API Wrapper. + +This class provides methods to interact with the Synology DSM Core Certificate API, +allowing management of SSL certificates on a Synology NAS. + +Parameters +---------- +ip_address : str + IP address or hostname of the Synology NAS. +port : str + Port number to connect to. +username : str + Username for authentication. +password : str + Password for authentication. +secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). +cert_verify : bool, optional + Verify SSL certificates (default is False). +dsm_version : int, optional + DSM version (default is 7). +debug : bool, optional + Enable debug output (default is True). +otp_code : Optional[str], optional + One-time password for 2FA (default is None). ## Methods ### `list_cert` +List all certificates. + +#### Internal API +
+`SYNO.Core.Certificate` +
+ +#### Returns +
+`dict[str, object]` +List of certificates. + +
@@ -24,6 +61,26 @@ This API is not documented yet. ### `set_default_cert` +Set a certificate as the default. + +#### Internal API +
+`SYNO.Core.Certificate` +
+ +#### Parameters +
+**_cert_id_** `str` +Certificate ID to set as default. + + +
+#### Returns +
+`dict[str, object]` +API response. + +
@@ -31,6 +88,26 @@ This API is not documented yet. ### `delete_certificate` +Delete one or more certificates. + +#### Internal API +
+`SYNO.Core.Certificate` +
+ +#### Parameters +
+**_ids_** `str or list[str]` +Certificate ID or list of IDs to delete. + + +
+#### Returns +
+`dict[str, object]` +API response. + +
@@ -38,6 +115,41 @@ This API is not documented yet. ### `upload_cert` +Upload a certificate to the Synology NAS. + +#### Internal API +
+`SYNO.Core.Certificate` +
+ +#### Parameters +
+**_serv_key_** `str` +Path to the server key file (default is "server.key"). + +**_ser_cert_** `str` +Path to the server certificate file (default is "server.crt"). + +**_ca_cert_** `Optional[str]` +Path to the CA certificate file (default is None). + +**_set_as_default_** `bool` +Set as default certificate after upload (default is True). + +**_cert_id_** `Optional[str]` +Certificate ID to update (default is None). + +**_desc_** `Optional[str]` +Description for the certificate (default is None). + + +
+#### Returns +
+`tuple[int, dict[str, object]]` +HTTP status code and API response. + +
@@ -45,6 +157,29 @@ This API is not documented yet. ### `set_certificate_for_service` +Set a certificate for a specific DSM service. + +#### Internal API +
+`SYNO.Core.Certificate.Service` +
+ +#### Parameters +
+**_cert_id_** `str` +Certificate ID to assign. + +**_service_name_** `str` +Name of the service (default is "DSM Desktop Service"). + + +
+#### Returns +
+`tuple[int, dict[str, object]]` +HTTP status code and API response. + +
@@ -69,7 +204,7 @@ The certificate ID to export. This can be found in the list_cert() method. #### Returns
`Optional[BytesIO]` -A BytesIO object containing the certificate archive. +A BytesIO object containing the certificate archive, or None if export fails.
diff --git a/documentation/docs/apis/classes/core_group.md b/documentation/docs/apis/classes/core_group.md index 7b8edfe8..5f777696 100644 --- a/documentation/docs/apis/classes/core_group.md +++ b/documentation/docs/apis/classes/core_group.md @@ -9,28 +9,42 @@ title: ✅ Group # Group ## Overview -Core Group API implementation. - -### Supported methods - - - **Getters** : - - Get all groups - - Get group members - - Get group shares permissions - - Get group shares quota - - Get group services speed limits - - - **Setters** : - - Set group name/description - - Set group share permissions - - Set group share quotas - - Set group service speed limit - - - **Actions** : - - Create new group - - Delete groups - - Add users to a group - - Remove users from a group +Core Group API implementation for Synology NAS. + +This class provides methods to manage groups, including: +- Retrieving group information, members, permissions, quotas, and speed limits. +- Modifying group name, description, share permissions, quotas, and speed limits. +- Creating and deleting groups. +- Adding and removing users from groups. + +Methods +------- +get_groups(offset=0, limit=-1, name_only=False) + Retrieve groups information. +get_users(group, in_group=True) + Retrieve users who are members or not members of a group. +get_speed_limits(group) + Retrieve bandwidth control settings for a group. +get_quota(group) + Retrieve quota settings for a group. +get_permissions(group) + Retrieve share permissions for a group. +set_group_info(group, new_name="", new_description="") + Change group name and/or description. +set_share_quota(group, share_quotas) + Set group quota for a given share. +set_share_permissions(group, permissions) + Set group permissions for a given share. +set_speed_limit(group, upload_limit, download_limit, protocol) + Set speed limit for a given share. +add_users(group, users) + Add users to a group. +remove_users(group, users) + Remove users from a group. +create(name, description="") + Create a new group. +delete(groups) + Delete specified groups. ## Methods ### `get_groups` Retrieve groups information. @@ -43,13 +57,13 @@ Retrieve groups information. #### Parameters
**_offset_** `int` -The offset of the groups to retrieve. Defaults to `0`. +The offset of the groups to retrieve. Defaults to 0. **_limit_** `int` -The maximum number of groups to retrieve. Defaults to `-1` (all groups). +The maximum number of groups to retrieve. Defaults to -1 (all groups). **_name_only_** `bool` -If `True`, returns only group names. If `False`, returns full group information. Defaults to `False`. +If True, returns only group names. If False, returns full group information. Defaults to False.
@@ -101,7 +115,7 @@ A dictionary containing the groups information. ### `get_users` -Retrieve users members or not of a group. +Retrieve users who are members or not members of a group. #### Internal API
@@ -114,9 +128,8 @@ Retrieve users members or not of a group. The group to list users from. **_in_group_** `bool` -Defaults to `True`. -If `True`, retrieves users who are members of the specified group. -If `False`, retrieves users who are not members of the group. +If True, retrieves users who are members of the specified group. +If False, retrieves users who are not members of the group. Defaults to True.
@@ -172,7 +185,7 @@ Retrieve bandwidth control settings for a given group. #### Parameters
-**_group_** `str ` +**_group_** `str` The group to retrieve settings for. @@ -183,6 +196,31 @@ The group to retrieve settings for. A dictionary containing the result of the request.
+#### Example return +
+Click to expand +```json +{ + "data": { + "bandwidths": [ + { + "download_limit_1": 0, + "download_limit_2": 0, + "name": "group_name", + "owner_type": "local_group", + "policy": "notexist", + "protocol": "FTP", + "protocol_ui": "FTP", + "schedule_plan": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "upload_limit_1": 0, + "upload_limit_2": 0 + }, + ] + }, + "success": true +} +``` +
@@ -199,14 +237,14 @@ Retrieve quota settings for a given group. #### Parameters
-**_group_** `str ` +**_group_** `str` The group to retrieve quota settings for.
#### Returns
-`dict[str, object] ` +`dict[str, object]` A dictionary containing the result of the request.
@@ -286,7 +324,7 @@ A dictionary containing the result of the request. "total": 1 }, "success": true -} +} ``` @@ -318,7 +356,7 @@ The new description of the group. Defaults to current value.
#### Returns
-`dict[str, object] ` +`dict[str, object]` A dictionary containing the result of the request.
@@ -354,27 +392,14 @@ Set group quota for a given share. **_group_** `str` The group to set the quota for. -**_share_quotas (list[dict[str, Any]])_** `` +**_share_quotas_** `list of dict` The quotas to set for the group. -Example: -```python -[ - { - "share": "web", - "quota": 1024, # in MB - }, - { - "share": "photo", - "quota": 5120, # in MB - } -] -```
#### Returns
-`dict[str, object] ` +`dict[str, object]` A dictionary containing the result of the request.
@@ -407,25 +432,8 @@ Set group permissions for a given share. **_group_** `str` The group to set the permissions for. -**_permissions_** `list[dict[str, object]]:` +**_permissions_** `list of dict` The permissions to set for the group. -Example: -```python -[ - { - "name": "web", - "is_readonly": False, - "is_writable": False, - "is_deny": True - }, - { - "name": "ActiveBackupforBusiness", - "is_readonly": False, - "is_writable": True, - "is_deny": False - } -] -```
@@ -451,13 +459,8 @@ A dictionary containing the result of the request. ### `set_speed_limit` -Set speed limit for a given share. -:::info - - Doesn't support **scheduled** speed limits, only on/off. - -::: - +Set speed limit for a given share. + #### Internal API
`SYNO.Core.BandwidthControl` @@ -475,13 +478,8 @@ The maximum upload speed in KB/s. The maximum download speed in KB/s. **_protocol_** `str` -The protocol to set the speed limit for. -Possible values: -- FileStation -- WebDAV -- FTP -- NetworkBackup (Rsync) -- CloudStation (Synology Drive) +The protocol to set the speed limit for. Possible values: +FileStation, WebDAV, FTP, NetworkBackup (Rsync), CloudStation (Synology Drive).
@@ -521,10 +519,10 @@ Add users to a group. #### Parameters
-**_group_** `str ` +**_group_** `str` The group to add users to. -**_users_** `list[str]` +**_users_** `list of str` The users to add to the group. @@ -561,10 +559,10 @@ Remove users from a group. #### Parameters
-**_group_** `str ` +**_group_** `str` The group to remove users from. -**_users_** `list[str]` +**_users_** `list of str` The users to remove from the group. @@ -592,7 +590,7 @@ A dictionary containing the result of the request. ### `create` -Create group. +Create a new group. #### Internal API
@@ -611,7 +609,7 @@ Description to assign to the group. Defaults to empty string.
#### Returns
-`dict[str, object] ` +`dict[str, object]` A dictionary containing the result of the request.
@@ -644,14 +642,14 @@ Delete specified groups. #### Parameters
-**_groups_** `list[str]` +**_groups_** `list of str` The groups to delete.
#### Returns
-`dict[str, object] ` +`dict[str, object]` A dictionary containing the result of the request.
diff --git a/documentation/docs/apis/classes/core_package.md b/documentation/docs/apis/classes/core_package.md index 1e558c9d..f9ce9635 100644 --- a/documentation/docs/apis/classes/core_package.md +++ b/documentation/docs/apis/classes/core_package.md @@ -14,10 +14,53 @@ This API is partially documented or under construction. ::: ## Overview -Core Package API implementation. +Core Package API implementation for Synology NAS. + +This class provides methods to manage packages, including: +- Listing installed and installable packages. +- Installing, upgrading, and uninstalling packages. +- Uploading package files. +- Configuring package center settings. + +Methods +------- +get_package(package_id, additional) + Get information about a package. +list_installed(additional, ignore_hidden) + List installed packages. +list_installable() + List installable packages. +get_package_center_settings() + Get package center settings. +set_package_center_settings(...) + Set package center settings. +get_package_center_infos() + Get package center information. +feasibility_check_install(packages) + Check if installation is possible. +download_package(url, package_id, checksum, filesize) + Start download of a package. +get_dowload_package_status(task_id) + Get current download status of a package. +check_installation_from_download(task_id) + Get info about downloaded package file. +upload_package_file(file_path, verify, progress_bar, additional) + Upload a file for installing a package. +get_default_install_volume() + Get default install volume for packages. +check_installation(...) + Check installation of a package. +upgrade_package(...) + Upgrade an existing package. +install_package(...) + Install a package that is already downloaded. +uninstall_package(package_id) + Uninstall a package. +easy_install(package_id, volume_path, install_dependencies) + Execute an easy installation process of a package. ## Methods ### `get_package` -Get infos of a package +Get infos of a package. #### Internal API
@@ -27,19 +70,19 @@ Get infos of a package #### Parameters
**_package_id_** `str` -Package ID +Package ID. **_additional_** `List[str]` -Additional field to retrieves. Defaults to `[]` +Additional field to retrieves. Defaults to `[]`. All filed known are: -`["status","dsm_apps"]` +`["status","dsm_apps"]`.
#### Returns
`dict` -Informations about the package +Informations about the package.
#### Example return @@ -71,7 +114,7 @@ Informations about the package ### `list_installed` -List installed packages +List installed packages. #### Internal API
@@ -82,7 +125,7 @@ List installed packages
**_additional_** `list[str]` Additional fields to retrieve. Defaults to `[]`. -All fields known are: +All fields known are: `["description", "description_enu", "dependent_packages", "beta", "distributor", "distributor_url", "maintainer", "maintainer_url", "dsm_apps", "dsm_app_page", "dsm_app_launch_name","report_beta_url", "support_center", "startable", "installed_info", "support_url", "is_uninstall_pages","install_type", @@ -90,14 +133,14 @@ All fields known are: "url","available_operation"]`. **_ignore_hidden_** `bool` -TODO: Write description +Whether to ignore hidden packages.
#### Returns
`dict` -List of packages installed on the NAS +List of packages installed on the NAS.
#### Example return @@ -110,13 +153,13 @@ List of packages installed on the NAS { "additional": { "install_type": "" - }, - "id": "ActiveBackup-Office365", - "name": "Active Backup for Microsoft 365", - "timestamp": 1738880043640, - "version": "2.5.5-14034" - } - ] + }, + "id": "ActiveBackup-Office365", + "name": "Active Backup for Microsoft 365", + "timestamp": 1738880043640, + "version": "2.5.5-14034" + } + } }, "success": true } @@ -129,7 +172,7 @@ List of packages installed on the NAS ### `list_installable` -List installable packages +List installable packages. #### Internal API
@@ -139,7 +182,7 @@ List installable packages #### Returns
`dict` -List of beta_package, categories and packages available +List of beta_package, categories and packages available.
#### Example return @@ -164,7 +207,7 @@ List of beta_package, categories and packages available ### `get_package_center_settings` -Get package center settings +Get package center settings. #### Internal API
@@ -174,7 +217,7 @@ Get package center settings #### Returns
`dict` -List settings of the Package center +List settings of the Package center.
#### Example return @@ -225,7 +268,7 @@ List settings of the Package center ### `set_package_center_settings` -Set settings of the package center +Set settings of the package center. #### Internal API
@@ -235,33 +278,33 @@ Set settings of the package center #### Parameters
**_enable_email_** `bool` -Enable email notification +Enable email notification. -**_enable_dsm_** `bool ` -Enable desktop notification +**_enable_dsm_** `bool` +Enable desktop notification. **_enable_autoupdate_** `bool` -Update packages automatically +Update packages automatically. **_autoupdateall_** `bool` -Auto update all packages +Auto update all packages. **_autoupdateimportant_** `bool` -Auto update "important" packages +Auto update "important" packages. **_default_vol_** `str` -Default volume for installation, all your volumes or `"no_default_vol" = Always ask me` +Default volume for installation, all your volumes or `"no_default_vol" = Always ask me`. -**_udpate_channel_** `str` -"stable" => Disable beta packages -"beta" => Enable beta packages +**_update_channel_** `str` +"stable" => Disable beta packages. +"beta" => Enable beta packages.
#### Returns
`dict` -Return some settings +Return some settings.
#### Example return @@ -285,7 +328,7 @@ Return some settings ### `get_package_center_infos` -Get package center informations +Get package center informations. #### Internal API
@@ -295,9 +338,44 @@ Get package center informations #### Returns
`dict` -List of configs +List of configs.
+#### Example return +
+Click to expand +```json +{ + "data": { + "config": { + "auth_key": "------------------------------", + "blBetaChannel": false, + "blOtherServer": false, + "def_void": "", + "ds_build": "72806", + "ds_major": "7", + "ds_minor": "2", + "ds_timezone": "Amsterdam", + "ds_unique": "synology_r1000_723+", + "myPayBaseURL": "https://payment.synology.com", + "myds_id": "7886858", + "serial": "2260TPR7X30E6", + "success": true + }, + "prerelease": { + "agreed": true, + "success": true + }, + "term": { + "agreed_term_version": "0003", + "curr_term_version": "0003", + "success": true + } + }, + "success": true +} +``` +
@@ -305,7 +383,7 @@ List of configs ### `feasibility_check_install` -Check if installation is possible +Check if installation is possible. #### Internal API
@@ -315,14 +393,14 @@ Check if installation is possible #### Parameters
**_packages_** `List[str]` -List of package IDs to check for feasibility +List of package IDs to check for feasibility.
#### Returns
`dict` -_description_ +Feasibility check result.
#### Example return @@ -344,7 +422,7 @@ _description_ ### `download_package` -Start download of the package, return a taskId for check status +Start download of the package, return a taskId for check status. #### Internal API
@@ -354,23 +432,23 @@ Start download of the package, return a taskId for check status #### Parameters
**_url_** `str` -Url that can be retrieve from package info using `get_installable` function, in the `link` field +Url that can be retrieve from package info using `get_installable` function, in the `link` field. **_package_id_** `str` -Package ID that can be retrieve from package info using `get_installable` function, in the `id` field +Package ID that can be retrieve from package info using `get_installable` function, in the `id` field. **_checksum_** `str` -Checksum that can be retrieve from package info using `get_installable` function, in the `md5` field +Checksum that can be retrieve from package info using `get_installable` function, in the `md5` field. **_filesize_** `str` -Filesize that can be retrieve from package info using `get_installable` function, in the `size` field +Filesize that can be retrieve from package info using `get_installable` function, in the `size` field.
#### Returns
`dict` -Retreive first progress of the download and the taskid used to check download status with `get_dowload_package_status` function +Retrieve first progress of the download and the taskid used to check download status with `get_dowload_package_status` function.
#### Example return @@ -393,7 +471,7 @@ Retreive first progress of the download and the taskid used to check download st ### `get_dowload_package_status` -Get current download status of the package +Get current download status of the package. #### Internal API
@@ -403,14 +481,14 @@ Get current download status of the package #### Parameters
**_task_id_** `str` -task ID retrieve from response of `download_package` function +Task ID retrieved from response of `download_package` function.
#### Returns
`dict` -Retrieve informations about the download, important info is the `progress` field +Retrieve informations about the download, important info is the `progress` field.
#### Example return @@ -444,7 +522,7 @@ Retrieve informations about the download, important info is the `progress` field ### `check_installation_from_download` -Get info about downloaded package file, response field is used for `check_installation` and `install_package` function +Get info about downloaded package file, response field is used for `check_installation` and `install_package` function. #### Internal API
@@ -454,14 +532,14 @@ Get info about downloaded package file, response field is used for `check_instal #### Parameters
**_task_id_** `str` -task ID retrieve from response of `download_package` function +Task ID retrieved from response of `download_package` function.
#### Returns
`dict` -Retrieve information about downloaded package installation file, response field is used for `check_installation` and `install_package` function +Retrieve information about downloaded package installation file, response field is used for `check_installation` and `install_package` function.
#### Example return @@ -498,7 +576,7 @@ Retrieve information about downloaded package installation file, response field ### `upload_package_file` -Upload a file for install a package +Upload a file for install a package. #### Internal API
@@ -508,16 +586,16 @@ Upload a file for install a package #### Parameters
**_file_path_** `str` -File path +File path. **_verify_** `bool` -Use https. Defaults to `False` +Use https. Defaults to `False`. **_progress_bar_** `bool` -Enable progress bar in the terminal. Defaults to `True` +Enable progress bar in the terminal. Defaults to `True`. **_additional_** `list` -Additional field to retrieves. Defaults to `[]` +Additional field to retrieves. Defaults to `[]`. All fields know are: `["description","maintainer","distributor","startable","dsm_apps","status","install_reboot", "install_type","install_on_cold_storage","break_pkgs","replace_pkgs"]`. @@ -527,7 +605,7 @@ All fields know are: #### Returns
`dict` -Informations about the uploaded file for installation +Informations about the uploaded file for installation.
#### Example return @@ -569,7 +647,7 @@ Informations about the uploaded file for installation ### `get_default_install_volume` -Get default install volume for package +Get default install volume for package. #### Internal API
@@ -579,7 +657,7 @@ Get default install volume for package #### Returns
`dict` -Return default volume, if default volume is set to `Always ask me` it return error 4501 +Return default volume, if default volume is set to `Always ask me` it return error 4501.
#### Example return @@ -601,7 +679,7 @@ Return default volume, if default volume is set to `Always ask me` it return err ### `check_installation` -Check installation of the package on the default volume +Check installation of the package on the default volume. #### Internal API
@@ -611,26 +689,26 @@ Check installation of the package on the default volume #### Parameters
**_package_id_** `str` -Id of the package to install +Id of the package to install. **_install_type_** `str, optionnal` -Installation type, Defaults to `""`. TODO: Add description and possible types +Installation type, Defaults to `""`. TODO: Add description and possible types. **_install_on_cold_storage_** `bool` -Defaults to `False`. TODO: Add description +Defaults to `False`. TODO: Add description. **_blCheckDep_** `bool` -Defaults to `False`. TODO: Add description +Defaults to `False`. TODO: Add description. **_replacepkgs_** `dict` -Defaults to `{}`. TODO: Add description +Defaults to `{}`. TODO: Add description.
#### Returns
`dict` -List of usefull informations about volumes +List of usefull informations about volumes.
#### Example return @@ -674,69 +752,52 @@ List of usefull informations about volumes ### `upgrade_package` -Upgrade an existing package -Parameters - ---------- - task_id : str - Task id of the download or the upload file - check_codesign : bool, optional - Check signature of the source code of the package (is it a Synology one). Defaults to `False` - force : bool, optional - Force installation. Defaults to `False` - installrunpackage : bool, optional - Run package after installation. Defaults to `True` - extra_values : dict, optional - Extra values due to some package installation. Defaults to `{}` - All known extra values are: - - Surveillance station - ```json - { - "chkSVS_Alias": true, - "strSVS_Alias": "cam", - "chkSVS_HTTP": true, - "strSVS_HTTP": "9900", - "chkSVS_HTTPS": true, - "strSVS_HTTPS": "9901" - } - ``` - - Returns - ------- - dict - Message and some info about installation - - Example return - ---------- - ```json - { - "data": { - "message": "

Installation Successful!

-

:::note - - If Plex cannot access your media, verify user PlexMediaServer is granted permission in Control Panel.


- -::: - -Set access to your media share(s) by performing the following steps:

-1. Open Control Panel and select Shared Folder
-2. Select the share which contains your media and click Edit
-3. Click the Permissions tab
-4. Change the dropdown from Local Users to System internal user
-5. Check the Read/Write checkbox for the PlexMediaServer user
-6. Click Save to confirm the new permissions
-7. Repeat steps 2-6 for each share you want Plex Media Server to access
-", - "packageName": "Plex Media Server", - "worker_message": [] - }, - "success": true, - } - ``` +Upgrade an existing package. + #### Internal API
`SYNO.Core.Package.Installation`
+#### Parameters +
+**_task_id_** `str` +Task id of the download or the upload file. + +**_check_codesign_** `bool` +Check signature of the source code of the package (is it a Synology one). Defaults to `False`. + +**_force_** `bool` +Force installation. Defaults to `False`. + +**_installrunpackage_** `bool` +Run package after installation. Defaults to `True`. + +**_extra_values_** `dict` +Extra values due to some package installation. Defaults to `{}`. + + +
+#### Returns +
+`dict` +Message and some info about installation. + +
+#### Example return +
+Click to expand +```json +{ + "data": { + "message": "message", + "packageName": "Plex Media Server", + "worker_message": [] + }, + "success": true, +} +``` +
@@ -744,7 +805,7 @@ Set access to your media share(s) by performing the following steps:

### `install_package` -Install a package that is already downloaded +Install a package that is already downloaded. #### Internal API
@@ -754,44 +815,32 @@ Install a package that is already downloaded #### Parameters
**_package_id_** `str` -Id of the package to install +Id of the package to install. **_volume_path_** `str` -Volume path of the installation, can get from `check_installation` function +Volume path of the installation, can get from `check_installation` function. **_file_path_** `str` -File path of the installation, can get from `check_installation_from_download` function +File path of the installation, can get from `check_installation_from_download` function. **_check_codesign_** `bool` -Check signature of the source code of the package (is it a Synology one). Defaults to `False` +Check signature of the source code of the package (is it a Synology one). Defaults to `False`. **_force_** `bool` -Force installation. Defaults to `False` +Force installation. Defaults to `False`. **_installrunpackage_** `bool` -Run package after installation. Defaults to `True` +Run package after installation. Defaults to `True`. **_extra_values_** `dict` -Extra values due to some package installation. Defaults to `{}` -All known extra values are: -- Surveillance station -```json - { - "chkSVS_Alias": true, - "strSVS_Alias": "cam", - "chkSVS_HTTP": true, - "strSVS_HTTP": "9900", - "chkSVS_HTTPS": true, - "strSVS_HTTPS": "9901" - } -``` +Extra values due to some package installation. Defaults to `{}`.
#### Returns
`dict` -Message and some info about installation +Message and some info about installation.
#### Example return @@ -838,14 +887,14 @@ Message and some info about installation "data": { "packageName": "Text Editor", "worker_message": [] - }, - "method": "install", - "success": true, - "version": 1 - } - ] - }, - "success": true + }, + "method": "install", + "success": true, + "version": 1 + } + ] +}, +"success": true } ``` @@ -856,7 +905,7 @@ Message and some info about installation ### `uninstall_package` -Uninstall a package +Uninstall a package. #### Internal API
@@ -866,14 +915,14 @@ Uninstall a package #### Parameters
**_package_id_** `str` -Id of the package to uninstall +Id of the package to uninstall.
#### Returns
`dict` -Possible message to the user +Possible message to the user.
#### Example return @@ -896,26 +945,30 @@ Possible message to the user ### `easy_install` -Execute an "easy" installation process of the package +Execute an easy installation process of the package. +#### Internal API +
+`hotfix` +
#### Parameters
**_package_id_** `str` -Package ID to install +Package ID to install. **_volume_path_** `str` -Volume path where you want to install the package +Volume path where you want to install the package. **_install_dependencies_** `bool` -If you want to install dependencies. Defaults to `True` +If you want to install dependencies. Defaults to True.
#### Returns
-`dict` -Information about installation, same as `install_package` function +`dict[str, object]` +Information about installation, same as install_package function.
#### Example return @@ -962,14 +1015,14 @@ Information about installation, same as `install_package` function "data": { "packageName": "Text Editor", "worker_message": [] - }, - "method": "install", - "success": true, - "version": 1 - } - ] - }, - "success": true + }, + "method": "install", + "success": true, + "version": 1 + } + ] +}, +"success": true } ``` diff --git a/documentation/docs/apis/classes/core_share.md b/documentation/docs/apis/classes/core_share.md index f6c3acdc..763ee207 100644 --- a/documentation/docs/apis/classes/core_share.md +++ b/documentation/docs/apis/classes/core_share.md @@ -26,7 +26,7 @@ This API is partially documented or under construction. Core Share API implementation. ## Methods ### `validate_set` -Validate set of parameter for a new / modified shared folder +Validate set of parameter for a new / modified shared folder. #### Internal API
@@ -80,7 +80,7 @@ Success. ### `list_folders` -List all folders informations +List all folders informations. #### Internal API
@@ -138,7 +138,7 @@ A dictionary containing the shared folders information. ### `get_folder` -Get a folder by name +Get a folder by name. #### Internal API
@@ -189,7 +189,7 @@ A dictionary containing the shared folder information. ### `create_folder` -Create a new shared folder +Create a new shared folder. #### Internal API
@@ -225,18 +225,24 @@ Enable share cow. Defaults to `False`. **_enable_share_compress_** `bool` Enable share compress. Defaults to `False`. -**_share_quota_** `int, optional ` +**_share_quota_** `int` Share quota. Defaults to `0`. -**_name_org_** `str, optional ` +**_name_org_** `str` Defaults to `""`. +**_encryption_** `bool` +Enable encryption. Defaults to `False`. + +**_enc_passwd_** `str` +Encrypted password. Defaults to `""`. +
#### Returns
`dict` -Name of the created shared folder +Name of the created shared folder.
#### Example return @@ -257,7 +263,7 @@ Name of the created shared folder ### `delete_folders` -Delete folder(s) by name(s) +Delete folder(s) by name(s). #### Internal API
@@ -340,7 +346,7 @@ Share quota. Defaults to `0`. #### Returns
`dict` -Name of the created shared folder +Name of the created shared folder.
#### Example return @@ -357,6 +363,81 @@ Name of the created shared folder +--- + + +### `decrypt_folder` +Decrypt a given share. + +#### Internal API +
+`SYNO.Core.Share.Crypto` +
+ +#### Parameters +
+**_name_** `str` +The share name to decrypt. + +**_password_** `str` +The password to use for decrypting the share. + + +
+#### Returns +
+`dict` +Success. + +
+#### Example return +
+Click to expand +```json + { + "success": true + } + ``` +
+ + + +--- + + +### `encrypt_folder` +Encrypt a given share. + +#### Internal API +
+`SYNO.Core.Share.Crypto` +
+ +#### Parameters +
+**_name_** `str` +The share name to encrypt. + + +
+#### Returns +
+`dict` +Success. + +
+#### Example return +
+Click to expand +```json + { + "success": true + } + ``` +
+ + + --- @@ -365,7 +446,7 @@ Name of the created shared folder Core Share Permission API implementation. ## Methods ### `get_folder_permission_by_name` -Retrieve share permissions for a given folder filtered by permission name (sub string) +Retrieve share permissions for a given folder filtered by permission name (sub string). #### Internal API
@@ -400,8 +481,8 @@ All known values are: `["system", "local_user", "local_group", "ldap_user", "lda
#### Returns
-`dict ` -List of permission(s) on the folder +`dict` +List of permission(s) on the folder.
#### Example return @@ -467,7 +548,7 @@ All known values are: `["system", "local_user", "local_group", "ldap_user", "lda #### Returns
`dict` -All permissions on the folder +All permissions on the folder.
#### Example return @@ -544,26 +625,14 @@ The type of user group to set permissions for. All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. **_permissions_** `dict` -The permissions to set for the folder. -Example: -```json -[ - { - "name":"guest", - "is_readonly":false, - "is_writable":true, - "is_deny":false, - "is_custom":false - } -] -``` +The permissions to set for the folder.
#### Returns
-`dict ` -Success +`dict` +Success.
#### Example return @@ -599,7 +668,7 @@ The group to list permissions for. #### Returns
`dict` -Permissions of a group on Shared folders +Permissions of a group on Shared folders.
#### Example return @@ -625,7 +694,7 @@ Permissions of a group on Shared folders "total": 1 }, "success": true -} +} ``` @@ -648,31 +717,14 @@ Set group permissions for a given share. The group to set the permissions for. **_permissions_** `list[dict[str, Any]]` -The permissions to set for the group. -Example: -``` -[ - { - "name": "web", - "is_readonly": False, - "is_writable": False, - "is_deny": True - }, - { - "name": "ActiveBackupforBusiness", - "is_readonly": False, - "is_writable": True, - "is_deny": False - } -] -``` +The permissions to set for the group.
#### Returns
`dict` -Success +Success.
#### Example return @@ -702,6 +754,12 @@ Initialize KeyManagerStore API. `SYNO.Core.Share.KeyManager.Store`
+#### Returns +
+`dict` +Not implemented yet. + +
@@ -709,6 +767,19 @@ Initialize KeyManagerStore API. ### `verify` +Not implemented yet. + +#### Internal API +
+`SYNO.Core.Share.KeyManager.Store` +
+ +#### Returns +
+`dict` +Not implemented yet. + +
@@ -716,8 +787,8 @@ Initialize KeyManagerStore API. ### `explore` -Explore KeyManagerStore API. Get list of existing stores - +Explore KeyManagerStore API. +Get list of existing stores. #### Internal API
`SYNO.Core.Share.KeyManager.Store` @@ -726,7 +797,7 @@ Explore KeyManagerStore API. Get list of existing stores #### Returns
`dict` -List of stores existing on the NAS +List of stores existing on the NAS.
#### Example return @@ -762,7 +833,7 @@ List KeyManagerStore API. #### Returns
`dict` -List of keys in the manager +List of keys in the manager.
#### Example return diff --git a/documentation/docs/apis/classes/core_sys_info.md b/documentation/docs/apis/classes/core_sys_info.md index da2ac1f0..c56fc982 100644 --- a/documentation/docs/apis/classes/core_sys_info.md +++ b/documentation/docs/apis/classes/core_sys_info.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +Core System Information API implementation for Synology NAS. +This class provides methods to retrieve and manage system, network, hardware, +service, and package information from a Synology NAS. ## Methods ### `fileserv_smb` +Get SMB file service status. + +#### Internal API +
+`SYNO.Core.FileServ.SMB` +
+ +#### Returns +
+`dict[str, object] or str` +SMB file service status. + +
@@ -24,6 +40,19 @@ This API is not documented yet. ### `fileserv_afp` +Get AFP file service status. + +#### Internal API +
+`SYNO.Core.FileServ.AFP` +
+ +#### Returns +
+`dict[str, object] or str` +AFP file service status. + +
@@ -31,6 +60,19 @@ This API is not documented yet. ### `fileserv_nfs` +Get NFS file service status. + +#### Internal API +
+`SYNO.Core.FileServ.NFS` +
+ +#### Returns +
+`dict[str, object] or str` +NFS file service status. + +
@@ -38,6 +80,19 @@ This API is not documented yet. ### `fileserv_ftp` +Get FTP file service status. + +#### Internal API +
+`SYNO.Core.FileServ.FTP` +
+ +#### Returns +
+`dict[str, object] or str` +FTP file service status. + +
@@ -45,6 +100,19 @@ This API is not documented yet. ### `fileserv_sftp` +Get SFTP file service status. + +#### Internal API +
+`SYNO.Core.FileServ.FTP.SFTP` +
+ +#### Returns +
+`dict[str, object] or str` +SFTP file service status. + +
@@ -52,6 +120,19 @@ This API is not documented yet. ### `network_backup_info` +Get network backup service information. + +#### Internal API +
+`SYNO.Backup.Service.NetworkBackup` +
+ +#### Returns +
+`dict[str, object] or str` +Network backup service information. + +
@@ -59,6 +140,19 @@ This API is not documented yet. ### `bandwidth_control_protocol` +Get bandwidth control protocol information. + +#### Internal API +
+`SYNO.Core.BandwidthControl.Protocol` +
+ +#### Returns +
+`dict[str, object] or str` +Bandwidth control protocol information. + +
@@ -66,6 +160,19 @@ This API is not documented yet. ### `shared_folders_info` +Get shared folders information. + +#### Internal API +
+`SYNO.Core.Share` +
+ +#### Returns +
+`dict[str, object] or str` +Shared folders information. + +
@@ -73,6 +180,19 @@ This API is not documented yet. ### `services_status` +Get status of core services. + +#### Internal API +
+`SYNO.Core.Service` +
+ +#### Returns +
+`dict[str, object] or str` +Status of core services. + +
@@ -80,6 +200,19 @@ This API is not documented yet. ### `services_discovery` +Get service discovery information. + +#### Internal API +
+`SYNO.Core.FileServ.ServiceDiscovery` +
+ +#### Returns +
+`dict[str, object] or str` +Service discovery information. + +
@@ -87,6 +220,19 @@ This API is not documented yet. ### `file_transfer_status` +Get file transfer status. + +#### Internal API +
+`SYNO.Core.SyslogClient.FileTransfer` +
+ +#### Returns +
+`dict[str, object] or str` +File transfer status. + +
@@ -94,6 +240,19 @@ This API is not documented yet. ### `network_status` +Get network status. + +#### Internal API +
+`SYNO.Core.Network` +
+ +#### Returns +
+`dict[str, object] or str` +Network status. + +
@@ -101,6 +260,19 @@ This API is not documented yet. ### `web_status` +Get DSM web status. + +#### Internal API +
+`SYNO.Core.Web.DSM` +
+ +#### Returns +
+`dict[str, object] or str` +DSM web status. + +
@@ -108,6 +280,19 @@ This API is not documented yet. ### `current_connection` +Get current connection information. + +#### Internal API +
+`SYNO.Core.CurrentConnection` +
+ +#### Returns +
+`dict[str, object] or str` +Current connection information. + +
@@ -115,6 +300,19 @@ This API is not documented yet. ### `bandwidth_control_status` +Get bandwidth control status. + +#### Internal API +
+`SYNO.Core.BandwidthControl.Status` +
+ +#### Returns +
+`dict[str, object] or str` +Bandwidth control status. + +
@@ -122,6 +320,19 @@ This API is not documented yet. ### `sys_status` +Get system status. + +#### Internal API +
+`SYNO.Core.System.Status` +
+ +#### Returns +
+`dict[str, object] or str` +System status. + +
@@ -129,6 +340,19 @@ This API is not documented yet. ### `latest_logs` +Get latest system logs. + +#### Internal API +
+`SYNO.Core.SyslogClient.Status` +
+ +#### Returns +
+`dict[str, object] or str` +Latest system logs. + +
@@ -136,6 +360,19 @@ This API is not documented yet. ### `client_notify_settings_status` +Get client notification settings status. + +#### Internal API +
+`SYNO.Core.SyslogClient.Setting.Notify` +
+ +#### Returns +
+`dict[str, object] or str` +Client notification settings status. + +
@@ -143,6 +380,19 @@ This API is not documented yet. ### `get_security_scan_info` +Get security scan configuration. + +#### Internal API +
+`SYNO.Core.SecurityScan.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +Security scan configuration. + +
@@ -150,6 +400,19 @@ This API is not documented yet. ### `get_security_scan_rules` +Get security scan rules. + +#### Internal API +
+`SYNO.Core.SecurityScan.Status` +
+ +#### Returns +
+`dict[str, object] or str` +Security scan rules. + +
@@ -157,6 +420,19 @@ This API is not documented yet. ### `get_security_scan_status` +Get security scan status. + +#### Internal API +
+`SYNO.Core.SecurityScan.Status` +
+ +#### Returns +
+`dict[str, object] or str` +Security scan status. + +
@@ -164,6 +440,19 @@ This API is not documented yet. ### `get_user_list` +Get user list. + +#### Internal API +
+`SYNO.Core.User` +
+ +#### Returns +
+`dict[str, object] or str` +User list. + +
@@ -171,6 +460,19 @@ This API is not documented yet. ### `quickconnect_info` +Get QuickConnect configuration. + +#### Internal API +
+`SYNO.Core.QuickConnect` +
+ +#### Returns +
+`dict[str, object] or str` +QuickConnect configuration. + +
@@ -178,6 +480,19 @@ This API is not documented yet. ### `quickconnect_permissions` +Get QuickConnect permissions. + +#### Internal API +
+`SYNO.Core.QuickConnect.Permission` +
+ +#### Returns +
+`dict[str, object] or str` +QuickConnect permissions. + +
@@ -185,6 +500,19 @@ This API is not documented yet. ### `network_topology` +Get network topology. + +#### Internal API +
+`SYNO.Core.Network.Router.Topology` +
+ +#### Returns +
+`dict[str, object] or str` +Network topology. + +
@@ -192,6 +520,19 @@ This API is not documented yet. ### `network_wifi_client` +Get WiFi client information. + +#### Internal API +
+`SYNO.Core.Network.Wifi.Client` +
+ +#### Returns +
+`dict[str, object] or str` +WiFi client information. + +
@@ -199,6 +540,19 @@ This API is not documented yet. ### `network_bond` +Get network bond information. + +#### Internal API +
+`SYNO.Core.Network.Bond` +
+ +#### Returns +
+`dict[str, object] or str` +Network bond information. + +
@@ -206,6 +560,19 @@ This API is not documented yet. ### `network_bridge` +Get network bridge information. + +#### Internal API +
+`SYNO.Core.Network.Bridge` +
+ +#### Returns +
+`dict[str, object] or str` +Network bridge information. + +
@@ -213,6 +580,19 @@ This API is not documented yet. ### `network_ethernet` +Get network ethernet information. + +#### Internal API +
+`SYNO.Core.Network.Ethernet` +
+ +#### Returns +
+`dict[str, object] or str` +Network ethernet information. + +
@@ -220,6 +600,19 @@ This API is not documented yet. ### `network_local_bridge` +Get local network bridge information. + +#### Internal API +
+`SYNO.Core.Network.LocalBridge` +
+ +#### Returns +
+`dict[str, object] or str` +Local network bridge information. + +
@@ -227,6 +620,19 @@ This API is not documented yet. ### `network_usb_modem` +Get USB modem information. + +#### Internal API +
+`SYNO.Core.Network.USBModem` +
+ +#### Returns +
+`dict[str, object] or str` +USB modem information. + +
@@ -234,6 +640,19 @@ This API is not documented yet. ### `network_pppoe` +Get PPPoE information. + +#### Internal API +
+`SYNO.Core.Network.PPPoE` +
+ +#### Returns +
+`dict[str, object] or str` +PPPoE information. + +
@@ -241,6 +660,19 @@ This API is not documented yet. ### `network_ipv6tunnel` +Get IPv6 tunnel information. + +#### Internal API +
+`SYNO.Core.Network.IPv6Tunnel` +
+ +#### Returns +
+`dict[str, object] or str` +IPv6 tunnel information. + +
@@ -248,6 +680,19 @@ This API is not documented yet. ### `network_vpn_pptp` +Get VPN PPTP information. + +#### Internal API +
+`SYNO.Core.Network.VPN.PPTP` +
+ +#### Returns +
+`dict[str, object] or str` +VPN PPTP information. + +
@@ -255,6 +700,19 @@ This API is not documented yet. ### `network_openvpn` +Get OpenVPN information. + +#### Internal API +
+`SYNO.Core.Network.VPN.OpenVPN` +
+ +#### Returns +
+`dict[str, object] or str` +OpenVPN information. + +
@@ -262,6 +720,19 @@ This API is not documented yet. ### `network_vpn_l2tp` +Get VPN L2TP information. + +#### Internal API +
+`SYNO.Core.Network.VPN.L2TP` +
+ +#### Returns +
+`dict[str, object] or str` +VPN L2TP information. + +
@@ -269,6 +740,19 @@ This API is not documented yet. ### `domain_schedule` +Get domain schedule. + +#### Internal API +
+`SYNO.Core.Directory.Domain.Schedule` +
+ +#### Returns +
+`dict[str, object] or str` +Domain schedule. + +
@@ -276,6 +760,19 @@ This API is not documented yet. ### `client_ldap` +Get LDAP client information. + +#### Internal API +
+`SYNO.Core.Directory.LDAP` +
+ +#### Returns +
+`dict[str, object] or str` +LDAP client information. + +
@@ -283,6 +780,19 @@ This API is not documented yet. ### `client_sso` +Get SSO client information. + +#### Internal API +
+`SYNO.Core.Directory.SSO` +
+ +#### Returns +
+`dict[str, object] or str` +SSO client information. + +
@@ -290,6 +800,19 @@ This API is not documented yet. ### `sys_upgrade_check` +Check for system upgrades. + +#### Internal API +
+`SYNO.Core.Upgrade.Server` +
+ +#### Returns +
+`dict[str, object] or str` +System upgrade check result. + +
@@ -297,6 +820,19 @@ This API is not documented yet. ### `sys_upgrade_download` +Get system upgrade download progress. + +#### Internal API +
+`SYNO.Core.Upgrade.Server.Download` +
+ +#### Returns +
+`dict[str, object] or str` +System upgrade download progress. + +
@@ -304,6 +840,19 @@ This API is not documented yet. ### `sys_upgrade_setting` +Get system upgrade settings. + +#### Internal API +
+`SYNO.Core.Upgrade.Setting` +
+ +#### Returns +
+`dict[str, object] or str` +System upgrade settings. + +
@@ -311,6 +860,19 @@ This API is not documented yet. ### `notification_sms_conf` +Get SMS notification configuration. + +#### Internal API +
+`SYNO.Core.Notification.SMS.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +SMS notification configuration. + +
@@ -318,6 +880,19 @@ This API is not documented yet. ### `notification_mail_conf` +Get mail notification configuration. + +#### Internal API +
+`SYNO.Core.Notification.Mail.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +Mail notification configuration. + +
@@ -325,6 +900,19 @@ This API is not documented yet. ### `notification_push_mail` +Get push mail notification configuration. + +#### Internal API +
+`SYNO.Core.Notification.Push.Mail` +
+ +#### Returns +
+`dict[str, object] or str` +Push mail notification configuration. + +
@@ -332,6 +920,19 @@ This API is not documented yet. ### `notification_push_conf` +Get push notification configuration. + +#### Internal API +
+`SYNO.Core.Notification.Push.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +Push notification configuration. + +
@@ -339,6 +940,19 @@ This API is not documented yet. ### `hardware_beep_control` +Get hardware beep control status. + +#### Internal API +
+`SYNO.Core.Hardware.BeepControl` +
+ +#### Returns +
+`dict[str, object] or str` +Hardware beep control status. + +
@@ -346,6 +960,19 @@ This API is not documented yet. ### `hardware_fan_speed` +Get hardware fan speed. + +#### Internal API +
+`SYNO.Core.Hardware.FanSpeed` +
+ +#### Returns +
+`dict[str, object] or str` +Hardware fan speed. + +
@@ -353,6 +980,26 @@ This API is not documented yet. ### `set_fan_speed` +Set hardware fan speed. + +#### Internal API +
+`SYNO.Core.Hardware.FanSpeed` +
+ +#### Parameters +
+**_fan_speed_** `str` +Fan speed mode (e.g., 'quietfan', 'coolfan', 'fullfan'). Defaults to 'quietfan'. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -360,6 +1007,26 @@ This API is not documented yet. ### `enable_zram` +Enable or disable ZRAM. + +#### Internal API +
+`SYNO.Core.Hardware.ZRAM` +
+ +#### Parameters +
+**_enable_zram_** `bool` +Enable ZRAM if True, disable if False. Defaults to True. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -367,6 +1034,29 @@ This API is not documented yet. ### `enable_power_recovery` +Enable power recovery options. + +#### Internal API +
+`SYNO.Core.Hardware.PowerRecovery` +
+ +#### Parameters +
+**_restart_auto_after_issue_** `bool` +Restart automatically after issue. Defaults to True. + +**_wake_on_lan_** `bool` +Enable Wake-on-LAN. Defaults to False. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -374,6 +1064,35 @@ This API is not documented yet. ### `enable_beep_control` +Enable or disable beep control options. + +#### Internal API +
+`SYNO.Core.Hardware.BeepControl` +
+ +#### Parameters +
+**_fan_fail_** `bool` +Enable beep on fan failure. + +**_volume_crash_** `bool` +Enable beep on volume crash. + +**_poweron_beep_** `bool` +Enable beep on power on. + +**_poweroff_beep_** `bool` +Enable beep on power off. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -381,6 +1100,26 @@ This API is not documented yet. ### `set_led_control` +Set LED brightness. + +#### Internal API +
+`SYNO.Core.Led.Brightness` +
+ +#### Parameters +
+**_led_brightness_** `int` +LED brightness level. Defaults to 2. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -388,6 +1127,29 @@ This API is not documented yet. ### `set_hibernation` +Set hibernation times. + +#### Internal API +
+`SYNO.Core.Hardware.Hibernation` +
+ +#### Parameters +
+**_internal_hd_idletime_** `int` +Idle time for internal hard drives. Defaults to 0. + +**_usb_idletime_** `int` +Idle time for USB devices. Defaults to 0. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -395,6 +1157,38 @@ This API is not documented yet. ### `enable_external_ups` +Enable or configure external UPS. + +#### Internal API +
+`SYNO.Core.ExternalDevice.UPS` +
+ +#### Parameters +
+**_enable_** `bool` +Enable external UPS. Defaults to False. + +**_mode_** `str` +UPS mode. Defaults to 'SLAVE'. + +**_delay_time_** `int` +Delay time. Defaults to 1. + +**_snmp_auth_key_dirty_** `bool` +SNMP auth key dirty flag. Defaults to False. + +**_snmp_privacy_key_dirty_** `bool` +SNMP privacy key dirty flag. Defaults to False. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -402,6 +1196,19 @@ This API is not documented yet. ### `get_system_info` +Get system information. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Returns +
+`dict[str, object] or str` +System information. + +
@@ -409,6 +1216,19 @@ This API is not documented yet. ### `get_cpu_temp` +Get CPU temperature. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Returns +
+`str` +CPU temperature. + +
@@ -416,6 +1236,19 @@ This API is not documented yet. ### `get_all_system_utilization` +Get all system utilization statistics. + +#### Internal API +
+`SYNO.Core.System.Utilization` +
+ +#### Returns +
+`str` +System utilization statistics. + +
@@ -423,6 +1256,19 @@ This API is not documented yet. ### `get_cpu_utilization` +Get CPU utilization statistics. + +#### Internal API +
+`SYNO.Core.System.Utilization` +
+ +#### Returns +
+`str` +CPU utilization statistics. + +
@@ -430,6 +1276,19 @@ This API is not documented yet. ### `get_disk_utilization` +Get disk utilization statistics. + +#### Internal API +
+`SYNO.Core.System.Utilization` +
+ +#### Returns +
+`str` +Disk utilization statistics. + +
@@ -437,6 +1296,19 @@ This API is not documented yet. ### `get_memory_utilization` +Get memory utilization statistics. + +#### Internal API +
+`SYNO.Core.System.Utilization` +
+ +#### Returns +
+`str` +Memory utilization statistics. + +
@@ -444,6 +1316,26 @@ This API is not documented yet. ### `shutdown` +Shutdown the system. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Parameters +
+**_version_** `str` +API version to use. Defaults to None. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -451,6 +1343,19 @@ This API is not documented yet. ### `reboot` +Reboot the system. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -458,6 +1363,19 @@ This API is not documented yet. ### `dsm_info` +Get DSM information. + +#### Internal API +
+`SYNO.DSM.Info` +
+ +#### Returns +
+`dict[str, object] or str` +DSM information. + +
@@ -465,6 +1383,19 @@ This API is not documented yet. ### `get_network_info` +Get network information. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Returns +
+`dict[str, object] or str` +Network information. + +
@@ -472,6 +1403,19 @@ This API is not documented yet. ### `get_volume_info` +Get volume information. + +#### Internal API +
+`SYNO.Core.System` +
+ +#### Returns +
+`dict[str, object] or str` +Volume information. + +
@@ -479,6 +1423,19 @@ This API is not documented yet. ### `hardware_hibernation` +Get hardware hibernation status. + +#### Internal API +
+`SYNO.Core.Hardware.Hibernation` +
+ +#### Returns +
+`dict[str, object] or str` +Hardware hibernation status. + +
@@ -486,13 +1443,19 @@ This API is not documented yet. ### `hardware_ups` +Get hardware UPS status. + +#### Internal API +
+`SYNO.Core.ExternalDevice.UPS` +
+ +#### Returns +
+`dict[str, object] or str` +Hardware UPS status. - - ---- - - -### `hardware_power_schedule` +
@@ -500,6 +1463,19 @@ This API is not documented yet. ### `terminal_info` +Get terminal information. + +#### Internal API +
+`SYNO.Core.Terminal` +
+ +#### Returns +
+`dict[str, object] or str` +Terminal information. + +
@@ -507,6 +1483,19 @@ This API is not documented yet. ### `snmp_info` +Get SNMP information. + +#### Internal API +
+`SYNO.Core.SNMP` +
+ +#### Returns +
+`dict[str, object] or str` +SNMP information. + +
@@ -514,6 +1503,19 @@ This API is not documented yet. ### `process` +Get system process information. + +#### Internal API +
+`SYNO.Core.System.Process` +
+ +#### Returns +
+`dict[str, object] or str` +System process information. + +
@@ -521,6 +1523,19 @@ This API is not documented yet. ### `storage` +Get storage information. + +#### Internal API +
+`SYNO.Storage.CGI.Storage` +
+ +#### Returns +
+`dict[str, object] or str` +Storage information. + +
@@ -528,6 +1543,19 @@ This API is not documented yet. ### `external_device_storage_usb` +Get USB storage device information. + +#### Internal API +
+`SYNO.Core.ExternalDevice.Storage.USB` +
+ +#### Returns +
+`dict[str, object] or str` +USB storage device information. + +
@@ -535,6 +1563,19 @@ This API is not documented yet. ### `external_device_storage_esata` +Get eSATA storage device information. + +#### Internal API +
+`SYNO.Core.ExternalDevice.Storage.eSATA` +
+ +#### Returns +
+`dict[str, object] or str` +eSATA storage device information. + +
@@ -542,6 +1583,19 @@ This API is not documented yet. ### `file_index_resource` +Get file indexing status. + +#### Internal API +
+`SYNO.Finder.FileIndexing.Status` +
+ +#### Returns +
+`dict[str, object] or str` +File indexing status. + +
@@ -549,6 +1603,19 @@ This API is not documented yet. ### `cms_info` +Get CMS information. + +#### Internal API +
+`SYNO.Core.CMS.Info` +
+ +#### Returns +
+`dict[str, object] or str` +CMS information. + +
@@ -556,6 +1623,19 @@ This API is not documented yet. ### `port_forwarding_rules` +Get port forwarding rules. + +#### Internal API +
+`SYNO.Core.PortForwarding.Rules` +
+ +#### Returns +
+`dict[str, object] or str` +Port forwarding rules. + +
@@ -563,6 +1643,19 @@ This API is not documented yet. ### `port_forwarding_router_conf` +Get port forwarding router configuration. + +#### Internal API +
+`SYNO.Core.PortForwarding.RouterConf` +
+ +#### Returns +
+`dict[str, object] or str` +Port forwarding router configuration. + +
@@ -570,6 +1663,19 @@ This API is not documented yet. ### `disk_list` +Get disk list. + +#### Internal API +
+`SYNO.Core.Polling.Data` +
+ +#### Returns +
+`dict[str, object] or str` +Disk list. + +
@@ -577,6 +1683,19 @@ This API is not documented yet. ### `ddns_provider_info` +Get DDNS provider information. + +#### Internal API +
+`SYNO.Core.DDNS.Provider` +
+ +#### Returns +
+`dict[str, object] or str` +DDNS provider information. + +
@@ -584,6 +1703,19 @@ This API is not documented yet. ### `ddns_record_info` +Get DDNS record information. + +#### Internal API +
+`SYNO.Core.DDNS.Record` +
+ +#### Returns +
+`dict[str, object] or str` +DDNS record information. + +
@@ -591,6 +1723,19 @@ This API is not documented yet. ### `ddns_external_ip` +Get DDNS external IP. + +#### Internal API +
+`SYNO.Core.DDNS.ExtIP` +
+ +#### Returns +
+`dict[str, object] or str` +DDNS external IP. + +
@@ -598,6 +1743,19 @@ This API is not documented yet. ### `ddns_synology` +Get Synology DDNS information. + +#### Internal API +
+`SYNO.Core.DDNS.Synology` +
+ +#### Returns +
+`dict[str, object] or str` +Synology DDNS information. + +
@@ -605,6 +1763,19 @@ This API is not documented yet. ### `iscsi_lun_info` +Get iSCSI LUN information. + +#### Internal API +
+`SYNO.Core.ISCSI.LUN` +
+ +#### Returns +
+`dict[str, object] or str` +iSCSI LUN information. + +
@@ -612,6 +1783,19 @@ This API is not documented yet. ### `hddman` +Get HDD manager information. + +#### Internal API +
+`SYNO.Storage.CGI.HddMan` +
+ +#### Returns +
+`dict[str, object] or str` +HDD manager information. + +
@@ -619,6 +1803,19 @@ This API is not documented yet. ### `ftp_security_info` +Get FTP security information. + +#### Internal API +
+`SYNO.Core.FileServ.FTP.Security` +
+ +#### Returns +
+`dict[str, object] or str` +FTP security information. + +
@@ -626,6 +1823,19 @@ This API is not documented yet. ### `bandwidth_control_info` +Get bandwidth control information. + +#### Internal API +
+`SYNO.Core.BandwidthControl.Protocol` +
+ +#### Returns +
+`dict[str, object] or str` +Bandwidth control information. + +
@@ -633,6 +1843,19 @@ This API is not documented yet. ### `directory_domain_info` +Get directory domain information. + +#### Internal API +
+`SYNO.Core.Directory.Domain` +
+ +#### Returns +
+`dict[str, object] or str` +Directory domain information. + +
@@ -640,6 +1863,19 @@ This API is not documented yet. ### `ws_transfer_info` +Get WS transfer information. + +#### Internal API +
+`SYNO.Core.FileServ.ServiceDiscovery.WSTransfer` +
+ +#### Returns +
+`dict[str, object] or str` +WS transfer information. + +
@@ -647,6 +1883,19 @@ This API is not documented yet. ### `ref_link_copy_info` +Get reflink copy information. + +#### Internal API +
+`SYNO.Core.FileServ.ReflinkCopy` +
+ +#### Returns +
+`dict[str, object] or str` +Reflink copy information. + +
@@ -654,6 +1903,19 @@ This API is not documented yet. ### `bonjour_service_info` +Get Bonjour service information. + +#### Internal API +
+`SYNO.Core.ExternalDevice.Printer.BonjourSharing` +
+ +#### Returns +
+`dict[str, object] or str` +Bonjour service information. + +
@@ -661,6 +1923,19 @@ This API is not documented yet. ### `personal_photo_enable` +Get personal photo enable status. + +#### Internal API +
+`SYNO.Core.User.Home` +
+ +#### Returns +
+`dict[str, object] or str` +Personal photo enable status. + +
@@ -668,6 +1943,19 @@ This API is not documented yet. ### `ftp_chroot_user` +Get FTP chroot user information. + +#### Internal API +
+`SYNO.Core.FileServ.FTP.ChrootUser` +
+ +#### Returns +
+`dict[str, object] or str` +FTP chroot user information. + +
@@ -675,6 +1963,19 @@ This API is not documented yet. ### `server_pair` +Get server pair information. + +#### Internal API +
+`SYNO.S2S.Server.Pair` +
+ +#### Returns +
+`dict[str, object] or str` +Server pair information. + +
@@ -682,6 +1983,32 @@ This API is not documented yet. ### `groups_info` +Get groups information. + +#### Internal API +
+`SYNO.Core.Group` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination. Defaults to 0. + +**_limit_** `int` +Maximum number of groups to retrieve. Defaults to -1. + +**_name_only_** `bool` +If True, returns only group names. Defaults to False. + + +
+#### Returns +
+`dict[str, object] or str` +Groups information. + +
@@ -689,6 +2016,19 @@ This API is not documented yet. ### `ldap_info` +Get LDAP information. + +#### Internal API +
+`SYNO.Core.Directory.LDAP` +
+ +#### Returns +
+`dict[str, object] or str` +LDAP information. + +
@@ -696,6 +2036,19 @@ This API is not documented yet. ### `sso_iwa_info` +Get SSO IWA information. + +#### Internal API +
+`SYNO.Core.Directory.SSO.IWA` +
+ +#### Returns +
+`dict[str, object] or str` +SSO IWA information. + +
@@ -703,6 +2056,19 @@ This API is not documented yet. ### `sso_info` +Get SSO information. + +#### Internal API +
+`SYNO.Core.Directory.SSO` +
+ +#### Returns +
+`dict[str, object] or str` +SSO information. + +
@@ -710,6 +2076,19 @@ This API is not documented yet. ### `network_interface_info` +Get network interface information. + +#### Internal API +
+`SYNO.Core.Network.Interface` +
+ +#### Returns +
+`dict[str, object] or str` +Network interface information. + +
@@ -717,6 +2096,19 @@ This API is not documented yet. ### `proxy_info` +Get proxy information. + +#### Internal API +
+`SYNO.Core.Network.Proxy` +
+ +#### Returns +
+`dict[str, object] or str` +Proxy information. + +
@@ -724,6 +2116,29 @@ This API is not documented yet. ### `gateway_list` +Get gateway list. + +#### Internal API +
+`SYNO.Core.Network.Router.Gateway.List` +
+ +#### Parameters +
+**_ip_type_** `str` +IP type (e.g., 'ipv4', 'ipv6'). Defaults to 'ipv4'. + +**_type_** `str` +Gateway type (e.g., 'wan'). Defaults to 'wan'. + + +
+#### Returns +
+`dict[str, object] or str` +Gateway list. + +
@@ -731,6 +2146,19 @@ This API is not documented yet. ### `firewall_info` +Get firewall information. + +#### Internal API +
+`SYNO.Core.Security.Firewall.Profile` +
+ +#### Returns +
+`dict[str, object] or str` +Firewall information. + +
@@ -738,6 +2166,19 @@ This API is not documented yet. ### `auto_upgrade_status` +Get auto upgrade status. + +#### Internal API +
+`SYNO.Core.Upgrade.AutoUpgrade` +
+ +#### Returns +
+`dict[str, object] or str` +Auto upgrade status. + +
@@ -745,6 +2186,19 @@ This API is not documented yet. ### `upgrade_server_check` +Check upgrade server. + +#### Internal API +
+`SYNO.Core.Upgrade.Server` +
+ +#### Returns +
+`dict[str, object] or str` +Upgrade server check result. + +
@@ -752,6 +2206,19 @@ This API is not documented yet. ### `alarm_rules_logs` +Get alarm rules logs. + +#### Internal API +
+`SYNO.ResourceMonitor.Log` +
+ +#### Returns +
+`dict[str, object] or str` +Alarm rules logs. + +
@@ -759,6 +2226,19 @@ This API is not documented yet. ### `alarm_rules_list` +Get alarm rules list. + +#### Internal API +
+`SYNO.ResourceMonitor.EventRule` +
+ +#### Returns +
+`dict[str, object] or str` +Alarm rules list. + +
@@ -766,6 +2246,19 @@ This API is not documented yet. ### `resource_monitor_settings_list` +Get resource monitor settings. + +#### Internal API +
+`SYNO.ResourceMonitor.Setting` +
+ +#### Returns +
+`dict[str, object] or str` +Resource monitor settings. + +
@@ -773,6 +2266,35 @@ This API is not documented yet. ### `file_handling_access` +Get file handling access information. + +#### Internal API +
+`SYNO.Core.FileHandle` +
+ +#### Parameters +
+**_sort_direction_** `str` +Sort direction ('ASC' or 'DESC'). Defaults to 'ASC'. + +**_sort_by_** `str` +Field to sort by. Defaults to 'service'. + +**_limit_** `int` +Maximum number of results. Defaults to 50. + +**_offset_** `int` +Offset for pagination. Defaults to 0. + + +
+#### Returns +
+`dict[str, object] or str` +File handling access information. + +
@@ -780,6 +2302,26 @@ This API is not documented yet. ### `list_service_group` +Get service group list. + +#### Internal API +
+`SYNO.Core.System.ProcessGroup` +
+ +#### Parameters +
+**_interval_** `int` +Interval for statistics. Defaults to 0. + + +
+#### Returns +
+`dict[str, object] or str` +Service group list. + +
@@ -787,6 +2329,19 @@ This API is not documented yet. ### `list_process_group` +Get process group list. + +#### Internal API +
+`SYNO.Core.System.Process` +
+ +#### Returns +
+`dict[str, object] or str` +Process group list. + +
@@ -794,6 +2349,19 @@ This API is not documented yet. ### `installed_package_list` +Get installed package list. + +#### Internal API +
+`SYNO.Core.Package` +
+ +#### Returns +
+`dict[str, object] or str` +Installed package list. + +
@@ -801,6 +2369,19 @@ This API is not documented yet. ### `active_notifications` +Get active notifications. + +#### Internal API +
+`SYNO.Core.DSMNotify` +
+ +#### Returns +
+`dict[str, object] or str` +Active notifications. + +
@@ -808,6 +2389,19 @@ This API is not documented yet. ### `get_system_health` +Get system health information. + +#### Internal API +
+`SYNO.Core.System.SystemHealth` +
+ +#### Returns +
+`dict[str, object] or str` +System health information. + +
@@ -815,6 +2409,19 @@ This API is not documented yet. ### `upgrade_status` +Get upgrade status. + +#### Internal API +
+`SYNO.Core.Upgrade` +
+ +#### Returns +
+`dict[str, object] or str` +Upgrade status. + +
diff --git a/documentation/docs/apis/classes/core_user.md b/documentation/docs/apis/classes/core_user.md index 1922e6e3..ac981626 100644 --- a/documentation/docs/apis/classes/core_user.md +++ b/documentation/docs/apis/classes/core_user.md @@ -11,20 +11,38 @@ title: ✅ User ## Overview Core User API implementation. -Supported actions: - - **Getters** : - - Get all users - - Password policies - - Password expiry - - - **Setters** : - - Set user password policy - - - **Actions** : - - Create new user - - Modify user - - Delete user - - User join/leave group +Methods +------- +get_users(offset=0, limit=-1, sort_by="name", sort_direction="ASC", additional=[]) + Retrieve groups information. +get_user(name, additional=[]) + Retrieve user information. +create_user(...) + Create a new user. +modify_user(...) + Modify a user. +delete_user(name) + Delete a user. +affect_groups(name, join_groups=[], leave_groups=[]) + Affect or disaffect groups to a user. +affect_groups_status(task_id) + Get the status of a join task. +get_password_policy() + Get the password policy. +set_password_policy(...) + Set the password policy. +get_password_expiry() + Get the password expiry. +set_password_expiry(...) + Set the password expiry. +password_confirm(password) + Confirm password/session. +get_username_policy() + Get the username policy. + +Examples +-------- +See individual method docstrings for usage examples. ## Methods ### `get_users` Retrieve groups information. @@ -40,7 +58,7 @@ Retrieve groups information. The offset of the groups to retrieve. Defaults to `0`. **_limit_** `int` -The maximum number of groups to retrieve. Defaults to `-1` . +The maximum number of groups to retrieve. Defaults to `-1`. **_sort_by_** `str` Sort by a specific field. Defaults to `"name"`. @@ -49,7 +67,7 @@ Sort by a specific field. Defaults to `"name"`. The sort direction. Defaults to `"ASC"` else `"DESC"`. **_additional_** `list[str]` -Additional fields to retrieve. Defaults to `[]`. +Additional fields to retrieve. Defaults to `[]`. All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change", "groups", "2fa_status"]`. @@ -110,7 +128,7 @@ A dictionary containing the groups information. ### `get_user` -Retrieve a user information. +Retrieve user information. #### Internal API
@@ -123,7 +141,7 @@ Retrieve a user information. The name of the user. **_additional_** `list[str]` -Additional fields to retrieve. Defaults to `[]`. +Additional fields to retrieve. Defaults to `[]`. All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change","is_password_pending"]`. @@ -216,7 +234,7 @@ A dictionary containing the user information.
Click to expand ```json -{ +{ "data": { "name":"toto", @@ -503,34 +521,34 @@ Set the password policy. #### Parameters
-**_enable_reset_passwd_by_email_** `bool, optional ` +**_enable_reset_passwd_by_email_** `bool` Defaults to `False`. -**_password_must_change_** `bool, optional ` +**_password_must_change_** `bool` Defaults to `False`. -**_exclude_username_** `bool, optional ` +**_exclude_username_** `bool` Defaults to `True`. -**_included_numeric_char_** `bool, optional ` +**_included_numeric_char_** `bool` Defaults to `True`. -**_included_special_char_** `bool, optional ` +**_included_special_char_** `bool` Defaults to `False`. -**_min_length_** `int, optional ` +**_min_length_** `int` Defaults to `8`. -**_min_length_enable_** `bool, optional ` +**_min_length_enable_** `bool` Defaults to `True`. -**_mixed_case_** `bool, optional ` +**_mixed_case_** `bool` Defaults to `True`. -**_exclude_common_password_** `bool, optional ` +**_exclude_common_password_** `bool` Defaults to `False`. -**_exclude_history_** `bool, optional ` +**_exclude_history_** `bool` Defaults to `False`. @@ -664,7 +682,7 @@ A dictionary indicating the success of the operation. ### `password_confirm` -Issues a passowrd/session comparison to ensure the given password matches the auth of the current session. +Confirm password/session to ensure the given password matches the auth of the current session. :::note This is needed by some APIs as a confirmation method, for example, when creating/modifying a scheduled task with root permissions, seldom needed by end users. @@ -708,7 +726,7 @@ A dictionary containing a `SynoConfirmPWToken`, or an error message. ### `get_username_policy` -Get the username policy (List of username that are not usable). +Get the username policy (list of usernames that are not usable). #### Internal API
diff --git a/documentation/docs/apis/classes/dhcp_server.md b/documentation/docs/apis/classes/dhcp_server.md index e1d56493..500b3f27 100644 --- a/documentation/docs/apis/classes/dhcp_server.md +++ b/documentation/docs/apis/classes/dhcp_server.md @@ -14,9 +14,32 @@ This API is not documented yet. ::: ## Overview +Core DHCP Server API implementation for Synology NAS. +This class provides methods to retrieve and manage DHCP server, PXE, TFTP, and network +interface information. ## Methods ### `general_info` +Get general DHCP server information for a given interface. + +#### Internal API +
+`SYNO.Network.DHCPServer` +
+ +#### Parameters +
+**_ifname_** `str` +Interface name. Defaults to 'ovs_eth0'. + + +
+#### Returns +
+`dict[str, object] or str` +General DHCP server information. + +
@@ -24,6 +47,19 @@ This API is not documented yet. ### `vendor` +Get DHCP vendor information. + +#### Internal API +
+`SYNO.Network.DHCPServer.Vendor` +
+ +#### Returns +
+`dict[str, object] or str` +DHCP vendor information. + +
@@ -31,6 +67,19 @@ This API is not documented yet. ### `pxe` +Get PXE server information. + +#### Internal API +
+`SYNO.Network.DHCPServer.PXE` +
+ +#### Returns +
+`dict[str, object] or str` +PXE server information. + +
@@ -38,6 +87,19 @@ This API is not documented yet. ### `tftp` +Get TFTP server information. + +#### Internal API +
+`SYNO.Core.TFTP` +
+ +#### Returns +
+`dict[str, object] or str` +TFTP server information. + +
@@ -45,6 +107,19 @@ This API is not documented yet. ### `network_bond` +Get network bond interface information. + +#### Internal API +
+`SYNO.Core.Network.Bond` +
+ +#### Returns +
+`dict[str, object] or str` +Network bond interface information. + +
@@ -52,6 +127,19 @@ This API is not documented yet. ### `network_ethernet` +Get network ethernet interface information. + +#### Internal API +
+`SYNO.Core.Network.Ethernet` +
+ +#### Returns +
+`dict[str, object] or str` +Network ethernet interface information. + +
@@ -59,6 +147,26 @@ This API is not documented yet. ### `dhcp_clientlist` +Get DHCP client list for a given interface. + +#### Internal API +
+`SYNO.Network.DHCPServer.ClientList` +
+ +#### Parameters +
+**_ifname_** `str` +Interface name. Defaults to 'bond0'. + + +
+#### Returns +
+`dict[str, object] or str` +DHCP client list. + +
@@ -66,6 +174,26 @@ This API is not documented yet. ### `dhcp_reservations` +Get DHCP reservations for a given interface. + +#### Internal API +
+`SYNO.Network.DHCPServer.Reservation` +
+ +#### Parameters +
+**_ifname_** `str` +Interface name. Defaults to 'bond0'. + + +
+#### Returns +
+`dict[str, object] or str` +DHCP reservations. + +
diff --git a/documentation/docs/apis/classes/directory_server.md b/documentation/docs/apis/classes/directory_server.md index 0e99724f..db8d690c 100644 --- a/documentation/docs/apis/classes/directory_server.md +++ b/documentation/docs/apis/classes/directory_server.md @@ -11,14 +11,15 @@ title: ✅ DirectoryServer ## Overview The directory server API. -Not all items within this class use the Active Directory API. Some use the Synology Entry API which proxies -the request. Some are related to managing users in ways that are useful in the Directory Server context. For +Not all items within this class use the Active Directory API. Some use the Synology Entry API which proxies +the request. Some are related to managing users in ways that are useful in the Directory Server context. For example, sending a user password reset email, or updating the user information. This api works slightly differently than other similar APIs. There are multi-leveled calls where Synology makes requests on behalf of the original request and relays information back. Additionally, the query-string api item is not used often in this class as API is defined within the actual request. The APIs in this class are tested working against the following scenarios: + - **Getters** : - Get Active Directory information - List objects within a Base DN on the Active Directory Server @@ -38,7 +39,7 @@ The APIs in this class are tested working against the following scenarios: - Perform an entry request to complete a Deletion ## Methods ### `get_directory_info` -Gets directory info. +Get directory info. #### Internal API
@@ -90,7 +91,7 @@ Information about your domain. ### `list_directory_objects` -lists directory objects. +List directory objects. #### Internal API
@@ -100,29 +101,26 @@ lists directory objects. #### Parameters
**_basedn_** `str` -The Base DN for the search. eg. `CN=Users,CN=MY,CN=DOMAIN,CN=COM" or CN=MY,CN=DOMAIN,CN=COM` +The Base DN for the search. E.g. `CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=MY,CN=DOMAIN,CN=COM`. **_offset_** `int` When searching large data, you may wish to start at a certain number, e.g. for 10 at a time one -would set the limit to 10 and the offset by multiples of 10 for each request. -Defaults to `0` +would set the limit to 10 and the offset by multiples of 10 for each request. Defaults to `0`. **_limit_** `int` -The numeric the number of maximum objects to return. -Defaults to `40` +The number of maximum objects to return. Defaults to `40`. -**_objectCategory_** `optional, list[str]` -The categories of items to search. e.g. `["organizationalUnit","container","builtinDomain"]` for a list of +**_objectCategory_** `list[str]` +The categories of items to search. E.g. `["organizationalUnit","container","builtinDomain"]` for a list of base server containers, and `["person","group","organizationalUnit","computer"]` for a list of contained objects. -Defaults to `["person","group","organizationalUnit","computer","container","builtinDomain"]` +Defaults to `["person","group","organizationalUnit","computer","container","builtinDomain"]`.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -167,19 +165,8 @@ Since this is a compound request, the data contains an object with it's own requ ### `create_new_user` -Create a new user. -:::note - - The user can be created in AD, but not able to log on until the next synchronization occurs. - -::: - -:::note - - Please note that synchronization with Synology is a separate step. - -::: - +Create a new user. + #### Internal API
`SYNO.ActiveDirectory.User` @@ -188,41 +175,38 @@ Create a new user. #### Parameters
**_logon_name_** `str` -The desired username. E.g `jdoe`. +The desired username. E.g. `jdoe`. **_email_** `str` The desired email. **_password_** `str` -The plain-text password for the new user. E.g `Password123`. +The plain-text password for the new user. E.g. `Password123`. **_located_dn_** `str` -The DN for the user. E.g `CN=Users,CN=MY,CN=DOMAIN,CN=COM`. +The DN for the user. E.g. `CN=Users,CN=MY,CN=DOMAIN,CN=COM`. **_description_** `str` A description for the user. **_account_is_disabled_** `str` -Set to 'true' if the account should be disabled Defaults to `False`. +Set to 'true' if the account should be disabled. Defaults to `False`. **_cannot_change_password_** `str` -Set to 'true' if the user cannot change the password Defaults to `False`. +Set to 'true' if the user cannot change the password. Defaults to `False`. **_change_password_next_logon_** `str` -Set to 'true' if the user must change password on next logon Defaults to `False`. - -**_cannot_change_password_** `str` -Set to 'true' if the user cannot change the password Defaults to `False`. +Set to 'true' if the user must change password on next logon. Defaults to `False`. **_password_never_expire_** `str` -Pwd Never Expire +Set to 'true' if the password never expires.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. The data dictionary contains an 'error', or it contains a 'dn' and a 'name'. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary.
#### Example return @@ -231,9 +215,9 @@ The result of this method is a dictionary object with a 'data' dictionary and a ```json { 'data': { - 'dn': 'CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM', + 'dn': 'CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM', 'name': 'NETBIOSNAME\ababab' - }, + }, 'success': true } ``` @@ -247,13 +231,7 @@ The result of this method is a dictionary object with a 'data' dictionary and a ### `reset_password` Send a password reset email. This will trigger the password reset email from -Control Panel>Notification>Rules>System>Reset password for your account to be sent to the user. -:::info - - In order to use this, Control Panel>User & Group>Advanced>"Allow non-administrator users to reset forgotten passwords via email" must be enabled. - -::: - +Control Panel>Notification>Rules>System>Reset password for your account to be sent to the user. #### Internal API
`SYNO.Auth.ForgotPwd` @@ -262,7 +240,7 @@ Control Panel>Notification>Rules>System>Reset password for your account to be se #### Parameters
**_username_** `str` -The username to reset. E.g. `My Group` +The username to reset. E.g. `My Group`.
@@ -279,7 +257,7 @@ The return object can be checked for the "success" to be a true or false. { "data": { "msg": 3 - }, + }, "success": true } ``` @@ -291,13 +269,8 @@ The return object can be checked for the "success" to be a true or false. ### `change_user_password` -Change the user's password. -:::info - - This is a compound dual-level request where the synology API proxies your request to the Directory Server. - -::: - +Change the user's password. + #### Internal API
`SYNO.Entry.Request` @@ -306,10 +279,10 @@ Change the user's password. #### Parameters
**_user_dn_** `str` -The user DN to be modified. eg. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM` +The user DN to be modified. E.g. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM`. **_password_** `str` -The new password to be set. e.g. `Password123` +The new password to be set. E.g. `Password123`.
@@ -317,8 +290,6 @@ The new password to be set. e.g. `Password123`
`dict[str, object]` The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. -Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
#### Example return @@ -364,52 +335,48 @@ Create a new AD group. #### Parameters
**_name_** `str` -The name of the group. E.g. `My Group` +The name of the group. E.g. `My Group`. **_located_dn_** `str` -The DN to place the group in. eg. `CN=Groups,DC=MY,DC=DOMAIN,DC=COM` +The DN to place the group in. E.g. `CN=Groups,DC=MY,DC=DOMAIN,DC=COM`. **_email_** `str` -The email address used to reference this group. -Defaults to `""` +The email address used to reference this group. Defaults to `""`. **_description_** `str` -A description of the AD Group. -Defaults to `""` +A description of the AD Group. Defaults to `""`. **_type_** `str` -Example Options: `security`, `distribution` +Example Options: `security`, `distribution`. Defaults to `"security"`. (definitions from https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/compare-groups?view=o365-worldwide ) - `distribution` (Distribution groups) are used for sending email - notifications to a group of people. + notifications to a group of people. - `security` - Security groups are used for granting access to resources - such as SharePoint sites. -Defaults to `"security"` + such as SharePoint sites. **_scope_** `str` -Example Options : `local`, `global`, `universal` -(Definitions from -https://www.netwrix.com/active_directory_group_management.html ) - - `local` (Domain Local Groups) should be used to manage permissions to - resources because this group can be applied everywhere in the domain. - A domain local group can include members of any type in the domain and - members from trusted domains. For example, suppose you need access - management for a collection of folders on one or more servers that - contain information for managers. The group you create for that purpose - should be a domain local group (ex. “DL_Managers_Modify”). - - `global` (Global Groups) are used primarily to define collections of - domain objects (users, other global groups and computers) based on - business roles, which means that they mostly serve as role groups. - Role-based groups of users (such as “HR” or “Marketing”) and role-based - groups of computers (such as a “Marketing Workstations”) areusually - global groups. - - `universal` (Universal Groups) in Active Directory are useful in - multi-domain forests. They enable you to define roles or manage - resources that span more than one domain. Each universal group is - stored in the domain of where it was created, but its group membership - is stored in the Global Catalog and replicated forest-wide. Don’t use - universal groups if you have only one domain. -Defaults to `"global"` +Example Options: `local`, `global`, `universal`. Defaults to `"global"`. + (Definitions from + https://www.netwrix.com/active_directory_group_management.html ) + - `local` (Domain Local Groups) should be used to manage permissions to + resources because this group can be applied everywhere in the domain. + A domain local group can include members of any type in the domain and + members from trusted domains. For example, suppose you need access + management for a collection of folders on one or more servers that + contain information for managers. The group you create for that purpose + should be a domain local group (ex. “DL_Managers_Modify”). + - `global` (Global Groups) are used primarily to define collections of + domain objects (users, other global groups and computers) based on + business roles, which means that they mostly serve as role groups. + Role-based groups of users (such as “HR” or “Marketing”) and role-based + groups of computers (such as a “Marketing Workstations”) areusually + global groups. + - `universal` (Universal Groups) in Active Directory are useful in + multi-domain forests. They enable you to define roles or manage + resources that span more than one domain. Each universal group is + stored in the domain of where it was created, but its group membership + is stored in the Global Catalog and replicated forest-wide. Don’t use + universal groups if you have only one domain.
@@ -425,9 +392,9 @@ A success object, and data object containing the new dn and the netbios name of ```json { 'data': { - 'dn': 'CN=My Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM', + 'dn': 'CN=My Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM', 'name': 'NETBIOSNAME\My Group' - }, + }, 'success': true } ``` @@ -439,7 +406,7 @@ A success object, and data object containing the new dn and the netbios name of ### `add_user_to_group` -Adds a user as a member of a group. +Add a user as a member of a group. #### Internal API
@@ -449,18 +416,18 @@ Adds a user as a member of a group. #### Parameters
**_userDn_** `str` -The fully qualified dn to add. eg. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` +The fully qualified dn to add. E.g. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM`. **_groupDn_** `str` -the fully qualified dn of the group to which the user is to be added. e.g. `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM` +The fully qualified dn of the group to which the user is to be added. E.g. `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM`.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. +The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -496,13 +463,8 @@ Since this is a compound request, the data contains an object with it's own requ ### `does_dn_exist` -Checks if a container exists. This can be used to verifiy the username or group name is unique. -:::info - - This will not check the container, only if a similarly named container already exists. - -::: - +Check if a container exists. +This can be used to verify the username or group name is unique. #### Internal API
`SYNO.ActiveDirectory.Group` @@ -511,16 +473,16 @@ Checks if a container exists. This can be used to verifiy the username or group #### Parameters
**_groupName_** `str` -The user, or group's name. e.g. `jdoe` or `My Cool Group` -Fully Qualified Domain Name such as `CN=My Cool Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM` are not successful. -Improper case such as `my cool group` instead of `My Cool Group` are successful +The user, or group's name. E.g. `jdoe` or `My Cool Group`. +Fully Qualified Domain Name such as `CN=My Cool Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM` are not successful. +Improper case such as `my cool group` instead of `My Cool Group` are successful.
#### Returns
`dict[str, object]` -`True` if the group exists. `False` if the group does not exist +`True` if the group exists. `False` if the group does not exist.
@@ -530,7 +492,7 @@ Improper case such as `my cool group` instead of `My Cool Group` are successful ### `modify_user_info` -Performs modification to user information within the Active Directory. +Modify user information within the Active Directory. #### Internal API
@@ -540,25 +502,25 @@ Performs modification to user information within the Active Directory. #### Parameters
**_user_dn_** `str` -The user DN to be modified. eg. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM` +The user DN to be modified. E.g. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM`. **_firstName_** `str` -The First name of the user. e.g. `John` +The First name of the user. E.g. `John`. **_lastName_** `str` -The Last Name of the user. e.g. `Doe` +The Last Name of the user. E.g. `Doe`. **_displayName_** `str` -The Display name of the user. e.g. `John Doe` +The Display name of the user. E.g. `John Doe`. **_description_** `str` -The Descrition of the user. e.g. `The guy who just came in` +The Description of the user. E.g. `The guy who just came in`. **_initials_** `str` -The Initials of the user. e.g. `JD` +The Initials of the user. E.g. `JD`. **_physicalDeliveryOfficeName_** `str` -The office location in the user's place of business +The office location in the user's place of business. **_telephoneNumber_** `str` The user's telephone number. @@ -571,8 +533,8 @@ The user's website or location on the web where information can be obtained. #### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. +The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -612,7 +574,7 @@ Since this is a compound request, the data contains an object with it's own requ ### `setEntryRequest` -Performs modification to an object within the Active Directory. +Modify an object within the Active Directory. #### Internal API
@@ -622,24 +584,24 @@ Performs modification to an object within the Active Directory. #### Parameters
**_modificationAPI_** `str` -API to be used +API to be used. **_method_** `str` -Method to be called +Method to be called. **_nameOfObject_** `str` -The user DN to be modified. eg. `"CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM"` +The user DN to be modified. E.g. `"CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM"`. **_jsonObject_** `str` -The json Object to be added, eg, a user object where the +The json Object to be added, e.g., a user object.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. +The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -679,8 +641,8 @@ Since this is a compound request, the data contains an object with it's own requ ### `update_domain_records` -Updates the Synology users and groups database with information from Directory Server. -This is a long-running and asynchronous task. You are given back a task_id, and you can use that task_id to check the status with the get_task_status(task_id) method. +Update the Synology users and groups database with information from Directory Server. +This is a long-running and asynchronous task. You are given back a task_id, and you can use that task_id to check the status with the get_task_status(task_id) method. #### Internal API
`SYNO.Core.Directory.Domain` @@ -690,18 +652,19 @@ This is a long-running and asynchronous task. You are given back a task_id, and
`dict[str, object]` The 'data' object contains the 'task_id' used to track with the getTaskStatus() method. -The 'success' object will be true if the operation was successful. or false if failed.
#### Example return
Click to expand -```python - updateResponse=directory.updateDomain() - status = directory.getTaskStatus(updateResponse['data']['task_id']) - while status['data']['status'] == 'updating': - status=directory.getTaskStatus(updateResponse['data']['task_id']) - ``` +```json +{ + "data": { + "task_id": "@administrators/DomainUpdate6146195136397F2" + }, + "success": true +} +```
@@ -710,8 +673,8 @@ The 'success' object will be true if the operation was successful. or false if f ### `get_task_status` -Gets the current status of a task running on the Directory Domain object. -This is used to ensure the task is completed. For example, the primary utilization of this is when updating Synology's internal Domain user and group list. +Get the current status of a task running on the Directory Domain object. +This is used to ensure the task is completed. For example, the primary utilization of this is when updating Synology's internal Domain user and group list. Until this method reports finish, the job is not completed, and it is not safe to operate under the assumption that users have been synchronized. #### Internal API
@@ -729,8 +692,7 @@ The task ID to be tracked for status.
`dict[str, object]` The 'data' object contains the 'status' used to determine the current status. 'status' will be 'updating' or 'finish' if the job was started. -T -The 'success' object will be true if the operation was successful. or false if failed. +The 'success' object will be true if the operation was successful, or false if failed.
#### Example return @@ -740,7 +702,7 @@ The 'success' object will be true if the operation was successful. or false if f { 'data': { 'status': 'updating' - }, + }, 'success': true } ``` @@ -752,7 +714,7 @@ The 'success' object will be true if the operation was successful. or false if f ### `deleteItems` -Deletes an array of DNs from AD. +Delete an array of DNs from AD. #### Internal API
@@ -762,16 +724,15 @@ Deletes an array of DNs from AD. #### Parameters
**_dnList_** `list[str]` -The fully qualified DN to be removed from the directory server. -eg. `["CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM","CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM"]` +The fully qualified DN to be removed from the directory server. E.g. `["CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM","CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM"]`.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. +The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -812,7 +773,7 @@ Since this is a compound request, the data contains an object with it's own requ ### `delete_item` -Deletes a DN from AD. +Delete a DN from AD. #### Internal API
@@ -822,16 +783,15 @@ Deletes a DN from AD. #### Parameters
**_dn_** `str` -The fully qualified DN to be removed from the directory server. -eg. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM` +The fully qualified DN to be removed from the directory server. E.g. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM`.
#### Returns
`dict[str, object]` -The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. -The first level is the success to the AD server. The second Data level is the status of the actual request. +The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. +The first level is the success to the AD server. The second Data level is the status of the actual request. Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request.
@@ -872,8 +832,8 @@ Since this is a compound request, the data contains an object with it's own requ ### `entryRequest` -Some requests require an entry. -Delete for example requires an entry. If an entry is required, the task will not complete without an Entry Request. +Perform an entry request for a task. +Some requests require an entry. Delete, for example, requires an entry. If an entry is required, the task will not complete without an Entry Request. #### Internal API
`SYNO.Entry.Request` @@ -882,11 +842,17 @@ Delete for example requires an entry. If an entry is required, the task will no #### Parameters
**_task_id_** `str` -The ID of the task to be checked. This is provided when making a request. +The ID of the task to be checked. This is provided when making a request. An example Task ID may look like this -`@administrators/Synoads_SYNO.ActiveDirectory.Directory_delete6145EA17C4F03DA9` + `@administrators/Synoads_SYNO.ActiveDirectory.Directory_delete6145EA17C4F03DA9`. +
+#### Returns +
+`Any` +The result of the entry request. +
diff --git a/documentation/docs/apis/classes/docker_api.md b/documentation/docs/apis/classes/docker_api.md index 504704df..1d0ac1f9 100644 --- a/documentation/docs/apis/classes/docker_api.md +++ b/documentation/docs/apis/classes/docker_api.md @@ -11,27 +11,26 @@ title: ✅ Docker ## Overview Docker API implementation. -This class provides methods to interact with Docker containers, images, registries, and projects on a Synology NAS. - -Supported actions: - - **Getters** : - - Get list of containers - - Get resources of all containers - - Get system resources - - List of docker images - - Get list of docker registries - - Get list of container logs - - Get containers resource usage statistics - - Search for docker image in all available registries - - Get list of projects - - Get list of docker networks - - - **Setters** : - - - - - **Actions** : - - Export container profile - - Export container profile and content + This class provides methods to interact with Docker containers, images, registries, and projects on a Synology NAS. + + Supported actions: + - **Getters** : + - Get list of containers + - Get resources of all containers + - Get system resources + - List of docker images + - Get list of docker registries + - Get list of container logs + - Get containers resource usage statistics + - Search for docker image in all available registries + - Get list of projects + - Get list of docker networks + + - **Setters** : + + - **Actions** : + - Export container profile + - Export container profile and content ## Methods ### `containers` Get list of containers. @@ -51,73 +50,73 @@ A dictionary containing the containers information.
Click to expand ```json -{ - "data": { - "1111aaaa-22bb-33cc-44dd-555555eeeeee": { - "containerIds": [ - "21bbe0c6a5d3b246f347367826a78db47f0f334a44bd6621e084f68f0ad63044" - ], - "created_at": "2025-03-14T14:07:04.874304Z", - "enable_service_portal": true, - "id": "187b2816-fd6c-4f87-b178-6d94806c7404", - "is_package": false, - "name": "pihole", - "path": "/volume1/docker/test", - "service_portal_name": "test", - "service_portal_port": 53, - "service_portal_protocol": "http", - "services": [ - { - "display_name": "test (project)", - "id": "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "proxy_target": "http://127.0.0.1:53", - "service": "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "type": "reverse_proxy" - } - ], - "share_path": "/docker/test", - "state": "", - "status": "STOPPED", - "updated_at": "2025-03-14T15:17:31.840634Z", - "version": 2 + { + "data": { + "1111aaaa-22bb-33cc-44dd-555555eeeeee": { + "containerIds": [ + "21bbe0c6a5d3b246f347367826a78db47f0f334a44bd6621e084f68f0ad63044" + ], + "created_at": "2025-03-14T14:07:04.874304Z", + "enable_service_portal": true, + "id": "187b2816-fd6c-4f87-b178-6d94806c7404", + "is_package": false, + "name": "pihole", + "path": "/volume1/docker/test", + "service_portal_name": "test", + "service_portal_port": 53, + "service_portal_protocol": "http", + "services": [ + { + "display_name": "test (project)", + "id": "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", + "proxy_target": "http://127.0.0.1:53", + "service": "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", + "type": "reverse_proxy" + } + ], + "share_path": "/docker/test", + "state": "", + "status": "STOPPED", + "updated_at": "2025-03-14T15:17:31.840634Z", + "version": 2 + }, + "2222bbbb-33cc-44dd-55ee-666666ffffff": { + "containerIds": [ + "d9301fc3aa925514760e7714a489cc2d14a26ed6e8169479ac6c356de6b5a7d9", + "89d63c6c3c4e299c82c2dcc4ba353c4c1e6c1c938b572153fe9f615646edc4f6", + "4a37c7a4a5cab34658071972c2c2bc3ff89dc6dc1407fd98751c7f227574a088", + "6df4151b6e24ea3b68b62851d65c8a830e342085f6f9cf0cfdf1e6f98357d9b1", + "1a1088cdf8d56e2443c22fa5c6f5658384ba894fe050d82b9214fb84342b0d93", + "36984528684d20c775ac67b3a286e48a5aa8ba73a36f58cfd062a8649d457328" + ], + "created_at": "2024-07-21T11:01:31.019924Z", + "enable_service_portal": true, + "id": "d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", + "is_package": false, + "name": "test2", + "path": "/volume1/docker/test2", + "service_portal_name": "test2-server", + "service_portal_port": 2283, + "service_portal_protocol": "http", + "services": [ + { + "display_name": "test2 (project)", + "id": "Docker-Project-d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", + "proxy_target": "http://127.0.0.1:2283", + "service": "Docker-Project-d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", + "type": "reverse_proxy" + } + ], + "share_path": "/docker/test2", + "state": "", + "status": "ERROR", + "updated_at": "2025-06-12T14:48:08.127657Z", + "version": 2 + } }, - "2222bbbb-33cc-44dd-55ee-666666ffffff": { - "containerIds": [ - "d9301fc3aa925514760e7714a489cc2d14a26ed6e8169479ac6c356de6b5a7d9", - "89d63c6c3c4e299c82c2dcc4ba353c4c1e6c1c938b572153fe9f615646edc4f6", - "4a37c7a4a5cab34658071972c2c2bc3ff89dc6dc1407fd98751c7f227574a088", - "6df4151b6e24ea3b68b62851d65c8a830e342085f6f9cf0cfdf1e6f98357d9b1", - "1a1088cdf8d56e2443c22fa5c6f5658384ba894fe050d82b9214fb84342b0d93", - "36984528684d20c775ac67b3a286e48a5aa8ba73a36f58cfd062a8649d457328" - ], - "created_at": "2024-07-21T11:01:31.019924Z", - "enable_service_portal": true, - "id": "d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", - "is_package": false, - "name": "test2", - "path": "/volume1/docker/test2", - "service_portal_name": "test2-server", - "service_portal_port": 2283, - "service_portal_protocol": "http", - "services": [ - { - "display_name": "test2 (project)", - "id": "Docker-Project-d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", - "proxy_target": "http://127.0.0.1:2283", - "service": "Docker-Project-d787e5ac-1b6a-4dd4-a2d9-35bcd5ad9577", - "type": "reverse_proxy" - } - ], - "share_path": "/docker/test2", - "state": "", - "status": "ERROR", - "updated_at": "2025-06-12T14:48:08.127657Z", - "version": 2 - } - }, - "success": true -} -``` + "success": true + } + ```
@@ -143,33 +142,33 @@ A dictionary containing the resources information of the containers.
Click to expand ```json - { - "data": { - "resources": [ - { - "cpu": 0, - "memory": 21106688, - "memoryPercent": 0.517403244972229, - "name": "container1" - }, - { - "cpu": 0, - "memory": 0, - "memoryPercent": 0, - "name": "container2" - }, - { - "cpu": 0, - "memory": 0, - "memoryPercent": 0, - "name": "stopped_container" - } - ] - }, - "httpd_restart": false, - "success": true - } -``` + { + "data": { + "resources": [ + { + "cpu": 0, + "memory": 21106688, + "memoryPercent": 0.517403244972229, + "name": "container1" + }, + { + "cpu": 0, + "memory": 0, + "memoryPercent": 0, + "name": "container2" + }, + { + "cpu": 0, + "memory": 0, + "memoryPercent": 0, + "name": "stopped_container" + } + ] + }, + "httpd_restart": false, + "success": true + } + ```
@@ -178,7 +177,7 @@ A dictionary containing the resources information of the containers. ### `system_resources` -Get system resources +Get system resources. #### Internal API
@@ -195,119 +194,119 @@ A dictionary containing the system resources information.
Click to expand ```json -{ - "data" : { - "cpu" : { - "15min_load" : 14, - "1min_load" : 29, - "5min_load" : 16, - "device" : "System", - "other_load" : 2, - "system_load" : 0, - "user_load" : 1 - }, - "disk" : { - "disk" : [ - { - "device" : "sata2", - "display_name" : "Drive 2", - "read_access" : 0, - "read_byte" : 0, - "type" : "internal", - "utilization" : 0, - "write_access" : 0, - "write_byte" : 0 - }, - { - "device" : "sata1", - "display_name" : "Drive 1", - "read_access" : 0, - "read_byte" : 0, - "type" : "internal", - "utilization" : 0, - "write_access" : 0, - "write_byte" : 0 - } - ], - "total" : { - "device" : "total", - "read_access" : 0, - "read_byte" : 0, - "utilization" : 0, - "write_access" : 0, - "write_byte" : 0 - } - }, - "lun" : [], - "memory" : { - "avail_real" : 444840, - "avail_swap" : 4163752, - "buffer" : 21716, - "cached" : 2658180, - "device" : "Memory", - "memory_size" : 4194304, - "real_usage" : 21, - "si_disk" : 0, - "so_disk" : 0, - "swap_usage" : 7, - "total_real" : 3983740, - "total_swap" : 4489140 - }, - "network" : [ - { - "device" : "total", - "rx" : 6822, - "tx" : 6336 - }, - { - "device" : "eth0", - "rx" : 0, - "tx" : 0 - }, - { - "device" : "eth1", - "rx" : 0, - "tx" : 0 - }, - { - "device" : "eth2", - "rx" : 6822, - "tx" : 6336 - } - ], - "nfs" : [], - "smb" : { - "smb_cmd" : [], - "smb_cpu" : [], - "smb_rwpkt" : [] - }, - "space" : { - "total" : { - "device" : "total", - "read_access" : 0, - "read_byte" : 0, - "utilization" : 0, - "write_access" : 0, - "write_byte" : 0 - }, - "volume" : [ - { - "device" : "dm-1", - "display_name" : "volume1", - "read_access" : 0, - "read_byte" : 0, - "utilization" : 0, - "write_access" : 0, - "write_byte" : 0 - } - ] - }, - "time" : 1749998465 - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "cpu" : { + "15min_load" : 14, + "1min_load" : 29, + "5min_load" : 16, + "device" : "System", + "other_load" : 2, + "system_load" : 0, + "user_load" : 1 + }, + "disk" : { + "disk" : [ + { + "device" : "sata2", + "display_name" : "Drive 2", + "read_access" : 0, + "read_byte" : 0, + "type" : "internal", + "utilization" : 0, + "write_access" : 0, + "write_byte" : 0 + }, + { + "device" : "sata1", + "display_name" : "Drive 1", + "read_access" : 0, + "read_byte" : 0, + "type" : "internal", + "utilization" : 0, + "write_access" : 0, + "write_byte" : 0 + } + ], + "total" : { + "device" : "total", + "read_access" : 0, + "read_byte" : 0, + "utilization" : 0, + "write_access" : 0, + "write_byte" : 0 + } + }, + "lun" : [], + "memory" : { + "avail_real" : 444840, + "avail_swap" : 4163752, + "buffer" : 21716, + "cached" : 2658180, + "device" : "Memory", + "memory_size" : 4194304, + "real_usage" : 21, + "si_disk" : 0, + "so_disk" : 0, + "swap_usage" : 7, + "total_real" : 3983740, + "total_swap" : 4489140 + }, + "network" : [ + { + "device" : "total", + "rx" : 6822, + "tx" : 6336 + }, + { + "device" : "eth0", + "rx" : 0, + "tx" : 0 + }, + { + "device" : "eth1", + "rx" : 0, + "tx" : 0 + }, + { + "device" : "eth2", + "rx" : 6822, + "tx" : 6336 + } + ], + "nfs" : [], + "smb" : { + "smb_cmd" : [], + "smb_cpu" : [], + "smb_rwpkt" : [] + }, + "space" : { + "total" : { + "device" : "total", + "read_access" : 0, + "read_byte" : 0, + "utilization" : 0, + "write_access" : 0, + "write_byte" : 0 + }, + "volume" : [ + { + "device" : "dm-1", + "display_name" : "volume1", + "read_access" : 0, + "read_byte" : 0, + "utilization" : 0, + "write_access" : 0, + "write_byte" : 0 + } + ] + }, + "time" : 1749998465 + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -346,30 +345,30 @@ A dictionary containing the list of downloaded images.
Click to expand ```json -{ - "data" : { - "images" : [ - { - "created" : 1745034718, - "description" : "", - "digest" : "", - "id" : "sha256:14300de7e087290520999f00d6a12b61385d1fe780ea83f38eabb7e8be66225f", - "remote_digest" : "", - "repository" : "caddy", - "size" : 50509416, - "tags" : [ "alpine" ], - "upgradable" : false, - "virtual_size" : 50509416 - } - ], - "limit" : 1, - "offset" : 0, - "total" : 1 - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "images" : [ + { + "created" : 1745034718, + "description" : "", + "digest" : "", + "id" : "sha256:14300de7e087290520999f00d6a12b61385d1fe780ea83f38eabb7e8be66225f", + "remote_digest" : "", + "repository" : "caddy", + "size" : 50509416, + "tags" : [ "alpine" ], + "upgradable" : false, + "virtual_size" : 50509416 + } + ], + "limit" : 1, + "offset" : 0, + "total" : 1 + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -379,58 +378,42 @@ A dictionary containing the list of downloaded images. ### `images_registry_resources` Get list of docker registries. -Example return --------------- -```json -{ - "data" : { - "offset" : 0, - "registries" : [ - { - "enable_registry_mirror" : false, - "enable_trust_SSC" : true, - "mirror_urls" : [], - "name" : "Docker Hub", - "syno" : true, - "url" : "https://registry.hub.docker.com" - } - ], - "total" : 1, - "using" : "Docker Hub" - }, - "httpd_restart" : false, - "success" : true -} -``` + #### Internal API
`SYNO.Docker.Registry`
+#### Returns +
+`dict[str, object]` +A dictionary containing the list of docker registries. + +
#### Example return
Click to expand ```json -{ - "data" : { - "offset" : 0, - "registries" : [ - { - "enable_registry_mirror" : false, - "enable_trust_SSC" : true, - "mirror_urls" : [], - "name" : "Docker Hub", - "syno" : true, - "url" : "https://registry.hub.docker.com" - } - ], - "total" : 1, - "using" : "Docker Hub" - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "offset" : 0, + "registries" : [ + { + "enable_registry_mirror" : false, + "enable_trust_SSC" : true, + "mirror_urls" : [], + "name" : "Docker Hub", + "syno" : true, + "url" : "https://registry.hub.docker.com" + } + ], + "total" : 1, + "using" : "Docker Hub" + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -440,76 +423,51 @@ Example return ### `network` Get list of docker networks. -Example return --------------- -```json -{ - "data" : { - "network" : [ - { - "containers" : [ "vault" ], - "driver" : "bridge", - "enable_ipv6" : false, - "gateway" : "172.22.0.1", - "id" : "b741915823aacdffc8ab806ab348e198c2c486b4dd5df2627b0d586259926b1a", - "iprange" : "", - "name" : "vault_default", - "subnet" : "172.22.0.0/16" - }, - { - "containers" : [], - "driver" : "host", - "enable_ipv6" : false, - "gateway" : "", - "id" : "2fc7ebae3901359e7bc9d7b50fad1f6aa2f8c1076474cadc9f83b3256f921ff3", - "iprange" : "", - "name" : "host", - "subnet" : "" - } - ] - }, - "httpd_restart" : false, - "success" : true -} -``` + #### Internal API
`SYNO.Docker.Network`
+#### Returns +
+`dict[str, object]` +A dictionary containing the list of docker networks. + +
#### Example return
Click to expand ```json -{ - "data" : { - "network" : [ - { - "containers" : [ "vault" ], - "driver" : "bridge", - "enable_ipv6" : false, - "gateway" : "172.22.0.1", - "id" : "b741915823aacdffc8ab806ab348e198c2c486b4dd5df2627b0d586259926b1a", - "iprange" : "", - "name" : "vault_default", - "subnet" : "172.22.0.0/16" - }, - { - "containers" : [], - "driver" : "host", - "enable_ipv6" : false, - "gateway" : "", - "id" : "2fc7ebae3901359e7bc9d7b50fad1f6aa2f8c1076474cadc9f83b3256f921ff3", - "iprange" : "", - "name" : "host", - "subnet" : "" - } - ] - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "network" : [ + { + "containers" : [ "vault" ], + "driver" : "bridge", + "enable_ipv6" : false, + "gateway" : "172.22.0.1", + "id" : "b741915823aacdffc8ab806ab348e198c2c486b4dd5df2627b0d586259926b1a", + "iprange" : "", + "name" : "vault_default", + "subnet" : "172.22.0.0/16" + }, + { + "containers" : [], + "driver" : "host", + "enable_ipv6" : false, + "gateway" : "", + "id" : "2fc7ebae3901359e7bc9d7b50fad1f6aa2f8c1076474cadc9f83b3256f921ff3", + "iprange" : "", + "name" : "host", + "subnet" : "" + } + ] + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -528,7 +486,7 @@ Search for docker image in all available registries. #### Parameters
**_query_** `str` -name of the docker image to search for. Defaults to None. +Name of the docker image to search for. Defaults to None.
@@ -542,37 +500,37 @@ A dictionary containing the search results for the docker image.
Click to expand ```json -{ - "data" : { - "data" : [ - { - "description" : "Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go.", - "downloads" : 650989718, - "is_automated" : false, - "is_official" : true, - "name" : "caddy", - "registry" : "https://registry.hub.docker.com", - "star_count" : 881 - }, - { - "description" : "Caddy is a lightweight, general-purpose web server.", - "downloads" : 111974910, - "is_automated" : true, - "is_official" : false, - "name" : "abiosoft/caddy", - "registry" : "https://registry.hub.docker.com", - "star_count" : 289 - } - ], - "limit" : 50, - "offset" : 0, - "page_size" : 50, - "total" : 6647 - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "data" : [ + { + "description" : "Caddy 2 is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go.", + "downloads" : 650989718, + "is_automated" : false, + "is_official" : true, + "name" : "caddy", + "registry" : "https://registry.hub.docker.com", + "star_count" : 881 + }, + { + "description" : "Caddy is a lightweight, general-purpose web server.", + "downloads" : 111974910, + "is_automated" : true, + "is_official" : false, + "name" : "abiosoft/caddy", + "registry" : "https://registry.hub.docker.com", + "star_count" : 289 + } + ], + "limit" : 50, + "offset" : 0, + "page_size" : 50, + "total" : 6647 + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -582,120 +540,73 @@ A dictionary containing the search results for the docker image. ### `list_projects` Get list of projects. -Example return --------------- -```json -{ - "data" : { - "187b2816-fd6c-4f87-b178-6d94806c7404" : { - "containerIds" : [ "21bbe0c6a5d3b246f347367826a78db47f0f334a44bd6621e084f68f0ad63044" ], - "created_at" : "2025-03-14T14:07:04.874304Z", - "enable_service_portal" : true, - "id" : "187b2816-fd6c-4f87-b178-6d94806c7404", - "is_package" : false, - "name" : "project1", - "path" : "/volume1/docker/project1", - "service_portal_name" : "project1", - "service_portal_port" : 53, - "service_portal_protocol" : "http", - "services" : [ - { - "display_name" : "project1 (project)", - "id" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "proxy_target" : "http://127.0.0.1:53", - "service" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "type" : "reverse_proxy" - } - ], - "share_path" : "/docker/project1", - "state" : "", - "status" : "STOPPED", - "updated_at" : "2025-03-14T15:17:31.840634Z", - "version" : 2 - }, - "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9" : { - "containerIds" : [ "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4" ], - "created_at" : "2025-05-27T08:33:03.213407Z", - "enable_service_portal" : false, - "id" : "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9", - "is_package" : false, - "name" : "project2", - "path" : "/volume1/docker/project2", - "service_portal_name" : "", - "service_portal_port" : 0, - "service_portal_protocol" : "", - "services" : [], - "share_path" : "/docker/project2", - "state" : "", - "status" : "RUNNING", - "updated_at" : "2025-06-15T10:38:52.247951Z", - "version" : 2 - } - }, - "httpd_restart" : false, - "success" : true -} -``` + #### Internal API
`SYNO.Docker.Project`
+#### Returns +
+`dict[str, object]` +A dictionary containing the list of projects. + +
#### Example return
Click to expand ```json -{ - "data" : { - "187b2816-fd6c-4f87-b178-6d94806c7404" : { - "containerIds" : [ "21bbe0c6a5d3b246f347367826a78db47f0f334a44bd6621e084f68f0ad63044" ], - "created_at" : "2025-03-14T14:07:04.874304Z", - "enable_service_portal" : true, - "id" : "187b2816-fd6c-4f87-b178-6d94806c7404", - "is_package" : false, - "name" : "project1", - "path" : "/volume1/docker/project1", - "service_portal_name" : "project1", - "service_portal_port" : 53, - "service_portal_protocol" : "http", - "services" : [ - { - "display_name" : "project1 (project)", - "id" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "proxy_target" : "http://127.0.0.1:53", - "service" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", - "type" : "reverse_proxy" - } - ], - "share_path" : "/docker/project1", - "state" : "", - "status" : "STOPPED", - "updated_at" : "2025-03-14T15:17:31.840634Z", - "version" : 2 - }, - "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9" : { - "containerIds" : [ "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4" ], - "created_at" : "2025-05-27T08:33:03.213407Z", - "enable_service_portal" : false, - "id" : "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9", - "is_package" : false, - "name" : "project2", - "path" : "/volume1/docker/project2", - "service_portal_name" : "", - "service_portal_port" : 0, - "service_portal_protocol" : "", - "services" : [], - "share_path" : "/docker/project2", - "state" : "", - "status" : "RUNNING", - "updated_at" : "2025-06-15T10:38:52.247951Z", - "version" : 2 - } - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "187b2816-fd6c-4f87-b178-6d94806c7404" : { + "containerIds" : [ "21bbe0c6a5d3b246f347367826a78db47f0f334a44bd6621e084f68f0ad63044" ], + "created_at" : "2025-03-14T14:07:04.874304Z", + "enable_service_portal" : true, + "id" : "187b2816-fd6c-4f87-b178-6d94806c7404", + "is_package" : false, + "name" : "project1", + "path" : "/volume1/docker/project1", + "service_portal_name" : "project1", + "service_portal_port" : 53, + "service_portal_protocol" : "http", + "services" : [ + { + "display_name" : "project1 (project)", + "id" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", + "proxy_target" : "http://127.0.0.1:53", + "service" : "Docker-Project-187b2816-fd6c-4f87-b178-6d94806c7404", + "type" : "reverse_proxy" + } + ], + "share_path" : "/docker/project1", + "state" : "", + "status" : "STOPPED", + "updated_at" : "2025-03-14T15:17:31.840634Z", + "version" : 2 + }, + "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9" : { + "containerIds" : [ "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4" ], + "created_at" : "2025-05-27T08:33:03.213407Z", + "enable_service_portal" : false, + "id" : "3c091e8b-f68f-4161-97a3-fc3db3f4bdc9", + "is_package" : false, + "name" : "project2", + "path" : "/volume1/docker/project2", + "service_portal_name" : "", + "service_portal_port" : 0, + "service_portal_protocol" : "", + "services" : [], + "share_path" : "/docker/project2", + "state" : "", + "status" : "RUNNING", + "updated_at" : "2025-06-15T10:38:52.247951Z", + "version" : 2 + } + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -728,309 +639,309 @@ A dictionary containing the project information.
Click to expand ```json -{ - "data" : { - "containerIds" : [ "1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf" ], - "containers" : [ - { - "AppArmorProfile" : "docker-default", - "Args" : [ "server", "-config=/vault/file/" ], - "Config" : { - "AttachStderr" : true, - "AttachStdin" : false, - "AttachStdout" : true, - "Cmd" : null, - "Domainname" : "", - "Entrypoint" : [ "vault", "server", "-config=/vault/file/" ], - "Env" : [ - "VAULT_RAFT_PATH=/vault/file", - "VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "NAME=vault", - "VERSION=" - ], - "ExposedPorts" : { - "8200/tcp" : {} - }, - "Healthcheck" : { - "Interval" : 30000000000, - "Retries" : 5, - "Test" : [ "CMD", "vault", "status" ], - "Timeout" : 10000000000 - }, - "Hostname" : "vault", - "Image" : "hashicorp/vault:latest", - "Labels" : { - "com.docker.compose.config-hash" : "6a08fb0e6d57f8ad25b3d78cac40d369be831be5cf98406520e514d68aa03251", - "com.docker.compose.container-number" : "1", - "com.docker.compose.depends_on" : "", - "com.docker.compose.image" : "sha256:2006f053b116f3a57dad1d8fff9d19c13f3e801e594dcbd58e219d4ccb654337", - "com.docker.compose.oneoff" : "False", - "com.docker.compose.project" : "vault", - "com.docker.compose.project.config_files" : "/volume1/docker/vault/compose.yaml", - "com.docker.compose.project.working_dir" : "/volume1/docker/vault", - "com.docker.compose.replace" : "1153d033ece9eb4242926f805a211daed65922652fdf73ffcf8147e20e4c0ce2", - "com.docker.compose.service" : "vault", - "com.docker.compose.version" : "2.20.1", - "description" : "Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log.", - "maintainer" : "Vault Team ", - "name" : "Vault", - "release" : "322786e236e268532e4b189845971ba67b5cbb23", - "revision" : "322786e236e268532e4b189845971ba67b5cbb23", - "summary" : "Vault is a tool for securely accessing secrets.", - "vendor" : "HashiCorp", - "version" : "1.19.4" - }, - "OnBuild" : null, - "OpenStdin" : false, - "StdinOnce" : false, - "Tty" : false, - "User" : "", - "Volumes" : { - "/vault/file" : {}, - "/vault/logs" : {} - }, - "WorkingDir" : "/" - }, - "Created" : "2025-05-25T17:57:06.296933361Z", - "Driver" : "btrfs", - "ExecIDs" : null, - "GraphDriver" : { - "Data" : null, - "Name" : "btrfs" - }, - "HostConfig" : { - "AutoRemove" : false, - "Binds" : [ - "/volume1/docker/vault/data:/vault/file:rw", - "/volume1/docker/vault/logs:/vault/logs:rw", - "/volume1/docker/vault/config:/vault/config:rw", - "/volume1/docker/vault/plugins:/vault/plugins:rw", - "/etc/localtime:/etc/localtime:ro" - ], - "BlkioDeviceReadBps" : null, - "BlkioDeviceReadIOps" : null, - "BlkioDeviceWriteBps" : null, - "BlkioDeviceWriteIOps" : null, - "BlkioWeight" : 0, - "BlkioWeightDevice" : null, - "CapAdd" : [ "IPC_LOCK" ], - "CapDrop" : null, - "Cgroup" : "", - "CgroupParent" : "", - "CgroupnsMode" : "host", - "ConsoleSize" : [ 0, 0 ], - "ContainerIDFile" : "", - "CpuCount" : 0, - "CpuPercent" : 0, - "CpuPeriod" : 0, - "CpuQuota" : 0, - "CpuRealtimePeriod" : 0, - "CpuRealtimeRuntime" : 0, - "CpuShares" : 768, - "CpusetCpus" : "", - "CpusetMems" : "", - "DeviceCgroupRules" : null, - "DeviceRequests" : null, - "Devices" : null, - "Dns" : [], - "DnsOptions" : [], - "DnsSearch" : [], - "ExtraHosts" : [], - "GroupAdd" : null, - "IOMaximumBandwidth" : 0, - "IOMaximumIOps" : 0, - "IpcMode" : "private", - "Isolation" : "", - "Links" : null, - "LogConfig" : { - "Config" : {}, - "Type" : "db" - }, - "MaskedPaths" : [ - "/proc/asound", - "/proc/acpi", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", - "/proc/timer_list", - "/proc/timer_stats", - "/proc/sched_debug", - "/proc/scsi", - "/sys/firmware" - ], - "Memory" : 536870912, - "MemoryReservation" : 0, - "MemorySwap" : 1073741824, - "MemorySwappiness" : null, - "NanoCpus" : 0, - "NetworkMode" : "vault_default", - "OomKillDisable" : false, - "OomScoreAdj" : 0, - "PidMode" : "", - "PidsLimit" : null, - "PortBindings" : { - "8200/tcp" : [ - { - "HostIp" : "", - "HostPort" : "8205" - } - ] - }, - "Privileged" : false, - "PublishAllPorts" : false, - "ReadonlyPaths" : [ - "/proc/bus", - "/proc/fs", - "/proc/irq", - "/proc/sys", - "/proc/sysrq-trigger" - ], - "ReadonlyRootfs" : false, - "RestartPolicy" : { - "MaximumRetryCount" : 5, - "Name" : "on-failure" - }, - "Runtime" : "runc", - "SecurityOpt" : [ "no-new-privileges:true" ], - "ShmSize" : 67108864, - "UTSMode" : "", - "Ulimits" : null, - "UsernsMode" : "", - "VolumeDriver" : "", - "VolumesFrom" : null - }, - "HostnamePath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/hostname", - "HostsPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/hosts", - "Id" : "1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf", - "Image" : "sha256:2006f053b116f3a57dad1d8fff9d19c13f3e801e594dcbd58e219d4ccb654337", - "LogPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/log.db", - "MountLabel" : "", - "Mounts" : [ - { - "Destination" : "/vault/plugins", - "Mode" : "rw", - "Propagation" : "rprivate", - "RW" : true, - "Source" : "/volume1/docker/vault/plugins", - "Type" : "bind" - }, - { - "Destination" : "/etc/localtime", - "Mode" : "ro", - "Propagation" : "rprivate", - "RW" : false, - "Source" : "/etc/localtime", - "Type" : "bind" - }, - { - "Destination" : "/vault/config", - "Mode" : "rw", - "Propagation" : "rprivate", - "RW" : true, - "Source" : "/volume1/docker/vault/config", - "Type" : "bind" - }, - { - "Destination" : "/vault/file", - "Mode" : "rw", - "Propagation" : "rprivate", - "RW" : true, - "Source" : "/volume1/docker/vault/data", - "Type" : "bind" - }, - { - "Destination" : "/vault/logs", - "Mode" : "rw", - "Propagation" : "rprivate", - "RW" : true, - "Source" : "/volume1/docker/vault/logs", - "Type" : "bind" - } - ], - "Name" : "/vault", - "NetworkSettings" : { - "Bridge" : "", - "EndpointID" : "", - "Gateway" : "", - "GlobalIPv6Address" : "", - "GlobalIPv6PrefixLen" : 0, - "HairpinMode" : false, - "IPAddress" : "", - "IPPrefixLen" : 0, - "IPv6Gateway" : "", - "LinkLocalIPv6Address" : "", - "LinkLocalIPv6PrefixLen" : 0, - "MacAddress" : "", - "Networks" : { - "vault_default" : { - "Aliases" : [ "vault", "vault", "1f2aa674d794" ], - "DriverOpts" : null, - "EndpointID" : "", - "Gateway" : "", - "GlobalIPv6Address" : "", - "GlobalIPv6PrefixLen" : 0, - "IPAMConfig" : null, - "IPAddress" : "", - "IPPrefixLen" : 0, - "IPv6Gateway" : "", - "Links" : null, - "MacAddress" : "", - "NetworkID" : "b741915823aacdffc8ab806ab348e198c2c486b4dd5df2627b0d586259926b1a" - } - }, - "Ports" : {}, - "SandboxID" : "d523ddff9d90b2ecc74f20c33db7b4898fa2869f10899ccc6567febd64d7142c", - "SandboxKey" : "/var/run/docker/netns/d523ddff9d90", - "SecondaryIPAddresses" : null, - "SecondaryIPv6Addresses" : null - }, - "Path" : "vault", - "Platform" : "linux", - "ProcessLabel" : "", - "ResolvConfPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/resolv.conf", - "RestartCount" : 5, - "State" : { - "Dead" : false, - "Error" : "", - "ExitCode" : 1, - "FinishedAt" : "2025-05-25T17:57:30.266770048Z", - "Health" : { - "FailingStreak" : 0, - "Log" : [], - "Status" : "unhealthy" - }, - "OOMKilled" : false, - "Paused" : false, - "Pid" : 0, - "Restarting" : false, - "Running" : false, - "StartedAt" : "2025-05-25T17:57:30.184237615Z", - "Status" : "exited" - } - } - ], - "content" : "docker-compose.yml contet", - "created_at" : "2025-05-25T17:31:00.875402Z", - "enable_service_portal" : false, - "id" : "b4d44e6c-5ab4-45f7-b380-481ef9839df1", - "is_package" : false, - "name" : "vault", - "path" : "/volume1/docker/vault", - "service_portal_name" : "", - "service_portal_port" : 0, - "service_portal_protocol" : "", - "services" : null, - "share_path" : "/docker/vault", - "state" : "", - "status" : "STOPPED", - "updated_at" : "2025-05-25T17:57:06.257863Z", - "version" : 2 - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "containerIds" : [ "1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf" ], + "containers" : [ + { + "AppArmorProfile" : "docker-default", + "Args" : [ "server", "-config=/vault/file/" ], + "Config" : { + "AttachStderr" : true, + "AttachStdin" : false, + "AttachStdout" : true, + "Cmd" : null, + "Domainname" : "", + "Entrypoint" : [ "vault", "server", "-config=/vault/file/" ], + "Env" : [ + "VAULT_RAFT_PATH=/vault/file", + "VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "NAME=vault", + "VERSION=" + ], + "ExposedPorts" : { + "8200/tcp" : {} + }, + "Healthcheck" : { + "Interval" : 30000000000, + "Retries" : 5, + "Test" : [ "CMD", "vault", "status" ], + "Timeout" : 10000000000 + }, + "Hostname" : "vault", + "Image" : "hashicorp/vault:latest", + "Labels" : { + "com.docker.compose.config-hash" : "6a08fb0e6d57f8ad25b3d78cac40d369be831be5cf98406520e514d68aa03251", + "com.docker.compose.container-number" : "1", + "com.docker.compose.depends_on" : "", + "com.docker.compose.image" : "sha256:2006f053b116f3a57dad1d8fff9d19c13f3e801e594dcbd58e219d4ccb654337", + "com.docker.compose.oneoff" : "False", + "com.docker.compose.project" : "vault", + "com.docker.compose.project.config_files" : "/volume1/docker/vault/compose.yaml", + "com.docker.compose.project.working_dir" : "/volume1/docker/vault", + "com.docker.compose.replace" : "1153d033ece9eb4242926f805a211daed65922652fdf73ffcf8147e20e4c0ce2", + "com.docker.compose.service" : "vault", + "com.docker.compose.version" : "2.20.1", + "description" : "Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log.", + "maintainer" : "Vault Team ", + "name" : "Vault", + "release" : "322786e236e268532e4b189845971ba67b5cbb23", + "revision" : "322786e236e268532e4b189845971ba67b5cbb23", + "summary" : "Vault is a tool for securely accessing secrets.", + "vendor" : "HashiCorp", + "version" : "1.19.4" + }, + "OnBuild" : null, + "OpenStdin" : false, + "StdinOnce" : false, + "Tty" : false, + "User" : "", + "Volumes" : { + "/vault/file" : {}, + "/vault/logs" : {} + }, + "WorkingDir" : "/" + }, + "Created" : "2025-05-25T17:57:06.296933361Z", + "Driver" : "btrfs", + "ExecIDs" : null, + "GraphDriver" : { + "Data" : null, + "Name" : "btrfs" + }, + "HostConfig" : { + "AutoRemove" : false, + "Binds" : [ + "/volume1/docker/vault/data:/vault/file:rw", + "/volume1/docker/vault/logs:/vault/logs:rw", + "/volume1/docker/vault/config:/vault/config:rw", + "/volume1/docker/vault/plugins:/vault/plugins:rw", + "/etc/localtime:/etc/localtime:ro" + ], + "BlkioDeviceReadBps" : null, + "BlkioDeviceReadIOps" : null, + "BlkioDeviceWriteBps" : null, + "BlkioDeviceWriteIOps" : null, + "BlkioWeight" : 0, + "BlkioWeightDevice" : null, + "CapAdd" : [ "IPC_LOCK" ], + "CapDrop" : null, + "Cgroup" : "", + "CgroupParent" : "", + "CgroupnsMode" : "host", + "ConsoleSize" : [ 0, 0 ], + "ContainerIDFile" : "", + "CpuCount" : 0, + "CpuPercent" : 0, + "CpuPeriod" : 0, + "CpuQuota" : 0, + "CpuRealtimePeriod" : 0, + "CpuRealtimeRuntime" : 0, + "CpuShares" : 768, + "CpusetCpus" : "", + "CpusetMems" : "", + "DeviceCgroupRules" : null, + "DeviceRequests" : null, + "Devices" : null, + "Dns" : [], + "DnsOptions" : [], + "DnsSearch" : [], + "ExtraHosts" : [], + "GroupAdd" : null, + "IOMaximumBandwidth" : 0, + "IOMaximumIOps" : 0, + "IpcMode" : "private", + "Isolation" : "", + "Links" : null, + "LogConfig" : { + "Config" : {}, + "Type" : "db" + }, + "MaskedPaths" : [ + "/proc/asound", + "/proc/acpi", + "/proc/kcore", + "/proc/keys", + "/proc/latency_stats", + "/proc/timer_list", + "/proc/timer_stats", + "/proc/sched_debug", + "/proc/scsi", + "/sys/firmware" + ], + "Memory" : 536870912, + "MemoryReservation" : 0, + "MemorySwap" : 1073741824, + "MemorySwappiness" : null, + "NanoCpus" : 0, + "NetworkMode" : "vault_default", + "OomKillDisable" : false, + "OomScoreAdj" : 0, + "PidMode" : "", + "PidsLimit" : null, + "PortBindings" : { + "8200/tcp" : [ + { + "HostIp" : "", + "HostPort" : "8205" + } + ] + }, + "Privileged" : false, + "PublishAllPorts" : false, + "ReadonlyPaths" : [ + "/proc/bus", + "/proc/fs", + "/proc/irq", + "/proc/sys", + "/proc/sysrq-trigger" + ], + "ReadonlyRootfs" : false, + "RestartPolicy" : { + "MaximumRetryCount" : 5, + "Name" : "on-failure" + }, + "Runtime" : "runc", + "SecurityOpt" : [ "no-new-privileges:true" ], + "ShmSize" : 67108864, + "UTSMode" : "", + "Ulimits" : null, + "UsernsMode" : "", + "VolumeDriver" : "", + "VolumesFrom" : null + }, + "HostnamePath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/hostname", + "HostsPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/hosts", + "Id" : "1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf", + "Image" : "sha256:2006f053b116f3a57dad1d8fff9d19c13f3e801e594dcbd58e219d4ccb654337", + "LogPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/log.db", + "MountLabel" : "", + "Mounts" : [ + { + "Destination" : "/vault/plugins", + "Mode" : "rw", + "Propagation" : "rprivate", + "RW" : true, + "Source" : "/volume1/docker/vault/plugins", + "Type" : "bind" + }, + { + "Destination" : "/etc/localtime", + "Mode" : "ro", + "Propagation" : "rprivate", + "RW" : false, + "Source" : "/etc/localtime", + "Type" : "bind" + }, + { + "Destination" : "/vault/config", + "Mode" : "rw", + "Propagation" : "rprivate", + "RW" : true, + "Source" : "/volume1/docker/vault/config", + "Type" : "bind" + }, + { + "Destination" : "/vault/file", + "Mode" : "rw", + "Propagation" : "rprivate", + "RW" : true, + "Source" : "/volume1/docker/vault/data", + "Type" : "bind" + }, + { + "Destination" : "/vault/logs", + "Mode" : "rw", + "Propagation" : "rprivate", + "RW" : true, + "Source" : "/volume1/docker/vault/logs", + "Type" : "bind" + } + ], + "Name" : "/vault", + "NetworkSettings" : { + "Bridge" : "", + "EndpointID" : "", + "Gateway" : "", + "GlobalIPv6Address" : "", + "GlobalIPv6PrefixLen" : 0, + "HairpinMode" : false, + "IPAddress" : "", + "IPPrefixLen" : 0, + "IPv6Gateway" : "", + "LinkLocalIPv6Address" : "", + "LinkLocalIPv6PrefixLen" : 0, + "MacAddress" : "", + "Networks" : { + "vault_default" : { + "Aliases" : [ "vault", "vault", "1f2aa674d794" ], + "DriverOpts" : null, + "EndpointID" : "", + "Gateway" : "", + "GlobalIPv6Address" : "", + "GlobalIPv6PrefixLen" : 0, + "IPAMConfig" : null, + "IPAddress" : "", + "IPPrefixLen" : 0, + "IPv6Gateway" : "", + "Links" : null, + "MacAddress" : "", + "NetworkID" : "b741915823aacdffc8ab806ab348e198c2c486b4dd5df2627b0d586259926b1a" + } + }, + "Ports" : {}, + "SandboxID" : "d523ddff9d90b2ecc74f20c33db7b4898fa2869f10899ccc6567febd64d7142c", + "SandboxKey" : "/var/run/docker/netns/d523ddff9d90", + "SecondaryIPAddresses" : null, + "SecondaryIPv6Addresses" : null + }, + "Path" : "vault", + "Platform" : "linux", + "ProcessLabel" : "", + "ResolvConfPath" : "/volume1/@docker/containers/1f2aa674d7942c25789c144c1e4ea04388e5a914e1ed3d7a1b8978f8f2f81ebf/resolv.conf", + "RestartCount" : 5, + "State" : { + "Dead" : false, + "Error" : "", + "ExitCode" : 1, + "FinishedAt" : "2025-05-25T17:57:30.266770048Z", + "Health" : { + "FailingStreak" : 0, + "Log" : [], + "Status" : "unhealthy" + }, + "OOMKilled" : false, + "Paused" : false, + "Pid" : 0, + "Restarting" : false, + "Running" : false, + "StartedAt" : "2025-05-25T17:57:30.184237615Z", + "Status" : "exited" + } + } + ], + "content" : "docker-compose.yml contet", + "created_at" : "2025-05-25T17:31:00.875402Z", + "enable_service_portal" : false, + "id" : "b4d44e6c-5ab4-45f7-b380-481ef9839df1", + "is_package" : false, + "name" : "vault", + "path" : "/volume1/docker/vault", + "service_portal_name" : "", + "service_portal_port" : 0, + "service_portal_protocol" : "", + "services" : null, + "share_path" : "/docker/vault", + "state" : "", + "status" : "STOPPED", + "updated_at" : "2025-05-25T17:57:06.257863Z", + "version" : 2 + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -1049,7 +960,7 @@ Start a container by its name. #### Parameters
**_container_** `str` -The name of the container +The name of the container.
@@ -1063,18 +974,18 @@ A dictionary containing the result of the export operation.
Click to expand ```json -{ - "data" : { - "cpu" : 0, - "memory" : 21241856, - "memoryPercent" : 0.52071672677993774, - "name" : "glance", - "start_dependent_container" : false - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "cpu" : 0, + "memory" : 21241856, + "memoryPercent" : 0.52071672677993774, + "name" : "glance", + "start_dependent_container" : false + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -1093,7 +1004,7 @@ Stop a container by its name. #### Parameters
**_container_** `str` -The name of the container +The name of the container.
@@ -1107,17 +1018,17 @@ A dictionary containing the result of the stop operation.
Click to expand ```json -{ - "data" : { - "cpu" : 0, - "memory" : 0, - "memoryPercent" : 0, - "name" : "glance" - }, - "httpd_restart" : false, - "success" : true -} -``` + { + "data" : { + "cpu" : 0, + "memory" : 0, + "memoryPercent" : 0, + "name" : "glance" + }, + "httpd_restart" : false, + "success" : true + } + ```
@@ -1126,7 +1037,7 @@ A dictionary containing the result of the stop operation. ### `export_container_settings` -Export container profile +Export container profile. file \.syno.json will be created in the specified path. #### Internal API
@@ -1136,12 +1047,12 @@ file \.syno.json will be created in the specified path. #### Parameters
**_container_** `str` -The name of the container +The name of the container. **_path_** `str` The path on filesystem of Synology NAS where the container settings will be exported. If not specified, the file will be offered as a download through the browser. -For example: `/docker/nging` +For example: `/docker/nging`.
@@ -1155,12 +1066,12 @@ A dictionary containing the result of the export operation.
Click to expand ```json - { - "data" : {}, - "httpd_restart" : false, - "success" : true - } -``` + { + "data" : {}, + "httpd_restart" : false, + "success" : true + } + ```
@@ -1179,11 +1090,11 @@ archive \.syno.txz will be created in the specified path. #### Parameters
**_container_** `str` -The name of the container +The name of the container. **_path_** `str` The path on filesystem of Synology NAS where the container settings will be exported. -For example: `/docker/nging` +For example: `/docker/nging`.
@@ -1197,12 +1108,12 @@ A dictionary containing the result of the export operation.
Click to expand ```json - { - "data" : {}, - "httpd_restart" : false, - "success" : true - } -``` + { + "data" : {}, + "httpd_restart" : false, + "success" : true + } + ```
@@ -1221,7 +1132,7 @@ Get list of container logs. #### Parameters
**_name_** `str` -The name of the container +The name of the container. **_from_date_** `str` The start date for the logs. Defaults to None. @@ -1256,23 +1167,23 @@ A dictionary containing the logs from the specified container.
Click to expand ```json - { - "data": { - "limit": 1, - "logs": [ - { - "created": "2025-06-15T10:38:55.869358659Z", - "docid": "1", - "stream": "stderr", - "text": "2025/06/15 10:38:55 Starting server on :8080" - } - ], - "offset": 0, - "total": 1 - }, - "success": true - } -``` + { + "data": { + "limit": 1, + "logs": [ + { + "created": "2025-06-15T10:38:55.869358659Z", + "docid": "1", + "stream": "stderr", + "text": "2025/06/15 10:38:55 Starting server on :8080" + } + ], + "offset": 0, + "total": 1 + }, + "success": true + } + ```
@@ -1298,111 +1209,111 @@ A dictionary containing the resource usage statistics of the containers.
Click to expand ```json - { - "data" : { - "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4" : { - "blkio_stats" : { - "io_merged_recursive" : [], - "io_queue_recursive" : [], - "io_service_bytes_recursive" : [], - "io_service_time_recursive" : [], - "io_serviced_recursive" : [], - "io_time_recursive" : [], - "io_wait_time_recursive" : [], - "sectors_recursive" : [] - }, - "cpu_stats" : { - "cpu_usage" : { - "percpu_usage" : [ 286394951, 245078386, 304613157, 186566695 ], - "total_usage" : 1022653189, - "usage_in_kernelmode" : 380000000, - "usage_in_usermode" : 580000000 - }, - "online_cpus" : 4, - "system_cpu_usage" : 990015100000000, - "throttling_data" : { - "periods" : 0, - "throttled_periods" : 0, - "throttled_time" : 0 - } - }, - "id" : "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4", - "memory_stats" : { - "limit" : 4079349760, - "max_usage" : 22630400, - "stats" : { - "active_anon" : 5500928, - "active_file" : 1294336, - "cache" : 15626240, - "dirty" : 0, - "hierarchical_memory_limit" : 9223372036854771712, - "hierarchical_memsw_limit" : 9223372036854771712, - "inactive_anon" : 0, - "inactive_file" : 14331904, - "mapped_file" : 11005952, - "pgfault" : 43383, - "pgmajfault" : 6, - "pgpgin" : 33405, - "pgpgout" : 28247, - "rss" : 5500928, - "rss_huge" : 0, - "total_active_anon" : 5500928, - "total_active_file" : 1294336, - "total_cache" : 15626240, - "total_dirty" : 0, - "total_inactive_anon" : 0, - "total_inactive_file" : 14331904, - "total_mapped_file" : 11005952, - "total_pgfault" : 43383, - "total_pgmajfault" : 6, - "total_pgpgin" : 33405, - "total_pgpgout" : 28247, - "total_rss" : 5500928, - "total_rss_huge" : 0, - "total_unevictable" : 0, - "total_writeback" : 0, - "unevictable" : 0, - "writeback" : 0 - }, - "usage" : 21127168 - }, - "name" : "/glance", - "networks" : { - "eth0" : { - "rx_bytes" : 876, - "rx_dropped" : 0, - "rx_errors" : 0, - "rx_packets" : 10, - "tx_bytes" : 0, - "tx_dropped" : 0, - "tx_errors" : 0, - "tx_packets" : 0 - } - }, - "num_procs" : 0, - "pids_stats" : {}, - "precpu_stats" : { - "cpu_usage" : { - "total_usage" : 0, - "usage_in_kernelmode" : 0, - "usage_in_usermode" : 0 - }, - "throttling_data" : { - "periods" : 0, - "throttled_periods" : 0, - "throttled_time" : 0 - } - }, - "preread" : "0001-01-01T00:00:00Z", - "read" : "2025-06-15T14:11:00.431111646Z", - "storage_stats" : {} - } - }, - "httpd_restart" : false, - "success" : true - } + { + "data" : { + "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4" : { + "blkio_stats" : { + "io_merged_recursive" : [], + "io_queue_recursive" : [], + "io_service_bytes_recursive" : [], + "io_service_time_recursive" : [], + "io_serviced_recursive" : [], + "io_time_recursive" : [], + "io_wait_time_recursive" : [], + "sectors_recursive" : [] + }, + "cpu_stats" : { + "cpu_usage" : { + "percpu_usage" : [ 286394951, 245078386, 304613157, 186566695 ], + "total_usage" : 1022653189, + "usage_in_kernelmode" : 380000000, + "usage_in_usermode" : 580000000 + }, + "online_cpus" : 4, + "system_cpu_usage" : 990015100000000, + "throttling_data" : { + "periods" : 0, + "throttled_periods" : 0, + "throttled_time" : 0 + } + }, + "id" : "ee220111cff2d2e7b9d764a4b781f9e23faa3cd7f3048d315aa6c95d48f0a1e4", + "memory_stats" : { + "limit" : 4079349760, + "max_usage" : 22630400, + "stats" : { + "active_anon" : 5500928, + "active_file" : 1294336, + "cache" : 15626240, + "dirty" : 0, + "hierarchical_memory_limit" : 9223372036854771712, + "hierarchical_memsw_limit" : 9223372036854771712, + "inactive_anon" : 0, + "inactive_file" : 14331904, + "mapped_file" : 11005952, + "pgfault" : 43383, + "pgmajfault" : 6, + "pgpgin" : 33405, + "pgpgout" : 28247, + "rss" : 5500928, + "rss_huge" : 0, + "total_active_anon" : 5500928, + "total_active_file" : 1294336, + "total_cache" : 15626240, + "total_dirty" : 0, + "total_inactive_anon" : 0, + "total_inactive_file" : 14331904, + "total_mapped_file" : 11005952, + "total_pgfault" : 43383, + "total_pgmajfault" : 6, + "total_pgpgin" : 33405, + "total_pgpgout" : 28247, + "total_rss" : 5500928, + "total_rss_huge" : 0, + "total_unevictable" : 0, + "total_writeback" : 0, + "unevictable" : 0, + "writeback" : 0 + }, + "usage" : 21127168 + }, + "name" : "/glance", + "networks" : { + "eth0" : { + "rx_bytes" : 876, + "rx_dropped" : 0, + "rx_errors" : 0, + "rx_packets" : 10, + "tx_bytes" : 0, + "tx_dropped" : 0, + "tx_errors" : 0, + "tx_packets" : 0 + } + }, + "num_procs" : 0, + "pids_stats" : {}, + "precpu_stats" : { + "cpu_usage" : { + "total_usage" : 0, + "usage_in_kernelmode" : 0, + "usage_in_usermode" : 0 + }, + "throttling_data" : { + "periods" : 0, + "throttled_periods" : 0, + "throttled_time" : 0 + } + }, + "preread" : "0001-01-01T00:00:00Z", + "read" : "2025-06-15T14:11:00.431111646Z", + "storage_stats" : {} + } + }, + "httpd_restart" : false, + "success" : true + } -``` + ```
diff --git a/documentation/docs/apis/classes/downloadstation.md b/documentation/docs/apis/classes/downloadstation.md index 48fbb3c2..9a45a9d7 100644 --- a/documentation/docs/apis/classes/downloadstation.md +++ b/documentation/docs/apis/classes/downloadstation.md @@ -14,9 +14,100 @@ This API is not documented yet. ::: ## Overview - +Core Download Station API implementation for Synology NAS. + +This class provides methods to manage downloads, tasks, RSS feeds, and BT searches. + +Parameters +---------- +ip_address : str + IP address or hostname of the Synology NAS. +port : str + Port number to connect to. +username : str + Username for authentication. +password : str + Password for authentication. +secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). +cert_verify : bool, optional + Verify SSL certificates (default is False). +dsm_version : int, optional + DSM version (default is 7). +debug : bool, optional + Enable debug output (default is True). +otp_code : Optional[str], optional + One-time password for 2FA (default is None). +device_id : Optional[str], optional + Device ID (default is None). +device_name : Optional[str], optional + Device name (default is None). +interactive_output : bool, optional + Enable interactive output (default is True). +download_st_version : int, optional + Download Station API version (default is None). + +Methods +------- +get_info() + Get Download Station info. +get_config() + Get Download Station config. +set_server_config(...) + Set Download Station server config. +schedule_info() + Get schedule info. +schedule_set_config(...) + Set schedule config. +tasks_list(...) + List download tasks. +tasks_info(...) + Get info for specific tasks. +tasks_source(...) + Download task source. +create_task(...) + Create a new download task. +delete_task(...) + Delete a download task. +pause_task(...) + Pause a download task. +resume_task(...) + Resume a download task. +edit_task(...) + Edit a download task. +get_statistic_info() + Get Download Station statistics. +get_rss_info_list(...) + Get RSS site info list. +refresh_rss_site(...) + Refresh RSS site. +rss_feed_list(...) + Get RSS feed list. +start_bt_search(...) + Start a BT search. +get_bt_search_results(...) + Get BT search results. +get_bt_search_category() + Get BT search categories. +clean_bt_search(...) + Clean BT search tasks. +get_bt_module() + Get BT search modules. ## Methods ### `get_info` +Get Download Station info. + +#### Internal API +
+`SYNO.DownloadStation.Info` +
+ +#### Returns +
+`dict[str, object] or str` +Download Station info. + +
@@ -24,6 +115,19 @@ This API is not documented yet. ### `get_config` +Get Download Station config. + +#### Internal API +
+`SYNO.DownloadStation.Info` +
+ +#### Returns +
+`dict[str, object] or str` +Download Station config. + +
@@ -31,6 +135,56 @@ This API is not documented yet. ### `set_server_config` +Set Download Station server configuration. + +#### Internal API +
+`SYNO.DownloadStation.Info` +
+ +#### Parameters +
+**_bt_max_download_** `Optional[int]` +Maximum BT download speed. + +**_bt_max_upload_** `Optional[int]` +Maximum BT upload speed. + +**_emule_max_download_** `Optional[int]` +Maximum eMule download speed. + +**_emule_max_upload_** `Optional[int]` +Maximum eMule upload speed. + +**_nzb_max_download_** `Optional[int]` +Maximum NZB download speed. + +**_http_max_download_** `Optional[int]` +Maximum HTTP download speed. + +**_ftp_max_download_** `Optional[int]` +Maximum FTP download speed. + +**_emule_enabled_** `Optional[bool]` +Enable eMule. + +**_unzip_service_enabled_** `Optional[bool]` +Enable unzip service. + +**_default_destination_** `Optional[str]` +Default download destination. + +**_emule_default_destination_** `Optional[str]` +Default eMule download destination. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -38,6 +192,19 @@ This API is not documented yet. ### `schedule_info` +Get Download Station schedule configuration. + +#### Internal API +
+`SYNO.DownloadStation.Schedule` +
+ +#### Returns +
+`dict[str, object] or str` +Schedule configuration. + +
@@ -45,6 +212,29 @@ This API is not documented yet. ### `schedule_set_config` +Set Download Station schedule configuration. + +#### Internal API +
+`SYNO.DownloadStation.Schedule` +
+ +#### Parameters +
+**_enabled_** `bool` +Enable schedule (default is False). + +**_emule_enabled_** `bool` +Enable eMule schedule (default is False). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -52,6 +242,32 @@ This API is not documented yet. ### `tasks_list` +List download tasks. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_additional_param_** `Optional[str or list[str]]` +Additional fields to retrieve. + +**_offset_** `int` +Offset for pagination (default is 0). + +**_limit_** `int` +Maximum number of tasks to retrieve (default is -1). + + +
+#### Returns +
+`dict[str, object] or str` +List of download tasks. + +
@@ -59,6 +275,29 @@ This API is not documented yet. ### `tasks_info` +Get information for specific download tasks. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + +**_additional_param_** `Optional[str or list[str]]` +Additional fields to retrieve. + + +
+#### Returns +
+`dict[str, object] or str` +Task information. + +
@@ -66,6 +305,53 @@ This API is not documented yet. ### `tasks_source` +Download task source. + +#### Internal API +
+`SYNO.DownloadStation2.Task.Source` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + + +
+#### Returns +
+`bytes` +Task source content. + +
+ + + +--- + + +### `get_task_list` +Get info from a task list containing the files to be downloaded. This is to be used after creating a task, and before starting the download. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_list_id_** `str` +List ID returned by create_task. + + +
+#### Returns +
+`dict[str, any]` +A dictionary containing a task list information. + +
@@ -73,6 +359,29 @@ This API is not documented yet. ### `create_task` +Create a new download task. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_url_** `str` +Download URL. + +**_destination_** `str` +Download destination. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -80,6 +389,29 @@ This API is not documented yet. ### `delete_task` +Delete a download task. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + +**_force_** `bool` +Force delete (default is False). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -87,6 +419,26 @@ This API is not documented yet. ### `pause_task` +Pause a download task. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -94,6 +446,26 @@ This API is not documented yet. ### `resume_task` +Resume a download task. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -101,6 +473,66 @@ This API is not documented yet. ### `edit_task` +Edit a download task. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_task_id_** `str or list[str]` +Task ID(s). + +**_destination_** `str` +New download destination (default is 'sharedfolder'). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
+ + + +--- + + +### `download_task_list` +Download files from a task list. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_list_id_** `str` +Task list ID. + +**_file_indexes_** `list[int]` +List of file indexes to download. +For example, if `get_task_list()` returns `files: [{index: 0, name: "file1.txt"}, {index: 1, name: "file2.txt"}]`, then `file_indexes = [1]` will download only file2.txt. + +**_destination_** `str` +Download destination, e.g. 'sharedfolder/subfolder' + +**_create_subfolder_** `bool` +Create subfolder. Defaults to `True` + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the task_id for the started download task. + +
@@ -108,6 +540,19 @@ This API is not documented yet. ### `get_statistic_info` +Get Download Station statistics. + +#### Internal API +
+`SYNO.DownloadStation.Statistic` +
+ +#### Returns +
+`dict[str, object] or str` +Statistics information. + +
@@ -115,6 +560,29 @@ This API is not documented yet. ### `get_rss_info_list` +Get RSS site info list. + +#### Internal API +
+`SYNO.DownloadStation.RSS.Site` +
+ +#### Parameters +
+**_offset_** `Optional[int]` +Offset for pagination. + +**_limit_** `Optional[int]` +Maximum number of RSS sites to retrieve. + + +
+#### Returns +
+`dict[str, object] or str` +RSS site info list. + +
@@ -122,6 +590,26 @@ This API is not documented yet. ### `refresh_rss_site` +Refresh an RSS site. + +#### Internal API +
+`SYNO.DownloadStation.RSS.Site` +
+ +#### Parameters +
+**_rss_id_** `Optional[str]` +RSS site ID. + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -129,6 +617,32 @@ This API is not documented yet. ### `rss_feed_list` +Get RSS feed list. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_rss_id_** `Optional[str]` +RSS site ID. + +**_offset_** `Optional[int]` +Offset for pagination. + +**_limit_** `Optional[int]` +Maximum number of RSS feeds to retrieve. + + +
+#### Returns +
+`dict[str, object] or str` +RSS feed list. + +
@@ -136,6 +650,29 @@ This API is not documented yet. ### `start_bt_search` +Start a BT search. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_keyword_** `Optional[str]` +Search keyword. + +**_module_** `str` +BT search module (default is 'all'). + + +
+#### Returns +
+`dict[str, object] or str` +BT search task information or message. + +
@@ -143,6 +680,44 @@ This API is not documented yet. ### `get_bt_search_results` +Get BT search results. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_taskid_** `Optional[str]` +BT search task ID. + +**_offset_** `Optional[int]` +Offset for pagination. + +**_limit_** `Optional[int]` +Maximum number of results to retrieve. + +**_sort_by_** `Optional[str]` +Field to sort by. + +**_sort_direction_** `Optional[str]` +Sort direction. + +**_filter_category_** `Optional[str]` +Filter by category. + +**_filter_title_** `Optional[str]` +Filter by title. + + +
+#### Returns +
+`dict[str, object] or str` +BT search results. + +
@@ -150,6 +725,19 @@ This API is not documented yet. ### `get_bt_search_category` +Get BT search categories. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Returns +
+`dict[str, object] or str` +BT search categories. + +
@@ -157,6 +745,26 @@ This API is not documented yet. ### `clean_bt_search` +Clean BT search tasks. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Parameters +
+**_taskid_** `Optional[str or list[str]]` +BT search task ID(s). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
@@ -164,6 +772,19 @@ This API is not documented yet. ### `get_bt_module` +Get BT search modules. + +#### Internal API +
+`SYNO.DownloadStation` +
+ +#### Returns +
+`dict[str, object] or str` +BT search modules. + +
diff --git a/documentation/docs/apis/classes/drive_admin_console.md b/documentation/docs/apis/classes/drive_admin_console.md index d385302d..64c94617 100644 --- a/documentation/docs/apis/classes/drive_admin_console.md +++ b/documentation/docs/apis/classes/drive_admin_console.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +Synology Drive Admin Console API implementation. +This class provides methods to retrieve and manage Synology Drive Admin Console status, +configuration, connections, logs, shares, and settings. ## Methods ### `status_info` +Get Synology Drive status information. + +#### Internal API +
+`SYNO.SynologyDrive` +
+ +#### Returns +
+`dict[str, object] or str` +Status information. + +
@@ -24,6 +40,19 @@ This API is not documented yet. ### `config_info` +Get Synology Drive configuration information. + +#### Internal API +
+`SYNO.SynologyDrive.Config` +
+ +#### Returns +
+`dict[str, object] or str` +Configuration information. + +
@@ -31,6 +60,19 @@ This API is not documented yet. ### `connections` +Get summary of Synology Drive connections. + +#### Internal API +
+`SYNO.SynologyDrive.Connection` +
+ +#### Returns +
+`dict[str, object] or str` +Connections summary. + +
@@ -38,6 +80,19 @@ This API is not documented yet. ### `drive_check_user` +Check user status in Synology Drive. + +#### Internal API +
+`SYNO.SynologyDrive` +
+ +#### Returns +
+`dict[str, object] or str` +User check result. + +
@@ -45,6 +100,19 @@ This API is not documented yet. ### `active_connections` +Get list of active Synology Drive connections. + +#### Internal API +
+`SYNO.SynologyDrive.Connection` +
+ +#### Returns +
+`dict[str, object] or str` +List of active connections. + +
@@ -52,6 +120,19 @@ This API is not documented yet. ### `active_sync_connections` +Get list of active Synology Drive ShareSync connections. + +#### Internal API +
+`SYNO.SynologyDriveShareSync.Connection` +
+ +#### Returns +
+`dict[str, object] or str` +List of active ShareSync connections. + +
@@ -59,6 +140,19 @@ This API is not documented yet. ### `share_active_list` +Get list of active shares in Synology Drive. + +#### Internal API +
+`SYNO.SynologyDrive.Share` +
+ +#### Returns +
+`dict[str, object] or str` +List of active shares. + +
@@ -66,6 +160,47 @@ This API is not documented yet. ### `log` +Get Synology Drive logs. + +#### Internal API +
+`SYNO.SynologyDrive.Log` +
+ +#### Parameters +
+**_share_type_** `str` +Type of share to filter logs (default is 'all'). + +**_get_all_** `bool` +Whether to get all logs (default is False). + +**_limit_** `int` +Maximum number of logs to return (default is 1000). + +**_keyword_** `str` +Keyword to filter logs (default is ''). + +**_date_from_** `int` +Start date in epoch format (default is 0). + +**_date_to_** `int` +End date in epoch format (default is 0). + +**_username_** `str` +Username to filter logs (default is ''). + +**_target_** `str` +Target type to filter logs (default is 'user'). + + +
+#### Returns +
+`dict[str, object] or str` +Log information. + +
@@ -73,6 +208,19 @@ This API is not documented yet. ### `c2fs_share` +Get list of C2FS shares. + +#### Internal API +
+`SYNO.C2FS.Share` +
+ +#### Returns +
+`dict[str, object] or str` +List of C2FS shares. + +
@@ -80,6 +228,19 @@ This API is not documented yet. ### `settings` +Get Synology Drive settings. + +#### Internal API +
+`SYNO.SynologyDrive.Settings` +
+ +#### Returns +
+`dict[str, object] or str` +Settings information. + +
@@ -87,6 +248,19 @@ This API is not documented yet. ### `db_usage` +Get Synology Drive database usage. + +#### Internal API +
+`SYNO.SynologyDrive.DBUsage` +
+ +#### Returns +
+`dict[str, object] or str` +Database usage information. + +
@@ -94,6 +268,19 @@ This API is not documented yet. ### `delete_status` +Get status of deleted nodes in Synology Drive. + +#### Internal API +
+`SYNO.SynologyDrive.Node.Delete` +
+ +#### Returns +
+`dict[str, object] or str` +Delete status information. + +
@@ -101,6 +288,19 @@ This API is not documented yet. ### `file_property_transfer_status` +Get file property transfer status for User Home migration. + +#### Internal API +
+`SYNO.SynologyDrive.Migration.UserHome` +
+ +#### Returns +
+`dict[str, object] or str` +File property transfer status. + +
@@ -108,6 +308,32 @@ This API is not documented yet. ### `user_sync_profile` +Get user sync profile(s). + +#### Internal API +
+`SYNO.SynologyDrive.Profiles` +
+ +#### Parameters +
+**_user_** `str` +Username to filter profiles (default is ''). + +**_start_** `int` +Start index for pagination (default is 0). + +**_limit_** `str or int` +Maximum number of profiles to return (default is 'null'). + + +
+#### Returns +
+`dict[str, object] or str` +User sync profile information. + +
@@ -115,6 +341,26 @@ This API is not documented yet. ### `index_pause` +Pause native client index for a specified duration. + +#### Internal API +
+`SYNO.SynologyDrive.Index` +
+ +#### Parameters +
+**_time_pause_** `int` +Pause duration in seconds (default is 60). + + +
+#### Returns +
+`dict[str, object] or str` +API response. + +
diff --git a/documentation/docs/apis/classes/event_scheduler.md b/documentation/docs/apis/classes/event_scheduler.md index ea44fdf7..af7bc4d9 100644 --- a/documentation/docs/apis/classes/event_scheduler.md +++ b/documentation/docs/apis/classes/event_scheduler.md @@ -13,14 +13,15 @@ Event Scheduler API implementation. This API provides functionality solely related to Event Tasks. For scheduled tasks, check `TaskScheduler`. -### Supported methods - -- **Getters** : +Methods +------- +**Getters** : - Get task results - Get result output -- **Setters** : - - Set task settings -- **Actions** : +**Setters** : + - Set task settings + - Set power schedule +**Actions** : - Enable task - Disable task - Run task @@ -82,33 +83,41 @@ A dictionary containing the task results. ### `get_result_output` Retrieve the output for a given result. -Parameters - ---------- - task_name : str - Name of the Event task to enable/disable. - result_id : int - ID of the result to retrieve. From `get_task_results()`. - Returns - ------- - dict[str, object] - A dictionary containing the result output. - Example return - -------------- - ```json - { - "data": { - "script_in": "hello", - "script_out": "/volume3/datastore/scripts_output/asd/1726190267/script.log: line 1: hello: command not found -" - }, - "success": true - } - ``` + #### Internal API
`SYNO.Core.EventScheduler`
+#### Parameters +
+**_task_name_** `str` +Name of the Event task to enable/disable. + +**_result_id_** `int` +ID of the result to retrieve. From get_task_results(). + + +
+#### Returns +
+`dict[str, object]` +A dictionary containing the result output. + +
+#### Example return +
+Click to expand +```json +{ + "data": { + "script_in": "hello", + "script_out": "/volume3/datastore/scripts_output/asd/1726190267/script.log: line 1: hello: command not found\n" + }, + "success": true +} +``` +
@@ -128,8 +137,8 @@ Enable or disable Event task. **_task_name_** `str` Name of the Event task to enable/disable. -**_enable (bool)_** `` -Wheter to enable (`True`) or disable (`False`) the task. +**_enable_** `bool` +Whether to enable (`True`) or disable (`False`) the task.
@@ -164,7 +173,7 @@ Run a specific Event task. #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` Name of the Event task to run. @@ -200,7 +209,7 @@ Delete a specific Event task. #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` Name of the Event task to run. @@ -211,6 +220,15 @@ Name of the Event task to run. A dictionary containing the result of the task deletion.
+#### Example return +
+Click to expand +```json +{ + "success": true +} +``` +
@@ -227,27 +245,27 @@ Create or modify an event-based task. #### Parameters
-**_action_** `str ` -Action to perform on the task. +**_action_** `str` +Action to perform on the task. Possible values: -- `create` -> Creates a new task. +- `create` -> Create a new task. - `set` -> Modify an existing task. -**_task_name_** `str ` +**_task_name_** `str` The name of the task. **_owner_** `dict[str, str]` -Dictionary containing the owner's ID and name (e.g., `{"1026": "user1"}`). -You can get the user UID by running `synouser --get your_user` in your NAS CLI. +Dictionary containing the owner's ID and name (e.g., `{"1026": "user1"}`). +You can get the user UID by running `synouser --get your_user` in your NAS CLI. For root privileges, pass `{"0":"root"}`. -**_trigger_event_** `str ` -The event that triggers the task. +**_trigger_event_** `str` +The event that triggers the task. Possible values: - `shutdown` - `bootup` -**_script_** `str ` +**_script_** `str` The script to be executed when the task is triggered. **_depend_on_task_** `list[str]` @@ -267,7 +285,7 @@ If `True`, notifications are only sent when an error occurs. Defaults to `False` #### Returns
`dict[str, object]` -A dictionary containing the result of the task creation or modification, or a strnig in case of an error. +A dictionary containing the result of the task creation or modification, or a string in case of an error.
#### Example return @@ -285,3 +303,111 @@ A dictionary containing the result of the task creation or modification, or a st --- +### `set_power_schedule` +Set the power schedule, poweron tasks and poweroff tasks. + +#### Internal API +
+`SYNO.Core.Hardware.PowerSchedule` +
+ +#### Parameters +
+**_poweron_tasks_** `List[dict]` +List of tasks for power on. Defaults to `[]`. +Example of a task: +```python +{ + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) +} +``` + +**_poweroff_tasks_** `List[dict]` +List of tasks for power off. Defaults to `[]`. +Example of a task: +```python +{ + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) +} +``` + + +
+#### Returns +
+`dict` +List of tasks in power schedule. + +
+#### Example return +
+Click to expand +```json +{ + "data": { + "poweroff_tasks": [], + "poweron_tasks": [ + { + "enabled": true, + "hour": 0, + "min": 0, + "weekdays": "1,2,3,4,5" + } + ] + }, + "success": true +} +``` +
+ + + +--- + + +### `load_power_schedule` +Load the power schedule, poweron tasks and poweroff tasks. + +#### Internal API +
+`SYNO.Core.Hardware.PowerSchedule` +
+ +#### Returns +
+`dict` +List of tasks in power schedule. + +
+#### Example return +
+Click to expand +```json +{ + "data": { + "poweroff_tasks": [], + "poweron_tasks": [ + { + "enabled": true, + "hour": 0, + "min": 0, + "weekdays": "1,2,3,4,5" + } + ] + }, + "success": true +} +``` +
+ + + +--- + + diff --git a/documentation/docs/apis/classes/filestation.md b/documentation/docs/apis/classes/filestation.md index 96575c8e..fbe2432c 100644 --- a/documentation/docs/apis/classes/filestation.md +++ b/documentation/docs/apis/classes/filestation.md @@ -14,9 +14,52 @@ This API is not documented yet. ::: ## Overview - +FileStation API implementation. + +Provides methods to interact with Synology NAS FileStation API for file and folder operations, +search, upload, download, and background task management. + +Parameters +---------- +ip_address : str + IP address of the Synology NAS. +port : str + Port number for the connection. +username : str + Username for authentication. +password : str + Password for authentication. +secure : bool, optional + Use HTTPS if True, HTTP otherwise. Default is False. +cert_verify : bool, optional + Verify SSL certificates if True. Default is False. +dsm_version : int, optional + DSM version of the Synology NAS. Default is 7. +debug : bool, optional + Enable debug output if True. Default is True. +otp_code : str, optional + One-time password for 2-step verification. Default is None. +device_id : str, optional + Device ID for authentication. Default is None. +device_name : str, optional + Name of the device. Default is None. +interactive_output : bool, optional + If True, enables interactive output. Default is False. ## Methods ### `get_info` +Get FileStation information. + +#### Internal API +
+`SYNO.FileStation.Info` +
+ +#### Returns +
+`dict[str, object] or str` +FileStation information or error message. + +
@@ -24,6 +67,41 @@ This API is not documented yet. ### `get_list_share` +List shared folders. + +#### Internal API +
+`SYNO.FileStation.List` +
+ +#### Parameters +
+**_additional_** `str or list of str` +Additional attributes to include. + +**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_onlywritable_** `bool` +If True, only writable shares are listed. + + +
+#### Returns +
+`dict[str, object] or str` +List of shared folders or error message. + +
@@ -31,6 +109,50 @@ This API is not documented yet. ### `get_file_list` +List files in a folder. + +#### Internal API +
+`SYNO.FileStation.List` +
+ +#### Parameters +
+**_folder_path_** `str` +Path to the folder. + +**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_pattern_** `str` +Pattern to filter files. + +**_filetype_** `str` +File type filter. + +**_goto_path_** `str` +Path to go to. + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`dict[str, object]` +List of files or error message. + +
@@ -38,6 +160,29 @@ This API is not documented yet. ### `get_file_info` +Get information about a file or files. + +#### Internal API +
+`SYNO.FileStation.List` +
+ +#### Parameters +
+**_path_** `str or list of str` +Path(s) to the file(s). + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`dict[str, object] or str` +File information or error message. + +
@@ -45,6 +190,68 @@ This API is not documented yet. ### `search_start` +Start a search task. + +#### Internal API +
+`SYNO.FileStation.Search` +
+ +#### Parameters +
+**_folder_path_** `str` +Path to the folder where the search will start. + +**_recursive_** `bool` +If True, the search will be recursive. + +**_pattern_** `str` +Pattern to search for. + +**_extension_** `str` +File extension to filter by. + +**_filetype_** `str` +File type filter. + +**_size_from_** `int` +Minimum file size. + +**_size_to_** `int` +Maximum file size. + +**_mtime_from_** `str or int` +Minimum modification time (Unix timestamp or formatted string). + +**_mtime_to_** `str or int` +Maximum modification time (Unix timestamp or formatted string). + +**_crtime_from_** `str or int` +Minimum creation time (Unix timestamp or formatted string). + +**_crtime_to_** `str or int` +Maximum creation time (Unix timestamp or formatted string). + +**_atime_from_** `str or int` +Minimum access time (Unix timestamp or formatted string). + +**_atime_to_** `str or int` +Maximum access time (Unix timestamp or formatted string). + +**_owner_** `str` +Owner filter. + +**_group_** `str` +Group filter. + + +
+#### Returns +
+`dict[str, object] or str` +Search task ID or error message. + +
@@ -52,6 +259,44 @@ This API is not documented yet. ### `get_search_list` +Get the results of a search task. + +#### Internal API +
+`SYNO.FileStation.Search` +
+ +#### Parameters +
+**_task_id_** `str` +Task ID of the search task. + +**_filetype_** `str` +File type filter. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_offset_** `int` +Offset for pagination. + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`dict[str, object] or str` +Search results or error message. + +
@@ -59,6 +304,26 @@ This API is not documented yet. ### `stop_search_task` +Stop a search task. + +#### Internal API +
+`SYNO.FileStation.Search` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the search task to stop. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -66,6 +331,19 @@ This API is not documented yet. ### `stop_all_search_task` +Stop all running search tasks. + +#### Internal API +
+`SYNO.FileStation.Search` +
+ +#### Returns +
+`str` +Confirmation message. + +
@@ -73,6 +351,41 @@ This API is not documented yet. ### `get_mount_point_list` +List mount points. + +#### Internal API +
+`SYNO.FileStation.VirtualFolder` +
+ +#### Parameters +
+**_mount_type_** `str` +Type of mount point to filter by. + +**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`dict[str, object] or str` +List of mount points or error message. + +
@@ -80,6 +393,38 @@ This API is not documented yet. ### `get_favorite_list` +List favorite files and folders. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_status_filter_** `str` +Status filter. + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`dict[str, object] or str` +List of favorites or error message. + +
@@ -87,6 +432,32 @@ This API is not documented yet. ### `add_a_favorite` +Add a file or folder to favorites. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Parameters +
+**_path_** `str` +Path to the file or folder. + +**_name_** `str` +Name for the favorite. + +**_index_** `int` +Index for the favorite. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -94,6 +465,26 @@ This API is not documented yet. ### `delete_a_favorite` +Delete a favorite. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Parameters +
+**_path_** `str` +Path to the favorite to delete. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -101,6 +492,19 @@ This API is not documented yet. ### `clear_broken_favorite` +Clear broken favorites. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -108,6 +512,29 @@ This API is not documented yet. ### `edit_favorite_name` +Edit the name of a favorite. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Parameters +
+**_path_** `str` +Path to the favorite. + +**_new_name_** `str` +New name for the favorite. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -115,6 +542,29 @@ This API is not documented yet. ### `replace_all_favorite` +Replace all favorites with new paths and names. + +#### Internal API +
+`SYNO.FileStation.Favorite` +
+ +#### Parameters +
+**_path_** `str or list of str` +New path or list of new paths for the favorites. + +**_name_** `str or list of str` +New name or list of new names for the favorites. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -122,6 +572,26 @@ This API is not documented yet. ### `start_dir_size_calc` +Start a directory size calculation task. + +#### Internal API +
+`SYNO.FileStation.DirSize` +
+ +#### Parameters +
+**_path_** `str` +Path to the directory. + + +
+#### Returns +
+`dict[str, object] or str` +Task ID or error message. + +
@@ -129,6 +599,26 @@ This API is not documented yet. ### `stop_dir_size_calc` +Stop a directory size calculation task. + +#### Internal API +
+`SYNO.FileStation.DirSize` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the size calculation task to stop. + + +
+#### Returns +
+`str` +Confirmation message. + +
@@ -136,6 +626,26 @@ This API is not documented yet. ### `get_dir_status` +Get the status of a directory size calculation task. + +#### Internal API +
+`SYNO.FileStation.DirSize` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the size calculation task. + + +
+#### Returns +
+`dict[str, object] or str` +Task status or error message. + +
@@ -143,6 +653,26 @@ This API is not documented yet. ### `start_md5_calc` +Start an MD5 calculation task. + +#### Internal API +
+`SYNO.FileStation.MD5` +
+ +#### Parameters +
+**_file_path_** `str` +Path to the file. + + +
+#### Returns +
+`str or dict[str, object]` +Task ID or error message. + +
@@ -150,6 +680,26 @@ This API is not documented yet. ### `get_md5_status` +Get the status of an MD5 calculation task. + +#### Internal API +
+`SYNO.FileStation.MD5` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the MD5 calculation task. + + +
+#### Returns +
+`str or dict[str, object]` +Task status or error message. + +
@@ -157,6 +707,26 @@ This API is not documented yet. ### `stop_md5_calc` +Stop an MD5 calculation task. + +#### Internal API +
+`SYNO.FileStation.DirSize` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the MD5 calculation task to stop. + + +
+#### Returns +
+`str` +Confirmation message. + +
@@ -164,6 +734,35 @@ This API is not documented yet. ### `check_permissions` +Check permissions for a file or folder. + +#### Internal API +
+`SYNO.FileStation.CheckPermission` +
+ +#### Parameters +
+**_path_** `str` +Path to the file or folder. + +**_filename_** `str` +Name of the file. + +**_overwrite_** `bool` +If True, overwriting is allowed. + +**_create_only_** `bool` +If True, only creation is allowed. + + +
+#### Returns +
+`dict[str, object] or str` +Permission check result or error message. + +
@@ -171,6 +770,41 @@ This API is not documented yet. ### `upload_file` +Upload a file to the server. + +#### Internal API +
+`SYNO.FileStation.Upload` +
+ +#### Parameters +
+**_dest_path_** `str` +Destination path on the server. + +**_file_path_** `str` +Path to the file to upload. + +**_create_parents_** `bool` +If True, parent folders will be created. + +**_overwrite_** `bool` +If True, existing files will be overwritten. + +**_verify_** `bool` +If True, SSL certificates will be verified. + +**_progress_bar_** `bool` +If True, shows a progress bar during upload. + + +
+#### Returns +
+`str or tuple[int, dict[str, object]]` +Upload result or error message. + +
@@ -178,6 +812,26 @@ This API is not documented yet. ### `get_shared_link_info` +Get information about a shared link. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Parameters +
+**_link_id_** `str` +ID of the shared link. + + +
+#### Returns +
+`dict[str, object] or str` +Shared link information or error message. + +
@@ -185,6 +839,38 @@ This API is not documented yet. ### `get_shared_link_list` +List shared links. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_force_clean_** `bool` +If True, forces a clean of the shared link list. + + +
+#### Returns +
+`dict[str, object] or str` +List of shared links or error message. + +
@@ -192,6 +878,38 @@ This API is not documented yet. ### `create_sharing_link` +Create a shared link. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Parameters +
+**_path_** `str` +Path to the file or folder to share. + +**_password_** `str` +Password for the shared link. + +**_date_expired_** `str or int` +Expiration date for the shared link (Unix timestamp or formatted string). + +**_date_available_** `str or int` +Availability date for the shared link (Unix timestamp or formatted string). + +**_expire_times_** `int` +Number of times the link can be accessed before expiring. + + +
+#### Returns +
+`dict[str, object] or str` +Shared link details or error message. + +
@@ -199,6 +917,26 @@ This API is not documented yet. ### `delete_shared_link` +Delete a shared link. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Parameters +
+**_link_id_** `str` +ID of the shared link to delete. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -206,6 +944,19 @@ This API is not documented yet. ### `clear_invalid_shared_link` +Clear invalid shared links. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -213,13 +964,74 @@ This API is not documented yet. ### `edit_shared_link` +Edit a shared link. + +#### Internal API +
+`SYNO.FileStation.Sharing` +
+ +#### Parameters +
+**_link_id_** `str` +ID of the shared link to edit. + +**_password_** `str` +New password for the shared link. + +**_date_expired_** `str or int` +New expiration date for the shared link (Unix timestamp or formatted string). + +**_date_available_** `str or int` +New availability date for the shared link (Unix timestamp or formatted string). + +**_expire_times_** `int` +New number of times the link can be accessed before expiring. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
--- -### `create_folder` +### `create_folder` +Create a new folder. + +#### Internal API +
+`SYNO.FileStation.CreateFolder` +
+ +#### Parameters +
+**_folder_path_** `str or list of str` +Path or list of paths where the folder should be created. + +**_name_** `str or list of str` +Name or list of names for the new folder. + +**_force_parent_** `bool` +If True, parent folders will be created if they don't exist. + +**_additional_** `str or list of str` +Additional attributes to include. + + +
+#### Returns +
+`str or dict[str, object]` +Creation result or error message. + +
@@ -227,6 +1039,35 @@ This API is not documented yet. ### `rename_folder` +Rename a folder. + +#### Internal API +
+`SYNO.FileStation.Rename` +
+ +#### Parameters +
+**_path_** `str or list of str` +Current path or list of paths of the folder(s) to rename. + +**_name_** `str or list of str` +New name or list of new names for the folder(s). + +**_additional_** `str or list of str` +Additional attributes to include. + +**_search_taskid_** `str` +Task ID of a search task. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -234,6 +1075,41 @@ This API is not documented yet. ### `start_copy_move` +Start a copy or move task. + +#### Internal API +
+`SYNO.FileStation.CopyMove` +
+ +#### Parameters +
+**_path_** `str or list of str` +Source path or list of source paths to copy or move. + +**_dest_folder_path_** `str or list of str` +Destination folder path or list of destination folder paths. + +**_overwrite_** `bool` +If True, existing files will be overwritten. + +**_remove_src_** `bool` +If True, source files will be removed after copying. + +**_accurate_progress_** `bool` +If True, shows accurate progress. + +**_search_taskid_** `str` +Task ID of a search task. + + +
+#### Returns +
+`str or dict[str, object]` +Task ID or error message. + +
@@ -241,6 +1117,26 @@ This API is not documented yet. ### `get_copy_move_status` +Get the status of a copy or move task. + +#### Internal API +
+`SYNO.FileStation.CopyMove` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the copy or move task. + + +
+#### Returns +
+`dict[str, object] or str` +Task status or error message. + +
@@ -248,6 +1144,26 @@ This API is not documented yet. ### `stop_copy_move_task` +Stop a copy or move task. + +#### Internal API +
+`SYNO.FileStation.CopyMove` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the copy or move task to stop. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -255,6 +1171,35 @@ This API is not documented yet. ### `start_delete_task` +Start a delete task. + +#### Internal API +
+`SYNO.FileStation.Delete` +
+ +#### Parameters +
+**_path_** `str or list of str` +Path or list of paths to the file or folder to delete. + +**_accurate_progress_** `bool` +If True, shows accurate progress. + +**_recursive_** `bool` +If True, deletes folders recursively. + +**_search_taskid_** `str` +Task ID of a search task. + + +
+#### Returns +
+`dict[str, object] or str` +Task ID or error message. + +
@@ -262,6 +1207,26 @@ This API is not documented yet. ### `get_delete_status` +Get the status of a delete task. + +#### Internal API +
+`SYNO.FileStation.Delete` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the delete task. + + +
+#### Returns +
+`dict[str, object] or str` +Task status or error message. + +
@@ -269,6 +1234,26 @@ This API is not documented yet. ### `stop_delete_task` +Stop a delete task. + +#### Internal API +
+`SYNO.FileStation.Delete` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the delete task to stop. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -276,6 +1261,32 @@ This API is not documented yet. ### `delete_blocking_function` +Delete a file or folder (blocking function). +This function will stop your script until done! Do not interrupt. +#### Internal API +
+`SYNO.FileStation.Delete` +
+ +#### Parameters +
+**_path_** `str or list of str` +Path or list of paths to the file or folder to delete. + +**_recursive_** `bool` +If True, deletes folders recursively. + +**_search_taskid_** `str` +Task ID of a search task. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -283,6 +1294,47 @@ This API is not documented yet. ### `start_extract_task` +Start an extract task. + +#### Internal API +
+`SYNO.FileStation.Extract` +
+ +#### Parameters +
+**_file_path_** `str` +Path to the archive file. + +**_dest_folder_path_** `str` +Destination folder path where the files will be extracted. + +**_overwrite_** `bool` +If True, existing files will be overwritten. + +**_keep_dir_** `bool` +If True, the original directory structure will be kept. + +**_create_subfolder_** `bool` +If True, a subfolder will be created for the extracted files. + +**_codepage_** `str` +Codepage for the extraction. + +**_password_** `str` +Password for the archive, if required. + +**_item_id_** `str` +Item ID for the extraction task. + + +
+#### Returns +
+`dict[str, object] or str` +Task ID or error message. + +
@@ -290,6 +1342,26 @@ This API is not documented yet. ### `get_extract_status` +Get the status of an extract task. + +#### Internal API +
+`SYNO.FileStation.Extract` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the extract task. + + +
+#### Returns +
+`dict[str, object] or str` +Task status or error message. + +
@@ -297,6 +1369,26 @@ This API is not documented yet. ### `stop_extract_task` +Stop an extract task. + +#### Internal API +
+`SYNO.FileStation.Extract` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the extract task to stop. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -304,6 +1396,47 @@ This API is not documented yet. ### `get_file_list_of_archive` +Get the list of files in an archive. + +#### Internal API +
+`SYNO.FileStation.Extract` +
+ +#### Parameters +
+**_file_path_** `str` +Path to the archive file. + +**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_codepage_** `str` +Codepage for the file list. + +**_password_** `str` +Password for the archive, if required. + +**_item_id_** `str` +Item ID for the archive. + + +
+#### Returns +
+`dict[str, object] or str` +List of files in the archive or error message. + +
@@ -311,6 +1444,41 @@ This API is not documented yet. ### `start_file_compression` +Start a file compression task. + +#### Internal API +
+`SYNO.FileStation.Compress` +
+ +#### Parameters +
+**_path_** `str or list of str` +Path or list of paths to the file or folder to compress. + +**_dest_file_path_** `str` +Destination file path for the compressed file. + +**_level_** `int` +Compression level. + +**_mode_** `str` +Compression mode. + +**_compress_format_** `str` +Compression format. + +**_password_** `str` +Password for the compressed file, if required. + + +
+#### Returns +
+`dict[str, object] or str` +Task ID or error message. + +
@@ -318,6 +1486,26 @@ This API is not documented yet. ### `get_compress_status` +Get the status of a file compression task. + +#### Internal API +
+`SYNO.FileStation.Compress` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the compression task. + + +
+#### Returns +
+`dict[str, object] or str` +Task status or error message. + +
@@ -325,6 +1513,26 @@ This API is not documented yet. ### `stop_compress_task` +Stop a file compression task. + +#### Internal API +
+`SYNO.FileStation.Compress` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID of the compression task to stop. + + +
+#### Returns +
+`dict[str, object] or str` +Response from the API or error message. + +
@@ -332,6 +1540,38 @@ This API is not documented yet. ### `get_list_of_all_background_task` +Get a list of all background tasks. + +#### Internal API +
+`SYNO.FileStation.BackgroundTask` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Limit for pagination. + +**_sort_by_** `str` +Field to sort by. + +**_sort_direction_** `str` +Sort direction ('asc' or 'desc'). + +**_api_filter_** `str` +API filter. + + +
+#### Returns +
+`dict[str, object] or str` +List of background tasks or error message. + +
@@ -339,6 +1579,38 @@ This API is not documented yet. ### `get_file` +Download a file from the server. + +#### Internal API +
+`SYNO.FileStation.Download` +
+ +#### Parameters +
+**_path_** `str` +Path to the file on the server. + +**_mode_** `str` +Mode for downloading the file ('open' to open in browser, 'download' to download to disk). + +**_dest_path_** `str` +Destination path on the local machine (for 'download' mode). + +**_chunk_size_** `int` +Chunk size for downloading. + +**_verify_** `bool` +If True, SSL certificates will be verified. + + +
+#### Returns +
+`Optional[str]` +None if successful, error message otherwise. + +
@@ -346,16 +1618,26 @@ This API is not documented yet. ### `generate_file_tree` -Generate the file tree based on the folder path you give, you need to create the root node before call this function - +Recursively generate the file tree based on the folder path you give constrained with. +You need to create the root node before calling this function. +#### Internal API +
+`hotfix` +
#### Parameters
**_folder_path_** `str` -Folder path to generate file tree +Folder path to generate file tree. **_tree_** `Tree` -Instance of the Tree of lib "Treelib" +Instance of the Tree from the `treelib` library. + +**_max_depth_** `int` +Non-negative number of maximum depth of tree generation if node tree is directory, default to '1' to generate full tree. If 'max_depth=0' it will be equivalent to no recursion. + +**_start_depth_** `int` +Non negative number to start to control tree generation default to '0'.
diff --git a/documentation/docs/apis/classes/log_center.md b/documentation/docs/apis/classes/log_center.md index f63ca313..0c92930b 100644 --- a/documentation/docs/apis/classes/log_center.md +++ b/documentation/docs/apis/classes/log_center.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +Interface for Synology Log Center API. +Provides methods to interact with log center features such as retrieving logs, +client status, remote archives, and storage settings. ## Methods ### `logcenter` +Retrieve the list of log center receive rules. + +#### Internal API +
+`SYNO.LogCenter.RecvRule` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the receive rules or an error message. + +
@@ -24,6 +40,19 @@ This API is not documented yet. ### `client_status_cnt` +Retrieve the count status from the syslog client. + +#### Internal API +
+`SYNO.Core.SyslogClient.Status` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the count status or an error message. + +
@@ -31,6 +60,19 @@ This API is not documented yet. ### `client_status_eps` +Retrieve the EPS (events per second) status from the syslog client. + +#### Internal API +
+`SYNO.Core.SyslogClient.Status` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the EPS status or an error message. + +
@@ -38,6 +80,19 @@ This API is not documented yet. ### `remote_log_archives` +Retrieve the list of remote log archive subfolders. + +#### Internal API +
+`SYNO.LogCenter.Log` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing remote archive subfolders or an error message. + +
@@ -45,6 +100,19 @@ This API is not documented yet. ### `display_logs` +Retrieve the list of logs from the syslog client. + +#### Internal API +
+`SYNO.Core.SyslogClient.Log` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the logs or an error message. + +
@@ -52,6 +120,19 @@ This API is not documented yet. ### `setting_storage_list` +Retrieve the log center storage settings. + +#### Internal API +
+`SYNO.LogCenter.Setting.Storage` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing storage settings or an error message. + +
@@ -59,6 +140,19 @@ This API is not documented yet. ### `registry_send_list` +Retrieve the list of log center client registry send settings. + +#### Internal API +
+`SYNO.LogCenter.Client` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing registry send settings or an error message. + +
@@ -66,6 +160,19 @@ This API is not documented yet. ### `history` +Retrieve the log center history. + +#### Internal API +
+`SYNO.LogCenter.History` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the log center history or an error message. + +
diff --git a/documentation/docs/apis/classes/notestation.md b/documentation/docs/apis/classes/notestation.md index 43064e8d..6231bf7b 100644 --- a/documentation/docs/apis/classes/notestation.md +++ b/documentation/docs/apis/classes/notestation.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +Interface for Synology NoteStation API. +Provides methods to interact with NoteStation features such as retrieving settings, +notebooks, tags, shortcuts, todos, smart notes, and individual notes. ## Methods ### `settings_info` +Retrieve NoteStation settings information. + +#### Internal API +
+`SYNO.NoteStation.Setting` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing settings information or an error message. + +
@@ -24,6 +40,19 @@ This API is not documented yet. ### `info` +Retrieve NoteStation general information. + +#### Internal API +
+`SYNO.NoteStation.Info` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing general information or an error message. + +
@@ -31,6 +60,19 @@ This API is not documented yet. ### `notebooks_info` +Retrieve the list of notebooks. + +#### Internal API +
+`SYNO.NoteStation.Notebook` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of notebooks or an error message. + +
@@ -38,6 +80,19 @@ This API is not documented yet. ### `tags_info` +Retrieve the list of tags. + +#### Internal API +
+`SYNO.NoteStation.Tag` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of tags or an error message. + +
@@ -45,6 +100,19 @@ This API is not documented yet. ### `shortcuts` +Retrieve the list of shortcuts. + +#### Internal API +
+`SYNO.NoteStation.Shortcut` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of shortcuts or an error message. + +
@@ -52,6 +120,19 @@ This API is not documented yet. ### `todo` +Retrieve the list of todo items. + +#### Internal API +
+`SYNO.NoteStation.Todo` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of todo items or an error message. + +
@@ -59,6 +140,19 @@ This API is not documented yet. ### `smart` +Retrieve the list of smart notes. + +#### Internal API +
+`SYNO.NoteStation.Smart` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of smart notes or an error message. + +
@@ -66,6 +160,19 @@ This API is not documented yet. ### `note_list` +Retrieve the list of notes. + +#### Internal API +
+`SYNO.NoteStation.Note` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the list of notes or an error message. + +
@@ -73,6 +180,26 @@ This API is not documented yet. ### `specific_note_id` +Retrieve a specific note by its ID. + +#### Internal API +
+`SYNO.NoteStation.Note` +
+ +#### Parameters +
+**_note_id_** `str or int` +The ID of the note to retrieve. + + +
+#### Returns +
+`dict[str, object] or str` +The API response containing the note data or an error message. + +
diff --git a/documentation/docs/apis/classes/oauth.md b/documentation/docs/apis/classes/oauth.md index dc3fc567..76b62aa5 100644 --- a/documentation/docs/apis/classes/oauth.md +++ b/documentation/docs/apis/classes/oauth.md @@ -14,9 +14,34 @@ This API is not documented yet. ::: ## Overview +Interface for Synology OAuth API. +Provides methods to interact with OAuth clients, tokens, and logs. ## Methods ### `clients` +Retrieve the list of OAuth clients. + +#### Internal API +
+`SYNO.OAUTH.Client` +
+ +#### Parameters +
+**_offset_** `int` +The starting index of the client list. Default is 0. + +**_limit_** `int` +The maximum number of clients to retrieve. Default is 20. + + +
+#### Returns +
+`dict[str, object] or str` +The API response containing the list of clients or an error message. + +
@@ -24,6 +49,29 @@ This API is not documented yet. ### `tokens` +Retrieve the list of OAuth tokens. + +#### Internal API +
+`SYNO.OAUTH.Token` +
+ +#### Parameters +
+**_offset_** `int` +The starting index of the token list. Default is 0. + +**_limit_** `int` +The maximum number of tokens to retrieve. Default is 20. + + +
+#### Returns +
+`dict[str, object] or str` +The API response containing the list of tokens or an error message. + +
@@ -31,6 +79,29 @@ This API is not documented yet. ### `logs` +Retrieve the list of OAuth logs. + +#### Internal API +
+`SYNO.OAUTH.Log` +
+ +#### Parameters +
+**_offset_** `int` +The starting index of the log list. Default is 0. + +**_limit_** `int` +The maximum number of logs to retrieve. Default is 20. + + +
+#### Returns +
+`dict[str, object] or str` +The API response containing the list of logs or an error message. + +
diff --git a/documentation/docs/apis/classes/photos.md b/documentation/docs/apis/classes/photos.md index 9e39cf9b..219c1c0e 100644 --- a/documentation/docs/apis/classes/photos.md +++ b/documentation/docs/apis/classes/photos.md @@ -14,9 +14,50 @@ This API is partially documented or under construction. ::: ## Overview - +Interface for Synology Photos API. + +Provides methods to interact with Photos features such as retrieving user info, +folders, albums, sharing, and items. + +Parameters +---------- +ip_address : str + The IP address or hostname of the Synology NAS. +port : str + The port number to connect to. +username : str + The username for authentication. +password : str + The password for authentication. +secure : bool, optional + Whether to use HTTPS. Default is False. +cert_verify : bool, optional + Whether to verify SSL certificates. Default is False. +dsm_version : int, optional + DSM version. Default is 7. +debug : bool, optional + Enable debug output. Default is True. +otp_code : str, optional + One-time password for 2FA, if required. +device_id : str, optional + Device ID for the session. +device_name : str, optional + Device name for the session. ## Methods ### `get_userinfo` +Retrieve user information for the current session. + +#### Internal API +
+`SYNO.Foto.UserInfo` +
+ +#### Returns +
+`Any` +The user information data. + +
@@ -24,6 +65,26 @@ This API is partially documented or under construction. ### `get_folder` +Retrieve information about a specific folder. + +#### Internal API +
+`SYNO.Foto.Browse.Folder` +
+ +#### Parameters +
+**_folder_id_** `int` +The ID of the folder. Default is 0. + + +
+#### Returns +
+`dict[str, object] or str` +The folder information or an error message. + +
@@ -31,6 +92,35 @@ This API is partially documented or under construction. ### `list_folders` +List folders in Personal Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_folder_id_** `int` +The parent folder ID. Default is 0. + +**_limit_** `int` +Maximum number of folders to return. Default is 1000. + +**_offset_** `int` +Number of folders to skip. Default is 0. + +**_additional_** `str or list of str` +Additional fields to include. + + +
+#### Returns +
+`dict[str, object] or str` +The list of folders or an error message. + +
@@ -38,6 +128,35 @@ This API is partially documented or under construction. ### `list_teams_folders` +List folders in Team Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_folder_id_** `int` +The parent folder ID. Default is 0. + +**_limit_** `int` +Maximum number of folders to return. Default is 2000. + +**_offset_** `int` +Number of folders to skip. Default is 0. + +**_additional_** `str or list of str` +Additional fields to include. + + +
+#### Returns +
+`dict[str, object] or str` +The list of team folders or an error message. + +
@@ -45,6 +164,26 @@ This API is partially documented or under construction. ### `count_folders` +Count folders in Personal Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_folder_id_** `int` +The parent folder ID. Default is 0. + + +
+#### Returns +
+`dict[str, object] or str` +The count of folders or an error message. + +
@@ -52,6 +191,26 @@ This API is partially documented or under construction. ### `count_team_folders` +Count folders in Team Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_folder_id_** `int` +The parent folder ID. Default is 0. + + +
+#### Returns +
+`dict[str, object] or str` +The count of team folders or an error message. + +
@@ -59,6 +218,26 @@ This API is partially documented or under construction. ### `lookup_folder` +Lookup a folder by path in Personal Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_path_** `str` +The folder path. + + +
+#### Returns +
+`dict[str, object] or str` +The folder information or None if not found. + +
@@ -66,6 +245,26 @@ This API is partially documented or under construction. ### `lookup_team_folder` +Lookup a folder by path in Team Space. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_path_** `str` +The folder path. + + +
+#### Returns +
+`dict[str, object] or str` +The folder information or None if not found. + +
@@ -73,6 +272,29 @@ This API is partially documented or under construction. ### `get_album` +Retrieve information about a specific album. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_album_id_** `str` +The album ID. + +**_additional_** `str or list of str` +Additional fields to include. + + +
+#### Returns +
+`dict[str, object] or str` +The album information or an error message. + +
@@ -80,6 +302,29 @@ This API is partially documented or under construction. ### `list_albums` +List albums. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_offset_** `int` +Number of albums to skip. Default is 0. + +**_limit_** `int` +Maximum number of albums to return. Default is 100. + + +
+#### Returns +
+`dict[str, object] or str` +The list of albums or an error message. + +
@@ -87,6 +332,32 @@ This API is partially documented or under construction. ### `suggest_condition` +Suggest album conditions based on a keyword. + +#### Internal API +
+`SYNO.Foto.Browse.ConditionAlbum` +
+ +#### Parameters +
+**_keyword_** `str` +The keyword to suggest conditions for. + +**_condition_** `list of str` +List of conditions to use. Default is ['general_tag']. + +**_user_id_** `str` +User ID to use. If None, uses the current user. + + +
+#### Returns +
+`dict[str, object] or str` +The suggested conditions or an error message. + +
@@ -94,6 +365,29 @@ This API is partially documented or under construction. ### `create_album` +Create a new album with the specified condition. + +#### Internal API +
+`SYNO.Foto.Browse.ConditionAlbum` +
+ +#### Parameters +
+**_name_** `str` +The name of the album. + +**_condition_** `list of str` +The condition for the album. + + +
+#### Returns +
+`dict[str, object] or str` +The API response for album creation. + +
@@ -101,6 +395,26 @@ This API is partially documented or under construction. ### `delete_album` +Delete an album by ID. + +#### Internal API +
+`SYNO.Foto.Browse.Album` +
+ +#### Parameters +
+**_album_id_** `str` +The album ID. + + +
+#### Returns +
+`dict[str, object] or str` +The API response for album deletion. + +
@@ -108,6 +422,29 @@ This API is partially documented or under construction. ### `set_album_condition` +Set the condition for an album. + +#### Internal API +
+`SYNO.Foto.Browse.ConditionAlbum` +
+ +#### Parameters +
+**_folder_id_** `int` +The folder ID. + +**_condition_** `list of str` +The condition to set. + + +
+#### Returns +
+`dict[str, object] or str` +The API response for setting the condition. + +
@@ -115,6 +452,35 @@ This API is partially documented or under construction. ### `share_album` +Share an album with specified permissions. + +#### Internal API +
+`SYNO.Foto.Sharing.Misc` +
+ +#### Parameters +
+**_album_id_** `str` +The album ID. + +**_permission_** `str or list of str` +Permissions to set. + +**_enabled_** `bool` +Whether sharing is enabled. Default is True. + +**_expiration_** `int or str` +Expiration time for the share. Default is 0. + + +
+#### Returns +
+`Any` +The API response for sharing the album. + +
@@ -122,6 +488,35 @@ This API is partially documented or under construction. ### `share_team_folder` +Share a team folder with specified permissions. + +#### Internal API +
+`SYNO.Foto.Sharing.Misc` +
+ +#### Parameters +
+**_folder_id_** `int` +The folder ID. + +**_permission_** `str` +Permissions to set. + +**_enabled_** `bool` +Whether sharing is enabled. Default is True. + +**_expiration_** `int or str` +Expiration time for the share. Default is 0. + + +
+#### Returns +
+`Any` +The API response for sharing the team folder. + +
@@ -129,6 +524,26 @@ This API is partially documented or under construction. ### `list_shareable_users_and_groups` +List users and groups that can be shared with. + +#### Internal API +
+`SYNO.Foto.Sharing.Misc` +
+ +#### Parameters +
+**_team_space_sharable_list_** `bool` +Whether to include team space sharable list. Default is False. + + +
+#### Returns +
+`dict[str, object] or str` +The list of users and groups or an error message. + +
@@ -136,7 +551,7 @@ This API is partially documented or under construction. ### `list_item_in_folders` -List all items in all folders in Personal Space +List all items in all folders in Personal Space. #### Internal API
@@ -148,36 +563,36 @@ List all items in all folders in Personal Space **_offset_** `int` Specify how many shared folders are skipped before beginning to return listed shared folders. -**_limit_** `int ` +**_limit_** `int` Number of shared folders requested. Set to `0` to list all shared folders. **_folder_id_** `int` -ID of folder +ID of folder. **_sort_by_** `str` -Possible values: -- `filename` -- `filesize` -- `takentime` -- `item_type` +Possible values: 'filename', 'filesize', 'takentime', 'item_type'. -**_sort_direction_** `str, optional ` -Possible values: `asc` or `desc`. Defaults to: `desc` +**_sort_direction_** `str` +Possible values: 'asc' or 'desc'. Defaults to: 'desc'. -**_passphrase_** `str` -Passphrase for a shared album +**_type_** `str` +Possible values: 'photo', 'video', 'live'. -**_additional_** `list[str]` -Possible values: -`["thumbnail","resolution", "orientation", "video_convert", "video_meta", "provider_user_id", "exif", "tag", "description", "gps", "geocoding_id", "address", "person"]` +**_passphrase_** `str` +Passphrase for a shared album. -**_type_** `str ` +**_additional_** `list` +Additional fields to include. Possible values: -- `photo`: Photo -- `video`: Video -- `live`: iPhone live photos' + `["thumbnail","resolution", "orientation", "video_convert", "video_meta", "provider_user_id", "exif", "tag", "description", "gps", "geocoding_id", "address", "person"]`. +
+#### Returns +
+`dict[str, object] or str` +The list of items or an error message. +
@@ -186,6 +601,19 @@ Possible values: ### `list_search_filters` +List available search filters. + +#### Internal API +
+`SYNO.Foto.Search.Filter` +
+ +#### Returns +
+`dict[str, object] or str` +The list of search filters or an error message. + +
@@ -193,6 +621,19 @@ Possible values: ### `get_guest_settings` +Retrieve guest settings for Photos. + +#### Internal API +
+`SYNO.Foto.Setting.Guest` +
+ +#### Returns +
+`dict[str, object] or str` +The guest settings or an error message. + +
diff --git a/documentation/docs/apis/classes/security_advisor.md b/documentation/docs/apis/classes/security_advisor.md index 742fe55c..a3bae6bd 100644 --- a/documentation/docs/apis/classes/security_advisor.md +++ b/documentation/docs/apis/classes/security_advisor.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +Interface for Synology Security Advisor API. +Provides methods to retrieve general info, scan results, checklists, +login activity, and configuration for Security Advisor. ## Methods ### `general_info` +Retrieve general information about Security Advisor location configuration. + +#### Internal API +
+`SYNO.SecurityAdvisor.Conf.Location` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing location configuration or an error message. + +
@@ -24,6 +40,19 @@ This API is not documented yet. ### `security_scan` +Retrieve the current security scan configuration. + +#### Internal API +
+`SYNO.Core.SecurityScan.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing security scan configuration or an error message. + +
@@ -31,6 +60,19 @@ This API is not documented yet. ### `checklist` +Retrieve the checklist for the Security Advisor. + +#### Internal API +
+`SYNO.SecurityAdvisor.Conf.Checklist` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing the checklist or an error message. + +
@@ -38,6 +80,29 @@ This API is not documented yet. ### `login_activity` +Retrieve login activity records. + +#### Internal API +
+`SYNO.SecurityAdvisor.LoginActivity` +
+ +#### Parameters +
+**_offset_** `int` +The starting index of the login activity list. Default is 0. + +**_limit_** `int` +The maximum number of records to retrieve. Default is 20. + + +
+#### Returns +
+`dict[str, object] or str` +The API response containing login activity records or an error message. + +
@@ -45,6 +110,19 @@ This API is not documented yet. ### `advisor_config` +Retrieve Security Advisor configuration. + +#### Internal API +
+`SYNO.SecurityAdvisor.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing advisor configuration or an error message. + +
@@ -52,6 +130,19 @@ This API is not documented yet. ### `scan_config` +Retrieve custom group enumeration for security scan configuration. + +#### Internal API +
+`SYNO.Core.SecurityScan.Conf` +
+ +#### Returns +
+`dict[str, object] or str` +The API response containing custom group enumeration or an error message. + +
diff --git a/documentation/docs/apis/classes/snapshot.md b/documentation/docs/apis/classes/snapshot.md index 9af830c4..fa3b6f97 100644 --- a/documentation/docs/apis/classes/snapshot.md +++ b/documentation/docs/apis/classes/snapshot.md @@ -14,20 +14,20 @@ Class for interacting with Snapshot Replication APIs. This class implements APIs to manage snapshots. There is no documentation for these APIs, so the implementation is based on network inspection. -### Supported methods +Methods +------- +**Getters** : + - Get all share/LUN snapshots + - Get all replications + - Get all LUNs - - **Getters** : - - Get all share/LUN snapshots - - Get all replications - - Get all LUNs +**Setters** : + - Set snapshot attributes - - **Setters** : - - Set snapshot attributes - - - **Actions** : - - Create share/LUN snapshot (WORM support only for share snaps ATM) - - Delete share/LUN snapshot - - Sync replication +**Actions** : + - Create share/LUN snapshot (WORM support only for share snaps ATM) + - Delete share/LUN snapshot + - Sync replication Examples -------- @@ -78,17 +78,14 @@ List snapshots for a share. Name of the share to list snapshots for. **_attribute_filter_** `list[str]` -List of attributes filter to apply. Defaults to `[]` (no filter). - -Each attribute filter is a string in the format of `"attr==value"` or `"attr=value"` and optionally prefixed with `!` to negate the filter. - +List of attributes filter to apply. Defaults to `[]` (no filter). +Each attribute filter is a string in the format of `"attr==value"` or `"attr=value"` and optionally prefixed with `!` to negate the filter. The following are examples of valid attribute filters: - `["!hide==true", "desc==abc"]` -> hide is not true and desc is exactly abc. - `["desc=abc"]` -> desc has abc in it. **_additional_attribute_** `list[str]` -List of snapshot attributes whose values are included in the response. Defaults to `[]` (only time is returned). - +List of snapshot attributes whose values are included in the response. Defaults to `[]` (only time is returned). Note that not all attributes are available via API. The following are confirmed to work: - `"desc"` - `"lock"` @@ -153,9 +150,8 @@ List snapshots for a LUN. UUID of the source LUN to list snapshots for. **_additional_** `list[str]` -Additional fields to retrieve. Specify `[]` to get only basic information. -Defaults to `["locked_app_keys", "is_worm_locked"]` - +Additional fields to retrieve. Specify `[]` to get only basic information. +Defaults to `["locked_app_keys", "is_worm_locked"]` Possible values: - `"locked_app_keys"` -> If snapshot is preserved by the system, the locking package key will be returned. - `"is_worm_locked"` -> Whether the snapshot is locked by WORM. @@ -235,7 +231,7 @@ Dictionary containing the LUN snapshots information. ### `list_luns` -List available LUNs +List available LUNs. #### Internal API
@@ -245,29 +241,25 @@ List available LUNs #### Parameters
**_types_** `list[str]` -Type of LUNS to retrieve. - - Defaults to `[ "BLOCK", "FILE", "THIN", "ADV", "SINK", "CINDER", "CINDER_BLUN", "CINDER_BLUN_THICK", "BLUN", "BLUN_THICK", "BLUN_SINK", "BLUN_THICK_SINK" ]`. - - Possible values: - - `"BLOCK"` - - `"FILE"` - - `"THIN"` - - `"ADV"` - - `"SINK"` - - `"CINDER"` - - `"CINDER_BLUN"` - - `"CINDER_BLUN_THICK"` - - `"BLUN"` - - `"BLUN_THICK"` - - `"BLUN_SINK"` - - `"BLUN_THICK_SINK"` +Type of LUNS to retrieve. +Defaults to `[ "BLOCK", "FILE", "THIN", "ADV", "SINK", "CINDER", "CINDER_BLUN", "CINDER_BLUN_THICK", "BLUN", "BLUN_THICK", "BLUN_SINK", "BLUN_THICK_SINK" ]`. +Possible values: +- `"BLOCK"` +- `"FILE"` +- `"THIN"` +- `"ADV"` +- `"SINK"` +- `"CINDER"` +- `"CINDER_BLUN"` +- `"CINDER_BLUN_THICK"` +- `"BLUN"` +- `"BLUN_THICK"` +- `"BLUN_SINK"` +- `"BLUN_THICK_SINK"` **_additional_info_** `list[str]` -Additional LUN information to include in the response. Specify `[]` to get only basic information. - -Defaults to `[ "is_action_locked", "is_mapped", "extent_size", "allocated_size", "status", "allow_bkpobj", "flashcache_status", "family_config", "snapshot_info" ]`. - +Additional LUN information to include in the response. Specify `[]` to get only basic information. +Defaults to `[ "is_action_locked", "is_mapped", "extent_size", "allocated_size", "status", "allow_bkpobj", "flashcache_status", "family_config", "snapshot_info" ]`. Possible values: - `"is_action_locked"` - `"is_mapped"` @@ -438,10 +430,8 @@ List replication plans. #### Parameters
**_additional_info_** `list[str]` -List of additional information to include in the response. Specify `[]` to get only basic information. - -Defaults to `["sync_policy", "sync_report", "main_site_info", "dr_site_info", "can_do", "op_info", "last_op_info", "topology", "testfailover_info", "retention_lock_report"]`. - +List of additional information to include in the response. Specify `[]` to get only basic information. +Defaults to `["sync_policy", "sync_report", "main_site_info", "dr_site_info", "can_do", "op_info", "last_op_info", "topology", "testfailover_info", "retention_lock_report"]`. Possible values: - `"sync_policy"` -> Information about the sync policy as schedule, retention, lock, etc. - `"sync_report"` -> Information about the previous runs and their results / error count. @@ -459,7 +449,7 @@ Possible values: #### Returns
`dict[str, object]` -API response if successful, error message if not +API response if successful, error message if not.
#### Example return @@ -790,7 +780,7 @@ Whether to lock the snapshot. Defaults to `False`. Whether to make the snapshot immutable. Defaults to `False`. **_immutable_days_** `int` -Number of days to make the snapshot immutable for. Defaults to `7`. +Number of days to make the snapshot immutable for. Defaults to `7`. Must be greater than `0`. Mandatory if immutable is `True`. @@ -819,12 +809,7 @@ API response if successful, error message if not. ### `delete_snapshots` Delete snapshots for a share. -:::warning - - This action removes data from the file system. Use with caution. - -::: - + #### Internal API
`SYNO.Core.Share.Snapshot` @@ -872,10 +857,10 @@ Set attributes for a snapshot. #### Parameters
**_share_name_** `str` -Name of the share to set attributes for +Name of the share to set attributes for. **_snapshot_** `str` -Name of the snapshot to set attributes for +Name of the snapshot to set attributes for. **_description_** `str` Description of the snapshot. Defaults to `None` (no change). @@ -901,7 +886,7 @@ API response if successful, error message if not. #### Example return
Click to expand -```json +```json { "success": true } @@ -937,7 +922,7 @@ Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. #### Returns
`dict[str, object]` -API response if successful +API response if successful.
#### Example return @@ -956,13 +941,8 @@ API response if successful ### `create_snapshot_lun` -Create a snapshot for a LUN. -:::note - - At the moment, it does not support creating WORM snapshots. - -::: - +Create a snapshot for a LUN. + #### Internal API
`SYNO.Core.ISCSI.LUN` @@ -971,7 +951,7 @@ Create a snapshot for a LUN. #### Parameters
**_lun_id_** `str` -ID of the LUN to create a snapshot for +ID of the LUN to create a snapshot for. **_description_** `str` Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. @@ -987,7 +967,7 @@ Whether to make the snapshot application aware. Defaults to `True`. #### Returns
`dict[str, object]` -API response if successful +API response if successful.
#### Example return @@ -1011,12 +991,7 @@ API response if successful ### `delete_snapshots_lun` Delete snapshots for a LUN. -:::warning - - This action removes data from the file system. Use with caution. - -::: - + #### Internal API
`SYNO.Core.ISCSI.LUN` @@ -1032,9 +1007,7 @@ List of UUIDs of the snapshots to delete. #### Returns
`dict[str, object]` -API response if successful. - -If deletion fails, an error code is returned alonside the snapshot uuid: +If deletion fails, an error code is returned alongside the snapshot uuid: ```json { "data": [ @@ -1044,7 +1017,8 @@ If deletion fails, an error code is returned alonside the snapshot uuid: ], "success": true } -``` +``` +API response if successful.
#### Example return diff --git a/documentation/docs/apis/classes/surveillancestation.md b/documentation/docs/apis/classes/surveillancestation.md index 53f23945..d9c70f32 100644 --- a/documentation/docs/apis/classes/surveillancestation.md +++ b/documentation/docs/apis/classes/surveillancestation.md @@ -14,9 +14,26 @@ This API is not documented yet. ::: ## Overview +API wrapper for Synology Surveillance Station. +Provides methods to interact with Surveillance Station features such as retrieving +station information and saving camera configurations. ## Methods ### `surveillance_station_info` +Retrieve information about the Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Info` +
+ +#### Returns +
+`dict[str, object] or str` +A dictionary containing Surveillance Station information, or a string +with error details if the request fails. + +
@@ -24,6 +41,104 @@ This API is not documented yet. ### `camera_save` +Save or update camera configuration. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_id_** `str` +Camera ID. + +**_name_** `str` +Camera name. + +**_dsld_** `int` +Device slot ID. + +**_newName_** `str` +New camera name. + +**_ip_** `str` +Camera IP address. + +**_port_** `int` +Camera port. + +**_vendor_** `str` +Camera vendor. + +**_model_** `str` +Camera model. + +**_userName_** `str` +Username for camera authentication. + +**_password_** `str` +Password for camera authentication. + +**_videoCodec_** `int` +Video codec type. + +**_audioCodec_** `int` +Audio codec type. + +**_tvStandard_** `int` +TV standard. + +**_channel_** `str` +Channel identifier. + +**_userDefinePath_** `str` +User-defined path. + +**_fov_** `str` +Field of view. + +**_streamXX_** `Any` +Stream configuration. + +**_recordTime_** `int` +Recording time. + +**_preRecordTime_** `int` +Pre-recording time. + +**_postRecordTime_** `int` +Post-recording time. + +**_enableRecordingKeepDays_** `bool` +Enable recording retention by days. + +**_recordingKeepDays_** `int` +Number of days to keep recordings. + +**_enableRecordingKeepSize_** `bool` +Enable recording retention by size. + +**_recordingKeepSize_** `int` +Maximum size for recordings. + +**_enableLowProfile_** `bool` +Enable low profile recording. + +**_recordSchedule_** `list of int` +Recording schedule. + +**_rtspPathTimeout_** `int` +RTSP path timeout. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
@@ -31,6 +146,53 @@ This API is not documented yet. ### `camera_list` +Retrieve a list of cameras from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of camera IDs to filter. + +**_offset_** `int` +The starting index for the camera list. + +**_limit_** `int` +The maximum number of cameras to return. + +**_blFromCamList_** `bool` +Whether to retrieve from the camera list. + +**_blIncludeDeletedCam_** `bool` +Whether to include deleted cameras. + +**_privCamType_** `str` +Filter by camera privilege type. + +**_basic_** `bool` +Whether to return only basic information. + +**_streamInfo_** `bool` +Whether to include stream information. + +**_blPrivilege_** `bool` +Whether to include privilege information. + +**_camStm_** `int` +Camera stream type. + + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing camera list information, or a string with error details. + +
@@ -38,20 +200,61 @@ This API is not documented yet. ### `get_camera_info` -This function return information about a camera. -cameraIds : This parameter is named cameraIds in the API documentation but it refer to 1 camera ID -privCamType: int = 1 - SYNO.SS.CamPriv.LIVEVIEW = 1; - SYNO.SS.CamPriv.PLAYBACK = 2; - SYNO.SS.CamPriv.LENS = 4; - SYNO.SS.CamPriv.AUDIO = 8; - SYNO.SS.CamPriv.DIGIOUT = 16; -All other parameters must be let to default value +Return information about a camera. + #### Internal API
`SYNO.SurveillanceStation.Camera`
+#### Parameters +
+**_cameraIds_** `int` +Camera ID. Although named cameraIds in the API, it refers to a single camera ID. + +**_privCamType_** `int, default=1` +Camera privilege type. Possible values: + 1: LIVEVIEW + 2: PLAYBACK + 4: LENS + 8: AUDIO + 16: DIGIOUT + +**_blIncludeDeletedCam_** `bool, default=True` +Whether to include deleted cameras. + +**_basic_** `bool, default=True` +Whether to return only basic information. + +**_streamInfo_** `bool, default=True` +Whether to include stream information. + +**_optimize_** `bool, default=True` +Whether to optimize the returned data. + +**_ptz_** `bool, default=True` +Whether to include PTZ (Pan-Tilt-Zoom) information. + +**_eventDetection_** `bool, default=True` +Whether to include event detection information. + +**_deviceOutCap_** `bool, default=True` +Whether to include device output capabilities. + +**_fisheye_** `bool, default=True` +Whether to include fisheye camera information. + +**_camAppInfo_** `bool, default=True` +Whether to include camera application information. + + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing camera information, or a string with error details. + +
@@ -59,6 +262,29 @@ All other parameters must be let to default value ### `camera_list_group` +Retrieve a list of camera groups from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_offset_** `int` +The starting index for the camera group list. + +**_limit_** `int` +The maximum number of camera groups to return. + + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing camera group information, or a string with error details. + +
@@ -66,13 +292,35 @@ All other parameters must be let to default value ### `get_snapshot` -By default, the profileType is 1, which is the default profile. -Binary data is returned, so the response is not a json object. +Retrieve a snapshot image from a camera. + #### Internal API
`SYNO.SurveillanceStation.Camera`
+#### Parameters +
+**_id_** `Any` +Camera identifier. + +**_name_** `str` +Camera name. + +**_dsld_** `int` +Device slot ID. + +**_profileType_** `int, default=1` +Profile type for the snapshot (1 is the default profile). + + +
+#### Returns +
+`str` +Binary data of the snapshot image. The response is not a JSON object. + +
@@ -80,6 +328,29 @@ Binary data is returned, so the response is not a json object. ### `enable_camera` +Enable one or more cameras by their IDs. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of camera IDs to enable. + +**_blIncludeDeletedCam_** `bool` +Whether to include deleted cameras in the operation. Default is False. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation as a dictionary, or a string with error details. + +
@@ -87,6 +358,29 @@ Binary data is returned, so the response is not a json object. ### `disable_camera` +Disable one or more cameras by their IDs. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of camera IDs to disable. + +**_blIncludeDeletedCam_** `bool` +Whether to include deleted cameras in the operation. Default is False. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the disable operation as a dictionary, or a string with error details. + +
@@ -94,6 +388,26 @@ Binary data is returned, so the response is not a json object. ### `get_capability_by_cam_id` +Retrieve the capability information for a specific camera by its ID. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera for which to retrieve capability information. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the camera's capability information, or a string with error details if the request fails. + +
@@ -101,6 +415,26 @@ Binary data is returned, so the response is not a json object. ### `count_occupied_size` +Retrieve the occupied storage size for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to retrieve the occupied size. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the occupied size information, or a string with error details if the request fails. + +
@@ -108,6 +442,26 @@ Binary data is returned, so the response is not a json object. ### `is_shortcut_valid` +Check if a camera shortcut is valid. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_cameraId_** `int` +The ID of the camera to validate the shortcut for. + + +
+#### Returns +
+`dict[str, object] or str` +A dictionary with the validation result, or a string with error details. + +
@@ -115,6 +469,26 @@ Binary data is returned, so the response is not a json object. ### `get_live_path` +Retrieve the live view path for one or more cameras. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera` +
+ +#### Parameters +
+**_idList_** `int` +Camera ID or comma-separated list of camera IDs for which to retrieve the live view path. + + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing the live view path information, or a string with error details. + +
@@ -122,2045 +496,9567 @@ Binary data is returned, so the response is not a json object. ### `audio_event_enum` +Enumerate audio events for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to enumerate audio events. + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing audio event enumeration, or a string with error details. - ---- +
-### `alarm_event_enum` +--- ---- +### `alarm_event_enum` +Enumerate alarm events for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to enumerate alarm events. + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing alarm event enumeration, or a string with error details. -### `md_parameter_save` +
--- -### `motion_event_enum` - +### `md_parameter_save` +Save motion detection parameters for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to save motion detection parameters. + +**_source_** `int` +The source channel or stream index. + +**_mode_** `int` +The motion detection mode. + +**_sensitivity_** `int` +Sensitivity level for motion detection. + +**_threshold_** `int` +Threshold value for motion detection. + +**_objectSize_** `int` +Minimum object size to trigger detection. + +**_percentage_** `int` +Minimum percentage of the detection area to trigger detection. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation as a dictionary, or a string with error details. ---- +
-### `motion_parameter_save` +--- ---- +### `motion_event_enum` +Enumerate motion events for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to enumerate motion events. + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing motion event enumeration, or a string with error details. -### `di_parameter_save` +
--- -### `alarm_sts_polling` - - - ---- +### `motion_parameter_save` +Save advanced motion detection parameters for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to save motion detection parameters. + +**_source_** `int` +The source channel or stream index. + +**_mode_** `int` +The motion detection mode. + +**_keep_** `bool` +Whether to keep the current settings. + +**_level_** `int` +Sensitivity level for advanced motion detection. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation as a dictionary, or a string with error details. -### `td_parameter_save` +
--- -### `enumerate_camera_group` - - - ---- +### `di_parameter_save` +Save digital input (DI) parameters for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to save DI parameters. + +**_idx_** `int` +The index of the DI channel. + +**_keep_** `bool` +Whether to keep the current DI settings. + +**_normal_** `int` +The normal state value for the DI channel. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation as a dictionary, or a string with error details. -### `save_specific_group` +
--- -### `delete_specific_groups` - - - ---- +### `alarm_sts_polling` +Poll the alarm status for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to poll alarm status. + +**_timeOut_** `int` +Timeout value for the polling operation. + +**_keep_** `Any` +Reserved for future use or additional options (currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing alarm status polling result, or a string with error details. -### `enumerate_group_information` +
--- -### `enumerate_camera_from_archive` - - - ---- +### `td_parameter_save` +Save tamper detection (TD) parameters for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Event` +
+ +#### Parameters +
+**_camId_** `int` +The ID of the camera for which to save tamper detection parameters. + +**_source_** `int` +The source channel or stream index. + +**_keep_** `Any` +Whether to keep the current settings (reserved for future use). + +**_duration_** `int` +Duration for the tamper detection event. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation as a dictionary, or a string with error details. -### `enumerate_archive_from_folder` +
--- -### `check_available_size_of_sdcard` - - - ---- +### `enumerate_camera_group` +Enumerate camera groups in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Group` +
+ +#### Parameters +
+**_privCamType_** `int` +Camera privilege type to filter groups. + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing camera group enumeration, or a string with error details. -### `check_licence_quota` +
--- -### `format_specific_sd_card` - +### `save_specific_group` +Save or update a specific camera group in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Group` +
+ +#### Parameters +
+**_groupList_** `Any` +The list of groups to be saved or updated. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation as a dictionary, or a string with error details. ---- +
-### `quick_create_single_camera` +--- ---- +### `delete_specific_groups` +Delete specific camera groups in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Group` +
+ +#### Parameters +
+**_Id_** `int` +The ID of the camera group to delete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation as a dictionary, or a string with error details. -### `move_camera_lens` +
--- -### `camera_lens_zoom` - +### `enumerate_group_information` +Enumerate group information for camera import in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Import` +
+ +#### Parameters +
+**_camServerId_** `int` +The ID of the camera server. + +**_shareName_** `str` +The name of the shared folder. + +**_archiveName_** `str` +The name of the archive. + +**_camlist_** `Any` +List of cameras to include. + +**_actFromHost_** `bool` +Whether the action is performed from the host. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the group information enumeration as a dictionary, or a string with error details. ---- +
-### `list_preset_ptz_camera` +--- ---- +### `enumerate_camera_from_archive` +Enumerate cameras from a specified archive in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Import` +
+ +#### Parameters +
+**_shareName_** `str` +The name of the shared folder containing the archive. + +**_archiveName_** `str` +The name of the archive to enumerate cameras from. + +**_serverId_** `int` +The ID of the server associated with the archive. + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing camera enumeration details, or a string with error details if the request fails. -### `move_camera_lens_to_preset_position` +
--- -### `list_patrol_cameras` - +### `enumerate_archive_from_folder` +Enumerate archives from a specified folder in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Import` +
+ +#### Parameters +
+**_shareName_** `str` +The name of the shared folder containing the archives. + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing archive enumeration details, or a string with error details if the request fails. ---- +
-### `force_cam_to_execute_patrol` +--- ---- +### `check_available_size_of_sdcard` +Check the available size of the SD card for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Wizard` +
+ +#### Parameters +
+**_camId_** `Any` +The ID of the camera. + +**_host_** `str` +The host address of the camera. + +**_port_** `str` +The port number for the camera connection. + +**_user_** `str` +The username for authentication. + +**_passw_** `str` +The password for authentication. + +**_vendor_** `str` +The vendor of the camera. + +**_model_** `str` +The model of the camera. + +**_ch_** `str` +The channel identifier. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the available size information, or a string with error details. -### `focus_camera` +
--- -### `control_camera_iris_in_out` +### `check_licence_quota` +Check the license quota for Surveillance Station cameras. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Wizard` +
+ +#### Returns +
+`dict[str, object] or str` +A dictionary containing license quota information, or a string with error details if the request fails. + +
--- -### `auto_focus` - +### `format_specific_sd_card` +Format the SD card of a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Wizard` +
+ +#### Parameters +
+**_camId_** `Any` +The ID of the camera whose SD card is to be formatted. + +**_host_** `str` +The host address of the camera. + +**_port_** `str` +The port number for the camera connection. + +**_user_** `str` +The username for authentication. + +**_passw_** `str` +The password for authentication. + +**_vendor_** `str` +The vendor of the camera. + +**_model_** `str` +The model of the camera. + +**_ch_** `str` +The channel identifier. + +**_timeout_** `int` +Timeout value for the formatting operation. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +A dictionary containing the result of the format operation, or a string with error details. ---- +
-### `move_cam_lens_to_absolute_position` +--- ---- +### `quick_create_single_camera` +Quickly create a single camera in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Wizard` +
+ +#### Parameters +
+**_camServerId_** `Any` +The ID of the camera server. + +**_actFromHost_** `bool` +Whether the action is performed from the host. + +**_camStreamingType_** `str` +The streaming type of the camera. + +**_camName_** `str` +The name of the camera. + +**_camIP_** `str` +The IP address of the camera. + +**_camPort_** `str` +The port number of the camera. + +**_camVendor_** `str` +The vendor of the camera. + +**_camModel_** `str` +The model of the camera. + +**_camMountType_** `int` +The mount type of the camera. + +**_camChannel_** `str` +The channel of the camera. + +**_camVideoType_** `str` +The video type of the camera. + +**_camAudioType_** `str` +The audio type of the camera. + +**_camSourcePath_** `str` +The source path for the camera stream. + +**_camUserName_** `str` +The username for camera authentication. + +**_camPassWord_** `str` +The password for camera authentication. (To be checked). + +
+#### Returns +
+`dict[str, object] or str` +Result of the quick create operation as a dictionary, or a string with error details. -### `move_cam_to_home_position` +
--- -### `auto_pan_camera` - +### `move_camera_lens` +Move the camera lens in a specified direction with an optional speed and move type. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control. + +**_direction_** `str` +The direction to move the lens (e.g., 'up', 'down', 'left', 'right'). + +**_speed_** `int` +The speed at which to move the lens. + +**_moveType_** `str` +The type of movement (reserved for future use, currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the move operation as a dictionary, or a string with error details. ---- +
-### `start_stop_object_tracking` +--- ---- +### `camera_lens_zoom` +Control the zoom function of a camera lens. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control. + +**_control_** `Any` +The zoom control command or value. + +**_moveType_** `str` +The type of movement (reserved for future use, currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the zoom operation as a dictionary, or a string with error details. -### `start_stop_external_recording` +
--- -### `query_event_list_by_filter` - +### `list_preset_ptz_camera` +List preset positions for a PTZ (Pan-Tilt-Zoom) camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the PTZ camera to list presets for. + +**_offset_** `int` +The starting index for the preset list. + +**_limit_** `int` +The maximum number of presets to return. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing the list of PTZ presets, or a string with error details. ---- +
-### `delete_recordings` +--- ---- +### `move_camera_lens_to_preset_position` +Move the camera lens to a specified preset position. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control. + +**_presetId_** `Any` +The ID of the preset position to move to. + +**_position_** `Any` +The position value for the preset. + +**_speed_** `Any` +The speed at which to move the lens. + +**_type_** `Any` +The type of movement or preset. + +**_isPatrol_** `bool` +Whether the movement is part of a patrol operation. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the move operation as a dictionary, or a string with error details. -### `delete_events_by_filter` +
--- -### `delete_all_recordings` - +### `list_patrol_cameras` +List patrols for a PTZ (Pan-Tilt-Zoom) camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the PTZ camera to list patrols for. + +**_offset_** `int` +The starting index for the patrol list. + +**_limit_** `int` +The maximum number of patrols to return. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing the list of PTZ patrols, or a string with error details. ---- +
-### `apply_settings_advance_tab` +--- ---- +### `force_cam_to_execute_patrol` +Force a camera to execute a specified patrol. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to execute the patrol. + +**_patrolId_** `Any` +The ID of the patrol to execute. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the patrol execution as a dictionary, or a string with error details. -### `count_by_number_of_event` +
--- -### `keep_event_play_alive` - +### `focus_camera` +Control the focus function of a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control. + +**_control_** `Any` +The focus control command or value. + +**_moveType_** `Any` +The type of movement (reserved for future use, currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the focus operation as a dictionary, or a string with error details. ---- +
-### `stop_recording_event` +--- ---- +### `control_camera_iris_in_out` +Control the iris (in/out) function of a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control. + +**_control_** `Any` +The iris control command or value. + +**_moveType_** `Any` +The type of movement (reserved for future use, currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the iris control operation as a dictionary, or a string with error details. -### `load_settings_in_advanced_tab` +
--- -### `lock_selected_event` - +### `auto_focus` +Perform an auto-focus operation on a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to auto-focus. + +
+#### Returns +
+`dict[str, object] or str` +Result of the auto-focus operation as a dictionary, or a string with error details. ---- +
-### `unlock_selected_event` +--- ---- +### `move_cam_lens_to_absolute_position` +Move the camera lens to an absolute position. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_posX_** `int` +The X coordinate for the absolute position. + +**_posY_** `int` +The Y coordinate for the absolute position. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the move operation as a dictionary, or a string with error details. -### `unlock_selected_filter_event` +
--- -### `lock_selected_recordings` - +### `move_cam_to_home_position` +Move the camera to its home position. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to move to the home position. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the move operation as a dictionary, or a string with error details. ---- +
-### `download_recordings` +--- ---- +### `auto_pan_camera` +Automatically pan the camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to auto-pan. + +**_moveType_** `str` +The type of movement (reserved for future use, currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the auto-pan operation as a dictionary, or a string with error details. -### `check_if_recording_playable` +
--- -### `play_specific_recording` +### `start_stop_object_tracking` +Start or stop object tracking for a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ` +
+ +#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control object tracking. + +**_moveType_** `str` +The type of movement (reserved for future use, currently not working). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the object tracking operation as a dictionary, or a string with error details. + +
--- -### `download_merged_recording_files` -Download the merged files of UTC time range recordings of target camera. -If there are different resolution or codec within UTC time range, the recordings will merge as much as possible -and downlod file will be a zip file. -This method will start a task which have keep-alive mechanism. -Use GetRangeExportProgress method to get newest progress and keep-alive. -After receiving progress 100, use OnRangeExportDone method to download exported recording within 1 -minutes. -If you want to cancel range export task, just do not send GetRangeExportProgress method or -OnRangeExportDone method. System will cleanup processed files itself. +### `start_stop_external_recording` +Start or stop external recording for a specified camera. + #### Internal API
-`SYNO.SurveillanceStation.Recording` +`SYNO.SurveillanceStation.ExternalRecording`
+#### Parameters +
+**_cameraId_** `Any` +The ID of the camera to control external recording. + +**_action_** `str` +The action to perform (e.g., 'start' or 'stop'). (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the external recording operation as a dictionary, or a string with error details. - ---- - - -### `get_newest_progress_keep_alive` +
--- -### `download_recording_from_target` -Response -MP4 or zip file data. -The response type can be found in fileExt of GetRangeExportProgress method response when progress 100. -Note -GetRangeExportProgress method must be sent within 1 minute after corresponding RangeExport method task -is completed, otherwise the exported recordings will be cleared. -2.3.11.20 API Error Code -Code Description -400 Execution failed. -401 Parameter invalid. -405 CMS server connection failed. -414 Some events not exist. -439 Too many items selected. +### `query_event_list_by_filter` +Query the event list by applying various filters. + #### Internal API
`SYNO.SurveillanceStation.Recording`
+#### Parameters +
+**_offset_** `int` +The starting index for the event list. + +**_limit_** `int` +The maximum number of events to return. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter events. + +**_fromTime_** `int` +Start time (timestamp) for filtering events. + +**_toTime_** `int` +End time (timestamp) for filtering events. + +**_dsld_** `int` +Device slot ID to filter events. + +**_mountId_** `int` +Mount ID to filter events. + + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing the filtered event list, or a string with error details. + +
--- -### `handle_load_event_export` +### `delete_recordings` +Delete specific recordings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_idList_** `int` +The ID or comma-separated list of IDs of the recordings to delete. + +**_dsld_** `int` +Device slot ID associated with the recordings. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation as a dictionary, or a string with error details. +
---- -### `check_name_export_event` - +--- ---- +### `delete_events_by_filter` +Delete events from Surveillance Station by applying various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_reason_** `str` +The reason for deleting the events. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter events. + +**_fromTime_** `Any` +Start time (timestamp) for filtering events. + +**_toTime_** `Any` +End time (timestamp) for filtering events. + +**_locked_** `int` +Whether to include locked events. + +**_evtSrcType_** `int` +Event source type. + +**_evtSrcId_** `int` +Event source ID. + +**_blIncludeSnapshot_** `bool` +Whether to include snapshots in the deletion. + +**_includeAllCam_** `bool` +Whether to include all cameras. + +**_from_end_** `int` +End index for the filter range. + +**_from_start_** `int` +Start index for the filter range. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation as a dictionary, or a string with error details. -### `get_camera_information_list` +
--- -### `check_destination_folder_availability` +### `delete_all_recordings` +Delete all recordings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the delete operation as a dictionary, or a string with error details. +
---- +--- -### `handle_save_event_export` +### `apply_settings_advance_tab` +Apply advanced settings in the Surveillance Station recording tab. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_rotateUnrecogCam_** `bool` +Whether to rotate unrecognized cameras. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the apply operation as a dictionary, or a string with error details. ---- +
-### `get_event_export_info_from_recording_server` +--- ---- +### `count_by_number_of_event` +Count the number of events by category, with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_offset_** `bool` +Whether to offset the results. + +**_limit_** `int` +The maximum number of results to return. + +**_reason_** `str` +The reason for filtering events. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter events. + +**_fromTime_** `int` +Start time (timestamp) for filtering events. + +**_toTime_** `int` +End time (timestamp) for filtering events. + +**_locked_** `int` +Whether to include locked events. + +**_evtSrcType_** `int` +Event source type. + +**_evtSrcId_** `int` +Event source ID. + +**_blIncludeSnapshot_** `bool` +Whether to include snapshots in the count. + +**_includeAllCam_** `bool` +Whether to include all cameras. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Dictionary containing the event count by category, or a string with error details. -### `load_event_mount` +
--- -### `redirect_webapi_to_target_ds` -webAPI Array of `webAPI_info` -Example: -`webAPI={"api": "SYNO.SurveillanceStation.AddOns", "version": 1, "method": -"List"}` +### `keep_event_play_alive` +Keep the event play session alive. + #### Internal API
-`SYNO.SurveillanceStation.CMS` +`SYNO.SurveillanceStation.Recording`
+#### Returns +
+`dict[str, object] or str` +Result of the keepalive operation as a dictionary, or a string with error details. - - ---- - - -### `modify_share_privilege` +
--- -### `apply_option_settings` +### `stop_recording_event` +Stop a recording event for the specified event IDs. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_idList_** `Any` +The ID or list of IDs of the events to stop recording. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the stop operation as a dictionary, or a string with error details. +
---- -### `get_cms_info` +--- +### `load_settings_in_advanced_tab` +Load settings from the advanced tab in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Returns +
+`dict[str, object] or str` +Dictionary containing the advanced settings, or a string with error details. ---- +
-### `get_log_recording_data_from_target_ds` +--- ---- +### `lock_selected_event` +Lock selected events by applying various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_reason_** `str` +The reason for locking the events. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter events. + +**_fromTime_** `int` +Start time (timestamp) for filtering events. + +**_toTime_** `int` +End time (timestamp) for filtering events. + +**_locked_** `int` +Whether to lock the events. + +**_evtSrcType_** `int` +Event source type. + +**_evtSrcId_** `int` +Event source ID. + +**_blIncludeSnapshot_** `bool` +Whether to include snapshots in the lock operation. + +**_includeAllCam_** `bool` +Whether to include all cameras. + +**_from_end_** `int` +End index for the filter range. + +**_from_start_** `int` +Start index for the filter range. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation as a dictionary, or a string with error details. -### `get_samba_service` +
--- -### `check_if_samba_on_and_rec_enabled` - +### `unlock_selected_event` +Unlock selected events by their IDs. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of event IDs to unlock. + +**_dsld_** `int` +Device slot ID associated with the events. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation as a dictionary, or a string with error details. ---- +
-### `get_encoded_single_image_of_camera` +--- ---- +### `unlock_selected_filter_event` +Unlock events by applying various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_reason_** `str` +The reason for unlocking the events. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter events. + +**_fromTime_** `int` +Start time (timestamp) for filtering events. + +**_toTime_** `int` +End time (timestamp) for filtering events. + +**_locked_** `int` +Whether to unlock only locked events. + +**_evtSrcType_** `int` +Event source type. + +**_evtSrcId_** `int` +Event source ID. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation as a dictionary, or a string with error details. -### `get_cms_status` +
--- -### `enable_smb_service` - +### `lock_selected_recordings` +Lock selected recordings by their IDs. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of recording IDs to lock. + +**_dsld_** `int` +Device slot ID associated with the recordings. + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation as a dictionary, or a string with error details. ---- +
-### `notify_slave_ds_to_disconnect` +--- ---- +### `download_recordings` +Download recordings by specifying recording ID and optional parameters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_id_** `int` +The ID of the recording to download. + +**_mountId_** `int` +The mount ID associated with the recording. + +**_offsetTimeMs_** `int` +Offset time in milliseconds for the download. + +**_playTimeMs_** `int` +Playback time in milliseconds for the download. + +
+#### Returns +
+`dict[str, object] or str` +The downloaded recording as a binary response, or a string with error details. -### `lock_recording_server_prevent_setting_change` +
--- -### `enable_ds_into_recording_server` - +### `check_if_recording_playable` +Check if a recording is playable by event ID and optional parameters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_eventId_** `int` +The event ID of the recording to check. + +**_chkDetail_** `bool` +Whether to check detailed information. + +**_mountId_** `int` +The mount ID associated with the recording. + +**_dsld_** `int` +Device slot ID. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the check as a dictionary, or a string with error details. ---- +
-### `unpair_recording_servers` +--- ---- +### `play_specific_recording` +Stream a specific recording from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_recordingId_** `int` +The ID of the recording to play. + +**_alertRecording_** `bool` +Whether the recording is an alert recording. + +**_mountId_** `int` +The mount ID associated with the recording. + +**_dsld_** `int` +Device slot ID. + +**_videoCodec_** `int` +Video codec to use for streaming. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Streaming information or error details. -### `get_free_memory_size` +
--- -### `handle_slave_ds` - - - ---- +### `download_merged_recording_files` +Download merged files of recordings within a UTC time range for a target camera. +If there are different resolutions or codecs within the time range, recordings will be merged as much as possible, +and the download file will be a zip file. +This method starts a task with a keep-alive mechanism. +Use GetRangeExportProgress to get the latest progress and keep-alive. +After receiving progress 100, use OnRangeExportDone to download the exported recording within 1 minute. +To cancel the export task, do not send GetRangeExportProgress or OnRangeExportDone; the system will clean up processed files. +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_camId_** `int` +The camera ID to export recordings from. + +**_fromTime_** `int` +Start UTC timestamp for the export range. + +**_toTime_** `int` +End UTC timestamp for the export range. + +**_fileName_** `str` +Name of the output file. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Task information for the export or error details. -### `get_target_ds_info` +
--- -### `logout_slave_ds` - - - ---- +### `get_newest_progress_keep_alive` +Get the latest progress of a range export task and keep the task alive. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording` +
+ +#### Parameters +
+**_dlid_** `int` +The download task ID. + +
+#### Returns +
+`dict[str, object] or str` +Progress information or error details. -### `pair_slave_ds` +
--- -### `login_slave_ds` -2.3.15.9 API Error Code -Code Description -400 Execution failed. -401 Invalid parameter. -415 message connect failed. +### `download_recording_from_target` +Download the exported recording file from a completed range export task. + #### Internal API
-`SYNO.SurveillanceStation.CMS.GetDsStatus` +`SYNO.SurveillanceStation.Recording`
+#### Parameters +
+**_dlid_** `int` +The download task ID. + +**_fileName_** `str` +Name of the file to download. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Downloaded file data or error details. - ---- - - -### `save_slave_ds` +
--- -### `load_slave_ds_list` - +### `handle_load_event_export` +Load exported event recordings with optional pagination. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_start_** `int` +The starting index for loading events. + +**_limit_** `bool` +The maximum number of events to load. + +
+#### Returns +
+`dict[str, object] or str` +Exported event information or error details. ---- +
-### `count_number_of_logs` +--- ---- +### `check_name_export_event` +Check if an export event name is valid or already exists. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_dsId_** `int` +The data source ID. + +**_name_** `int` +The name to check for the export event. + +**_share_** `str` +The share name associated with the export event. + +
+#### Returns +
+`dict[str, object] or str` +Result of the name check or error details. -### `clear_selected_logs` +
--- -### `get_information_log` - +### `get_camera_information_list` +Retrieve the list of camera information for event export. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_dslld_** `int` +The ID of the data source (recording server) to query cameras from. + +
+#### Returns +
+`dict[str, object] or str` +Camera information list or error details. ---- +
-### `get_advanced_settings_logs` +--- ---- +### `check_destination_folder_availability` +Check if the destination folder has enough available space for export. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_freeSize_** `int` +Required free size in bytes. + +**_startTime_** `int` +Start time of the export range (UTC timestamp). + +**_stopTime_** `int` +End time of the export range (UTC timestamp). + +**_camIdList_** `str` +Comma-separated list of camera IDs to check. + +
+#### Returns +
+`dict[str, object] or str` +Availability information or error details. -### `set_advanced_setting_logs` +
--- -### `load_license_data` - +### `handle_save_event_export` +Save an event export task with the specified parameters. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_name_** `str` +Name of the export task. + +**_srcDsId_** `int` +Source data source ID. + +**_dstDsId_** `int` +Destination data source ID. + +**_dstdir_** `str` +Destination directory for export. + +**_freesize_** `int` +Required free size in bytes. + +**_start_time_** `int` +Start time of the export range (UTC timestamp). + +**_stop_time_** `int` +End time of the export range (UTC timestamp). + +**_isoverwrite_** `int` +Whether to overwrite existing files (1 for true, 0 for false). + +**_camlistid_** `str` +Comma-separated list of camera IDs to export. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. ---- +
-### `check_license_quota` +--- ---- +### `get_event_export_info_from_recording_server` +Retrieve event export information from the recording server. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Export` +
+ +#### Parameters +
+**_start_time_** `int` +Start time of the export range (UTC timestamp). + +**_stop_time_** `int` +End time of the export range (UTC timestamp). + +**_camlistid_** `str` +Comma-separated list of camera IDs. + +
+#### Returns +
+`dict[str, object] or str` +Export information or error details. -### `get_http_video_stream` +
--- -### `save_action_rule` +### `load_event_mount` +Load event mount information for export. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Mount` +
+ +#### Returns +
+`dict[str, object] or str` +Mount information or error details. + +
--- -### `download_action_rule` - +### `redirect_webapi_to_target_ds` +Redirect a WebAPI request to a target DiskStation. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_dsId_** `int` +Target DiskStation ID. + +**_webAPI_** `Any` +WebAPI information to redirect (array of webAPI_info). + +
+#### Returns +
+`dict[str, object] or str` +Result of the redirect operation or error details. ---- +
-### `send_data_2_player` +--- ---- +### `modify_share_privilege` +Modify the share privilege settings in Surveillance Station CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_privSet_** `int` +Privilege set value. + +**_shareName_** `str` +Name of the share to modify. + +
+#### Returns +
+`dict[str, object] or str` +Result of the privilege modification or error details. -### `delete_all_histories_of_action_rule` +
--- -### `list_action_rules` - +### `apply_option_settings` +Apply option settings for Surveillance Station CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_central_auto_video_relay_** `bool` +Enable or disable central auto video relay. + +**_central_enable_** `bool` +Enable or disable central management. + +**_central_mode_** `str` +Set the central management mode. + +**_central_rec_mask_mode_** `bool` +Enable or disable central recording mask mode. + +**_central_rec_sync_time_** `bool` +Enable or disable central recording time synchronization. + +**_nvr_enable_** `bool` +Enable or disable NVR. + +**_nvr_lang_** `str` +Set the NVR language. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the apply operation or error details. ---- +
-### `disable_action_rules` +--- ---- +### `get_cms_info` +Retrieve CMS (Central Management System) information. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_isPolling_** `bool` +Whether to poll for CMS information. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +CMS information or error details. -### `enable_action_rules` +
--- -### `list_history_action_rules` - +### `get_log_recording_data_from_target_ds` +Retrieve log recording data from a target DiskStation. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_syncType_** `int` +Type of synchronization. + +**_syncTargetId_** `int` +ID of the target DiskStation for synchronization. + +**_limit_** `int` +Limit the number of records returned. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Log recording data or error details. ---- +
-### `delete_action_rule` +--- ---- - +### `get_samba_service` +Check if the Samba service is enabled on the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Returns +
+`dict[str, object] or str` +Samba service status or error details. -### `get_list_of_emaps` +
--- -### `get_specific_emaps_setting` - - - ---- - +### `check_if_samba_on_and_rec_enabled` +Check if Samba is enabled and recording is enabled on the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Returns +
+`dict[str, object] or str` +Status of Samba and recording or error details. -### `get_emap_image` +
--- -### `get_autorized_ds_token` - - - ---- +### `get_encoded_single_image_of_camera` +Retrieve an encoded single image (snapshot) from a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_camId_** `int` +ID of the camera to get the snapshot from. + +
+#### Returns +
+`dict[str, object] or str` +Encoded image data or error details. -### `set_message_event` +
--- -### `get_message_event` - - - ---- +### `get_cms_status` +Retrieve the status of the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_camId_** `int` +ID of the camera to check status for. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +CMS status or error details. -### `set_notification_sender_name` +
--- -### `get_notification_sender_name` - +### `enable_smb_service` +Enable the Samba service on the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. +
---- -### `set_advanced_notification_setting` +--- +### `notify_slave_ds_to_disconnect` +Notify a slave DiskStation to disconnect from the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the notification or error details. ---- +
-### `get_advanced_notification_setting` +--- ---- +### `lock_recording_server_prevent_setting_change` +Lock the recording server to prevent setting changes. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS` +
+ +#### Parameters +
+**_locked_** `bool` +Whether to lock the server. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation or error details. -### `send_test_mesg_to_primary_secondary_phone` +
--- -### `get_setting_notification_sms` - +### `enable_ds_into_recording_server` +Enable a DiskStation as a recording server in the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_adminUsername_** `str` +Administrator username. + +**_adminPasswd_** `str` +Administrator password. + +**_central_rec_mask_mode_** `str` +Central recording mask mode. + +**_central_rec_sync_time_** `str` +Central recording synchronization time. + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. ---- +
-### `set_sms_service_setting` +--- ---- +### `unpair_recording_servers` +Unpair recording servers from the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_adminUsername_** `str` +Administrator username. + +**_key_** `str` +Key for unpairing. + +**_mac_** `str` +MAC address of the server. + +**_cmsMode_** `int` +CMS mode. + +
+#### Returns +
+`dict[str, object] or str` +Result of the unpair operation or error details. -### `send_test_sms` +
--- -### `send_test_mail` +### `get_free_memory_size` +Retrieve the free memory size from the target DiskStation. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Returns +
+`dict[str, object] or str` +Free memory size information or error details. +
---- +--- -### `list_mobile_paired_devices` +### `handle_slave_ds` +Handle slave DiskStation operations such as locking or authentication. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_lock_** `bool` +Whether to lock the slave DiskStation. + +**_adminUsername_** `str` +Administrator username. + +**_key_** `str` +Authentication key. + +**_mac_** `str` +MAC address of the slave DiskStation. + +**_masterAuthKey_** `str` +Master authentication key. (To check). + +
+#### Returns +
+`dict[str, object] or str` +Result of the operation or error details. ---- +
-### `unpair_device` +--- ---- +### `get_target_ds_info` +Retrieve information about the target slave DiskStation. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_slaveDslp_** `str` +Slave DiskStation IP or identifier. + +
+#### Returns +
+`dict[str, object] or str` +Target DiskStation information or error details. -### `get_controller_access_schedule` +
--- -### `get_camera_alarm_schedule` - +### `logout_slave_ds` +Log out a slave DiskStation from the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_adminUsername_** `str` +Administrator username. + +**_key_** `str` +Authentication key. + +**_mac_** `str` +MAC address of the slave DiskStation. + +
+#### Returns +
+`dict[str, object] or str` +Result of the logout operation or error details. ---- +
-### `get_sys_dependent_schedule` +--- ---- +### `pair_slave_ds` +Pair a slave DiskStation with the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_dsname_** `str` +Name of the slave DiskStation. + +**_slaveDslp_** `str` +Slave DiskStation IP or identifier. + +**_port_** `int` +Port number for connection. + +**_masterAuthKey_** `str` +Master authentication key. + +**_model_** `str` +Model of the slave DiskStation. + +**_mac_** `str` +MAC address of the slave DiskStation. + +**_cms_locked_** `bool` +Whether the CMS is locked. + +**_cms_masked_** `bool` +Whether the CMS is masked. + +**_cms_sync_time_** `bool` +Synchronize time with CMS. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the pairing operation or error details. -### `set_batch_schedule` +
--- -### `get_access_ctrl_door_schedule` +### `login_slave_ds` +Log in a slave DiskStation to the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_adminUsername_** `str` +Administrator username. + +**_key_** `str` +Authentication key. + +**_mac_** `str` +MAC address of the slave DiskStation. + +**_masterAuthKey_** `str` +Master authentication key. + +**_hostName_** `str` +Hostname of the slave DiskStation. + +**_hostPort_** `int` +Port number for connection. + +**_ignoreAuthError_** `str` +Ignore authentication errors. + +**_hostDisconnect_** `bool` +Whether to disconnect the host. + +**_blUpdateVolSpace_** `bool` +Update volume space information. + +**_enable_rec_** `bool` +Enable recording. + +**_cms_locked_** `bool` +Whether the CMS is locked. + +**_cms_masked_** `bool` +Whether the CMS is masked. + +**_cms_sync_time_** `bool` +Synchronize time with CMS. (Currently not working). + +
+#### Returns +
+`dict[str, object] or str` +Result of the login operation or error details. +
---- -### `get_camera_schedule` +--- + + +### `save_slave_ds` +Save or update a slave DiskStation's configuration in the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.GetDsStatus` +
+ +#### Parameters +
+**_slavedsName_** `str` +Name of the slave DiskStation. + +**_slavedsModel_** `str` +Model of the slave DiskStation. + +**_slavedsPort_** `int` +Port number used by the slave DiskStation. + +**_slavedsVersion_** `str` +Version of the slave DiskStation. + +**_slavedsMaxCamNum_** `int` +Maximum number of cameras supported by the slave DiskStation. + +**_slavedsId_** `str` +Identifier for the slave DiskStation. + +**_slavedsIP_** `str` +IP address of the slave DiskStation. + +**_slavedsEnable_** `int` +Enable status of the slave DiskStation. + +**_slavedsCamCnt_** `bool` +Number of cameras currently connected to the slave DiskStation. + +**_adminUsername_** `str` +Administrator username for authentication. + +**_adminPasswd_** `str` +Administrator password for authentication. + +**_cms_locked_** `bool` +Whether the CMS is locked. + +**_cms_masked_** `bool` +Whether the CMS is masked. + +**_cms_sync_time_** `bool` +Synchronize time with CMS. (Currently not working). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `load_slave_ds_list` +Load the list of slave DiskStations from the CMS. + +#### Internal API +
+`SYNO.SurveillanceStation.CMS.SlavedsList` +
+ +#### Parameters +
+**_blNeedStatus_** `bool` +Whether to include status information. + +**_blGetSortInfo_** `bool` +Whether to include sorting information. + +**_blRuntimeInfo_** `bool` +Whether to include runtime information. + +**_dslds_** `str` +Comma-separated list of DiskStation IDs to load. + +**_sortInfo_** `int` +Sorting information. + + +
+#### Returns +
+`dict[str, object] or str` +List of slave DiskStations or error details. + +
+ + + +--- + + +### `count_number_of_logs` +Count the number of logs in Surveillance Station based on various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Log` +
+ +#### Parameters +
+**_slavedsName_** `str` +Name of the slave DiskStation. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of logs to count. + +**_level_** `str` +Log level filter. + +**_filterCamera_** `str` +Filter by camera. + +**_cameraIds_** `str` +Comma-separated list of camera IDs. + +**_dsfrom_** `int` +Start time (timestamp). + +**_to_** `int` +End time (timestamp). + +**_keyword_** `str` +Keyword to search in logs. + +**_keywordDsId_** `str` +DiskStation ID for keyword search. + +**_time2String_** `str` +Time string for filtering. + +**_dsId_** `str` +DiskStation ID. + +**_srcType_** `int` +Source type filter. + +**_timezoneOffset_** `int` +Timezone offset. + + +
+#### Returns +
+`dict[str, object] or str` +Count of logs or error details. + +
+ + + +--- + + +### `clear_selected_logs` +Clear selected logs from Surveillance Station based on various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Log` +
+ +#### Parameters +
+**_blClearAll_** `bool` +Whether to clear all logs. + +**_level_** `int` +Log level filter. + +**_dsId_** `int` +DiskStation ID. + +**_filterCamera_** `str` +Filter by camera. + +**_cameraIds_** `str` +Comma-separated list of camera IDs. + +**_dsfrom_** `int` +Start time (timestamp). + +**_to_** `int` +End time (timestamp). + +**_keyword_** `str` +Keyword to search in logs. + +**_keywordDsId_** `str` +DiskStation ID for keyword search. + +**_srcType_** `int` +Source type filter. + +**_timezoneOffset_** `int` +Timezone offset. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the clear operation or error details. + +
+ + + +--- + + +### `get_information_log` +Retrieve information logs from Surveillance Station based on various filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Log` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of logs to retrieve. + +**_level_** `str` +Log level filter. + +**_filterCamera_** `str` +Filter by camera. + +**_cameraIds_** `str` +Comma-separated list of camera IDs. + +**_dsfrom_** `int` +Start time (timestamp). + +**_to_** `int` +End time (timestamp). + +**_keyword_** `str` +Keyword to search in logs. + +**_keywordDsId_** `str` +DiskStation ID for keyword search. + +**_time2String_** `str` +Time string for filtering. + +**_dsId_** `int` +DiskStation ID. + +**_srcType_** `int` +Source type filter. + +**_all_** `bool` +Whether to retrieve all logs. + +**_blIncludeRecCnt_** `str` +Include recording count information. + +**_blIncludeAuInfo_** `str` +Include additional information. + + +
+#### Returns +
+`dict[str, object] or str` +List of information logs or error details. + +
+ + + +--- + + +### `get_advanced_settings_logs` +Retrieve advanced log settings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Log` +
+ +#### Returns +
+`dict[str, object] or str` +Advanced log settings or error details. + +
+ + + +--- + + +### `set_advanced_setting_logs` +Set advanced log settings in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Log` +
+ +#### Parameters +
+**_data_** `Any` +List of log type settings to apply. +Example: + data=\[\{"SSLogType":321912835,"enable":1\},\{"SSLogType":321912836,"enable":0\}\] + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `load_license_data` +Load license data from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.License` +
+ +#### Parameters +
+**_num_only_** `int` +If set, only the number of licenses will be returned. + + +
+#### Returns +
+`dict[str, object] or str` +License data or error details. + +
+ + + +--- + + +### `check_license_quota` +Check the license quota for cameras in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.License` +
+ +#### Parameters +
+**_camList_** `Any` +List of camera information dictionaries. +Example: + camList = \[\{"ip": "10.13.22.141", "model": "DCS-3110", "vendor": "DLink", "port": 80\}\] + +**_camServerId_** `int` +Camera server ID. + + +
+#### Returns +
+`dict[str, object] or str` +License quota information or error details. + +
+ + + +--- + + +### `get_http_video_stream` +Retrieve an HTTP video event stream from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Stream` +
+ +#### Parameters +
+**_writeHeader_** `bool` +Whether to include headers in the stream. + +**_analyevent_** `bool` +Whether to analyze events in the stream. + +**_mountId_** `int` +Mount ID for the stream. + + +
+#### Returns +
+`dict[str, object] or str` +Video stream data or error details. + +
+ + + +--- + + +### `save_action_rule` +Save or update an action rule in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_id_** `int` +Action rule ID. + +**_name_** `str` +Name of the action rule. + +**_ruleType_** `int` +Type of the rule. + +**_actType_** `int` +Action type. + +**_evtSrc_** `int` +Event source. + +**_evtDsId_** `int` +Event DiskStation ID. + +**_evtDevId_** `int` +Event device ID. + +**_evtId_** `int` +Event ID. + +**_evtItem_** `int` +Event item. + +**_evtMinIntvl_** `int` +Minimum interval between events. + +**_Actions_** `Any` +List of actions to perform. + +**_actSchedule_** `str` +Action schedule. + +**_Id_** `int` +Alternative action rule ID. + +**_actSrc_** `int` +Action source. + +**_actDsId_** `int` +Action DiskStation ID. + +**_actDevId_** `int` +Action device ID. + +**_actId_** `int` +Action ID. + +**_actTimes_** `int` +Number of times to perform the action. + +**_actTimeUnit_** `int` +Time unit for the action. + +**_actTimeDur_** `int` +Duration for the action. + +**_actItemId_** `int` +Action item ID. + +**_actRetPos_** `int` +Action return position. + +**_extUrl_** `str` +External URL for the action. + +**_userName_** `str` +Username for authentication. + +**_password_** `str` +Password for authentication. (Currently not working). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `download_action_rule` +Download the history of action rules from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Returns +
+`dict[str, object] or str` +Downloaded action rule history or error details. + +
+ + + +--- + + +### `send_data_2_player` +Send data to the Surveillance Station player. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the send operation or error details. + +
+ + + +--- + + +### `delete_all_histories_of_action_rule` +Delete all histories of specified action rules. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of action rule IDs to delete histories for. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `list_action_rules` +List action rules in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_start_** `str` +Start index for pagination. + +**_limit_** `int` +Maximum number of action rules to return. + + +
+#### Returns +
+`dict[str, object] or str` +List of action rules or error details. + +
+ + + +--- + + +### `disable_action_rules` +Disable specified action rules in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of action rule IDs to disable. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the disable operation or error details. + +
+ + + +--- + + +### `enable_action_rules` +Enable specified action rules in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of action rule IDs to enable. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. + +
+ + + +--- + + +### `list_history_action_rules` +List the history of action rules in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of history records to return. + + +
+#### Returns +
+`dict[str, object] or str` +List of action rule histories or error details. + +
+ + + +--- + + +### `delete_action_rule` +Delete specified action rules from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ActionRule` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of action rule IDs to delete. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `get_list_of_emaps` +Retrieve a list of eMaps from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Emap` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `str` +Maximum number of eMaps to return. + +**_emapIds_** `int` +Specific eMap IDs to retrieve. + +**_includeItems_** `int` +Whether to include items in the eMap. + + +
+#### Returns +
+`dict[str, object] or str` +List of eMaps or error details. + +
+ + + +--- + + +### `get_specific_emaps_setting` +Retrieve specific eMap settings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Emap` +
+ +#### Parameters +
+**_emapIds_** `int` +The ID(s) of the eMap(s) to retrieve settings for. + +**_includeImage_** `int` +Whether to include the eMap image in the response. + + +
+#### Returns +
+`dict[str, object] or str` +The eMap settings or error details. + +
+ + + +--- + + +### `get_emap_image` +Retrieve an eMap image from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Emap.Image` +
+ +#### Parameters +
+**_filename_** `str` +The filename of the eMap image to retrieve. + + +
+#### Returns +
+`dict[str, object] or str` +The eMap image data or error details. + +
+ + + +--- + + +### `get_autorized_ds_token` +Retrieve an authorized DiskStation token for notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Returns +
+`dict[str, object] or str` +The authorized token or error details. + +
+ + + +--- + + +### `set_message_event` +Set a customized message event in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Parameters +
+**_eventTypes_** `str` +The type(s) of event(s) to set the message for. + +**_subject_** `str` +The subject of the message. + +**_content_** `str` +The content of the message. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `get_message_event` +Retrieve a customized message event from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Parameters +
+**_eventTypes_** `int` +The type(s) of event(s) to retrieve the message for. + + +
+#### Returns +
+`dict[str, object] or str` +The message event data or error details. + +
+ + + +--- + + +### `set_notification_sender_name` +Set the sender name for Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Parameters +
+**_ss_pkg_name_** `str` +The sender name to set. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `get_notification_sender_name` +Retrieve the sender name for Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Returns +
+`dict[str, object] or str` +The sender name or error details. + +
+ + + +--- + + +### `set_advanced_notification_setting` +Set advanced notification settings in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Parameters +
+**_blSyncDSMNotify_** `bool` +Whether to synchronize DSM notifications. + +**_blCompactMsg_** `bool` +Whether to enable compact message format. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `get_advanced_notification_setting` +Retrieve advanced notification settings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification` +
+ +#### Returns +
+`dict[str, object] or str` +The advanced notification settings or error details. + +
+ + + +--- + + +### `send_test_mesg_to_primary_secondary_phone` +Send a test message to the primary and secondary phone numbers via SMS. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS` +
+ +#### Parameters +
+**_smsEnable_** `bool` +Whether SMS notifications are enabled. + +**_smsMethod_** `int` +The SMS sending method. + +**_smsProvider_** `str` +The SMS provider name. + +**_userName_** `str` +Username for SMS provider authentication. + +**_password_** `str` +Password for SMS provider authentication. + +**_confirmPassword_** `str` +Confirmation of the password. + +**_primaryPhoneCode_** `str` +Country code for the primary phone. + +**_primaryPhonePrefix_** `str` +Prefix for the primary phone. + +**_secondaryPhoneCode_** `str` +Country code for the secondary phone. + +**_secondaryPhonePrefix_** `str` +Prefix for the secondary phone. + +**_secondaryPhoneNumber_** `str` +The secondary phone number. + +**_setMinMessageInterval_** `bool` +Whether to set a minimum message interval. + +**_minMessageInterval_** `int` +The minimum interval between messages. + +**_hasSysSms_** `bool` +Whether system SMS is enabled. + +**_apiId_** `str` +The API ID for the SMS provider. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the test message operation or error details. + +
+ + + +--- + + +### `get_setting_notification_sms` +Retrieve the SMS notification settings from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS` +
+ +#### Returns +
+`dict[str, object] or str` +The SMS notification settings or error details. + +
+ + + +--- + + +### `set_sms_service_setting` +Set the SMS service settings for Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS` +
+ +#### Parameters +
+**_smsEnable_** `bool` +Whether SMS notifications are enabled. + +**_smsMethod_** `int` +The SMS sending method. + +**_smsProvider_** `str` +The SMS provider name. + +**_userName_** `str` +Username for SMS provider authentication. + +**_password_** `str` +Password for SMS provider authentication. + +**_confirmPassword_** `str` +Confirmation of the password. + +**_primaryPhoneCode_** `str` +Country code for the primary phone. + +**_primaryPhonePrefix_** `str` +Prefix for the primary phone. + +**_secondaryPhoneCode_** `str` +Country code for the secondary phone. + +**_secondaryPhonePrefix_** `str` +Prefix for the secondary phone. + +**_secondaryPhoneNumber_** `str` +The secondary phone number. + +**_setMinMessageInterval_** `bool` +Whether to set a minimum message interval. + +**_minMessageInterval_** `int` +The minimum interval between messages. + +**_hasSysSms_** `bool` +Whether system SMS is enabled. + +**_apiId_** `str` +The API ID for the SMS provider. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `send_test_sms` +Send a test SMS notification from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS` +
+ +#### Parameters +
+**_attachSnapshot_** `bool` +Whether to attach a snapshot to the SMS. + +**_enableInterval_** `bool` +Whether to enable message interval. + +**_mobileEnable_** `bool` +Whether to enable mobile notifications. + +**_msgInterval_** `str` +The interval between messages. + +**_primaryEmail_** `str` +The primary email address for notifications. + +**_secondaryEmail_** `str` +The secondary email address for notifications. + +**_synoMailEnable_** `bool` +Whether to enable Synology Mail notifications. + +**_mail_recipient_** `str` +The recipient of the test mail. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the test SMS operation or error details. + +
+ + + +--- + + +### `send_test_mail` +Send a test verification mail for Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.PushService` +
+ +#### Parameters +
+**_attachSnapshot_** `bool` +Whether to attach a snapshot to the email. + +**_enableInterval_** `bool` +Whether to enable message interval. + +**_mobileEnable_** `bool` +Whether to enable mobile notifications. + +**_msgInterval_** `str` +The interval between messages. + +**_primaryEmail_** `str` +The primary email address for notifications. + +**_secondaryEmail_** `str` +The secondary email address for notifications. + +**_synoMailEnable_** `bool` +Whether to enable Synology Mail notifications. + +**_mail_recipient_** `str` +The recipient of the test mail. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the test mail operation or error details. + +
+ + + +--- + + +### `list_mobile_paired_devices` +List mobile devices paired with Surveillance Station for push notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.PushService` +
+ +#### Parameters +
+**_attachSnapshot_** `bool` +Whether to attach a snapshot to the notification. + +**_enableInterval_** `bool` +Whether to enable message interval. + +**_mobileEnable_** `bool` +Whether to enable mobile notifications. + +**_msgInterval_** `str` +The interval between messages. + +**_primaryEmail_** `str` +The primary email address for notifications. + +**_secondaryEmail_** `str` +The secondary email address for notifications. + +**_synoMailEnable_** `bool` +Whether to enable Synology Mail notifications. + +**_mail_recipient_** `str` +The recipient of the notification. + + +
+#### Returns +
+`dict[str, object] or str` +List of paired mobile devices or error details. + +
+ + + +--- + + +### `unpair_device` +Unpair a mobile device from Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.PushService` +
+ +#### Parameters +
+**_targetIds_** `str` +The ID(s) of the device(s) to unpair. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the unpair operation or error details. + +
+ + + +--- + + +### `get_controller_access_schedule` +Retrieve the access control controller schedule from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_targetIds_** `str` +The ID(s) of the controllers to retrieve the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +The controller access schedule or error details. + +
+ + + +--- + + +### `get_camera_alarm_schedule` +Retrieve the alarm schedule for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_cameraId_** `int` +The ID of the camera. + +**_alarmdx_** `int` +Additional alarm parameter (to check). + + +
+#### Returns +
+`dict[str, object] or str` +The camera alarm schedule or error details. + +
+ + + +--- + + +### `get_sys_dependent_schedule` +Retrieve the system dependent schedule for Surveillance Station events. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_eventGroupTypes_** `int` +The type(s) of event groups to retrieve the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +The system dependent schedule or error details. + +
+ + + +--- + + +### `set_batch_schedule` +Set batch schedules for events, cameras, or camera groups. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_eventTypes_** `str` +The type(s) of events to schedule. + +**_schedule_** `Any` +The schedule data to apply. + +**_cameraIds_** `str` +The IDs of cameras to apply the schedule to. + +**_cameraGroupIds_** `str` +The IDs of camera groups to apply the schedule to. + +**_filter_** `int` +Additional filter parameter (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the batch schedule operation or error details. + +
+ + + +--- + + +### `get_access_ctrl_door_schedule` +Retrieve the access control door schedule from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_doorId_** `str` +The ID of the door to retrieve the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +The door schedule or error details. + +
+ + + +--- + + +### `get_camera_schedule` +Retrieve the schedule for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_cameraId_** `str` +The ID of the camera to retrieve the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +The camera schedule or error details. + +
+ + + +--- + + +### `set_sys_dependent_schedule` +Set the system dependent schedule for Surveillance Station events. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_eventType_** `int` +The type of event to set the schedule for. + +**_schedule_** `Any` +The schedule data to apply. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `set_controller_access_schedule` +Set the access control schedule for a controller or door. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_eventType_** `int` +The type of event to set the schedule for. + +**_schedule_** `Any` +The schedule data to apply. + +**_doorId_** `int` +The ID of the door to set the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `set_camera_schedule` +Set the schedule for a specific camera in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Schedule` +
+ +#### Parameters +
+**_eventType_** `int` +The type of event to set the schedule for. + +**_schedule_** `Any` +The schedule data to apply. + +**_cameraId_** `Any` +The ID of the camera to set the schedule for. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `get_notification_email_string` +Retrieve the notification email settings string from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Email` +
+ +#### Returns +
+`dict[str, object] or str` +The notification email settings or error details. + +
+ + + +--- + + +### `set_adv_tab_info_filter` +Set the advanced tab information filter for notification emails. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.Email` +
+ +#### Parameters +
+**_X_** `int` +The filter value to set (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `create_sms_service_provider` +Create a new SMS service provider for Surveillance Station notifications. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS.ServiceProvider` +
+ +#### Parameters +
+**_providerName_** `str` +The name of the SMS provider. + +**_providerPort_** `int` +The port used by the provider. + +**_providerUrl_** `str` +The URL of the provider. + +**_providerTemplate_** `str` +The message template for the provider. + +**_providerSepChar_** `str` +The separator character used by the provider. + +**_providerNeedSSL_** `bool` +Whether SSL is required for the provider. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the create operation or error details. + +
+ + + +--- + + +### `list_sms_provider` +List all SMS service providers configured in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS.ServiceProvider` +
+ +#### Returns +
+`dict[str, object] or str` +List of SMS providers or error details. + +
+ + + +--- + + +### `delete_sms_service_provider` +Delete an SMS service provider from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Notification.SMS.ServiceProvider` +
+ +#### Parameters +
+**_providerName_** `str` +The name of the SMS provider to delete. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `get_addson_to_update` +Retrieve information about add-ons that require updates in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Returns +
+`dict[str, object] or str` +Add-on update information or error details. + +
+ + + +--- + + +### `enable_specific_addon` +Enable a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to enable. + +**_servicename_** `str` +The name of the add-on service to enable. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. + +
+ + + +--- + + +### `get_specific_addon_update_info` +Retrieve update information for a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to check for updates. + + +
+#### Returns +
+`dict[str, object] or str` +Update information or error details. + +
+ + + +--- + + +### `get_specific_addon_info` +Retrieve information for a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to retrieve information for. + + +
+#### Returns +
+`dict[str, object] or str` +Add-on information or error details. + +
+ + + +--- + + +### `get_total_addon_info` +Retrieve information about all add-ons in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Returns +
+`dict[str, object] or str` +List of all add-ons or error details. + +
+ + + +--- + + +### `update_addon_package` +Update an add-on package in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to update. + +**_filePath_** `str` +The file path to the add-on package (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the update operation or error details. + +
+ + + +--- + + +### `check_addon_status` +Check the enable status of a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to check (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Status information or error details. + +
+ + + +--- + + +### `disable_addon` +Disable a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to disable. + +**_serviceName_** `str` +The name of the add-on service to disable (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the disable operation or error details. + +
+ + + +--- + + +### `set_addon_autoupdate` +Set the auto-update setting for a specific add-on in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AddOns` +
+ +#### Parameters +
+**_service_** `int` +The ID of the add-on service to configure. + +**_BlEnabled_** `Any` +Whether auto-update is enabled (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. + +
+ + + +--- + + +### `delete_specific_camera_recording_server` +Delete a specific camera recording server in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +List of camera IDs to delete from the recording server (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `get_camera_event_analytic` +Retrieve camera event analytics from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +List of camera IDs to retrieve analytics for (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Analytics data or error details. + +
+ + + +--- + + +### `delete_selected_events` +Delete selected events from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_dsIdList_** `str` +List of DS IDs for which to delete events. + +**_idList_** `str` +List of event IDs to delete (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `delete_specific_camera_events` +Delete events for specific cameras in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +List of camera IDs for which to delete events (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `get_analytic_history` +Retrieve analytic history for cameras in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +List of camera IDs to retrieve history for. + +**_typeListstring_** `str` +List of analytic types as a string (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Analytic history data or error details. + +
+ + + +--- + + +### `get_analytic_history_by_filter` +Retrieve analytic history for cameras by filter in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +List of camera IDs to filter. + +**_dsId_** `int` +The DS ID to filter. + +**_lock_** `int` +Lock status to filter. + +**_typeList_** `str` +List of analytic types as a string (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Filtered analytic history data or error details. + +
+ + + +--- + + +### `unklock_selected_events` +Unlock selected events in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_dsId_** `int` +The DS ID for which to unlock events. + +**_idList_** `str` +List of event IDs to unlock (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation or error details. + +
+ + + +--- + + +### `set_camera_analytic_trigger` +Trigger camera analytics for specified cameras in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_trigCamIdList_** `str` +List of camera IDs to trigger analytics for (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the trigger operation or error details. + +
+ + + +--- + + +### `flush_event_header` +Flush the header of a specific event in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_eventId_** `str` +The ID of the event to flush the header for (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the flush operation or error details. + +
+ + + +--- + + +### `lock_selected_events` +Lock selected events in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_dsId_** `int` +The DS ID for which to lock events. + +**_idList_** `str` +List of event IDs to lock (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation or error details. + +
+ + + +--- + + +### `get_analytic_event_from_rec_server` +Retrieve analytic event counts from the recording server for specified cameras. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert` +
+ +#### Parameters +
+**_camIdList_** `str` +Comma-separated list of camera IDs to query. + +**_idList_** `int` +Additional ID list parameter (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Analytic event count data or error details. + +
+ + + +--- + + +### `save_analytic_settings` +Save analytic settings for a specific camera. + +#### Internal API +
+`SYNO.SurveillanceStation.Alert.Setting` +
+ +#### Parameters +
+**_camId_** `int` +Camera ID to apply settings to. + +**_type_** `int` +Type of analytic. + +**_showFrame_** `bool` +Whether to display the frame. + +**_showLine_** `bool` +Whether to display lines. + +**_showVirtualFence_** `bool` +Whether to display virtual fences. + +**_beep_** `bool` +Whether to enable beep on event. + +**_sens_** `int` +Sensitivity setting. + +**_dwellTime_** `int` +Dwell time setting. + +**_direction_** `int` +Direction setting. + +**_objSize_** `int` +Object size setting. + +**_region_** `str` +Region definition (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `check_if_snapshot_exist` +Check if a snapshot exists for a given ID. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_id_** `int` +Snapshot ID to check (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Existence status or error details. + +
+ + + +--- + + +### `save_snapshot_modification` +Save modifications to a snapshot. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_id_** `int` +Snapshot ID to modify. + +**_createCopy_** `bool` +Whether to create a copy of the snapshot. + +**_width_** `int` +Width of the snapshot. + +**_height_** `int` +Height of the snapshot. + +**_byteSize_** `int` +Size of the snapshot in bytes. + +**_imageData_** `str` +Image data (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the modification or error details. + +
+ + + +--- + + +### `count_snapshot_by_category` +Count snapshots by category within a specified range. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_keyword_** `str` +Keyword to filter snapshots. + +**_dsfrom_** `int` +Start timestamp. + +**_to_** `int` +End timestamp. + +**_timezoneOffset_** `int` +Timezone offset. + +**_byteSize_** `int` +Size of the snapshot in bytes. + +**_imageData_** `str` +Image data (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Count data or error details. + +
+ + + +--- + + +### `check_any_locked_snapshot` +Check if any locked snapshots exist within a specified range. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_id_** `str` +Snapshot ID(s) to check. + +**_dsfrom_** `int` +Start timestamp. + +**_to_** `int` +End timestamp. + +**_keyword_** `str` +Keyword to filter snapshots (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Lock status or error details. + +
+ + + +--- + + +### `unlock_snapshot_by_filter` +Unlock snapshots by filter within a specified range. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_dsfrom_** `int` +Start timestamp. + +**_to_** `int` +End timestamp. + +**_keyword_** `str` +Keyword to filter snapshots (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation or error details. + +
+ + + +--- + + +### `list_snapshot_information` +List snapshot information with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_idList_** `str` +Comma-separated list of snapshot IDs. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_dsfrom_** `int` +Start timestamp. + +**_to_** `int` +End timestamp. + +**_keyword_** `str` +Keyword to filter snapshots. + +**_imgSize_** `int` +Image size filter. + +**_blIncludeAuInfo_** `bool` +Whether to include additional info. + +**_blIncludeRecCnt_** `bool` +Whether to include recording count. + +**_camId_** `int` +Camera ID filter (to check). + + +
+#### Returns +
+`dict[str, object] or str` +List of snapshot information or error details. + +
+ + + +--- + + +### `unlock_snapshot` +Unlock specific snapshots. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_objList_** `Any` +List of snapshot objects to unlock (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation or error details. + +
+ + + +--- + + +### `take_snapshot` +Take a snapshot for a specific camera and DS. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_dsId_** `int` +DS ID for the snapshot. + +**_camId_** `int` +Camera ID for the snapshot. + +**_blSave_** `bool` +Whether to save the snapshot (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the snapshot operation or error details. + +
+ + + +--- + + +### `get_snapshot_setting_function` +Retrieve the snapshot setting function. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Returns +
+`dict[str, object] or str` +Snapshot setting information or error details. + +
+ + + +--- + + +### `delete_snapshot_by_filter` +Delete snapshots by filter within a specified range. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_deleteAllCommand_** `bool` +Whether to delete all snapshots. + +**_dsfrom_** `int` +Start timestamp. + +**_to_** `int` +End timestamp. + +**_keyword_** `str` +Keyword to filter snapshots (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `get_snapshot_image` +Retrieve a snapshot image by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_id_** `int` +Snapshot ID to retrieve. + +**_imgSize_** `int` +Image size (to modify for download?). + + +
+#### Returns +
+`dict[str, object] or str` +Snapshot image data or error details. + +
+ + + +--- + + +### `lock_snapshot_image` +Lock specific snapshot images. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_objList_** `Any` +List of snapshot objects to lock. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation or error details. + +
+ + + +--- + + +### `downld_single_snapshot` +Download a single snapshot by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_id_** `int` +Snapshot ID to download (not working). + + +
+#### Returns +
+`dict[str, object] or str` +Download result or error details. + +
+ + + +--- + + +### `save_new_snapshot_setting` +Save new snapshot settings. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_dispSnapshot_** `bool` +Whether to display snapshots. + +**_dispDuration_** `int` +Display duration for snapshots. + +**_limitTotalSize_** `bool` +Whether to limit total snapshot size. + +**_limitSizeInGb_** `int` +Limit size in GB. + +**_addTimestamp_** `bool` +Whether to add a timestamp to snapshots. + +**_timestampPosition_** `int` +Position of the timestamp. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `save_snapshot` +Save a new snapshot. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_camName_** `str` +Name of the camera. + +**_createdTm_** `int` +Creation timestamp. + +**_width_** `int` +Width of the snapshot. + +**_height_** `int` +Height of the snapshot. + +**_byteSize_** `int` +Size of the snapshot in bytes. + +**_imageData_** `str` +Image data (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `check_snapshot_status` +Check the status of snapshot display. + +#### Internal API +
+`SYNO.SurveillanceStation.SnapShot` +
+ +#### Parameters +
+**_dispSnapshot_** `bool` +Whether to display snapshots. + + +
+#### Returns +
+`dict[str, object] or str` +Status information or error details. + +
+ + + +--- + + +### `enable_visualstation` +Enable VisualStation devices. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vslist_** `str` +Comma-separated list of VisualStation IDs to enable (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. + +
+ + + +--- + + +### `update_vs_network_config` +Update the network configuration for a VisualStation device. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vsMAc_** `str` +MAC address of the VisualStation. + +**_ip_** `str` +IP address to assign. + +**_mask_** `str` +Subnet mask. + +**_gateway_** `str` +Gateway address. + +**_blDhcp_** `bool` +Whether to use DHCP. + +**_name_** `str` +Name of the VisualStation (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the update operation or error details. + +
+ + + +--- + + +### `lock_visualstation_by_id` +Lock VisualStation devices by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vslist_** `str` +Comma-separated list of VisualStation IDs to lock (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation or error details. + +
+ + + +--- + + +### `enumerate_vs_owner_info` +Enumerate VisualStation owner information. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Returns +
+`dict[str, object] or str` +Owner information or error details. + +
+ + + +--- + + +### `unlock_visualstation_by_id` +Unlock VisualStation devices by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vslist_** `str` +Comma-separated list of VisualStation IDs to unlock (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation or error details. + +
+ + + +--- + + +### `disable_visualstation_by_id` +Disable VisualStation devices by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vslist_** `str` +Comma-separated list of VisualStation IDs to disable (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the disable operation or error details. + +
+ + + +--- + + +### `delete_specific_visualstation` +Delete specific VisualStation devices by ID. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation` +
+ +#### Parameters +
+**_vslist_** `str` +Comma-separated list of VisualStation IDs to delete (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `enumerate_layout_visualstation` +Enumerate VisualStation layouts. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Layout` +
+ +#### Parameters +
+**_vsId_** `int` +VisualStation ID to filter layouts (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Layout information or error details. + +
+ + + +--- + + +### `save_layout_information` +Save layout information for a VisualStation. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Layout` +
+ +#### Parameters +
+**_id_** `int` +Layout ID. + +**_vsId_** `int` +VisualStation ID. + +**_name_** `str` +Name of the layout. + +**_canGrpId_** `int` +Camera group ID. + +**_isDefault_** `int` +Whether this is the default layout. + +**_isFixAspectRatio_** `int` +Whether to fix the aspect ratio. + +**_layoutType_** `int` +Type of the layout. + +**_channelList_** `Any` +List of channels in the layout. + +**_customPosList_** `str` +Custom position list (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
+ + + +--- + + +### `delete_layout_visualstation` +Delete a VisualStation layout. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Layout` +
+ +#### Parameters +
+**_id_** `int` +Layout ID to delete. + +**_vsId_** `int` +VisualStation ID (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. + +
+ + + +--- + + +### `clear_visualstation_search_result` +Clear VisualStation search results. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Search` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the clear operation or error details. + +
+ + + +--- + + +### `get_visualstation_ip_info` +Retrieve VisualStation IP information. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Search` +
+ +#### Parameters +
+**_ip_** `int` +IP address to search for (to check). + + +
+#### Returns +
+`dict[str, object] or str` +IP information or error details. + +
+ + + +--- + + +### `stop_previous_visualstation_search` +Stop the previous VisualStation search operation. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Search` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the stop operation or error details. + +
--- -### `set_sys_dependent_schedule` +### `get_visualstation_list` +Retrieve the list of VisualStation devices. + +#### Internal API +
+`SYNO.SurveillanceStation.VisualStation.Layout` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination (to check). + + +
+#### Returns +
+`dict[str, object] or str` +List of VisualStation devices or error details. + +
--- -### `set_controller_access_schedule` +### `get_number_of_controller` +Get the number of controllers in the system. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Returns +
+`dict[str, object] or str` +Number of controllers or error details. + +
--- -### `set_camera_schedule` +### `get_cardholder_count` +Get the count of cardholders, optionally filtered by keyword. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_filterKeyword_** `str` +Keyword to filter cardholders. + +
+#### Returns +
+`dict[str, object] or str` +Cardholder count or error details. +
---- -### `get_notification_email_string` +--- +### `enum_all_controllers_logger` +Enumerate all controller logger configurations. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Returns +
+`dict[str, object] or str` +Logger configuration information or error details. ---- +
-### `set_adv_tab_info_filter` +--- ---- +### `get_cardholder_photo` +Retrieve a cardholder's photo. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_photo_name_** `str` +Name of the photo file. + +**_isRedirectCgi_** `bool` +Whether to redirect to CGI for the photo (to check). + +
+#### Returns +
+`dict[str, object] or str` +Photo data or error details. -### `create_sms_service_provider` +
--- -### `list_sms_provider` - +### `get_log_count` +Get the count of logs with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_filterType_** `int` +Type of filter to apply. + +**_filterEventSource_** `Any` +Event source filter. + +**_filterSource_** `int` +Source filter. + +**_filterEventSourceItem_** `int` +Event source item filter. + +**_filterTimeFrom_** `int` +Start time for filtering. + +**_filterTimeTo_** `int` +End time for filtering. + +**_filterKeyword_** `str` +Keyword to filter logs. + +**_timezoneOffset_** `int` +Timezone offset. + +**_doorIds_** `str` +Door IDs filter. + +**_eventTypes_** `str` +Event types filter. + +**_update_** `int` +Update flag. + +
+#### Returns +
+`dict[str, object] or str` +Log count or error details. ---- +
-### `delete_sms_service_provider` +--- ---- +### `get_cardholder_info` +Retrieve cardholder information with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_filterKeyword_** `str` +Keyword to filter cardholders. + +**_filterStatus_** `int` +Status filter. + +**_filterCtrlerId_** `int` +Controller ID filter. + +
+#### Returns +
+`dict[str, object] or str` +Cardholder information or error details. -### `get_addson_to_update` +
--- -### `enable_specific_addon` - +### `retrieve_last_access_credential` +Retrieve the last access credential for a controller. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_ctrlerId_** `int` +Controller ID. + +**_idPtId_** `int` +ID/point ID (to check). + +
+#### Returns +
+`dict[str, object] or str` +Last access credential information or error details. ---- +
-### `get_specific_addon_update_info` +--- ---- +### `enable_disable_controller` +Enable or disable controllers. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_blEnable_** `bool` +Whether to enable (True) or disable (False) controllers. + +**_arrayJson_** `str` +JSON array of controller IDs. + +
+#### Returns +
+`dict[str, object] or str` +Result of the operation or error details. -### `get_specific_addon_info` +
--- -### `get_total_addon_info` - +### `acknowledge_all_alarm_level_log` +Acknowledge all alarm level logs with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_filterEventSource_** `Any` +Event source filter. + +**_filterSource_** `int` +Source filter. + +**_filterEventSourceItem_** `str` +Event source item filter. + +**_filterTimeFrom_** `int` +Start time for filtering. + +**_filterKeyword_** `str` +Keyword to filter logs. + +**_doorIds_** `str` +Door IDs filter. + +**_eventTypes_** `str` +Event types filter. + +**_update_** `int` +Update flag. + +
+#### Returns +
+`dict[str, object] or str` +Result of the acknowledge operation or error details. ---- +
-### `update_addon_package` +--- ---- +### `modify_controller_logger_config` +Modify the logger configuration for a controller. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_data_** `Any` +Logger configuration data (see example in docstring). + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. -### `check_addon_status` +
--- -### `disable_addon` +### `save_controller_settings` +Save controller settings for Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_arrayJson_** `str` +JSON string representing controller settings. Example: +\[\{"enable": true, "id": 97, "name": "ctrler1", "host": "10.13.12.173", "port": 80, + "model": "A1001", "username": "root", "password": "Q__Q-__-", "time_server": + "SurveillanceStation", "time_zone": "Fiji", "door": \[\{"id": 231, "name": "FrontDoor", + "enable_cam": true, "cam_ds_id": 0, "cam_id": 13\}\]\}\] + + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. + +
--- -### `set_addon_autoupdate` +### `download_filtered_logs` +Download filtered logs from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_filterType_** `int` +Type of filter to apply. + +**_filterEventSource_** `int` +Event source filter. + +**_filterSource_** `int` +Source filter. + +**_filterEventSourceItem_** `str` +Event source item filter. + +**_filterTimeFrom_** `int` +Start time for filtering. + +**_filterTimeTo_** `int` +End time for filtering. + +**_filterKeyword_** `str` +Keyword to filter logs. + +**_doorIds_** `str` +Door IDs filter. + +**_eventTypes_** `str` +Event types filter. + +**_update_** `int` +Update flag. + + +
+#### Returns +
+`dict[str, object] or str` +Downloaded log data or error details. + +
--- -### `delete_specific_camera_recording_server` +### `get_door_name_from_controller` +Retrieve door names from a specific controller. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_ctrlerId_** `int` +Controller ID. + +**_ip_** `str` +Controller IP address. + +**_port_** `int` +Controller port. + +**_userName_** `str` +Username for authentication. + +**_password_** `int` +Password for authentication (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Door names or error details. + +
--- -### `get_camera_event_analytic` +### `test_connection_and_authentication` +Test connection and authentication to a controller. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_ctrlerId_** `int` +Controller ID. + +**_ip_** `str` +Controller IP address. + +**_port_** `int` +Controller port. + +**_userName_** `str` +Username for authentication. + +**_password_** `int` +Password for authentication (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Result of the test or error details. + +
--- -### `delete_selected_events` +### `enumerate_controller_list_info` +Enumerate controller list information. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_update_** `int` +Update flag. + +**_blIncludeRecCnt_** `bool` +Whether to include record count. + +**_blIncludeAuInfo_** `bool` +Whether to include additional info (to check). + + +
+#### Returns +
+`dict[str, object] or str` +Controller list information or error details. + +
--- -### `delete_specific_camera_events` - - - ---- +### `save_cardholder_setting` +Save cardholder settings. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_arrayJson_** `str` +JSON string representing cardholder settings. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. -### `get_analytic_history` +
--- -### `get_analytic_history_by_filter` - - - ---- +### `enumerate_door_info` +Enumerate door information. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_DoorIds_** `str` +Comma-separated list of door IDs. + +
+#### Returns +
+`dict[str, object] or str` +Door information or error details. -### `unklock_selected_events` +
--- -### `set_camera_analytic_trigger` - - - ---- +### `clear_logs_surveillance_station` +Clear logs in Surveillance Station with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_filterType_** `int` +Type of filter to apply. + +**_filterEventSource_** `Any` +Event source filter. + +**_filterSource_** `int` +Source filter. + +**_filterEventSourceItem_** `str` +Event source item filter. + +**_filterTimeFrom_** `int` +Start time for filtering. + +**_filterTimeTo_** `int` +End time for filtering. + +**_filterKeyword_** `str` +Keyword to filter logs. + +**_doorIds_** `str` +Door IDs filter. + +**_eventTypes_** `str` +Event types filter. + +**_update_** `int` +Update flag. + +
+#### Returns +
+`dict[str, object] or str` +Result of the clear operation or error details. -### `flush_event_header` +
--- -### `lock_selected_events` +### `list_all_user_privilege` +List all user privileges in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Returns +
+`dict[str, object] or str` +List of user privileges or error details. +
---- +--- -### `get_analytic_event_from_rec_server` +### `manual_lock_operation` +Perform a manual lock or unlock operation on a door. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_doorId_** `int` +Door ID to operate on. + +**_operation_** `int` +Operation code (to check). + +
+#### Returns +
+`dict[str, object] or str` +Result of the operation or error details. ---- +
-### `save_analytic_settings` +--- ---- +### `save_user_door_priv_setting` +Save user door privilege settings. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_arrayJson_** `str` +JSON string representing user door privilege settings. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. -### `check_if_snapshot_exist` +
--- -### `save_snapshot_modification` - +### `list_all_logs` +List all logs in Surveillance Station with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_filterType_** `int` +Type of filter to apply. + +**_filterEventSource_** `Any` +Event source filter. + +**_filterSource_** `int` +Source filter. + +**_filterEventSourceItem_** `str` +Event source item filter. + +**_filterTimeFrom_** `int` +Start time for filtering. + +**_filterTimeTo_** `int` +End time for filtering. + +**_filterKeyword_** `str` +Keyword to filter logs. + +**_timezoneOffset_** `int` +Timezone offset. + +**_doorIds_** `str` +Door IDs filter. + +**_eventTypes_** `str` +Event types filter. + +**_update_** `int` +Update flag. + +**_blIncludeRecCnt_** `bool` +Whether to include record count. + +**_blIncludeAuInfo_** `bool` +Whether to include additional info. + +
+#### Returns +
+`dict[str, object] or str` +List of logs or error details. ---- +
-### `count_snapshot_by_category` +--- ---- +### `delete_selected_controller` +Delete selected controllers from Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated string of controller IDs to delete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. -### `check_any_locked_snapshot` +
--- -### `unlock_snapshot_by_filter` - +### `retrieve_data_from_controller` +Retrieve data from a specific controller. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_ctrlerId_** `str` +ID of the controller to retrieve data from. + +
+#### Returns +
+`dict[str, object] or str` +Retrieved data or error details. ---- +
-### `list_snapshot_information` +--- ---- +### `block_cardholder` +Block cardholders in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Parameters +
+**_arrayJson_** `str` +JSON string representing cardholder(s) to block. + +
+#### Returns +
+`dict[str, object] or str` +Result of the block operation or error details. -### `unlock_snapshot` +
--- -### `take_snapshot` +### `get_controller_count` +Get the count of controllers by category. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler` +
+ +#### Returns +
+`dict[str, object] or str` +Controller count or error details. + +
--- -### `get_snapshot_setting_function` +### `start_controller_search` +Start searching for controllers. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler.Search` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the search operation or error details. +
---- +--- -### `delete_snapshot_by_filter` +### `get_controller_search_info` +Get information about the current controller search. + +#### Internal API +
+`SYNO.SurveillanceStation.AxisAcsCtrler.Search` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the search. + +**_offset_** `int` +Offset for paginated results. + +
+#### Returns +
+`dict[str, object] or str` +Search information or error details. ---- +
-### `get_snapshot_image` +--- ---- +### `enumerate_digital_output` +Enumerate digital output devices. + +#### Internal API +
+`SYNO.SurveillanceStation.DigitalOutput` +
+ +#### Parameters +
+**_camId_** `int` +Camera ID to filter digital outputs. + +
+#### Returns +
+`dict[str, object] or str` +List of digital outputs or error details. -### `lock_snapshot_image` +
--- -### `downld_single_snapshot` - +### `save_digital_output_parameters` +Save parameters for a digital output device. + +#### Internal API +
+`SYNO.SurveillanceStation.DigitalOutput` +
+ +#### Parameters +
+**_camId_** `int` +Camera ID. + +**_idx_** `int` +Index of the digital output. + +**_keep_setting_** `bool` +Whether to keep the current setting. + +**_normal_state_** `int` +Normal state value. + +**_trigger_state_** `bool` +Trigger state value. + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. ---- +
-### `save_new_snapshot_setting` +--- ---- +### `long_polling_digital_output_status` +Perform long polling to get the status of a digital output. + +#### Internal API +
+`SYNO.SurveillanceStation.DigitalOutput` +
+ +#### Parameters +
+**_camId_** `int` +Camera ID. + +**_idx_** `int` +Index of the digital output. + +**_keep_** `bool` +Whether to keep polling. + +**_setNormalCap_** `bool` +Set normal capability. + +**_normal_** `int` +Normal state value. + +**_trigger_** `bool` +Trigger state value. + +**_timeOut_** `int` +Timeout for polling. + +
+#### Returns +
+`dict[str, object] or str` +Status information or error details. -### `save_snapshot` +
--- -### `check_snapshot_status` - - - ---- +### `trigger_external_event` +Trigger an external event in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.ExternalEvent` +
+ +#### Parameters +
+**_eventId_** `int` +ID of the event to trigger. + +**_eventName_** `str` +Name of the event to trigger. + +
+#### Returns +
+`dict[str, object] or str` +Result of the trigger operation or error details. -### `enable_visualstation` +
--- -### `update_vs_network_config` - - - ---- +### `get_list_io_modules` +Get a list of I/O modules. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_blFromList_** `bool` +Whether to get from list. + +**_ownerDsId_** `int` +Owner device station ID. + +
+#### Returns +
+`dict[str, object] or str` +List of I/O modules or error details. -### `lock_visualstation_by_id` +
--- -### `enumerate_vs_owner_info` - - - ---- +### `get_io_port_list` +Get a list of I/O ports for a module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_Id_** `int` +Module ID. + +**_Port_** `int` +Port number. + +**_IP_** `str` +IP address. + +**_User_** `str` +Username. + +**_Pass_** `str` +Password. + +**_Vendor_** `str` +Vendor name. + +**_Model_** `str` +Model name. + +
+#### Returns +
+`dict[str, object] or str` +List of I/O ports or error details. -### `unlock_visualstation_by_id` +
--- -### `disable_visualstation_by_id` +### `get_supported_list_io_modules` +Get a list of supported I/O module vendor models. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Returns +
+`dict[str, object] or str` +List of supported vendor models or error details. + +
--- -### `delete_specific_visualstation` - +### `save_setting_io_module` +Save or update the settings for an I/O module in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_name_** `str` +Name of the I/O module. + +**_id_** `int` +ID of the I/O module. + +**_ownerDsId_** `int` +Owner device station ID. + +**_vendor_** `str` +Vendor name of the I/O module. + +**_model_** `str` +Model name of the I/O module. + +**_ip_** `str` +IP address of the I/O module. + +**_port_** `int` +Port number for the I/O module. + +**_userName_** `str` +Username for authentication. + +**_enabled_** `bool` +Whether the I/O module is enabled. + +**_status_** `int` +Status code of the I/O module. + +**_timeServer_** `str` +Time server address. + +**_passWord_** `str` +Password for authentication. + +**_ntpEnable_** `bool` +Whether NTP is enabled. + +**_DIOdata_** `Any` +Digital I/O data (structure to be checked). + +
+#### Returns +
+`dict[str, object] or str` +Result of the save operation or error details. ---- +
-### `enumerate_layout_visualstation` +--- ---- +### `enable_io_modules` +Enable specified I/O modules. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_iomlist_** `str` +Comma-separated list of I/O module IDs to enable. + +
+#### Returns +
+`dict[str, object] or str` +Result of the enable operation or error details. -### `save_layout_information` +
--- -### `delete_layout_visualstation` - +### `disable_io_modules` +Disable specified I/O modules. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_iomlist_** `str` +Comma-separated list of I/O module IDs to disable. + +
+#### Returns +
+`dict[str, object] or str` +Result of the disable operation or error details. ---- +
-### `clear_visualstation_search_result` +--- ---- +### `delete_io_modules` +Delete specified I/O modules. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_iomlist_** `str` +Comma-separated list of I/O module IDs to delete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. -### `get_visualstation_ip_info` +
--- -### `stop_previous_visualstation_search` - +### `test_connection_to_io_module` +Test the connection to a specified I/O module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_id_** `int` +ID of the I/O module. + +**_port_** `str` +Port number for the I/O module. + +**_ip_** `str` +IP address of the I/O module. + +**_userName_** `str` +Username for authentication. + +**_passWord_** `str` +Password for authentication. + +**_model_** `str` +Model name of the I/O module. + +
+#### Returns +
+`dict[str, object] or str` +Result of the connection test or error details. ---- +
-### `get_visualstation_list` +--- ---- +### `get_capability_io_module` +Get the capability information for a specified I/O module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_vendor_** `str` +Vendor name of the I/O module. + +**_model_** `str` +Model name of the I/O module. + +
+#### Returns +
+`dict[str, object] or str` +Capability information or error details. -### `get_number_of_controller` +
--- -### `get_cardholder_count` - +### `configure_io_port_setting` +Configure the port settings for a specified I/O module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_id_** `int` +ID of the I/O module. + +**_DIOdata_** `Any` +Digital I/O data for port configuration (structure to be checked). + +
+#### Returns +
+`dict[str, object] or str` +Result of the configuration or error details. ---- +
-### `enum_all_controllers_logger` +--- ---- +### `poll_trigger_state_io_module` +Poll the trigger state of digital input (DI) ports for a specified I/O module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_Id_** `int` +ID of the I/O module. + +**_list_** `Any` +List of DI ports to poll (structure to be checked). + +**_timeOut_** `int` +Timeout for polling operation. + +
+#### Returns +
+`dict[str, object] or str` +Polling result or error details. -### `get_cardholder_photo` +
--- -### `get_log_count` +### `poll_do_trigger_module` +Poll the trigger state of digital output (DO) ports for a specified I/O module. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_id_** `int` +ID of the I/O module. + +**_idx_** `int` +Index of the DO port. + +**_normal_** `int` +Normal state value. + +**_trigger_** `bool` +Trigger state. + +**_timeOut_** `int` +Timeout for polling operation. + +
+#### Returns +
+`dict[str, object] or str` +Polling result or error details. +
---- -### `get_cardholder_info` +--- +### `get_number_of_devices` +Get the number of I/O devices for each device station. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Returns +
+`dict[str, object] or str` +Number of devices or error details. ---- +
-### `retrieve_last_access_credential` +--- ---- +### `get_category_count_io_module` +Get the count of I/O modules by category. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule` +
+ +#### Parameters +
+**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +**_ownerDsId_** `int` +Owner device station ID. + +**_blFromList_** `bool` +Whether to get count from a list (to be checked). + +
+#### Returns +
+`dict[str, object] or str` +Count by category or error details. -### `enable_disable_controller` +
--- -### `acknowledge_all_alarm_level_log` +### `start_search_io_module` +Start searching for I/O modules. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule.Search` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the search operation or error details. + +
--- -### `modify_controller_logger_config` - +### `get_search_io_module_info` +Get information about the current I/O module search. + +#### Internal API +
+`SYNO.SurveillanceStation.IOModule.Search` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the search. + +
+#### Returns +
+`dict[str, object] or str` +Search information or error details. ---- +
-### `save_controller_settings` +--- ---- +### `get_current_camera_status` +Get the current status of specified cameras. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Status` +
+ +#### Parameters +
+**_id_list_** `str` +Comma-separated list of camera IDs. + +
+#### Returns +
+`dict[str, object] or str` +Camera status information or error details. -### `download_filtered_logs` +
--- -### `get_door_name_from_controller` - +### `enum_preset_camera_list` +Enumerate the list of presets for a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `Any` +ID of the camera. + +
+#### Returns +
+`dict[str, object] or str` +List of camera presets or error details. ---- +
-### `test_connection_and_authentication` +--- ---- +### `get_preset_camera_capability` +Get the capability information for camera presets. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `int` +ID of the camera. + +
+#### Returns +
+`dict[str, object] or str` +Preset capability information or error details. -### `enumerate_controller_list_info` +
--- -### `save_cardholder_setting` - +### `record_current_camera_position` +Record the current position of a camera as a preset. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `int` +ID of the camera. + +**_position_** `int` +Preset position index. + +**_speed_** `int` +Speed for moving to the preset. + +**_name_** `str` +Name for the preset. + +
+#### Returns +
+`dict[str, object] or str` +Result of the record operation or error details. ---- +
-### `enumerate_door_info` +--- ---- +### `delete_list_preset_camera` +Delete specified presets from a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `Any` +ID of the camera. + +**_position_** `str` +Preset position(s) to delete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. -### `clear_logs_surveillance_station` +
--- -### `list_all_user_privilege` - +### `go_specific_preset_by_given_speed` +Move a camera to a specific preset position at a given speed. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `Any` +ID of the camera. + +**_position_** `int` +Preset position index. + +**_speed_** `int` +Speed for moving to the preset. + +**_type_** `int` +Type of preset move (to be checked). + +
+#### Returns +
+`dict[str, object] or str` +Result of the move operation or error details. ---- +
-### `manual_lock_operation` +--- ---- +### `set_current_camera_position` +Set the current position of a camera as the home position. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Preset` +
+ +#### Parameters +
+**_cameraId_** `Any` +ID of the camera. + +**_bindPosition_** `int` +Position to bind as home. + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error details. -### `save_user_door_priv_setting` +
--- -### `list_all_logs` - +### `enum_patrol_list` +Enumerate the list of patrols for a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_cam_** `Any` +Camera identifier. + +
+#### Returns +
+`dict[str, object] or str` +List of patrols or error details. ---- +
-### `delete_selected_controller` +--- ---- +### `enum_patrol_name_list` +Enumerate the list of patrol names for a specified camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_camId_** `Any` +Camera identifier. + +
+#### Returns +
+`dict[str, object] or str` +List of patrol names or error details. -### `retrieve_data_from_controller` +
--- -### `block_cardholder` - +### `load_patrol_detail` +Load the details of a specific patrol. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_id_** `int` +Patrol ID. + +
+#### Returns +
+`dict[str, object] or str` +Patrol details or error information. ---- +
-### `get_controller_count` +--- ---- +### `add_or_modify_patrol` +Add or modify a patrol for a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_camId_** `Any` +Camera identifier. + +**_id_** `int` +Patrol ID. + +**_stayTime_** `int` +Stay time at each preset. + +**_speed_** `int` +Patrol speed. + +**_name_** `str` +Name of the patrol. + +**_presetList_** `Any` +List of presets for the patrol (structure to be checked). + +
+#### Returns +
+`dict[str, object] or str` +Result of the add/modify operation or error details. -### `start_controller_search` +
--- -### `get_controller_search_result` - +### `delete_specific_patrol` +Delete a specific patrol from a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_camId_** `Any` +Camera identifier. + +**_patrolId_** `str` +Patrol ID to delete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. ---- +
-### `enumerate_digital_output` +--- ---- +### `run_patrol` +Run a specified patrol on a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_camId_** `Any` +Camera identifier. + +**_id_** `int` +Patrol ID. + +
+#### Returns +
+`dict[str, object] or str` +Result of the run operation or error details. -### `save_digital_output_parameters` +
--- -### `long_polling_digital_output_status` +### `stop_patrol` +Stop the currently running patrol on a camera. + +#### Internal API +
+`SYNO.SurveillanceStation.PTZ.Patrol` +
+ +#### Parameters +
+**_camId_** `Any` +Camera identifier. + +
+#### Returns +
+`dict[str, object] or str` +Result of the stop operation or error details. +
---- -### `trigger_external_event` +--- +### `start_camera_search_process` +Start searching for cameras. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Search` +
+ +#### Returns +
+`dict[str, object] or str` +Result of the search operation or error details. ---- +
-### `get_list_io_modules` +--- ---- +### `get_camera_search_info` +Get information about the current camera search. + +#### Internal API +
+`SYNO.SurveillanceStation.Camera.Search` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the search. + +**_offset_** `int` +Offset for pagination. + +
+#### Returns +
+`dict[str, object] or str` +Search information or error details. -### `get_io_port_list` +
--- -### `get_supported_list_io_modules` - +### `toggle_home_mode` +Toggle the Home Mode in Surveillance Station. + +#### Internal API +
+`SYNO.SurveillanceStation.HomeMode` +
+ +#### Parameters +
+**_on_** `bool` +Whether to enable (True) or disable (False) Home Mode. + +
+#### Returns +
+`dict[str, object] or str` +Result of the toggle operation or error details. ---- +
-### `save_setting_io_module` +--- ---- +### `get_home_mode_settings` +Get the current Home Mode settings. + +#### Internal API +
+`SYNO.SurveillanceStation.HomeMode` +
+ +#### Parameters +
+**_need_mobiles_** `bool` +Whether to include mobile device information. + +
+#### Returns +
+`dict[str, object] or str` +Home Mode settings or error details. -### `enable_io_modules` +
--- -### `disable_io_modules` - +### `get_transaction_list` +Get a list of device transactions with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Device` +
+ +#### Parameters +
+**_filterIds_** `str` +Comma-separated list of transaction IDs to filter. + +**_filterDsIds_** `str` +Comma-separated list of device station IDs to filter. + +**_filterEnable_** `bool` +Filter by enabled status. + +**_filterStatus_** `int` +Filter by status code. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +
+#### Returns +
+`dict[str, object] or str` +List of transactions or error details. ---- +
-### `delete_io_modules` +--- ---- +### `get_all_transaction_list` +Get a list of all transactions with optional filters. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_filterIds_** `str` +Comma-separated list of transaction IDs to filter. + +**_dsId_** `int` +Device station ID. + +**_filterTimeFrom_** `Any` +Start time for filtering. + +**_filterStatus_** `int` +Filter by status code. + +**_filterLock_** `bool` +Filter by lock status. + +**_filterTimeTo_** `Any` +End time for filtering. + +**_filterTimeRangeIntersect_** `bool` +Whether to intersect time ranges. + +**_filterKeyword_** `str` +Keyword for filtering. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +
+#### Returns +
+`dict[str, object] or str` +List of transactions or error details. -### `test_connection_to_io_module` +
--- -### `get_capability_io_module` - +### `lock_history_records` +Lock specified history records. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_filterIds_** `str` +Comma-separated list of record IDs to lock. + +**_dsId_** `int` +Device station ID. + +**_filterStatus_** `int` +Filter by status code. + +**_filterLock_** `bool` +Filter by lock status. + +**_filterTimeFrom_** `Any` +Start time for filtering. + +**_filterTimeTo_** `Any` +End time for filtering. + +**_filterTimeRangeIntersect_** `bool` +Whether to intersect time ranges. + +**_filterKeyword_** `str` +Keyword for filtering. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +
+#### Returns +
+`dict[str, object] or str` +Result of the lock operation or error details. ---- +
-### `configure_io_port_setting` +--- ---- +### `unlock_history_records` +Unlock specified history records. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_filterIds_** `str` +Comma-separated list of record IDs to unlock. + +**_dsId_** `int` +Device station ID. + +**_filterStatus_** `int` +Filter by status code. + +**_filterLock_** `bool` +Filter by lock status. + +**_filterTimeFrom_** `Any` +Start time for filtering. + +**_filterTimeTo_** `Any` +End time for filtering. + +**_filterTimeRangeIntersect_** `bool` +Whether to intersect time ranges. + +**_filterKeyword_** `str` +Keyword for filtering. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +
+#### Returns +
+`dict[str, object] or str` +Result of the unlock operation or error details. -### `poll_trigger_state_io_module` +
--- -### `poll_do_trigger_module` - +### `delete_history_records` +Delete specified history records. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_filterIds_** `str` +Comma-separated list of record IDs to delete. + +**_dsId_** `int` +Device station ID. + +**_filterStatus_** `int` +Filter by status code. + +**_filterLock_** `bool` +Filter by lock status. + +**_filterTimeFrom_** `Any` +Start time for filtering. + +**_filterTimeTo_** `Any` +End time for filtering. + +**_filterTimeRangeIntersect_** `bool` +Whether to intersect time ranges. + +**_filterKeyword_** `str` +Keyword for filtering. + +**_start_** `int` +Start index for pagination. + +**_limit_** `int` +Maximum number of results to return. + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error details. ---- +
-### `get_number_of_devices` +--- ---- +### `start_session_with_specified_session_id` +Start a session with a specified session ID. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_device_name_** `str` +Name of the device. + +**_session_id_** `str` +Session ID to start. + +**_timeout_** `int` +Timeout for the session. + +
+#### Returns +
+`dict[str, object] or str` +Result of the start operation or error details. -### `get_category_count_io_module` +
--- -### `start_search_io_module` - +### `complete_session_with_specified_id` +Complete a session with a specified session ID. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_device_name_** `str` +Name of the device. + +**_session_id_** `str` +Session ID to complete. + +
+#### Returns +
+`dict[str, object] or str` +Result of the complete operation or error details. ---- +
-### `get_search_io_module_info` +--- ---- +### `cancel_session_with_specified_session_id` +Cancel a session with a specified session ID. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_device_name_** `str` +Name of the device. + +**_session_id_** `str` +Session ID to cancel. + +
+#### Returns +
+`dict[str, object] or str` +Result of the cancel operation or error details. -### `get_current_camera_status` +
--- -### `enum_preset_camera_list` - +### `carry_data_into_session_id` +Append data to a session with a specified session ID. + +#### Internal API +
+`SYNO.SurveillanceStation.Transactions.Transaction` +
+ +#### Parameters +
+**_device_name_** `str` +Name of the device. + +**_session_id_** `str` +Session ID to append data to. + +**_content_** `str` +Data content to append. + +
+#### Returns +
+`dict[str, object] or str` +Result of the append operation or error details. ---- +
-### `get_preset_camera_capability` +--- ---- +### `add_edit_active_vault_task` +Add or edit an active vault task for archiving. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_blCustomFolder_** `bool` +Whether to use a custom folder for storage. + +**_blLimitBySize_** `bool` +Whether to limit the archive by size. + +**_blRotateFile_** `bool` +Whether to enable file rotation. + +**_blSrcRecNoOverlap_** `bool` +Whether to avoid overlapping source recordings. + +**_blUseRecDet_** `bool` +Whether to use recording detection. + +**_camId_** `Any` +Camera ID. + +**_camInfo_** `Any` +Camera information. + +**_dayLimit_** `int` +Day limit for the archive. + +**_didCode_** `str` +Device code. + +**_dsSerial_** `str` +Device serial number. + +**_execTime_** `Any` +Execution time. + +**_hostname_** `str` +Hostname of the source server. + +**_id_** `int` +Task ID (for editing). + +**_name_** `str` +Name of the task. + +**_passwd_** `str` +Password for authentication. + +**_port_** `str` +Port number. + +**_recEndTm_** `Any` +Recording end time. + +**_recMode_** `str` +Recording mode. + +**_recSchedule_** `str` +Recording schedule. + +**_recStartTm_** `Any` +Recording start time. + +**_schedule_** `str` +Task schedule. + +**_storagePath_** `str` +Path for storage. + +**_type_** `int` +Type of the task. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `record_current_camera_position` +
--- -### `delete_list_preset_camera` - - - ---- +### `login_source_server_get_info` +Log in to the source server and retrieve information. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_port_** `str` +Port number of the source server. + +**_hostname_** `str` +Hostname of the source server. + +**_protocol_** `bool` +Protocol to use (e.g., HTTPS). + +**_username_** `str` +Username for authentication. + +**_passwd_** `str` +Password for authentication. + +**_archId_** `int` +Archive ID. + +**_didCode_** `str` +Device code. + +**_srcDsId_** `int` +Source device ID (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `go_specific_preset_by_given_speed` +
--- -### `set_current_camera_position` - - - ---- +### `delete_archive_vault_task` +Delete an archive vault task. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_id_** `int` +Task ID to delete. + +**_keepRec_** `bool` +Whether to keep the recordings. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `enum_patrol_list` +
--- -### `enum_patrol_name_list` - - - ---- - +### `list_exist_archive_vault` +List all existing archive vault tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Returns +
+`dict of str to object or str` +API response from the request. -### `load_patrol_detail` +
--- -### `add_or_modify_patrol` - - - ---- +### `enable_archive_vault_task` +Enable an archive vault task. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_id_** `int` +Task ID to enable. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `delete_specific_patrol` +
--- -### `run_patrol` - - - ---- +### `disable_archive_vault_task` +Disable an archive vault task. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_id_** `int` +Task ID to disable. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `stop_patrol` +
--- -### `start_camera_search_process` - - - ---- +### `disable_archive_vault_batchedit_task` +Batch edit (disable) archive vault tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_taskIds_** `str` +Comma-separated list of task IDs. + +**_attrs_** `Any` +Additional attributes for batch edit (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_camera_search_info` +
--- -### `toggle_home_mode` - - - ---- +### `get_batch_edit_progress` +Get the progress of a batch edit operation. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the batch edit operation (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_home_mode_settings` +
--- -### `get_transaction_list` - - - ---- +### `get_batchedit_proress_info` +Get detailed information about batch edit progress. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the batch edit operation (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_all_transaction_list` +
--- -### `lock_history_records` - - - ---- +### `clean_batchedit_progress_data` +Clean up batch edit progress data. + +#### Internal API +
+`SYNO.SurveillanceStation.Archiving.Pull` +
+ +#### Parameters +
+**_pid_** `int` +Process ID of the batch edit operation. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `unlock_history_records` +
--- -### `delete_history_records` - - +### `get_youtube_live_broadcast_setting` +Get the current YouTube Live broadcast settings. + +#### Internal API +
+`SYNO.SurveillanceStation.YoutubeLive` +
+ +#### Returns +
+`dict of str to object or str` +API response from the request. ---- +
-### `start_session_with_specified_session_id` +--- ---- +### `set_youtube_live_broadcast_info` +Set YouTube Live broadcast information. + +#### Internal API +
+`SYNO.SurveillanceStation.YoutubeLive` +
+ +#### Parameters +
+**_rtmp_path_** `str` +RTMP path for the broadcast. + +**_key_** `str` +Stream key. + +**_cam_id_** `int` +Camera ID. + +**_stream_profile_** `int` +Stream profile. + +**_live_on_** `bool` +Whether to enable live broadcast. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `complete_session_with_specified_id` +
--- -### `cancel_session_with_specified_session_id` - +### `close_youtube_live_broadcast` +Close the current YouTube Live broadcast. + +#### Internal API +
+`SYNO.SurveillanceStation.YoutubeLive` +
+ +#### Returns +
+`dict of str to object or str` +API response from the request. +
---- -### `carry_data_into_session_id` +--- +### `get_deep_video_analytic` +Get the list of deep video analytic tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Returns +
+`dict of str to object or str` +API response from the request. ---- +
-### `add_edit_active_vault_task` +--- ---- +### `create_edit_DVA_task` +Create or edit a Deep Video Analytics (DVA) task. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Parameters +
+**_analyze_type_** `int` +Type of analysis to perform. + +**_actFromHost_** `bool` +Whether the action is triggered from the host. + +**_name_** `str` +Name of the DVA task. + +**_camera_id_** `int` +ID of the camera associated with the task. + +**_enable_** `bool` +Whether to enable the task. + +**_enable_recording_** `bool` +Whether to enable recording for the task. + +**_pre_rec_time_** `int` +Pre-recording time in seconds. + +**_post_rec_time_** `int` +Post-recording time in seconds. + +**_event_integration_** `int` +Event integration setting. + +**_region_type_** `int` +Type of detection region. + +**_det_region_cnt_** `int` +Number of detection regions. + +**_det_region_** `int` +Detection region configuration. + +**_people_mode_** `int` +People counting mode. + +**_reset_cnt_frequency_** `int` +Frequency for resetting the counter. + +**_reset_weekday_** `int` +Weekday for counter reset. + +**_reset_date_** `int` +Date for counter reset. + +**_reset_time_minute_** `int` +Minute for counter reset. + +**_reset_time_hour_** `int` +Hour for counter reset. + +**_fence_dir_flag_** `int` +Fence direction flag. + +**_people_display_pos_** `int` +Display position for people counting. + +**_stream_profile_** `int` +Stream profile to use. + +**_people_enable_stay_max_** `bool` +Whether to enable maximum stay for people. + +**_intrusion_detect_target_** `int` +Target for intrusion detection. + +**_min_obj_size_** `Any` +Minimum object size for detection. + +**_min_obj_size_option_** `int` +Option for minimum object size. + +**_enable_min_duration_** `int` +Enable minimum duration for detection. + +**_people_display_info_** `int` +Display information for people counting. + +**_people_enter_** `int` +Number of people entering. + +**_people_stay_max_** `int` +Maximum number of people staying. + +**_people_region_** `str` +Region for people counting. + +**_people_hint_pos_** `str` +Hint position for people counting. + +**_blEditMode_** `bool` +Edit mode flag (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `login_source_server_get_info` +
--- -### `delete_archive_vault_task` - - - ---- +### `delete_dva_task` +Delete a Deep Video Analytics (DVA) task. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of DVA task IDs to delete. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `list_exist_archive_vault` +
--- -### `enable_archive_vault_task` - - - ---- +### `enable_dva_task` +Enable one or more Deep Video Analytics (DVA) tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of DVA task IDs to enable. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `disable_archive_vault_task` +
--- -### `disable_archive_vault_batchedit_task` - - - ---- +### `disable_dva_task` +Disable one or more Deep Video Analytics (DVA) tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of DVA task IDs to disable. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_batch_edit_progress` +
--- -### `get_batchedit_proress_info` - - - ---- +### `reset_counter_people_counting_task` +Reset the people counting counter for a specific DVA task. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA` +
+ +#### Parameters +
+**_taskId_** `str` +ID of the people counting task to reset. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `clean_batchedit_progress_data` +
--- -### `get_youtube_live_broadcast_setting` - - - ---- +### `get_people_enter_leave_count` +Get the count of people entering and leaving for specified DVA tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Report` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of DVA task IDs. + +**_timeStart_** `str` +Start time for the count (ISO format or timestamp). + +**_timeEnd_** `str` +End time for the count (ISO format or timestamp). + +**_timezone_** `int` +Timezone offset. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `set_youtube_live_broadcast_info` +
--- -### `close_youtube_live_broadcast` - - - ---- +### `get_people_count_of_day` +Get the people count report for a specific day. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Report` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of DVA task IDs. + +**_interval_** `int` +Interval for the report. + +**_intervalUnit_** `int` +Unit for the interval. + +**_timezone_** `int` +Timezone offset. + +**_timestamp_** `int` +Timestamp for the report. + +**_blOccupancy_** `int` +Occupancy flag (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_deep_video_analytic` +
--- -### `create_edit_DVA_task` - - - ---- +### `list_people_counting_task` +List people counting tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Recording` +
+ +#### Parameters +
+**_taskList_** `str` +Comma-separated list of task IDs to list. + +**_limit_** `int` +Limit the number of tasks returned (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `delete_dva_task` +
--- -### `enable_dva_task` - - - ---- +### `delete_recording_file_of_detection` +Delete recording files associated with detection events. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Recording` +
+ +#### Parameters +
+**_slaveDsParam_** `str` +Parameters for the slave device. + +**_deleteMethod_** `int` +Method for deletion (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `disable_dva_task` +
--- -### `reset_counter_people_counting_task` - - - ---- +### `get_info_of_task_and_frame` +Get analytic result information for a specific task and frame. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Recording` +
+ +#### Parameters +
+**_eventId_** `int` +Event ID to query. + +**_taskId_** `int` +Task ID to query. + +**_blAlertEvt_** `bool` +Alert event flag (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_people_enter_leave_count` +
--- -### `get_people_count_of_day` - +### `lock_recording_file_of_detection` +Lock recording files associated with detection events. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Recording` +
+ +#### Parameters +
+**_dsId_** `int` +Device server ID. + +**_idList_** `int` +List of recording file IDs to lock (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. ---- +
-### `list_people_counting_task` +--- ---- +### `unlock_recording_file_of_detection` +Unlock recording files associated with detection events. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.Recording` +
+ +#### Parameters +
+**_dsId_** `int` +Device server ID. + +**_idList_** `str` +List of recording file IDs to unlock (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `delete_recording_file_of_detection` +
--- -### `get_info_of_task_and_frame` +### `get_info_people_counting_task` +Get information about people counting tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Returns +
+`dict of str to object or str` +API response from the request. +
---- +--- -### `lock_recording_file_of_detection` +### `create_people_counting_task` +Create a new people counting task. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_enable_** `bool` +Whether to enable the task. + +**_task_ids_** `str` +Comma-separated list of task IDs. + +**_owner_ds_id_** `int` +Owner device server ID. + +**_name_** `str` +Name of the task. + +**_people_display_info_** `str` +Display information for people counting. + +**_people_enable_stay_max_** `int` +Enable maximum stay for people. + +**_reset_cnt_frequency_** `int` +Frequency for resetting the counter. + +**_resert_date_** `int` +Date for counter reset. + +**_resert_weekday_** `int` +Weekday for counter reset. + +**_resert_tome_hour_** `int` +Hour for counter reset. + +**_resert_tome_minute_** `int` +Minute for counter reset (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. ---- +
-### `unlock_recording_file_of_detection` +--- ---- +### `modify_setting_of_people_counting_task` +Modify the settings of an existing people counting task. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_enable_** `bool` +Whether to enable the task. + +**_id_** `int` +ID of the task to modify. + +**_task_ids_** `str` +Comma-separated list of task IDs. + +**_name_** `str` +Name of the task. + +**_people_display_info_** `int` +Display information for people counting. + +**_people_enable_max_** `int` +Enable maximum stay for people. + +**_reset_cnt_frequency_** `int` +Frequency for resetting the counter. + +**_resert_date_** `int` +Date for counter reset. + +**_resert_weekday_** `int` +Weekday for counter reset. + +**_resert_tome_hour_** `int` +Hour for counter reset. + +**_resert_tome_minute_** `int` +Minute for counter reset (not working). + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `get_info_people_counting_task` +
--- -### `create_people_counting_task` - - - ---- +### `delete_task_group` +Delete a people counting task group. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task group IDs to delete. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `modify_setting_of_people_counting_task` +
--- -### `delete_task_group` - - - ---- +### `start_count_people_task_in_groups` +Enable people counting tasks in specified groups. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task group IDs to enable. + +
+#### Returns +
+`dict of str to object or str` +API response from the request. -### `start_count_people_task_in_groups` +
@@ -2168,6 +10064,26 @@ Code Description ### `stop_count_people_task_in_groups` +Disable people counting tasks in specified groups. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task group IDs to disable. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2175,6 +10091,26 @@ Code Description ### `get_number_counting_task_group` +Get the people count for a specific task group. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_id_** `int` +ID of the task group. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2182,6 +10118,26 @@ Code Description ### `lock_recording_file_result` +Reset the people count for a specific IVA task group. + +#### Internal API +
+`SYNO.SurveillanceStation.IVA.TaskGroup` +
+ +#### Parameters +
+**_id_** `int` +ID of the IVA task group. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2189,6 +10145,32 @@ Code Description ### `get_face_list_task` +Retrieve the list of face detection tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task IDs to filter. + +**_ownerDsId_** `int` +ID of the owner DiskStation. + +**_blOnlyEnableDs_** `bool` +Whether to include only enabled DiskStations. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2196,6 +10178,119 @@ Code Description ### `create_or_edit_task` +Create or edit a face detection task. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_id_** `int` +Task ID. + +**_id_on_rec_server_** `int` +Task ID on the recording server. + +**_camera_id_** `int` +Camera ID. + +**_camera_id_on_rec_** `int` +Camera ID on the recording server. + +**_owner_ds_id_** `int` +Owner DiskStation ID. + +**_enable_** `bool` +Whether to enable the task. + +**_blEditMode_** `bool` +Edit mode flag. + +**_stream_profile_** `int` +Stream profile index. + +**_name_** `str` +Name of the task. + +**_similarity_** `float` +Similarity threshold for face recognition. + +**_allowed_color_** `int` +Color code for allowed faces. + +**_allowed_list_** `Any` +List of allowed faces. + +**_blocked_color_** `int` +Color code for blocked faces. + +**_blocked_list_** `Any` +List of blocked faces. + +**_vip_color_** `int` +Color code for VIP faces. + +**_vip_list_** `Any` +List of VIP faces. + +**_recognized_color_** `int` +Color code for recognized faces. + +**_unrecognized_color_** `int` +Color code for unrecognized faces. + +**_deleted_** `bool` +Whether the task is deleted. + +**_det_region_** `str` +Detection region. + +**_det_region_cnt_** `int` +Number of detection regions. + +**_region_type_** `int` +Type of region. + +**_display_info_** `int` +Display information. + +**_display_type_** `int` +Display type. + +**_frame_display_info_** `int` +Frame display information. + +**_enable_min_ogj_size_** `bool` +Enable minimum object size. + +**_min_ogj_size_** `float` +Minimum object size. + +**_post_rec_time_** `int` +Post-recording time in seconds. + +**_pre_rec_time_** `int` +Pre-recording time in seconds. + +**_schedule_** `str` +Task schedule. + +**_scheduleOn_** `bool` +Whether the schedule is enabled. + +**_ignore_bad_quality_** `bool` +Ignore bad quality flag (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2203,6 +10298,29 @@ Code Description ### `delete_face_task` +Delete one or more face detection tasks. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task IDs to delete. + +**_keepRecording_** `bool` +Whether to keep the associated recordings (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2210,6 +10328,26 @@ Code Description ### `enable_task_to_start_detection_recording` +Enable face detection tasks to start detection and recording. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task IDs to enable. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2217,6 +10355,26 @@ Code Description ### `disable_task_to_stop_detection_recording` +Disable face detection tasks to stop detection and recording. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of task IDs to disable. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2224,6 +10382,26 @@ Code Description ### `list_task_with_privilege_to_watch` +List face detection tasks with privilege to watch. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `int` +Task group ID to filter. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2231,6 +10409,32 @@ Code Description ### `create_face_group` +Create a new face group. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_name_** `str` +Name of the face group. + +**_description_** `str` +Description of the face group. + +**_update_registered_face_** `Any` +Registered face update information (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2238,6 +10442,26 @@ Code Description ### `disable_face_grooup` +Delete (disable) one or more face groups. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `Any` +IDs of the face groups to delete (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2245,6 +10469,35 @@ Code Description ### `edit_face_group` +Edit an existing face group. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_name_** `str` +Name of the face group. + +**_description_** `str` +Description of the face group. + +**_update_registered_face_** `Any` +Registered face update information. + +**_id_** `int` +ID of the face group to edit. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2252,6 +10505,29 @@ Code Description ### `get_face_group_list` +Retrieve the list of face groups. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_id_only_** `bool` +Whether to return only IDs. + +**_filter_** `Any` +Filter criteria (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2259,13 +10535,56 @@ Code Description ### `count_face_groups` +Count the number of face groups. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
--- -### `detect_faces_image` +### `detect_faces_image` +Detect faces in an image. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_image_data_** `str` +Base64-encoded image data. + +**_image_size_** `int` +Size of the image (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2273,6 +10592,53 @@ Code Description ### `create_registered_face` +Create a new registered face. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_account_** `str` +Account associated with the face. + +**_name_** `str` +Name of the person. + +**_description_** `str` +Description of the face. + +**_image_data_** `str` +Base64-encoded image data. + +**_image_size_** `int` +Size of the image. + +**_face_** `Any` +Face data. + +**_update_face_group_** `Any` +Face group update information. + +**_captured_face_id_** `int` +ID of the captured face. + +**_update_unrecognized_captured_face_** `bool` +Whether to update unrecognized captured face. + +**_append_image_data_** `bool` +Append image data flag (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2280,6 +10646,26 @@ Code Description ### `delete_registered_face` +Delete one or more registered faces. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_ids_** `Any` +IDs of the registered faces to delete (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2287,6 +10673,56 @@ Code Description ### `edit_registered_face` +Edit an existing registered face. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_id_** `int` +ID of the registered face. + +**_account_** `str` +Account associated with the face. + +**_name_** `str` +Name of the person. + +**_description_** `str` +Description of the face. + +**_image_data_** `str` +Base64-encoded image data. + +**_image_size_** `int` +Size of the image. + +**_face_** `Any` +Face data. + +**_update_face_group_** `Any` +Face group update information. + +**_captured_face_id_** `int` +ID of the captured face. + +**_update_unrecognized_captured_face_** `bool` +Whether to update unrecognized captured face. + +**_append_image_data_** `bool` +Append image data flag. + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2294,6 +10730,32 @@ Code Description ### `list_registered_face` +List registered faces. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_id_only_** `bool` +Whether to return only IDs. + +**_filter_** `Any` +Filter criteria. + +**_append_image_data_** `bool` +Whether to append image data (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2301,6 +10763,26 @@ Code Description ### `count_registered_face` +Count the number of registered faces. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2308,6 +10790,29 @@ Code Description ### `search_registered_face` +Search for registered faces by keywords. + +#### Internal API +
+`SYNO.SurveillanceStation.Face` +
+ +#### Parameters +
+**_keywords_** `str` +Search keywords. + +**_append_image_data_** `bool` +Whether to append image data (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response from the request. + +
@@ -2315,6 +10820,38 @@ Code Description ### `get_face_result_list` +Retrieve a list of face recognition results. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria for the face results. + +**_blIncludeSnapshot_** `bool` +Whether to include snapshot images in the results. + +**_blIncludeRegisteredFace_** `bool` +Whether to include registered face information. + +**_limit_** `int` +Maximum number of results to return. + +**_slaveDsParam_** `int` +Additional parameter for slave DiskStation (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response containing the list of face recognition results. + +
@@ -2322,6 +10859,29 @@ Code Description ### `delete_face_result` +Delete face recognition results. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria for selecting face results to delete. + +**_slaveDsParam_** `Any` +Additional parameter for slave DiskStation (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the delete operation. + +
@@ -2329,6 +10889,29 @@ Code Description ### `lock_face_result` +Lock face recognition results to prevent modification or deletion. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria for selecting face results to lock. + +**_slaveDsParam_** `Any` +Additional parameter for slave DiskStation (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the lock operation. + +
@@ -2336,6 +10919,29 @@ Code Description ### `unlock_face_result` +Unlock face recognition results to allow modification or deletion. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_filter_** `Any` +Filter criteria for selecting face results to unlock. + +**_slaveDsParam_** `Any` +Additional parameter for slave DiskStation (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the unlock operation. + +
@@ -2343,6 +10949,26 @@ Code Description ### `get_recording_file_of_face_info` +Retrieve the recording file associated with a specific captured face. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_capturedFaceId_** `int` +ID of the captured face (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response containing the recording file information. + +
@@ -2350,6 +10976,38 @@ Code Description ### `get_recognition_face_information` +Retrieve analytic results for face recognition events. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_taskId_** `int` +ID of the face recognition task. + +**_eventId_** `int` +ID of the event. + +**_startTime_** `int` +Start time for the query (timestamp). + +**_endTime_** `int` +End time for the query (timestamp). + +**_blIncludeRegisteredFace_** `int` +Whether to include registered face information (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response containing analytic results. + +
@@ -2357,6 +11015,29 @@ Code Description ### `correct_face_result` +Correct the result of a face recognition event by associating it with a registered face. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_id_** `int` +ID of the face recognition result to correct. + +**_registered_face_id_** `int` +ID of the registered face to associate (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the correction. + +
@@ -2364,6 +11045,26 @@ Code Description ### `mark_face_result_as_stranger` +Mark one or more face recognition results as strangers. + +#### Internal API +
+`SYNO.SurveillanceStation.Face.Result` +
+ +#### Parameters +
+**_ids_** `str` +Comma-separated list of face result IDs to mark as strangers (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the operation. + +
@@ -2371,6 +11072,44 @@ Code Description ### `add_new_bookmark` +Add a new bookmark to a recording. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Bookmark` +
+ +#### Parameters +
+**_id_** `int` +ID of the bookmark. + +**_eventId_** `int` +ID of the associated event. + +**_cameraId_** `int` +ID of the camera. + +**_archId_** `int` +ID of the archive. + +**_name_** `str` +Name of the bookmark. + +**_timestamp_** `Any` +Timestamp for the bookmark. + +**_comment_** `str` +Comment for the bookmark. + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the add operation. + +
@@ -2378,6 +11117,26 @@ Code Description ### `delete_bookmark` +Delete one or more bookmarks from recordings. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Bookmark` +
+ +#### Parameters +
+**_bookmarkIds_** `Any` +IDs of the bookmarks to delete (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response indicating the result of the delete operation. + +
@@ -2385,6 +11144,38 @@ Code Description ### `list_bookmark_detail` +List details of bookmarks for recordings. + +#### Internal API +
+`SYNO.SurveillanceStation.Recording.Bookmark` +
+ +#### Parameters +
+**_offset_** `int` +Offset for pagination. + +**_limit_** `int` +Maximum number of bookmarks to return. + +**_cameraIds_** `str` +Comma-separated list of camera IDs to filter. + +**_fromTime_** `int` +Start time for filtering bookmarks (timestamp). + +**_toTime_** `int` +End time for filtering bookmarks (not working). + + +
+#### Returns +
+`dict of str to object or str` +API response containing bookmark details. + +
diff --git a/documentation/docs/apis/classes/task_scheduler.md b/documentation/docs/apis/classes/task_scheduler.md index 70863178..edac4d1c 100644 --- a/documentation/docs/apis/classes/task_scheduler.md +++ b/documentation/docs/apis/classes/task_scheduler.md @@ -11,24 +11,24 @@ title: ✅ TaskScheduler ## Overview Task Scheduler API implementation. -This API provides the functionality to get information related to the scheduler settings and current tasks. - -### Supported methods - -- **Getters** : - - Get all tasks - - Get task information - - Get task results - - Get output path for task results -- **Setters** : - - Set output path for task results - - Set task settings -- **Actions** : - - Run task - - Create task - - Delete task - - Enable task - - Disable task + This API provides the functionality to get information related to the scheduler settings and current tasks. + + ### Supported methods + + - **Getters** : + - Get all tasks + - Get task information + - Get task results + - Get output path for task results + - **Setters** : + - Set output path for task results + - Set task settings + - **Actions** : + - Run task + - Create task + - Delete task + - Enable task + - Disable task ## Methods ### `get_output_config` Retrieve tasks output configuration. @@ -44,6 +44,20 @@ Retrieve tasks output configuration. A dictionary containing a list of the tasks and information related to them.
+#### Example return +
+Click to expand +```json +{ + "data": { + "enable_output": true, + "output_path": "share/scripts_output", + "type": "esynoscheduler", + }, + "success": true +} +``` +
@@ -60,7 +74,7 @@ List all present scheduled tasks and event triggered tasks. #### Parameters
-**_sort_by_** `str, optional ` +**_sort_by_** `str` The field to sort tasks by. Defaults to `"next_trigger_time"`. Possible values: - "next_trigger_time" @@ -69,16 +83,16 @@ Possible values: - "action" - "owner" -**_sort_direction_** `str, optional ` +**_sort_direction_** `str` The sort direction. Defaults to `"ASC"`. Possible values: - "ASC" - "DESC" -**_offset_** `int, optional ` +**_offset_** `int` Task offset for pagination. Defaults to `0`. -**_limit_** `int, optional ` +**_limit_** `int` Number of tasks to retrieve. Defaults to `50`. @@ -136,7 +150,7 @@ A dictionary containing a list of the tasks and information related to them. ### `get_task_config` -Retrieve the configuration for a specific task or list of all the available services and their corresponding IDs. +Retrieve the configuration for a specific task or list all available services and their corresponding IDs. #### Internal API
@@ -145,14 +159,14 @@ Retrieve the configuration for a specific task or list of all the available serv #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task to retrieve the configuration for. Pass `-1` to get a list of all available services with their IDs. -**_real_owner_** `str ` -The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. +**_real_owner_** `str` +The real owner of the task, usually `root`. You can double check from the result of `get_task_config()`. -**_type_** `str, optional ` -The type of task (e.g., 'service'). Pass "service" to get a list of all available services with their IDs. Defaults to `""`. +**_type_** `str` +The type of task (e.g., 'service'). Pass `"service"` to get a list of all available services with their IDs. Defaults to `""`.
@@ -224,7 +238,7 @@ Retrieve the results list for a specific task. #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task to retrieve the results for. @@ -276,11 +290,11 @@ Configure the output settings for tasks results. #### Parameters
-**_enable_output_** `bool ` +**_enable_output_** `bool` Whether to enable result logging or not. -**_output_path_** `str, optional ` -The path where the result logs will be stored, e.g. `share/scripts_output'`. Defaults to `""`. +**_output_path_** `str` +The path where the result logs will be stored, e.g. `share/scripts_output`. Defaults to `""`.
@@ -294,10 +308,10 @@ A dictionary containing the result of the output configuration.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -315,10 +329,10 @@ Enable or disable a task. #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task to be enabled. -**_real_owner_** `str ` +**_real_owner_** `str` The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. **_enable_** `bool` @@ -336,10 +350,10 @@ A dictionary containing the result of the task enabling.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -357,10 +371,10 @@ Run a specific task. #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task to be run. -**_real_owner_** `str ` +**_real_owner_** `str` The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. @@ -375,10 +389,10 @@ A dictionary containing the result of the task execution.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -396,10 +410,10 @@ Delete a specific task. #### Parameters
-**_task_id_** `int ` +**_task_id_** `int` The ID of the task to be deleted. -**_real_owner_** `str ` +**_real_owner_** `str` The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. @@ -414,10 +428,10 @@ A dictionary containing the result of the task deletion.
Click to expand ```json -{ - "success": true -} -``` + { + "success": true + } + ```
@@ -426,7 +440,7 @@ A dictionary containing the result of the task deletion. ### `create_script_task` -Create a new Script task with the provided schedule and notification settings. +Create a new Script task with the provided schedule and notification settings. :::tip If the task needs to run with root privileges, please specify the owner as "root". @@ -440,28 +454,28 @@ Create a new Script task with the provided schedule and notification settings. #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_owner_** `str ` +**_owner_** `str` The task owner. If the task needs to run with root privileges, please specify the owner as "root". -**_script_** `str ` +**_script_** `str` The script to be executed. -**_enable_** `bool, optional ` +**_enable_** `bool` Whether the task should be enabled upon creation. Defaults to `True`. -**_run_frequently_** `bool, optional ` +**_run_frequently_** `bool` Determines whether the task runs on a recurring schedule (`True`) or only on a specific date (`False`). Defaults to `True`. -**_run_days_** `str, optional ` +**_run_days_** `str` Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). -**_run_date_** `str, optional ` +**_run_date_** `str` The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` +**_repeat_** `str` How often the task should repeat. Defaults to `daily`. Possible values: - `daily` -> Only when 'run_frequently=True' @@ -472,35 +486,35 @@ Possible values: - `every_6_months` -> Only when 'run_frequently=False' - `yearly` -> Only when 'run_frequently=False' -**_monthly_week_** `list[str], optional ` -If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. +**_monthly_week_** `list[str]` +If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. -**_start_time_h_** `int, optional ` +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). Possible values: `0..23` The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). Posible values: `1`, `5`, `10`, `15`, `20`, `30` The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. -**_notify_email_** `str, optional ` +**_notify_email_** `str` Email address to send notifications to. Defaults to `""`, thus disabling the notification feature. -**_notify_only_on_error_** `bool, optional ` +**_notify_only_on_error_** `bool` If `True`, notifications are only sent when an error occurs. Defaults to `False`. @@ -515,13 +529,13 @@ A dictionary with the id of the created task.
Click to expand ```json -{ - "data": { - "id": 20 - }, - "success": true -} -``` + { + "data": { + "id": 20 + }, + "success": true + } + ```
@@ -530,14 +544,13 @@ A dictionary with the id of the created task. ### `modify_script_task` -Modify settings of a Script task. +Modify settings of a Script task. :::warning - This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. + This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. ::: - :::tip If the task needs to run with root privileges, please specify the owner as "root". @@ -554,31 +567,31 @@ Modify settings of a Script task. **_task_id_** `int` The ID of the task. -**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_owner_** `str ` +**_owner_** `str` The task owner. If the task needs to run with root privileges, please specify the owner as "root". -**_real_owner_** `str ` +**_real_owner_** `str` The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. -**_script_** `str ` +**_script_** `str` The script to be executed. -**_enable_** `bool, optional ` +**_enable_** `bool` Whether the task should be enabled upon creation. Defaults to `True`. -**_run_frequently_** `bool, optional ` +**_run_frequently_** `bool` Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. -**_run_days_** `str, optional ` +**_run_days_** `str` Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). -**_run_date_** `str, optional ` +**_run_date_** `str` The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` +**_repeat_** `str` How often the task should repeat. Defaults to `'daily'`. Possible values: - `daily` -> Only when 'run_frequently=True' @@ -589,34 +602,34 @@ Possible values: - `every_6_months` -> Only when 'run_frequently=False' - `yearly` -> Only when 'run_frequently=False' -**_monthly_week_** `list[str], optional ` +**_monthly_week_** `list[str]` If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. -**_start_time_h_** `int, optional ` +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. Set to `0` to disable same-day repeats. Defaults to `0`. Possible values: `0..23` The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. Set to `0` to disable same-day repeats. Defaults to `0`. Posible values: `1`, `5`, `10`, `15`, `20`, `30` The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. -**_notify_email_** `str, optional ` +**_notify_email_** `str` Email address to send notifications to. Defaults to `""`, thus disabling the notification feature. -**_notify_only_on_error_** `bool, optional ` +**_notify_only_on_error_** `bool` If `True`, notifications are only sent when an error occurs. Defaults to `False`. @@ -631,13 +644,13 @@ A dictionary with the id of the created task.
Click to expand ```json -{ - "data": { - "id": 20 - }, - "success": true -} -``` + { + "data": { + "id": 20 + }, + "success": true + } + ```
@@ -655,62 +668,61 @@ Create a new Beep Control task with the provided schedule and beep duration. #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_owner_** `str ` +**_owner_** `str` The task owner. -**_beep_duration_** `int, optional ` -The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. +**_enable_** `bool` +Whether the task should be enabled upon creation. Defaults to True. -**_enable_** `bool, optional ` -Whether the task should be enabled upon creation. Defaults to `True`. +**_beep_duration_** `int` +The amount of seconds the beep will be triggered for. Defaults to 60. -**_run_frequently_** `bool, optional ` -Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. +**_run_frequently_** `bool` +Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to True. -**_run_days_** `str, optional ` -Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). +**_run_days_** `str` +Days of the week when the task should run, used if `run_frequently` is set to True, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to '0,1,2,3,4,5,6'. -**_run_date_** `str, optional ` -The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. +**_run_date_** `str` +The specific date the task should run, used if `run_frequently` is set to False. Format: yyyy/m/d (no prefix zeros). Defaults to "". -**_repeat_** `str, optional ` -How often the task should repeat. Defaults to `'daily'`. +**_repeat_** `str` +How often the task should repeat. Defaults to 'daily'. Possible values: -- `daily` -> Only when 'run_frequently=True' -- `weekly` -> Only when 'run_frequently=True' -- `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' -- `no_repeat` -> Only when 'run_frequently=False' -- `every_3_months` -> Only when 'run_frequently=False' -- `every_6_months` -> Only when 'run_frequently=False' -- `yearly` -> Only when 'run_frequently=False' + - 'daily' -> Only when run_frequently=True + - 'weekly' -> Only when run_frequently=True + - 'monthly' -> Works for both run_frequently=True and run_frequently=False + - 'no_repeat' -> Only when run_frequently=False + - 'every_3_months' -> Only when run_frequently=False + - 'every_6_months' -> Only when run_frequently=False + - 'yearly' -> Only when run_frequently=False -**_monthly_week_** `list[str], optional ` -If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. -Defaults to `[]`. +**_monthly_week_** `list[str]` +If run_frequently=True and repeat='monthly', specifies the weeks the task should run, e.g., ['first', 'third']. Defaults to []. -**_start_time_h_** `int, optional ` -Hour at which the task should start. Defaults to `0`. +**_start_time_h_** `int` +Hour at which the task should start. Defaults to 0. -**_start_time_m_** `int, optional ` -Minute at which the task should start. Defaults to `0`. +**_start_time_m_** `int` +Minute at which the task should start. Defaults to 0. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. -Possible values: `0..23` -The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to 0 to disable same-day repeats. Defaults to 0. +Possible values: 0..23 +The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time, if both are passed, same_day_repeat_h will be prioritized. -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. -Posible values: `1`, `5`, `10`, `15`, `20`, `30` -The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to 0 to disable same-day repeats. Defaults to 0. +Possible values: 1, 5, 10, 15, 20, 30 +The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time, if both are passed, same_day_repeat_h will be prioritized. -**_same_day_repeat_until_** `int, optional ` -Last hour of the day when the task can repeat. Defaults to `start_time_h`. +**_same_day_repeat_until_** `int` +Last hour of the day when the task can repeat. Defaults to start_time_h.
@@ -739,13 +751,8 @@ A dictionary with the id of the created task. ### `modify_beep_control_task` -Modify settings of a Beep Control task. -:::warning - - This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. - -::: - +Modify settings of a Beep Control task. + #### Internal API
`SYNO.Core.TaskScheduler` @@ -753,49 +760,52 @@ Modify settings of a Beep Control task. #### Parameters
-**_task_name_** `str ` +**_task_id_** `int` +The ID of the task to modify. + +**_task_name_** `str` The name of the task. -**_real_owner_** `str ` +**_real_owner_** `str` The task owner. -**_beep_duration_** `int, optional ` -The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. +**_enable_** `bool` +Whether the task should be enabled upon modification. Defaults to `True`. -**_enable_** `bool, optional ` -Whether the task should be enabled upon creation. Defaults to `True`. +**_beep_duration_** `int` +The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. -**_run_frequently_** `bool, optional ` -Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. +**_run_frequently_** `bool` +Determines whether the task runs on a recurring schedule (`True`) or only on a specific date (`False`). Defaults to `True`. -**_run_days_** `str, optional ` +**_run_days_** `str` Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). -**_run_date_** `str, optional ` +**_run_date_** `str` The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` +**_repeat_** `str` How often the task should repeat. Defaults to `'daily'`. Possible values: -- `daily` -> Only when 'run_frequently=True' -- `weekly` -> Only when 'run_frequently=True' -- `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' -- `no_repeat` -> Only when 'run_frequently=False' -- `every_3_months` -> Only when 'run_frequently=False' -- `every_6_months` -> Only when 'run_frequently=False' -- `yearly` -> Only when 'run_frequently=False' - -**_monthly_week_** `list[str], optional ` + - `daily` -> Only when `run_frequently=True` + - `weekly` -> Only when `run_frequently=True` + - `monthly` -> Works for both `run_frequently=True` and `run_frequently=False` + - `no_repeat` -> Only when `run_frequently=False` + - `every_3_months` -> Only when `run_frequently=False` + - `every_6_months` -> Only when `run_frequently=False` + - `yearly` -> Only when `run_frequently=False` + +**_monthly_week_** `list[str]` If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. -**_start_time_h_** `int, optional ` +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. Set to `0` to disable same-day repeats. Defaults to `0`. Possible values: `0..23` :::info @@ -805,10 +815,10 @@ Possible values: `0..23` ::: -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. Set to `0` to disable same-day repeats. Defaults to `0`. -Posible values: `1`, `5`, `10`, `15`, `20`, `30` +Possible values: `1`, `5`, `10`, `15`, `20`, `30` :::info The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. @@ -816,7 +826,7 @@ Posible values: `1`, `5`, `10`, `15`, `20`, `30` ::: -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. @@ -824,7 +834,7 @@ Last hour of the day when the task can repeat. Defaults to `start_time_h`. #### Returns
`dict[str, object]` -A dictionary with the id of the created task. +A dictionary with the id of the modified task.
#### Example return @@ -855,15 +865,15 @@ Create a new Service Control task with the provided schedule and services to sta #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_owner_** `str ` +**_owner_** `str` The task owner. -**_services (list)_** `` +**_services_** `list[dict]` A list containing the services and their type to be influenced by the specified action (start / stop). -To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. +To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. E.g.: ```python [ @@ -873,23 +883,23 @@ E.g.: ] ``` -**_action_** `str ` +**_action_** `str` The action to apply to the services. Either `'start'` or `'stop'`. -**_enable_** `bool, optional ` +**_enable_** `bool` Whether the task should be enabled upon creation. Defaults to `True`. -**_run_frequently_** `bool, optional ` +**_run_frequently_** `bool` Determines whether the task runs on a recurring schedule (`True`) or only on a specific date (`False`). Defaults to `True`. -**_run_days_** `str, optional ` +**_run_days_** `str` Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). -**_run_date_** `str, optional ` +**_run_date_** `str` The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` -How often the task should repeat. Defaults to `'daily'`. +**_repeat_** `str` +How often the task should repeat. Defaults to `'daily'`. Possible values: - `daily` -> Only when 'run_frequently=True' - `weekly` -> Only when 'run_frequently=True' @@ -899,18 +909,18 @@ Possible values: - `every_6_months` -> Only when 'run_frequently=False' - `yearly` -> Only when 'run_frequently=False' -**_monthly_week_** `list[str], optional ` +**_monthly_week_** `list[str]` If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. -**_start_time_h_** `int, optional ` +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. Possible values: `0..23` :::info @@ -919,9 +929,9 @@ Possible values: `0..23` ::: -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. Posible values: `1`, `5`, `10`, `15`, `20`, `30` :::info @@ -930,7 +940,7 @@ Posible values: `1`, `5`, `10`, `15`, `20`, `30` ::: -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. @@ -945,13 +955,13 @@ A dictionary with the id of the created task.
Click to expand ```json -{ - "data": { - "id": 20 - }, - "success": true -} -``` + { + "data": { + "id": 20 + }, + "success": true + } + ```
@@ -960,7 +970,7 @@ A dictionary with the id of the created task. ### `modify_service_control_task` -Modify settings of a Service Control task. +Modify settings of a Service Control task. :::warning This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. @@ -977,15 +987,15 @@ Modify settings of a Service Control task. **_task_id_** `int` The ID of the task. -**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_real_owner_** `str ` +**_real_owner_** `str` The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. -**_services (list)_** `` +**_services_** `list[dict]` A list containing the services and their type to be influenced by the specified action (start / stop). -To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. +To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. E.g.: ```python [ @@ -995,25 +1005,25 @@ E.g.: ] ``` -**_action_** `str ` +**_action_** `str` The action to apply to the services. Either `'start'` or `'stop'`. -**_enable_** `bool, optional ` +**_enable_** `bool` Whether the task should be enabled upon creation. Defaults to `True`. -**_run_frequently_** `bool, optional ` +**_run_frequently_** `bool` Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. -**_run_days_** `str, optional ` -Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list +**_run_days_** `str` +Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). -**_run_date_** `str, optional ` -The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). +**_run_date_** `str` +The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` -How often the task should repeat. Defaults to `'daily'`. +**_repeat_** `str` +How often the task should repeat. Defaults to `'daily'`. Possible values: - `daily` -> Only when 'run_frequently=True' - `weekly` -> Only when 'run_frequently=True' @@ -1023,19 +1033,19 @@ Possible values: - `every_6_months` -> Only when 'run_frequently=False' - `yearly` -> Only when 'run_frequently=False' -**_monthly_week_** `list[str], optional ` -If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. +**_monthly_week_** `list[str]` +If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. -**_start_time_h_** `int, optional ` +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. Possible values: `0..23` :::info @@ -1044,9 +1054,9 @@ Possible values: `0..23` ::: -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0`. +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. Posible values: `1`, `5`, `10`, `15`, `20`, `30` :::info @@ -1055,7 +1065,7 @@ Posible values: `1`, `5`, `10`, `15`, `20`, `30` ::: -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. @@ -1070,13 +1080,13 @@ A dictionary with the id of the created task.
Click to expand ```json -{ - "data": { - "id": 20 - }, - "success": true -} -``` + { + "data": { + "id": 20 + }, + "success": true + } + ```
@@ -1085,7 +1095,7 @@ A dictionary with the id of the created task. ### `create_recycle_bin_task` -Create a new Recycle Bin Control task with the provided schedule and services to start/stop. +Create a new Recycle Bin Control task with the provided schedule and policy. #### Internal API
@@ -1094,86 +1104,84 @@ Create a new Recycle Bin Control task with the provided schedule and services to #### Parameters
-**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_owner_** `str ` +**_owner_** `str` The task owner. -**_clean_all_shares_** `bool ` -Whether the task should empty the recycle bins of all shares or not, if set to `False`, shares must be specified. +**_clean_all_shares_** `bool` +Whether the task should empty the recycle bins of all shares. If set to False, `shares` must be specified. -**_shares_** `list[str]` -List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to `[]`. - -**_policy (dict)_** `` -Determines what files will be deleted from the recycle bins. +**_policy_** `dict` +Determines what files will be deleted from the recycle bins. Possible values are: -- `{"policy": "clean_all"}` -> Clean all files -- `{"policy": "time", "time": int}` -> Clean all files older than X days, days being possed as value for "time" key. -- `{"policy": "size", "size": int , "sort_type": int}` -> Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". -Possible values for "sort_type" are: -- `0` -> Delete bigger files first -- `1` -> Delete older files first - -**_enable_** `bool, optional ` -Whether the task should be enabled upon creation. Defaults to `True`. - -**_run_frequently_** `bool, optional ` -Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. - -**_run_days_** `str, optional ` -Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). + - \{"policy": "clean_all"\}: Clean all files. + - \{"policy": "time", "time": int\}: Clean all files older than X days, where X is the value for "time". + - \{"policy": "size", "size": int, "sort_type": int\}: Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". +Possible values for "sort_type": + - 0: Delete bigger files first. + - 1: Delete older files first. -**_run_date_** `str, optional ` -The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). -Defaults to `""`. +**_shares_** `list[str]` +List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to []. -**_repeat_** `str, optional ` -How often the task should repeat. Defaults to `'daily'`. -Possible values: -- `daily` -> Only when 'run_frequently=True' -- `weekly` -> Only when 'run_frequently=True' -- `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' -- `no_repeat` -> Only when 'run_frequently=False' -- `every_3_months` -> Only when 'run_frequently=False' -- `every_6_months` -> Only when 'run_frequently=False' -- `yearly` -> Only when 'run_frequently=False' +**_enable_** `bool` +Whether the task should be enabled upon creation. Defaults to True. -**_monthly_week_** `list[str], optional ` -If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. -Defaults to `[]`. +**_run_frequently_** `bool` +Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to True. -**_start_time_h_** `int, optional ` -Hour at which the task should start. Defaults to `0`. +**_run_days_** `str` +Days of the week when the task should run, used if `run_frequently` is True, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to '0,1,2,3,4,5,6'. -**_start_time_m_** `int, optional ` -Minute at which the task should start. Defaults to `0`. +**_run_date_** `str` +The specific date the task should run, used if `run_frequently` is False. Format: yyyy/m/d (no prefix zeros). Defaults to "". -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). -Possible values: `0..23` -:::info +**_repeat_** `str` +How often the task should repeat. Defaults to 'daily'. +Possible values: + - 'daily' (only when run_frequently=True) + - 'weekly' (only when run_frequently=True) + - 'monthly' (works for both run_frequently=True and run_frequently=False) + - 'no_repeat' (only when run_frequently=False) + - 'every_3_months' (only when run_frequently=False) + - 'every_6_months' (only when run_frequently=False) + - 'yearly' (only when run_frequently=False) + +**_monthly_week_** `list[str]` +If run_frequently=True and repeat='monthly', specifies the weeks the task should run, e.g., ['first', 'third']. Defaults to []. + +**_start_time_h_** `int` +Hour at which the task should start. Defaults to 0. + +**_start_time_m_** `int` +Minute at which the task should start. Defaults to 0. + +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to 0 to disable same-day repeats. Defaults to 0. +Possible values: 0..23 +:::note - The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time; if both are passed, same_day_repeat_h will be prioritized. ::: -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). -Posible values: `1`, `5`, `10`, `15`, `20`, `30` -:::info +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to 0 to disable same-day repeats. Defaults to 0. +Possible values: 1, 5, 10, 15, 20, 30 +:::note - The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time; if both are passed, same_day_repeat_h will be prioritized. ::: -**_same_day_repeat_until_** `int, optional ` -Last hour of the day when the task can repeat. Defaults to `start_time_h`. +**_same_day_repeat_until_** `int` +Last hour of the day when the task can repeat. Defaults to start_time_h.
@@ -1181,11 +1189,8 @@ Last hour of the day when the task can repeat. Defaults to `start_time_h`.
`dict[str, object]` A dictionary with the id of the created task. - -
-#### Example return -
-Click to expand +Examples +-------- ```json { "data": { @@ -1193,7 +1198,20 @@ A dictionary with the id of the created task. }, "success": true } -``` +``` + +
+#### Example return +
+Click to expand +```json + { + "data": { + "id": 20 + }, + "success": true + } + ```
@@ -1202,13 +1220,8 @@ A dictionary with the id of the created task. ### `modify_recycle_bin_task` -Modify settings of a Recycle Bin Control task. -:::warning - - This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. - -::: - +Modify settings of a Recycle Bin Control task. + #### Internal API
`SYNO.Core.TaskScheduler` @@ -1219,65 +1232,63 @@ Modify settings of a Recycle Bin Control task. **_task_id_** `int` The ID of the task. -**_task_name_** `str ` +**_task_name_** `str` The name of the task. -**_real_owner_** `str ` -The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. +**_real_owner_** `str` +The task real owner, usually it is `root`. You can double check from the result of `get_task_config()`. + +**_clean_all_shares_** `bool` +Whether the task should empty the recycle bins of all shares. If set to `False`, `shares` must be specified. -**_clean_all_shares_** `bool ` -Whether the task should empty the recycle bins of all shares or not, if set to `False`, shares must be specified. +**_policy_** `dict` +Determines what files will be deleted from the recycle bins. +Possible values are: + - \{"policy": "clean_all"\}: Clean all files. + - \{"policy": "time", "time": int\}: Clean all files older than X days, where X is the value for "time". + - \{"policy": "size", "size": int, "sort_type": int\}: Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". +Possible values for "sort_type": + - 0: Delete bigger files first. + - 1: Delete older files first. **_shares_** `list[str]` -List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to `[]`. +List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to []. -**_policy (dict)_** `` -Determines what files will be deleted from the recycle bins. -Possible values are: -- `{"policy": "clean_all"}` -> Clean all files -- `{"policy": "time", "time": int}` -> Clean all files older than X days, days being possed as value for "time" key. -- `{"policy": "size", "size": int , "sort_type": int}` -> Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". -Possible values for "sort_type" are: -- `0` -> Delete bigger files first -- `1` -> Delete older files first - -**_enable_** `bool, optional ` -Whether the task should be enabled upon creation. Defaults to `True`. +**_enable_** `bool` +Whether the task should be enabled upon modification. Defaults to `True`. -**_run_frequently_** `bool, optional ` +**_run_frequently_** `bool` Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. -**_run_days_** `str, optional ` -Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). +**_run_days_** `str` +Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'`. -**_run_date_** `str, optional ` -The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). -Defaults to `""`. +**_run_date_** `str` +The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. -**_repeat_** `str, optional ` +**_repeat_** `str` How often the task should repeat. Defaults to `'daily'`. Possible values: -- `daily` -> Only when 'run_frequently=True' -- `weekly` -> Only when 'run_frequently=True' -- `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' -- `no_repeat` -> Only when 'run_frequently=False' -- `every_3_months` -> Only when 'run_frequently=False' -- `every_6_months` -> Only when 'run_frequently=False' -- `yearly` -> Only when 'run_frequently=False' - -**_monthly_week_** `list[str], optional ` -If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. -Defaults to `[]`. - -**_start_time_h_** `int, optional ` + - `daily` (only when run_frequently=True) + - `weekly` (only when run_frequently=True) + - `monthly` (works for both run_frequently=True and run_frequently=False) + - `no_repeat` (only when run_frequently=False) + - `every_3_months` (only when run_frequently=False) + - `every_6_months` (only when run_frequently=False) + - `yearly` (only when run_frequently=False) + +**_monthly_week_** `list[str]` +If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to []. + +**_start_time_h_** `int` Hour at which the task should start. Defaults to `0`. -**_start_time_m_** `int, optional ` +**_start_time_m_** `int` Minute at which the task should start. Defaults to `0`. -**_same_day_repeat_h_** `int, optional ` -Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). +**_same_day_repeat_h_** `int` +Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. Possible values: `0..23` :::info @@ -1286,10 +1297,10 @@ Possible values: `0..23` ::: -**_same_day_repeat_m_** `int, optional ` -Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. -Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). -Posible values: `1`, `5`, `10`, `15`, `20`, `30` +**_same_day_repeat_m_** `int` +Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. +Set to `0` to disable same-day repeats. Defaults to `0`. +Possible values: `1`, `5`, `10`, `15`, `20`, `30` :::info The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. @@ -1297,7 +1308,7 @@ Posible values: `1`, `5`, `10`, `15`, `20`, `30` ::: -**_same_day_repeat_until_** `int, optional ` +**_same_day_repeat_until_** `int` Last hour of the day when the task can repeat. Defaults to `start_time_h`. @@ -1305,7 +1316,7 @@ Last hour of the day when the task can repeat. Defaults to `start_time_h`. #### Returns
`dict[str, object]` -A dictionary with the id of the created task. +A dictionary with the id of the modified task.
#### Example return diff --git a/documentation/docs/apis/classes/universal_search.md b/documentation/docs/apis/classes/universal_search.md index fb1b5917..328ab16a 100644 --- a/documentation/docs/apis/classes/universal_search.md +++ b/documentation/docs/apis/classes/universal_search.md @@ -14,9 +14,31 @@ This API is not documented yet. ::: ## Overview +API wrapper for Synology Universal Search. +Provides methods to perform keyword-based searches using Synology's Universal Search API. ## Methods ### `search` +Search for files and metadata matching the given keyword. + +#### Internal API +
+`SYNO.Finder.FileIndexing.Search` +
+ +#### Parameters +
+**_keyword_** `str` +The search keyword. + + +
+#### Returns +
+`dict[str, object] or str` +Search results as a dictionary, or a string with error details. + +
diff --git a/documentation/docs/apis/classes/usb_copy.md b/documentation/docs/apis/classes/usb_copy.md index 2ccbab77..06214515 100644 --- a/documentation/docs/apis/classes/usb_copy.md +++ b/documentation/docs/apis/classes/usb_copy.md @@ -9,17 +9,17 @@ title: ✅ USBCopy # USBCopy ## Overview -USB Copy Implementation. +USB Copy API wrapper for Synology NAS. -### Supported methods +Methods +------- +**Getters** : + - Get package settings + - Get package logs + - Get task settings - - **Getters** : - - Get package settings - - Get package logs - - Get task settings - - - **Actions** : - - Enable / Disable task +**Actions** : + - Enable / Disable task ## Methods ### `get_package_settings` Retrieve package settings. @@ -32,21 +32,21 @@ Retrieve package settings. #### Returns
`dict[str, object]` -Parsed JSON into `dict` +Parsed JSON into a dictionary.
#### Example return
Click to expand ```python -{ - "data" : { - "beep_on_task_start_end" : True, - "log_rotate_count" : 100000, - "repo_volume_path" : "/volume2" - }, - "success" : True -} + { + "data": { + "beep_on_task_start_end": True, + "log_rotate_count": 100000, + "repo_volume_path": "/volume2" + }, + "success": True + } ```
@@ -66,39 +66,39 @@ Retrieve package logs. #### Parameters
**_offset_** `int` -Defaults to `0`. +Offset for logs. Defaults to 0. **_limit_** `int` -Defaults to `200`. +Maximum number of logs to retrieve. Defaults to 200.
#### Returns
`dict[str, object]` -Parsed response JSON into `dict` +Parsed response JSON into a dictionary.
#### Example return
Click to expand ```python -{ - "data" : { - "count" : 1, - "log_list" : [ - { - "description_id" : 101, - "description_parameter" : "["asdf"]", - "error" : 0, - "log_type" : 1, - "task_id" : 2, - "timestamp" : 1738341351 - }, - ] - }, - "success" : True -} + { + "data": { + "count": 1, + "log_list": [ + { + "description_id": 101, + "description_parameter": "["asdf"]", + "error": 0, + "log_type": 1, + "task_id": 2, + "timestamp": 1738341351 + } + ] + }, + "success": True + } ```
@@ -108,7 +108,7 @@ Parsed response JSON into `dict` ### `get_task_settings` -Retrieve task settings +Retrieve task settings. #### Internal API
@@ -118,54 +118,54 @@ Retrieve task settings #### Parameters
**_task_id_** `int` -Task ID to retrieve info for +Task ID to retrieve info for.
#### Returns
`dict[str, object]` -Parsed response JSON into `dict` +Parsed response JSON into a dictionary.
#### Example return
Click to expand ```python -{ - "data" : { - "task" : { - "conflict_policy" : "rename", - "copy_file_path" : "", - "copy_strategy" : "versioning", - "default_device_port" : "NA", - "destination_path" : "[USB]", - "eject_when_task_done" : True, - "enable_rotation" : False, - "error_code" : 0, - "id" : 2, - "is_default_task" : False, - "is_ds_mounted" : False, - "is_task_runnable" : False, - "is_usb_mounted" : False, - "latest_finish_time" : 1738341351, - "max_version_count" : 256, - "name" : "asdf", - "next_run_time" : "N/A", - "not_keep_dir_structure" : False, - "remove_src_file" : False, - "rename_photo_video" : False, - "rotation_policy" : "oldest_version", - "run_when_plug_in" : False, - "schedule_id" : 13, - "smart_create_date_dir" : False, - "source_path" : "/music", - "status" : "unmounted", - "type" : "export_general" - } - }, - "success" : True -} + { + "data": { + "task": { + "conflict_policy": "rename", + "copy_file_path": "", + "copy_strategy": "versioning", + "default_device_port": "NA", + "destination_path": "[USB]", + "eject_when_task_done": True, + "enable_rotation": False, + "error_code": 0, + "id": 2, + "is_default_task": False, + "is_ds_mounted": False, + "is_task_runnable": False, + "is_usb_mounted": False, + "latest_finish_time": 1738341351, + "max_version_count": 256, + "name": "asdf", + "next_run_time": "N/A", + "not_keep_dir_structure": False, + "remove_src_file": False, + "rename_photo_video": False, + "rotation_policy": "oldest_version", + "run_when_plug_in": False, + "schedule_id": 13, + "smart_create_date_dir": False, + "source_path": "/music", + "status": "unmounted", + "type": "export_general" + } + }, + "success": True + } ```
@@ -175,7 +175,7 @@ Parsed response JSON into `dict` ### `toggle_task` -Enable or disable USB Copy task +Enable or disable a USB Copy task. #### Internal API
@@ -188,23 +188,23 @@ Enable or disable USB Copy task Task ID to apply the setting to. **_enable_** `bool` -Whether to enable (`True`) or disable (`False`) USB Copy. Defaults to `True`. +Whether to enable (True) or disable (False) the USB Copy task. Defaults to True.
#### Returns
`dict[str, object]` -Parsed response JSON into `dict` +Parsed response JSON into a dictionary.
#### Example return
Click to expand ```python -{ - "success": True -} + { + "success": True + } ```
diff --git a/documentation/docs/apis/classes/virtualization.md b/documentation/docs/apis/classes/virtualization.md index b1a462af..06f255c8 100644 --- a/documentation/docs/apis/classes/virtualization.md +++ b/documentation/docs/apis/classes/virtualization.md @@ -14,9 +14,45 @@ This API is not documented yet. ::: ## Overview - +API wrapper for Synology Virtual Machine Manager. + +Provides methods to manage tasks, networks, storage, hosts, VMs, and images. + +Parameters +---------- +ip_address : str + IP address of the Synology NAS. +port : str + Port number to connect to. +username : str + DSM username. +password : str + DSM password. +secure : bool, optional + Use HTTPS if True. Default is False. +cert_verify : bool, optional + Verify SSL certificate if True. Default is False. +dsm_version : int, optional + DSM version. Default is 7. +debug : bool, optional + Enable debug mode. Default is True. +otp_code : str, optional + One-time password for 2FA, if required. ## Methods ### `get_task_list` +Get the list of virtualization tasks. + +#### Internal API +
+`SYNO.Virtualization.API.Task.Info` +
+ +#### Returns +
+`list of str` +List of task IDs. + +
@@ -24,6 +60,26 @@ This API is not documented yet. ### `clear_task` +Clear a specific task by its ID. + +#### Internal API +
+`SYNO.Virtualization.API.Task.Info` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID to clear. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the clear operation or error message. + +
@@ -31,6 +87,26 @@ This API is not documented yet. ### `get_task_info` +Get information about a specific task. + +#### Internal API +
+`SYNO.Virtualization.API.Task.Info` +
+ +#### Parameters +
+**_taskid_** `str` +Task ID to retrieve information for. + + +
+#### Returns +
+`dict[str, object] or str` +Task information or error message. + +
@@ -38,6 +114,19 @@ This API is not documented yet. ### `get_network_group_list` +Get the list of network groups. + +#### Internal API +
+`SYNO.Virtualization.API.Network` +
+ +#### Returns +
+`list of dict` +List of network group information. + +
@@ -45,6 +134,19 @@ This API is not documented yet. ### `get_storage_operation` +Get the list of storage operations. + +#### Internal API +
+`SYNO.Virtualization.API.Storage` +
+ +#### Returns +
+`list of str` +List of storage operation information. + +
@@ -52,6 +154,19 @@ This API is not documented yet. ### `get_host_operation` +Get the list of host operations. + +#### Internal API +
+`SYNO.Virtualization.API.Host` +
+ +#### Returns +
+`list of str` +List of host operation information. + +
@@ -59,6 +174,26 @@ This API is not documented yet. ### `get_vm_operation` +Get the list of virtual machines. + +#### Internal API +
+`SYNO.Virtualization.API.Guest` +
+ +#### Parameters +
+**_additional_** `bool` +Whether to include additional information. Default is False. + + +
+#### Returns +
+`list of dict` +List of VM information. + +
@@ -66,6 +201,32 @@ This API is not documented yet. ### `get_specific_vm_info` +Get information about a specific virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest` +
+ +#### Parameters +
+**_additional_** `str or list of str` +Additional fields to include. + +**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + + +
+#### Returns +
+`dict[str, object] or str` +VM information or error message. + +
@@ -73,6 +234,44 @@ This API is not documented yet. ### `set_vm_property` +Set properties for a virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest` +
+ +#### Parameters +
+**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + +**_autorun_** `int` +Autorun setting (0: off, 1: last state, 2: on). + +**_description_** `str` +VM description. + +**_new_guest_name_** `str` +New VM name. + +**_vcpu_num_** `int` +Number of virtual CPUs. + +**_vram_size_** `int` +RAM size in MB. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the set operation or error message. + +
@@ -80,6 +279,29 @@ This API is not documented yet. ### `delete_vm` +Delete a virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest` +
+ +#### Parameters +
+**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error message. + +
@@ -87,6 +309,35 @@ This API is not documented yet. ### `vm_power_on` +Power on a virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Action` +
+ +#### Parameters +
+**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + +**_host_id_** `str` +Host ID. + +**_host_name_** `str` +Host name. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the power on operation or error message. + +
@@ -94,6 +345,29 @@ This API is not documented yet. ### `vm_force_power_off` +Force power off a virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Action` +
+ +#### Parameters +
+**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the power off operation or error message. + +
@@ -101,6 +375,29 @@ This API is not documented yet. ### `vm_shut_down` +Shut down a virtual machine. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Action` +
+ +#### Parameters +
+**_guest_id_** `str` +Guest VM ID. + +**_guest_name_** `str` +Guest VM name. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the shutdown operation or error message. + +
@@ -108,6 +405,19 @@ This API is not documented yet. ### `get_images_list` +Get the list of VM images. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Image` +
+ +#### Returns +
+`dict[str, object]` +Dictionary containing image information. + +
@@ -115,6 +425,29 @@ This API is not documented yet. ### `delete_image` +Delete a VM image. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Image` +
+ +#### Parameters +
+**_image_id_** `str` +Image ID. + +**_image_name_** `str` +Image name. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the delete operation or error message. + +
@@ -122,6 +455,41 @@ This API is not documented yet. ### `create_image` +Create a new VM image. + +#### Internal API +
+`SYNO.Virtualization.API.Guest.Image` +
+ +#### Parameters +
+**_auto_clean_task_** `bool` +Whether to auto-clean the task after creation. Default is True. + +**_storage_names_** `str` +Storage names. + +**_storage_ids_** `str` +Storage IDs. + +**_type_** `str` +Image type ('disk', 'vdsm', or 'iso'). + +**_ds_file_path_** `str` +File path (should begin with a shared folder). + +**_image_name_** `str` +Name of the image. + + +
+#### Returns +
+`dict[str, object] or str` +Result of the create operation or error message. + +
diff --git a/documentation/docs/apis/classes/vpn.md b/documentation/docs/apis/classes/vpn.md index a0ca683e..33872cb0 100644 --- a/documentation/docs/apis/classes/vpn.md +++ b/documentation/docs/apis/classes/vpn.md @@ -14,9 +14,25 @@ This API is not documented yet. ::: ## Overview +API wrapper for Synology VPN Server. +Provides methods to retrieve VPN settings, active connections, logs, network interfaces, +security autoblock settings, permissions, and VPN protocol-specific settings. ## Methods ### `settings_list` +Retrieve VPN server settings. + +#### Internal API +
+`SYNO.VPNServer.Settings.Config` +
+ +#### Returns +
+`dict[str, object] or str` +VPN server settings as a dictionary, or an error message as a string. + +
@@ -24,6 +40,35 @@ This API is not documented yet. ### `active_connections_list` +Retrieve a list of active VPN connections. + +#### Internal API +
+`SYNO.VPNServer.Management.Connection` +
+ +#### Parameters +
+**_sort_** `str` +Field to sort by. Default is 'login_time'. + +**_sort_dir_** `str` +Sort direction ('ASC' or 'DESC'). Default is 'DESC'. + +**_start_** `int` +Pagination start index. Default is 0. + +**_limit_** `int` +Maximum number of results to return. Default is 100. + + +
+#### Returns +
+`dict[str, object] or str` +Active connections as a dictionary, or an error message as a string. + +
@@ -31,6 +76,32 @@ This API is not documented yet. ### `log_list` +Retrieve VPN server logs. + +#### Internal API +
+`SYNO.VPNServer.Management.Log` +
+ +#### Parameters +
+**_start_** `int` +Pagination start index. Default is 0. + +**_limit_** `int` +Maximum number of logs to return. Default is 50. + +**_prtltype_** `int` +Protocol type filter. Default is 0 (all). + + +
+#### Returns +
+`dict[str, object] or str` +Logs as a dictionary, or an error message as a string. + +
@@ -38,6 +109,19 @@ This API is not documented yet. ### `network_interface_setting` +Retrieve VPN network interface settings. + +#### Internal API +
+`SYNO.VPNServer.Management.Interface` +
+ +#### Returns +
+`dict[str, object] or str` +Network interface settings as a dictionary, or an error message as a string. + +
@@ -45,6 +129,19 @@ This API is not documented yet. ### `security_autoblock_setting` +Retrieve security autoblock settings. + +#### Internal API +
+`SYNO.Core.Security.AutoBlock` +
+ +#### Returns +
+`dict[str, object] or str` +Autoblock settings as a dictionary, or an error message as a string. + +
@@ -52,6 +149,29 @@ This API is not documented yet. ### `permission_setting` +Retrieve VPN permission settings. + +#### Internal API +
+`SYNO.VPNServer.Management.Account` +
+ +#### Parameters +
+**_start_** `int` +Pagination start index. Default is 0. + +**_limit_** `int` +Maximum number of results to return. Default is 100. + + +
+#### Returns +
+`dict[str, object] or str` +Permission settings as a dictionary, or an error message as a string. + +
@@ -59,6 +179,19 @@ This API is not documented yet. ### `pptp_settings_info` +Retrieve PPTP VPN settings. + +#### Internal API +
+`SYNO.VPNServer.Settings.Config` +
+ +#### Returns +
+`dict[str, object] or str` +PPTP settings as a dictionary, or an error message as a string. + +
@@ -66,6 +199,19 @@ This API is not documented yet. ### `openvpn_settings_info` +Retrieve OpenVPN settings. + +#### Internal API +
+`SYNO.VPNServer.Settings.Config` +
+ +#### Returns +
+`dict[str, object] or str` +OpenVPN settings as a dictionary, or an error message as a string. + +
@@ -73,6 +219,46 @@ This API is not documented yet. ### `l2tp_settings_info` +Retrieve L2TP VPN settings. + +#### Internal API +
+`SYNO.VPNServer.Settings.Config` +
+ +#### Returns +
+`dict[str, object] or str` +L2TP settings as a dictionary, or an error message as a string. + +
+ + + +--- + + +### `openvpn_export_configuration` +Download the OpenVPN configuration as a zip file or bytes. + +#### Internal API +
+`SYNO.VPNServer.Settings.Certificate` +
+ +#### Parameters +
+**_as_zip_file_** `bool` +If True, return a ZipFile object. If False, return bytes. Default is False. + + +
+#### Returns +
+`bytes or ZipFile` +The OpenVPN configuration file as bytes, or a ZipFile object if `as_zip_file` is True. + +
diff --git a/documentation/docs/apis/readme.md b/documentation/docs/apis/readme.md index c51368e9..a8630c4a 100644 --- a/documentation/docs/apis/readme.md +++ b/documentation/docs/apis/readme.md @@ -63,24 +63,28 @@ At the moment there are quite a few APIs implemented. They could be totally or p ### [Share](./apis/classes/core_share) - `SYNO.Core.Share` +- `SYNO.Core.Share.Crypto` - `SYNO.Core.Share.Permission` - `SYNO.Core.Share.KeyManager.Store` - `SYNO.Core.Share.KeyManager.AutoKey` ### [SharePermission](./apis/classes/core_share) - `SYNO.Core.Share` +- `SYNO.Core.Share.Crypto` - `SYNO.Core.Share.Permission` - `SYNO.Core.Share.KeyManager.Store` - `SYNO.Core.Share.KeyManager.AutoKey` ### [KeyManagerStore](./apis/classes/core_share) - `SYNO.Core.Share` +- `SYNO.Core.Share.Crypto` - `SYNO.Core.Share.Permission` - `SYNO.Core.Share.KeyManager.Store` - `SYNO.Core.Share.KeyManager.AutoKey` ### [KeyManagerAutoKey](./apis/classes/core_share) - `SYNO.Core.Share` +- `SYNO.Core.Share.Crypto` - `SYNO.Core.Share.Permission` - `SYNO.Core.Share.KeyManager.Store` - `SYNO.Core.Share.KeyManager.AutoKey` @@ -148,7 +152,6 @@ At the moment there are quite a few APIs implemented. They could be totally or p - `SYNO.Core.ExternalDevice.Storage.eSATA` - `SYNO.Finder.FileIndexing.Status` - `SYNO.Core.CMS.Info` -- `SYNO.Core.Service.PortInfo` - `SYNO.Core.PortForwarding.Rules` - `SYNO.Core.PortForwarding.RouterConf` - `SYNO.Core.Polling.Data` @@ -215,12 +218,17 @@ At the moment there are quite a few APIs implemented. They could be totally or p - `SYNO.Docker.Image` - `SYNO.Docker.Registry` - `SYNO.Docker.Network` +- `SYNO.Docker.Project` +- `SYNO.Docker.Container.Profile` +- `SYNO.Docker.Container.Log` ### [DownloadStation](./apis/classes/downloadstation) - `SYNO.DownloadStation.Info` - `SYNO.DownloadStation.Schedule` - `SYNO.DownloadStation{DOWNLOAD_ST_VERSION}.Task` - `SYNO.DownloadStation2.Task.Source` +- `SYNO.DownloadStation{DOWNLOAD_ST_VERSION}.Task.List` +- `SYNO.DownloadStation{DOWNLOAD_ST_VERSION}.Task.List.Polling` - `SYNO.DownloadStation.Statistic` - `SYNO.DownloadStation.RSS.Site` - `SYNO.DownloadStation{DOWNLOAD_ST_VERSION}.RSS.Feed` diff --git a/documentation/package-lock.json b/documentation/package-lock.json index bf0941f1..f1dc55c4 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -167,6 +167,7 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.20.0.tgz", "integrity": "sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==", "license": "MIT", + "peer": true, "dependencies": { "@algolia/client-common": "5.20.0", "@algolia/requester-browser-xhr": "5.20.0", @@ -305,6 +306,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz", "integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==", "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -2070,6 +2072,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2092,6 +2095,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2172,6 +2176,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2506,6 +2511,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3335,6 +3341,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.7.0.tgz", "integrity": "sha512-GXg5V7kC9FZE4FkUZA8oo/NrlRb06UwuICzI6tcbzj0+TVgjq/mpUXXzSgKzMS82YByi4dY2Q808njcBCyy6tQ==", "license": "MIT", + "peer": true, "dependencies": { "@docusaurus/core": "3.7.0", "@docusaurus/logger": "3.7.0", @@ -3951,6 +3958,7 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -4109,6 +4117,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.3.tgz", "integrity": "sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==", "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.1.2", @@ -4595,6 +4604,7 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -5005,6 +5015,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5338,6 +5349,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5393,6 +5405,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -5438,6 +5451,7 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.20.0.tgz", "integrity": "sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==", "license": "MIT", + "peer": true, "dependencies": { "@algolia/client-abtesting": "5.20.0", "@algolia/client-analytics": "5.20.0", @@ -5912,6 +5926,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -6434,16 +6449,16 @@ } }, "node_modules/compression": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", - "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "license": "MIT", "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", - "on-headers": "~1.0.2", + "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" }, @@ -6858,6 +6873,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8016,39 +8032,39 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.13.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -8094,6 +8110,21 @@ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, + "node_modules/express/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -8276,6 +8307,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -8479,6 +8511,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -8967,9 +9000,9 @@ } }, "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -10111,9 +10144,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -10748,9 +10781,9 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -12890,9 +12923,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", + "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -12989,6 +13022,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13123,9 +13157,9 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -13572,6 +13606,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -14475,6 +14510,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -15268,6 +15304,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -15416,6 +15453,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.25.0" }, @@ -15474,6 +15512,7 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/react": "*" }, @@ -15502,6 +15541,7 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -17340,6 +17380,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17719,6 +17760,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -17917,6 +17959,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -18154,6 +18197,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", diff --git a/requirements-dev.txt b/requirements-dev.txt index 24c1bd4c..8be12690 100644 Binary files a/requirements-dev.txt and b/requirements-dev.txt differ diff --git a/requirements.txt b/requirements.txt index 9f1d1105..f93c7126 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/setup.cfg b/setup.cfg index 2070cac7..f8e32896 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [tool:numpydoc_validation] ; to ignore some check add them after for example: checks = all,GL02, GL08 -checks = all,SA01,ES01,EX01 +checks = all,SA01,ES01,EX01,RT04,PR09 exclude = \.undocumented_method$,\.__repr__$ diff --git a/setup.py b/setup.py index 3c2703c0..d3542965 100644 --- a/setup.py +++ b/setup.py @@ -8,14 +8,16 @@ setup( name='synology-api', - version='0.8.1', + version='0.8.2', packages=find_packages(exclude=['tests*']), license='MIT', description='Python Synology API Wrapper', long_description=long_description, long_description_content_type='text/markdown', install_requires=['requests', 'urllib3', 'setuptools', - 'requests_toolbelt', 'tqdm', 'cryptography', 'treelib'], + 'requests_toolbelt', 'tqdm', 'cryptography', 'treelib', + 'noiseprotocol', + ], url='https://github.com/N4S4/synology-api', author='Renato Visaggio', author_email='synology.python.api@gmail.com' diff --git a/synology_api/DSM/ControlPanel/ApplicationPrivileges.py b/synology_api/DSM/ControlPanel/ApplicationPrivileges.py new file mode 100644 index 00000000..9224f438 --- /dev/null +++ b/synology_api/DSM/ControlPanel/ApplicationPrivileges.py @@ -0,0 +1,304 @@ +""" +Manage application privileges. +""" + +from synology_api import base_api +import json + + +class ApplicationPrivileges(base_api.BaseApi): + """ + Manage application privileges. + """ + + def list_all(self, offset: int = 0, limit: int = 20) -> dict: + """ + List applications privileges. + + Parameters + ---------- + offset : int, optional + Offset in the application list. Defaults to `0` + limit : int, optional + Limit the len of the returned list. Defaults to `20` + + Returns + ------- + dict + List of applications privileges. + + Examples + -------- + ```json + { + "data": { + "applications": [ + { + "app_id": "SYNO.AFP", + "grant_by_default": true, + "grant_type": [ + "local", + "domain", + "ldap" + ], + "isInternal": true, + "name": "AFP", + "service_type": "modules/LegacyApps", + "supportIP": true + }, + { + "app_id": "SYNO.Desktop", + "grant_by_default": true, + "grant_type": [ + "local", + "domain", + "ldap" + ], + "isInternal": true, + "name": "DSM", + "service_type": "modules/LegacyApps", + "supportIP": true + } + ], + "offset": 0, + "total": 2 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.AppPriv.App' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'offset': offset, + 'limit': limit + } + + return self.request_data(api_name, api_path, req_param) + + def list_entities(self, app_id: str, type: str = "local", filter_type: str = "all", rule_type: str = "user", offset: int = 0, limit: int = 50) -> dict: + """ + List entities of the specify app_id. + + Parameters + ---------- + app_id : str + Application ID + type : str, optional + Type to filter for rule_type. Defaults to `"local"` + Example: for rule_type = "user", type = "local" + All known values are: `["local"]` + filter_type : str, optional + Filter actual rules. Defaults to `"all"` + All known values are: `["all", "allow", "deny", "any", "custom"]` + rule_type : str, optional + Type of the rule. Defaults to `"user"` + All known values are: `["user", "group"]` + offset : int, optional + Offset in entity list. Defaults to `0` + limit : int, optional + Limit the len of the returned list. Defaults to `50` + + Returns + ------- + dict + Return list of entity available. + + Examples + -------- + ```json + { + "data": { + "offset": 0, + "total": 3, + "users": [ + { + "name": "admin" + }, + { + "name": "guest" + }, + { + "name": "test_api" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.AppPriv' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'action': 'list', + 'offset': offset, + 'limit': limit, + 'type': type, + 'app_id': app_id, + 'filter_type': filter_type, + 'rule_type': rule_type + } + + return self.request_data(api_name, api_path, req_param) + + def list_app_rules(self, app_id: str) -> dict: + """ + Retrieve application rules. + + Parameters + ---------- + app_id : str + Application ID + + Returns + ------- + dict + List of rules. + + Examples + -------- + ```json + "data": { + "rules": [ + { + "allow_ip": [ + "0.0.0.0" + ], + "app_id": "SYNO.AFP", + "deny_ip": [], + "entity_name": "everyone", + "entity_type": "everyone" + }, + { + "allow_ip": [ + "0.0.0.0" + ], + "app_id": "SYNO.AFP", + "deny_ip": [], + "entity_name": "test_api", + "entity_type": "user" + }, + { + "allow_ip": [ + "0.0.0.0" + ], + "app_id": "SYNO.AFP", + "deny_ip": [], + "entity_name": "test_group", + "entity_type": "group" + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.AppPriv.Rule' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'app_id': app_id + } + + return self.request_data(api_name, api_path, req_param) + + def set_app_rules(self, app_id: str, rules: list) -> dict: + """ + Set application rules. + + Parameters + ---------- + app_id : str + Application ID + rules : list + List of rules, a rule is a dict with the following keys: + ```json + { + "entity_type":"user", + "entity_name":"test_api", + "app_id":"SYNO.AFP", + "allow_ip":["0.0.0.0"], + "deny_ip":[] + } + ``` + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.AppPriv.Rule' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'app_id': app_id, + 'rules': json.dumps(rules) + } + + return self.request_data(api_name, api_path, req_param) + + def delete_app_rules(self, app_id: str, rules: list) -> dict: + """ + Delete application rules. + + Parameters + ---------- + app_id : str + Application ID + rules : list + List of rules, a rule is a dict with the following keys: + ```json + { + "entity_type":"user", + "entity_name":"test_api", + "app_id":"SYNO.AFP", + "allow_ip":["0.0.0.0"], + "deny_ip":[] + } + ``` + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.AppPriv.Rule' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'app_id': app_id, + 'rules': json.dumps(rules) + } + + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/DomainLDAP.py b/synology_api/DSM/ControlPanel/DomainLDAP.py new file mode 100644 index 00000000..3edf8ffd --- /dev/null +++ b/synology_api/DSM/ControlPanel/DomainLDAP.py @@ -0,0 +1,262 @@ +""" +Manage Domain and LDAP settings. +""" + +from synology_api import base_api + + +class DomainLDAP(base_api.BaseApi): + """ + Manage Domain and LDAP settings. + """ + + def get_ldap_info(self) -> dict: + """ + Get LDAP information. + + Returns + ------- + dict + Informations about LDAP settings. + + Examples + -------- + ```json + { + "data": { + "base_dn": "dc=test_api,dc=dev", + "enable_cifs": false, + "enable_cifs_pam": false, + "enable_client": false, + "enable_client_certificate": false, + "enable_idmap": false, + "encryption": "no", + "error": 2703, + "expand_nested_groups": true, + "is_syno_server": false, + "ldap_schema": "rfc2307bis", + "nested_group_level": 5, + "profile": "standard", + "server_address": "127.0.0.1", + "tls_reqcert": false, + "update_min": 60 + }, + "success": true, + ``` + """ + + api_name = 'SYNO.Core.Directory.LDAP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_domain_info(self) -> dict: + """ + Get domain info. + + Returns + ------- + dict + Informations about domain settings. + + Examples + -------- + ```json + { + "data": { + "enable_domain": false + }, + "success": true, + } + ``` + """ + + api_name = 'SYNO.Core.Directory.Domain' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_sso_login_settings(self) -> dict: + """ + Get SSO login settings. + + Returns + ------- + dict + Informations about SSO login settings. + + Examples + -------- + ```json + { + "data": { + "sso_default_login": false + }, + "success": true, + } + ``` + """ + + api_name = 'SYNO.Core.Directory.SSO.Setting' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_synology_sso_settings(self) -> dict: + """ + Get Synology SSO service settings. + + Returns + ------- + dict + Informations about Synology SSO service settings. + + Examples + -------- + ```json + { + "data": { + "allow_local_user": true, + "appid": "", + "enable_sso": false, + "host": "", + "name": "Synology SSO", + "pingpong": null, + "sso_default_login": false + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Directory.SSO' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_sso_profile(self) -> dict: + """ + Get SSO profile. + + Returns + ------- + dict + Informations about SSO profile. + + Examples + -------- + ```json + { + "data": { + "sso_enable": false, + "sso_profile": "" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Directory.SSO.Profile' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_sam_sso_settings(self) -> dict: + """ + Get SAM SSO settings. + + Returns + ------- + dict + Informations about SAM SSO settings. + + Examples + -------- + ```json + { + "data": { + "saml_allow_local_user": false, + "saml_cert_detail": "", + "saml_idp_entity_id": "", + "saml_idp_signin_url": "", + "saml_name": "SAML", + "saml_response_signature": "response", + "saml_system_date": "", + "saml_valid_date": "", + "sso_saml_enable": "" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Directory.SSO.SAM' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) + + def get_cas_sso_settings(self) -> dict: + """ + Get CAS SSO settings. + + Returns + ------- + dict + Informations about CAS SSO settings. + + Examples + -------- + ```json + { + "data": { + "cas_allow_local_user": true, + "cas_auth_url": "", + "cas_name": "CAS", + "cas_service_ids": "", + "cas_validate_url": "", + "sso_cas_enable": "" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Directory.SSO.CAS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/ExternalAccess.py b/synology_api/DSM/ControlPanel/ExternalAccess.py new file mode 100644 index 00000000..c3aa6c6a --- /dev/null +++ b/synology_api/DSM/ControlPanel/ExternalAccess.py @@ -0,0 +1,883 @@ +""" +External access class for Synology DSM. +""" +from synology_api import base_api + + +class ExternalAccess(base_api.BaseApi): + """ + External access class for interacting with Synology DSM External Access settings. + + Supported methods: + - Getters: + - get_ddns_provider_list + - get_ddns_record_list + - get_external_ip_list + - get_ddns_synology_account + - get_certificate_list + - get_ethernet_port_list + - get_quickconnect_info + - get_quickconnect_status + - get_quickconnect_permission + - check_quickconnect_availability + - get_quickconnect_misc_config + - get_detect_router_information_task + - get_detect_router_information_status + - get_router_list + - get_port_forwarding_rule_list + - get_services_port_info + - get_advanced_external_access + + - Setters: + - set_quickconnect_server_alias + - set_quickconnect_enable + - set_router_config + - set_advanced_external_access + """ + + def get_ddns_provider_list(self) -> dict: + """ + Get the list of DDNS providers. + + Returns + ------- + dict + List of ddns provider. + + Examples + -------- + ```json + { + "data": { + "providers": + [ + { + "id": "Synology", + "provider": "Synology", + "website": "https://account.synology.com" + }, + { + "id": "Oray.com", + "provider": "Oray.com", + "website": "" + } + ] + } + }, + "success": true + ``` + """ + api_name = 'SYNO.Core.DDNS.Provider' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_ddns_record_list(self) -> dict: + """ + Get the list of DDNS records. + + Returns + ------- + dict + List of ddns record. + + Examples + -------- + ```json + { + "data": { + "next_update_time": "", + "records": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.DDNS.Record' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_external_ip_list(self) -> dict: + """ + Get the list of external IP addresses. + + Returns + ------- + dict + List of external IP addresses. + + Examples + -------- + ```json + { + "data": [ + { + "ip": "XXX.XXX.XXX.XXX", + "ipv6": "cf92:1469:123f:219f:73af:319a:1c77:181e", + "type": "WAN" + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.DDNS.ExtIP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_ddns_synology_account(self) -> dict: + """ + Get the Synology DDNS account email. + + Returns + ------- + dict + Synology DDNS account email. + + Examples + -------- + ```json + { + "data": { + "email": "YOUR_EMAIL", + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.DDNS.Synology' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get_myds_account' + } + return self.request_data(api_name, api_path, req_param) + + def get_certificate_list(self) -> dict: + """ + Get the list of certificates. + + Returns + ------- + dict + List of certificates. + + Examples + -------- + ```json + { + "data": { + "certificates": [ + { + "desc": "", + "id": "C6meKD", + "is_broken": false, + "is_default": false, + "issuer": { + "city": "Taipel", + "common_name": "Synology Inc. CA", + "country": "TW", + "organization": "Synology Inc." + }, + "key_types": "", + "renewable": false, + "self_signed_cacrt_info": { + "issuer": { + "city": "Taipel", + "common_name": "Synology Inc. CA", + "country": "TW", + "organization": "Synology Inc." + }, + "subject": { + "city": "Taipel", + "common_name": "Synology Inc. CA", + "country": "TW", + "organization": "Synology Inc." + } + }, + "services": [], + "signature_algorithm": "sha256WithRSAEncryption", + "subject": { + "city": "Taipel", + "common_name": "synology", + "country": "TW", + "organization": "Synology Inc.", + "sub_alt_name": [ + "synology" + ] + }, + "user_deletable": true, + "valid_from": "Nov 4 12:33:40 2024 GMT", + "valid_till": "Nov 5 12:33:40 2025 GMT" + } + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Certificate.CRT' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_ethernet_port_list(self) -> dict: + """ + Get the list of ethernet ports. + + Returns + ------- + dict + List of ethernet ports. + + Examples + -------- + ```json + { + "data": [ + { + "ifname": "ovs_eth0", + "ip": "XXX.XXX.XXX.XXX", + "ipv6": [ + "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX" + ] + }, + { + "ifname": "ovs_eth1", + "ip": "XXX.XXX.XXX.XXX", + "ipv6": [] + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.DDNS.Ethernet' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_quickconnect_info(self) -> dict: + """ + Get the QuickConnect information. + + Returns + ------- + dict + QuickConnect information. + + Examples + -------- + ```json + { + "data": { + "ddns_domain": "direct.quickconnect.to", + "domain": "quickconnect.to", + "enabled": false, + "myds_account": "YOUR_MYDS_ACCOUNT", + "region": "fr", + "server_alias": "YOUR_SERVER_ALIAS", + "server_id": "" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_quickconnect_status(self) -> dict: + """ + Get the QuickConnect status. + + Returns + ------- + dict + QuickConnect status. + + Examples + -------- + ```json + { + "data": { + "alias_status": "success", + "status": "not_running" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status' + } + return self.request_data(api_name, api_path, req_param) + + def get_quickconnect_permission(self) -> dict: + """ + Get the QuickConnect permission. + + Returns + ------- + dict + QuickConnect permission. + + Examples + -------- + ```json + { + "data": { + "services": [ + { + "enabled": true, + "id": "mobile_apps" + }, + { + "enabled": true, + "id": "cloudstation" + }, + { + "enabled": true, + "id": "file_sharing" + }, + { + "enabled": true, + "id": "dsm_portal" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect.Permission' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def check_quickconnect_availability(self) -> dict: + """ + Check the availability of QuickConnect. + + Returns + ------- + dict + Availability status of QuickConnect. + + Examples + -------- + ```json + { + "data": { + "available": true, + "code": 2908, + "country": "FR" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'check_availability' + } + return self.request_data(api_name, api_path, req_param) + + def get_quickconnect_misc_config(self) -> dict: + """ + Get the QuickConnect miscellaneous configuration. + + Returns + ------- + dict + QuickConnect miscellaneous configuration. + + Examples + -------- + ```json + { + "data": { + "relay_enabled": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get_misc_config' + } + return self.request_data(api_name, api_path, req_param) + + def set_quickconnect_server_alias(self, server_alias: str) -> dict: + """ + Set the QuickConnect server alias. + + Parameters + ---------- + server_alias : str + The server alias to set. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set_server_alias', + 'server_alias': server_alias + } + return self.request_data(api_name, api_path, req_param) + + def set_quickconnect_enable(self, enable: bool) -> dict: + """ + Enable or disable QuickConnect. + + Parameters + ---------- + enable : bool + True to enable, False to disable. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.QuickConnect' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable + } + return self.request_data(api_name, api_path, req_param) + + def get_detect_router_information_task(self) -> dict: + """ + Get the task information for detecting router. + + Returns + ------- + dict + Task information for detecting router. + + Examples + -------- + ```json + { + "data": { + "task_id": "@administrators/SYNO.Core.PortForwarding.detect174570013646DCEDAC" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.PortForwarding' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'detect' + } + return self.request_data(api_name, api_path, req_param) + + def get_detect_router_information_status(self, task_id: str) -> dict: + """ + Get the status of the task for detecting router. + + Parameters + ---------- + task_id : str + The task ID to check the status of. + + Returns + ------- + dict + Status of the task for detecting router. + + Examples + -------- + ```json + { + "data": { + "percentage": 30, + "progress": { + "check_connect_wan_step": { + "check_id": 3, + "status": "initial" + }, + "check_dns_setting_step": { + "check_id": 5, + "status": "initial" + }, + "check_gateway_setting_step": { + "check_id": 2, + "status": "processing" + }, + "check_hops_lan2wan_step": { + "check_id": 4, + "status": "initial" + }, + "check_interface_enable_step": { + "check_id": 1, + "network_interface": "ovs_eth0", + "status": "success" + }, + "detect_router_step": { + "check_id": 6, + "status": "initial" + } + } + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.PortForwarding' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'detect_status', + 'task_id': task_id + } + return self.request_data(api_name, api_path, req_param) + + def get_router_list(self) -> dict: + """ + Get the list of routers. + + Returns + ------- + dict + List of routers. + + Examples + -------- + ```json + { + "data": { + "routers":[ + { + "generic": false, + "router_brand": "3rd Party", + "router_model": "DD-WRT", + "router_version": "v24-sp1 micro" + }, + { + "generic": false, + "router_brand": "3rd Party", + "router_model": "DD-WRT", + "router_version": "v24-sp2 std - build 14896" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.PortForwarding.RouterList' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def set_router_config(self, + router_brand: str, router_model: str, router_version: str, router_protocol: str, router_port: int, + support_upnp: bool = False, support_natpmp: bool = False + ) -> dict: + """ + Set the router configuration. + + Parameters + ---------- + router_brand : str + The brand of the router. + router_model : str + The model of the router. + router_version : str + The version of the router. + router_protocol : str + The protocol used by the router. + router_port : int + The port used by the router. + support_upnp : bool, optional + Whether UPnP is supported (default is False). + support_natpmp : bool, optional + Whether NAT-PMP is supported (default is False). + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.PortForwarding.RouterConf' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'router_brand': router_brand, + 'router_model': router_model, + 'router_version': router_version, + 'router_protocol': router_protocol, + 'router_port': router_port, + 'support_upnp': "yes" if support_upnp else "no", + 'support_natpmp': "yes" if support_natpmp else "no" + } + return self.request_data(api_name, api_path, req_param) + + def get_port_forwarding_rule_list(self) -> dict: + """ + Get the list of port forwarding rules. + + Returns + ------- + dict + List of port forwarding rules. + + Examples + -------- + ```json + { + "data": [ + { + "ds_port": "873", + "enable": true, + "router_port": "873", + "router_protocol": "tcp", + "rule_id": "1", + "service_name": "", + "serviceid": "netbkp" + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.PortForwarding.Rules' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'load' + } + return self.request_data(api_name, api_path, req_param) + + def get_services_port_info(self) -> dict: + """ + Get the port information of services. + + Returns + ------- + dict + Port information of services. + + Examples + -------- + ```json + { + "data": { + "service": [ + { + "additional": { + "port_info": [ + { + "desc": "Share files with Mac", + "dst_port": [ + "548" + ], + "name": "AFP", + "port_id": "afp", + "protocol": "tcp", + "src_port": null + } + ] + }, + "display_name": "AFP", + "enable_status": "disabled", + "service_id": "atalk" + }, + { + "additional": { + "port_info": [ + { + "desc": "Bonjour", + "dst_port": [ + "5353" + ], + "name": "Bonjour Service", + "port_id": "bonjour", + "protocol": "udp", + "src_port": null + } + ] + }, + "display_name": "Bonjour Printer Broadcast", + "enable_status": "disabled", + "service_id": "bonjour" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Service' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get', + 'additional': ["port_info"] + } + return self.request_data(api_name, api_path, req_param) + + def get_advanced_external_access(self) -> dict: + """ + Get the advanced external access settings. + + Returns + ------- + dict + Advanced external access settings: + - `hostname`: The hostname of the DSM. + - `http_port`: The HTTP port of the DSM. + - `https_port`: The HTTPS port of the DSM. + + Examples + -------- + ```json + { + "data": { + "hostname": "HOSTNAME", + "http_port": 5000, + "https_port": 5001 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Web.DSM.External' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_advanced_external_access(self, hostname: str, http_port: int, https_port: int) -> dict: + """ + Set the advanced external access settings. + + Parameters + ---------- + hostname : str + The hostname of the DSM. + http_port : int + The HTTP port of the DSM. + https_port : int + The HTTPS port of the DSM. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.Web.DSM.External' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'hostname': hostname, + 'http_port': http_port, + 'https_port': https_port + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/ExternalDevices.py b/synology_api/DSM/ControlPanel/ExternalDevices.py new file mode 100644 index 00000000..fda878c7 --- /dev/null +++ b/synology_api/DSM/ControlPanel/ExternalDevices.py @@ -0,0 +1,399 @@ +""" +External devices class for Synology DSM. +""" + +from synology_api import base_api +from typing import List + + +class ExternalDevices(base_api.BaseApi): + """ + External devices class for interacting with Synology DSM External devices settings. + + Supported methods: + - Getters: + - get_printer_driver_list() + - get_printer_bonjour_enabled() + - get_storage_settings() + - get_list_usb_devices() + - get_list_esata_devices() + - get_list_of_printer() + - get_permissions() + - Setters: + - set_printer_bonjour_enabled() + - set_permissions() + """ + + def get_printer_driver_list(self) -> dict: + """ + Get the list of printer driver. + + Returns + ------- + dict + List of printer driver. + + Examples + -------- + ```json + { + "data": { + "Apollo": [ + [ + "Apollo P-2100", + "stp-pcl-apollo-p2100.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2150", + "stp-pcl-apollo-p2150.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2200", + "stp-pcl-apollo-p2200.5.2.ppd.tgz", + "EPSON", + "Stylus DX4800" + ], + [ + "Apollo P-2250", + "stp-pcl-apollo-p2250.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2500", + "stp-pcl-apollo-p2500.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2550", + "stp-pcl-apollo-p2550.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2600", + "stp-pcl-apollo-p2600.5.2.ppd.tgz", + "", + "" + ], + [ + "Apollo P-2650", + "stp-pcl-apollo-p2650.5.2.ppd.tgz", + "", + "" + ] + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Printer.Driver' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_printer_bonjour_enabled(self) -> dict: + """ + Get the printer bonjour enabled status. + + Returns + ------- + dict + Printer bonjour enabled status. + + Examples + -------- + ```json + { + "data": { + "enable_bonjour_support": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Printer.BonjourSharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_printer_bonjour_enabled(self, enable: bool) -> dict: + """ + Set the printer bonjour enabled status. + + Parameters + ---------- + enable : bool + Printer bonjour enabled status. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Printer.BonjourSharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable_bonjour_support': enable + } + return self.request_data(api_name, api_path, req_param) + + def get_storage_settings(self) -> dict: + """ + Get the external devices storage settings. + + Returns + ------- + dict + External devices storage settings. + + Examples + -------- + ```json + { + "data": { + "delalloc": false, + "forbid_usb": false, + "needReboot": false, + "non_admin_eject": false, + "setting": false, + "support_exfat_mkfs": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Storage.Setting' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_list_usb_devices(self) -> dict: + """ + Get the list of USB devices. + + Returns + ------- + dict + List of USB devices. + + Examples + -------- + ```json + { + "data": { + "devices": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Storage.USB' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'additional': ["all"], + } + return self.request_data(api_name, api_path, req_param) + + def get_list_esata_devices(self) -> dict: + """ + Get the list of eSATA devices. + + Returns + ------- + dict + List of eSATA devices. + + Examples + -------- + ```json + { + "data": { + "devices": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Storage.eSATA' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'additional': ["all"], + } + return self.request_data(api_name, api_path, req_param) + + def get_list_of_printer(self) -> dict: + """ + Get the list of printers. + + Returns + ------- + dict + List of printers. + + Examples + -------- + ```json + { + "data": { + "printers": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.Printer' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'additional': ["all"], + } + return self.request_data(api_name, api_path, req_param) + + def get_permissions(self, + offset: int = 0, limit: int = 50, + user_group_type: str = "local_user" + ) -> dict: + """ + Get the permissions of the external devices. + + Parameters + ---------- + offset : int, optional + The offset for pagination. Defaults to `0`. + limit : int, optional + The limit for pagination. Defaults to `50`. + user_group_type : str, optional + The type of user group to list permissions for. Defaults to `"local_user"`. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + + Returns + ------- + dict + Permissions of the external devices. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "is_admin": true, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "admin" + }, + { + "is_admin": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "guest" + } + ], + "total": 2 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.DefaultPermission' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'action': 'enum', + 'offset': offset, + 'limit': limit, + 'user_group_type': user_group_type + } + return self.request_data(api_name, api_path, req_param) + + def set_permissions(self, user_group_type: str, permissions: List[dict[str, object]]) -> dict: + """ + Set the permissions of the external devices. + + Parameters + ---------- + user_group_type : str + The type of user group to set permissions for. All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + permissions : List[dict[str, object]] + List of permissions to set. Each permission is a dictionary. + Example: + ```json + [ + { + "name":"guest", + "is_readonly":false, + "is_writable":true, + "is_deny":false, + "is_custom":false + } + ] + ``` + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.DefaultPermission' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'user_group_type': user_group_type, + 'permissions': permissions + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/FileServices.py b/synology_api/DSM/ControlPanel/FileServices.py new file mode 100644 index 00000000..4d93b21c --- /dev/null +++ b/synology_api/DSM/ControlPanel/FileServices.py @@ -0,0 +1,831 @@ + +""" +File services class for interacting with Synology DSM File services settings. +""" + +from synology_api import base_api + + +class FileServices(base_api.BaseApi): + """ + File services class for interacting with Synology DSM File services settings. + + Provides methods to get and set SMB, AFP, NFS, FTP, SFTP, and other file service settings. + """ + + def get_smb_settings(self): + """ + Get SMB settings. + + Returns + ------- + dict + SMB settings data. + + Examples + -------- + ```json + { + "data": { + "disable_shadow_copy": false, + "disable_strict_allocate": false, + "enable_access_based_share_enum": false, + "enable_adserver": null, + "enable_aio_read": false, + "enable_delete_vetofiles": false, + "enable_dirsort": false, + "enable_durable_handles": false, + "enable_enhance_log": false, + "enable_fruit_locking": false, + "enable_local_master_browser": false, + "enable_mask": false, + "enable_msdfs": false, + "enable_multichannel": false, + "enable_ntlmv1_auth": false, + "enable_op_lock": true, + "enable_perf_chart": false, + "enable_reset_on_zero_vc": false, + "enable_samba": true, + "enable_server_signing": 0, + "enable_smb2_leases": true, + "enable_smb3_directory_leasing": true, + "enable_strict_sync": false, + "enable_symlink": true, + "enable_syno_catia": true, + "enable_synotify": true, + "enable_vetofile": false, + "enable_widelink": false, + "offline_files_support": false, + "smb3_directory_leasing_scope": "home_only", + "smb_encrypt_transport": 1, + "smb_max_protocol": 3, + "smb_min_protocol": 1, + "syno_wildcard_search": false, + "vetofile": "", + "wins": "", + "workgroup": "WORKGROUP" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.SMB' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_afp_settings(self) -> dict: + """ + Get AFP settings. + + Returns + ------- + dict + AFP settings data. + + Examples + -------- + ```json + { + "data": { + "enable_afp": false, + "enable_disconnect_quick": false, + "enable_umask": false, + "time_machine": "" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.AFP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_nfs_settings(self) -> dict: + """ + Get NFS settings. + + Returns + ------- + dict + NFS settings data. + + Examples + -------- + ```json + { + "data": { + "enable_nfs": false, + "enable_nfs_v4": false, + "enabled_minor_ver": 0, + "nfs_v4_domain": "", + "read_size": 8192, + "support_encrypt_share": 1, + "support_major_ver": 4, + "support_minor_ver": 1, + "unix_pri_enable": true, + "write_size": 8192 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.NFS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_ftp_settings(self) -> dict: + """ + Get FTP settings. + + Returns + ------- + dict + FTP settings data. + + Examples + -------- + ```json + { + "data": { + "custom_port": "55536:55899", + "custom_port_range": false, + "enable_ascii": false, + "enable_fips": false, + "enable_flow_ctrl": false, + "enable_ftp": false, + "enable_ftps": false, + "enable_fxp": false, + "ext_ip": "", + "max_conn_per_ip": 0, + "maxdownloadrate": 0, + "maxuploadrate": 0, + "modify_time_std": "utc", + "portnum": 21, + "timeout": 300, + "use_ext_ip": false, + "utf8_mode": 1 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_sftp_settings(self) -> dict: + """ + Get SFTP settings. + + Returns + ------- + dict + SFTP settings data. + + Examples + -------- + ```json + { + "data": { + "enable": false, + "portnum": 22 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP.SFTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_bandwidth_control_protocol_settings(self, protocol: str, schedule_plan: str) -> dict: + """ + Get bandwidth control protocol settings. + + Parameters + ---------- + protocol : str + Protocol name (e.g. "FTP", "NetworkBackup"). + schedule_plan : str + Schedule plan, a 128-bit binary string. + + Returns + ------- + dict + Bandwidth control protocol settings data. + + Examples + -------- + ```json + { + "data": { + "policy": "disabled", + "protocol": "FTP", + "schedule_plan": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.BandwidthControl.Protocol' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get', + 'protocol': protocol + } + return self.request_data(api_name, api_path, req_param) + + def get_network_backup_settings(self) -> dict: + """ + Get network backup settings. + + Returns + ------- + dict + Network backup settings data. + + Examples + -------- + ```json + { + "data": { + "enable": false, + "enable_custom_config": false, + "enable_rsync_account": false, + "rsync_sshd_port": "22" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Backup.Service.NetworkBackup' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_domain_settings(self) -> dict: + """ + Get domain settings. + + Returns + ------- + dict + Domain settings data. + + Examples + -------- + ```json + { + "data": { + "enable_domain": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Directory.Domain' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_service_discovery_settings(self) -> dict: + """ + Get service discovery settings. + + Returns + ------- + dict + Service discovery settings data. + + Examples + -------- + ```json + { + "data": { + "enable_afp_time_machine": false, + "enable_smb_time_machine": false, + "time_machine_disable_shares": [], + "time_machine_shares": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.ServiceDiscovery' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_wstransfer_settings(self) -> dict: + """ + Get WSTransfer settings. + + Returns + ------- + dict + WSTransfer settings data. + + Examples + -------- + ```json + { + "data": { + "enable_wstransfer": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.ServiceDiscovery.WSTransfer' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_reflink_copy_settings(self) -> dict: + """ + Get reflink copy settings. + + Returns + ------- + dict + Reflink copy settings data. + + Examples + -------- + ```json + { + "data": { + "reflink_copy_enable": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.ReflinkCopy' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_tftp_settings(self) -> dict: + """ + Get TFTP settings. + + Returns + ------- + dict + TFTP settings data. + + Examples + -------- + ```json + { + "data": { + "enable": false, + "enable_log": false, + "endip": "255.255.255.255", + "permission": "r", + "root_path": "", + "startip": "0.0.0.0", + "timeout": 3 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.TFTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def clean_smb_cache(self) -> dict: + """ + Clean SMB cache. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.SMB' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'clean_cache' + } + return self.request_data(api_name, api_path, req_param) + + def set_afp_settings(self, enable: bool, enable_transfer_log: bool, enable_umask: bool, enable_disconnect_quick: bool) -> dict: + """ + Set AFP settings. + + Parameters + ---------- + enable : bool + Enable or disable AFP. + enable_transfer_log : bool + Enable or disable transfer log. + enable_umask : bool + Enable or disable umask. + enable_disconnect_quick : bool + Enable or disable quick disconnect. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.AFP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'enable_transfer_log': enable_transfer_log, + 'enable_umask': enable_umask, + 'enable_disconnect_quick': enable_disconnect_quick + } + return self.request_data(api_name, api_path, req_param) + + def set_nfs_settings(self, enable: bool, max_protocol: int, enable_v4: bool, enabled_minor_ver: int) -> dict: + """ + Set NFS settings. + + Parameters + ---------- + enable : bool + Enable or disable NFS. + max_protocol : int + Maximum NFS protocol version. + enable_v4 : bool + Enable or disable NFSv4. + enabled_minor_ver : int + Enabled minor version. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.NFS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'max_protocol': max_protocol, + 'enable_v4': enable_v4, + 'enabled_minor_ver': enabled_minor_ver + } + return self.request_data(api_name, api_path, req_param) + + def get_ftp_security_settings(self) -> dict: + """ + Get FTP security settings. + + Returns + ------- + dict + FTP security settings data. + + Examples + -------- + ```json + { + "data": { + "anonymous": false, + "anonymous_chroot": false, + "anonymous_chroot_share": "", + "enable_umask": false, + "user_chroot": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP.Security' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_ftp_security_share_list(self) -> dict: + """ + Get FTP security share list. + + Returns + ------- + dict + FTP security share list data. + + Examples + -------- + ```json + { + "data":{ + "share": [ + "docker" + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP.Security.ShareList' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_ftp_settings(self, enable_ftp: bool, enable_ftps: bool, + timeout: int = 300, portnum: int = 21, custom_port_range: bool = False, + use_ext_ip: bool = False, enable_fxp: bool = True, enable_ascii: bool = True, + utf8_mode: int = 1, modify_time_std: str = "utc", custom_port: str = "55536:55899", + external_ip: str = "default" + ) -> dict: + """ + Set FTP settings. + + Parameters + ---------- + enable_ftp : bool + Enable or disable FTP. + enable_ftps : bool + Enable or disable FTPS. + timeout : int, optional + Timeout in seconds. Default is 300. + portnum : int, optional + Port number. Default is 21. + custom_port_range : bool, optional + Enable or disable custom port range. Default is False. + use_ext_ip : bool, optional + Enable or disable external IP. Default is False. + enable_fxp : bool, optional + Enable or disable FXP. Default is True. + enable_ascii : bool, optional + Enable or disable ASCII mode. Default is True. + utf8_mode : int, optional + UTF-8 mode (0: disable, 1: Auto, 2: Force). Default is 1. + modify_time_std : str, optional + Modify time standard ("utc", "local"). Default is "utc". + custom_port : str, optional + Custom port range. Default is "55536:55899". + external_ip : str, optional + External IP address. Default is "default". + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable_ftp': enable_ftp, + 'enable_ftps': enable_ftps, + 'timeout': timeout, + 'portnum': portnum, + 'custom_port_range': custom_port_range, + 'use_ext_ip': use_ext_ip, + 'enable_fxp': enable_fxp, + 'enable_ascii': enable_ascii, + 'utf8_mode': utf8_mode, + 'modify_time_std': modify_time_std, + 'custom_port': custom_port, + 'external_ip': external_ip + } + return self.request_data(api_name, api_path, req_param) + + def set_sftp_settings(self, enable: bool, portnum: int = 22) -> dict: + """ + Set SFTP settings. + + Parameters + ---------- + enable : bool + Enable or disable SFTP. + portnum : int, optional + Port number. Default is 22. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.FTP.SFTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'portnum': portnum, + 'sftp_portnum': portnum + } + return self.request_data(api_name, api_path, req_param) + + def set_rsync_settings(self, enable: bool, port: int = 22) -> dict: + """ + Set rsync settings. + + Parameters + ---------- + enable : bool + Enable or disable rsync. + port : int, optional + Rsync SSHD port. Default is 22. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Backup.Service.NetworkBackup' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'rsync_sshd_port': port + } + return self.request_data(api_name, api_path, req_param) + + def set_reflink_copy_settings(self, reflink_copy_enable: bool) -> dict: + """ + Set reflink copy settings. + + Parameters + ---------- + reflink_copy_enable : bool + Enable or disable reflink copy. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.FileServ.ReflinkCopy' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'reflink_copy_enable': reflink_copy_enable + } + return self.request_data(api_name, api_path, req_param) + + def set_tftp_settings(self, enable: bool, root_path: str) -> dict: + """ + Set TFTP settings. + + Parameters + ---------- + enable : bool + Enable or disable TFTP. + root_path : str + Root path for TFTP. Path must be a valid directory. + + Returns + ------- + dict + Result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.TFTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'root_path': root_path + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/HardwarePower.py b/synology_api/DSM/ControlPanel/HardwarePower.py new file mode 100644 index 00000000..19346030 --- /dev/null +++ b/synology_api/DSM/ControlPanel/HardwarePower.py @@ -0,0 +1,830 @@ +""" +Hardware power class for Synology DSM. +""" + +from synology_api import base_api +import json +from typing import List + + +class HardwarePower(base_api.BaseApi): + """ + Hardware power class for interacting with Synology DSM Hardware & Power settings. + + Supported methods: + - Getters: + + - Setters: + """ + + def need_reboot(self) -> dict: + """ + TODO: Determine usage of this method. + + Returns + ------- + dict + Return boolean value indicating if a reboot is needed. + + Examples + -------- + ```json + { + "data": { + "need_reboot": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.NeedReboot' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_need_reboot(self) -> dict: + """ + TODO: Determine usage of this method. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.NeedReboot' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set' + } + return self.request_data(api_name, api_path, req_param) + + def get_led_brightness_stats(self) -> dict: + """ + Get LED brightness stats. + + Returns + ------- + dict + Return LED brightness default settigns and min / max. + + Examples + -------- + ```json + { + "data": { + "default": 3, + "max": 3, + "min": 0 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Led.Brightness' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get_static_data' + } + return self.request_data(api_name, api_path, req_param) + + def get_zram_settings(self) -> dict: + """ + Get ZRAM settings. + + Returns + ------- + dict + Return ZRAM settings. + + Examples + -------- + ```json + { + "data": { + "enable_zram": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.ZRAM' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_power_recovery_settings(self) -> dict: + """ + Get power recovery settings. + + Returns + ------- + dict + Return power recovery settings. + + Examples + -------- + ```json + { + "data": { + "internal_lan_num": 2, + "rc_power_config": true, + "wol": [ + { + "enable": false, + "idx": 1 + }, + { + "enable": false, + "idx": 2 + } + ], + "wol1": false, + "wol2": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.PowerRecovery' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_beep_control_settings(self) -> dict: + """ + Get beep control settings. + + Returns + ------- + dict + Return beep control settings. + + Examples + -------- + ```json + { + "data": { + "enc_module_fail": true, + "eunit_redundant_power_fail": true, + "fan_fail": true, + "poweroff_beep": true, + "poweron_beep": true, + "redundant_power_fail": true, + "reset_beep": true, + "sas_link_fail": true, + "support_fan_fail": true, + "support_poweroff_beep": true, + "support_poweron_beep": true, + "support_redundant_power_fail": false, + "support_reset_beep": false, + "support_volume_or_cache_crash": true, + "volume_or_cache_crash": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.BeepControl' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_fan_speed_settings(self) -> dict: + """ + Get fan speed settings. + + Returns + ------- + dict + Return fan speed settings. + + Examples + -------- + ```json + { + "data": { + "enc_module_fail": true, + "eunit_redundant_power_fail": true, + "fan_fail": true, + "poweroff_beep": true, + "poweron_beep": true, + "redundant_power_fail": true, + "reset_beep": true, + "sas_link_fail": true, + "support_fan_fail": true, + "support_poweroff_beep": true, + "support_poweron_beep": true, + "support_redundant_power_fail": false, + "support_reset_beep": false, + "support_volume_or_cache_crash": true, + "volume_or_cache_crash": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.FanSpeed' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_led_brightness_schedule(self) -> dict: + """ + Get LED brightness settings. + + Returns + ------- + dict + Return LED brightness settings. Schedule is a 144 character string. + 1 character = 1 hour. Start from Sunday 00:00 to Saturday 23:00. + 0 = Default, 1= Ajusted, 2 = Off. + + Examples + -------- + ```json + { + "data": { + "led_brightness": 3, + "schedule": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Led.Brightness' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_power_schedule_settings(self) -> dict: + """ + Get power schedule settings. + + Returns + ------- + dict + Return power schedule settings. + + Examples + -------- + ```json + { + "data": { + "poweroff_tasks": [], + "poweron_tasks": [] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.PowerSchedule' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'load' + } + return self.request_data(api_name, api_path, req_param) + + def get_hibernation_settings(self) -> dict: + """ + Get hibernation settings. + + Returns + ------- + dict + Return hibernation settings. + + Examples + -------- + ```json + { + "data": { + "auto_poweroff_enable": false, + "enable_log": false, + "eunit_deep_sleep": 0, + "eunit_dsleep_blacklist": "none", + "hibernation_blacklist": "none", + "ignore_netbios_broadcast": false, + "internal_hd_idletime": 20, + "sata_deep_sleep": 1, + "sata_dsleep_blacklist": "none", + "support_esata": "yes", + "support_eunit_deep_sleep": false, + "support_eunit_switch_mode": true, + "usb_idletime": 0 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Hibernation' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_ups_settings(self) -> dict: + """ + Get UPS settings. + + Returns + ------- + dict + Return UPS settings. + + Examples + -------- + ```json + { + "data": { + "ACL_enable": false, + "ACL_list": [], + "charge": 0, + "delay_time": -1, + "enable": false, + "manufacture": "", + "mode": "SLAVE", + "model": "", + "net_server_ip": "", + "runtime": 0, + "shutdown_device": false, + "snmp_auth": false, + "snmp_auth_key": false, + "snmp_auth_type": "", + "snmp_community": "", + "snmp_mib": "", + "snmp_privacy": false, + "snmp_privacy_key": false, + "snmp_privacy_type": "", + "snmp_server_ip": "", + "snmp_user": "", + "snmp_version": "", + "status": "usb_ups_status_unknown", + "usb_ups_connect": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.UPS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_led_brightness(self, brightness: int = 3) -> dict: + """ + Set LED brightness. + + Parameters + ---------- + brightness : int + LED brightness level (0-3). Default is `3`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Led.Brightness' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'brightness': brightness + } + return self.request_data(api_name, api_path, req_param) + + def set_zram_settings(self, enable_zram: bool = False) -> dict: + """ + Set ZRAM settings. + + Parameters + ---------- + enable_zram : bool + Enable or disable ZRAM. Default is `False`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.ZRAM' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable_zram': enable_zram + } + return self.request_data(api_name, api_path, req_param) + + def set_power_recovery_settings(self, + enable: bool = False, wol1: bool = False, wol2: bool = False, wol3: bool = False + ) -> dict: + """ + Set power recovery settings. Note if a wol option is enabled, the enable option will be forced to `True`. + + Parameters + ---------- + enable : bool + Enable or disable power recovery configuration. Default is `False`. + wol1 : bool + Enable or disable Wake on LAN for port 1. Default is `False`. + wol2 : bool + Enable or disable Wake on LAN for port 2. Default is `False`. + wol3 : bool + Enable or disable Wake on LAN for port 3. Default is `False`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.PowerRecovery' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'wol1': wol1, + 'wol2': wol2, + 'wol3': wol3 + } + return self.request_data(api_name, api_path, req_param) + + def set_beep_control_settings(self, + fan_fail: bool = True, volume_or_cache_crash: bool = True, + poweroff_beep: bool = True, poweron_beep: bool = True + ) -> dict: + """ + Set beep control settings. + + Parameters + ---------- + fan_fail : bool + Enable or disable fan failure beep. Default is `True`. + volume_or_cache_crash : bool + Enable or disable volume or cache crash beep. Default is `True`. + poweroff_beep : bool + Enable or disable power off beep. Default is `True`. + poweron_beep : bool + Enable or disable power on beep. Default is `True`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.BeepControl' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'fan_fail': fan_fail, + 'volume_or_cache_crash': volume_or_cache_crash, + 'poweroff_beep': poweroff_beep, + 'poweron_beep': poweron_beep + } + return self.request_data(api_name, api_path, req_param) + + def set_fan_speed_settings(self, fan_speed: str = "coolfan") -> dict: + """ + Set fan speed settings. + + Parameters + ---------- + fan_speed : str + Fan speed level (0-2). Default is `quietfan`. + Known values are `quietfan`, `coolfan`, and `fullspeed`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.FanSpeed' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'dual_fan_speed': fan_speed + } + return self.request_data(api_name, api_path, req_param) + + def set_led_brightness_schedule(self, + led_brightness: int = 3, schedule: str = "1"*144 + ) -> dict: + """ + Set LED brightness schedule. + + Parameters + ---------- + led_brightness : int + LED brightness level (0-3). Default is `3`. + schedule : str + Schedule string for LED brightness. 1 character = 1 hour. Start from Sunday 00:00 to Saturday 23:00. + Default is `1` for all hours. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Led.Brightness' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'led_brightness': led_brightness, + 'schedule': schedule + } + return self.request_data(api_name, api_path, req_param) + + def set_hibernation_settings(self, + internal_hd_idletime: int = 20, stat_deep_sleep: bool = True, + ignore_netbios_broadcast: bool = False, usb_idletime: int = 0, + enable_log: bool = False + ) -> dict: + """ + Set hibernation settings. + + Parameters + ---------- + internal_hd_idletime : int + Internal hard drive idle time in minutes. Default is `20`. + stat_deep_sleep : bool + Enable or disable SATA deep sleep. Default is `True`. + ignore_netbios_broadcast : bool + Enable or disable ignoring NetBIOS broadcast. Default is `False`. + usb_idletime : int + USB idle time in minutes. Default is `0`. + enable_log : bool + Enable or disable logging. Default is `False`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.Hibernation' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'internal_hd_idletime': internal_hd_idletime, + 'stat_deep_sleep': stat_deep_sleep, + 'ignore_netbios_broadcast': ignore_netbios_broadcast, + 'usb_idletime': usb_idletime, + 'enable_log': enable_log + } + return self.request_data(api_name, api_path, req_param) + + def set_ups_settings(self, + enable: bool = False, mode: str = "SLAVE", delay_time: str = "-1", + snmp_auth_key_dirty: bool = False, snmp_privacy_key_dirty: bool = False, + ) -> dict: + """ + Set UPS settings. + + Parameters + ---------- + enable : bool + Enable or disable UPS. Default is `False`. + mode : str + UPS mode. Default is `SLAVE`. + TODO: Determine valid values for this parameter. + delay_time : str + Delay time in seconds. Default is `-1`. + TODO: Determine valid values for this parameter. + snmp_auth_key_dirty : bool + SNMP authentication key dirty flag. Default is `False`. + snmp_privacy_key_dirty : bool + SNMP privacy key dirty flag. Default is `False`. + + Returns + ------- + dict + Return success status. + + Examples + -------- + ```json + { + "data": { + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.ExternalDevice.UPS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'mode': mode, + 'delay_time': delay_time, + 'snmp_auth_key_dirty': snmp_auth_key_dirty, + 'snmp_privacy_key_dirty': snmp_privacy_key_dirty + } + return self.request_data(api_name, api_path, req_param) + + def set_power_schedule(self, poweron_tasks: List[dict] = [], poweroff_tasks: List[dict] = []) -> dict: + """ + Set the power schedule, poweron tasks and poweroff tasks. + + Parameters + ---------- + poweron_tasks : List[dict], optional + List of tasks for power on. Defaults to `[]` + Example of a task: + ```python + { + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday) + } + ``` + poweroff_tasks : List[dict], optional + List of tasks for power off. Defaults to `[]` + Example of a task: + ```python + { + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday) + } + ``` + + Returns + ------- + dict + List of tasks in power schedule. + + Examples + -------- + ```json + { + "data": { + "poweroff_tasks": [], + "poweron_tasks": [ + { + "enabled": true, + "hour": 0, + "min": 0, + "weekdays": "1,2,3,4,5" + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Hardware.PowerSchedule' + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "save", + "poweron_tasks": json.dumps(poweron_tasks), + "poweroff_tasks": json.dumps(poweroff_tasks) + } + + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/IndexingService.py b/synology_api/DSM/ControlPanel/IndexingService.py new file mode 100644 index 00000000..ae80b1f5 --- /dev/null +++ b/synology_api/DSM/ControlPanel/IndexingService.py @@ -0,0 +1,316 @@ +""" +Indexing service class for Synology DSM. +""" + +from synology_api import base_api + + +class IndexingService(base_api.BaseApi): + """ + Indexing service class for interacting with Synology DSM Indexing service settings. + + Supported methods: + - Getters: + + - Setters: + """ + + def get_indexed_folders(self) -> dict: + """ + Get indexed folders. + + Returns + ------- + dict + Return list of folders indexed by the indexing service. + + Examples + -------- + ```json + { + "data": { + "folders": [ + { + "default": false, + "exist": true, + "name": "Films", + "path": "/Films", + "types": [ + "video" + ] + }, + { + "default": false, + "exist": true, + "name": "Series", + "path": "/Series", + "types": [ + "video" + ] + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.MediaIndexing.IndexFolder' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_media_indexing_status(self) -> dict: + """ + Get media indexing status. + + Returns + ------- + dict + Return the status of the media indexing service. + + Examples + -------- + ```json + { + "data": { + "reindexing": false + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.MediaIndexing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status' + } + return self.request_data(api_name, api_path, req_param) + + def get_thumbnail_quality_settings(self) -> dict: + """ + Get thumbnail quality settings. + + Returns + ------- + dict + Return the thumbnail quality settings. + + Examples + -------- + ```json + { + "data": { + "packages": [], + "thumbnail_quality": "normal" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.MediaIndexing.ThumbnailQuality' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_scheduler_settings(self) -> dict: + """ + Get scheduler settings. + + Returns + ------- + dict + Return the scheduler settings of the indexing service. + + Examples + -------- + ```json + { + "data": { + "duration": 1, + "manual_action_by_user": "none", + "mode": "schedule", + "start": { + "hour": 0 + }, + "week": [ + true, + true, + true, + true, + true, + true, + true + ] + }, + "success": true, + ``` + """ + api_name = 'SYNO.Core.MediaIndexing.Scheduler' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_indexed_folders(self, folders: list) -> dict: + """ + Set indexed folders. + + Parameters + ---------- + folders : list + A list of dictionaries representing the folders to be indexed. Each dictionary should contain: + - `path`: The path of the folder to be indexed. + - `name`: The name of the folder. + - `default`: A boolean indicating if this is a default folder. Should be `False` + - `types`: A list of media types to index in the folder (e.g., `["video"]`). Fields are `photo`, `video`, `music`. + example: + ```json + [ + { + "path": "/Films", + "name": "Films", + "default": false, + "types": ["video"] + }, + { + "path": "/Series", + "name": "Series", + "default": false, + "types": ["video"] + } + ] + ``` + + Returns + ------- + dict + Return the result of the operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.MediaIndexing.IndexFolder' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'folders': folders + } + return self.request_data(api_name, api_path, req_param) + + def set_thumbnail_quality_settings(self, quality: str = "normal") -> dict: + """ + Set thumbnail quality settings. + + Parameters + ---------- + quality : str + The desired thumbnail quality setting. Options are `normal`, `high`. Default to `normal`. + + Returns + ------- + dict + Return the result of the operation. + + Examples + -------- + ```json + { + "data": { + "thumbnail_quality": "normal" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.MediaIndexing.ThumbnailQuality' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'quality': quality + } + return self.request_data(api_name, api_path, req_param) + + def set_shudler_settings(self, mode: str = "always", start_hour: int = 0, duration: int = 1, week: list = [True, True, True, True, True, True, True]) -> dict: + """ + Set scheduler settings. + + Parameters + ---------- + mode : str + The scheduling mode. Options are `schedule`, `always`. Default to `always`. + start_hour : int + The hour to start the indexing service. Default to `0`. Not used if `mode` is set to `always`. + duration : int + The duration in hours for the indexing service. Default to `1`. Not used if `mode` is set to `always`. + week : list + A list of booleans indicating which days of the week the service should run. Default to `[True, True, True, True, True, True, True]`. Not used if `mode` is set to `always`. + + Returns + ------- + dict + Return the result of the operation. + + Examples + -------- + ```json + { + "data": { + "duration": 1, + "manual_action_by_user": "none", + "mode": "schedule", + "start": { + "hour": 0 + }, + "week": [ + true, + true, + true, + true, + true, + true, + true + ] + }, + "success": true + } + ``` + """ + if week is None: + week = [True] * 7 + + api_name = 'SYNO.Core.MediaIndexing.Scheduler' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'mode': mode, + 'start': {'hour': start_hour}, + 'duration': duration, + 'week': week + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/InfoCenter.py b/synology_api/DSM/ControlPanel/InfoCenter.py new file mode 100644 index 00000000..1fea0059 --- /dev/null +++ b/synology_api/DSM/ControlPanel/InfoCenter.py @@ -0,0 +1,589 @@ +""" +Info center class for Synology DSM Info center settings. +""" + +from synology_api import base_api + + +class InfoCenter(base_api.BaseApi): + """ + Info center class for interacting with Synology DSM Info center settings. + + Supported methods: + - Getters: + + - Setters: + """ + + def get_system_info(self) -> dict: + """ + Get system information. + + Returns + ------- + dict + Return system information including CPU, memory, and disk usage. + + Examples + -------- + ```json + { + "data": { + "cpu_clock_speed": 2600, + "cpu_cores": "2", + "cpu_family": "Ryzen", + "cpu_series": "R1600", + "cpu_vendor": "AMD", + "enabled_ntp": true, + "external_pci_slot_info": [ + { + "Occupied": "no", + "Recognized": "no", + "cardName": "-", + "slot": "1" + } + ], + "firmware_date": "2025/01/20", + "firmware_ver": "DSM 7.2.2-72806 Update 3", + "model": "DS723+", + "ntp_server": "time.google.com", + "ram_size": 2048, + "sata_dev": [], + "serial": "YOUR-SERIAL-NUMBER", + "support_esata": "yes", + "sys_temp": 47, + "sys_tempwarn": false, + "systempwarn": false, + "temperature_warning": false, + "time": "2025-07-06 00:23:44", + "time_zone": "Amsterdam", + "time_zone_desc": "(GMT+01:00) Amsterdam, Berlin, Rome, Stockholm, Vienna", + "up_time": "49:46:21", + "usb_dev": [] + }, + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.System' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'info' + } + return self.request_data(api_name, api_path, req_param) + + def get_network_info(self) -> dict: + """ + Get network information. + + Returns + ------- + dict + Return network information including interfaces, IP addresses, and DNS settings. + + Examples + -------- + ```json + { + "data": { + "dns": "YOUR-DNS", + "enabled_domain": false, + "enabled_samba": true, + "gateway": "YOUR-GATEWAY", + "hostname": "YOUR-HOSTNAME", + "nif": [ + { + "addr": "YOUR-IP-ADDRESS", + "duplex": true, + "id": "ovs_eth0", + "ipv6": [ + { + "addr": "YOUR-IPv6-ADDRESS", + "prefix_len": 64, + "scope": "global" + }, + { + "addr": "YOUR-IPv6-ADDRESS", + "prefix_len": 64, + "scope": "link" + } + ], + "mac": "YOUR-MAC-ADDRESS", + "mask": "255.255.255.0", + "mtu": 1500, + "speed": 1000, + "status": "connected", + "type": "ovseth", + "use_dhcp": true + }, + { + "addr": "YOUR-SECOND-IP-ADDRESS", + "duplex": true, + "id": "ovs_eth1", + "mac": "YOUR-SECOND-MAC-ADDRESS", + "mask": "255.255.0.0", + "mtu": 1500, + "speed": -1, + "status": "disconnected", + "type": "ovseth", + "use_dhcp": true + } + ], + "wins": "", + "workgroup": "WORKGROUP" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.System' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'info', + 'type': 'network' + } + return self.request_data(api_name, api_path, req_param) + + def get_storage_info(self) -> dict: + """ + Get storage information. + + Returns + ------- + dict + Return storage information including volumes, disks, and RAID status. + + Examples + -------- + ```json + { + "data": { + "hdd_info": [ + { + "action": { + "alert": false, + "notification": false, + "selectable": true, + "show_lifetime_chart": true + }, + "action_status": { + "action_name": "idle", + "action_progress": "" + }, + "action_status_category": "processing", + "action_status_key": "idle", + "adv_progress": "", + "adv_status": "not_support", + "allocation_role": "reuse_1", + "below_remain_life_mail_notify_thr": false, + "below_remain_life_show_thr": false, + "below_remain_life_thr": false, + "compatibility": "support", + "container": { + "order": 0, + "str": "DS723+", + "supportPwrBtnDisable": false, + "type": "internal" + }, + "container_id": 0, + "device": "/dev/sata1", + "disable_secera": false, + "diskType": "SATA", + "disk_code": "", + "disk_location": "Main", + "drive_status_category": "health", + "drive_status_key": "normal", + "erase_time": 450, + "firm": "SC60", + "firmware_status": "-", + "has_system": true, + "hide_info": [], + "i18nNamingInfo": "[\"dsm:volume:volume_disk\",\" \",\"1\"]", + "id": "sata1", + "ihm_testing": false, + "is4Kn": false, + "isSsd": false, + "isSynoDrive": false, + "isSynoPartition": true, + "is_bundle_ssd": false, + "is_erasing": false, + "longName": "Drive 1", + "m2_pool_support": false, + "model": "ST4000VN006-3CW104", + "name": "Drive 1", + "num_id": 1, + "order": 1, + "overview_status": "normal", + "pciSlot": -1, + "perf_testing": false, + "portType": "normal", + "remain_life": { + "trustable": true, + "value": -1 + }, + "remain_life_danger": false, + "remote_info": { + "compatibility": "disabled", + "unc": 0 + }, + "sb_days_left": 0, + "sb_days_left_below_show_thres": false, + "sb_days_left_critical": false, + "sb_days_left_warning": false, + "serial": "YOUR-FIRST-SERIAL-NUMBER", + "size_total": "4000787030016", + "slot_id": 1, + "smart_progress": "", + "smart_status": "normal", + "smart_test_limit": 0, + "smart_test_support": true, + "smart_testing": false, + "ssd_unhealth_reason": "none", + "status": "normal", + "summary_status_category": "health", + "summary_status_key": "normal", + "temp": 35, + "testing_progress": "", + "testing_type": "idle", + "tray_status": "join", + "ui_serial": "YOUR-FIRST-SERIAL-NUMBER", + "unc": 0, + "used_by": "reuse_1", + "vendor": "Seagate", + "wcache_force_off": false, + "wcache_force_on": false, + "wdda_support": false + }, + { + "action": { + "alert": false, + "notification": false, + "selectable": true, + "show_lifetime_chart": true + }, + "action_status": { + "action_name": "idle", + "action_progress": "" + }, + "action_status_category": "processing", + "action_status_key": "idle", + "adv_progress": "", + "adv_status": "not_support", + "allocation_role": "reuse_1", + "below_remain_life_mail_notify_thr": false, + "below_remain_life_show_thr": false, + "below_remain_life_thr": false, + "compatibility": "support", + "container": { + "order": 0, + "str": "DS723+", + "supportPwrBtnDisable": false, + "type": "internal" + }, + "container_id": 0, + "device": "/dev/sata2", + "disable_secera": false, + "diskType": "SATA", + "disk_code": "", + "disk_location": "Main", + "drive_status_category": "health", + "drive_status_key": "normal", + "erase_time": 462, + "firm": "SC60", + "firmware_status": "-", + "has_system": true, + "hide_info": [], + "i18nNamingInfo": "[\"dsm:volume:volume_disk\",\" \",\"2\"]", + "id": "sata2", + "ihm_testing": false, + "is4Kn": false, + "isSsd": false, + "isSynoDrive": false, + "isSynoPartition": true, + "is_bundle_ssd": false, + "is_erasing": false, + "longName": "Drive 2", + "m2_pool_support": false, + "model": "ST4000VN006-3CW104", + "name": "Drive 2", + "num_id": 2, + "order": 2, + "overview_status": "normal", + "pciSlot": -1, + "perf_testing": false, + "portType": "normal", + "remain_life": { + "trustable": true, + "value": -1 + }, + "remain_life_danger": false, + "remote_info": { + "compatibility": "disabled", + "unc": 0 + }, + "sb_days_left": 0, + "sb_days_left_below_show_thres": false, + "sb_days_left_critical": false, + "sb_days_left_warning": false, + "serial": "YOUR-SECOND-SERIAL-NUMBER", + "size_total": "4000787030016", + "slot_id": 2, + "smart_progress": "", + "smart_status": "normal", + "smart_test_limit": 0, + "smart_test_support": true, + "smart_testing": false, + "ssd_unhealth_reason": "none", + "status": "normal", + "summary_status_category": "health", + "summary_status_key": "normal", + "temp": 37, + "testing_progress": "", + "testing_type": "idle", + "tray_status": "join", + "ui_serial": "YOUR-SECOND-SERIAL-NUMBER", + "unc": 0, + "used_by": "reuse_1", + "vendor": "Seagate", + "wcache_force_off": false, + "wcache_force_on": false, + "wdda_support": false + } + ], + "vol_info": [ + { + "desc": "", + "inode_free": "0", + "inode_total": "0", + "is_encrypted": false, + "name": "volume_1", + "status": "normal", + "total_size": "206158430208", + "used_size": "16905019392", + "vol_desc": "Apps", + "volume": "volume_1" + }, + { + "desc": "", + "inode_free": "0", + "inode_total": "0", + "is_encrypted": false, + "name": "volume_2", + "status": "normal", + "total_size": "3623234412544", + "used_size": "1154716925952", + "vol_desc": "Stockage", + "volume": "volume_2" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Storage' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'info', + 'type': 'storage_v2' + } + return self.request_data(api_name, api_path, req_param) + + def get_services_status(self) -> dict: + """ + Get services status. + + Returns + ------- + dict + Return the status of various services running on the Synology DSM. + + Examples + -------- + ```json + { + "data": { + "service": [ + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "helptoc:winmacnfs_mac", + "enable_status": "disabled", + "service_id": "atalk" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "network:bonjourPrinter_subject", + "enable_status": "enabled", + "service_id": "bonjour" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "helptoc:ntp_service", + "enable_status": "enabled", + "service_id": "chronyd" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "service:cups_printer_daemon", + "enable_status": "static", + "service_id": "cupsd" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "tree:leaf_ftp", + "enable_status": "disabled", + "service_id": "ftp-pure" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "tree:leaf_ftpes", + "enable_status": "disabled", + "service_id": "ftp-ssl" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "remote_key:kmip_tab_title", + "enable_status": "disabled", + "service_id": "kmip-server" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "nfs:nfs_title", + "enable_status": "disabled", + "service_id": "nfs-server" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "tree:leaf_iscsi", + "enable_status": "static", + "service_id": "pkg-iscsi" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "helptoc:winmacnfs_win", + "enable_status": "enabled", + "service_id": "pkg-synosamba-smbd" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "service:wstransfer_title", + "enable_status": "enabled", + "service_id": "pkg-synosamba-wstransfer-genconf" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "service:service_rsync", + "enable_status": "enabled", + "service_id": "rsyncd" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "tree:leaf_sftp", + "enable_status": "disabled", + "service_id": "sftp" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "SNMP", + "enable_status": "static", + "service_id": "snmpd" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "firewall:firewall_service_opt_ssh", + "enable_status": "enabled", + "service_id": "ssh-shell" + }, + { + "additional": { + "active_status": "active" + }, + "display_name_section_key": "about:dsm", + "enable_status": "static", + "service_id": "synoscgi" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "firewall:firewall_service_opt_telnet", + "enable_status": "disabled", + "service_id": "telnetd" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "ftp:tftp_title", + "enable_status": "disabled", + "service_id": "tftp" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "helptoc:power_ups", + "enable_status": "disabled", + "service_id": "ups-net" + }, + { + "additional": { + "active_status": "inactive" + }, + "display_name_section_key": "helptoc:power_ups", + "enable_status": "static", + "service_id": "ups-usb" + } + ] + }, + "success": true, + } + ``` + """ + api_name = 'SYNO.Core.Service' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get', + 'additional': ['active_status'] + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/LoginPortal.py b/synology_api/DSM/ControlPanel/LoginPortal.py new file mode 100644 index 00000000..2fe0df0d --- /dev/null +++ b/synology_api/DSM/ControlPanel/LoginPortal.py @@ -0,0 +1,829 @@ +""" +Login portal class for Synology DSM. +""" +from synology_api import base_api +import json + + +class LoginPortal(base_api.BaseApi): + """ + Login portal class for Synology DSM. + """ + + def get_dsm_web_service_info(self) -> dict: + """ + Get the web status of the login portal. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "enable_avahi": true, + "enable_custom_domain": false, + "enable_hsts": false, + "enable_https_redirect": false, + "enable_max_connections": false, + "enable_reuseport": false, + "enable_server_header": true, + "enable_spdy": true, + "enable_ssdp": true, + "fqdn": null, + "http_port": 5000, + "https_port": 5001, + "main_app": "DSM", + "max_connections": 2048, + "max_connections_limit": { + "lower": 2048, + "upper": 131070 + }, + "server_header": "nginx", + "support_reuseport": true + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Web.DSM" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "get", + } + return self.request_data(api_name, api_path, req_param) + + def list_app_portal(self, additionnal: list = []) -> dict: + """ + List application portals. + + Parameters + ---------- + additionnal : list, optional + Additional fields to include in the response, by default []. Possible values are "default_setting". + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "portal": [ + { + "display_name": "Active Backup for Microsoft 365 Portal", + "enable_redirect": false, + "id": "SYNO.SDS.ActiveBackupOffice365.Portal.Instance" + }, + { + "display_name": "Synology Calendar", + "enable_redirect": false, + "id": "SYNO.Cal.Application" + }, + { + "display_name": "Synology Contacts", + "enable_redirect": false, + "id": "SYNO.Contacts.AppInstance" + }, + { + "display_name": "Download Station", + "enable_redirect": false, + "id": "SYNO.SDS.DownloadStation.Application" + }, + { + "display_name": "File Station", + "enable_redirect": false, + "id": "SYNO.SDS.App.FileStation3.Instance" + }, + { + "display_name": "Note Station", + "enable_redirect": false, + "id": "SYNO.SDS.NoteStation.Application" + }, + { + "acl": null, + "alias": "cam", + "display_name": "Surveillance Station", + "enable_redirect": false, + "fqdn": null, + "hsts": false, + "http_port": 9900, + "id": "SYNO.SDS.SurveillanceStation" + }, + { + "display_name": "Synology Drive", + "enable_redirect": false, + "id": "SYNO.SDS.SheetStation.Application" + }, + { + "display_name": "Virtual Machine Manager", + "enable_redirect": false, + "id": "SYNO.SDS.Virtualization.Application" + } + ] + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "list", + "additional": json.dumps(additionnal), + } + return self.request_data(api_name, api_path, req_param) + + def list_reverse_proxy(self) -> dict: + """ + List reverse proxy rules. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "entries": [] + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.ReverseProxy" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "list", + } + return self.request_data(api_name, api_path, req_param) + + def list_access_control(self) -> dict: + """ + List access control rules. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "entries": [ + { + "UUID": "4d0b7d3d-d8a5-4b91-a160-efd45703005f", + "name": "test", + "rules": [ + { + "access": true, + "address": "127.0.0.1" + } + ] + } + ] + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.AccessControl" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "list", + } + return self.request_data(api_name, api_path, req_param) + + def get_login_theme(self) -> dict: + """ + Get the current login theme. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "background_color": "#FFFFFF", + "background_position": "fill", + "background_seq": 0, + "enable_background_customize": false, + "enable_logo_customize": false, + "login_footer_enable_html": false, + "login_title": "", + "login_version_logo": false, + "logo_position": "center", + "logo_seq": 0, + "only_background_color": false, + "weather_info": "display" + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Theme.Login" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "get", + } + return self.request_data(api_name, api_path, req_param) + + def get_app_theme(self, app_id: str) -> dict: + """ + Get the theme for a specific application. + + Parameters + ---------- + app_id : str + The ID of the application. The app_id can be found in the `list_app_portal()` returns. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "background_color": "#FFFFFF", + "background_position": "fill", + "background_seq": 0, + "enable_background_customize": false, + "enable_logo_customize": false, + "from_dsm": true, + "login_footer_enable_html": false, + "login_title": "", + "login_version_logo": false, + "logo_position": "center", + "logo_seq": 0, + "only_background_color": false, + "weather_info": "display" + } + ``` + """ + api_name = "SYNO.Core.Theme.AppPortalLogin" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "get", + "app": app_id, + } + return self.request_data(api_name, api_path, req_param) + + def set_dsm_web_service_info(self, + enable_custom_domain: bool, enable_avahi: bool, enable_hsts: bool, enable_https_redirect: bool, + enable_max_connections: bool, enable_reuseport: bool, enable_server_header: bool, enable_spdy: bool, + enable_ssdp: bool, fqdn: str = "", http_port: int = 5000, https_port: int = 5001, main_app: str = "DSM", max_connections: int = 2048, + max_connections_limit: dict = {"lower": 2048, "upper": 131070}, server_header: str = "nginx", support_reuseport: bool = True + ) -> dict: + """ + Set the web service information for DSM. Note that this will likely restart the web service. + + Parameters + ---------- + enable_custom_domain : bool + Enable custom domain. + enable_avahi : bool + Enable Avahi (mDNS) support. + enable_hsts : bool + Enable HTTP Strict Transport Security (HSTS). + enable_https_redirect : bool + Enable HTTPS redirection. + enable_max_connections : bool + Enable maximum connections limit. + enable_reuseport : bool + Enable SO_REUSEPORT option. + enable_server_header : bool + Enable server header in responses. + enable_spdy : bool + Enable SPDY protocol support. + enable_ssdp : bool + Enable SSDP support. + fqdn : str, optional + Fully qualified domain name, by default "". + http_port : int, optional + HTTP port number, by default 5000. + https_port : int, optional + HTTPS port number, by default 5001. + main_app : str, optional + Main application to launch on login, by default "DSM". + max_connections : int, optional + Maximum number of connections, by default 2048. + max_connections_limit : dict, optional + Dictionary with 'lower' and 'upper' keys for max connections limit, by default {"lower": 2048, "upper": 131070}. + server_header : str, optional + Server header string, by default "nginx". + support_reuseport : bool, optional + Whether SO_REUSEPORT is supported, by default True. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Web.DSM" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "set", + "enable_custom_domain": enable_custom_domain, + "enable_avahi": enable_avahi, + "enable_hsts": enable_hsts, + "enable_https_redirect": enable_https_redirect, + "enable_max_connections": enable_max_connections, + "enable_reuseport": enable_reuseport, + "enable_server_header": enable_server_header, + "enable_spdy": enable_spdy, + "enable_ssdp": enable_ssdp, + "fqdn": fqdn, + "http_port": http_port, + "https_port": https_port, + "main_app": main_app, + "max_connections": max_connections, + "max_connections_limit": json.dumps(max_connections_limit), + "server_header": server_header, + "support_reuseport": support_reuseport + } + return self.request_data(api_name, api_path, req_param) + + def set_login_theme(self, + background_color: str = "#FFFFFF", background_position: str = "fill", background_seq: int = 0, + enable_background_customize: bool = False, enable_logo_customize: bool = False, + login_footer_enable_html: bool = False, login_title: str = "", login_version_logo: bool = False, + logo_position: str = "center", logo_seq: int = 0, only_background_color: bool = False, + weather_info: str = "display" + ) -> dict: + """ + Set the login theme for DSM. + + Parameters + ---------- + background_color : str, optional + Background color in HEX format, by default "#FFFFFF". + background_position : str, optional + Background image position, by default "fill". Possible values are "fill", "fit", "stretch", "center", "tile". + background_seq : int, optional + Background image sequence number, by default 0. + enable_background_customize : bool, optional + Enable custom background image, by default False. + enable_logo_customize : bool, optional + Enable custom logo image, by default False. + login_footer_enable_html : bool, optional + Enable HTML in the login footer, by default False. + login_title : str, optional + Custom login title text, by default "". + login_version_logo : bool, optional + Show DSM version logo on the login page, by default False. + logo_position : str, optional + Logo image position, by default "center". Possible values are "left", "center", "right". + logo_seq : int, optional + Logo image sequence number, by default 0. + only_background_color : bool, optional + Use only background color without image, by default False. + weather_info : str, optional + Weather information display option, by default "display". Possible values are "display", "hide". + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Theme.Login" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "set", + "background_color": background_color, + "background_position": background_position, + "background_seq": background_seq, + "enable_background_customize": enable_background_customize, + "enable_logo_customize": enable_logo_customize, + "login_footer_enable_html": login_footer_enable_html, + "login_title": login_title, + "login_version_logo": login_version_logo, + "logo_position": logo_position, + "logo_seq": logo_seq, + "only_background_color": only_background_color, + "weather_info": weather_info + } + return self.request_data(api_name, api_path, req_param) + + def get_config(self) -> dict: + """ + Get the login portal configuration. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "data": { + "show_titlebar": true + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.Config" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "get", + } + return self.request_data(api_name, api_path, req_param) + + def set_config(self, show_titlebar: bool) -> dict: + """ + Set the login portal configuration. + + Parameters + ---------- + show_titlebar : bool + Whether to show the title bar on the login portal. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.Config" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "set", + "show_titlebar": show_titlebar + } + return self.request_data(api_name, api_path, req_param) + + def create_access_control_profile(self, name: str, rules: list) -> dict: + """ + Create an access control profile. + + Parameters + ---------- + name : str + Name of the access control profile. + rules : list + List of rules for the access control profile. Each rule is a dictionary with keys: + - action: "allow" or "deny" + - source: source IP or subnet in CIDR notation + - protocol: "http", "https", or "both" + - port: port number or range (e.g., "80", "443", "8000-9000") + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.AccessControl" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "create", + "name": name, + "rules": json.dumps(rules) + } + return self.request_data(api_name, api_path, req_param) + + def edit_access_control_profile(self, uuid: str, name: str, rules: list) -> dict: + """ + Edit an existing access control profile. + + Parameters + ---------- + uuid : str + UUID of the access control profile to edit. The UUID can be found in the `list_access_control()` returns. + name : str + New name for the access control profile. + rules : list + New list of rules for the access control profile. Each rule is a dictionary with keys: + - address : str (source IP or subnet in CIDR notation) + - access : bool (True for allow, False for deny) + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.AccessControl" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "edit", + "uuid": uuid, + "name": name, + "rules": json.dumps(rules) + } + return self.request_data(api_name, api_path, req_param) + + def delete_access_control_profile(self, uuids: list) -> dict: + """ + Delete one or more access control profiles. + + Parameters + ---------- + uuids : list + List of UUIDs of the access control profiles to delete. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.AccessControl" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "delete", + "uuids": json.dumps(uuids) + } + return self.request_data(api_name, api_path, req_param) + + def create_reverse_proxy_rule(self, entry: dict) -> dict: + """ + Create a reverse proxy rule. + + Parameters + ---------- + entry : dict + The reverse proxy rule configuration. Example: + { + "description": "yrdy", + "proxy_connect_timeout": 60, + "proxy_read_timeout": 60, + "proxy_send_timeout": 60, + "proxy_http_version": 1, + "proxy_intercept_errors": False, + "frontend": { + "acl": None, + "fqdn": None, + "port": 8000, + "protocol": 0, + "https": {"hsts": False} + }, + "backend": { + "fqdn": "localhost", + "port": 8080, + "protocol": 0 + }, + "customize_headers": [ + {"name": "yoyo", "value": "test"} + ] + } + + Returns + ------- + dict + Success response from the API. + + Examples + -------- + ```json + { + 'success': True + } + ``` + """ + api_name = 'SYNO.Core.AppPortal.ReverseProxy' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': 1, + 'method': 'create', + 'entry': json.dumps(entry) + } + return self.request_data(api_name, api_path, req_param) + + def edit_reverse_proxy_rule(self, entry: dict) -> dict: + """ + Edit a reverse proxy rule. + + Parameters + ---------- + entry : dict + The reverse proxy rule configuration, including UUID and _key. Example: + { + "description": "yrdy", + "proxy_connect_timeout": 60, + "proxy_read_timeout": 60, + "proxy_send_timeout": 60, + "proxy_http_version": 1, + "proxy_intercept_errors": False, + "UUID": "91dbcc5b-2467-4047-996c-2b5beb4fbefa", + "backend": { + "fqdn": "localhost", + "port": 8080, + "protocol": 0 + }, + "customize_headers": [ + {"name": "yoyo", "value": "test"} + ], + "frontend": { + "acl": None, + "fqdn": None, + "port": 8000, + "protocol": 0, + "https": {"hsts": False} + } + } + + Returns + ------- + dict + API response. + + Examples + -------- + ```json + { + 'success': True + } + ``` + """ + api_name = 'SYNO.Core.AppPortal.ReverseProxy' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': 1, + 'method': 'update', + 'entry': json.dumps(entry) + } + return self.request_data(api_name, api_path, req_param) + + def delete_reverse_proxy_rule(self, uuids: list) -> dict: + """ + Delete one or more reverse proxy rules. + + Parameters + ---------- + uuids : list + List of UUIDs of the reverse proxy rules to delete. + + Returns + ------- + dict + The response from the API call. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.AppPortal.ReverseProxy" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["maxVersion"], + "method": "delete", + "uuids": json.dumps(uuids) + } + return self.request_data(api_name, api_path, req_param) + + def edit_app_portal(self, id: str, display_name: str, additional: dict, enable_custom_domain: bool = False, + acl: str = None, fqdn: str = None, enable_redirect: bool = False) -> dict: + """ + Edit (set) an app portal. + + Parameters + ---------- + id : str + The app portal instance ID. + display_name : str + The display name for the portal. + additional : dict + Additional settings, e.g.: + { + "default_setting": { + "alias": "microsoft365", + "fqdn": "", + "hsts": False, + "http_port": 28003, + "https_port": 28004 + } + } + enable_custom_domain : bool, optional + Enable custom domain. Default is False. + acl : str, optional + Access control profile uuid. Default is None. + fqdn : str, optional + Fully qualified domain name. Default is None. + enable_redirect : bool, optional + Enable redirect. Default is False. + + Returns + ------- + dict + API response. + + Examples + -------- + ```json + { + 'success': True + } + ``` + """ + api_name = 'SYNO.Core.AppPortal' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': 2, + 'method': 'set', + 'id': id, + 'display_name': display_name, + 'additional': json.dumps(additional), + 'enable_custom_domain': enable_custom_domain, + 'acl': acl, + 'fqdn': fqdn, + 'enable_redirect': enable_redirect + } + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/Network.py b/synology_api/DSM/ControlPanel/Network.py new file mode 100644 index 00000000..9a221ad6 --- /dev/null +++ b/synology_api/DSM/ControlPanel/Network.py @@ -0,0 +1,906 @@ +""" +Network class for Synology DSM network settings. +""" + +from synology_api import base_api +import json + + +class Network(base_api.BaseApi): + """ + Network class for interacting with Synology DSM network settings. + + Supported methods: + - Getters: + - Get general settings + - Get proxy settings + - Get list of gateways + - Get list of network interfaces + - Get OVS status + - Get list of bond interfaces + - Get list of ethernet interfaces + - Get list of PPPoE interfaces + - Get list of PPTP VPN interfaces + - Get list of OpenVPN with conf file VPN interfaces + - Get list of OpenVPN VPN interfaces + - Get list of L2TP VPN interfaces + - Get traffic control rules + - Get port list per service + + - Setters: + - Set general settings + - Set proxy settings + - Set ethernet interfaces + """ + + def get_general_settings(self) -> dict: + """ + Get general network settings. + + Returns + ------- + dict + General network settings. + + Examples + -------- + ```json + { + "data": { + "arp_ignore": true, + "dns_manual": true, + "dns_primary": "103.86.96.100", + "dns_secondary": "192.168.1.1", + "enable_ip_conflict_detect": true, + "enable_windomain": false, + "gateway": "192.168.1.1", + "gateway_info": { + "ifname": "ovs_eth0", + "ip": "192.168.1.14", + "mask": "255.255.255.0", + "status": "connected", + "type": "ovseth", + "use_dhcp": true + }, + "ipv4_first": false, + "multi_gateway": false, + "server_name": "SERVER-NAME", + "use_dhcp_domain": true, + "v6gateway": "fe80::670:56ff:fe48:1f94" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_general_settings( + self, server_name: str, dns_manual: bool, dns_primary: str, + dns_secondary: str, arp_ignore: bool, multi_gateway: bool, + ipv4_first: bool, enable_ip_conflict_detect: bool, use_dhcp_domain: bool + ) -> dict: + """ + Set general network settings. + + Parameters + ---------- + server_name : str + Server name. + dns_manual : bool + Whether to set DNS manually. + dns_primary : str + Primary DNS server. + dns_secondary : str + Secondary DNS server. + arp_ignore : bool + Whether to ignore ARP. + multi_gateway : bool + Whether to enable multiple gateways. + ipv4_first : bool + Whether to prioritize IPv4. + enable_ip_conflict_detect : bool + Whether to enable IP conflict detection. + use_dhcp_domain : bool + Whether to use DHCP domain. + + Returns + ------- + dict + Result of setting general network settings. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Network", + "data": { + "hostname_changed_and_join_domain": false + }, + "method": "set", + "success": true, + "version": 2 + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Network' + info = self.gen_list[api_name] + compound = [ + { + 'api': api_name, + 'version': info['maxVersion'], + 'method': 'set', + 'server_name': server_name, + 'dns_manual': dns_manual, + 'dns_primary': dns_primary, + 'dns_secondary': dns_secondary, + 'arp_ignore': arp_ignore, + 'multi_gateway': multi_gateway, + 'ipv4_first': ipv4_first, + 'enable_ip_conflict_detect': enable_ip_conflict_detect, + 'use_dhcp_domain': use_dhcp_domain + } + ] + return self.batch_request(compound=compound) + + def get_proxy_settings(self) -> dict: + """ + Get proxy settings. + + Returns + ------- + dict + Proxy settings. + + Examples + -------- + ```json + { + "data": { + "enable": false, + "enable_auth": false, + "enable_bypass": true, + "enable_different_host": false, + "http_host": "", + "http_port": "80", + "https_host": "", + "https_port": "80", + "password": "\t\t\t\t\t\t\t\t", + "username": "" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Proxy' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def set_proxy_settings( + self, enable: bool, enable_auth: bool, enable_bypass: bool, + enable_different_host: bool, http_host: str, http_port: str, + https_host: str, https_port: str, username: str = None, password: str = None + ) -> dict: + """ + Set proxy settings. + + Parameters + ---------- + enable : bool + Whether to enable proxy. + enable_auth : bool + Whether to enable authentication. + enable_bypass : bool + Whether to enable bypass. + enable_different_host : bool + Whether to enable different host. + http_host : str + HTTP host. + http_port : str + HTTP port. + https_host : str + HTTPS host. + https_port : str + HTTPS port. + username : str, optional + Username for authentication. Default is None. + password : str, optional + Password for authentication. Default is None. + + Returns + ------- + dict + Result of setting proxy settings. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Network.Proxy", + "method": "set", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Network.Proxy' + info = self.gen_list[api_name] + compound = [ + { + 'api': api_name, + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable, + 'enable_auth': enable_auth, + 'enable_bypass': enable_bypass, + 'enable_different_host': enable_different_host, + 'http_host': http_host, + 'http_port': http_port, + 'https_host': https_host, + 'https_port': https_port + } + ] + + if username and password: + if self.session._secure: + compound[0]['username'] = username + compound[0]['password'] = password + else: + params_enc = { + 'username': username, + 'password': password + } + compound[0].update(self.session.encrypt_params(params_enc)) + + return self.batch_request(compound=compound) + + def get_gateway_list(self) -> dict: + """ + Get list of gateways. + + Returns + ------- + dict + List of gateways. + + Examples + -------- + ```json + { + "data": { + "configs": [ + { + "class": "ethernet", + "dns": "192.168.1.1", + "gateway": "192.168.1.1", + "ifname": "ovs_eth0", + "priority": 0, + "slave": false + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Gateway.List' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_interfaces_list(self) -> dict: + """ + Get list of network interfaces. + + Returns + ------- + dict + List of network interfaces. + + Examples + -------- + ```json + { + "data": [ + { + "ifname": "ovs_eth0", + "ip": "192.168.1.14", + "mask": "255.255.255.0", + "speed": 1000, + "status": "connected", + "type": "ovseth", + "use_dhcp": true + }, + { + "ifname": "ovs_eth1", + "ip": "169.254.183.6", + "mask": "255.255.0.0", + "speed": -1, + "status": "disconnected", + "type": "ovseth", + "use_dhcp": true + }, + { + "ifname": "pppoe", + "ip": "", + "mask": "", + "speed": 0, + "status": "disconnected", + "type": "pppoe", + "use_dhcp": true + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Interface' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_ovs_status(self) -> dict: + """ + Get infos if ovs is enabled or not. + + Returns + ------- + dict + Infos about ovs status. + + Examples + -------- + ```json + { + "data": { + "enable_ovs": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.OVS' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_bond_list(self) -> dict: + """ + Get list of bond interfaces. + + Returns + ------- + dict + List of bond interfaces. + + Examples + -------- + ```json + { + "data": [ + { + "block": 0, + "dns": "192.168.1.1", + "duplex": true, + "enable_ha_ip": false, + "enable_vlan": false, + "enabled": true, + "error": false, + "gateway": "192.168.1.1", + "ha_local_ip": "", + "ha_local_mask": "", + "ifname": "ovs_bond0", + "ip": "192.168.1.14", + "ipv6": [ + "2a01:cb05:814e:7d00:9209:d0ff:fe25:7371/64", + "fe80::9209:d0ff:fe25:7371/64" + ], + "is_default_gateway": false, + "is_main_ha_ip": false, + "mask": "255.255.255.0", + "max_supported_speed": -1, + "mode": "balance-slb", + "mtu": 1500, + "mtu_config": 1500, + "nat": false, + "slaves": [ + { + "block": 0, + "dns": "", + "duplex": true, + "enable_ha_ip": false, + "enable_vlan": false, + "gateway": "", + "ha_local_ip": "", + "ha_local_mask": "", + "ifname": "eth0", + "ip": "", + "ipv6": [], + "is_default_gateway": false, + "is_main_ha_ip": false, + "mask": "", + "max_supported_speed": 1000, + "mtu": 1500, + "mtu_config": 1500, + "nat": false, + "speed": 1000, + "status": "connected", + "type": "lan", + "use_dhcp": true, + "vlan_id": 0 + }, + { + "block": 0, + "dns": "", + "duplex": true, + "enable_ha_ip": false, + "enable_vlan": false, + "gateway": "", + "ha_local_ip": "", + "ha_local_mask": "", + "ifname": "eth1", + "ip": "", + "ipv6": [], + "is_default_gateway": false, + "is_main_ha_ip": false, + "mask": "", + "max_supported_speed": 1000, + "mtu": 1500, + "mtu_config": 1500, + "nat": false, + "speed": -1, + "status": "disconnected", + "type": "lan", + "use_dhcp": true, + "vlan_id": 0 + } + ], + "speed": 1000, + "status": "connected", + "type": "ovsbond", + "use_dhcp": true, + "vlan_id": 0 + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Bond' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_ethernet_interface_list(self) -> dict: + """ + Get list of ethernet interfaces. + + Returns + ------- + dict + List of ethernet interfaces. + + Examples + -------- + ```json + { + "data": [ + { + "block": 0, + "dns": "192.168.1.1", + "duplex": true, + "enable_ha_ip": false, + "enable_vlan": false, + "gateway": "192.168.1.1", + "ha_local_ip": "", + "ha_local_mask": "", + "ifname": "ovs_eth0", + "ip": "192.168.1.14", + "ipv6": [ + "2a01:cb05:814e:7d00:9209:d0ff:fe25:7371/64", + "fe80::9209:d0ff:fe25:7371/64" + ], + "is_default_gateway": false, + "is_main_ha_ip": false, + "mask": "255.255.255.0", + "max_supported_speed": 1000, + "mtu": 1500, + "mtu_config": 1500, + "nat": false, + "speed": 1000, + "status": "connected", + "type": "ovseth", + "use_dhcp": true, + "vlan_id": 0 + }, + { + "block": 0, + "dns": "", + "duplex": true, + "enable_ha_ip": false, + "enable_vlan": false, + "gateway": "", + "ha_local_ip": "", + "ha_local_mask": "", + "ifname": "ovs_eth1", + "ip": "169.254.183.6", + "ipv6": [], + "is_default_gateway": false, + "is_main_ha_ip": false, + "mask": "255.255.0.0", + "max_supported_speed": 1000, + "mtu": 1500, + "mtu_config": 1500, + "nat": false, + "speed": -1, + "status": "disconnected", + "type": "ovseth", + "use_dhcp": true, + "vlan_id": 0 + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Ethernet' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def set_ethernet_interfaces(self, configs: list) -> dict: + """ + Set ethernet interfaces. + + Parameters + ---------- + configs : list + List of configurations for ethernet interfaces. Each configuration is a dictionary with the following keys: + - ifname : str + Interface name. + - use_dhcp : bool + Whether to use DHCP. + - enable_ha_ip : bool, optional + Whether to enable HA IP. + - is_default_gateway : bool, optional + Whether this interface is the default gateway. + - mtu : int, optional + MTU size. + - enable_vlan : bool, optional + Whether to enable VLAN. + - ip : str, optional + IP address. + - mask : str, optional + Subnet mask. + - gateway : str, optional + Gateway address. + - dns : str, optional + DNS server address. + + Returns + ------- + dict + Result of setting ethernet interfaces. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Network.Ethernet", + "method": "set", + "success": true, + "version": 2 + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.Ethernet' + info = self.gen_list[api_name] + compound = [ + { + 'api': api_name, + 'version': info['maxVersion'], + 'method': 'set', + 'configs': configs + } + ] + return self.batch_request(compound=compound) + + def get_pppoe_interface_list(self) -> dict: + """ + Get list of pppoe interfaces. + + Returns + ------- + dict + List of pppoe interfaces. + + Examples + -------- + ```json + { + "data": [ + { + "devs": [ + "ovs_eth0", + "ovs_eth1" + ], + "guest_enabled": false, + "ifname": "pppoe", + "ip": "", + "is_default_gateway": 1, + "mask": "", + "mtu_config": "1492", + "password": "", + "real_ifname": "ovs_eth0", + "status": "disconnected", + "type": "pppoe", + "use_dhcp": true, + "username": "" + } + ], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.PPPoE' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_vpn_pptp_list(self) -> dict: + """ + Get list of pptp vpn interfaces. + + Returns + ------- + dict + List of pptp vpn interfaces. + + Examples + -------- + ```json + { + "data": [], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.VPN.PPTP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_vpn_openvpn_with_conf_list(self) -> dict: + """ + Get list of openvpn with conf file vpn interfaces. + + Returns + ------- + dict + List of openvpn with conf file vpn interfaces. + + Examples + -------- + ```json + { + "data": [], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.VPN.OpenVPNWithConf' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_vpn_openvpn_list(self) -> dict: + """ + Get list of openvpn vpn interfaces. + + Returns + ------- + dict + List of openvpn vpn interfaces. + + Examples + -------- + ```json + { + "data": [], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.VPN.OpenVPN' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_vpn_l2tp_list(self) -> dict: + """ + Get list of l2tp vpn interfaces. + + Returns + ------- + dict + List of l2tp vpn interfaces. + + Examples + -------- + ```json + { + "data": [], + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.VPN.L2TP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_traffic_control_rules(self, adapter: str) -> dict: + """ + Get traffic control rules. + + Parameters + ---------- + adapter : str + Adapter name, e.g. 'ovs_eth0'. + + Returns + ------- + dict + A dictionary containing the traffic control rules for the specified adapter. + + Examples + -------- + ```json + { + "data": { + "rules": [], + "total": 0 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Network.TrafficControl.Rules' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'load', + 'adapter': adapter + } + return self.request_data(api_name, api_path, req_param) + + def get_port_list_per_service(self) -> dict: + """ + Get port list per service. + + Returns + ------- + dict + Port list per service. + + Examples + -------- + ```json + { + "data": { + "port_info": [ + { + "desc": "rsync", + "dst_port": [ + "873" + ], + "name": "rsync", + "port_id": "netbkp", + "protocol": "tcp", + "src_port": null + }, + { + "desc": "Network MFP", + "dst_port": [ + "3240-3259" + ], + "name": "Network MFP", + "port_id": "mfp", + "protocol": "tcp", + "src_port": null + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Service.PortInfo' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'load', + 'target': json.dumps(["traffic_control"]) + } + return self.request_data(api_name, api_path, req_param) + + pass diff --git a/synology_api/DSM/ControlPanel/Notifications.py b/synology_api/DSM/ControlPanel/Notifications.py new file mode 100644 index 00000000..46fc1f66 --- /dev/null +++ b/synology_api/DSM/ControlPanel/Notifications.py @@ -0,0 +1,1204 @@ +""" +Notifications API endpoint. +""" +from synology_api import base_api +import json + + +class Notifications(base_api.BaseApi): + """ + Notifications API endpoint. + """ + + def list_filter_settings(self) -> dict: + """ + List current filter settings. + + Returns + ------- + dict + Current filter settings including enabled rule levels and types. + + Examples + -------- + ```json + { + "data": { + "All": [ + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "AutoBlockAdd", + "source": "dsm", + "tag": "AutoBlockAdd", + "title": "IP address blocked", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_WARN", + "name": "AutoBlockDatabaseRulesWarning", + "source": "dsm", + "tag": "AutoBlockDatabaseRulesWarning", + "title": "Too many IP addresses in the Block List on %HOSTNAME%", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_ERROR", + "name": "CMSClientConnectFailed", + "source": "dsm", + "tag": "CMSClientConnectFailed", + "title": "Unable to connect to the CMS Host", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "CMSClientDetachSuccess", + "source": "dsm", + "tag": "CMSClientDetachSuccess", + "title": "Disjoined from CMS host", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "CMSClientJoinSuccess", + "source": "dsm", + "tag": "CMSClientJoinSuccess", + "title": "Joined CMS host", + "warnPercent": 1 + } + ], + "send_welcome_mail": false, + "sender_mail": "test@gmail.com", + "sender_name": "", + "smtp_auth": { + "enable": true, + "user": "test@gmail.com" + }, + "smtp_info": { + "port": 465, + "server": "smtp.gmail.com", + "ssl": true + }, + "subject_prefix": "[SYNO-FLORENTB]" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def list_event(self) -> dict: + """ + List recent notification events. + + Returns + ------- + dict + Recent notification events including timestamps, app IDs, levels, and messages. + + Examples + -------- + ```json + { + "data": { + "All": [ + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "AutoBlockAdd", + "source": "dsm", + "tag": "AutoBlockAdd", + "title": "IP address blocked", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_WARN", + "name": "AutoBlockDatabaseRulesWarning", + "source": "dsm", + "tag": "AutoBlockDatabaseRulesWarning", + "title": "Too many IP addresses in the Block List on %HOSTNAME%", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_ERROR", + "name": "CMSClientConnectFailed", + "source": "dsm", + "tag": "CMSClientConnectFailed", + "title": "Unable to connect to the CMS Host", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "CMSClientDetachSuccess", + "source": "dsm", + "tag": "CMSClientDetachSuccess", + "title": "Disjoined from CMS host", + "warnPercent": 1 + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.FilterSettings.Template' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_filter_rule_settings(self, template_id: int) -> dict: + """ + Get the filter settings for a specific template. + + Parameters + ---------- + template_id : int + The ID of the template to retrieve settings for. + + Returns + ------- + dict + API response containing the filter settings for the specified template. + + Examples + -------- + ```json + { + "data": { + "All": [ + { + "appid": "SYNO.SDS.AdminCenter.Application", + "enabled": false, + "format": "mail", + "group": "System", + "level": "NOTIFICATION_INFO", + "name": "AutoBlockAdd", + "source": "dsm", + "tag": "AutoBlockAdd", + "title": "IP address blocked", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "enabled": true, + "format": "mail", + "group": "System", + "level": "NOTIFICATION_WARN", + "name": "AutoBlockDatabaseRulesWarning", + "source": "dsm", + "tag": "AutoBlockDatabaseRulesWarning", + "title": "Too many IP addresses in the Block List on %HOSTNAME%", + "warnPercent": 1 + }, + { + "appid": "SYNO.SDS.AdminCenter.Application", + "enabled": true, + "format": "mail", + "group": "System", + "level": "NOTIFICATION_ERROR", + "name": "CMSClientConnectFailed", + "source": "dsm", + "tag": "CMSClientConnectFailed", + "title": "Unable to connect to the CMS Host", + "warnPercent": 1 + } + ], + "template_id": 5, + "template_name": "test" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.FilterSettings.Template' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'get', + 'template_id': template_id + } + return self.request_data(api_name, api_path, req_param) + + def get_push_mail(self) -> dict: + """ + Get push mail configuration. + + Returns + ------- + dict + Push notification configuration details including service status and linked devices. + + Examples + -------- + ```json + { + "data": { + "enable_mail": true, + "mail": [ + "test@gmail.com" + ], + "subject_prefix": "", + "template_id": 1 + }, + "success": true + } + """ + api_name = 'SYNO.Core.Notification.Push.Mail' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def refresh_token(self) -> dict: + """ + Refresh the push notification token. + + Returns + ------- + dict + Status of the token refresh operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'refresh_token' + } + return self.request_data(api_name, api_path, req_param) + + def set_mail_config(self, + enable_mail: bool, + enable_oauth: bool, + subject_prefix: str, + smtp_info: dict, + send_welcome_mail: bool, + sender_name: str, + sender_mail: str, + oauth_provider: str) -> dict: + """ + Set the mail configuration for notifications. + + Parameters + ---------- + enable_mail : bool + Enable mail notifications. + enable_oauth : bool + Enable OAuth authentication. + subject_prefix : str + Prefix for the email subject. + smtp_info : dict + SMTP server information, e.g.: + {"server": "smtp.gmail.com", "port": 465, "ssl": True} + send_welcome_mail : bool + Send a welcome mail after configuration. + sender_name : str + Name of the sender. + sender_mail : str + Email address of the sender. + oauth_provider : str + OAuth provider (e.g., "gmail"). + + Returns + ------- + dict + API response. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable_mail': enable_mail, + 'enable_oauth': enable_oauth, + 'subject_prefix': subject_prefix, + 'smtp_info': json.dumps(smtp_info), + 'send_welcome_mail': send_welcome_mail, + 'sender_name': sender_name, + 'sender_mail': sender_mail, + 'oauth_provider': oauth_provider + } + return self.request_data(api_name, api_path, req_param) + + def send_test_mail(self, smtp_info: dict, mail: list[str], subject_prefix: str) -> dict: + """ + Send a test mail to verify the mail configuration. + + Parameters + ---------- + smtp_info : dict + SMTP server information, e.g.: + {"server": "smtp.gmail.com", "port": 465, "ssl": True} + mail : list[str] + List of email addresses to send the test email to. + subject_prefix : str + Prefix for the email subject. + + Returns + ------- + dict + Status of the test email operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'send_test', + 'smtp_info': json.dumps(smtp_info) if smtp_info else None, + 'mail': json.dumps(mail) if mail else None, + 'subject_prefix': subject_prefix + } + return self.request_data(api_name, api_path, req_param) + + def send_test_push_mail(self, target_id_list: list[int] = None) -> dict: + """ + Send a test push mail to synology account. + + Parameters + ---------- + target_id_list : list[int], optional + List of target IDs to send the test push mail to. If None, sends to all linked devices. + + Returns + ------- + dict + Status of the test email operation. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Mail' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'send_test' + } + if target_id_list: + req_param['target_id_list'] = json.dumps(target_id_list) if len( + target_id_list) > 1 else target_id_list[0] + + return self.request_data(api_name, api_path, req_param) + + def create_mail_profile(self, template_id: int, mail: list[str]) -> dict: + """ + Create a new mail profile for notifications. + + Parameters + ---------- + template_id : int + ID of the filter template to use. Use `list_filter_template` to get available templates. + mail : list[str] + List of email addresses to receive notifications. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail.Profile.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'create', + 'template_id': template_id, + 'mail': json.dumps(mail) + } + return self.request_data(api_name, api_path, req_param) + + def edit_mail_profile(self, profile_id: int, template_id: int, mail: list[str]) -> dict: + """ + Edit an existing mail profile for notifications. + + Parameters + ---------- + profile_id : int + ID of the profile to edit. Use `get_mail_config` to get existing profiles. + template_id : int + ID of the filter template to use. Use `list_filter_template` to get available templates. + mail : list[str] + List of email addresses to receive notifications. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail.Profile.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'profile_id': profile_id, + 'template_id': template_id, + 'mail': json.dumps(mail) + } + return self.request_data(api_name, api_path, req_param) + + def delete_mail_profile(self, profile_id: int) -> dict: + """ + Delete a mail profile for notifications. + + Parameters + ---------- + profile_id : int + ID of the profile to delete. Use `get_mail_config` to get existing profiles. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Mail.Profile.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'profile_id': profile_id + } + return self.request_data(api_name, api_path, req_param) + + def create_filter_rule(self, template_name: str, settings: list[dict]) -> dict: + """ + Create a new notification filter rule template. + + Parameters + ---------- + template_name : str + The name of the filter template. + settings : list of dict + List of filter settings, e.g.: + [ + {"tag": "AutoBlockAdd", "enabled": False}, + {"tag": "AutoBlockDatabaseRulesWarning", "enabled": True}, + ... + ] + + Returns + ------- + dict + template ID. + + Examples + -------- + ```json + { + "data": { + "template_id": 2 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.FilterSettings.Template' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'create', + 'template_name': template_name, + 'settings': json.dumps(settings) + } + return self.request_data(api_name, api_path, req_param) + + def edit_filter_rule(self, template_id: int, template_name: str, settings: list[dict]) -> dict: + """ + Edit an existing notification filter rule template. + + Parameters + ---------- + template_id : int + ID of the filter template to edit. Use `list_filter_template` to get existing templates. + template_name : str + The name of the filter template. + settings : list of dict + List of filter settings, e.g.: + [ + {"tag": "AutoBlockAdd", "enabled": False}, + {"tag": "AutoBlockDatabaseRulesWarning", "enabled": True}, + ... + ] + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.FilterSettings.Template' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'set', + 'template_id': template_id, + 'template_name': template_name, + 'settings': json.dumps(settings) + } + return self.request_data(api_name, api_path, req_param) + + def delete_filter_rule(self, template_id: int) -> dict: + """ + Delete a notification filter rule template. + + Parameters + ---------- + template_id : int + ID of the filter template to delete. Use `list_filter_template` to get existing templates. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.FilterSettings.Template' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'delete', + 'template_id': template_id + } + return self.request_data(api_name, api_path, req_param) + + def list_push_service(self) -> dict: + """ + List available push notification services. + + Returns + ------- + dict + Available push notification services. + + Examples + -------- + ```json + { + "data": { + "count": 1, + "list": [ + { + "app_version": "2.5.4-468", + "device_name": "IN2013", + "firmware_version": "13", + "profile_id": 5, + "target_id": 61451444, + "template_id": 2 + } + ], + "success": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Mobile' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def get_push_service_auth_token(self) -> dict: + """ + Get authentication token for push notification services. + + Returns + ------- + dict + Authentication token details. + + Examples + -------- + ```json + { + "data": { + "oauth_id": xxxxxxxxxxxxxxxxxxx, + "pushbrowser_server": "https://notification.synology.com/web/", + "register_token": "YOUR_REGISTER_TOKEN" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Mobile' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def unpair_push_service(self, target_id: int) -> dict: + """ + Unpair a push notification service. + + Parameters + ---------- + target_id : int + Target ID of the push service to unpair. Use `list_push_service` to get existing services. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Mobile' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'unpair', + 'target_id_list': str(target_id) + } + return self.request_data(api_name, api_path, req_param) + + def list_webhook(self) -> dict: + """ + List configured webhooks for notifications. + + Returns + ------- + dict + Configured webhooks details. + + Examples + -------- + ```json + { + "data": { + "count": 1, + "list": [ + { + "profile_id": 6, + "target_config": { + "interval": 0, + "needssl": true, + "port": 443, + "prefix": "[SYNO-FLORENTB]", + "provider": "test", + "req_header": "", + "req_method": "get", + "req_param": "", + "sepchar": " ", + "type": "custom", + "url": "https://webhook.site/558e159f-2dd8-48a1-8afb-ee9715ef5753?text=%40%40TEXT%40%40", + "use_default_lang": true + }, + "target_id": 6, + "target_name": "test", + "target_type": "webhook", + "template_config": { + "default_enabled_rule_level": "NOTIFICATION_ERROR", + "default_type": "Critical", + "is_default": true + }, + "template_id": 3, + "template_name": "Critical" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Webhook.Provider' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list' + } + return self.request_data(api_name, api_path, req_param) + + def _format_req_list(self, req_list): + """ + Convert a list of dicts or tuples to Synology API string format. Example: [{"name": "X-Token", "value": "abc"}, {"name": "X-Id", "value": "123"}] -> "X-Token:abc\rX-Id:123\r". + + Parameters + ---------- + req_list : list of dict + List of dicts with 'name' and 'value' keys. + + Returns + ------- + str + Formatted string for Synology API. + """ + if not req_list: + return "\r" + formatted = "".join( + f"{item['name']}:{item['value']}\r" for item in req_list) + return formatted + + def create_webhook(self, + provider: str, + url: str, + template_id: int, + req_header: list = None, + req_param: list = [ + {"name": "text", "value": "@@TEXT@@"}], + port: int = 443, + type_: str = "custom", + interval: int = 0, + req_method: str = "get", + needssl: bool = True, + use_default_lang: bool = True, + prefix: str = "", + sepchar: str = " ") -> dict: + """ + Create a new webhook provider for notifications, formatting req_header and req_param as required. + + Parameters + ---------- + provider : str + The provider name. + url : str + The webhook URL. + template_id : int + The template ID. + req_header : list of dict, optional + Example: [{"name": "X-Token", "value": "abc"}]. + req_param : list of dict, optional + Example: [{"name": "X-Token", "value": "abc"}]. + port : int, optional + The port to use (default: 443). + type_ : str, optional + The type of webhook (default: "custom"). Only "custom" is supported, TODO: Add others types. + interval : int, optional + The interval (default: 0). + req_method : str, optional + The HTTP request method (default: "get"). + needssl : bool, optional + Whether SSL is needed (default: True). + use_default_lang : bool, optional + Use default language (default: True). + prefix : str, optional + Prefix for the notification (default: ""). + sepchar : str, optional + Separator character (default: " "). + + Returns + ------- + dict + API response success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Notification.Push.Webhook.Provider' + info = self.core_list[api_name] + api_path = info['path'] + req_param_dict = { + 'version': info['maxVersion'], + 'method': 'create', + 'type': type_, + 'port': port, + 'template_id': template_id, + 'interval': interval, + 'req_method': req_method, + 'req_header': self._format_req_list(req_header), + 'req_param': self._format_req_list(req_param), + 'needssl': needssl, + 'provider': provider, + 'use_default_lang': use_default_lang, + 'prefix': prefix, + 'sepchar': sepchar, + 'url': url + } + + return self.request_data(api_name, api_path, req_param_dict) + + def edit_webhook(self, + profile_id: int, + provider: str, + url: str, + template_id: int, + req_header: list = None, + req_param: list = None, + port: int = 443, + type_: str = "custom", + interval: int = 0, + req_method: str = "get", + needssl: bool = True, + use_default_lang: bool = True, + prefix: str = "", + sepchar: str = " ") -> dict: + """ + Update (set) a webhook provider for notifications, formatting req_header and req_param as required. + + Parameters + ---------- + profile_id : int + The profile ID of the webhook provider. + provider : str + The provider name. + url : str + The webhook URL. + template_id : int + The template ID. + req_header : list of dict, optional + Example: [{"name": "X-Token", "value": "abc"}] + req_param : list of dict, optional + Example: [{"name": "foo", "value": "bar"}] + port : int, optional + The port to use (default: 443). + type_ : str, optional + The type of webhook (default: "custom"). Only "custom" is supported, TODO: Add others types. + interval : int, optional + The interval (default: 0). + req_method : str, optional + The HTTP request method (default: "get"). + needssl : bool, optional + Whether SSL is needed (default: True). + use_default_lang : bool, optional + Use default language (default: True). + prefix : str, optional + Prefix for the notification (default: ""). + sepchar : str, optional + Separator character (default: " "). + + Returns + ------- + dict + API response. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Webhook.Provider' + info = self.core_list[api_name] + api_path = info['path'] + req_param_dict = { + 'version': info['maxVersion'], + 'method': 'set', + 'profile_id': profile_id, + 'type': type_, + 'port': port, + 'template_id': template_id, + 'interval': interval, + 'req_method': req_method, + 'req_header': self._format_req_list(req_header), + 'req_param': self._format_req_list(req_param), + 'needssl': needssl, + 'provider': provider, + 'use_default_lang': use_default_lang, + 'prefix': prefix, + 'sepchar': sepchar, + 'url': url + } + return self.request_data(api_name, api_path, req_param_dict) + + def delete_webhook(self, profile_id: int) -> dict: + """ + Delete a webhook provider for notifications. + + Parameters + ---------- + profile_id : int + The profile ID of the webhook provider to delete. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Push.Webhook.Provider' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'profile_id': profile_id + } + return self.request_data(api_name, api_path, req_param) + + def get_variables(self) -> dict: + """ + Get notification variables such as company name and HTTP URL. + + Returns + ------- + dict + Notification variables including company name and HTTP URL. + + Examples + -------- + ```json + { + "data": { + "company_name": "Synology", + "http_url": "http://www.synology.com" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.Variables' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def edit_variables(self, company_name: str, http_url: str) -> dict: + """ + Edit notification variables such as company name and HTTP URL. + + Parameters + ---------- + company_name : str + The company name to set. + http_url : str + The HTTP URL to set. + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + # If http_url is not empty, verify it's a valid URL + if http_url and not (http_url.startswith("http://") or http_url.startswith("https://")): + raise ValueError( + "http_url must start with 'http://' or 'https://'") + + api_name = 'SYNO.Core.Notification.Advance.Variables' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'company_name': company_name, + 'http_url': http_url + } + return self.request_data(api_name, api_path, req_param) + + def get_event_message(self, event_tag: str) -> dict: + """ +Get the subject and message for a specific event tag. + + Parameters + ---------- + event_tag : str + The event tag to retrieve (e.g., "ActiveBackupOffice365_restore_warning"). + + Returns + ------- + dict + API response containing the subject and message for the specified event tag. + + Examples + -------- + ```json + { + "data": { + "content": "", + "default_content": "Les données [%SERVICENAME%] du compte [%SRCUSERNAME%] ont été partiellement restaurées sur le compte [%DESTUSERNAME%] par [%TRIGGER%] (succès : %SUCCESSNUM% ; avertissement : %WARNINGNUM%).\nHeure de début : %STARTTIME%\nHeure de fin : %ENDTIME%\nConnectez-vous à la console d'administration d'Active Backup for Microsoft 365 pour plus d'informations, puis réessayez plus tard.\n\nDe %HOSTNAME%", + "default_subject": "%PACKAGENAME% - Les données de sauvegarde sur [%HOSTNAME%] ont été partiellement restaurées", + "subject": "" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.CustomizedData' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get', + 'event_tag': event_tag + } + return self.request_data(api_name, api_path, req_param) + + def edit_event_message(self, event_tag: str, subject: str, message: str) -> dict: + """ + Edit the subject and message for a specific event tag. + + Parameters + ---------- + event_tag : str + The event tag to edit (e.g., "ActiveBackupOffice365_restore_warning"). + subject : str + The subject template for the event. + message : str + The message template for the event. Must be a valid html
...
with text in it. + E.g., "
Les données [%SERVICENAME%] du compte [%SRCUSERNAME%] ont été partiellement restaurées sur le compte [%DESTUSERNAME%] par [%TRIGGER%] (succès : %SUCCESSNUM% ; avertissement : %WARNINGNUM%).
Heure de début : %STARTTIME%
Heure de fin : %ENDTIME%
Connectez-vous à la console d'administration d'Active Backup for Microsoft 365 pour plus d'informations, puis réessayez plus tard.

De %HOSTNAME%
". + + Returns + ------- + dict + API response success status. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Notification.Advance.CustomizedData' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'event_tag': event_tag, + 'subject': subject, + 'message': message + } + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/RegionalOptions.py b/synology_api/DSM/ControlPanel/RegionalOptions.py new file mode 100644 index 00000000..104c4b9d --- /dev/null +++ b/synology_api/DSM/ControlPanel/RegionalOptions.py @@ -0,0 +1,384 @@ +""" +Regional options class for Synology DSM. +""" +from synology_api import base_api +import enum + + +class LanguageEnum(enum.Enum): + """ + Enum for available languages in Synology DSM. + """ + ENGLISH = "enu" + FRENCH = "fre" + GERMAN = "ger" + GREEK = "gre" + HEBREW = "heb" + THAI = "tha" + ITALIAN = "ita" + SPANISH = "spn" + TRADITIONAL_CHINESE = "cht" + SIMPLIFIED_CHINESE = "chs" + JAPANESE = "jpn" + KOREAN = "krn" + PORTUGUESE_BRAZIL = "ptb" + RUSSIAN = "rus" + DANISH = "dan" + NORWEGIAN = "nor" + SWEDISH = "sve" + DUTCH = "nld" + POLISH = "plk" + PORTUGUESE_GALICIAN = "ptg" + HUNGARIAN = "hun" + TURKISH = "trk" + CZECH = "csy" + ARABIC = "ara" + DEFAULT = "def" + + +class RegionalOptions(base_api.BaseApi): + """ +Regional options class for Synology DSM. + """ + + def get_time_info(self) -> dict: + """ +Get Date & Time information, Time Zone and Time Settings. + + Returns + ------- + dict + Date & Time information, Time Zone and Time Settings. + + Examples + -------- + ```json + { + "data": { + "date": "2025/9/15", + "date_format": "d/m/Y", + "enable_ntp": "ntp", + "hour": 20, + "minute": 48, + "now": "Mon Sep 15 20:48:00 2025\n", + "second": 0, + "server": "time.google.com", + "time_format": "H:i", + "timestamp": 1757962080, + "timezone": "Amsterdam" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_language_info(self) -> dict: + """ + Get Language information. + + Returns + ------- + dict + Language information. + + Examples + -------- + ```json + { + "data": { + "codepage": "fre", + "language": "def", + "maillang": "fre" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.Language' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_ntp_service_info(self) -> dict: + """ + Get NTP Service information. + + Returns + ------- + dict + NTP Service information. + + Examples + -------- + ```json + { + "data": { + "enable": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP.Server' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_ntp_service_status(self) -> dict: + """ + Get NTP Service status. + + Returns + ------- + dict + NTP Service status. + + Examples + -------- + ```json + { + "data": { + "ntp_status": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status' + } + return self.request_data(api_name, api_path, req_param) + + def list_timezone(self) -> dict: + """ + List available time zones. + + Returns + ------- + dict + Available time zones. + + Examples + -------- + ```json + { + "data": { + "zonedata": [ + { + "display": "(GMT-11:00) Samoa Standard Time; Midway Is.", + "offset": -39600, + "value": "Midway" + }, + { + "display": "(GMT-10:00) Hawaii Standard Time", + "offset": -36000, + "value": "Hawaii" + }, + { + "display": "(GMT-09:00) Alaska Standard Time", + "offset": -32400, + "value": "Alaska" + }, + { + "display": "(GMT-08:00) Pacific Time (US & Canada); Tijuana", + "offset": -28800, + "value": "Pacific" + }, + { + "display": "(GMT-07:00) Arizona", + "offset": -25200, + "value": "Arizona" + }, + { + "display": "(GMT-07:00) Mountain Time (US & Canada)", + "offset": -25200, + "value": "Mountain" + }, + { + "display": "(GMT-06:00) Central Time (US & Canada)", + "offset": -21600, + "value": "Central" + }, + { + "display": "(GMT-06:00) Chihuahua, Mazatlan", + "offset": -21600, + "value": "Chihuahua" + }, + { + "display": "(GMT-06:00) Central America Standard Time; Guatemala", + "offset": -21600, + "value": "Guatemala" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['minVersion'], + 'method': 'listzone' + } + return self.request_data(api_name, api_path, req_param) + + def set_time_info(self, date_format: str, time_format: str, timezone: str, enable_ntp: str, server: str, date: str, hour: int, minute: int, second: int, change_time: bool = False) -> dict: + """ + Set Date & Time information, Time Zone and Time Settings. + + Parameters + ---------- + date_format : str + Date format, known formats are `YYYY-MM-dd`, `YYYY/MM/dd`, `YYYY.MM.dd`, `dd-MM-YYYY`, `dd/MM/YYYY`, `dd.MM.YYYY`, `MM-dd-YYYY`, `MM/dd/YYYY`, `MM.dd.YYYY`. + time_format : str + Time format, known formats are `H:i`, `h:i A`. + timezone : str + Time zone, can be get from `list_timezone` field "value". + enable_ntp : str + NTP setting ('ntp' to enable, 'manual' to disable). + server : str + NTP server address, only if `enable_ntp` is set to 'ntp'. + date : str + Date in 'YYYY/MM/DD' format, only if `enable_ntp` is set to 'manual'. + hour : int + Hour (0-23), only if `enable_ntp` is set to 'manual'. + minute : int + Minute (0-59), only if `enable_ntp` is set to 'manual'. + second : int + Second (0-59), only if `enable_ntp` is set to 'manual'. + change_time : bool, optional + Whether to change the time immediately, defaults to False. + + Returns + ------- + dict + Response from the API. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'date_format': date_format, + 'time_format': time_format, + 'timezone': timezone, + 'enable_ntp': enable_ntp, + 'change_time': change_time + } + if enable_ntp == 'manual': + req_param.update({ + 'date': date, + 'hour': hour, + 'minute': minute, + 'second': second + }) + elif enable_ntp == 'ntp': + # server is required in this case + req_param.update({ + 'server': server + }) + return self.request_data(api_name, api_path, req_param) + + def list_language(self) -> LanguageEnum: + """ + List available languages. + + Returns + ------- + LanguageEnum + Available languages. + """ + return LanguageEnum + + def set_language_info(self, language: LanguageEnum, maillang: LanguageEnum, codepage: LanguageEnum) -> dict: + """ + Set Language information. + + Parameters + ---------- + language : LanguageEnum + Display language, you can use the `DEFAULT` from the LanguageEnum. + maillang : LanguageEnum + Notification language, you cannot use `DEFAULT` from the LanguageEnum. + codepage : LanguageEnum + Codepage, you cannot use `DEFAULT` from the LanguageEnum. + + Returns + ------- + dict + Response from the API. + """ + api_name = 'SYNO.Core.Region.Language' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'language': language.value, + 'maillang': maillang.value, + 'codepage': codepage.value + } + return self.request_data(api_name, api_path, req_param) + + def set_ntp_service_info(self, enable: bool) -> dict: + """ + Set NTP Service information. + + Parameters + ---------- + enable : bool + Whether to enable the NTP service. + + Returns + ------- + dict + Response from the API. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Region.NTP.Server' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'set', + 'enable': enable + } + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/Security.py b/synology_api/DSM/ControlPanel/Security.py new file mode 100644 index 00000000..39a49005 --- /dev/null +++ b/synology_api/DSM/ControlPanel/Security.py @@ -0,0 +1,473 @@ +""" +Security class for Synology DSM. +""" +from synology_api import base_api +import json + + +class Security(base_api.BaseApi): + """ + Security class for Synology DSM. + """ + + def get_security_settings(self) -> dict: + """ + Get security settings, Security tab: General, Login Settings. + + Returns + ------- + dict + Security settings information. + + Examples + -------- + ```json + { + "data": { + "allow_stay_signed_in_option": true, + "allow_trust_device_2fa_option": true, + "csp_header_option": true, + "enable_csrf_protection": true, + "restart_clean_session": true, + "skip_ip_checking": true, + "timeout": 15 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Security.DSM' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_dsm_embedded_settings(self) -> dict: + """ + Get DSM embedded settings. + + Returns + ------- + dict + DSM embedded settings information. + + Examples + -------- + ```json + { + "data": { + "enable_block": true, + "whitelist": [ + "find.synology.com/", + "gofile.me/" + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Security.DSM.Embed' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_2fa_settings(self) -> dict: + """ + Get 2-factor authentication settings, Account tab: 2-factor authentication. + + Returns + ------- + dict + 2-factor authentication settings information. + + Examples + -------- + ```json + { + "data": { + "otp_enforce_option": "custom" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.OTP.EnforcePolicy' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_amfa_settings(self) -> dict: + """ + Get AMFA (Adaptive Multi-Factor Authentication) settings, Account tab: Adaptive multi-factor authentication. + + Returns + ------- + dict + AMFA settings information. + + Examples + -------- + ```json + { + "data": { + "group_list": "", + "type": "admin", + "user_list": "" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.SecureSignIn.AMFA.Policy' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_smartblock_settings(self) -> dict: + """ + Get Smart Block settings, Login Settings tab: Smart Block. + + Returns + ------- + dict + Smart Block settings information. + + Examples + -------- + ```json + { + "data": { + "enabled": true, + "trust_lock": 30, + "trust_minute": 1, + "trust_try": 10, + "untrust_lock": 30, + "untrust_minute": 1, + "untrust_try": 5 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.SmartBlock' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_firewall_status(self) -> dict: + """ + Get firewall status, Firewall tab: Enable firewall. + + Returns + ------- + dict + Firewall status information. + + Examples + -------- + ```json + { + "data": { + "enable_firewall": true, + "profile_name": "default" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Security.Firewall' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_firewall_notifications_settings(self) -> dict: + """ + Get firewall notifications settings, Firewall tab: Enable firewall notifications. + + Returns + ------- + dict + Firewall notifications settings information. + + Examples + -------- + ```json + { + "data": { + "enable_port_check": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Security.Firewall.Conf' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_auto_block_settings(self) -> dict: + """ + Get auto block settings, Auto Block tab: Enable auto block. + + Returns + ------- + dict + Auto block settings information. + + Examples + -------- + ```json + { + "data": { + "attempts": 10, + "enable": true, + "expire_day": 0, + "within_mins": 5 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Security.AutoBlock' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_dos_settings(self, adapter_list: list[str]) -> dict: + """ + Get DoS settings, Protect tab: Denial-of-Service (DoS) Protection. + + Parameters + ---------- + adapter_list : list[str] + List of network interfaces to get DoS settings for. Can be obtained via `Network.get_network_interface()` and get `ifname` from the response. + + Returns + ------- + dict + DoS settings information. + + Examples + -------- + ```json + { + "data": [ + { + "adapter": "ovs_eth0", + "dos_protect_enable": true + }, + { + "adapter": "ovs_eth1", + "dos_protect_enable": false + }, + { + "adapter": "pppoe", + "dos_protect_enable": false + } + ], + "success": true + } + ``` + """ + configs = [{"adapter": adapter} for adapter in adapter_list] + + api_name = 'SYNO.Core.Security.DoS' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get', + 'configs': json.dumps(configs) + } + + return self.request_data(api_name, api_path, req_param) + + def get_http_compression_settings(self) -> dict: + """ + Get HTTP compression settings, Advanced tab: HTTP compression. + + Returns + ------- + dict + HTTP compression settings information. + + Examples + -------- + ```json + { + "data": { + "http_compression": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Web.Security.HTTPCompression' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_tls_profile_settings(self) -> dict: + """ + Get TLS profile settings, Advanced tab: TLS / SSL Profile level. + + Returns + ------- + dict + TLS profile settings information. + + Examples + -------- + ```json + { + "data": { + "default-level": 1, + "services": { + "LogCenter": { + "current-level": 0, + "display-name": "Log Receiving", + "display-name-i18n": "helptoc:logcenter_server" + }, + "WebStation_4437801d-caf5-45d6-afbd-99fc2f9f91dc": { + "current-level": 0, + "display-name": "*:8080" + }, + "dsm": { + "current-level": 0, + "display-name": "DSM Desktop Service", + "display-name-i18n": "common:web_desktop" + }, + "openldap": { + "current-level": 0, + "display-name": "LDAP Server" + }, + "smbftpd": { + "current-level": 0, + "display-name": "FTPS", + "display-name-i18n": "tree:leaf_ftpes" + }, + "system_quickconnect": { + "current-level": 0, + "display-name": "QuickConnect", + "display-name-i18n": "helptoc:quickconnect" + } + } + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Web.Security.TLSProfile' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_spectre_meldown_settings(self) -> dict: + """ + Get Spectre/Meltdown settings, Advanced tab: Spectre/Meltdown Protection. + + Returns + ------- + dict + Spectre/Meltdown settings information. + + Examples + -------- + ```json + { + "data": { + "enable_spectre_meltdown_mitigation": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Hardware.SpectreMeltdown' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) + + def get_kmip_settings(self) -> dict: + """ + Get KMIP settings, KMIP tab. + + Returns + ------- + dict + KMIP settings information. + + Examples + -------- + ```json + { + "data": { + "client_cert_info": null, + "client_enable": false, + "conn_success": false, + "conn_time": "", + "kmip_conn_server_desc": "", + "kmip_conn_server_port": "5696", + "kmip_db_loc": "", + "kmip_enabled": "", + "kmip_mode": "", + "kmip_server": "", + "kmip_server_port": "5696", + "server_cert_info": null, + "server_enable": false, + "support_kmip": "yes" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Storage.CGI.KMIP' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'get' + } + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/SharedFolder.py b/synology_api/DSM/ControlPanel/SharedFolder.py new file mode 100644 index 00000000..d2222b40 --- /dev/null +++ b/synology_api/DSM/ControlPanel/SharedFolder.py @@ -0,0 +1,1025 @@ +""" +Core Share API implementation. +""" + +from synology_api import base_api +import json +from typing import List, Any + + +class SharedFolder(base_api.BaseApi): + """ + Core Share API implementation. + + Supported methods: + - Getters: + - Validate set of parameters for a new/modified shared folder + - List all folders information + - Get a folder by name + - Retrieve share permissions for a given folder filtered by permission name (sub string) + - Retrieve share permissions for a given folder + - Retrieve share permissions for a given group + + - Setters: + - Create a new shared folder + - Set folder permissions for a given folder + - Set group permissions for a given share + + - Actions: + - Delete folder(s) by name(s) + - Clone existing shared folder + """ + + def validate_set(self, name: str, vol_path: str, desc: str = "", enable_share_compress: bool = False, enable_share_cow: bool = False, enc_passwd: str = "", encryption: bool = False) -> dict: + """ + Validate set of parameter for a new / modified shared folder. + + Parameters + ---------- + name : str + Share name. + vol_path : str + Volume path. + desc : str, optional + Share description. Defaults to `""`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enc_passwd : str, optional + Encrypted password. Defaults to `""`. + encryption : bool, optional + Enable encryption. Defaults to `False`. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true, + } + ``` + """ + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "validate_set", + "version": info['maxVersion'], + "name": name, + } + + req_param_encrypted = { + "shareinfo": json.dumps({ + "name": name, + "vol_path": vol_path, + "desc": desc, + "enable_share_compress": enable_share_compress, + "enable_share_cow": enable_share_cow, + "enc_passwd": enc_passwd, + "encryption": encryption, + }) + } + + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def list_folders(self, share_type: str = "all", additional: list = []) -> dict: + """ + List all folders informations. + + Parameters + ---------- + share_type : str, optional + Share type. Defaults to `all`. + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `[ + "hidden","encryption","is_aclmode","unite_permission","is_support_acl","is_sync_share","is_force_readonly","force_readonly_reason", + "recyclebin","is_share_moving","is_cluster_share","is_exfat_share","is_c2_share","is_cold_storage_share","is_missing_share", + "is_offline_share","support_snapshot","share_quota","enable_share_compress","enable_share_cow","enable_share_tiering", + "load_worm_attr","include_cold_storage_share","is_cold_storage_share","include_missing_share","is_missing_share", + "include_offline_share","is_offline_share","include_worm_share" + ]`. + + Returns + ------- + dict + A dictionary containing the shared folders information. + + Examples + -------- + ```json + { + "data": { + "shares": [ + { + "desc": "", + "is_usb_share": false, + "name": "test_shared_folder", + "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", + "vol_path": "/volume1" + } + ], + "total": 1 + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "list", + "version": info['minVersion'], + "shareType": share_type, + "additional": json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def get_folder(self, name: str, additional: list = []) -> dict: + """ + Get a folder by name. + + Parameters + ---------- + name : str + Share name. + additional : list, optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `["disable_list","disable_modify","disable_download","unite_permission","is_aclmode"]`. + + Returns + ------- + dict + A dictionary containing the shared folder information. + + Examples + -------- + ```json + { + "data": { + "desc": "", + "disable_download": false, + "disable_list": false, + "disable_modify": false, + "is_aclmode": true, + "is_usb_share": false, + "name": "test_shared_folder", + "unite_permission": false, + "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", + "vol_path": "/volume1" + }, + "success": true, + ``` + """ + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "get", + "version": info['minVersion'], + "name": name, + "additional": json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def create_folder(self, + name: str, vol_path: str, desc: str = "", hidden: bool = False, + enable_recycle_bin: bool = True, recycle_bin_admin_only: bool = True, + hide_unreadable: bool = False, enable_share_cow: bool = False, + enable_share_compress: bool = False, share_quota: int = 0, name_org: str = "", + encryption: bool = False, enc_passwd: str = "" + ) -> dict: + """ + Create a new shared folder. + + Parameters + ---------- + name : str + Share name. + vol_path : str + Volume path. + desc : str, optional + Share description. Defaults to `""`. + hidden : bool, optional + Hide share. Defaults to `False`. + enable_recycle_bin : bool, optional + Enable recycle bin. Defaults to `True`. + recycle_bin_admin_only : bool, optional + Recycle bin admin only. Defaults to `True`. + hide_unreadable : bool, optional + Hide unreadable. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + share_quota : int, optional + Share quota. Defaults to `0`. + name_org : str, optional + Defaults to `""`. + encryption : bool, optional + Enable encryption. Defaults to `False`. + enc_passwd : str, optional + Encrypted password. Defaults to `""`. + + Returns + ------- + dict + Name of the created shared folder. + + Examples + -------- + ```json + { + "data": { + "name": "test_shared_folder" + }, + "success": true, + ``` + """ + + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "create", + "version": info['maxVersion'], + "name": name, + } + req_param_encrypted = { + "shareinfo": json.dumps({ + "desc": desc, + "enable_recycle_bin": enable_recycle_bin, + "enable_share_compress": enable_share_compress, + "enable_share_cow": enable_share_cow, + "name": name, + "name_org": name_org, + "vol_path": vol_path, + "recycle_bin_admin_only": recycle_bin_admin_only, + "hidden": hidden, + "hide_unreadable": hide_unreadable, + "share_quota": share_quota, + "encryption": encryption, + "enc_passwd": enc_passwd, + }) + } + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def delete_folders(self, name: List[str]) -> dict: + """ + Delete folder(s) by name(s). + + Parameters + ---------- + name : List[str] + Share names. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "delete", + "version": info['minVersion'], + "name": name + } + + return self.request_data(api_name, api_path, req_param) + + def clone(self, + name: str, name_org: str, vol_path: str, desc: str = "", hidden: bool = False, + enable_recycle_bin: bool = True, recycle_bin_admin_only: bool = True, + hide_unreadable: bool = False, enable_share_cow: bool = False, + enable_share_compress: bool = False, share_quota: int = 0 + ) -> dict: + """ + Clone existing shared folder. + + Parameters + ---------- + name : str + New shared folder name. + name_org : str + Original shared folder name. + vol_path : str + Volume path. + desc : str, optional + Shared folder description. Defaults to `""`. + hidden : bool, optional + Hide shared folder. Defaults to `False`. + enable_recycle_bin : bool, optional + Enable recycle bin. Defaults to `True`. + recycle_bin_admin_only : bool, optional + Recycle bin admin only. Defaults to `True`. + hide_unreadable : bool, optional + Hide unreadable. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + share_quota : int, optional + Share quota. Defaults to `0`. + + Returns + ------- + dict + Name of the created shared folder. + + Examples + -------- + ```json + { + "data": { + "name": "test_shared_folder" + }, + "success": true, + ``` + """ + api_name = "SYNO.Core.Share" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "clone", + "version": info['maxVersion'], + "name": name, + } + + req_param_encrypted = { + "shareinfo": json.dumps({ + "desc": desc, + "enable_recycle_bin": enable_recycle_bin, + "enable_share_compress": enable_share_compress, + "enable_share_cow": enable_share_cow, + "name": name, + "name_org": name_org, + "vol_path": vol_path, + "recycle_bin_admin_only": recycle_bin_admin_only, + "hidden": hidden, + "hide_unreadable": hide_unreadable, + "share_quota": share_quota, + }) + } + + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def get_folder_permission_by_name(self, + name: str, permission_substr: str, offset: int = 0, limit: int = 50, is_unite_permission: bool = False, with_inherit: bool = False, + user_group_type: str = "local_user" + ) -> dict: + """ + Retrieve share permissions for a given folder filtered by permission name (sub string). + + Parameters + ---------- + name : str + The folder name to list permissions for. + permission_substr : str + The substring to search for in the permissions. + offset : int, optional + The offset to start at. Defaults to `0`. + limit : int, optional + The maximum number of results to return. Defaults to `50`. + is_unite_permission : bool, optional + Whether to return unified permissions. Defaults to `False`. + with_inherit : bool, optional + Whether to include inherited permissions. Defaults to `False`. + user_group_type : str, optional + The type of user group to list permissions for. Defaults to `"local_user"`. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + + Returns + ------- + dict + List of permission(s) on the folder. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "guest" + } + ], + "total": 1 + }, + "success": true + } + ``` + """ + + api_name = "SYNO.Core.Share.Permission" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["minVersion"], + "method": "list", + "name": name, + "offset": offset, + "limit": limit, + "action": "find", + "substr": permission_substr, + "is_unite_permission": is_unite_permission, + "with_inherit": with_inherit, + "user_group_type": user_group_type, + } + return self.request_data(api_name, api_path, req_param, method="get") + + def get_folder_permissions(self, + name: str, offset: int = 0, limit: int = 50, is_unite_permission: bool = False, with_inherit: bool = False, + user_group_type: str = "local_user" + ) -> dict: + """ + Retrieve share permissions for a given folder. + + Parameters + ---------- + name : str + The folder name to list permissions for. + offset : int, optional + The offset to start at. Defaults to `0`. + limit : int, optional + The maximum number of results to return. Defaults to `50`. + is_unite_permission : bool, optional + Whether to return unified permissions. Defaults to `False`. + with_inherit : bool, optional + Whether to include inherited permissions. Defaults to `False`. + user_group_type : str, optional + The type of user group to list permissions for. Defaults to `"local_user"`. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + + Returns + ------- + dict + All permissions on the folder. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "inherit": "rw", + "is_admin": true, + "is_custom": false, + "is_deny": true, + "is_readonly": false, + "is_writable": false, + "name": "admin" + }, + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "guest" + }, + { + "inherit": "rw", + "is_admin": true, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": true, + "name": "test_api" + }, + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "test_test" + } + ], + "total": 5 + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Permission" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["minVersion"], + "method": "list", + "name": name, + "offset": offset, + "limit": limit, + "action": "enum", + "is_unite_permission": is_unite_permission, + "with_inherit": with_inherit, + "user_group_type": user_group_type, + } + return self.request_data(api_name, api_path, req_param, method="get") + + def set_folder_permissions(self, name: str, user_group_type: str, permissions: List[dict[str, object]]) -> dict: + """ + Set folder permissions for a given folder. + + Parameters + ---------- + name : str + The folder name to set permissions for. + user_group_type : str + The type of user group to set permissions for. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + permissions : dict + The permissions to set for the folder. + Example: + ```json + [ + { + "name":"guest", + "is_readonly":false, + "is_writable":true, + "is_deny":false, + "is_custom":false + } + ] + ``` + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Permission" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["minVersion"], + "method": "set", + "name": name, + "user_group_type": user_group_type, + "permissions": json.dumps(permissions), + } + return self.request_data(api_name, api_path, req_param, method="get") + + def get_local_group_permissions(self, group: str) -> dict: + """ + Retrieve share permissions for a given group. + + Parameters + ---------- + group : str + The group to list permissions for. + + Returns + ------- + dict + Permissions of a group on Shared folders. + + Examples + -------- + ```json + { + "data": { + "shares": [ + { + "is_aclmode": true, + "is_custom": false, + "is_deny": true, + "is_mask": false, + "is_readonly": false, + "is_sync_share": false, + "is_unite_permission": false, + "is_writable": false, + "name": "ActiveBackupforBusiness", + "share_path": "/volume3/ActiveBackupforBusiness" + } + ], + "total": 1 + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Permission" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": 1, + "method": "list_by_group", + "name": group, + "user_group_type": "local_group", + "share_type": json.dumps( + ["dec", "local", "usb", "sata", "cluster", + "c2", "cold_storage", "worm"] + ), + "additional": json.dumps(["hidden", "encryption", "is_aclmode"]), + } + return self.request_data(api_name, api_path, req_param) + + def set_local_group_permissions( + self, group: str, permissions: list[dict[str, Any]] + ) -> dict: + """ + Set group permissions for a given share. + + Parameters + ---------- + group : str + The group to set the permissions for. + + permissions : list[dict[str, Any]] + The permissions to set for the group. + Example: + ``` + [ + { + "name": "web", + "is_readonly": False, + "is_writable": False, + "is_deny": True + }, + { + "name": "ActiveBackupforBusiness", + "is_readonly": False, + "is_writable": True, + "is_deny": False + } + ] + ``` + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Permission" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "version": info["minVersion"], + "method": "set_by_user_group", + "name": group, + "user_group_type": "local_group", + "permissions": json.dumps(permissions), + } + + return self.request_data(api_name, api_path, req_param) + + def export_encryption_key(self, name: str, password: str) -> dict: + """ + Export encryption key for a given share. + + Parameters + ---------- + name : str + The share name to export the encryption key for. + password : str + The password to use for exporting the encryption key. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Crypto.Key" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "export", + "version": info['maxVersion'], + "name": name, + } + + enc_req_param = { + "password": password, + } + # If using https don't use encryption + if self.session._secure: + req_param.update(enc_req_param) + else: + encrypted_params = self.session.encrypt_params(enc_req_param) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def decrypt_folder(self, name: str, password: str) -> dict: + """ + Decrypt a given share. + + Parameters + ---------- + name : str + The share name to decrypt. + password : str + The password to use for decrypting the share. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Crypto" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "decrypt", + "version": info['maxVersion'], + "name": name, + } + + req_param_encrypted = { + "password": password, + } + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def encrypt_folder(self, name: str) -> dict: + """ + Encrypt a given share. + + Parameters + ---------- + name : str + The share name to encrypt. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Crypto" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "encrypt", + "version": info['maxVersion'], + "name": name, + } + return self.request_data(api_name, api_path, req_param, method="post") + + +class KeyManagerStore(base_api.BaseApi): + """ + Core Share KeyManager Store API implementation. + """ + + def init(self) -> dict: + """ + Initialize KeyManagerStore API. + + Returns + ------- + dict + Not implemented yet. + """ + + raise NotImplementedError( + "This method is not completly implemented yet. API return error 403") + + api_name = "SYNO.Core.Share.KeyManager.Store" + version = self.core_list[api_name]["maxVersion"] + api_path = self.core_list[api_name]["path"] + req_param = { + "version": version, + "method": "init", + "share_path": "/usr/syno/etc/.encrypt" + } + + req_param_encrypted = { + "passphrase": "", + } + + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def verify(self) -> dict: + """ + Verify KeyManagerStore API. + + Returns + ------- + dict + Not implemented yet. + """ + raise NotImplementedError("This method is not implemented yet.") + + api_name = "SYNO.Core.Share.KeyManager.Store" + version = self.core_list[api_name]["maxVersion"] + api_path = self.core_list[api_name]["path"] + req_param = { + "version": version, + "method": "verify", + } + + req_param_encrypted = { + "passphrase": "", + } + + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) + + return self.request_data(api_name, api_path, req_param, method="post") + + def explore(self) -> dict: + """ + Explore KeyManagerStore API. Get list of existing stores. + + Returns + ------- + dict + List of stores existing on the NAS. + + Examples + -------- + ```json + { + "data": { + "stores": [] + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.KeyManager.Store" + version = self.core_list[api_name]["minVersion"] + api_path = self.core_list[api_name]["path"] + req_param = { + "version": version, + "method": "explore", + } + + return self.request_data(api_name, api_path, req_param) + + def add(self, share_name: str, share_cypher: int, share_password: str) -> dict: + """ + Add KeyManagerStore API. Add a new store. + + Parameters + ---------- + share_name : str + The share name to add to the store. + share_cypher : int + The share cypher to use. + share_password : str + The share password to use. + + Returns + ------- + dict + Not implemented yet. + """ + raise NotImplementedError( + "This method is not completly implemented yet. API return error 403") + + api_name = "SYNO.Core.Share.KeyManager.Key" + version = self.core_list[api_name]["maxVersion"] + api_path = self.core_list[api_name]["path"] + req_param = { + "version": version, + "method": "add", + "share_name": share_name, + "share_cypher": share_cypher, + "share_password": share_password, + "passphrase": "2PassValidation", + } + + return self.request_data(api_name, api_path, req_param, method="post") + + +class KeyManagerAutoKey(base_api.BaseApi): + """ + Core Share KeyManager AutoKey API implementation. + """ + + def list(self) -> dict: + """ + List KeyManagerStore API. + + Returns + ------- + dict + List of keys in the manager. + + Examples + -------- + ```json + { + "data": { + "keys": [] + }, + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.KeyManager.AutoKey" + version = self.core_list[api_name]["minVersion"] + api_path = self.core_list[api_name]["path"] + req_param = { + "version": version, + "method": "list", + } + + return self.request_data(api_name, api_path, req_param) diff --git a/synology_api/DSM/ControlPanel/SynologyAccount.py b/synology_api/DSM/ControlPanel/SynologyAccount.py new file mode 100644 index 00000000..23a16f7f --- /dev/null +++ b/synology_api/DSM/ControlPanel/SynologyAccount.py @@ -0,0 +1,11 @@ +""" +Synology Account API endpoint. +""" +from synology_api import base_api + + +class SynologyAccount(base_api.BaseApi): + """ + Synology Account API endpoint. + """ + pass diff --git a/synology_api/DSM/ControlPanel/TaskScheduler.py b/synology_api/DSM/ControlPanel/TaskScheduler.py new file mode 100644 index 00000000..62098203 --- /dev/null +++ b/synology_api/DSM/ControlPanel/TaskScheduler.py @@ -0,0 +1,11 @@ +""" +Task Scheduler API endpoint. +""" +from synology_api import base_api + + +class TaskScheduler(base_api.BaseApi): + """ + Task Scheduler API endpoint. + """ + pass diff --git a/synology_api/DSM/ControlPanel/TerminalSNMP.py b/synology_api/DSM/ControlPanel/TerminalSNMP.py new file mode 100644 index 00000000..f4483900 --- /dev/null +++ b/synology_api/DSM/ControlPanel/TerminalSNMP.py @@ -0,0 +1,11 @@ +""" +Terminal SNMP class for Synology DSM. +""" +from synology_api import base_api + + +class TerminalSNMP(base_api.BaseApi): + """ + Terminal SNMP class for Synology DSM. + """ + pass diff --git a/synology_api/DSM/ControlPanel/UpdateRestore.py b/synology_api/DSM/ControlPanel/UpdateRestore.py new file mode 100644 index 00000000..ac2d618d --- /dev/null +++ b/synology_api/DSM/ControlPanel/UpdateRestore.py @@ -0,0 +1,11 @@ +""" +Update and restore class for Synology DSM. +""" +from synology_api import base_api + + +class UpdateRestore(base_api.BaseApi): + """ + Update and restore class for Synology DSM. + """ + pass diff --git a/synology_api/DSM/ControlPanel/UserGroup.py b/synology_api/DSM/ControlPanel/UserGroup.py new file mode 100644 index 00000000..67903d0f --- /dev/null +++ b/synology_api/DSM/ControlPanel/UserGroup.py @@ -0,0 +1,11 @@ +""" +User Group API endpoint. +""" +from synology_api import base_api + + +class UserGroup(base_api.BaseApi): + """ + User Group API endpoint. + """ + pass diff --git a/synology_api/DSM/ControlPanel/__init__.py b/synology_api/DSM/ControlPanel/__init__.py new file mode 100644 index 00000000..32bc6060 --- /dev/null +++ b/synology_api/DSM/ControlPanel/__init__.py @@ -0,0 +1,375 @@ +""" +ControlPanel submodule for Synology DSM API. Provides access to all DSM Control Panel APIs. +""" + +from .ApplicationPrivileges import ApplicationPrivileges +from .DomainLDAP import DomainLDAP +from .ExternalAccess import ExternalAccess +from .ExternalDevices import ExternalDevices +from .FileServices import FileServices +from .HardwarePower import HardwarePower +from .IndexingService import IndexingService +from .InfoCenter import InfoCenter +from .LoginPortal import LoginPortal +from .Network import Network +from .Notifications import Notifications +from .RegionalOptions import RegionalOptions +from .Security import Security +from .SharedFolder import SharedFolder +from .SynologyAccount import SynologyAccount +from .TaskScheduler import TaskScheduler +from .Security import Security +from .TerminalSNMP import TerminalSNMP +from .UpdateRestore import UpdateRestore +from .UserGroup import UserGroup + +from synology_api import base_api + + +class ControlPanel(base_api.BaseApi): + """ + ControlPanel submodule for Synology DSM API. Provides access to all DSM Control Panel APIs. + """ + _app_priv = None + _domain_ldap = None + _ext_access = None + _ext_devices = None + _file_services = None + _hard_power = None + _idx_service = None + _info_center = None + _log_portal = None + _network = None + _notification = None + _region_opt = None + _security = None + _shared_folder = None + _syno_account = None + _task_scheduler = None + _terminal_snmp = None + _update_restore = None + _user_group = None + + @property + def ApplicationPrivileges(self): + """ + ControlPanel: ApplicationPrivileges. + + Returns + ------- + ApplicationPrivileges + Instance of the ApplicationPrivileges API, sharing the same state as DSM. + """ + if self._app_priv is None: + # Create ApplicationPrivileges instance without calling __init__ + self._app_priv = ApplicationPrivileges.__new__( + ApplicationPrivileges) + # Share the state + self._app_priv.__dict__ = self.__dict__ + return self._app_priv + + @property + def DomainLDAP(self): + """ + ControlPanel: DomainLDAP. + + Returns + ------- + DomainLDAP + Instance of the DomainLDAP API, sharing the same state as DSM. + """ + if self._domain_ldap is None: + # Create DomainLDAP instance without calling __init__ + self._domain_ldap = DomainLDAP.__new__(DomainLDAP) + # Share the state + self._domain_ldap.__dict__ = self.__dict__ + return self._domain_ldap + + @property + def ExternalAccess(self): + """ + ControlPanel: ExternalAccess. + + Returns + ------- + ExternalAccess + Instance of the ExternalAccess API, sharing the same state as DSM. + """ + if self._ext_access is None: + # Create ExternalAccess instance without calling __init__ + self._ext_access = ExternalAccess.__new__(ExternalAccess) + # Share the state + self._ext_access.__dict__ = self.__dict__ + return self._ext_access + + @property + def ExternalDevices(self): + """ + ControlPanel: ExternalDevices. + + Returns + ------- + ExternalDevices + Instance of the ExternalDevices API, sharing the same state as DSM. + """ + if self._ext_devices is None: + # Create ExternalDevices instance without calling __init__ + self._ext_devices = ExternalDevices.__new__(ExternalDevices) + # Share the state + self._ext_devices.__dict__ = self.__dict__ + return self._ext_devices + + @property + def FileServices(self): + """ + ControlPanel: FileServices. + + Returns + ------- + FileServices + Instance of the FileServices API, sharing the same state as DSM. + """ + if self._file_services is None: + # Create FileServices instance without calling __init__ + self._file_services = FileServices.__new__(FileServices) + # Share the state + self._file_services.__dict__ = self.__dict__ + return self._file_services + + @property + def HardwarePower(self): + """ + ControlPanel: HardwarePower. + + Returns + ------- + HardwarePower + Instance of the HardwarePower API, sharing the same state as DSM. + """ + if self._hard_power is None: + # Create HardwarePower instance without calling __init__ + self._hard_power = HardwarePower.__new__(HardwarePower) + # Share the state + self._hard_power.__dict__ = self.__dict__ + return self._hard_power + + @property + def IndexingService(self): + """ + ControlPanel: IndexingService. + + Returns + ------- + IndexingService + Instance of the IndexingService API, sharing the same state as DSM. + """ + if self._idx_service is None: + # Create IndexingService instance without calling __init__ + self._idx_service = IndexingService.__new__(IndexingService) + # Share the state + self._idx_service.__dict__ = self.__dict__ + return self._idx_service + + @property + def InfoCenter(self): + """ + ControlPanel: InfoCenter. + + Returns + ------- + InfoCenter + Instance of the InfoCenter API, sharing the same state as DSM. + """ + if self._info_center is None: + # Create InfoCenter instance without calling __init__ + self._info_center = InfoCenter.__new__(InfoCenter) + # Share the state + self._info_center.__dict__ = self.__dict__ + return self._info_center + + @property + def LoginPortal(self): + """ + ControlPanel: LoginPortal. + + Returns + ------- + LoginPortal + Instance of the LoginPortal API, sharing the same state as DSM. + """ + if self._log_portal is None: + # Create LoginPortal instance without calling __init__ + self._log_portal = LoginPortal.__new__(LoginPortal) + # Share the state + self._log_portal.__dict__ = self.__dict__ + return self._log_portal + + @property + def Network(self): + """ + ControlPanel: Network. + + Returns + ------- + Network + Instance of the Network API, sharing the same state as DSM. + """ + if self._network is None: + # Create Network instance without calling __init__ + self._network = Network.__new__(Network) + # Share the state + self._network.__dict__ = self.__dict__ + return self._network + + @property + def Notifications(self): + """ + ControlPanel: Notifications. + + Returns + ------- + Notifications + Instance of the Notifications API, sharing the same state as DSM. + """ + if self._notification is None: + # Create Notifications instance without calling __init__ + self._notification = Notifications.__new__(Notifications) + # Share the state + self._notification.__dict__ = self.__dict__ + return self._notification + + @property + def RegionalOptions(self): + """ + ControlPanel: RegionalOptions. + + Returns + ------- + RegionalOptions + Instance of the RegionalOptions API, sharing the same state as DSM. + """ + if self._region_opt is None: + # Create RegionalOptions instance without calling __init__ + self._region_opt = RegionalOptions.__new__(RegionalOptions) + # Share the state + self._region_opt.__dict__ = self.__dict__ + return self._region_opt + + @property + def Security(self): + """ + ControlPanel: Security. + + Returns + ------- + Security + Instance of the Security API, sharing the same state as DSM. + """ + if self._security is None: + # Create Security instance without calling __init__ + self._security = Security.__new__(Security) + # Share the state + self._security.__dict__ = self.__dict__ + return self._security + + @property + def SharedFolder(self): + """ + ControlPanel: SharedFolder. + + Returns + ------- + SharedFolder + Instance of the SharedFolder API, sharing the same state as DSM. + """ + if self._shared_folder is None: + # Create SharedFolder instance without calling __init__ + self._shared_folder = SharedFolder.__new__(SharedFolder) + # Share the state + self._shared_folder.__dict__ = self.__dict__ + return self._shared_folder + + @property + def SynologyAccount(self): + """ + ControlPanel: SynologyAccount. + + Returns + ------- + SynologyAccount + Instance of the SynologyAccount API, sharing the same state as DSM. + """ + if self._syno_account is None: + # Create ApplicationPrivileges instance without calling __init__ + self._syno_account = SynologyAccount.__new__(SynologyAccount) + # Share the state + self._syno_account.__dict__ = self.__dict__ + return self._syno_account + + @property + def TaskScheduler(self): + """ + ControlPanel: TaskScheduler. + + Returns + ------- + TaskScheduler + Instance of the TaskScheduler API, sharing the same state as DSM. + """ + if self._task_scheduler is None: + # Create TaskScheduler instance without calling __init__ + self._task_scheduler = TaskScheduler.__new__(TaskScheduler) + # Share the state + self._task_scheduler.__dict__ = self.__dict__ + return self._task_scheduler + + @property + def TerminalSNMP(self): + """ + ControlPanel: TerminalSNMP. + + Returns + ------- + TerminalSNMP + Instance of the TerminalSNMP API, sharing the same state as DSM. + """ + if self._terminal_snmp is None: + # Create TerminalSNMP instance without calling __init__ + self._terminal_snmp = TerminalSNMP.__new__(TerminalSNMP) + # Share the state + self._terminal_snmp.__dict__ = self.__dict__ + return self._terminal_snmp + + @property + def UpdateRestore(self): + """ + ControlPanel: UpdateRestore. + + Returns + ------- + UpdateRestore + Instance of the UpdateRestore API, sharing the same state as DSM. + """ + if self._update_restore is None: + # Create UpdateRestore instance without calling __init__ + self._update_restore = UpdateRestore.__new__(UpdateRestore) + # Share the state + self._update_restore.__dict__ = self.__dict__ + return self._update_restore + + @property + def UserGroup(self): + """ + ControlPanel: UserGroup. + + Returns + ------- + UserGroup + Instance of the UserGroup API, sharing the same state as DSM. + """ + if self._user_group is None: + # Create UserGroup instance without calling __init__ + self._user_group = UserGroup.__new__(UserGroup) + # Share the state + self._user_group.__dict__ = self.__dict__ + return self._user_group diff --git a/synology_api/DSM/Package/FileStation.py b/synology_api/DSM/Package/FileStation.py new file mode 100644 index 00000000..1d3655ca --- /dev/null +++ b/synology_api/DSM/Package/FileStation.py @@ -0,0 +1,2605 @@ +""" +Implementation of FileStation API based on the Synology API documentation. +""" + +from __future__ import annotations +from typing import Optional, Any +from datetime import datetime +import requests +import tqdm +import time +import io +import json +import os +import sys +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor +from urllib import parse +from treelib import Tree +import warnings +from synology_api import base_api + + +class FileStation(base_api.BaseApi): + """ + Implementation of FileStation API based on the Synology API documentation. See: https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf . + """ + + def get_info(self) -> dict[str, object]: + """ + Get info about FileStation. + + Returns + ------- + dict of str to object + List of FileStation info. + + Examples + -------- + ```json + { + "data": { + "allow_normal_disable_html": true, + "enable_list_usergrp": false, + "enable_send_email_attachment": true, + "enable_view_google": true, + "enable_view_microsoft": true, + "hostname": "SYNO-FLORENTB", + "is_manager": true, + "items": [ + { + "gid": 100 + }, + { + "gid": 101 + }, + { + "gid": 1023 + } + ], + "support_file_request": true, + "support_sharing": true, + "support_vfs": true, + "support_virtual": { + "enable_iso_mount": true, + "enable_remote_mount": true + }, + "support_virtual_protocol": [ + "cifs", + "nfs", + "iso" + ], + "system_codepage": "fre", + "uid": 1027 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Info' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = {'version': info['maxVersion'], 'method': 'get'} + + return self.request_data(api_name, api_path, req_param) + + def get_list_share(self, + additional: Optional[list[str]] = None, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort_by: Optional[str] = None, + sort_direction: Optional[str] = None, + onlywritable: bool = False + ) -> dict[str, object]: + """ + Get list of shared folders. + + Parameters + ---------- + additional : Optional[list[str]], optional + Additionnal field to retrieve from shared folder. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","mount_point_type","sync_share","volume_status","indexed","hybrid_share","worm_share"]`. + offset : Optional[int], optional + Offset in the shared folder list. Defaults to `None` + limit : Optional[int], optional + Limit the len of the returned list. Defaults to `None` + sort_by : Optional[str], optional + Specify which file information to sort on. Defaults to `None` + All fields know are: `["name","user","group","mtime","atime","ctime","crtime","posix"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `None` + All possible direction are: `["asc","desc"]` + onlywritable : bool, optional + Force list of shared folder where the user as write access. Defaults to `False` + + Returns + ------- + dict[str, object] + List of shared folder in FileStation. + + Examples + -------- + ```json + { + "data": { + "offset": 0, + "shares": [ + { + "isdir": true, + "name": "docker", + "path": "/docker" + }, + { + "isdir": true, + "name": "Documents", + "path": "/Documents" + } + ], + "total": 2 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.List' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list_share', + 'onlywritable': onlywritable, + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'additional': json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def get_file_list(self, + folder_path: str, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort_by: Optional[str] = None, + sort_direction: Optional[str] = None, + pattern: Optional[list[str]] = None, + filetype: Optional[str] = None, + goto_path: Optional[str] = None, + additional: Optional[list[str]] = None, + check_dir: Optional[bool] = None + ) -> dict[str, object]: + """ + Get list of files in a folder. + + Parameters + ---------- + folder_path : str + A listed folder path starting with a shared folder. + offset : Optional[int], optional + Specify how many files are skipped before beginning to return listed files. Defaults to `None` + limit : Optional[int], optional + Number of files requested. 0 indicates to list all files with a given folder. Defaults to `None` + sort_by : Optional[str], optional + Specify which file information to sort on. Defaults to `None` + All fields known are: `["name","size","user","group","mtime","atime","ctime","crtime","posix","type"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `None` + All possible direction are: `["asc","desc"]` + pattern : Optional[list[str]], optional + Given glob pattern(s) to find files whose names and extensions match a case insensitive glob pattern. Defaults to `None` + Note: 1. If the pattern doesn't contain any glob syntax (? and *), * of glob syntax will be added at begin and end of the string automatically for partially matching the pattern. + filetype : Optional[str], optional + "file": only enumerate regular files; "dir": only enumerate folders; "all" enumerate regular files and folders. Defaults to `None` + All fields know are: `["file","dir","all"]` + goto_path : Optional[str], optional + Folder path starting with a shared folder. Return all files and sub-folders within folder_path path until goto_path path recursively. Defaults to `None` + Note: goto_path is only valid with parameter "additional" contains real_path. + additional : Optional[list[str]], optional + Additionnal field to retrieve from file. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","type","mount_point_type"]`. + check_dir : Optional[bool], optional + _description_. Defaults to `None` + + Returns + ------- + dict[str, object] + Information about the files in the folder. + + Examples + -------- + ```json + { + "data": { + "files": [ + { + "isdir": false, + "name": "compose.yaml", + "path": "/docker/compose.yaml" + } + ], + "offset": 0, + "total": 1 + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.List' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'action': 'list', + 'method': 'list', + 'folder_path': folder_path, + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'pattern': ', '.join(pattern) if isinstance(pattern, list) else pattern if isinstance(pattern, str) else None, + 'filetype': filetype, + 'goto_path': goto_path, + 'additional': json.dumps(additional), + 'check_dir': check_dir + } + + return self.request_data(api_name, api_path, req_param) + + def get_file_info(self, path: list[str], additional: Optional[list[str]] = None) -> dict[str, object]: + """ + Get information of file(s) / folder(s). + + Parameters + ---------- + path : list[str] + One or more folder/file path(s) starting with a shared folder + additional : Optional[list[str]], optional + Additionnal field to retrieve from file. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","type","mount_point_type"]`. + + Returns + ------- + dict[str, object] + Information of file(s) / folder(s). + + Examples + -------- + ```json + { + "data": { + "files": [ + { + "isdir": true, + "name": "Films", + "path": "/Films" + }, + { + "isdir": true, + "name": "Documents", + "path": "/Documents" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.List' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'getinfo', + 'path': json.dumps(path), + 'additional': json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def search_start(self, + folder_path: str = None, recursive: Optional[bool] = None, pattern: Optional[list[str]] = None, + extension: Optional[list[str]] = None, filetype: Optional[str] = None, size_from: Optional[int] = None, + size_to: Optional[int] = None, mtime_from: Optional[int] = None, mtime_to: Optional[int] = None, + crtime_from: Optional[int] = None, crtime_to: Optional[int] = None, atime_from: Optional[int] = None, + atime_to: Optional[int] = None, owner: Optional[str] = None, group: Optional[str] = None + ) -> dict[str, object]: + """ + Start to search files according to given criteria. If more than one criterion is given in different parameters, searched files match all these criteria. + + Parameters + ---------- + folder_path : str, optional + A searched folder path starting with a shared folder. One or more folder paths to be searched, separated by commas "," and around brackets. Defaults to `None` + recursive : Optional[bool], optional + If searching files within a folder and subfolders recursively or not. Defaults to `None` + pattern : Optional[list[str]], optional + Given glob pattern(s) to find files whose names and extensions match a case insensitive glob pattern. Defaults to `None` + Note: 1. If the pattern doesn't contain any glob syntax (? and *), * of glob syntax will be added at begin and end of the string automatically for partially matching the pattern.. Defaults to `None` + extension : Optional[list[str]], optional + Search for files whose extensions match a file type pattern in a case-insensitive glob pattern. If you give this criterion, folders aren't matched. Defaults to `None` + filetype : Optional[str], optional + "file": only enumerate regular files; "dir": only enumerate folders; "all" enumerate regular files and folders. Defaults to `None` + All fields know are: `["file","dir","all"]` + size_from : Optional[int], optional + Search for files whose sizes are greater than the given byte size. Defaults to `None` + size_to : Optional[int], optional + Search for files whose sizes are less than the given byte size. Defaults to `None` + mtime_from : Optional[int], optional + Search for files whose last modified time after the given Linux timestamp (UTC) in second. Defaults to `None` + mtime_to : Optional[int], optional + Search for files whose last modified time before the given Linux timestamp (UTC) in second. Defaults to `None` + crtime_from : Optional[int], optional + Search for files whose create time after the given Linux timestamp (UTC) in second. Defaults to `None` + crtime_to : Optional[int], optional + Search for files whose create time before the given Linux timestamp (UTC) in second. Defaults to `None` + atime_from : Optional[int], optional + Search for files whose last access time after the given Linux timestamp (UTC) in second. Defaults to `None` + atime_to : Optional[int], optional + Search for files whose last access time before the given Linux timestamp (UTC) in second. Defaults to `None` + owner : Optional[str], optional + Search for files whose user name matches this criterion. This criterion is case-insensitive. Defaults to `None` + group : Optional[str], optional + Search for files whose group name matches this criterion. This criterion is case-insensitive. Defaults to `None` + + Returns + ------- + dict[str, object] + A unique ID for the search task. + + Examples + -------- + ```json + { + "data": { + "has_not_index_share": true, + "taskid": "51CE617CF57B24E5" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Search' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'folder_path': folder_path, + 'recursive': recursive, + 'pattern': ', '.join(pattern) if isinstance(pattern, list) else pattern if isinstance(pattern, str) else None, + 'extension': ', '.join(extension) if isinstance(extension, list) else extension if isinstance(extension, str) else None, + 'filetype': filetype, + 'size_from': size_from, + 'size_to': size_to, + 'mtime_from': mtime_from, + 'mtime_to': mtime_to, + 'crtime_from': crtime_from, + 'crtime_to': crtime_to, + 'atime_from': atime_from, + 'atime_to': atime_to, + 'owner': owner, + 'group': group + } + + return self.request_data(api_name, api_path, req_param) + + def get_search_list(self, + taskid: str, + offset: Optional[int] = None, + limit: Optional[int] = None, + sort_by: Optional[str] = None, + sort_direction: Optional[str] = None, + pattern: Optional[list[str]] = None, + filetype: Optional[str] = None, + additional: Optional[list[str]] = None + ) -> dict[str, object]: + """ + List matched files in a search temporary database. You can check the finished value in response to know if the search operation is processing or has been finished. + + Parameters + ---------- + taskid : str + A unique ID for the search task which is obtained from `search_start` method. + offset : Optional[int], optional + Specify how many files are skipped before beginning to return listed files. Defaults to `None` + limit : Optional[int], optional + Number of files requested. 0 indicates to list all files with a given folder. Defaults to `None` + sort_by : Optional[str], optional + Specify which file information to sort on. Defaults to `None` + All fields known are: `["name","size","user","group","mtime","atime","ctime","crtime","posix","type"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `None` + All possible direction are: `["asc","desc"]` + pattern : Optional[list[str]], optional + Given glob pattern(s) to find files whose names and extensions match a case insensitive glob pattern. Defaults to `None` + Note: 1. If the pattern doesn't contain any glob syntax (? and *), * of glob syntax will be added at begin and end of the string automatically for partially matching the pattern. + filetype : Optional[str], optional + "file": only enumerate regular files; "dir": only enumerate folders; "all" enumerate regular files and folders. Defaults to `None` + All fields know are: `["file","dir","all"]` + additional : Optional[list[str]], optional + Additionnal field to retrieve from file. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","type"]`. + + Returns + ------- + dict[str, object] + Infos about the search and the matched files. + + Examples + -------- + ```json + { + "data": { + "files": [ + { + "isdir": false, + "name": "compose.yaml", + "path": "/docker/compose.yaml" + } + ], + "finished": true, + "offset": 0, + "total": 1 + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Search' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'taskid': taskid, + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'pattern': ', '.join(pattern) if isinstance(pattern, list) else pattern if isinstance(pattern, str) else None, + 'filetype': filetype, + 'additional': json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def stop_search_task(self, taskid: str | list[str]) -> dict[str, object]: + """ + Stop the searching task(s). The search temporary database won't be deleted, so it's possible to list the search result using list method after stopping it. + + Parameters + ---------- + taskid : str | list[str] + Unique ID(s) for the search task which are obtained from `search_start` method. Specify multiple search task IDs by using list type. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Search' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': json.dumps(taskid) if isinstance(taskid, list) else taskid, + } + + return self.request_data(api_name, api_path, req_param) + + def clean_search_task(self, taskid: str | list[str]) -> dict[str, object]: + """ + Delete search temporary database(s). + + Parameters + ---------- + taskid : str | list[str] + Unique ID(s) for the search task which are obtained from `search_start` method. Specify multiple search task IDs by using list type. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Search' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'clean', + 'taskid': json.dumps(taskid) if isinstance(taskid, list) else taskid, + } + + return self.request_data(api_name, api_path, req_param) + + def get_mount_point_list(self, mount_type: str, offset: Optional[int] = None, limit: Optional[int] = None, + sort_by: Optional[str] = None, sort_direction: Optional[str] = None, additional: Optional[list[str]] = None + ) -> dict[str, object]: + """ + List all mount point folders on one given type of virtual file system. + + Parameters + ---------- + mount_type : str + A type of virtual file systems. + All fields known are: `["cifs","nfs","iso"]` + offset : Optional[int], optional + Specify how many mount point folders are skipped before beginning to return listed files. Defaults to `None` + limit : Optional[int], optional + Number of mount point folders requested. 0 indicates to list all files with a given folder. Defaults to `None` + sort_by : Optional[str], optional + Specify which file information to sort on. Defaults to `None` + All fields known are: `["name",,"user","group","mtime","atime","ctime","crtime","posix"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `None` + All possible direction are: `["asc","desc"]` + additional : Optional[list[str]], optional + Additionnal field to retrieve from file. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","volume_status"]`. + + Returns + ------- + dict[str, object] + List of mount point folders. + + Examples + -------- + ```json + { + "data": { + "folders": [ + { + "additional": { + "mount_point_type": "remote", + "owner": { + "gid": 100, + "group": "users", + "uid": 1024, + "user": "admin" + }, + "perm": { + "acl": { + "append": true, + "del": true, + "exec": true, + "read": true, + "write": true + }, + "is_acl_mode": false, + "posix": 777 + }, + "real_path": "/volume1/vidoe/remote", + "time": { + "atime": 1372313445, + "crtime": 1320204670, + "ctime": 1371206944, + "mtime": 1371206944 + }, + "volume_status": { + "freespace": 12282422599680, + "readonly": false, + "totalspace": 801958928384 + } + }, + "isdir": true, + "name": "remote", + "path": "/video/remote" + } + ], + "offset": 0, + "total": 0 + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.VirtualFolder' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'type': mount_type, + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'additional': json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def get_favorite_list(self, + offset: Optional[int] = None, + limit: Optional[int] = None, + status_filter: Optional[str] = None, + additional: Optional[str | list[str]] = None + ) -> dict[str, object]: + """ + List user's favorites. + + Parameters + ---------- + offset : Optional[int], optional + Specify how many favorites are skipped before beginning to return user's favorites. Defaults to `None` + limit : Optional[int], optional + Number of favorites requested. 0 indicates to list all favorites. Defaults to `None` + status_filter : Optional[str], optional + Show favorites with a given favorite status. Defaults to `None` + All fields known are: `["valid","broken","all"]` + additional : Optional[str | list[str]], optional + Additionnal field to retrieve from file. Defaults to `None` + All fields known are: `["real_path","owner","time","perm","mount_point_type"]`. + + Returns + ------- + dict[str, object] + List of user's favorites. + + Examples + -------- + ```json + { + "data": { + "favorites": [ + { + "isdir": true, + "name": "My Video Shared folder", + "path": "/video", + "status": "valid" + }, + { + "isdir": false, + "name": "deletedfolder", + "path": "/share/deletedfolder", + "status": "broken" + } + ], + "offset": 0, + "total": 2 + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'offset': offset, + 'limit': limit, + 'status_filter': status_filter, + 'additional': json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def add_a_favorite(self, path: str, name: Optional[str] = None, index: Optional[int] = -1) -> dict[str, object]: + """ + Add a folder to user's favorites. + + Parameters + ---------- + path : str + A folder path starting with a shared folder is added to the user's favorites. + name : Optional[str], optional + A favorite name. Defaults to `None` + index : Optional[int], optional + Index of location of an added favorite. Defaults to `-1` + If it's equal to -1, the favorite will be added to the last one in user's favorite. + If it's between 0 ~ total number of favorites-1, the favorite will be inserted into user's favorites by the index. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'add', + 'path': path, + 'name': name, + 'index': index + } + + return self.request_data(api_name, api_path, req_param) + + def delete_a_favorite(self, path: str) -> dict[str, object]: + """ + Delete a favorite in user's favorites. + + Parameters + ---------- + path : str + A folder path starting with a shared folder is deleted from a user's favorites. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'path': path + } + + return self.request_data(api_name, api_path, req_param) + + def clear_broken_favorite(self) -> dict[str, object]: + """ + Delete all broken statuses of favorites. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'clear_broken' + } + + return self.request_data(api_name, api_path, req_param) + + def edit_favorite_name(self, path: str, new_name: str) -> dict[str, object]: + """ + Edit a favorite name. + + Parameters + ---------- + path : str + A folder path starting with a shared folder is edited from a user's favorites. + new_name : str + New favorite name. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'edit', + 'path': path, + 'new_name': new_name + } + + return self.request_data(api_name, api_path, req_param) + + def replace_all_favorite(self, path: str | list[str], name: str | list[str]) -> dict[str, object]: + """ + Replace multiple favorites of folders to the existing user's favorites. + + Parameters + ---------- + path : str | list[str] + One or more folder paths starting with a shared folder is added to the user's favorites. + The number of paths must be the same as the number of favorite names in the name parameter. + The first path parameter corresponds to the first name parameter. + name : str | list[str] + One or more new favorite names. The number of favorite names must be the same as the number of folder paths in the path parameter. + The first name parameter corresponding to the first path parameter. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Favorite' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'edit', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'name': json.dumps(name) if isinstance(name, list) else name + } + + return self.request_data(api_name, api_path, req_param) + + def get_thumbnail(self, path: str, size: Optional[str] = "small", rotate: Optional[int] = None) -> bytes: + """ + Get a thumbnail of a file. + + Parameters + ---------- + path : str + A file path starting with a shared folder. + size : str + The size of the thumbnail. Defaults to `small` + All fields known are: `["small","medium","large","original"]` + rotate : Optional[int], optional + The angle of the thumbnail. Defaults to `None` + All fields known are: `[0,1,2,3,4] = ["0°","90°","180°","270°","360°"]` + + Returns + ------- + bytes + The thumbnail of the file. If the file is not found, it will raise an exception. + """ + + api_name = 'SYNO.FileStation.Thumb' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': "get", + 'path': path, + 'size': size, + 'rotate': rotate + } + response = self.request_data( + api_name, api_path, req_param, response_json=False) + match response.status_code: + case 200: + return response.content + case 404: + raise Exception("File not found") + case _: + raise Exception(f"HTTP Status error : {response.status_code}") + + def start_dir_size_calc(self, path: str | list[str]) -> dict[str, object]: + """ + Start to calculate size for one or more file/folder paths. + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths starting with a shared folder for calculating cumulative size + + Returns + ------- + dict[str, object] + Task ID for the size calculation request. + + Examples + -------- + ```json + { + "data": { + "taskid": "51CBD7CD5C76E461" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.DirSize' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'path': json.dumps(path) if isinstance(path, list) else path + } + return self.request_data(api_name, api_path, req_param)['data']['taskid'] + + def get_dir_status(self, taskid: str) -> dict[str, object]: + """ + Get the status of the size calculating task. + + Parameters + ---------- + taskid : str + A unique ID for the task which is obtained from `start_dir_size_calc` method. + + Returns + ------- + dict[str, object] + Infos about the size calculating task. + + Examples + -------- + ```json + { + "data": { + "finished": true, + "num_dir": 3, + "num_file": 104, + "total_size": 29973265 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.DirSize' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + + return self.request_data(api_name, api_path, req_param) + + def stop_dir_size_calc(self, taskid: str) -> dict[str, object]: + """ + Stop the calculation. + + Parameters + ---------- + taskid : str + A unique ID for the task which is obtained from `start_dir_size_calc` method. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.DirSize' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def start_md5_calc(self, file_path: str) -> dict[str, object]: + """ + Start to get MD5 of a file. + + Parameters + ---------- + file_path : str + A file path starting with a shared folder for calculating MD5 value. + + Returns + ------- + dict[str, object] + Task ID for the size calculation request. + + Examples + -------- + ```json + { + "data": { + "taskid": "51CBD7CD5C76E461" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.MD5' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'file_path': file_path + } + return self.request_data(api_name, api_path, req_param) + + def get_md5_status(self, taskid: str) -> dict[str, object]: + """ + Get the status of the MD5 calculation task. + + Parameters + ---------- + taskid : str + A unique ID for the task which is obtained from `start_md5_status` method. + + Returns + ------- + dict[str, object] + Finished status of the MD5 calculation task and the md5 of requested file. + + Examples + -------- + ```json + { + "data": { + "finished": true, + "md5": "6336c5a59aa63dd2042783f88e15410a" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.MD5' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def stop_md5_calc(self, taskid: str) -> dict[str, object]: + """ + Stop calculating the MD5 of a file. + + Parameters + ---------- + taskid : str + A unique ID for the task which is obtained from `start_md5_status` method. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.DirSize' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def check_permissions(self, + path: str, + filename: str, + overwrite: Optional[bool] = False, + create_only: Optional[bool] = True + ) -> dict[str, object]: + """ + Check if a logged-in user has write permission to create new files/folders in a given folder. + + Parameters + ---------- + path : str + A folder path starting with a shared folder to check write permission + filename : str + A filename you want to write to given path + overwrite : Optional[bool], optional + The value could be one of following: Defaults to `False` + - "true": overwrite the destination file if one exists. + - "false": skip if the destination file exists. + + Note: when it's not specified as true or false, it will be responded with error when the destination file exists. + + create_only : Optional[bool], optional + If set to "true", the permission will be allowed when there is non-existent file/folder. Defaults to `True` + + Returns + ------- + dict[str, object] + The request will get error response if no write permission for the specified path. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.CheckPermission' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'write', + 'path': path, + 'filename': filename, + 'overwrite': overwrite, + 'create_only': create_only + } + return self.request_data(api_name, api_path, req_param) + + def upload_file(self, + dest_path: str, + file_path: str, + create_parents: bool = True, + overwrite: bool = True, + verify: bool = False, + progress_bar: bool = True + ) -> tuple[int, dict[str, object]]: + """ + Upload a file to a given destination path. + + Parameters + ---------- + dest_path : str + A destination folder path starting with a shared folder. + file_path : str + A file path to be uploaded. + create_parents : bool, optional + Create parent folder(s) if none exist. Defaults to `True` + overwrite : bool, optional + If `True` overwrite the destination file if one exist else skip the upload if the destination file exist. Defaults to `True` + verify : bool, optional + If `True` use HTTPS else use HTTP. Defaults to `False` + progress_bar : bool, optional + Enable or note the progress bar in the stdout. Defaults to `True` + + Returns + ------- + tuple[int, dict[str, object]] + If failed return a tuple with the status code and the error message + else return the response json. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Upload' + info = self.gen_list[api_name] + api_path = info['path'] + filename = os.path.basename(file_path) + + session = requests.session() + + with open(file_path, 'rb') as payload: + url = ('%s%s' % (self.base_url, api_path)) + '?api=%s&version=%s&method=upload&_sid=%s' % ( + api_name, info['minVersion'], self._sid) + + encoder = MultipartEncoder({ + 'path': dest_path, + 'create_parents': str(create_parents).lower(), + 'overwrite': str(overwrite).lower(), + 'files': (filename, payload, 'application/octet-stream') + }) + + if progress_bar: + bar = tqdm.tqdm(desc='Upload Progress', + total=encoder.len, + dynamic_ncols=True, + unit='B', + unit_scale=True, + unit_divisor=1024 + ) + + monitor = MultipartEncoderMonitor( + encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) + + r = session.post( + url, + data=monitor, + verify=verify, + headers={"X-SYNO-TOKEN": self.session._syno_token, + 'Content-Type': monitor.content_type} + ) + + else: + r = session.post( + url, + data=encoder, + verify=verify, + headers={"X-SYNO-TOKEN": self.session._syno_token, + 'Content-Type': encoder.content_type} + ) + + session.close() + if r.status_code != 200 or not r.json()['success']: + return r.status_code, r.json() + + return r.json() + + def get_shared_link_info(self, link_id: str) -> dict[str, object]: + """ + Get information of a sharing link by the sharing link ID. + + Parameters + ---------- + link_id : str + A unique ID of a sharing link. + + Returns + ------- + dict[str, object] + Information about the sharing link. + + Examples + -------- + ```json + { + "data": { + "date_available": "0", + "date_expired": "0", + "has_password": false, + "id": "pHTBKQf9", + "isFolder": false, + "link_owner": "admin", + "name": "ITEMA_20448251-0.mp3", + "path": "/test/ITEMA_20448251-0.mp3", + "status": "valid", + "url": "http://myds.com:5000/fbsharing/pHTBKQf9" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'getinfo', + 'id': link_id + } + return self.request_data(api_name, api_path, req_param) + + def get_shared_link_list(self, offset: Optional[int] = None, limit: Optional[int] = None, sort_by: Optional[str] = None, + sort_direction: Optional[str] = None, force_clean: Optional[bool] = None + ) -> dict[str, object]: + """ + List user's file sharing links. + + Parameters + ---------- + offset : Optional[int], optional + Specify how many sharing links are skipped before beginning to return listed sharing links. Defaults to `None` + limit : Optional[int], optional + Number of sharing links requested. 0 means to list all sharing links. Defaults to `None` + sort_by : Optional[str], optional + Specify which file information to sort on. Defaults to `None` + All fields known are: `["name","isFolder","path","date_expired","date_available","status","has_password","id","url","link_owner"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `None` + All possible direction are: `["asc","desc"]` + force_clean : Optional[bool], optional + If set to false, the data will be retrieved from cache database rapidly. If set to true, all sharing information including sharing statuses and user name of sharing owner will be synchronized. It consumes some time. Defaults to `None` + + Returns + ------- + dict[str, object] + Information about the sharing links. + + Examples + -------- + ```json + { + "data": { + "links": [ + { + "date_available": "0", + "date_expired": "0", + "has_password": false, + "id": "pHTBKQf9", + "isFolder": false, + "link_owner": "admin", + "name": "ITEMA_20448251-0.mp3", + "path": "/test/ITEMA_20448251-0.mp3", + "status": "valid", + "url": "http://myds.com:5000/fbsharing/pHTBKQf9" + } + ], + "offset": 0, + "total": 1 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'force_clean': force_clean + } + return self.request_data(api_name, api_path, req_param) + + def create_sharing_link(self, path: str | list[str], password: Optional[str] = None, date_expired: Optional[str | int] = None, + date_available: Optional[str | int] = None + ) -> dict[str, object]: + """ + Generate one or more sharing link(s) by file/folder path(s). + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths with which to generate sharing links. + password : Optional[str], optional + The password for the sharing link when accessing it. The max password length are 16 characters. Defaults to `None` + date_expired : Optional[str | int], optional + The expiration date for the sharing link, written in the format YYYYMM-DD. When set to 0 (default), the sharing link is permanent. Defaults to `None` + + Note: SHOULD put the double quote outside expiration date and is based on user's DS date. + + date_available : Optional[str | int], optional + The available date for the sharing link to become effective, written in the format YYYY-MM-DD. When set to 0 (default), the sharing link is valid immediately after creation. Defaults to `None` + + Note: SHOULD put the double quote outside available date and is based on user's DS date. + + Returns + ------- + dict[str, object] + Information about the sharing link(s) generated. + + Examples + -------- + ```json + { + "data": { + "links": [ + { + "error": 0, + "id": "y4LmvpaX", + "path": "/test/ITEMA_20445972-0.mp3", + "qrcode": "iVBORw0KGgoAAAANSUh...", + "url": "http://myds.com:5000/fbsharing/y4LmvpaX" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'create', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'password': password, + 'date_expired': date_expired, + 'date_available': date_available + } + + return self.request_data(api_name, api_path, req_param) + + def delete_shared_link(self, link_id: str | list[str]) -> dict[str, object]: + """ + Delete one or more sharing links. + + Parameters + ---------- + link_id : str | list[str] + Unique IDs of file sharing link(s) to be deleted + + Returns + ------- + dict[str, object] + Returns an empty success response if completed without error; otherwise returns error object array contains failed IDs. + + Examples + -------- + ```json + {, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'id': json.dumps(link_id) if isinstance(link_id, list) else link_id + } + + return self.request_data(api_name, api_path, req_param) + + def clear_invalid_shared_link(self) -> dict[str, object]: + """ + Remove all expired and broken sharing links. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'clear_invalid' + } + + return self.request_data(api_name, api_path, req_param) + + def edit_shared_link(self, link_id: str | list[str], password: Optional[str] = None, date_expired: Optional[str | int] = None, + date_available: Optional[str | int] = None + ) -> dict[str, object]: + """ + Edit sharing link(s). + + Parameters + ---------- + link_id : str | list[str] + Unique ID(s) of sharing link(s) to edit. + password : Optional[str], optional + The password for the sharing link when accessing it. The max password length are 16 characters. Defaults to `None` + date_expired : Optional[str | int], optional + The expiration date for the sharing link, written in the format YYYYMM-DD. When set to 0 (default), the sharing link is permanent. Defaults to `None` + + Note: SHOULD put the double quote outside expiration date and is based on user's DS date. + + date_available : Optional[str | int], optional + The available date for the sharing link to become effective, written in the format YYYY-MM-DD. When set to 0 (default), the sharing link is valid immediately after creation. Defaults to `None` + + Note: SHOULD put the double quote outside available date and is based on user's DS date. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Sharing' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'edit', + 'id': json.dumps(link_id) if isinstance(link_id, list) else link_id, + 'password': password, + 'date_expired': date_expired, + 'date_available': date_available + } + return self.request_data(api_name, api_path, req_param) + + def create_folder(self, folder_path: str | list[str], name: str | list[str], + force_parent: Optional[bool] = False, additional: Optional[str | list[str]] = None + ) -> dict[str, object]: + """ + Create folders. + + Parameters + ---------- + folder_path : str | list[str] + One or more shared folder paths, separated by commas and around brackets. + If `force_parent` is `true`, and `folder_path` does not exist, the `folder_path` will be created. + If `force_parent` is `false`, `folder_path` must exist or a false value will be returned. + The number of paths must be the same as the number of names in the name parameter. + The first `folder_path` parameter corresponds to the first name parameter. + name : str | list[str] + One or more new folder names. + The number of names must be the same as the number of folder_paths paths in the `folder_path` parameter. + The first `name` parameter corresponding to the first `folder_path` parameter. + force_parent : Optional[bool], optional + Defaults to `False`. + If `true` : no error occurs if a folder exists and create parent folders as needed. + If `false` : parent folders are not created. + additional : Optional[str | list[str]], optional + Additionnal field to retrieve from folder. Defaults to `None` + All fields known are: `["real_path","size","owner","time","perm","type"]`. + + Returns + ------- + dict[str, object] + List of folder(s) created informations. + + Examples + -------- + ```json + { + "data": { + "folders": [ + { + "isdir": true, + "name": "test", + "path": "/video/test" + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.CreateFolder' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'create', + 'folder_path': json.dumps(folder_path) if isinstance(folder_path, list) else folder_path, + 'name': json.dumps(name) if isinstance(name, list) else name, + 'force_parent': force_parent + } + return self.request_data(api_name, api_path, req_param) + + def rename_folder(self, path: str | list[str], name: str | list[str], additional: Optional[str | list[str]] = None, search_taskid: Optional[str] = None) -> dict[str, object]: + """ + Rename folders. + + Parameters + ---------- + path : str | list[str] + One or more paths of files/folders to be renamed. + The number of paths must be the same as the number of names in the `name` parameter. + The first `path` parameter corresponds to the first `name` parameter. + name : str | list[str] + One or more new folder names. + The number of names must be the same as the number of paths paths in the `path` parameter. + The first `name` parameter corresponding to the first `path` parameter. + additional : Optional[str | list[str]], optional + Defaults to `None` + Additionnal field to retrieve from folder. + All fields known are: `["real_path","size","owner","time","perm","type"]`. + search_taskid : Optional[str], optional + The task ID of the `search_start` method. Defaults to `None` + + Returns + ------- + dict[str, object] + List of folder(s) renamed informations. + + Examples + -------- + ```json + { + "data": { + "files": [ + { + "isdir": true, + "name": "test", + "path": "/video/test" + } + ] + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.Rename' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'rename', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'name': json.dumps(name) if isinstance(name, list) else name, + 'search_taskid': search_taskid + } + return self.request_data(api_name, api_path, req_param) + + def start_copy_move(self, + path: str | list[str], + dest_folder_path: str, + overwrite: Optional[bool] = None, + remove_src: Optional[bool] = False, + accurate_progress: Optional[bool] = True, + search_taskid: Optional[str] = None + ) -> dict[str, object]: + """ + Start to copy/move files. + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths starting with a shared folder to copy/move. + dest_folder_path : str + A destination folder path where files/folders are copied/moved. + overwrite : Optional[bool], optional + Defaults to `None`. + If `true` : overwrite all existing files with the same name. + If `false` : skip all existing files with the same name. + + Note: do not overwrite or skip existed files. If there is any existing files, an error occurs (error code: 1003). + + remove_src : Optional[bool], optional + Defaults to `False`. + If `true`: move files/folders. If `false`: copy files/folders. + accurate_progress : Optional[bool], optional + Defaults to `True`. + If `true` : calculate the progress by each moved/copied file within sub-folder. + If `false` : calculate the progress by files which you give in path parameters. This calculates the progress faster, but is less precise. + search_taskid : Optional[str], optional + The task ID of the `search_start` method. Defaults to `None`. + + Returns + ------- + dict[str, object] + Return unique task ID for the copy/move task. + + Examples + -------- + ```json + { + "data": { + "taskid": "FileStation_51D00B7912CDE0B0" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.FileStation.CopyMove' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'dest_folder_path': dest_folder_path, + 'overwrite': overwrite, + 'remove_src': remove_src, + 'accurate_progress': accurate_progress, + 'search_taskid': search_taskid + } + + return self.request_data(api_name, api_path, req_param) + + def get_copy_move_status(self, taskid: str) -> dict[str, object]: + """ + Get the copying/moving status. + + Parameters + ---------- + taskid : str + A unique ID for the copy/move task which is obtained from `start_copy_move` method + + Returns + ------- + dict[str, object] + Infos about the copy/move task. + + Examples + -------- + ```json + { + "data": { + "dest_folder_path": "/video/test", + "finished": false, + "path": "/video/test.avi", + "processed_size": 1057, + "progress": 0.01812258921563625, + "total": 58325 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.CopyMove' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def stop_copy_move_task(self, taskid: str) -> dict[str, object]: + """ + Stop a copy/move task. + + Parameters + ---------- + taskid : str + A unique ID for the copy/move task which is obtained from `start_copy_move` method + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.CopyMove' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def start_delete_task(self, + path: str | list[str], + accurate_progress: Optional[bool] = True, + recursive: Optional[bool] = True, + search_taskid: Optional[str] = None + ) -> dict[str, object]: + """ + Delete file(s)/folder(s). This is a non-blocking method. You should poll a request with `get_delete_status` method to get the task status or stop the task with `stop_delete_task` method. + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths starting with a shared folder to delete. + accurate_progress : Optional[bool], optional + Defaults to `True` + If `true` : calculates the progress of each deleted file with the sub-folder recursively. + If `false` : calculates the progress of files which you give in `path` parameters. The latter is faster than recursively, but less precise. + Note: Only non-blocking methods suits using the `get_delete_status` method to get progress. + recursive : Optional[bool], optional + Defaults to `True`. + If `true` : delete files/folders recursively. + If `false` : Only delete first-level file/folder. If a deleted folder contains any file, an error occurs because the folder can't be directly deleted. + search_taskid : Optional[str], optional + A unique ID for the search task which is obtained from `search_start` method. It's used to delete the file in the search result. Defaults to `None` + + Returns + ------- + dict[str, object] + A unique task ID for the delete task. + + Examples + -------- + ```json + { + "data": { + "taskid": "FileStation_51CEC9C979340E5A" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Delete' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'accurate_progress': accurate_progress, + 'recursive': recursive, + 'search_taskid': search_taskid + } + return self.request_data(api_name, api_path, req_param) + + def get_delete_status(self, taskid: str) -> dict[str, object]: + """ + Get the deleting status. + + Parameters + ---------- + taskid : str + A unique ID for the delete task which is obtained from `start_delete_task` method. + + Returns + ------- + dict[str, object] + Infos about the delete task. + + Examples + -------- + ```json + { + "data": { + "finished": false, + "path": "/video/1000", + "processed_num": 193, + "processing_path": "/video/1000/509", + "progress": 0.03199071809649467, + "total": 6033 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Delete' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def stop_delete_task(self, taskid: str) -> dict[str, object]: + """ + Stop a delete task. + + Parameters + ---------- + taskid : str + A unique ID for the delete task which is obtained from `start_delete_task` method. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Delete' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def delete_delete_task(self, path: str | list[str], recursive: Optional[bool] = True, search_taskid: Optional[str] = None) -> dict[str, object]: + """ + Delete files/folders. This is a blocking method. The response is not returned until the deletion operation is completed. + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths starting with a shared folder to delete. + recursive : Optional[bool], optional + Defaults to `True`. + If `true` : Recursively delete files within a folder. + If `false` : Only delete first-level file/folder. If a deleted folder contains any file, an error occurs because the folder can't be directly deleted. + search_taskid : Optional[str], optional + A unique ID for the search task which is obtained from `search_start` method. It's used to delete the file in the search result. Defaults to `None` + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Delete' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'delete', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'recursive': recursive, + 'search_taskid': search_taskid + } + return self.request_data(api_name, api_path, req_param) + + def start_extract_task(self, file_path: str, dest_folder_path: str, overwrite: Optional[bool] = False, + keep_dir: Optional[bool] = True, create_subfolder: Optional[bool] = False, codepage: Optional[str] = None, + password: Optional[str] = None, item_id: Optional[str | list[str]] = None + ) -> dict[str, object]: + """ + Start to extract an archive. This is a non-blocking method. You should poll a request with `get_extract_status` method to get the task status or stop the task with `stop_extract_task` method. + + Parameters + ---------- + file_path : str + A file path of an archive to be extracted, starting with a shared folder + dest_folder_path : str + A destination folder path starting with a shared folder to which the archive will be extracted. + overwrite : Optional[bool], optional + Whether or not to overwrite if the extracted file exists in the destination folder. Defaults to `False` + keep_dir : Optional[bool], optional + Whether to keep the folder structure within an archive. Defaults to `True` + create_subfolder : Optional[bool], optional + Whether to create a subfolder with an archive name which archived files are extracted to. Defaults to `False` + codepage : Optional[str], optional + The language codepage used for decoding file name with an archive. Defaults to `None` + All fields known are: `["enu","cht","chs","krn","ger","fre","ita","spn","jpn","dan","nor","sve","nld","rus","plk","ptb","ptg","hun","trk","csy"]` + password : Optional[str], optional + The password for extracting the file. Defaults to `None` + item_id : Optional[str | list[str]], optional + Item IDs of archived files used for extracting files within an archive. Item IDs could be listed by requesting the `get_file_list_of_archive` method. Defaults to `None` + + Returns + ------- + dict[str, object] + Unique task ID for the extract task. + + Examples + -------- + ```json + { + "data": { + "taskid": "FileStation_51CBB59C68EFE6A3" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Extract' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'file_path': file_path, + 'dest_folder_path': dest_folder_path, + 'overwrite': overwrite, + 'keep_dir': keep_dir, + 'create_subfolder': create_subfolder, + 'codepage': codepage, + 'password': password, + 'item_id': json.dumps(item_id) if isinstance(item_id, list) else item_id + } + return self.request_data(api_name, api_path, req_param)['data']['taskid'] + + def get_extract_status(self, taskid: str) -> dict[str, object]: + """ + Get the extract task status. + + Parameters + ---------- + taskid : str + A unique ID for the extract task which is obtained from `start_extract_task` method + + Returns + ------- + dict[str, object] + Information about the extract task. + + Examples + -------- + ```json + { + "data": { + "dest_folder_path": "/download/download", + "finished": false, + "progress": 0.1 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Extract' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def stop_extract_task(self, taskid: str) -> dict[str, object]: + """ + Stop the extract task. + + Parameters + ---------- + taskid : str + A unique ID for the extract task which is obtained from `start_extract_task` method + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Extract' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def get_file_list_of_archive(self, file_path: str, offset: Optional[int] = 0, limit: Optional[int] = -1, + sort_by: Optional[str] = 'name', sort_direction: Optional[str] = 'asc', codepage: Optional[str] = None, + password: Optional[str] = None, item_id: Optional[str] = None + ) -> dict[str, object]: + """ + List archived files contained in an archive. + + Parameters + ---------- + file_path : str + An archive file path starting with a shared folder to list. + offset : Optional[int], optional + Specify how many archived files are skipped before beginning to return listed archived files in an archive. Defaults to `0`. + limit : Optional[int], optional + Number of archived files requested. -1 indicates in an archive to list all archived files. Defaults to `-1`. + sort_by : Optional[str], optional + Specify which archived file information to sort on. Defaults to `'name'` + All fields known are: `["name","size","pack_size","mtime"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `'asc'` + All possible direction are: `["asc","desc"]`. + codepage : Optional[str], optional + The language codepage used for decoding file name with an archive. Defaults to `None` + All fields known are: `["enu","cht","chs","krn","ger","fre","ita","spn","jpn","dan","nor","sve","nld","rus","plk","ptb","ptg","hun","trk","csy"]` + password : Optional[str], optional + The password for extracting the file.. Defaults to `None` + item_id : Optional[str], optional + Item ID of an archived folder to be listed within an archive. (None) or -1 will list archive files in a root folder within an archive. Defaults to `None` + + Returns + ------- + dict[str, object] + Information about the archived files. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "is_dir": false, + "item_id": 1, + "mtime": "2013-02-03 00:17:12", + "name": "ITEMA_20445972-0.mp3", + "pack_size": 51298633, + "path": "ITEMA_20445972-0.mp3", + "size": 51726464 + }, + { + "is_dir": false, + "item_id": 0, + "mtime": "2013-03-03 00:18:12", + "name": "ITEMA_20455319-0.mp3", + "pack_size": 51434239, + "path": "ITEMA_20455319-0.mp3", + "size": 51896448 + } + ], + "total":2 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Extract' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'file_path': file_path, + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'codepage': codepage, + 'password': password, + 'item_id': item_id + } + return self.request_data(api_name, api_path, req_param) + + def start_file_compression(self, path: str | list[str], dest_file_path: str, level: Optional[int] = 'moderate', + mode: Optional[str] = 'add', format: Optional[str] = 'zip', password: Optional[str] = None + ) -> dict[str, object] | tuple[str]: + """ + Start to compress file(s)/folder(s). + + Parameters + ---------- + path : str | list[str] + One or more file paths to be compressed, starting with a shared folder. + dest_file_path : str + A destination file path (including file name) of an archive for the compressed archive. + level : Optional[int], optional + Defaults to `'moderate'`. + Compress level used, could be one of following values: + - `moderate`: moderate compression and normal compression speed. + - `store`: pack files with no compress. fastest: fastest compression speed but less compression. + - `best`: slowest compression speed but optimal compression. + mode : Optional[str], optional + Defaults to `'add'` + Compress mode used, could be one of following values: + - `add`: Update existing items and add new files. If an archive does not exist, a new one is created. + - `update`: Update existing items if newer on the file system and add new files. If the archive does not exist create a new archive. + - `refreshen`: Update existing items of an archive if newer on the file system. Does not add new files to the archive. + - `synchronize`: Update older files in the archive and add files that are not already in the archive. + format : Optional[str], optional + The compress format, ZIP or 7z format. Defaults to `'zip'` + All fields known are: `["zip","7z"]` + password : Optional[str], optional + The password for the archive. Defaults to `None` + + Returns + ------- + dict[str, object] | tuple[str] + Unique task ID for the compress task. + + Examples + -------- + ```json + { + "data": { + "taskid": "FileStation_51CBB25CC31961FD" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Compress' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'start', + 'path': json.dumps(path) if isinstance(path, list) else path, + 'dest_file_path': dest_file_path, + 'level': level, + 'mode': mode, + 'format': format, + 'password': password + } + return self.request_data(api_name, api_path, req_param) + + def get_compress_status(self, taskid: str) -> dict[str, object]: + """ + Get the compress task status. + + Parameters + ---------- + taskid : str + A unique ID for the compress task. This is obtained from `start_file_compression` method. + + Returns + ------- + dict[str, object] + Information about the compress task. + + Examples + -------- + ```json + { + "data": { + "dest_file_path": "/download/download.zip", + "finished": true + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Compress' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'status', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def stop_compress_task(self, taskid: str) -> dict[str, object]: + """ + Stop the compress task. + + Parameters + ---------- + taskid : str + A unique ID for the compress task. This is obtained from `start_file_compression` method. + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.Compress' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'stop', + 'taskid': taskid + } + return self.request_data(api_name, api_path, req_param) + + def get_list_of_all_background_task(self, offset: Optional[int] = 0, limit: Optional[int] = 0, + sort_by: Optional[str] = 'crtime', sort_direction: Optional[str] = 'asc', api_filter: Optional[str | list[str]] = None + ) -> dict[str, object]: + """ + List all background tasks including copy, move, delete, compress and extract tasks. + + Parameters + ---------- + offset : Optional[int], optional + Specify how many background tasks are skipped before beginning to return listed background tasks. Defaults to `0` + limit : Optional[int], optional + Number of background tasks requested. 0 indicates to list all background tasks. Defaults to `0` + sort_by : Optional[str], optional + Specify which information of the background task to sort on. Defaults to `'crtime'` + All fields known are: `["crtime","finished"]` + sort_direction : Optional[str], optional + Specify to sort ascending or to sort descending. Defaults to `'asc'` + All possible direction are: `["asc","desc"]` + api_filter : Optional[str | list[str]], optional + List background tasks with one or more given API name(s). If not given, all background tasks are listed. Defaults to `None` + All fields known are: `["SYNO.FileStation.CopyMove","SYNO.FileStation.Delete","SYNO.FileStation.Compress","SYNO.FileStation.Extract"]` + + Returns + ------- + dict[str, object] + List of background tasks. + + Examples + -------- + ```json + { + "data": { + "tasks": [ + { + "api": "SYNO.FileStation.CopyMove", + "crtime": 1372926088, + "finished": true, + "method": "start", + "params": { + "accurate_progress": true, + "dest_folder_path": "/video/test", + "overwrite": true, + "path": [ + "/video/test2/test.avi" + ], + "remove_src": false + }, + "path": "/video/test2/test.avi", + "processed_size": 12800, + "processing_path": "/video/test2/test.avi", + "progress": 1, + "taskid": "FileStation_51D53088860DD653", + "total": 12800, + "version": 1 + }, + { + "api": "SYNO.FileStation.Compress", + "crtime": 1372926097, + "finished": true, + "method": "start", + "params": { + "dest_file_path": "/video/test/test.zip", + "format": "zip", + "level": "", + "mode": "", + "password": "", + "path": [ + "/video/test/test.avi" + ] + }, + "progress": 0, + "taskid": "FileStation_51D53091A82CD948", + "total": -1, + "version": 1 + }, + { + "api": "SYNO.FileStation.Extract", + "crtime": 1372926103, + "finished": true, + "method": "start", + "params": { + "create_subfolder": false, + "dest_folder_path": "/video/test", + "file_path": [ + "/video/test/test.zip" + ], + "keep_dir": true, + "overwrite": false + }, + "progress": 1, + "taskid": "FileStation_51D530978633C014", + "total": -1, + "version": 1 + }, + { + "api": "SYNO.FileStation.Delete", + "crtime": 1372926110, + "finished": true, + "method": "start", + "params": { + "accurate_progress": true, + "path": [ + "/video/test/test.avi" + ] + }, + "path": "/video/test/test.avi", + "processed_num": 1, + "processing_path": "/video/test/test.avi", + "progress": 1, + "taskid": "FileStation_51D5309EE1E10BD9", + "total": 1, + "version": 1 + } + ], + "offset": 0, + "total": 4 + }, + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.BackgroundTask' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'list', + 'offset': offset, + 'limit': limit, + 'sort_by': sort_by, + 'sort_direction': sort_direction, + 'filter': json.dumps(api_filter) if isinstance(api_filter, list) else api_filter + } + return self.request_data(api_name, api_path, req_param) + + def clear_all_finished_background_task(self, taskid: Optional[str | list[str]] = None) -> dict[str, object]: + """ + Delete all finished background tasks. + + Parameters + ---------- + taskid : Optional[str | list[str]], optional + Unique IDs of finished copy, move, delete, compress or extract tasks. If it's not given, all finished tasks are deleted. Defaults to `None` + + Returns + ------- + dict[str, object] + No specific response. It returns an empty success response if completed without error. + + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = 'SYNO.FileStation.BackgroundTask' + info = self.gen_list[api_name] + api_path = info['path'] + req_param = { + 'version': info['maxVersion'], + 'method': 'clear_finished', + 'taskid': json.dumps(taskid) if isinstance(taskid, list) else taskid + } + return self.request_data(api_name, api_path, req_param) + + def get_file(self, path: str | list[str], mode: str, dest_path: str = ".", chunk_size: int = 8192, verify: bool = False) -> Optional[io.BytesIO]: + """ + Download a file. + + Parameters + ---------- + path : str | list[str] + One or more file/folder paths starting with a shared folder to be downloaded. When more than one file is to be downloaded, files/folders will be compressed as a zip file. + mode : str + Mode used to download files/folders, value could be: + - `open`: print the file content to stdout + - `download`: write the file content to a file based on the `dest_path` parameter + - `serve`: return the file content as a stream + dest_path : str, optional + Destination folder where the file is downloaded, if mode is `download`. Defaults to `"."` + chunk_size : int, optional + Size of chunk to download. Defaults to `8192` + verify : bool, optional + If `True` use HTTPS else use HTTP. Defaults to `False` + + Returns + ------- + Optional[io.BytesIO] + If mode is `serve`, return the file content as a stream. + """ + api_name = 'SYNO.FileStation.Download' + info = self.gen_list[api_name] + api_path = info['path'] + + session = requests.session() + str_path: str = json.dumps(path) if isinstance(path, list) else path + url = ('%s%s' % (self.base_url, api_path)) + '?api=%s&version=%s&method=download&path=%s&mode=%s&_sid=%s' % ( + api_name, info['maxVersion'], str_path, mode, self._sid) + + if mode == r'open': + with session.get(url, stream=True, verify=verify, headers={"X-SYNO-TOKEN": self.session._syno_token}) as r: + r.raise_for_status() + for chunk in r.iter_content(chunk_size=chunk_size): + if chunk: # filter out keep-alive new chunks + sys.stdout.buffer.write(chunk) + + if mode == r'download': + with session.get(url, stream=True, verify=verify, headers={"X-SYNO-TOKEN": self.session._syno_token}) as r: + r.raise_for_status() + if not os.path.isdir(dest_path): + os.makedirs(dest_path) + + if isinstance(path, list): + if len(path) > 1: + file_name = f"{os.path.splitext(os.path.basename(path[0]))[0]}.zip" + else: + file_name = os.path.basename(path[0]) + else: + file_name = os.path.basename(path) + with open(dest_path + "/" + file_name, 'wb') as f: + for chunk in r.iter_content(chunk_size=chunk_size): + if chunk: # filter out keep-alive new chunks + f.write(chunk) + + if mode == r'serve': + with session.get(url, stream=True, verify=verify, headers={"X-SYNO-TOKEN": self.session._syno_token}) as r: + r.raise_for_status() + return io.BytesIO(r.content) + + def generate_file_tree(self, + folder_path: str, + tree: Tree, + max_depth: Optional[int] = 1, + start_depth: Optional[int] = 0) -> None: + """ + Recursively generate the file tree based on the folder path you give constrained with. + + You need to create the root node before calling this function. + + Parameters + ---------- + folder_path : str + Folder path to generate file tree. + tree : Tree + Instance of the Tree from the `treelib` library. + max_depth : int, optional + Non-negative number of maximum depth of tree generation if node tree is directory, default to '1' to generate full tree. If 'max_depth=0' it will be equivalent to no recursion. + start_depth : int, optional + Non negative number to start to control tree generation default to '0'. + """ + api_name = 'hotfix' # fix for docs_parser.py issue + + if start_depth < 0: + start_depth = 0 + warnings.warn( + f"'start_depth={start_depth}'. It should not be less or than 0, setting 'start_depth' to 0!", + RuntimeWarning, + stacklevel=2 + ) + + assert start_depth <= max_depth, ValueError( + f"'start_depth' should not be greater than 'max_depth'. Got '{start_depth=}, {max_depth=}'") + assert isinstance(tree, Tree), ValueError( + "'tree' has to be a type of 'Tree'") + + data: dict[str, object] = self.get_file_list( + folder_path=folder_path + ).get("data") + + files = data.get("files") + _file_info_getter = map(lambda x: ( + x.get('isdir'), x.get('name'), x.get('path')), files) + for isdir, file_name, file_path in _file_info_getter: + + if isdir and (start_depth >= max_depth): + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": True}) + + elif isdir: + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": False}) + self.generate_file_tree( + file_path, tree, max_depth, start_depth + 1) + + else: + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": False}) diff --git a/synology_api/DSM/Package/PackageCenter.py b/synology_api/DSM/Package/PackageCenter.py new file mode 100644 index 00000000..7db980b6 --- /dev/null +++ b/synology_api/DSM/Package/PackageCenter.py @@ -0,0 +1,1131 @@ +""" +Core Package API implementation. + +Implementation of the PackageCenter application APIs. +""" + +import json +from typing import List +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor +import os +import requests +import tqdm +import time +from synology_api import base_api + + +class PackageCenter(base_api.BaseApi): + """ + Core Package API implementation. + + Implementation of the PackageCenter application APIs. + """ + + def get_package(self, package_id: str, additional: List[str] = []) -> dict: + """ + Get infos of a package. + + Parameters + ---------- + package_id : str + Package ID. + additional : list of str, optional + Additional fields to retrieve. Defaults to []. + All fields known are: ["status", "dsm_apps"]. + + Returns + ------- + dict + Information about the package. + + Examples + -------- + ```json + { + "data": { + "additional": { + "dsm_apps": " com.plexapp.plexmediaserver", + "status": "running", + "status_code": 0, + "status_description": "retrieve from status script", + "status_origin": "running" + }, + "id": "PlexMediaServer", + "name": "Plex Media Server", + "timestamp": 1739228562839, + "version": "1.41.3.9314-72009314" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "get", + "version": info['minVersion'], + "id": package_id, + "additional": json.dumps(additional) + } + return self.request_data(api_name, api_path, req_param) + + def list_installed(self, additional: list = [], ignore_hidden: bool = False) -> dict: + """ + List installed packages. + + Parameters + ---------- + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: + `["description", "description_enu", "dependent_packages", "beta", "distributor", "distributor_url", + "maintainer", "maintainer_url", "dsm_apps", "dsm_app_page", "dsm_app_launch_name","report_beta_url", + "support_center", "startable", "installed_info", "support_url", "is_uninstall_pages","install_type", + "autoupdate", "silent_upgrade", "installing_progress", "ctl_uninstall", "updated_at", "status", + "url","available_operation"]`. + ignore_hidden : bool + TODO: Write description + + Returns + ------- + dict + List of packages installed on the NAS. + + Examples + -------- + ```json + { + "data": { + "packages": [ + { + "additional": { + "install_type": "" + }, + "id": "ActiveBackup-Office365", + "name": "Active Backup for Microsoft 365", + "timestamp": 1738880043640, + "version": "2.5.5-14034" + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "list", + "version": info['maxVersion'], + "ignore_hidden": ignore_hidden, + "additional": json.dumps(additional) + } + + return self.request_data(api_name, api_path, req_param) + + def list_installable(self) -> dict: + """ + List installable packages. + + Returns + ------- + dict + List of beta_package, categories and packages available. + + Examples + -------- + ```json + { + "data": { + "banners": [], + "beta_packages": [...], + "categories": [...], + "packages": [...] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Server' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "list", + "version": info['maxVersion'], + "blforcereload": False, + "blloadothers": False + } + + return self.request_data(api_name, api_path, req_param) + + def get_package_center_settings(self) -> dict: + """ + Get package center settings. + + Returns + ------- + dict + List settings of the Package center. + + Examples + -------- + ```json + { + "data": { + "autoupdateall": false, + "autoupdateimportant": true, + "default_vol": "/volume1", + "enable_autoupdate": true, + "enable_dsm": true, + "enable_email": false, + "mailset": true, + "trust_level": 0, + "update_channel": true, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 184.72 GB )", + "mount_point": "/volume1", + "size_free": "198336327680", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.14 GB )", + "mount_point": "/volume2", + "size_free": "2567467421696", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ] + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Setting' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "get", + "version": info['maxVersion'], + } + + return self.request_data(api_name, api_path, req_param) + + def set_package_center_settings(self, + enable_email: bool, enable_dsm: bool, enable_autoupdate: bool, + autoupdateall: bool, autoupdateimportant: bool, + default_vol: str, update_channel: str + ) -> dict: + """ + Set settings of the package center. + + Parameters + ---------- + enable_email : bool + Enable email notification + enable_dsm : bool + Enable desktop notification + enable_autoupdate : bool + Update packages automatically + autoupdateall : bool + Auto update all packages + autoupdateimportant : bool + Auto update "important" packages + default_vol : str + Default volume for installation, all your volumes or `"no_default_vol" = Always ask me` + update_channel : str + "stable" => Disable beta packages + "beta" => Enable beta packages + + Returns + ------- + dict + Return some settings. + + Examples + -------- + ```json + { + "data": { + "enable_dsm": true, + "enable_email": false, + "update_channel": "stable" + }, + "success": true + } + ``` + """ + + api_name = 'SYNO.Core.Package.Setting' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "set", + "version": info['maxVersion'], + "enable_email": enable_email, + "enable_dsm": enable_dsm, + "enable_autoupdate": enable_autoupdate, + "autoupdateall": autoupdateall, + "autoupdateimportant": autoupdateimportant, + "default_vol": default_vol, + "update_channel": update_channel + } + + return self.request_data(api_name, api_path, req_param) + + def get_package_center_infos(self) -> dict: + """ + Get package center informations. + + Returns + ------- + dict + List of configs. + + Examples + -------- + ```json + { + "data": { + "config": { + "auth_key": "------------------------------", + "blBetaChannel": false, + "blOtherServer": false, + "def_void": "", + "ds_build": "72806", + "ds_major": "7", + "ds_minor": "2", + "ds_timezone": "Amsterdam", + "ds_unique": "synology_r1000_723+", + "myPayBaseURL": "https://payment.synology.com", + "myds_id": "7886858", + "serial": "2260TPR7X30E6", + "success": true + }, + "prerelease": { + "agreed": true, + "success": true + }, + "term": { + "agreed_term_version": "0003", + "curr_term_version": "0003", + "success": true + } + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Info' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "get", + "version": info['maxVersion'], + } + return self.request_data(api_name, api_path, req_param) + + def feasibility_check_install(self, packages: List[str]) -> dict: + """ + Check if installation is possible. + + Parameters + ---------- + packages : List[str] + List of package IDs to check for feasibility + + Returns + ------- + dict + A dictionary containing the feasibility check results. + + Examples + -------- + ```json + { + "data": { + "template": "data" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Setting' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "feasibility_check", + "version": info['maxVersion'], + "type": "install_check", + "packages": json.dumps(packages) + } + + return self.request_data(api_name, api_path, req_param) + + def download_package(self, url: str, package_id: str, checksum: str, filesize: str) -> dict: + """ + Start download of the package, return a taskId for check status. + + Parameters + ---------- + url : str + Url that can be retrieve from package info using `get_installable` function, in the `link` field + package_id : str + Package ID that can be retrieve from package info using `get_installable` function, in the `id` field + checksum : str + Checksum that can be retrieve from package info using `get_installable` function, in the `md5` field + filesize : str + Filesize that can be retrieve from package info using `get_installable` function, in the `size` field + + Returns + ------- + dict + Retreive first progress of the download and the taskid used to check download status with `get_dowload_package_status` function. + + Examples + -------- + ```json + { + "data": { + "progress": 1.0000000000000001e-05, + "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Installation' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "install", + "version": info['minVersion'], + "operation": "install", + "type": 0, + "blqinst": False, + "url": url, + "name": package_id, + "checksum": checksum, + "filesize": filesize + } + return self.request_data(api_name, api_path, req_param) + + def get_dowload_package_status(self, task_id: str) -> dict: + """ + Get current download status of the package. + + Parameters + ---------- + task_id : str + Task ID retrieve from response of `download_package` function + + Returns + ------- + dict + Retrieve informations about the download, important info is the `progress` field. + + Examples + -------- + ```json + { + "data": { + "beta": false, + "blqinst": false, + "finished": false, + "id": "DhcpServer", + "installing": false, + "name": "DhcpServer", + "pid": 27844, + "progress": 1.0000000000000001e-05, + "remote_link": "https://global.synologydownload.com/download/Package/spk/DhcpServer/1.0.2-0046/DhcpServer-x86_64-1.0.2-0046.spk", + "size": "1378697", + "success": true, + "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer", + "tmp_folder": "/volume1/@tmp/synopkg/download.esnnkb" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Installation' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "status", + "version": info['minVersion'], + "task_id": task_id + } + return self.request_data(api_name, api_path, req_param) + + def check_installation_from_download(self, task_id: str) -> dict: + """ + Get info about downloaded package file, response field is used for `check_installation` and `install_package` function. + + Parameters + ---------- + task_id : str + Task ID retrieve from response of `download_package` function + + Returns + ------- + dict + Retrieve information about downloaded package installation file, response field is used for `check_installation` and `install_package` function. + + Examples + -------- + ```json + { + "data": { + "description": "DHCP Server turns your DiskStation into a DHCP server within LAN to assign dynamic IP addresses and manage DHCP clients.", + "distributor": "", + "dsm_apps": "SYNO.SDS.DHCP.Instance", + "filename": "/volume1/@tmp/synopkg/download.esnnkb/@SYNOPKG_DOWNLOAD_DhcpServer", + "id": "DhcpServer", + "install_on_cold_storage": false, + "install_reboot": false, + "install_type": "system", + "maintainer": "Synology Inc.", + "name": "DHCP Server", + "startable": true, + "status": "non_installed", + "status_code": 255, + "status_description": "failed to locate given package", + "status_origin": "non_installed", + "version": "1.0.2-0046" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Installation.Download' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "check", + "version": info['minVersion'], + "taskid": task_id + } + return self.request_data(api_name, api_path, req_param) + + def upload_package_file(self, file_path: str, verify: bool = False, progress_bar: bool = True, additional: list = []) -> dict: + """ + Upload a file for install a package. + + Parameters + ---------- + file_path : str + File path + verify : bool, optional + Use https. Defaults to `False` + progress_bar : bool, optional + Enable progress bar in the terminal. Defaults to `True` + additional : list, optional + Additional field to retrieves. Defaults to `[]` + All fields know are: + `["description","maintainer","distributor","startable","dsm_apps","status","install_reboot", + "install_type","install_on_cold_storage","break_pkgs","replace_pkgs"]`. + + Returns + ------- + dict + Informations about the uploaded file for installation. + + Examples + -------- + ```json + { + "data": { + "additional": { + "break_pkgs": null, + "description": "Plex organizes all of your personal media so you can easily access and enjoy it.", + "distributor": "", + "dsm_apps": " com.plexapp.plexmediaserver", + "install_on_cold_storage": false, + "install_reboot": false, + "install_type": "", + "maintainer": "Plex Inc", + "replace_pkgs": { "Plex Media Server": "" }, + "startable": true, + "status": "running", + "status_code": 0, + "status_description": "retrieve from status script", + "status_origin": "running" + }, + "codesign_error": 4532, + "id": "PlexMediaServer", + "name": "Plex Media Server", + "task_id": "@SYNOPKG_UPLOAD_17392283048566DD3", + "version": "1.41.3.9314-72009314" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Installation' + info = self.core_list[api_name] + api_path = info['path'] + filename = os.path.basename(file_path) + + session = requests.session() + + with open(file_path, 'rb') as payload: + url = ('%s%s' % (self.base_url, api_path)) + '?api=%s&version=%s&method=upload&_sid=%s' % ( + api_name, info['minVersion'], self._sid) + + encoder = MultipartEncoder({ + 'additional': json.dumps(additional), + 'file': (filename, payload, 'application/octet-stream') + }) + + if progress_bar: + bar = tqdm.tqdm(desc='Upload Progress', + total=encoder.len, + dynamic_ncols=True, + unit='B', + unit_scale=True, + unit_divisor=1024 + ) + + monitor = MultipartEncoderMonitor( + encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) + + r = session.post( + url, + data=monitor, + verify=verify, + headers={"X-SYNO-TOKEN": self.session._syno_token, + 'Content-Type': monitor.content_type} + ) + + else: + r = session.post( + url, + data=encoder, + verify=verify, + headers={"X-SYNO-TOKEN": self.session._syno_token, + 'Content-Type': encoder.content_type} + ) + + session.close() + if r.status_code != 200 or not r.json()['success']: + return r.status_code, r.json() + + return r.json() + + def get_default_install_volume(self) -> dict: + """ + Get default install volume for package. + + Returns + ------- + dict + Return default volume, if default volume is set to `Always ask me` it return error 4501. + + Examples + -------- + ```json + { + "data": { + "default_vol": "/volume1" + }, + "success": true + } + ``` + """ + api_name = 'SYNO.Core.Package.Setting.Volume' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "get", + "version": info['maxVersion'], + } + + return self.request_data(api_name, api_path, req_param) + + def check_installation(self, + package_id: str, install_type: str = "", install_on_cold_storage: bool = False, + blCheckDep: bool = False, replacepkgs: dict = {} + ) -> dict: + """ + Check installation of the package on the default volume. + + Parameters + ---------- + package_id : str + Id of the package to install + install_type : str, optionnal + Installation type, Defaults to `""`. TODO: Add description and possible types + install_on_cold_storage : bool, optional + Defaults to `False`. TODO: Add description + blCheckDep : bool, optional + Defaults to `False`. TODO: Add description + replacepkgs : dict, optional + Defaults to `{}`. TODO: Add description + + Returns + ------- + dict + List of usefull informations about volumes. + + Examples + -------- + ```json + { + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 184.52 GB )", + "mount_point": "/volume1", + "size_free": "198126022656", + "size_total": "206158430208", + "vol_desc": "vol1", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.16 GB )", + "mount_point": "/volume2", + "size_free": "2567484923904", + "size_total": "3623234412544", + "vol_desc": "vol2", + "volume_features": [] + } + ], + "volume_path": "/volume1" + }, + "success": true, + } + ``` + """ + + api_name = 'SYNO.Core.Package.Installation' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "check", + "version": info['maxVersion'], + "id": package_id, + "install_type": install_type, + "install_on_cold_storage": install_on_cold_storage, + "breakpkgs": None, + "blCheckDep": blCheckDep, + "replacepkgs": json.dumps(replacepkgs) + } + + return self.request_data(api_name, api_path, req_param) + + def upgrade_package(self, task_id: str, check_codesign: bool = False, force: bool = False, installrunpackage: bool = True, extra_values: dict = {}) -> dict: + """ +Upgrade an existing package. + + Parameters + ---------- + task_id : str + Task id of the download or the upload file + check_codesign : bool, optional + Check signature of the source code of the package (is it a Synology one). Defaults to `False` + force : bool, optional + Force installation. Defaults to `False` + installrunpackage : bool, optional + Run package after installation. Defaults to `True` + extra_values : dict, optional + Extra values due to some package installation. Defaults to `{}` + All known extra values are: + - Surveillance station + ```json + { + "chkSVS_Alias": true, + "strSVS_Alias": "cam", + "chkSVS_HTTP": true, + "strSVS_HTTP": "9900", + "chkSVS_HTTPS": true, + "strSVS_HTTPS": "9901" + } + ``` + + Returns + ------- + dict + Message and some info about installation. + + Examples + -------- + ```json + { + "data": { + "message": "

Installation Successful!

\n

Note: If Plex cannot access your media, verify user PlexMediaServer is granted permission in Control Panel.


\nSet access to your media share(s) by performing the following steps:

\n1. Open Control Panel and select Shared Folder
\n2. Select the share which contains your media and click Edit
\n3. Click the Permissions tab
\n4. Change the dropdown from Local Users to System internal user
\n5. Check the Read/Write checkbox for the PlexMediaServer user
\n6. Click Save to confirm the new permissions
\n7. Repeat steps 2-6 for each share you want Plex Media Server to access
\n", + "packageName": "Plex Media Server", + "worker_message": [] + }, + "success": true, + } + ``` + """ + + api_name = 'SYNO.Core.Package.Installation' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "upgrade", + "version": info['minVersion'], + "type": 0, + "check_codesign": check_codesign, + "force": force, + "installrunpackage": installrunpackage, + "task_id": task_id, + "extra_values": json.dumps(extra_values), + } + return self.request_data(api_name, api_path, req_param) + + def install_package(self, package_id: str, volume_path: str, file_path: str, check_codesign: bool = True, force: bool = True, installrunpackage: bool = True, extra_values: dict = {}) -> dict: + """ + Install a package that is already downloaded. + + Parameters + ---------- + package_id : str + Id of the package to install + volume_path : str + Volume path of the installation, can get from `check_installation` function + file_path : str + File path of the installation, can get from `check_installation_from_download` function + check_codesign : bool, optional + Check signature of the source code of the package (is it a Synology one). Defaults to `False` + force : bool, optional + Force installation. Defaults to `False` + installrunpackage : bool, optional + Run package after installation. Defaults to `True` + extra_values : dict, optional + Extra values due to some package installation. Defaults to `{}` + All known extra values are: + - Surveillance station + ```json + { + "chkSVS_Alias": true, + "strSVS_Alias": "cam", + "chkSVS_HTTP": true, + "strSVS_HTTP": "9900", + "chkSVS_HTTPS": true, + "strSVS_HTTPS": "9901" + } + ``` + + Returns + ------- + dict + Message and some info about installation. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Package.Installation", + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 185.09 GB )", + "mount_point": "/volume1", + "size_free": "198739943424", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.17 GB )", + "mount_point": "/volume2", + "size_free": "2567495630848", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ], + "volume_path": "/volume1" + }, + "method": "check", + "success": true, + "version": 1 + }, + { + "api": "SYNO.Core.Package.Installation", + "data": { + "packageName": "Text Editor", + "worker_message": [] + }, + "method": "install", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` + """ + compound = [ + { + "api": "SYNO.Core.Package.Installation", + "method": "check", + "version": self.core_list['SYNO.Core.Package.Installation']['minVersion'], + "id": package_id, + "install_type": "", + "install_on_cold_storage": False, + "breakpkgs": None, + "blCheckDep": False, + "replacepkgs": None + }, + { + "api": "SYNO.Core.Package.Installation", + "method": "install", + "version": self.core_list["SYNO.Core.Package.Installation"]['minVersion'], + "type": 0, + "volume_path": volume_path, + "path": file_path, + "check_codesign": check_codesign, + "force": force, + "installrunpackage": installrunpackage, + "extra_values": json.dumps(extra_values), + } + ] + return self.batch_request(compound=compound) + + def uninstall_package(self, package_id: str) -> dict: + """ + Uninstall a package. + + Parameters + ---------- + package_id : str + Id of the package to uninstall + + Returns + ------- + dict + Possible message to the user. + + Examples + -------- + ```json + { + "data": { + "message": "", + "worker_message": [] + }, + "success": true + } + ``` + """ + + if not self._is_package_already_installed(package_id=package_id): + raise Exception( + f"""Package "{package_id}" is not installed, it cannot be uninstalled""") + + api_name = 'SYNO.Core.Package.Uninstallation' + info = self.core_list[api_name] + api_path = info['path'] + req_param = { + "method": "uninstall", + "version": info['minVersion'], + "id": package_id, + "dsm_apps": "" + } + + return self.request_data(api_name, api_path, req_param) + + def _is_package_already_installed(self, package_id: str) -> bool: + """ + Check if a package is already installed. + + Parameters + ---------- + package_id : str + Package ID to check + + Returns + ------- + bool + `True` if the package is already installed, `False` otherwise. + """ + response: dict = self.list_installed() + data: dict = response.get("data") + installed_packages = data.get("packages") + package_infos: dict = next( + (package for package in installed_packages if package["id"] == package_id), None) + return package_infos != None + + def easy_install(self, package_id: str, volume_path: str, install_dependencies: bool = True) -> dict: + """ + Execute an "easy" installation process of the package. + + Parameters + ---------- + package_id : str + Package ID to install + volume_path : str + Volume path where you want to install the package + install_dependencies : bool, optional + If you want to install dependencies. Defaults to `True` + + Returns + ------- + dict + Information about installation, same as `install_package` function. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Package.Installation", + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 185.11 GB )", + "mount_point": "/volume1", + "size_free": "198759485440", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.17 GB )", + "mount_point": "/volume2", + "size_free": "2567495565312", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ], + "volume_path": "/volume1" + }, + "method": "check", + "success": true, + "version": 1 + }, + { + "api": "SYNO.Core.Package.Installation", + "data": { + "packageName": "Text Editor", + "worker_message": [] + }, + "method": "install", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` + """ + + # Package already installed + if self._is_package_already_installed(package_id): + raise Exception(f"""Package "{package_id}" already installed""") + + response: dict = self.list_installable() + data: dict = response.get("data") + installable_packages = data.get("packages") + package_infos: dict = next( + (package for package in installable_packages if package["id"] == package_id), None) + # Package not found + if package_infos == None: + raise Exception( + f"""Package "{package_id}" not found in installable list, installation not possible""") + + # Check dependencies + deppkgs = package_infos.get("deppkgs") + if deppkgs: + if not install_dependencies: + raise Exception( + f"""Package "{package_id}" has dependencies that needs to be installed but "install_dependencies" is set to "False" """) + deppkg: str + for deppkg in deppkgs: + if not self._is_package_already_installed(deppkg): + print( + f"""Installation of dependency "{deppkg}" for "{package_id}" started""") + self.easy_install(package_id=deppkg, + volume_path=volume_path) + print( + f"""Installation of dependency "{deppkg}" for "{package_id}" done""") + + # Store information of the package + url = package_infos.get("link") + filesize = package_infos.get("size") + version = package_infos.get("version") + checksum = package_infos.get("md5") + + # Start installation sequence + + # Start download the package installation file + response: dict = self.download_package( + url=url, package_id=package_id, checksum=checksum, filesize=filesize) + data: dict = response.get("data") + task_id = data.get("taskid") + + # Create progress bar of the status + response: dict = self.get_dowload_package_status(task_id=task_id) + data: dict = response.get("data") + progress = data.get("progress") + if not data.get("finished"): + with tqdm.tqdm(total=100) as pbar: + while not data.get("finished"): + response: dict = self.get_dowload_package_status( + task_id=task_id) + data: dict = response.get("data") + progress: float = data.get("progress") + if progress: + pbar.update(int(progress*100)) + time.sleep(0.500) + pbar.update(100) + + print(f"""Download of "{package_id}" done""") + + # Check downloaded file + response: dict = self.check_installation_from_download(task_id=task_id) + data: dict = response.get("data") + status = data.get("status") + file_path = data.get("filename") + print(f"""Downloaded file status : {status}""") + + # Check installation + response = self.check_installation(package_id=package_id) + + # Install package + extra_values = {} + if package_id == "SurveillanceStation": + extra_values = { + "chkSVS_Alias": True, + "strSVS_Alias": "cam", + "chkSVS_HTTP": True, + "strSVS_HTTP": "9900", + "chkSVS_HTTPS": True, + "strSVS_HTTPS": "9901" + } + + return self.install_package(package_id=package_id, volume_path=volume_path, file_path=file_path, extra_values=extra_values) diff --git a/synology_api/DSM/Package/__init__.py b/synology_api/DSM/Package/__init__.py new file mode 100644 index 00000000..4ab7b736 --- /dev/null +++ b/synology_api/DSM/Package/__init__.py @@ -0,0 +1,9 @@ + +""" +Package submodule for Synology DSM API. + +Provides FileStation and PackageCenter API classes. +""" + +from .FileStation import FileStation +from .PackageCenter import PackageCenter diff --git a/synology_api/DSM/__init__.py b/synology_api/DSM/__init__.py new file mode 100644 index 00000000..42906cec --- /dev/null +++ b/synology_api/DSM/__init__.py @@ -0,0 +1,88 @@ +""" +Main entry point for Synology DSM API access. +""" + +from .ControlPanel import ControlPanel +from .Package.FileStation import FileStation +from .Package.PackageCenter import PackageCenter +from synology_api import base_api + + +class DSM(base_api.BaseApi): + """ + Main entry point for Synology DSM API access. Provides access to ControlPanel, FileStation, and PackageCenter APIs. + + Parameters + ---------- + *args : tuple + Positional arguments passed to BaseApi. + **kwargs : dict + Keyword arguments passed to BaseApi. + """ + _ctrl_panel = None + _file_station = None + _package_center = None + + def __init__(self, *args, **kwargs): + """ + Initialize DSM API wrapper. + + Parameters + ---------- + *args : tuple + Positional arguments passed to BaseApi. + **kwargs : dict + Keyword arguments passed to BaseApi. + """ + super().__init__(*args, **kwargs) + + @property + def ControlPanel(self): + """ + ControlPanel: ControlPanel. + + Returns + ------- + ControlPanel + Instance of the ControlPanel API, sharing the same state as DSM. + """ + if self._ctrl_panel is None: + # Create ControlPanel instance without calling __init__ + self._ctrl_panel = ControlPanel.__new__(ControlPanel) + # Share the state + self._ctrl_panel.__dict__ = self.__dict__ + return self._ctrl_panel + + @property + def FileStation(self): + """ + FileStation: FileStation. + + Returns + ------- + FileStation + Instance of the FileStation API, sharing the same state as DSM. + """ + if self._file_station is None: + # Create FileStation instance without calling __init__ + self._file_station = FileStation.__new__(FileStation) + # Share the state + self._file_station.__dict__ = self.__dict__ + return self._file_station + + @property + def PackageCenter(self): + """ + PackageCenter: PackageCenter. + + Returns + ------- + PackageCenter + Instance of the PackageCenter API, sharing the same state as DSM. + """ + if self._package_center is None: + # Create PackageCenter instance without calling __init__ + self._package_center = PackageCenter.__new__(PackageCenter) + # Share the state + self._package_center.__dict__ = self.__dict__ + return self._package_center diff --git a/synology_api/__init__.py b/synology_api/__init__.py index 1f5f8a19..bf061576 100755 --- a/synology_api/__init__.py +++ b/synology_api/__init__.py @@ -1,3 +1,4 @@ +"""Synology API Python Client.""" from . import \ audiostation, \ auth, \ @@ -28,3 +29,28 @@ universal_search, \ snapshot, \ surveillancestation + +from .DSM import DSM +from .DSM.ControlPanel import \ + ControlPanel, \ + ApplicationPrivileges, \ + DomainLDAP, \ + ExternalAccess, \ + ExternalDevices, \ + FileServices, \ + HardwarePower, \ + IndexingService, \ + InfoCenter, \ + LoginPortal, \ + Network, \ + Notifications, \ + RegionalOptions, \ + Security, \ + SharedFolder, \ + SynologyAccount, \ + TaskScheduler, \ + TerminalSNMP, \ + UpdateRestore, \ + UserGroup +from .DSM.Package import \ + FileStation diff --git a/synology_api/abm.py b/synology_api/abm.py index 41025428..03961dc6 100644 --- a/synology_api/abm.py +++ b/synology_api/abm.py @@ -1,6 +1,4 @@ -""" -Active Backup for Microsoft 365 Implementation. -""" +"""Active Backup for Microsoft 365 Implementation.""" from __future__ import annotations import json @@ -735,7 +733,7 @@ def set_task_schedule(self, "repeat_every_hours": 1, "run_days": [0, 1, 2, 3, 4, 5, 6] } - ```. + ``` Returns ------- diff --git a/synology_api/auth.py b/synology_api/auth.py index 32710226..7a5c936d 100644 --- a/synology_api/auth.py +++ b/synology_api/auth.py @@ -1,11 +1,12 @@ -""" -Provides authentication and API request handling for Synology DSM, including session management, encryption utilities, and error handling for various Synology services. -""" +"""Provides authentication and API request handling for Synology DSM, including session management, encryption utilities, and error handling for various Synology services.""" from __future__ import annotations from random import randint -from typing import Optional +from typing import Optional, Any, Union import requests import json + +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor + from .error_codes import error_codes, CODE_SUCCESS, download_station_error_codes, file_station_error_codes from .error_codes import auth_error_codes, virtualization_error_codes from urllib3 import disable_warnings @@ -24,7 +25,10 @@ import base64 import hashlib import urllib - +from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey +import base64 +from noise.connection import NoiseConnection, Keypair +import time USE_EXCEPTIONS: bool = True @@ -131,6 +135,52 @@ def __init__(self, self.full_api_list = {} self.app_api_list = {} + def get_ik_message(self) -> str: + """ + Get the IK message for authentication. + + Returns + ------- + str + The IK message. + """ + + url = self._base_url + 'entry.cgi/SYNO.API.Auth.UIConfig' + data = { + "api": "SYNO.API.Auth.UIConfig", + "method": "get", + "version": "1" + } + response = requests.post(url, data=data, verify=self._verify) + + # Try to get cookie "_SSID" + if response.status_code != 200: + raise Exception("Failed to access the URL for IK message. Status code: {}".format( + response.status_code)) + cookies = response.cookies + if "_SSID" not in cookies: + raise Exception("Cookie '_SSID' not found in the response.") + _SSID_encoded = cookies["_SSID"] + _SSID = self.decode_ssid_cookie(_SSID_encoded) + + private_bytes = X25519PrivateKey.generate().private_bytes_raw() + + noise = NoiseConnection.from_name(b"Noise_IK_25519_ChaChaPoly_BLAKE2b") + noise.set_as_initiator() + noise.set_keypair_from_private_bytes(Keypair.STATIC, private_bytes) + noise.set_keypair_from_public_bytes(Keypair.REMOTE_STATIC, _SSID) + + noise.start_handshake() + + payload = json.dumps({ + "time": int(time.time()), + }).encode('utf-8') + + message = noise.write_message(payload) + ik_message = self.encode_ssid_cookie(message) + + return ik_message + def verify_cert_enabled(self) -> bool: """ Check if SSL certificate verification is enabled. @@ -161,6 +211,9 @@ def login(self) -> None: params = {'api': "SYNO.API.Auth", 'version': self._version, 'method': 'login', 'enable_syno_token': 'yes', 'client': 'browser'} + if self._version >= 7: + params.update({'ik_message': self.get_ik_message()}) + params_enc = { 'account': self._username, 'enable_device_token': 'no', @@ -325,9 +378,7 @@ def get_api_list(self, app: Optional[str] = None) -> None: return def show_api_name_list(self) -> None: - """ - Print the list of available API names. - """ + """Print the list of available API names.""" prev_key = '' for key in self.full_api_list: if key != prev_key: @@ -336,9 +387,7 @@ def show_api_name_list(self) -> None: return def show_json_response_type(self) -> None: - """ - Print API names that return JSON data. - """ + """Print API names that return JSON data.""" for key in self.full_api_list: for sub_key in self.full_api_list[key]: if sub_key == 'requestFormat': @@ -577,6 +626,7 @@ def request_data(self, api_path: str, req_param: dict[str, object], method: Optional[str] = None, + data: MultiPartEncoderMonitor | MultipartEncoder | str | None = None, response_json: bool = True ) -> dict[str, object] | str | list | requests.Response: # 'post' or 'get' """ @@ -592,6 +642,8 @@ def request_data(self, The parameters to include in the request. method : str, optional The HTTP method to use ('get' or 'post'). Defaults to 'get' if not specified. + data : str, optional + The data to send to upload a file like a torrent file. response_json : bool, optional Whether to return the response as JSON. If False, returns the raw response object. @@ -630,8 +682,15 @@ def request_data(self, response = requests.get(url, req_param, verify=self._verify, headers={ "X-SYNO-TOKEN": self._syno_token}) elif method == 'post': - response = requests.post(url, req_param, verify=self._verify, headers={ - "X-SYNO-TOKEN": self._syno_token}) + if data is None: + response = requests.post(url, req_param, verify=self._verify, headers={ + "X-SYNO-TOKEN": self._syno_token}) + else: + url = ('%s%s' % (self._base_url, api_path)) + \ + '/' + api_name + response = requests.post(url, data=data, params=req_param, verify=self._verify, headers={ + "Content-Type": data.content_type, "X-SYNO-TOKEN": self._syno_token}) + response.raise_for_status() except requests.exceptions.ConnectionError as e: raise SynoConnectionError(error_message=e.args[0]) except requests.exceptions.HTTPError as e: @@ -644,6 +703,7 @@ def request_data(self, elif method == 'post': response = requests.post(url, req_param, verify=self._verify, headers={ "X-SYNO-TOKEN": self._syno_token}) + response.raise_for_status() # Check for error response from dsm: error_code = 0 @@ -808,6 +868,52 @@ def _get_error_message(code: int, api_name: str) -> str: message = "" % api_name return 'Error {} - {}'.format(code, message) + @staticmethod + def decode_ssid_cookie(ssid: str) -> bytes: + """ + Decode the SSID cookie. + + Parameters + ---------- + ssid : str + The SSID cookie string to decode. + + Returns + ------- + bytes + The decoded SSID cookie. + """ + # Replace '-' with '+' and '_' with '/' + ssid_fixed = ssid.replace('-', '+').replace('_', '/') + # Pad with '=' if needed + padding = '=' * (-len(ssid_fixed) % 4) + ssid_fixed += padding + # Decode base64 + return base64.b64decode(ssid_fixed) + + @staticmethod + def encode_ssid_cookie(ssid_bytes: bytes) -> str: + """ + Encode the SSID cookie. + + Parameters + ---------- + ssid_bytes : bytes + The SSID cookie bytes to encode. + + Returns + ------- + str + The encoded SSID cookie. + """ + # Encode to base64 + ssid_b64 = base64.b64encode(ssid_bytes).decode('utf-8') + # Replace '+' with '-' and '/' with '_' + ssid_fixed = ssid_b64.replace('+', '-').replace('/', '_') + # Remove padding '=' + ssid_fixed = ssid_fixed.rstrip('=') + return ssid_fixed + @property def sid(self) -> Optional[str]: """ diff --git a/synology_api/base_api.py b/synology_api/base_api.py index c1702e64..909456d5 100644 --- a/synology_api/base_api.py +++ b/synology_api/base_api.py @@ -1,42 +1,46 @@ +""" +Base API module for Synology DSM. + +Provides a base class for all API implementations, handling authentication, +session management, and connection setup to a Synology NAS device. +""" from typing import Optional, Any from . import auth as syn class BaseApi(object): - """Base class to be used for all API implementations. - - Takes auth and connection information to create a session to the NAS. - - The session is created on instanciation. - - Parameters - ---------- - ip_address : str - The IP/DNS address of the NAS. - - port : str - The port of the NAS. Defaults to `5000`. - - username : str - The username to use for authentication. - - password : str - The password to use for authentication. - - secure : bool - Whether to use HTTPS or not. Defaults to `False`. - - cert_verify : bool - Whether to verify the SSL certificate or not. Defaults to `False`. - - dsm_version : int - The DSM version. Defaults to `7`. - - debug : bool - Whether to print debug messages or not. Defaults to `True`. - - otp_code : str - The OTP code to use for authentication. Defaults to `None` + """ + Base class to be used for all API implementations. + + Takes auth and connection information to create a session to the NAS. + The session is created on instanciation. + + Parameters + ---------- + ip_address : str + The IP/DNS address of the NAS. + port : str + The port of the NAS. Defaults to `5000`. + username : str + The username to use for authentication. + password : str + The password to use for authentication. + secure : bool, optional + Whether to use HTTPS or not. Defaults to `False`. + cert_verify : bool, optional + Whether to verify the SSL certificate or not. Defaults to `False`. + dsm_version : int, optional + The DSM version. Defaults to `7`. + debug : bool, optional + Whether to print debug messages or not. Defaults to `True`. + otp_code : str, optional + The OTP code to use for authentication. Defaults to `None`. + device_id : str, optional + Device ID for device binding. Defaults to `None`. + device_name : str, optional + Device name for device binding. Defaults to `None`. + application : str, optional + The application context for API list retrieval. Defaults to `'Core'`. """ # Class-level attribute to store the shared session @@ -56,7 +60,41 @@ def __init__(self, device_name: Optional[str] = None, application: str = 'Core', ) -> None: + """ + Initialize the BaseApi object and create or reuse a session. + Parameters + ---------- + ip_address : str + The IP/DNS address of the NAS. + port : str + The port of the NAS. + username : str + The username to use for authentication. + password : str + The password to use for authentication. + secure : bool, optional + Whether to use HTTPS or not. Defaults to `False`. + cert_verify : bool, optional + Whether to verify the SSL certificate or not. Defaults to `False`. + dsm_version : int, optional + The DSM version. Defaults to `7`. + debug : bool, optional + Whether to print debug messages or not. Defaults to `True`. + otp_code : str, optional + The OTP code to use for authentication. Defaults to `None`. + device_id : str, optional + Device ID for device binding. Defaults to `None`. + device_name : str, optional + Device name for device binding. Defaults to `None`. + application : str, optional + The application context for API list retrieval. Defaults to `'Core'`. + + Returns + ------- + None + Just actions, no return values. + """ self.application = application # Reuse shared session if it exists, otherwise create a new one @@ -87,7 +125,14 @@ def __init__(self, self.base_url: str = self.session.base_url def logout(self) -> None: - """Close current session.""" + """ + Close current session. + + Returns + ------- + None + Action, no return values. + """ api_name = 'hotfix' # fix for docs_parser.py issue if self.session: self.session.logout() diff --git a/synology_api/cloud_sync.py b/synology_api/cloud_sync.py index bb95f033..1c90ba07 100644 --- a/synology_api/cloud_sync.py +++ b/synology_api/cloud_sync.py @@ -1,3 +1,9 @@ +""" +CloudSync API module. + +This module provides the CloudSync class, which implements methods to interact with Synology's Cloud Sync API. +It allows retrieving and setting package settings, managing cloud connections and tasks, and handling synchronization processes. +""" from __future__ import annotations from typing import Any from . import base_api @@ -6,7 +12,8 @@ class CloudSync(base_api.BaseApi): - """Cloud Sync API implementation. + """ + Cloud Sync API implementation. This API provides the functionality to get information related to the package settings and current connections and tasks. It also provides functionalities to set most of the settings for tasks and package configuration, as well as manage the current syncing processes. @@ -45,11 +52,11 @@ class CloudSync(base_api.BaseApi): - Delete task - Validate task settings - Create S3 task - """ def get_pkg_config(self) -> dict[str, object]: - """Retrieve package settings. + """ + Retrieve package settings. Returns ------- @@ -103,7 +110,8 @@ def get_pkg_config(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_connections(self, group_by: str = 'group_by_user') -> dict[str, object]: - """Retrieve a list of current cloud connections. + """ + Retrieve a list of current cloud connections. Parameters ---------- @@ -175,7 +183,8 @@ def get_connections(self, group_by: str = 'group_by_user') -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_connection_settings(self, conn_id: int) -> dict[str, object]: - """Retrieve settings for a specific connection. + """ + Retrieve settings for a specific connection. Parameters ---------- @@ -219,7 +228,8 @@ def get_connection_settings(self, conn_id: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_connection_information(self, conn_id: int) -> dict[str, object]: - """Retrieve cloud information for a specific connection. + """ + Retrieve cloud information for a specific connection. Parameters ---------- @@ -267,7 +277,8 @@ def get_connection_information(self, conn_id: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_connection_auth(self, conn_id: int) -> dict[str, object]: - """Retrieve authentication information for a specific connection. + """ + Retrieve authentication information for a specific connection. Parameters ---------- @@ -344,7 +355,8 @@ def get_connection_logs( offset: int = 0, limit: int = 200 ) -> dict[str, object]: - """Retrieve logs for a specific connection. + """ + Retrieve logs for a specific connection. Parameters ---------- @@ -445,7 +457,8 @@ def get_connection_logs( return self.request_data(api_name, api_path, req_param) def get_tasks(self, conn_id: int) -> dict[str, object]: - """Retrieve a list of tasks related to a specific connection. + """ + Retrieve a list of tasks related to a specific connection. Parameters ---------- @@ -495,7 +508,8 @@ def get_tasks(self, conn_id: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_task_filters(self, sess_id: int) -> dict[str, object]: - """Retrieve filter information for a specific task. + """ + Retrieve filter information for a specific task. Parameters ---------- @@ -553,7 +567,8 @@ def get_task_cloud_folders( remote_folder_id: str, path: str = '/' ) -> dict[str, object]: - """Retrieve a list of children directories in the cloud for a specific task. + """ + Retrieve a list of children directories in the cloud for a specific task. Parameters ---------- @@ -622,7 +637,8 @@ def get_task_cloud_folders( return self.request_data(api_name, api_path, req_param) def get_recently_modified(self) -> dict[str, object]: - """Retrieve the 5 latest modified files and the currently syncing items. + """ + Retrieve the 5 latest modified files and the currently syncing items. Returns ------- @@ -722,7 +738,8 @@ def set_pkg_config( workers: int = 3, admin_mode: bool = True ) -> dict[str, object]: - """Set package configuration settings. + """ + Set package configuration settings. Parameters ---------- @@ -768,7 +785,8 @@ def set_pkg_config( return self.request_data(api_name, api_path, req_param) def set_relink_behavior(self, delete_from_cloud: bool) -> dict[str, object]: - """Set the relinking behavior for personal user accounts. + """ + Set the relinking behavior for personal user accounts. Warning: Miss-configuration of this action may lead to data loss. @@ -814,7 +832,8 @@ def set_connection_settings( isSSE: bool = False, part_size: int = 128 ) -> dict[str, object]: - """Set settings for a specific cloud connection. + """ + Set settings for a specific cloud connection. Parameters ---------- @@ -880,7 +899,8 @@ def set_connection_schedule( enable: bool, schedule_info: list[str] = [] ) -> dict[str, object]: - """Set the schedule for a specific connection. + """ + Set the schedule for a specific connection. Parameters ---------- @@ -951,7 +971,8 @@ def set_task_settings( no_delete_on_cloud: bool = True, convert_gd: bool = False ) -> dict[str, object]: - """Set the task settings for a specific session. + """ + Set the task settings for a specific session. Parameters ---------- @@ -1011,7 +1032,8 @@ def set_task_filters( filtered_extensions: list[str] = [], max_upload_size: int = 0 ) -> dict[str, object]: - """Set task filters for selective synchronization in a specific session. + """ + Set task filters for selective synchronization in a specific session. Parameters ---------- @@ -1061,7 +1083,8 @@ def set_task_filters( return self.request_data(api_name, api_path, req_param) def connection_pause(self, conn_id: int = -1) -> dict[str, object]: - """Pause one or all connections. + """ + Pause one or all connections. Parameters ---------- @@ -1095,7 +1118,8 @@ def connection_pause(self, conn_id: int = -1) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def connection_resume(self, conn_id: int = -1) -> dict[str, object]: - """Resume one or all connections. + """ + Resume one or all connections. Parameters ---------- @@ -1129,7 +1153,8 @@ def connection_resume(self, conn_id: int = -1) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def connection_remove(self, conn_id: int) -> dict[str, object]: - """Remove a specific connection and all associated tasks. + """ + Remove a specific connection and all associated tasks. The data will remain in both the local and remote directories. @@ -1167,7 +1192,8 @@ def task_remove( conn_id: int, sess_id: int ) -> dict[str, object]: - """Remove a specific task. + """ + Remove a specific task. The data will remain in both the local and remote directories. @@ -1215,7 +1241,8 @@ def __generate_sync_task_s3_params( filter_names: list[str] = [], server_folder_id: str = '', ) -> dict[str, Any]: - """Generate parameters for creating a sync task with S3. + """ + Generate parameters for creating a sync task with S3. Parameters ---------- @@ -1243,6 +1270,9 @@ def __generate_sync_task_s3_params( filter_names : list[str], optional List of file names to filter. Defaults to `[]`. + server_folder_id : str, optional + The unique identifier of the remote (cloud) folder to be synchronized. Defaults ``. + Returns ------- dict[str, Any] @@ -1294,7 +1324,7 @@ def __generate_sync_task_s3_params( # Merge authentication details with request parameters return merge_dicts(auth['data'], create_session_request_params) - def test_task_setting( + def create_sync_task_s3( self, conn_id: int, local_path: str, @@ -1304,8 +1334,9 @@ def test_task_setting( file_filter: list[str] = [], filter_max_upload_size: int = 0, filter_names: list[str] = [], - ) -> tuple[bool, dict[str, object] | str]: - """Test the task settings make sure they are valid. + ) -> tuple[bool, Any]: + """ + Add a new synchronization task. Parameters ---------- @@ -1335,11 +1366,17 @@ def test_task_setting( Returns ------- - tuple[bool, dict[str, object] | str] - A tuple containing a boolean indicating success, and a dictionary or string with the result. + tuple[bool, Any] + A tuple containing the result of the task creation. """ - # Generate sync task parameters - creation_params = self.generate_sync_task_s3_params( + + # Validate is connection is Amazon S3 + conn_info = self.get_connection_information(conn_id) + if conn_info['data']['type'] != 'az': + return (False, 'Connection is not Amazon S3') + + # Merge authentication details with request parameters + creation_params = self.__generate_sync_task_s3_params( conn_id, local_path, cloud_path, @@ -1349,41 +1386,53 @@ def test_task_setting( filter_max_upload_size, filter_names ) - # Prepare API request data api_name = 'SYNO.CloudSync' info = self.gen_list[api_name] - request_params = { + # Run test task setting + test_result = self.test_task_setting( + conn_id, + local_path, + cloud_path, + sync_direction, + storage_class, + file_filter, + filter_max_upload_size, + filter_names + ) + if not test_result[0]: + return (False, test_result[1]) + + create_session_request = { 'api': api_name, - 'method': 'test_task_setting', + 'method': 'create_session', 'version': info['minVersion'], - 'conn_info': creation_params + 'conn_info': creation_params, } + list_session_request = { + 'api': api_name, + 'method': 'list_sess', + 'version': info['minVersion'], + 'connection_id': conn_id + } + # Compound data + compound_data = [create_session_request, list_session_request] + # Send request and return response + return (True, self.batch_request(compound_data, method='post')) - # Send request and get result - compound_data = [request_params] - result = self.batch_request(compound_data, method='post') - - # Check if the request was successful - if result is not None and result['data']['has_fail'] == False: - # print('Task setting is valid') - return (True, result['data']) - else: - # print('Task setting is invalid') - return (False, 'Invalid task setting') - - def create_sync_task_s3( + def test_task_setting( self, conn_id: int, local_path: str, cloud_path: str, sync_direction='BIDIRECTION', storage_class='STANDARD', - filter_max_upload_size: int = 0, file_filter: list[str] = [], + filter_max_upload_size: int = 0, filter_names: list[str] = [], - ) -> tuple[bool, Any]: - """Add a new synchronization task. + ) -> tuple[bool, dict[str, object] | str]: + """ + Test the task settings make sure they are valid. Parameters ---------- @@ -1411,20 +1460,13 @@ def create_sync_task_s3( filter_names : list[str], optional List of file names to filter. Defaults to `[]`. - Returns ------- - tuple[bool, Any] - A tuple containing the result of the task creation. + tuple[bool, dict[str, object] | str] + A tuple containing a boolean indicating success, and a dictionary or string with the result. """ - - # Validate is connection is Amazon S3 - conn_info = self.get_connection_information(conn_id) - if conn_info['data']['type'] != 'az': - return (False, 'Connection is not Amazon S3') - - # Merge authentication details with request parameters - creation_params = self.__generate_sync_task_s3_params( + # Generate sync task parameters + creation_params = self.generate_sync_task_s3_params( conn_id, local_path, cloud_path, @@ -1434,36 +1476,25 @@ def create_sync_task_s3( filter_max_upload_size, filter_names ) + # Prepare API request data api_name = 'SYNO.CloudSync' info = self.gen_list[api_name] - # Run test task setting - test_result = self.test_task_setting( - conn_id, - local_path, - cloud_path, - sync_direction, - storage_class, - file_filter, - filter_max_upload_size, - filter_names - ) - if not test_result[0]: - return (False, test_result[1]) - - create_session_request = { - 'api': api_name, - 'method': 'create_session', - 'version': info['minVersion'], - 'conn_info': creation_params, - } - list_session_request = { + request_params = { 'api': api_name, - 'method': 'list_sess', + 'method': 'test_task_setting', 'version': info['minVersion'], - 'connection_id': conn_id + 'conn_info': creation_params } - # Compound data - compound_data = [create_session_request, list_session_request] - # Send request and return response - return (True, self.batch_request(compound_data, method='post')) + + # Send request and get result + compound_data = [request_params] + result = self.batch_request(compound_data, method='post') + + # Check if the request was successful + if result is not None and result['data']['has_fail'] == False: + # print('Task setting is valid') + return (True, result['data']) + else: + # print('Task setting is invalid') + return (False, 'Invalid task setting') diff --git a/synology_api/core_active_backup.py b/synology_api/core_active_backup.py index fe730dc5..21830afb 100644 --- a/synology_api/core_active_backup.py +++ b/synology_api/core_active_backup.py @@ -1,3 +1,4 @@ +"""Active Backup for Business API Implementation.""" from __future__ import annotations from . import base_api @@ -6,7 +7,8 @@ class ActiveBackupBusiness(base_api.BaseApi): - """Active Backup for Business API Implementation. + """ + Active Backup for Business API Implementation. This class provides methods to interact with the Active Backup for Business package. @@ -46,7 +48,31 @@ def __create_filter( action_type: str = "" ): """ - Create a filter dictionary based on the provided parameters. + Create a filter dictionary for API requests based on provided parameters. + + Parameters + ---------- + log_level : str, optional + Log level to filter by. Possible values: 'error', 'warning', 'information'. Defaults to "" (all). + keyword : str, optional + Keyword to filter logs or tasks. Defaults to "" (no keyword). + from_date : int, optional + Start of the time window (epoch seconds). Defaults to 0 (no lower bound). + to_date : int, optional + End of the time window (epoch seconds). Defaults to 0 (no upper bound). + task_status : str, optional + Task status to filter by. Defaults to "" (all statuses). + result_status : str, optional + Result status to filter by. Possible values: 'success', 'partial_success', 'fail', 'cancel', 'no_backup'. Defaults to "" (all). + backup_type : str, optional + Backup type to filter by. Possible values: 'vm', 'pc', 'physical_server', 'file_server', 'nas'. Defaults to "" (all). + action_type : str, optional + Action type to filter by. Possible values: 'backup', 'dedup_data', 'restore', 'migrate', 'delete_target', 'delete_version', 'delete_host', 'relink', 'create_task'. Defaults to "" (all). + + Returns + ------- + dict + Dictionary containing filter parameters for API requests. """ log_level_map = { 'error': 0, @@ -104,7 +130,8 @@ def __create_filter( return filter def get_settings(self) -> dict[str, object]: - """Get the package settings including certificate information. + """ + Get the package settings including certificate information. Returns ------- @@ -198,7 +225,8 @@ def get_settings(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def set_concurrent_devices(self, value: int) -> dict[str, object]: - """Set the maximum number of concurrent devices that can be backed up at the same time. + """ + Set the maximum number of concurrent devices that can be backed up at the same time. Note: You can run multiple concurrent backup devices, but only up to the maximum limit you set—provided that your NAS's RAM usage does not exceed its limit. @@ -239,7 +267,8 @@ def set_concurrent_devices(self, value: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def set_retention_policy_exec_time(self, hour: int, minute: int) -> dict[str, object]: - """Set the time of day when the retention policy will be executed. + """ + Set the time of day when the retention policy will be executed. Parameters ---------- @@ -247,7 +276,7 @@ def set_retention_policy_exec_time(self, hour: int, minute: int) -> dict[str, ob Hour in 24-hour format (0 - 23) when the retention policy will be executed. minute : int - Minute (0 - 59) when the retention policy will be executed + Minute (0 - 59) when the retention policy will be executed. Returns ------- @@ -283,7 +312,8 @@ def set_traffic_throttle( traffic_control: dict[str, object] = {"enable": False, "bandwidth": 0}, ip_range: list[str] = ["", ""] ) -> dict[str, object]: - """Set the global bandwidth control and IP range bandwidth control. + """ + Set the global bandwidth control and IP range bandwidth control. Note: Applies only to PC, Physical Server and NAS devices. @@ -329,6 +359,21 @@ def set_traffic_throttle( settings = [] def item(key: str, value: str) -> dict[str, str]: + """ + Create a dictionary representing a setting item. + + Parameters + ---------- + key : str + The name of the setting. + value : str + The value of the setting. + + Returns + ------- + dict[str, str] + Dictionary with 'name' and 'value' keys. + """ return {'name': key, 'value': value} if traffic_control['enable'] and traffic_control['bandwidth'] > -1: @@ -357,7 +402,8 @@ def item(key: str, value: str) -> dict[str, str]: return self.request_data(api_name, api_path, req_param) def set_use_pkg_cert(self, use_package_cert: bool) -> dict[str, object]: - """Set whether to use the self signed certificate provided by the package. + """ + Set whether to use the self signed certificate provided by the package. Parameters ---------- @@ -391,7 +437,8 @@ def set_use_pkg_cert(self, use_package_cert: bool) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def list_vm_hypervisor(self) -> dict[str, object]: - """Get a list of all configured hypervisors present in ABB. + """ + Get a list of all configured hypervisors present in ABB. Returns ------- @@ -416,7 +463,8 @@ def list_device_transfer_size( time_start: int = int(time.time() - 86400), time_end: int = int(time.time()) ) -> dict[str, object]: - """Get a list of all devices and their respective transfer size for the given time frame. + """ + Get a list of all devices and their respective transfer size for the given time frame. Parameters ---------- @@ -558,12 +606,13 @@ def list_tasks( to_date: int = 0, include_versions: bool = False, ) -> dict[str, object]: - """Get information of one or all tasks. + """ + Get information of one or all tasks. Parameters ---------- task_id : int, optional - Get information of specific task. Defaults to `-1` (all tasks) + Get information of specific task. Defaults to `-1` (all tasks). backup_type : str, optional Return only tasks matching the device type provided. Defaults to `""` (all device types). @@ -575,7 +624,6 @@ def list_tasks( - `"file_server"` - `"nas"` - Note that values are different when returned by the API. Return values mappings: @@ -823,14 +871,19 @@ def list_logs( offset: int = 0, limit: int = 200, ) -> dict[str, object]: - """Get logs from the package, tasks and devices. From `[Activities -> Log]` screen in ABB. + """ + Get logs from the package, tasks and devices. + + Notes + ----- + From `[Activities -> Log]` screen in ABB. For specific task logs `[Task List -> Details -> Log]`, specify `task_id` parameter. Parameters ---------- task_id : int, optional - Get logs of specific task. Defaults to `-1` (all logs - package/tasks/devices) + Get logs of specific task. Defaults to `-1` (all logs - package/tasks/devices). log_level : str, optional Type of logs to return. Defaults to `""` (all types). @@ -840,7 +893,6 @@ def list_logs( - `"warning"` - `"information"` - Note that values are different when returned by the API. Return values mappings: @@ -933,12 +985,13 @@ def task_history( offset: int = 0, limit: int = 200 ) -> dict[str, object]: - """Return the history of task execution. + """ + Return the history of task execution. Parameters ---------- task_id : int, optional - Get logs of specific task. Defaults to `-1` (all tasks) + Get logs of specific task. Defaults to `-1` (all tasks). status : str, optional Return only tasks matching the status provided. Defaults to `""` (all status). @@ -949,7 +1002,6 @@ def task_history( - `"fail"` - `"cancel"` - Note that values are different when returned by the API. Return values mappings: @@ -958,6 +1010,9 @@ def task_history( - `4` -> `fail` - `5` -> `cancel` + keyword : str, optional + Keyword used to filter the results. Defaults to `""`. + backup_type : str, optional Return only tasks matching the device type provided. Defaults to `""` (all device types). @@ -968,7 +1023,6 @@ def task_history( - `"file_server"` - `"nas"` - Note that values are different when returned by the API. Return values mappings: @@ -992,7 +1046,6 @@ def task_history( - `"relink"` - `"create_task"` - Note that values are different when returned by the API. Return values mappings: @@ -1006,9 +1059,6 @@ def task_history( - `2097152` -> `relink` - `268435456` -> `create_task` - keyword : str, optional - Keyword used to filter the results. Defaults to `""`. - from_date : int, optional Date from which the results will start. Format must be epoch date in seconds. Defaults to `0` (no time limit). @@ -1093,75 +1143,80 @@ def result_details( order_by: str = "log_level", direction: str = "ASC" ) -> dict[str, object]: - """Get details of a task result log. `result_id` can be retrieved from `list_logs()` function. - - Parameters - ---------- - result_id : int - ID of the result to get details from. - - limit : int, optional - Amount of results to be returned. Defaults to `500`. - - order_by : str, optional - What to order the results by. Defaults to `"log_level"`. - - Possible values: - - `"log_level"` - - `"log_time"` - - direction : str, optional - Direction of the order. Defaults to `"ASC"`. - - Possible values: - - `"ASC"` - - `"DESC"` - - Returns - ------- - dict[str, object] - Dictionary containing a list of result details. - - Examples - -------- - ```json - { - "data": { - "count": 2, - "result_detail_list": [ - { - "error_code": 0, - "log_level": 0, - "log_time": 1741897456, - "log_type": 6002, - "other_params": { - "fs_error": -65, - "os_name": "smb", - "path": "/D", - "task_id": 8 - }, - "result_detail_id": 9526, - "result_id": 592 + """ + Get details of a task result log. + + Parameters + ---------- + result_id : int + ID of the result to get details from. + + limit : int, optional + Amount of results to be returned. Defaults to `500`. + + order_by : str, optional + What to order the results by. Defaults to `"log_level"`. + + Possible values: + - `"log_level"` + - `"log_time"` + + direction : str, optional + Direction of the order. Defaults to `"ASC"`. + + Possible values: + - `"ASC"` + - `"DESC"` + + Returns + ------- + dict[str, object] + Dictionary containing a list of result details. + + Notes + ----- + `result_id` can be retrieved from `list_logs()` function. + + Examples + -------- + ```json + { + "data": { + "count": 2, + "result_detail_list": [ + { + "error_code": 0, + "log_level": 0, + "log_time": 1741897456, + "log_type": 6002, + "other_params": { + "fs_error": -65, + "os_name": "smb", + "path": "abc", + "task_id": 8 }, - { - "error_code": 0, - "log_level": 0, - "log_time": 1741897498, - "log_type": 1104, - "other_params": { - "os_name": "smb", - "path": "", - "task_id": 8, - "task_name": "SMB LAPTOP" - }, - "result_detail_id": 9527, - "result_id": 592 - } - ] - }, - "success": true - } - ``` + "result_detail_id": 9526, + "result_id": 592 + }, + { + "error_code": 0, + "log_level": 0, + "log_time": 1741897498, + "log_type": 1104, + "other_params": { + "os_name": "smb", + "path": "", + "task_id": 8, + "task_name": "SMB LAPTOP" + }, + "result_detail_id": 9527, + "result_id": 592 + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.ActiveBackup.Log' info = self.gen_list[api_name] @@ -1179,7 +1234,8 @@ def result_details( return self.request_data(api_name, api_path, req_param) def list_storage(self) -> dict[str, object]: - """Get a list of all storage devices present in ABB. + """ + Get a list of all storage devices present in ABB. Returns ------- @@ -1249,7 +1305,8 @@ def list_storage(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def backup_task_run(self, task_ids: list[int]) -> dict[str, object]: - """Trigger a backup event for the given tasks. + """ + Trigger a backup event for the given tasks. Parameters ---------- @@ -1285,7 +1342,8 @@ def backup_task_run(self, task_ids: list[int]) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def backup_task_cancel(self, task_ids: list[int]) -> dict[str, object]: - """Cancel specified ongoing task. + """ + Cancel specified ongoing task. Parameters ---------- @@ -1320,7 +1378,8 @@ def backup_task_cancel(self, task_ids: list[int]) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def backup_task_remove(self, task_ids: list[int]) -> dict[str, object]: - """Remove the given tasks from ABB. + """ + Remove the given tasks from ABB. Warning: This will remove the task and all its versions from the NAS. The backed up data will not be preserved after this operation. @@ -1357,7 +1416,8 @@ def backup_task_remove(self, task_ids: list[int]) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def backup_task_delete_versions(self, task_id: int, versions_ids: list[int]) -> dict[str, object]: - """Delete the specified versions from a task. + """ + Delete the specified versions from a task. Warning: This will remove the specified versions from the NAS. The corresponding versions data will not be preserved after this operation. diff --git a/synology_api/core_backup.py b/synology_api/core_backup.py index 81541804..7295e418 100644 --- a/synology_api/core_backup.py +++ b/synology_api/core_backup.py @@ -1,13 +1,25 @@ +"""Synology Hyper Backup API.""" from __future__ import annotations from . import base_api class Backup(base_api.BaseApi): + """Synology Hyper Backup API.""" def backup_repository_get(self, task_id: str) -> dict[str, object] | str: - ''' - Get repository information for given task. - ''' + """ + Get repository information for a given task. + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + Repository information. + """ api_name = 'SYNO.Backup.Repository' info = self.gen_list[api_name] api_path = info['path'] @@ -17,9 +29,14 @@ def backup_repository_get(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_repository_list(self) -> dict[str, object] | str: - ''' + """ Get a list of all present repositories in Hyper Backup. - ''' + + Returns + ------- + dict[str, object] or str + List of repositories. + """ api_name = 'SYNO.Backup.Repository' info = self.gen_list[api_name] api_path = info['path'] @@ -28,9 +45,14 @@ def backup_repository_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_list(self) -> dict[str, object] | str: - ''' + """ Get current restoring information and a list of present tasks in Hyper Backup. - ''' + + Returns + ------- + dict[str, object] or str + List of tasks and restoring information. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -39,9 +61,19 @@ def backup_task_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_status(self, task_id: str) -> dict[str, object] | str: - ''' - Get status and state of task. - ''' + """ + Get status and state of a task. + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + Status and state information. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -51,9 +83,19 @@ def backup_task_status(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_get(self, task_id: str) -> dict[str, object] | str: - ''' + """ Get detailed task information. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + Task information. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -63,9 +105,19 @@ def backup_task_get(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_result(self, task_id: str) -> dict[str, object] | str: - ''' + """ Get last result summary information of a task. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + Last result summary. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -76,10 +128,21 @@ def backup_task_result(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_run(self, task_id: str) -> dict[str, object] | str: - ''' + """ Run backup task for corresponding task_id. + If the task is not in backupable state, the API will return an error, usually 44xx. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -91,10 +154,21 @@ def backup_task_run(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_cancel(self, task_id: str) -> dict[str, object] | str: - ''' + """ Cancel currently running backup task. + If the task is not running, the API will return an error, usually 44xx. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -107,10 +181,21 @@ def backup_task_cancel(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_suspend(self, task_id: str) -> dict[str, object] | str: - ''' + """ Suspend currently running backup task. + If the task is not running or not yet suspendable, the API will return an error, usually 44xx. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -123,10 +208,21 @@ def backup_task_suspend(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_discard(self, task_id: str) -> dict[str, object] | str: - ''' + """ Discard currently suspended backup task. + If the task is not suspended, the request will not fail, and will fail to discard the task, leaving the task state as "Failed". - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -138,10 +234,21 @@ def backup_task_discard(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_resume(self, task_id: str) -> dict[str, object] | str: - ''' - Discard currently suspended backup task. + """ + Resume currently suspended backup task. + If the task is not suspended, the request will not fail, and will fail to resume the task, leaving the task state as "Failed". - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -153,12 +260,23 @@ def backup_task_resume(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def backup_task_remove(self, task_id_list: str) -> dict[str, object] | str: - ''' + """ Remove one or more backup tasks. + Data in destination will not be removed. It is still possible to relink the task using the original .hbk file. The API requires an array of tasks to remove, it should be passed as a string with the following format: - `task_id_list = '[29]'` || `task_id_list = '[29,15]'` - ''' + `task_id_list = '[29]'` or `task_id_list = '[29,15]'` + + Parameters + ---------- + task_id_list : str + List of task IDs as a string. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Task' info = self.gen_list[api_name] api_path = info['path'] @@ -171,10 +289,21 @@ def backup_task_remove(self, task_id_list: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def integrity_check_run(self, task_id: str) -> dict[str, object] | str: - ''' + """ Run integrity check for backup task. - If the task is running, the request will not fail, and will fail to perform the integrity check due to target is busy. - ''' + + If the task is running, the request will not fail, and will fail to perform the integrity check due to target being busy. + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Target' info = self.gen_list[api_name] api_path = info['path'] @@ -189,10 +318,21 @@ def integrity_check_run(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def integrity_check_cancel(self, task_id: str) -> dict[str, object] | str: - ''' + """ Cancel currently running integrity check for backup task. + If integrity check is not running, the API will return an error, usually 44xx. - ''' + + Parameters + ---------- + task_id : str + Task ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Backup.Target' info = self.gen_list[api_name] api_path = info['path'] @@ -203,18 +343,38 @@ def integrity_check_cancel(self, task_id: str) -> dict[str, object] | str: } return self.request_data(api_name, api_path, req_param) - def hb_logs_get(self, - limit: int = 1000, - offset: int = 0, - filter_keyword: str = '', - # filter_level: str = '', For some reason when passing filter_level, the API returns error 120. - filter_date_from: int = 0, - filter_date_to: int = 0) -> dict[str, object] | str: - ''' + def hb_logs_get( + self, + limit: int = 1000, + offset: int = 0, + filter_keyword: str = '', + # filter_level: str = '', For some reason when passing filter_level, the API returns error 120. + filter_date_from: int = 0, + filter_date_to: int = 0 + ) -> dict[str, object] | str: + """ Get Hyper Backup UI logs. `filter_date_from` and `filter_date_to` need to be passed in epoch format. - ''' + + Parameters + ---------- + limit : int, optional + Maximum number of logs to return (default is 1000). + offset : int, optional + Offset for pagination (default is 0). + filter_keyword : str, optional + Keyword to filter logs (default is ''). + filter_date_from : int, optional + Start date in epoch format (default is 0). + filter_date_to : int, optional + End date in epoch format (default is 0). + + Returns + ------- + dict[str, object] or str + Logs information. + """ api_name = 'SYNO.SDS.Backup.Client.Common.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -230,10 +390,15 @@ def hb_logs_get(self, } return self.request_data(api_name, api_path, req_param) - def vault_target_list(self) -> dict[str, object]: # Should be working now - ''' + def vault_target_list(self) -> dict[str, object]: + """ List all available targets in Vault. - ''' + + Returns + ------- + dict[str, object] + List of available targets. + """ api_name = 'SYNO.Backup.Service.VersionBackup.Target' info = self.gen_list[api_name] api_path = info['path'] @@ -242,9 +407,14 @@ def vault_target_list(self) -> dict[str, object]: # Should be working now return self.request_data(api_name, api_path, req_param) def vault_concurrency_get(self) -> dict[str, object]: - ''' - Get number of concurrent tasks allowed to run in HB Vault. Default value is 2. - ''' + """ + Get number of concurrent tasks allowed to run in HB Vault. + + Returns + ------- + dict[str, object] + Number of concurrent tasks (default is 2). + """ api_name = 'SYNO.Backup.Service.VersionBackup.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -255,9 +425,19 @@ def vault_concurrency_get(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def vault_concurrency_set(self, parallel_backup_limit: int = 2) -> dict[str, object]: - ''' - Set number of concurrent tasks allowed to run in HB Vault. Default value is 2. - ''' + """ + Set number of concurrent tasks allowed to run in HB Vault. + + Parameters + ---------- + parallel_backup_limit : int, optional + Number of concurrent tasks (default is 2). + + Returns + ------- + dict[str, object] + API response. + """ api_name = 'SYNO.Backup.Service.VersionBackup.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -269,9 +449,19 @@ def vault_concurrency_set(self, parallel_backup_limit: int = 2) -> dict[str, obj return self.request_data(api_name, api_path, req_param) def vault_target_settings_get(self, target_id: int) -> dict[str, object]: - ''' - Get settings of target. - ''' + """ + Get settings of a target. + + Parameters + ---------- + target_id : int + Target ID. + + Returns + ------- + dict[str, object] + Target settings. + """ api_name = 'SYNO.Backup.Service.VersionBackup.Target' info = self.gen_list[api_name] api_path = info['path'] @@ -283,9 +473,19 @@ def vault_target_settings_get(self, target_id: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def vault_task_statistics_get(self, task_id: int) -> dict[str, object]: - ''' - Get statistics for given task. - ''' + """ + Get statistics for a given task. + + Parameters + ---------- + task_id : int + Task ID. + + Returns + ------- + dict[str, object] + Task statistics. + """ api_name = 'SYNO.SDS.Backup.Server.Common.Statistic' info = self.gen_list[api_name] api_path = info['path'] @@ -297,13 +497,29 @@ def vault_task_statistics_get(self, task_id: int) -> dict[str, object]: } return self.request_data(api_name, api_path, req_param) - def vault_target_logs_get(self, - target_id: int, - limit: int = 1000, - offset: int = 0) -> dict[str, object]: - ''' - Get logs for given task. - ''' + def vault_target_logs_get( + self, + target_id: int, + limit: int = 1000, + offset: int = 0 + ) -> dict[str, object]: + """ + Get logs for a given target. + + Parameters + ---------- + target_id : int + Target ID. + limit : int, optional + Maximum number of logs to return (default is 1000). + offset : int, optional + Offset for pagination (default is 0). + + Returns + ------- + dict[str, object] + Logs information. + """ api_name = 'SYNO.SDS.Backup.Server.Common.Log' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/core_certificate.py b/synology_api/core_certificate.py index b648dc18..7f52dce4 100644 --- a/synology_api/core_certificate.py +++ b/synology_api/core_certificate.py @@ -1,3 +1,4 @@ +"""Synology DSM Core Certificate API Wrapper.""" from __future__ import annotations from io import BytesIO from typing import Optional @@ -10,6 +11,34 @@ class Certificate(base_api.BaseApi): + """ + Synology DSM Core Certificate API Wrapper. + + This class provides methods to interact with the Synology DSM Core Certificate API, + allowing management of SSL certificates on a Synology NAS. + + Parameters + ---------- + ip_address : str + IP address or hostname of the Synology NAS. + port : str + Port number to connect to. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). + cert_verify : bool, optional + Verify SSL certificates (default is False). + dsm_version : int, optional + DSM version (default is 7). + debug : bool, optional + Enable debug output (default is True). + otp_code : Optional[str], optional + One-time password for 2FA (default is None). + """ + def __init__(self, ip_address: str, port: str, @@ -21,6 +50,30 @@ def __init__(self, debug: bool = True, otp_code: Optional[str] = None ) -> None: + """ + Initialize the Certificate API wrapper. + + Parameters + ---------- + ip_address : str + IP address or hostname of the Synology NAS. + port : str + Port number to connect to. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). + cert_verify : bool, optional + Verify SSL certificates (default is False). + dsm_version : int, optional + DSM version (default is 7). + debug : bool, optional + Enable debug output (default is True). + otp_code : Optional[str], optional + One-time password for 2FA (default is None). + """ super(Certificate, self).__init__(ip_address, port, username, password, secure, cert_verify, dsm_version, debug, otp_code) self._debug: bool = debug @@ -30,6 +83,23 @@ def _base_certificate_methods(self, cert_id: Optional[str] = None, ids: Optional[str | list[str]] = None ) -> str | dict[str, object]: + """ + Internal method to perform basic certificate operations. + + Parameters + ---------- + method : str + The method to perform ('list', 'set', or 'delete'). + cert_id : Optional[str], optional + Certificate ID for 'set' method (default is None). + ids : Optional[str or list[str]], optional + Certificate IDs for 'delete' method (default is None). + + Returns + ------- + str or dict[str, object] + API response or error message. + """ available_method = ['list', 'set', 'delete'] if method not in available_method: # print error here @@ -55,12 +125,46 @@ def _base_certificate_methods(self, return self.request_data(api_name, api_path, req_param) def list_cert(self) -> dict[str, object]: + """ + List all certificates. + + Returns + ------- + dict[str, object] + List of certificates. + """ return self._base_certificate_methods('list') def set_default_cert(self, cert_id: str) -> dict[str, object]: + """ + Set a certificate as the default. + + Parameters + ---------- + cert_id : str + Certificate ID to set as default. + + Returns + ------- + dict[str, object] + API response. + """ return self._base_certificate_methods('set', cert_id) def delete_certificate(self, ids: str | list[str]) -> dict[str, object]: + """ + Delete one or more certificates. + + Parameters + ---------- + ids : str or list[str] + Certificate ID or list of IDs to delete. + + Returns + ------- + dict[str, object] + API response. + """ if isinstance(ids, str): ids = [ids] return self._base_certificate_methods('delete', ids=ids) @@ -73,6 +177,29 @@ def upload_cert(self, cert_id: Optional[str] = None, desc: Optional[str] = None ) -> tuple[int, dict[str, object]]: + """ + Upload a certificate to the Synology NAS. + + Parameters + ---------- + serv_key : str, optional + Path to the server key file (default is "server.key"). + ser_cert : str, optional + Path to the server certificate file (default is "server.crt"). + ca_cert : Optional[str], optional + Path to the CA certificate file (default is None). + set_as_default : bool, optional + Set as default certificate after upload (default is True). + cert_id : Optional[str], optional + Certificate ID to update (default is None). + desc : Optional[str], optional + Description for the certificate (default is None). + + Returns + ------- + tuple[int, dict[str, object]] + HTTP status code and API response. + """ api_name = 'SYNO.Core.Certificate' info = self.session.app_api_list[api_name] api_path = info['path'] @@ -114,6 +241,21 @@ def set_certificate_for_service(self, cert_id: str, service_name: str = "DSM Desktop Service", ) -> tuple[int, dict[str, object]]: + """ + Set a certificate for a specific DSM service. + + Parameters + ---------- + cert_id : str + Certificate ID to assign. + service_name : str, optional + Name of the service (default is "DSM Desktop Service"). + + Returns + ------- + tuple[int, dict[str, object]] + HTTP status code and API response. + """ api_name = 'SYNO.Core.Certificate.Service' info = self.session.app_api_list[api_name] api_path = info['path'] @@ -188,17 +330,18 @@ def set_certificate_for_service(self, return r.status_code, r.json() def export_cert(self, cert_id: str) -> Optional[BytesIO]: - """Export a certificate from the Synology NAS. + """ + Export a certificate from the Synology NAS. - Parameters - ---------- - cert_id : str - The certificate ID to export. This can be found in the list_cert() method. + Parameters + ---------- + cert_id : str + The certificate ID to export. This can be found in the list_cert() method. - Returns - ------- - Optional[BytesIO] - A BytesIO object containing the certificate archive. + Returns + ------- + Optional[BytesIO] + A BytesIO object containing the certificate archive, or None if export fails. """ api_name = "SYNO.Core.Certificate" diff --git a/synology_api/core_group.py b/synology_api/core_group.py index 0a0d13b4..952372fb 100644 --- a/synology_api/core_group.py +++ b/synology_api/core_group.py @@ -1,3 +1,11 @@ +""" +Synology Core Group API wrapper. + +This module provides a Python interface for managing groups on Synology NAS devices, +including group creation, deletion, membership management, quota and permission settings, +and bandwidth control. +""" + import json from typing import Any from . import base_api @@ -5,83 +13,97 @@ class Group(base_api.BaseApi): """ - Core Group API implementation. - - Supported methods: - - Getters: - - Get all groups - - Get group members - - Get group shares permissions - - Get group shares quota - - Get group services speed limits - - - Setters: - - Set group name/description - - Set group share permissions - - Set group share quotas - - Set group service speed limit - - - Actions: - - Create new group - - Delete groups - - Add users to a group - - Remove users from a group + Core Group API implementation for Synology NAS. + + This class provides methods to manage groups, including: + - Retrieving group information, members, permissions, quotas, and speed limits. + - Modifying group name, description, share permissions, quotas, and speed limits. + - Creating and deleting groups. + - Adding and removing users from groups. + + Methods + ------- + get_groups(offset=0, limit=-1, name_only=False) + Retrieve groups information. + get_users(group, in_group=True) + Retrieve users who are members or not members of a group. + get_speed_limits(group) + Retrieve bandwidth control settings for a group. + get_quota(group) + Retrieve quota settings for a group. + get_permissions(group) + Retrieve share permissions for a group. + set_group_info(group, new_name="", new_description="") + Change group name and/or description. + set_share_quota(group, share_quotas) + Set group quota for a given share. + set_share_permissions(group, permissions) + Set group permissions for a given share. + set_speed_limit(group, upload_limit, download_limit, protocol) + Set speed limit for a given share. + add_users(group, users) + Add users to a group. + remove_users(group, users) + Remove users from a group. + create(name, description="") + Create a new group. + delete(groups) + Delete specified groups. """ def get_groups( self, offset: int = 0, limit: int = -1, name_only: bool = False ) -> dict[str, object]: - """Retrieve groups information. - - Parameters - ---------- - offset : int, optional - The offset of the groups to retrieve. Defaults to `0`. - - limit : int, optional - The maximum number of groups to retrieve. Defaults to `-1` (all groups). - - name_only : bool, optional - If `True`, returns only group names. If `False`, returns full group information. Defaults to `False`. - - Returns - ------- - dict[str, object] - A dictionary containing the groups information. - - Examples - -------- - ```json - { - "data": { - "groups": [ - { - "description": "System default admin group", - "gid": 101, - "name": "administrators" - }, - { - "description": "System default group for Web services", - "gid": 1023, - "name": "http" - }, - { - "description": "A test group", - "gid": 65536, - "name": "Test" - }, - { - "description": "System default group", - "gid": 100, - "name": "users" - } - ], - "offset": 0, - "total": 4 - }, - "success": true - } - ``` + """ + Retrieve groups information. + + Parameters + ---------- + offset : int, optional + The offset of the groups to retrieve. Defaults to 0. + limit : int, optional + The maximum number of groups to retrieve. Defaults to -1 (all groups). + name_only : bool, optional + If True, returns only group names. If False, returns full group information. Defaults to False. + + Returns + ------- + dict[str, object] + A dictionary containing the groups information. + + Examples + -------- + ```json + { + "data": { + "groups": [ + { + "description": "System default admin group", + "gid": 101, + "name": "administrators" + }, + { + "description": "System default group for Web services", + "gid": 1023, + "name": "http" + }, + { + "description": "A test group", + "gid": 65536, + "name": "Test" + }, + { + "description": "System default group", + "gid": 100, + "name": "users" + } + ], + "offset": 0, + "total": 4 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Group" @@ -106,53 +128,50 @@ def get_groups( return self.request_data(api_name, api_path, req_param) def get_users(self, group: str, in_group: bool = True) -> dict[str, object]: - """Retrieve users members or not of a group. - - Parameters - ---------- - group : str - The group to list users from. - - in_group : bool, optional - Defaults to `True`. - - If `True`, retrieves users who are members of the specified group. - - If `False`, retrieves users who are not members of the group. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "offset": 0, - "total": 3, - "users": [ - { - "description": "System default user", - "name": "admin", - "uid": 1024 - }, - { - "description": "", - "name": "customAdmin", - "uid": 1026 - }, - { - "description": "", - "name": "test", - "uid": 1032 - } - ] - }, - "success": true - } - ``` + """ + Retrieve users who are members or not members of a group. + + Parameters + ---------- + group : str + The group to list users from. + in_group : bool, optional + If True, retrieves users who are members of the specified group. + If False, retrieves users who are not members of the group. Defaults to True. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "offset": 0, + "total": 3, + "users": [ + { + "description": "System default user", + "name": "admin", + "uid": 1024 + }, + { + "description": "", + "name": "customAdmin", + "uid": 1026 + }, + { + "description": "", + "name": "test", + "uid": 1032 + } + ] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Group.Member" info = self.core_list[api_name] @@ -167,40 +186,42 @@ def get_users(self, group: str, in_group: bool = True) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_speed_limits(self, group: str) -> dict[str, object]: - """Retrieve bandwidth control settings for a given group. - - Parameters - ---------- - group : str - The group to retrieve settings for. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "bandwidths": [ - { - "download_limit_1": 0, - "download_limit_2": 0, - "name": "group_name", - "owner_type": "local_group", - "policy": "notexist", - "protocol": "FTP", - "protocol_ui": "FTP", - "schedule_plan": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", - "upload_limit_1": 0, - "upload_limit_2": 0 - }, - ] - }, - "success": true - } + """ + Retrieve bandwidth control settings for a given group. + + Parameters + ---------- + group : str + The group to retrieve settings for. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "bandwidths": [ + { + "download_limit_1": 0, + "download_limit_2": 0, + "name": "group_name", + "owner_type": "local_group", + "policy": "notexist", + "protocol": "FTP", + "protocol_ui": "FTP", + "schedule_plan": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "upload_limit_1": 0, + "upload_limit_2": 0 + }, + ] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.BandwidthControl" info = self.core_list[api_name] @@ -214,42 +235,43 @@ def get_speed_limits(self, group: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_quota(self, group: str) -> dict[str, object]: - """Retrieve quota settings for a given group. - - Parameters - ---------- - group : str - The group to retrieve quota settings for. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "group_quota": [ - { - "deduped": false, - "quota_status": "v1", - "shares": [ - { - "description": "", - "name": "ActiveBackupforBusiness", - "quota": 1024 - } - ], - "support_share_quota": true, - "volume": "/volume3" - } - ] - }, - "success": true - } - ``` + """ + Retrieve quota settings for a given group. + + Parameters + ---------- + group : str + The group to retrieve quota settings for. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "group_quota": [ + { + "deduped": false, + "quota_status": "v1", + "shares": [ + { + "description": "", + "name": "ActiveBackupforBusiness", + "quota": 1024 + } + ], + "support_share_quota": true, + "volume": "/volume3" + } + ] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Quota" info = self.core_list[api_name] @@ -264,42 +286,43 @@ def get_quota(self, group: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_permissions(self, group: str) -> dict[str, object]: - """Retrieve share permissions for a given group. - - Parameters - ---------- - group : str - The group to list permissions for. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "shares": [ - { - "is_aclmode": true, - "is_custom": false, - "is_deny": true, - "is_mask": false, - "is_readonly": false, - "is_sync_share": false, - "is_unite_permission": false, - "is_writable": false, - "name": "ActiveBackupforBusiness", - "share_path": "/volume3/ActiveBackupforBusiness" - } - ], - "total": 1 - }, - "success": true - } - ``` + """ + Retrieve share permissions for a given group. + + Parameters + ---------- + group : str + The group to list permissions for. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "shares": [ + { + "is_aclmode": true, + "is_custom": false, + "is_deny": true, + "is_mask": false, + "is_readonly": false, + "is_sync_share": false, + "is_unite_permission": false, + "is_writable": false, + "name": "ActiveBackupforBusiness", + "share_path": "/volume3/ActiveBackupforBusiness" + } + ], + "total": 1 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -320,35 +343,34 @@ def get_permissions(self, group: str) -> dict[str, object]: def set_group_info( self, group: str, new_name: str = "", new_description: str = "" ) -> dict[str, object]: - """Change group name and/or description. - - Parameters - ---------- - group : str - The group to set information for. - - new_name : str, optional - The new name of the group. Defaults to current value. - - new_description : str, optional - The new description of the group. Defaults to current value. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "gid": 65536, - "name": "Test_mod" - }, - "success": true - } - ``` + """ + Change group name and/or description. + + Parameters + ---------- + group : str + The group to set information for. + new_name : str, optional + The new name of the group. Defaults to current value. + new_description : str, optional + The new description of the group. Defaults to current value. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "gid": 65536, + "name": "Test_mod" + }, + "success": true + } + ``` """ current_groups_info = self.groups_info() current_group = filter( @@ -377,43 +399,29 @@ def set_group_info( def set_share_quota( self, group: str, share_quotas: list[dict[str, Any]] ) -> dict[str, object]: - """Set group quota for a given share. - - Parameters - ---------- - group : str - The group to set the quota for. - - share_quotas (list[dict[str, Any]]): - The quotas to set for the group. - - Example: - ```python - [ - { - "share": "web", - "quota": 1024, # in MB - }, - { - "share": "photo", - "quota": 5120, # in MB - } - ] - ``` - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": {}, - "success": true - } - ``` + """ + Set group quota for a given share. + + Parameters + ---------- + group : str + The group to set the quota for. + share_quotas : list of dict + The quotas to set for the group. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": {}, + "success": true + } + ``` """ api_name = "SYNO.Core.Quota" info = self.core_list[api_name] @@ -430,46 +438,28 @@ def set_share_quota( def set_share_permissions( self, group: str, permissions: list[dict[str, object]] ) -> dict[str, object]: - """Set group permissions for a given share. - - Parameters - ---------- - group : str - The group to set the permissions for. - - permissions : list[dict[str, object]]: - The permissions to set for the group. - - Example: - ```python - [ - { - "name": "web", - "is_readonly": False, - "is_writable": False, - "is_deny": True - }, - { - "name": "ActiveBackupforBusiness", - "is_readonly": False, - "is_writable": True, - "is_deny": False - } - ] - ``` - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Set group permissions for a given share. + + Parameters + ---------- + group : str + The group to set the permissions for. + permissions : list of dict + The permissions to set for the group. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -491,48 +481,40 @@ def set_speed_limit( download_limit: int, protocol: str, ) -> dict[str, object]: - """Set speed limit for a given share. - - Info: Doesn't support **scheduled** speed limits, only on/off. - - Parameters - ---------- - group : str - The group to set the speed limit for. - - upload_limit : int - The maximum upload speed in KB/s. - - download_limit : int - The maximum download speed in KB/s. - - protocol : str - The protocol to set the speed limit for. - - Possible values: - - FileStation - - WebDAV - - FTP - - NetworkBackup (Rsync) - - CloudStation (Synology Drive) - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. + """ + Set speed limit for a given share. + + Parameters + ---------- + group : str + The group to set the speed limit for. + upload_limit : int + The maximum upload speed in KB/s. + download_limit : int + The maximum download speed in KB/s. + protocol : str + The protocol to set the speed limit for. Possible values: + FileStation, WebDAV, FTP, NetworkBackup (Rsync), CloudStation (Synology Drive). + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "results": [ + true + ] + }, + "success": true + } + ``` - Examples - -------- - ```json - { - "data": { - "results": [ - true - ] - }, - "success": true - } - ``` + Note: Doesn't support scheduled speed limits, only on/off. """ settings = [ { @@ -557,29 +539,29 @@ def set_speed_limit( return self.request_data(api_name, api_path, req_param) def add_users(self, group: str, users: list[str]) -> dict[str, object]: - """Add users to a group. - - Parameters - ---------- - group : str - The group to add users to. - - users : list[str] - The users to add to the group. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": {}, - "success": true - } - ``` + """ + Add users to a group. + + Parameters + ---------- + group : str + The group to add users to. + users : list of str + The users to add to the group. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": {}, + "success": true + } + ``` """ api_name = "SYNO.Core.Group.Member" info = self.core_list[api_name] @@ -595,29 +577,29 @@ def add_users(self, group: str, users: list[str]) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def remove_users(self, group: str, users: list[str]) -> dict[str, object]: - """Remove users from a group. - - Parameters - ---------- - group : str - The group to remove users from. - - users : list[str] - The users to remove from the group. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": {}, - "success": true - } - ``` + """ + Remove users from a group. + + Parameters + ---------- + group : str + The group to remove users from. + users : list of str + The users to remove from the group. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": {}, + "success": true + } + ``` """ api_name = "SYNO.Core.Group.Member" info = self.core_list[api_name] @@ -633,32 +615,32 @@ def remove_users(self, group: str, users: list[str]) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def create(self, name: str, description: str = "") -> dict[str, object]: - """Create group. - - Parameters - ---------- - name : str - Name to assign to the group. - - description : str, optional - Description to assign to the group. Defaults to empty string. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": { - "gid": 65541, - "name": "new_group" - }, - "success": true - } - ``` + """ + Create a new group. + + Parameters + ---------- + name : str + Name to assign to the group. + description : str, optional + Description to assign to the group. Defaults to empty string. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": { + "gid": 65541, + "name": "new_group" + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Group" @@ -674,26 +656,27 @@ def create(self, name: str, description: str = "") -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def delete(self, groups: list[str]) -> dict[str, object]: - """Delete specified groups. - - Parameters - ---------- - groups : list[str] - The groups to delete. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the request. - - Examples - -------- - ```json - { - "data": {}, - "success": true - } - ``` + """ + Delete specified groups. + + Parameters + ---------- + groups : list of str + The groups to delete. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the request. + + Examples + -------- + ```json + { + "data": {}, + "success": true + } + ``` """ api_name = "SYNO.Core.Group" info = self.core_list[api_name] diff --git a/synology_api/core_package.py b/synology_api/core_package.py index 2582d7e1..acc2a47f 100644 --- a/synology_api/core_package.py +++ b/synology_api/core_package.py @@ -1,3 +1,10 @@ +""" +Synology Core Package API wrapper. + +This module provides a Python interface for managing packages on Synology NAS devices, +including listing, installing, upgrading, uninstalling, and configuring packages. +""" + import json from typing import List from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor @@ -10,46 +17,90 @@ class Package(base_api.BaseApi): """ - Core Package API implementation. + Core Package API implementation for Synology NAS. + + This class provides methods to manage packages, including: + - Listing installed and installable packages. + - Installing, upgrading, and uninstalling packages. + - Uploading package files. + - Configuring package center settings. + + Methods + ------- + get_package(package_id, additional) + Get information about a package. + list_installed(additional, ignore_hidden) + List installed packages. + list_installable() + List installable packages. + get_package_center_settings() + Get package center settings. + set_package_center_settings(...) + Set package center settings. + get_package_center_infos() + Get package center information. + feasibility_check_install(packages) + Check if installation is possible. + download_package(url, package_id, checksum, filesize) + Start download of a package. + get_dowload_package_status(task_id) + Get current download status of a package. + check_installation_from_download(task_id) + Get info about downloaded package file. + upload_package_file(file_path, verify, progress_bar, additional) + Upload a file for installing a package. + get_default_install_volume() + Get default install volume for packages. + check_installation(...) + Check installation of a package. + upgrade_package(...) + Upgrade an existing package. + install_package(...) + Install a package that is already downloaded. + uninstall_package(package_id) + Uninstall a package. + easy_install(package_id, volume_path, install_dependencies) + Execute an easy installation process of a package. """ def get_package(self, package_id: str, additional: List[str] = []) -> dict: - """Get infos of a package - - Parameters - ---------- - package_id : str - Package ID - additional : List[str], optional - Additional field to retrieves. Defaults to `[]` - All filed known are: - `["status","dsm_apps"]` - - Returns - ------- - dict - Informations about the package - - Examples - -------- - ```json - { - "data": { - "additional": { - "dsm_apps": " com.plexapp.plexmediaserver", - "status": "running", - "status_code": 0, - "status_description": "retrieve from status script", - "status_origin": "running" - }, - "id": "PlexMediaServer", - "name": "Plex Media Server", - "timestamp": 1739228562839, - "version": "1.41.3.9314-72009314" + """ + Get infos of a package. + + Parameters + ---------- + package_id : str + Package ID. + additional : List[str], optional + Additional field to retrieves. Defaults to `[]`. + All filed known are: + `["status","dsm_apps"]`. + + Returns + ------- + dict + Informations about the package. + + Examples + -------- + ```json + { + "data": { + "additional": { + "dsm_apps": " com.plexapp.plexmediaserver", + "status": "running", + "status_code": 0, + "status_description": "retrieve from status script", + "status_origin": "running" }, - "success": true - } - ``` + "id": "PlexMediaServer", + "name": "Plex Media Server", + "timestamp": 1739228562839, + "version": "1.41.3.9314-72009314" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package' info = self.core_list[api_name] @@ -63,45 +114,47 @@ def get_package(self, package_id: str, additional: List[str] = []) -> dict: return self.request_data(api_name, api_path, req_param) def list_installed(self, additional: list = [], ignore_hidden: bool = False) -> dict: - """List installed packages - Parameters - ---------- - additional : list[str], optional - Additional fields to retrieve. Defaults to `[]`. - All fields known are: - `["description", "description_enu", "dependent_packages", "beta", "distributor", "distributor_url", - "maintainer", "maintainer_url", "dsm_apps", "dsm_app_page", "dsm_app_launch_name","report_beta_url", - "support_center", "startable", "installed_info", "support_url", "is_uninstall_pages","install_type", - "autoupdate", "silent_upgrade", "installing_progress", "ctl_uninstall", "updated_at", "status", - "url","available_operation"]`. - ignore_hidden : bool - TODO: Write description - - Returns - ------- - dict - List of packages installed on the NAS - - Examples - -------- - ```json - { - "data": { - "packages": [ - { - "additional": { - "install_type": "" - }, - "id": "ActiveBackup-Office365", - "name": "Active Backup for Microsoft 365", - "timestamp": 1738880043640, - "version": "2.5.5-14034" - } - ] - }, - "success": true + """ + List installed packages. + + Parameters + ---------- + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: + `["description", "description_enu", "dependent_packages", "beta", "distributor", "distributor_url", + "maintainer", "maintainer_url", "dsm_apps", "dsm_app_page", "dsm_app_launch_name","report_beta_url", + "support_center", "startable", "installed_info", "support_url", "is_uninstall_pages","install_type", + "autoupdate", "silent_upgrade", "installing_progress", "ctl_uninstall", "updated_at", "status", + "url","available_operation"]`. + ignore_hidden : bool + Whether to ignore hidden packages. + + Returns + ------- + dict + List of packages installed on the NAS. + + Examples + -------- + ```json + { + "data": { + "packages": [ + { + "additional": { + "install_type": "" + }, + "id": "ActiveBackup-Office365", + "name": "Active Backup for Microsoft 365", + "timestamp": 1738880043640, + "version": "2.5.5-14034" + } } - ``` + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package' info = self.core_list[api_name] @@ -116,25 +169,27 @@ def list_installed(self, additional: list = [], ignore_hidden: bool = False) -> return self.request_data(api_name, api_path, req_param) def list_installable(self) -> dict: - """List installable packages - Returns - ------- - dict - List of beta_package, categories and packages available - - Examples - -------- - ```json - { - "data": { - "banners": [], - "beta_packages": [...], - "categories": [...], - "packages": [...] - }, - "success": true - } - ``` + """ + List installable packages. + + Returns + ------- + dict + List of beta_package, categories and packages available. + + Examples + -------- + ```json + { + "data": { + "banners": [], + "beta_packages": [...], + "categories": [...], + "packages": [...] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Server' info = self.core_list[api_name] @@ -149,51 +204,53 @@ def list_installable(self) -> dict: return self.request_data(api_name, api_path, req_param) def get_package_center_settings(self) -> dict: - """Get package center settings - Returns - ------- - dict - List settings of the Package center - - Examples - -------- - ```json - { - "data": { - "autoupdateall": false, - "autoupdateimportant": true, - "default_vol": "/volume1", - "enable_autoupdate": true, - "enable_dsm": true, - "enable_email": false, - "mailset": true, - "trust_level": 0, - "update_channel": true, - "volume_count": 2, - "volume_list": [ - { - "desc": "", - "display": "Volume 1 (Available capacity: 184.72 GB )", - "mount_point": "/volume1", - "size_free": "198336327680", - "size_total": "206158430208", - "vol_desc": "Apps", - "volume_features": [] - }, - { - "desc": "", - "display": "Volume 2 (Available capacity: 2391.14 GB )", - "mount_point": "/volume2", - "size_free": "2567467421696", - "size_total": "3623234412544", - "vol_desc": "Stockage", - "volume_features": [] - } - ] - }, - "success": true - } - ``` + """ + Get package center settings. + + Returns + ------- + dict + List settings of the Package center. + + Examples + -------- + ```json + { + "data": { + "autoupdateall": false, + "autoupdateimportant": true, + "default_vol": "/volume1", + "enable_autoupdate": true, + "enable_dsm": true, + "enable_email": false, + "mailset": true, + "trust_level": 0, + "update_channel": true, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 184.72 GB )", + "mount_point": "/volume1", + "size_free": "198336327680", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.14 GB )", + "mount_point": "/volume2", + "size_free": "2567467421696", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Setting' info = self.core_list[api_name] @@ -210,48 +267,44 @@ def set_package_center_settings(self, autoupdateall: bool, autoupdateimportant: bool, default_vol: str, update_channel: str ) -> dict: - """Set settings of the package center - Parameters - ---------- - enable_email : bool - Enable email notification - - enable_dsm : bool - Enable desktop notification - - enable_autoupdate: bool - Update packages automatically - - autoupdateall : bool - Auto update all packages - - autoupdateimportant : bool - Auto update "important" packages - - default_vol : str - Default volume for installation, all your volumes or `"no_default_vol" = Always ask me` - - udpate_channel : str - "stable" => Disable beta packages - "beta" => Enable beta packages - - Returns - ------- - dict - Return some settings - - Examples - -------- - ```json - { - "data": { - "enable_dsm": true, - "enable_email": false, - "update_channel": "stable" - }, - "success": true - } - ``` + """ + Set settings of the package center. + + Parameters + ---------- + enable_email : bool + Enable email notification. + enable_dsm : bool + Enable desktop notification. + enable_autoupdate : bool + Update packages automatically. + autoupdateall : bool + Auto update all packages. + autoupdateimportant : bool + Auto update "important" packages. + default_vol : str + Default volume for installation, all your volumes or `"no_default_vol" = Always ask me`. + update_channel : str + "stable" => Disable beta packages. + "beta" => Enable beta packages. + + Returns + ------- + dict + Return some settings. + + Examples + -------- + ```json + { + "data": { + "enable_dsm": true, + "enable_email": false, + "update_channel": "stable" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Setting' @@ -272,45 +325,47 @@ def set_package_center_settings(self, return self.request_data(api_name, api_path, req_param) def get_package_center_infos(self) -> dict: - """Get package center informations - Returns - ------- - dict - List of configs - - Examples - -------- - ```json - { - "data": { - "config": { - "auth_key": "------------------------------", - "blBetaChannel": false, - "blOtherServer": false, - "def_void": "", - "ds_build": "72806", - "ds_major": "7", - "ds_minor": "2", - "ds_timezone": "Amsterdam", - "ds_unique": "synology_r1000_723+", - "myPayBaseURL": "https://payment.synology.com", - "myds_id": "7886858", - "serial": "2260TPR7X30E6", - "success": true - }, - "prerelease": { - "agreed": true, - "success": true - }, - "term": { - "agreed_term_version": "0003", - "curr_term_version": "0003", - "success": true - } + """ + Get package center informations. + + Returns + ------- + dict + List of configs. + + Examples + -------- + ```json + { + "data": { + "config": { + "auth_key": "------------------------------", + "blBetaChannel": false, + "blOtherServer": false, + "def_void": "", + "ds_build": "72806", + "ds_major": "7", + "ds_minor": "2", + "ds_timezone": "Amsterdam", + "ds_unique": "synology_r1000_723+", + "myPayBaseURL": "https://payment.synology.com", + "myds_id": "7886858", + "serial": "2260TPR7X30E6", + "success": true }, - "success": true - } - ``` + "prerelease": { + "agreed": true, + "success": true + }, + "term": { + "agreed_term_version": "0003", + "curr_term_version": "0003", + "success": true + } + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Info' info = self.core_list[api_name] @@ -322,28 +377,29 @@ def get_package_center_infos(self) -> dict: return self.request_data(api_name, api_path, req_param) def feasibility_check_install(self, packages: List[str]) -> dict: - """Check if installation is possible - - Parameters - ---------- - packages : List[str] - List of package IDs to check for feasibility - - Returns - ------- - dict - _description_ - - Examples - -------- - ```json - { - "data": { - "template": "data" - }, - "success": true - } - ``` + """ + Check if installation is possible. + + Parameters + ---------- + packages : List[str] + List of package IDs to check for feasibility. + + Returns + ------- + dict + Feasibility check result. + + Examples + -------- + ```json + { + "data": { + "template": "data" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Setting' info = self.core_list[api_name] @@ -358,35 +414,36 @@ def feasibility_check_install(self, packages: List[str]) -> dict: return self.request_data(api_name, api_path, req_param) def download_package(self, url: str, package_id: str, checksum: str, filesize: str) -> dict: - """Start download of the package, return a taskId for check status - - Parameters - ---------- - url : str - Url that can be retrieve from package info using `get_installable` function, in the `link` field - package_id : str - Package ID that can be retrieve from package info using `get_installable` function, in the `id` field - checksum : str - Checksum that can be retrieve from package info using `get_installable` function, in the `md5` field - filesize : str - Filesize that can be retrieve from package info using `get_installable` function, in the `size` field - - Returns - ------- - dict - Retreive first progress of the download and the taskid used to check download status with `get_dowload_package_status` function - - Examples - -------- - ```json - { - "data": { - "progress": 1.0000000000000001e-05, - "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer" - }, - "success": true - } - ``` + """ + Start download of the package, return a taskId for check status. + + Parameters + ---------- + url : str + Url that can be retrieve from package info using `get_installable` function, in the `link` field. + package_id : str + Package ID that can be retrieve from package info using `get_installable` function, in the `id` field. + checksum : str + Checksum that can be retrieve from package info using `get_installable` function, in the `md5` field. + filesize : str + Filesize that can be retrieve from package info using `get_installable` function, in the `size` field. + + Returns + ------- + dict + Retrieve first progress of the download and the taskid used to check download status with `get_dowload_package_status` function. + + Examples + -------- + ```json + { + "data": { + "progress": 1.0000000000000001e-05, + "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Installation' info = self.core_list[api_name] @@ -405,40 +462,41 @@ def download_package(self, url: str, package_id: str, checksum: str, filesize: s return self.request_data(api_name, api_path, req_param) def get_dowload_package_status(self, task_id: str) -> dict: - """Get current download status of the package - - Parameters - ---------- - task_id : str - task ID retrieve from response of `download_package` function - - Returns - ------- - dict - Retrieve informations about the download, important info is the `progress` field - - Examples - -------- - ```json - { - "data": { - "beta": false, - "blqinst": false, - "finished": false, - "id": "DhcpServer", - "installing": false, - "name": "DhcpServer", - "pid": 27844, - "progress": 1.0000000000000001e-05, - "remote_link": "https://global.synologydownload.com/download/Package/spk/DhcpServer/1.0.2-0046/DhcpServer-x86_64-1.0.2-0046.spk", - "size": "1378697", - "success": true, - "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer", - "tmp_folder": "/volume1/@tmp/synopkg/download.esnnkb" - }, - "success": true - } - ``` + """ + Get current download status of the package. + + Parameters + ---------- + task_id : str + Task ID retrieved from response of `download_package` function. + + Returns + ------- + dict + Retrieve informations about the download, important info is the `progress` field. + + Examples + -------- + ```json + { + "data": { + "beta": false, + "blqinst": false, + "finished": false, + "id": "DhcpServer", + "installing": false, + "name": "DhcpServer", + "pid": 27844, + "progress": 1.0000000000000001e-05, + "remote_link": "https://global.synologydownload.com/download/Package/spk/DhcpServer/1.0.2-0046/DhcpServer-x86_64-1.0.2-0046.spk", + "size": "1378697", + "success": true, + "taskid": "@SYNOPKG_DOWNLOAD_DhcpServer", + "tmp_folder": "/volume1/@tmp/synopkg/download.esnnkb" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Installation' info = self.core_list[api_name] @@ -451,43 +509,44 @@ def get_dowload_package_status(self, task_id: str) -> dict: return self.request_data(api_name, api_path, req_param) def check_installation_from_download(self, task_id: str) -> dict: - """Get info about downloaded package file, response field is used for `check_installation` and `install_package` function - - Parameters - ---------- - task_id : str - task ID retrieve from response of `download_package` function - - Returns - ------- - dict - Retrieve information about downloaded package installation file, response field is used for `check_installation` and `install_package` function - - Examples - -------- - ```json - { - "data": { - "description": "DHCP Server turns your DiskStation into a DHCP server within LAN to assign dynamic IP addresses and manage DHCP clients.", - "distributor": "", - "dsm_apps": "SYNO.SDS.DHCP.Instance", - "filename": "/volume1/@tmp/synopkg/download.esnnkb/@SYNOPKG_DOWNLOAD_DhcpServer", - "id": "DhcpServer", - "install_on_cold_storage": false, - "install_reboot": false, - "install_type": "system", - "maintainer": "Synology Inc.", - "name": "DHCP Server", - "startable": true, - "status": "non_installed", - "status_code": 255, - "status_description": "failed to locate given package", - "status_origin": "non_installed", - "version": "1.0.2-0046" - }, - "success": true - } - ``` + """ + Get info about downloaded package file, response field is used for `check_installation` and `install_package` function. + + Parameters + ---------- + task_id : str + Task ID retrieved from response of `download_package` function. + + Returns + ------- + dict + Retrieve information about downloaded package installation file, response field is used for `check_installation` and `install_package` function. + + Examples + -------- + ```json + { + "data": { + "description": "DHCP Server turns your DiskStation into a DHCP server within LAN to assign dynamic IP addresses and manage DHCP clients.", + "distributor": "", + "dsm_apps": "SYNO.SDS.DHCP.Instance", + "filename": "/volume1/@tmp/synopkg/download.esnnkb/@SYNOPKG_DOWNLOAD_DhcpServer", + "id": "DhcpServer", + "install_on_cold_storage": false, + "install_reboot": false, + "install_type": "system", + "maintainer": "Synology Inc.", + "name": "DHCP Server", + "startable": true, + "status": "non_installed", + "status_code": 255, + "status_description": "failed to locate given package", + "status_origin": "non_installed", + "version": "1.0.2-0046" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Installation.Download' info = self.core_list[api_name] @@ -500,57 +559,58 @@ def check_installation_from_download(self, task_id: str) -> dict: return self.request_data(api_name, api_path, req_param) def upload_package_file(self, file_path: str, verify: bool = False, progress_bar: bool = True, additional: list = []) -> dict: - """Upload a file for install a package - - Parameters - ---------- - file_path : str - File path - verify : bool, optional - Use https. Defaults to `False` - progress_bar : bool, optional - Enable progress bar in the terminal. Defaults to `True` - additional : list, optional - Additional field to retrieves. Defaults to `[]` - All fields know are: - `["description","maintainer","distributor","startable","dsm_apps","status","install_reboot", - "install_type","install_on_cold_storage","break_pkgs","replace_pkgs"]`. - - Returns - ------- - dict - Informations about the uploaded file for installation - - Examples - -------- - ```json - { - "data": { - "additional": { - "break_pkgs": null, - "description": "Plex organizes all of your personal media so you can easily access and enjoy it.", - "distributor": "", - "dsm_apps": " com.plexapp.plexmediaserver", - "install_on_cold_storage": false, - "install_reboot": false, - "install_type": "", - "maintainer": "Plex Inc", - "replace_pkgs": { "Plex Media Server": "" }, - "startable": true, - "status": "running", - "status_code": 0, - "status_description": "retrieve from status script", - "status_origin": "running" - }, - "codesign_error": 4532, - "id": "PlexMediaServer", - "name": "Plex Media Server", - "task_id": "@SYNOPKG_UPLOAD_17392283048566DD3", - "version": "1.41.3.9314-72009314" + """ + Upload a file for install a package. + + Parameters + ---------- + file_path : str + File path. + verify : bool, optional + Use https. Defaults to `False`. + progress_bar : bool, optional + Enable progress bar in the terminal. Defaults to `True`. + additional : list, optional + Additional field to retrieves. Defaults to `[]`. + All fields know are: + `["description","maintainer","distributor","startable","dsm_apps","status","install_reboot", + "install_type","install_on_cold_storage","break_pkgs","replace_pkgs"]`. + + Returns + ------- + dict + Informations about the uploaded file for installation. + + Examples + -------- + ```json + { + "data": { + "additional": { + "break_pkgs": null, + "description": "Plex organizes all of your personal media so you can easily access and enjoy it.", + "distributor": "", + "dsm_apps": " com.plexapp.plexmediaserver", + "install_on_cold_storage": false, + "install_reboot": false, + "install_type": "", + "maintainer": "Plex Inc", + "replace_pkgs": { "Plex Media Server": "" }, + "startable": true, + "status": "running", + "status_code": 0, + "status_description": "retrieve from status script", + "status_origin": "running" }, - "success": true - } - ``` + "codesign_error": 4532, + "id": "PlexMediaServer", + "name": "Plex Media Server", + "task_id": "@SYNOPKG_UPLOAD_17392283048566DD3", + "version": "1.41.3.9314-72009314" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Installation' info = self.core_list[api_name] @@ -604,23 +664,24 @@ def upload_package_file(self, file_path: str, verify: bool = False, progress_bar return r.json() def get_default_install_volume(self) -> dict: - """Get default install volume for package - - Returns - ------- - dict - Return default volume, if default volume is set to `Always ask me` it return error 4501 - - Examples - -------- - ```json - { - "data": { - "default_vol": "/volume1" - }, - "success": true - } - ``` + """ + Get default install volume for package. + + Returns + ------- + dict + Return default volume, if default volume is set to `Always ask me` it return error 4501. + + Examples + -------- + ```json + { + "data": { + "default_vol": "/volume1" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Package.Setting.Volume' info = self.core_list[api_name] @@ -636,58 +697,59 @@ def check_installation(self, package_id: str, install_type: str = "", install_on_cold_storage: bool = False, blCheckDep: bool = False, replacepkgs: dict = {} ) -> dict: - """Check installation of the package on the default volume - - Parameters - ---------- - package_id : str - Id of the package to install - install_type : str, optionnal - Installation type, Defaults to `""`. TODO: Add description and possible types - install_on_cold_storage : bool, optional - Defaults to `False`. TODO: Add description - blCheckDep : bool, optional - Defaults to `False`. TODO: Add description - replacepkgs : dict, optional - Defaults to `{}`. TODO: Add description - - Returns - ------- - dict - List of usefull informations about volumes - - Examples - -------- - ```json - { - "data": { - "is_occupied": false, - "volume_count": 2, - "volume_list": [ - { - "desc": "", - "display": "Volume 1 (Available capacity: 184.52 GB )", - "mount_point": "/volume1", - "size_free": "198126022656", - "size_total": "206158430208", - "vol_desc": "vol1", - "volume_features": [] - }, - { - "desc": "", - "display": "Volume 2 (Available capacity: 2391.16 GB )", - "mount_point": "/volume2", - "size_free": "2567484923904", - "size_total": "3623234412544", - "vol_desc": "vol2", - "volume_features": [] - } - ], - "volume_path": "/volume1" - }, - "success": true, - } - ``` + """ + Check installation of the package on the default volume. + + Parameters + ---------- + package_id : str + Id of the package to install. + install_type : str, optionnal + Installation type, Defaults to `""`. TODO: Add description and possible types. + install_on_cold_storage : bool, optional + Defaults to `False`. TODO: Add description. + blCheckDep : bool, optional + Defaults to `False`. TODO: Add description. + replacepkgs : dict, optional + Defaults to `{}`. TODO: Add description. + + Returns + ------- + dict + List of usefull informations about volumes. + + Examples + -------- + ```json + { + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 184.52 GB )", + "mount_point": "/volume1", + "size_free": "198126022656", + "size_total": "206158430208", + "vol_desc": "vol1", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.16 GB )", + "mount_point": "/volume2", + "size_free": "2567484923904", + "size_total": "3623234412544", + "vol_desc": "vol2", + "volume_features": [] + } + ], + "volume_path": "/volume1" + }, + "success": true, + } + ``` """ api_name = 'SYNO.Core.Package.Installation' @@ -707,50 +769,39 @@ def check_installation(self, return self.request_data(api_name, api_path, req_param) def upgrade_package(self, task_id: str, check_codesign: bool = False, force: bool = False, installrunpackage: bool = True, extra_values: dict = {}) -> dict: - """Upgrade an existing package - - Parameters - ---------- - task_id : str - Task id of the download or the upload file - check_codesign : bool, optional - Check signature of the source code of the package (is it a Synology one). Defaults to `False` - force : bool, optional - Force installation. Defaults to `False` - installrunpackage : bool, optional - Run package after installation. Defaults to `True` - extra_values : dict, optional - Extra values due to some package installation. Defaults to `{}` - All known extra values are: - - Surveillance station - ```json - { - "chkSVS_Alias": true, - "strSVS_Alias": "cam", - "chkSVS_HTTP": true, - "strSVS_HTTP": "9900", - "chkSVS_HTTPS": true, - "strSVS_HTTPS": "9901" - } - ``` - - Returns - ------- - dict - Message and some info about installation - - Examples - -------- - ```json - { - "data": { - "message": "message", - "packageName": "Plex Media Server", - "worker_message": [] - }, - "success": true, - } - ``` + """ + Upgrade an existing package. + + Parameters + ---------- + task_id : str + Task id of the download or the upload file. + check_codesign : bool, optional + Check signature of the source code of the package (is it a Synology one). Defaults to `False`. + force : bool, optional + Force installation. Defaults to `False`. + installrunpackage : bool, optional + Run package after installation. Defaults to `True`. + extra_values : dict, optional + Extra values due to some package installation. Defaults to `{}`. + + Returns + ------- + dict + Message and some info about installation. + + Examples + -------- + ```json + { + "data": { + "message": "message", + "packageName": "Plex Media Server", + "worker_message": [] + }, + "success": true, + } + ``` """ api_name = 'SYNO.Core.Package.Installation' @@ -769,94 +820,84 @@ def upgrade_package(self, task_id: str, check_codesign: bool = False, force: boo return self.request_data(api_name, api_path, req_param) def install_package(self, package_id: str, volume_path: str, file_path: str, check_codesign: bool = True, force: bool = True, installrunpackage: bool = True, extra_values: dict = {}) -> dict: - """Install a package that is already downloaded - - Parameters - ---------- - package_id : str - Id of the package to install - volume_path : str - Volume path of the installation, can get from `check_installation` function - file_path : str - File path of the installation, can get from `check_installation_from_download` function - check_codesign : bool, optional - Check signature of the source code of the package (is it a Synology one). Defaults to `False` - force : bool, optional - Force installation. Defaults to `False` - installrunpackage : bool, optional - Run package after installation. Defaults to `True` - extra_values : dict, optional - Extra values due to some package installation. Defaults to `{}` - All known extra values are: - - Surveillance station - ```json + """ + Install a package that is already downloaded. + + Parameters + ---------- + package_id : str + Id of the package to install. + volume_path : str + Volume path of the installation, can get from `check_installation` function. + file_path : str + File path of the installation, can get from `check_installation_from_download` function. + check_codesign : bool, optional + Check signature of the source code of the package (is it a Synology one). Defaults to `False`. + force : bool, optional + Force installation. Defaults to `False`. + installrunpackage : bool, optional + Run package after installation. Defaults to `True`. + extra_values : dict, optional + Extra values due to some package installation. Defaults to `{}`. + + Returns + ------- + dict + Message and some info about installation. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ { - "chkSVS_Alias": true, - "strSVS_Alias": "cam", - "chkSVS_HTTP": true, - "strSVS_HTTP": "9900", - "chkSVS_HTTPS": true, - "strSVS_HTTPS": "9901" - } - ``` - Returns - ------- - dict - Message and some info about installation - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ - { - "api": "SYNO.Core.Package.Installation", - "data": { - "is_occupied": false, - "volume_count": 2, - "volume_list": [ - { - "desc": "", - "display": "Volume 1 (Available capacity: 185.09 GB )", - "mount_point": "/volume1", - "size_free": "198739943424", - "size_total": "206158430208", - "vol_desc": "Apps", - "volume_features": [] - }, - { - "desc": "", - "display": "Volume 2 (Available capacity: 2391.17 GB )", - "mount_point": "/volume2", - "size_free": "2567495630848", - "size_total": "3623234412544", - "vol_desc": "Stockage", - "volume_features": [] - } - ], - "volume_path": "/volume1" - }, - "method": "check", - "success": true, - "version": 1 + "api": "SYNO.Core.Package.Installation", + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 185.09 GB )", + "mount_point": "/volume1", + "size_free": "198739943424", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.17 GB )", + "mount_point": "/volume2", + "size_free": "2567495630848", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ], + "volume_path": "/volume1" }, - { - "api": "SYNO.Core.Package.Installation", - "data": { - "packageName": "Text Editor", - "worker_message": [] - }, - "method": "install", - "success": true, - "version": 1 - } - ] - }, - "success": true - } - ``` + "method": "check", + "success": true, + "version": 1 + }, + { + "api": "SYNO.Core.Package.Installation", + "data": { + "packageName": "Text Editor", + "worker_message": [] + }, + "method": "install", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` """ compound = [ { @@ -886,29 +927,30 @@ def install_package(self, package_id: str, volume_path: str, file_path: str, che return self.batch_request(compound=compound) def uninstall_package(self, package_id: str) -> dict: - """Uninstall a package - - Parameters - ---------- - package_id : str - Id of the package to uninstall - - Returns - ------- - dict - Possible message to the user - - Examples - -------- - ```json - { - "data": { - "message": "", - "worker_message": [] - }, - "success": true - } - ``` + """ + Uninstall a package. + + Parameters + ---------- + package_id : str + Id of the package to uninstall. + + Returns + ------- + dict + Possible message to the user. + + Examples + -------- + ```json + { + "data": { + "message": "", + "worker_message": [] + }, + "success": true + } + ``` """ if not self._is_package_already_installed(package_id=package_id): @@ -928,6 +970,19 @@ def uninstall_package(self, package_id: str) -> dict: return self.request_data(api_name, api_path, req_param) def _is_package_already_installed(self, package_id: str) -> bool: + """ + Check if a package is already installed. + + Parameters + ---------- + package_id : str + The ID of the package to check. + + Returns + ------- + bool + True if the package is installed, False otherwise. + """ response: dict = self.list_installed() data: dict = response.get("data") installed_packages = data.get("packages") @@ -936,75 +991,76 @@ def _is_package_already_installed(self, package_id: str) -> bool: return package_infos != None def easy_install(self, package_id: str, volume_path: str, install_dependencies: bool = True) -> dict: - """Execute an easy installation process of the package - - Parameters - ---------- - package_id : str - Package ID to install - volume_path : str - Volume path where you want to install the package - install_dependencies : bool, optional - If you want to install dependencies. Defaults to True - - Returns - ------- - dict[str, object] - Information about installation, same as install_package function - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ - { - "api": "SYNO.Core.Package.Installation", - "data": { - "is_occupied": false, - "volume_count": 2, - "volume_list": [ - { - "desc": "", - "display": "Volume 1 (Available capacity: 185.11 GB )", - "mount_point": "/volume1", - "size_free": "198759485440", - "size_total": "206158430208", - "vol_desc": "Apps", - "volume_features": [] - }, - { - "desc": "", - "display": "Volume 2 (Available capacity: 2391.17 GB )", - "mount_point": "/volume2", - "size_free": "2567495565312", - "size_total": "3623234412544", - "vol_desc": "Stockage", - "volume_features": [] - } - ], - "volume_path": "/volume1" - }, - "method": "check", - "success": true, - "version": 1 + """ + Execute an easy installation process of the package. + + Parameters + ---------- + package_id : str + Package ID to install. + volume_path : str + Volume path where you want to install the package. + install_dependencies : bool, optional + If you want to install dependencies. Defaults to True. + + Returns + ------- + dict[str, object] + Information about installation, same as install_package function. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.Core.Package.Installation", + "data": { + "is_occupied": false, + "volume_count": 2, + "volume_list": [ + { + "desc": "", + "display": "Volume 1 (Available capacity: 185.11 GB )", + "mount_point": "/volume1", + "size_free": "198759485440", + "size_total": "206158430208", + "vol_desc": "Apps", + "volume_features": [] + }, + { + "desc": "", + "display": "Volume 2 (Available capacity: 2391.17 GB )", + "mount_point": "/volume2", + "size_free": "2567495565312", + "size_total": "3623234412544", + "vol_desc": "Stockage", + "volume_features": [] + } + ], + "volume_path": "/volume1" }, - { - "api": "SYNO.Core.Package.Installation", - "data": { - "packageName": "Text Editor", - "worker_message": [] - }, - "method": "install", - "success": true, - "version": 1 - } - ] - }, - "success": true - } - ``` + "method": "check", + "success": true, + "version": 1 + }, + { + "api": "SYNO.Core.Package.Installation", + "data": { + "packageName": "Text Editor", + "worker_message": [] + }, + "method": "install", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` """ api_name = 'hotfix' # fix for docs_parser.py issue diff --git a/synology_api/core_share.py b/synology_api/core_share.py index 74ca8a16..62b0a4bb 100644 --- a/synology_api/core_share.py +++ b/synology_api/core_share.py @@ -1,50 +1,51 @@ +""" +Synology Core Share API wrapper. + +This module provides a Python interface for managing shared folders, permissions, and encryption +on Synology NAS devices. +""" + import json from typing import List, Any from . import base_api class Share(base_api.BaseApi): - """ - Core Share API implementation. - """ + """Core Share API implementation.""" def validate_set(self, name: str, vol_path: str, desc: str = "", enable_share_compress: bool = False, enable_share_cow: bool = False, enc_passwd: str = "", encryption: bool = False) -> dict: - """Validate set of parameter for a new / modified shared folder - Parameters - ---------- - name : str - Share name. - - vol_path : str - Volume path. - - desc : str, optional - Share description. Defaults to `""`. - - enable_share_compress : bool, optional - Enable share compress. Defaults to `False`. - - enable_share_cow : bool, optional - Enable share cow. Defaults to `False`. - - enc_passwd : str, optional - Encrypted password. Defaults to `""`. - - encryption : bool, optional - Enable encryption. Defaults to `False`. - - Returns - ------- - dict - Success. - - Examples - -------- - ```json - { - "success": true, - } - ``` + """ + Validate set of parameter for a new / modified shared folder. + + Parameters + ---------- + name : str + Share name. + vol_path : str + Volume path. + desc : str, optional + Share description. Defaults to `""`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enc_passwd : str, optional + Encrypted password. Defaults to `""`. + encryption : bool, optional + Enable encryption. Defaults to `False`. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true, + } + ``` """ api_name = "SYNO.Core.Share" info = self.core_list[api_name] @@ -77,46 +78,47 @@ def validate_set(self, name: str, vol_path: str, desc: str = "", enable_share_co return self.request_data(api_name, api_path, req_param, method="post") def list_folders(self, share_type: str = "all", additional: list = []) -> dict: - """List all folders informations - Parameters - ---------- - share_type : str, optional - Share type. Defaults to `all`. - - additional : list[str], optional - Additional fields to retrieve. Defaults to `[]`. - All fields known are: `[ - "hidden","encryption","is_aclmode","unite_permission","is_support_acl","is_sync_share","is_force_readonly","force_readonly_reason", - "recyclebin","is_share_moving","is_cluster_share","is_exfat_share","is_c2_share","is_cold_storage_share","is_missing_share", - "is_offline_share","support_snapshot","share_quota","enable_share_compress","enable_share_cow","enable_share_tiering", - "load_worm_attr","include_cold_storage_share","is_cold_storage_share","include_missing_share","is_missing_share", - "include_offline_share","is_offline_share","include_worm_share" - ]`. - - Returns - ------- - dict - A dictionary containing the shared folders information. - - Examples - -------- - ```json - { - "data": { - "shares": [ - { - "desc": "", - "is_usb_share": false, - "name": "test_shared_folder", - "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", - "vol_path": "/volume1" - } - ], - "total": 1 - }, - "success": true - } - ``` + """ + List all folders informations. + + Parameters + ---------- + share_type : str, optional + Share type. Defaults to `all`. + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `[ + "hidden","encryption","is_aclmode","unite_permission","is_support_acl","is_sync_share","is_force_readonly","force_readonly_reason", + "recyclebin","is_share_moving","is_cluster_share","is_exfat_share","is_c2_share","is_cold_storage_share","is_missing_share", + "is_offline_share","support_snapshot","share_quota","enable_share_compress","enable_share_cow","enable_share_tiering", + "load_worm_attr","include_cold_storage_share","is_cold_storage_share","include_missing_share","is_missing_share", + "include_offline_share","is_offline_share","include_worm_share" + ]`. + + Returns + ------- + dict + A dictionary containing the shared folders information. + + Examples + -------- + ```json + { + "data": { + "shares": [ + { + "desc": "", + "is_usb_share": false, + "name": "test_shared_folder", + "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", + "vol_path": "/volume1" + } + ], + "total": 1 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share" info = self.core_list[api_name] @@ -131,39 +133,40 @@ def list_folders(self, share_type: str = "all", additional: list = []) -> dict: return self.request_data(api_name, api_path, req_param) def get_folder(self, name: str, additional: list = []) -> dict: - """Get a folder by name - Parameters - ---------- - name : str - Share name. - - additional : list, optional - Additional fields to retrieve. Defaults to `[]`. - All fields known are: `["disable_list","disable_modify","disable_download","unite_permission","is_aclmode"]`. - - Returns - ------- - dict - A dictionary containing the shared folder information. - - Examples - -------- - ```json - { - "data": { - "desc": "", - "disable_download": false, - "disable_list": false, - "disable_modify": false, - "is_aclmode": true, - "is_usb_share": false, - "name": "test_shared_folder", - "unite_permission": false, - "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", - "vol_path": "/volume1" - }, - "success": true, - ``` + """ + Get a folder by name. + + Parameters + ---------- + name : str + Share name. + additional : list, optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `["disable_list","disable_modify","disable_download","unite_permission","is_aclmode"]`. + + Returns + ------- + dict + A dictionary containing the shared folder information. + + Examples + -------- + ```json + { + "data": { + "desc": "", + "disable_download": false, + "disable_list": false, + "disable_modify": false, + "is_aclmode": true, + "is_usb_share": false, + "name": "test_shared_folder", + "unite_permission": false, + "uuid": "18585c8d-4d74-41a1-b561-21906a7f6f14", + "vol_path": "/volume1" + }, + "success": true, + ``` """ api_name = "SYNO.Core.Share" info = self.core_list[api_name] @@ -182,57 +185,54 @@ def create_folder(self, enable_recycle_bin: bool = True, recycle_bin_admin_only: bool = True, hide_unreadable: bool = False, enable_share_cow: bool = False, enable_share_compress: bool = False, share_quota: int = 0, name_org: str = "", + encryption: bool = False, enc_passwd: str = "" ) -> dict: - """Create a new shared folder - Parameters - ---------- - name : str - Share name. - - vol_path : str - Volume path. - - desc : str, optional - Share description. Defaults to `""`. - - hidden : bool, optional - Hide share. Defaults to `False`. - - enable_recycle_bin : bool, optional - Enable recycle bin. Defaults to `True`. - - recycle_bin_admin_only : bool, optional - Recycle bin admin only. Defaults to `True`. - - hide_unreadable : bool, optional - Hide unreadable. Defaults to `False`. - - enable_share_cow : bool, optional - Enable share cow. Defaults to `False`. - - enable_share_compress : bool, optional - Enable share compress. Defaults to `False`. - - share_quota : int, optional - Share quota. Defaults to `0`. - - name_org : str, optional - Defaults to `""`. - - Returns - ------- - dict - Name of the created shared folder - - Examples - -------- - ```json - { - "data": { - "name": "test_shared_folder" - }, - "success": true, - ``` + """ + Create a new shared folder. + + Parameters + ---------- + name : str + Share name. + vol_path : str + Volume path. + desc : str, optional + Share description. Defaults to `""`. + hidden : bool, optional + Hide share. Defaults to `False`. + enable_recycle_bin : bool, optional + Enable recycle bin. Defaults to `True`. + recycle_bin_admin_only : bool, optional + Recycle bin admin only. Defaults to `True`. + hide_unreadable : bool, optional + Hide unreadable. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + share_quota : int, optional + Share quota. Defaults to `0`. + name_org : str, optional + Defaults to `""`. + encryption : bool, optional + Enable encryption. Defaults to `False`. + enc_passwd : str, optional + Encrypted password. Defaults to `""`. + + Returns + ------- + dict + Name of the created shared folder. + + Examples + -------- + ```json + { + "data": { + "name": "test_shared_folder" + }, + "success": true, + ``` """ api_name = "SYNO.Core.Share" @@ -256,6 +256,8 @@ def create_folder(self, "hidden": hidden, "hide_unreadable": hide_unreadable, "share_quota": share_quota, + "encryption": encryption, + "enc_passwd": enc_passwd, }) } # If using https don't use encryption @@ -268,25 +270,26 @@ def create_folder(self, return self.request_data(api_name, api_path, req_param, method="post") def delete_folders(self, name: List[str]) -> dict: - """Delete folder(s) by name(s) - - Parameters - ---------- - name : List[str] - Share names. - - Returns - ------- - dict - Success. - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Delete folder(s) by name(s). + + Parameters + ---------- + name : List[str] + Share names. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = "SYNO.Core.Share" info = self.core_list[api_name] @@ -305,56 +308,48 @@ def clone(self, hide_unreadable: bool = False, enable_share_cow: bool = False, enable_share_compress: bool = False, share_quota: int = 0 ) -> dict: - """Clone existing shared folder. - Parameters - ---------- - name : str - New shared folder name. - - name_org : str - Original shared folder name. - - vol_path : str - Volume path. - - desc : str, optional - Shared folder description. Defaults to `""`. - - hidden : bool, optional - Hide shared folder. Defaults to `False`. - - enable_recycle_bin : bool, optional - Enable recycle bin. Defaults to `True`. - - recycle_bin_admin_only : bool, optional - Recycle bin admin only. Defaults to `True`. - - hide_unreadable : bool, optional - Hide unreadable. Defaults to `False`. - - enable_share_cow : bool, optional - Enable share cow. Defaults to `False`. - - enable_share_compress : bool, optional - Enable share compress. Defaults to `False`. - - share_quota : int, optional - Share quota. Defaults to `0`. - - Returns - ------- - dict - Name of the created shared folder - - Examples - -------- - ```json - { - "data": { - "name": "test_shared_folder" - }, - "success": true, - ``` + """ + Clone existing shared folder. + + Parameters + ---------- + name : str + New shared folder name. + name_org : str + Original shared folder name. + vol_path : str + Volume path. + desc : str, optional + Shared folder description. Defaults to `""`. + hidden : bool, optional + Hide shared folder. Defaults to `False`. + enable_recycle_bin : bool, optional + Enable recycle bin. Defaults to `True`. + recycle_bin_admin_only : bool, optional + Recycle bin admin only. Defaults to `True`. + hide_unreadable : bool, optional + Hide unreadable. Defaults to `False`. + enable_share_cow : bool, optional + Enable share cow. Defaults to `False`. + enable_share_compress : bool, optional + Enable share compress. Defaults to `False`. + share_quota : int, optional + Share quota. Defaults to `0`. + + Returns + ------- + dict + Name of the created shared folder. + + Examples + -------- + ```json + { + "data": { + "name": "test_shared_folder" + }, + "success": true, + ``` """ api_name = "SYNO.Core.Share" info = self.core_list[api_name] @@ -390,68 +385,139 @@ def clone(self, return self.request_data(api_name, api_path, req_param, method="post") + def decrypt_folder(self, name: str, password: str) -> dict: + """ + Decrypt a given share. -class SharePermission(base_api.BaseApi): - """ - Core Share Permission API implementation. - """ - - def get_folder_permission_by_name(self, - name: str, permission_substr: str, offset: int = 0, limit: int = 50, is_unite_permission: bool = False, with_inherit: bool = False, - user_group_type: str = "local_user" - ) -> dict: - """Retrieve share permissions for a given folder filtered by permission name (sub string) Parameters ---------- name : str - The folder name to list permissions for. + The share name to decrypt. + password : str + The password to use for decrypting the share. - permission_substr : str - The substring to search for in the permissions. + Returns + ------- + dict + Success. - offset : int, optional - The offset to start at. Defaults to `0`. + Examples + -------- + ```json + { + "success": true + } + ``` + """ + api_name = "SYNO.Core.Share.Crypto" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "decrypt", + "version": info['maxVersion'], + "name": name, + } - limit : int, optional - The maximum number of results to return. Defaults to `50`. + req_param_encrypted = { + "password": password, + } + # If using https don't use encryption + if self.session._secure: + req_param.update(req_param_encrypted) + else: + encrypted_params = self.session.encrypt_params(req_param_encrypted) + req_param.update(encrypted_params) - is_unite_permission : bool, optional - Whether to return unified permissions. Defaults to `False`. + return self.request_data(api_name, api_path, req_param, method="post") - with_inherit : bool, optional - Whether to include inherited permissions. Defaults to `False`. + def encrypt_folder(self, name: str) -> dict: + """ + Encrypt a given share. - user_group_type : str, optional - The type of user group to list permissions for. Defaults to `"local_user"`. - All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + Parameters + ---------- + name : str + The share name to encrypt. Returns ------- dict - List of permission(s) on the folder + Success. Examples -------- ```json { - "data": { - "items": [ - { - "inherit": "-", - "is_admin": false, - "is_custom": false, - "is_deny": false, - "is_readonly": false, - "is_writable": false, - "name": "guest" - } - ], - "total": 1 - }, "success": true } ``` """ + api_name = "SYNO.Core.Share.Crypto" + info = self.core_list[api_name] + api_path = info["path"] + req_param = { + "method": "encrypt", + "version": info['maxVersion'], + "name": name, + } + return self.request_data(api_name, api_path, req_param, method="post") + + +class SharePermission(base_api.BaseApi): + """Core Share Permission API implementation.""" + + def get_folder_permission_by_name(self, + name: str, permission_substr: str, offset: int = 0, limit: int = 50, is_unite_permission: bool = False, with_inherit: bool = False, + user_group_type: str = "local_user" + ) -> dict: + """ + Retrieve share permissions for a given folder filtered by permission name (sub string). + + Parameters + ---------- + name : str + The folder name to list permissions for. + permission_substr : str + The substring to search for in the permissions. + offset : int, optional + The offset to start at. Defaults to `0`. + limit : int, optional + The maximum number of results to return. Defaults to `50`. + is_unite_permission : bool, optional + Whether to return unified permissions. Defaults to `False`. + with_inherit : bool, optional + Whether to include inherited permissions. Defaults to `False`. + user_group_type : str, optional + The type of user group to list permissions for. Defaults to `"local_user"`. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + + Returns + ------- + dict + List of permission(s) on the folder. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "guest" + } + ], + "total": 1 + }, + "success": true + } + ``` + """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -474,81 +540,78 @@ def get_folder_permissions(self, name: str, offset: int = 0, limit: int = 50, is_unite_permission: bool = False, with_inherit: bool = False, user_group_type: str = "local_user" ) -> dict: - """Retrieve share permissions for a given folder. - Parameters - ---------- - name : str - The folder name to list permissions for. - - offset : int, optional - The offset to start at. Defaults to `0`. - - limit : int, optional - The maximum number of results to return. Defaults to `50`. - - is_unite_permission : bool, optional - Whether to return unified permissions. Defaults to `False`. - - with_inherit : bool, optional - Whether to include inherited permissions. Defaults to `False`. - - user_group_type : str, optional - The type of user group to list permissions for. Defaults to `"local_user"`. - All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. - - Returns - ------- - dict - All permissions on the folder - - Examples - -------- - ```json - { - "data": { - "items": [ - { - "inherit": "rw", - "is_admin": true, - "is_custom": false, - "is_deny": true, - "is_readonly": false, - "is_writable": false, - "name": "admin" - }, - { - "inherit": "-", - "is_admin": false, - "is_custom": false, - "is_deny": false, - "is_readonly": false, - "is_writable": false, - "name": "guest" - }, - { - "inherit": "rw", - "is_admin": true, - "is_custom": false, - "is_deny": false, - "is_readonly": false, - "is_writable": true, - "name": "test_api" - }, - { - "inherit": "-", - "is_admin": false, - "is_custom": false, - "is_deny": false, - "is_readonly": false, - "is_writable": false, - "name": "test_test" - } - ], - "total": 5 - }, - "success": true - } - ``` + """ + Retrieve share permissions for a given folder. + + Parameters + ---------- + name : str + The folder name to list permissions for. + offset : int, optional + The offset to start at. Defaults to `0`. + limit : int, optional + The maximum number of results to return. Defaults to `50`. + is_unite_permission : bool, optional + Whether to return unified permissions. Defaults to `False`. + with_inherit : bool, optional + Whether to include inherited permissions. Defaults to `False`. + user_group_type : str, optional + The type of user group to list permissions for. Defaults to `"local_user"`. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + + Returns + ------- + dict + All permissions on the folder. + + Examples + -------- + ```json + { + "data": { + "items": [ + { + "inherit": "rw", + "is_admin": true, + "is_custom": false, + "is_deny": true, + "is_readonly": false, + "is_writable": false, + "name": "admin" + }, + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "guest" + }, + { + "inherit": "rw", + "is_admin": true, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": true, + "name": "test_api" + }, + { + "inherit": "-", + "is_admin": false, + "is_custom": false, + "is_deny": false, + "is_readonly": false, + "is_writable": false, + "name": "test_test" + } + ], + "total": 5 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -567,43 +630,31 @@ def get_folder_permissions(self, return self.request_data(api_name, api_path, req_param, method="get") def set_folder_permissions(self, name: str, user_group_type: str, permissions: List[dict[str, object]]) -> dict: - """Set folder permissions for a given folder. - Parameters - ---------- - name : str - The folder name to set permissions for. - - user_group_type : str - The type of user group to set permissions for. - All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. - - permissions : dict - The permissions to set for the folder. - Example: - ```json - [ - { - "name":"guest", - "is_readonly":false, - "is_writable":true, - "is_deny":false, - "is_custom":false - } - ] - ``` - - Returns - ------- - dict - Success - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Set folder permissions for a given folder. + + Parameters + ---------- + name : str + The folder name to set permissions for. + user_group_type : str + The type of user group to set permissions for. + All known values are: `["system", "local_user", "local_group", "ldap_user", "ldap_group"]`. + permissions : dict + The permissions to set for the folder. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -618,41 +669,43 @@ def set_folder_permissions(self, name: str, user_group_type: str, permissions: L return self.request_data(api_name, api_path, req_param, method="get") def get_local_group_permissions(self, group: str) -> dict: - """Retrieve share permissions for a given group. - Parameters - ---------- - group : str - The group to list permissions for. - - Returns - ------- - dict - Permissions of a group on Shared folders - - Examples - -------- - ```json - { - "data": { - "shares": [ - { - "is_aclmode": true, - "is_custom": false, - "is_deny": true, - "is_mask": false, - "is_readonly": false, - "is_sync_share": false, - "is_unite_permission": false, - "is_writable": false, - "name": "ActiveBackupforBusiness", - "share_path": "/volume3/ActiveBackupforBusiness" - } - ], - "total": 1 - }, - "success": true - } - ``` + """ + Retrieve share permissions for a given group. + + Parameters + ---------- + group : str + The group to list permissions for. + + Returns + ------- + dict + Permissions of a group on Shared folders. + + Examples + -------- + ```json + { + "data": { + "shares": [ + { + "is_aclmode": true, + "is_custom": false, + "is_deny": true, + "is_mask": false, + "is_readonly": false, + "is_sync_share": false, + "is_unite_permission": false, + "is_writable": false, + "name": "ActiveBackupforBusiness", + "share_path": "/volume3/ActiveBackupforBusiness" + } + ], + "total": 1 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -673,44 +726,28 @@ def get_local_group_permissions(self, group: str) -> dict: def set_local_group_permissions( self, group: str, permissions: list[dict[str, Any]] ) -> dict: - """Set group permissions for a given share. - Parameters - ---------- - group : str - The group to set the permissions for. - - permissions : list[dict[str, Any]] - The permissions to set for the group. - Example: - ``` - [ - { - "name": "web", - "is_readonly": False, - "is_writable": False, - "is_deny": True - }, - { - "name": "ActiveBackupforBusiness", - "is_readonly": False, - "is_writable": True, - "is_deny": False - } - ] - ``` - - Returns - ------- - dict - Success - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Set group permissions for a given share. + + Parameters + ---------- + group : str + The group to set the permissions for. + permissions : list[dict[str, Any]] + The permissions to set for the group. + + Returns + ------- + dict + Success. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = "SYNO.Core.Share.Permission" info = self.core_list[api_name] @@ -727,12 +764,16 @@ def set_local_group_permissions( class KeyManagerStore(base_api.BaseApi): - """ - Core Share KeyManager Store API implementation. - """ + """Core Share KeyManager Store API implementation.""" def init(self) -> dict: - """Initialize KeyManagerStore API. + """ + Initialize KeyManagerStore API. + + Returns + ------- + dict + Not implemented yet. """ raise NotImplementedError( @@ -761,6 +802,14 @@ def init(self) -> dict: return self.request_data(api_name, api_path, req_param, method="post") def verify(self) -> dict: + """ + Not implemented yet. + + Returns + ------- + dict + Not implemented yet. + """ raise NotImplementedError("This method is not implemented yet.") @@ -786,22 +835,26 @@ def verify(self) -> dict: return self.request_data(api_name, api_path, req_param, method="post") def explore(self) -> dict: - """Explore KeyManagerStore API. Get list of existing stores - Returns - ------- - dict - List of stores existing on the NAS - - Examples - -------- - ```json - { - "data": { - "stores": [] - }, - "success": true - } - ``` + """ + Explore KeyManagerStore API. + + Get list of existing stores. + + Returns + ------- + dict + List of stores existing on the NAS. + + Examples + -------- + ```json + { + "data": { + "stores": [] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share.KeyManager.Store" version = self.core_list[api_name]["minVersion"] @@ -815,27 +868,27 @@ def explore(self) -> dict: class KeyManagerAutoKey(base_api.BaseApi): - """ - Core Share KeyManager AutoKey API implementation. - """ + """Core Share KeyManager AutoKey API implementation.""" def list(self) -> dict: - """List KeyManagerStore API. - Returns - ------- - dict - List of keys in the manager - - Examples - -------- - ```json - { - "data": { - "keys": [] - }, - "success": true - } - ``` + """ + List KeyManagerStore API. + + Returns + ------- + dict + List of keys in the manager. + + Examples + -------- + ```json + { + "data": { + "keys": [] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.Share.KeyManager.AutoKey" version = self.core_list[api_name]["minVersion"] diff --git a/synology_api/core_sys_info.py b/synology_api/core_sys_info.py index 61029a55..c5b4954e 100644 --- a/synology_api/core_sys_info.py +++ b/synology_api/core_sys_info.py @@ -1,3 +1,10 @@ +""" +Synology Core System Information API wrapper. + +This module provides a Python interface for retrieving and managing system information +on Synology NAS devices, including network, hardware, service, and package status. +""" + from __future__ import annotations from typing import Optional, List from . import base_api @@ -5,8 +12,22 @@ class SysInfo(base_api.BaseApi): + """ + Core System Information API implementation for Synology NAS. + + This class provides methods to retrieve and manage system, network, hardware, + service, and package information from a Synology NAS. + """ def fileserv_smb(self) -> dict[str, object] | str: + """ + Get SMB file service status. + + Returns + ------- + dict[str, object] or str + SMB file service status. + """ api_name = 'SYNO.Core.FileServ.SMB' info = self.core_list[api_name] api_path = info['path'] @@ -15,6 +36,14 @@ def fileserv_smb(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def fileserv_afp(self) -> dict[str, object] | str: + """ + Get AFP file service status. + + Returns + ------- + dict[str, object] or str + AFP file service status. + """ api_name = 'SYNO.Core.FileServ.AFP' info = self.core_list[api_name] api_path = info['path'] @@ -23,6 +52,14 @@ def fileserv_afp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def fileserv_nfs(self) -> dict[str, object] | str: + """ + Get NFS file service status. + + Returns + ------- + dict[str, object] or str + NFS file service status. + """ api_name = 'SYNO.Core.FileServ.NFS' info = self.core_list[api_name] api_path = info['path'] @@ -31,6 +68,14 @@ def fileserv_nfs(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def fileserv_ftp(self) -> dict[str, object] | str: + """ + Get FTP file service status. + + Returns + ------- + dict[str, object] or str + FTP file service status. + """ api_name = 'SYNO.Core.FileServ.FTP' info = self.core_list[api_name] api_path = info['path'] @@ -39,6 +84,14 @@ def fileserv_ftp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def fileserv_sftp(self) -> dict[str, object] | str: + """ + Get SFTP file service status. + + Returns + ------- + dict[str, object] or str + SFTP file service status. + """ api_name = 'SYNO.Core.FileServ.FTP.SFTP' info = self.core_list[api_name] api_path = info['path'] @@ -47,6 +100,14 @@ def fileserv_sftp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_backup_info(self) -> dict[str, object] | str: + """ + Get network backup service information. + + Returns + ------- + dict[str, object] or str + Network backup service information. + """ api_name = 'SYNO.Backup.Service.NetworkBackup' info = self.gen_list[api_name] api_path = info['path'] @@ -55,6 +116,14 @@ def network_backup_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def bandwidth_control_protocol(self) -> dict[str, object] | str: + """ + Get bandwidth control protocol information. + + Returns + ------- + dict[str, object] or str + Bandwidth control protocol information. + """ api_name = 'SYNO.Core.BandwidthControl.Protocol' info = self.core_list[api_name] api_path = info['path'] @@ -64,6 +133,14 @@ def bandwidth_control_protocol(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def shared_folders_info(self) -> dict[str, object] | str: + """ + Get shared folders information. + + Returns + ------- + dict[str, object] or str + Shared folders information. + """ api_name = 'SYNO.Core.Share' info = self.core_list[api_name] api_path = info['path'] @@ -72,6 +149,14 @@ def shared_folders_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def services_status(self) -> dict[str, object] | str: + """ + Get status of core services. + + Returns + ------- + dict[str, object] or str + Status of core services. + """ api_name = 'SYNO.Core.Service' info = self.core_list[api_name] api_path = info['path'] @@ -80,6 +165,14 @@ def services_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def services_discovery(self) -> dict[str, object] | str: + """ + Get service discovery information. + + Returns + ------- + dict[str, object] or str + Service discovery information. + """ api_name = 'SYNO.Core.FileServ.ServiceDiscovery' info = self.core_list[api_name] api_path = info['path'] @@ -88,6 +181,14 @@ def services_discovery(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def file_transfer_status(self) -> dict[str, object] | str: + """ + Get file transfer status. + + Returns + ------- + dict[str, object] or str + File transfer status. + """ api_name = 'SYNO.Core.SyslogClient.FileTransfer' info = self.core_list[api_name] api_path = info['path'] @@ -96,6 +197,14 @@ def file_transfer_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_status(self) -> dict[str, object] | str: + """ + Get network status. + + Returns + ------- + dict[str, object] or str + Network status. + """ api_name = 'SYNO.Core.Network' info = self.core_list[api_name] api_path = info['path'] @@ -104,6 +213,14 @@ def network_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def web_status(self) -> dict[str, object] | str: + """ + Get DSM web status. + + Returns + ------- + dict[str, object] or str + DSM web status. + """ api_name = 'SYNO.Core.Web.DSM' info = self.core_list[api_name] api_path = info['path'] @@ -112,6 +229,14 @@ def web_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def current_connection(self) -> dict[str, object] | str: + """ + Get current connection information. + + Returns + ------- + dict[str, object] or str + Current connection information. + """ api_name = 'SYNO.Core.CurrentConnection' info = self.core_list[api_name] api_path = info['path'] @@ -120,6 +245,14 @@ def current_connection(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def bandwidth_control_status(self) -> dict[str, object] | str: + """ + Get bandwidth control status. + + Returns + ------- + dict[str, object] or str + Bandwidth control status. + """ api_name = 'SYNO.Core.BandwidthControl.Status' info = self.core_list[api_name] api_path = info['path'] @@ -128,6 +261,14 @@ def bandwidth_control_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def sys_status(self) -> dict[str, object] | str: + """ + Get system status. + + Returns + ------- + dict[str, object] or str + System status. + """ api_name = 'SYNO.Core.System.Status' info = self.core_list[api_name] api_path = info['path'] @@ -136,6 +277,14 @@ def sys_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def latest_logs(self) -> dict[str, object] | str: + """ + Get latest system logs. + + Returns + ------- + dict[str, object] or str + Latest system logs. + """ api_name = 'SYNO.Core.SyslogClient.Status' info = self.core_list[api_name] api_path = info['path'] @@ -144,6 +293,14 @@ def latest_logs(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def client_notify_settings_status(self) -> dict[str, object] | str: + """ + Get client notification settings status. + + Returns + ------- + dict[str, object] or str + Client notification settings status. + """ api_name = 'SYNO.Core.SyslogClient.Setting.Notify' info = self.core_list[api_name] api_path = info['path'] @@ -152,6 +309,14 @@ def client_notify_settings_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_security_scan_info(self) -> dict[str, object] | str: + """ + Get security scan configuration. + + Returns + ------- + dict[str, object] or str + Security scan configuration. + """ api_name = 'SYNO.Core.SecurityScan.Conf' info = self.core_list[api_name] api_path = info['path'] @@ -160,6 +325,14 @@ def get_security_scan_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_security_scan_rules(self) -> dict[str, object] | str: + """ + Get security scan rules. + + Returns + ------- + dict[str, object] or str + Security scan rules. + """ api_name = 'SYNO.Core.SecurityScan.Status' info = self.core_list[api_name] api_path = info['path'] @@ -169,6 +342,14 @@ def get_security_scan_rules(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_security_scan_status(self) -> dict[str, object] | str: + """ + Get security scan status. + + Returns + ------- + dict[str, object] or str + Security scan status. + """ api_name = 'SYNO.Core.SecurityScan.Status' info = self.core_list[api_name] api_path = info['path'] @@ -177,6 +358,14 @@ def get_security_scan_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_user_list(self) -> dict[str, object] | str: + """ + Get user list. + + Returns + ------- + dict[str, object] or str + User list. + """ api_name = 'SYNO.Core.User' info = self.core_list[api_name] api_path = info['path'] @@ -187,6 +376,14 @@ def get_user_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def quickconnect_info(self) -> dict[str, object] | str: + """ + Get QuickConnect configuration. + + Returns + ------- + dict[str, object] or str + QuickConnect configuration. + """ api_name = 'SYNO.Core.QuickConnect' info = self.core_list[api_name] api_path = info['path'] @@ -196,6 +393,14 @@ def quickconnect_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def quickconnect_permissions(self) -> dict[str, object] | str: + """ + Get QuickConnect permissions. + + Returns + ------- + dict[str, object] or str + QuickConnect permissions. + """ api_name = 'SYNO.Core.QuickConnect.Permission' info = self.core_list[api_name] api_path = info['path'] @@ -204,6 +409,14 @@ def quickconnect_permissions(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_topology(self) -> dict[str, object] | str: + """ + Get network topology. + + Returns + ------- + dict[str, object] or str + Network topology. + """ api_name = 'SYNO.Core.Network.Router.Topology' info = self.core_list[api_name] api_path = info['path'] @@ -212,6 +425,14 @@ def network_topology(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_wifi_client(self) -> dict[str, object] | str: + """ + Get WiFi client information. + + Returns + ------- + dict[str, object] or str + WiFi client information. + """ api_name = 'SYNO.Core.Network.Wifi.Client' info = self.core_list[api_name] api_path = info['path'] @@ -220,6 +441,14 @@ def network_wifi_client(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_bond(self) -> dict[str, object] | str: + """ + Get network bond information. + + Returns + ------- + dict[str, object] or str + Network bond information. + """ api_name = 'SYNO.Core.Network.Bond' info = self.core_list[api_name] api_path = info['path'] @@ -228,6 +457,14 @@ def network_bond(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_bridge(self) -> dict[str, object] | str: + """ + Get network bridge information. + + Returns + ------- + dict[str, object] or str + Network bridge information. + """ api_name = 'SYNO.Core.Network.Bridge' info = self.core_list[api_name] api_path = info['path'] @@ -236,6 +473,14 @@ def network_bridge(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_ethernet(self) -> dict[str, object] | str: + """ + Get network ethernet information. + + Returns + ------- + dict[str, object] or str + Network ethernet information. + """ api_name = 'SYNO.Core.Network.Ethernet' info = self.core_list[api_name] api_path = info['path'] @@ -244,6 +489,14 @@ def network_ethernet(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_local_bridge(self) -> dict[str, object] | str: + """ + Get local network bridge information. + + Returns + ------- + dict[str, object] or str + Local network bridge information. + """ api_name = 'SYNO.Core.Network.LocalBridge' info = self.core_list[api_name] api_path = info['path'] @@ -252,6 +505,14 @@ def network_local_bridge(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_usb_modem(self) -> dict[str, object] | str: + """ + Get USB modem information. + + Returns + ------- + dict[str, object] or str + USB modem information. + """ api_name = 'SYNO.Core.Network.USBModem' info = self.core_list[api_name] api_path = info['path'] @@ -260,6 +521,14 @@ def network_usb_modem(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_pppoe(self) -> dict[str, object] | str: + """ + Get PPPoE information. + + Returns + ------- + dict[str, object] or str + PPPoE information. + """ api_name = 'SYNO.Core.Network.PPPoE' info = self.core_list[api_name] api_path = info['path'] @@ -268,6 +537,14 @@ def network_pppoe(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_ipv6tunnel(self) -> dict[str, object] | str: + """ + Get IPv6 tunnel information. + + Returns + ------- + dict[str, object] or str + IPv6 tunnel information. + """ api_name = 'SYNO.Core.Network.IPv6Tunnel' info = self.core_list[api_name] api_path = info['path'] @@ -276,6 +553,14 @@ def network_ipv6tunnel(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_vpn_pptp(self) -> dict[str, object] | str: + """ + Get VPN PPTP information. + + Returns + ------- + dict[str, object] or str + VPN PPTP information. + """ api_name = 'SYNO.Core.Network.VPN.PPTP' info = self.core_list[api_name] api_path = info['path'] @@ -284,6 +569,14 @@ def network_vpn_pptp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_openvpn(self) -> dict[str, object] | str: + """ + Get OpenVPN information. + + Returns + ------- + dict[str, object] or str + OpenVPN information. + """ api_name = 'SYNO.Core.Network.VPN.OpenVPN' info = self.core_list[api_name] api_path = info['path'] @@ -293,6 +586,14 @@ def network_openvpn(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_vpn_l2tp(self) -> dict[str, object] | str: + """ + Get VPN L2TP information. + + Returns + ------- + dict[str, object] or str + VPN L2TP information. + """ api_name = 'SYNO.Core.Network.VPN.L2TP' info = self.core_list[api_name] api_path = info['path'] @@ -301,6 +602,14 @@ def network_vpn_l2tp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def domain_schedule(self) -> dict[str, object] | str: + """ + Get domain schedule. + + Returns + ------- + dict[str, object] or str + Domain schedule. + """ api_name = 'SYNO.Core.Directory.Domain.Schedule' info = self.core_list[api_name] api_path = info['path'] @@ -309,6 +618,14 @@ def domain_schedule(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def client_ldap(self) -> dict[str, object] | str: + """ + Get LDAP client information. + + Returns + ------- + dict[str, object] or str + LDAP client information. + """ api_name = 'SYNO.Core.Directory.LDAP' info = self.core_list[api_name] api_path = info['path'] @@ -317,6 +634,14 @@ def client_ldap(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def client_sso(self) -> dict[str, object] | str: + """ + Get SSO client information. + + Returns + ------- + dict[str, object] or str + SSO client information. + """ api_name = 'SYNO.Core.Directory.SSO' info = self.core_list[api_name] api_path = info['path'] @@ -325,6 +650,14 @@ def client_sso(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def sys_upgrade_check(self) -> dict[str, object] | str: + """ + Check for system upgrades. + + Returns + ------- + dict[str, object] or str + System upgrade check result. + """ api_name = 'SYNO.Core.Upgrade.Server' info = self.core_list[api_name] api_path = info['path'] @@ -333,6 +666,14 @@ def sys_upgrade_check(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def sys_upgrade_download(self) -> dict[str, object] | str: + """ + Get system upgrade download progress. + + Returns + ------- + dict[str, object] or str + System upgrade download progress. + """ api_name = 'SYNO.Core.Upgrade.Server.Download' info = self.core_list[api_name] api_path = info['path'] @@ -341,6 +682,14 @@ def sys_upgrade_download(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def sys_upgrade_setting(self) -> dict[str, object] | str: + """ + Get system upgrade settings. + + Returns + ------- + dict[str, object] or str + System upgrade settings. + """ api_name = 'SYNO.Core.Upgrade.Setting' info = self.core_list[api_name] api_path = info['path'] @@ -349,6 +698,14 @@ def sys_upgrade_setting(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def notification_sms_conf(self) -> dict[str, object] | str: + """ + Get SMS notification configuration. + + Returns + ------- + dict[str, object] or str + SMS notification configuration. + """ api_name = 'SYNO.Core.Notification.SMS.Conf' info = self.core_list[api_name] api_path = info['path'] @@ -357,6 +714,14 @@ def notification_sms_conf(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def notification_mail_conf(self) -> dict[str, object] | str: + """ + Get mail notification configuration. + + Returns + ------- + dict[str, object] or str + Mail notification configuration. + """ api_name = 'SYNO.Core.Notification.Mail.Conf' info = self.core_list[api_name] api_path = info['path'] @@ -365,6 +730,14 @@ def notification_mail_conf(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def notification_push_mail(self) -> dict[str, object] | str: + """ + Get push mail notification configuration. + + Returns + ------- + dict[str, object] or str + Push mail notification configuration. + """ api_name = 'SYNO.Core.Notification.Push.Mail' info = self.core_list[api_name] api_path = info['path'] @@ -373,6 +746,14 @@ def notification_push_mail(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def notification_push_conf(self) -> dict[str, object] | str: + """ + Get push notification configuration. + + Returns + ------- + dict[str, object] or str + Push notification configuration. + """ api_name = 'SYNO.Core.Notification.Push.Conf' info = self.core_list[api_name] api_path = info['path'] @@ -381,6 +762,14 @@ def notification_push_conf(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def hardware_beep_control(self) -> dict[str, object] | str: + """ + Get hardware beep control status. + + Returns + ------- + dict[str, object] or str + Hardware beep control status. + """ api_name = 'SYNO.Core.Hardware.BeepControl' info = self.core_list[api_name] api_path = info['path'] @@ -389,6 +778,14 @@ def hardware_beep_control(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def hardware_fan_speed(self) -> dict[str, object] | str: + """ + Get hardware fan speed. + + Returns + ------- + dict[str, object] or str + Hardware fan speed. + """ api_name = 'SYNO.Core.Hardware.FanSpeed' info = self.core_list[api_name] api_path = info['path'] @@ -398,6 +795,19 @@ def hardware_fan_speed(self) -> dict[str, object] | str: # coolfan , fullfan def set_fan_speed(self, fan_speed: str = 'quietfan') -> dict[str, object] | str: + """ + Set hardware fan speed. + + Parameters + ---------- + fan_speed : str, optional + Fan speed mode (e.g., 'quietfan', 'coolfan', 'fullfan'). Defaults to 'quietfan'. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Hardware.FanSpeed' info = self.core_list[api_name] api_path = info['path'] @@ -407,6 +817,19 @@ def set_fan_speed(self, fan_speed: str = 'quietfan') -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def enable_zram(self, enable_zram: bool = True) -> dict[str, object] | str: + """ + Enable or disable ZRAM. + + Parameters + ---------- + enable_zram : bool, optional + Enable ZRAM if True, disable if False. Defaults to True. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Hardware.ZRAM' info = self.core_list[api_name] api_path = info['path'] @@ -415,10 +838,26 @@ def enable_zram(self, enable_zram: bool = True) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) - def enable_power_recovery(self, - restart_auto_after_issue: bool = True, - wake_on_lan: bool = False - ) -> dict[str, object] | str: + def enable_power_recovery( + self, + restart_auto_after_issue: bool = True, + wake_on_lan: bool = False + ) -> dict[str, object] | str: + """ + Enable power recovery options. + + Parameters + ---------- + restart_auto_after_issue : bool, optional + Restart automatically after issue. Defaults to True. + wake_on_lan : bool, optional + Enable Wake-on-LAN. Defaults to False. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Hardware.PowerRecovery' info = self.core_list[api_name] api_path = info['path'] @@ -427,12 +866,32 @@ def enable_power_recovery(self, return self.request_data(api_name, api_path, req_param) - def enable_beep_control(self, - fan_fail: Optional[bool] = None, - volume_crash: Optional[bool] = None, - poweron_beep: Optional[bool] = None, - poweroff_beep: Optional[bool] = None - ) -> dict[str, object] | str: + def enable_beep_control( + self, + fan_fail: Optional[bool] = None, + volume_crash: Optional[bool] = None, + poweron_beep: Optional[bool] = None, + poweroff_beep: Optional[bool] = None + ) -> dict[str, object] | str: + """ + Enable or disable beep control options. + + Parameters + ---------- + fan_fail : bool, optional + Enable beep on fan failure. + volume_crash : bool, optional + Enable beep on volume crash. + poweron_beep : bool, optional + Enable beep on power on. + poweroff_beep : bool, optional + Enable beep on power off. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Hardware.BeepControl' info = self.core_list[api_name] api_path = info['path'] @@ -443,6 +902,19 @@ def enable_beep_control(self, return self.request_data(api_name, api_path, req_param) def set_led_control(self, led_brightness: int = 2) -> dict[str, object] | str: + """ + Set LED brightness. + + Parameters + ---------- + led_brightness : int, optional + LED brightness level. Defaults to 2. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Led.Brightness' info = self.core_list[api_name] api_path = info['path'] @@ -452,6 +924,21 @@ def set_led_control(self, led_brightness: int = 2) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def set_hibernation(self, internal_hd_idletime: int = 0, usb_idletime: int = 0) -> dict[str, object] | str: + """ + Set hibernation times. + + Parameters + ---------- + internal_hd_idletime : int, optional + Idle time for internal hard drives. Defaults to 0. + usb_idletime : int, optional + Idle time for USB devices. Defaults to 0. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.Hardware.Hibernation' info = self.core_list[api_name] api_path = info['path'] @@ -460,13 +947,35 @@ def set_hibernation(self, internal_hd_idletime: int = 0, usb_idletime: int = 0) return self.request_data(api_name, api_path, req_param) - def enable_external_ups(self, - enable: bool = False, - mode: str = 'SLAVE', - delay_time: int = 1, - snmp_auth_key_dirty: bool = False, - snmp_privacy_key_dirty: bool = False - ) -> dict[str, object] | str: + def enable_external_ups( + self, + enable: bool = False, + mode: str = 'SLAVE', + delay_time: int = 1, + snmp_auth_key_dirty: bool = False, + snmp_privacy_key_dirty: bool = False + ) -> dict[str, object] | str: + """ + Enable or configure external UPS. + + Parameters + ---------- + enable : bool, optional + Enable external UPS. Defaults to False. + mode : str, optional + UPS mode. Defaults to 'SLAVE'. + delay_time : int, optional + Delay time. Defaults to 1. + snmp_auth_key_dirty : bool, optional + SNMP auth key dirty flag. Defaults to False. + snmp_privacy_key_dirty : bool, optional + SNMP privacy key dirty flag. Defaults to False. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.ExternalDevice.UPS' info = self.core_list[api_name] api_path = info['path'] @@ -477,6 +986,14 @@ def enable_external_ups(self, return self.request_data(api_name, api_path, req_param) def get_system_info(self) -> dict[str, object] | str: + """ + Get system information. + + Returns + ------- + dict[str, object] or str + System information. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -485,6 +1002,14 @@ def get_system_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_cpu_temp(self) -> str: + """ + Get CPU temperature. + + Returns + ------- + str + CPU temperature. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -493,6 +1018,14 @@ def get_cpu_temp(self) -> str: return self.request_data(api_name, api_path, req_param)['data']['sys_temp'] def get_all_system_utilization(self) -> str: + """ + Get all system utilization statistics. + + Returns + ------- + str + System utilization statistics. + """ api_name = 'SYNO.Core.System.Utilization' info = self.core_list[api_name] api_path = info['path'] @@ -501,6 +1034,14 @@ def get_all_system_utilization(self) -> str: return self.request_data(api_name, api_path, req_param)['data'] def get_cpu_utilization(self) -> str: + """ + Get CPU utilization statistics. + + Returns + ------- + str + CPU utilization statistics. + """ api_name = 'SYNO.Core.System.Utilization' info = self.core_list[api_name] api_path = info['path'] @@ -509,6 +1050,14 @@ def get_cpu_utilization(self) -> str: return self.request_data(api_name, api_path, req_param)['data']['cpu'] def get_disk_utilization(self) -> str: + """ + Get disk utilization statistics. + + Returns + ------- + str + Disk utilization statistics. + """ api_name = 'SYNO.Core.System.Utilization' info = self.core_list[api_name] api_path = info['path'] @@ -517,6 +1066,14 @@ def get_disk_utilization(self) -> str: return self.request_data(api_name, api_path, req_param)['data']['disk'] def get_memory_utilization(self) -> str: + """ + Get memory utilization statistics. + + Returns + ------- + str + Memory utilization statistics. + """ api_name = 'SYNO.Core.System.Utilization' info = self.core_list[api_name] api_path = info['path'] @@ -525,6 +1082,19 @@ def get_memory_utilization(self) -> str: return self.request_data(api_name, api_path, req_param)['data']['memory'] def shutdown(self, version: str = None) -> dict[str, object] | str: + """ + Shutdown the system. + + Parameters + ---------- + version : str, optional + API version to use. Defaults to None. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -534,6 +1104,14 @@ def shutdown(self, version: str = None) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def reboot(self) -> dict[str, object] | str: + """ + Reboot the system. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -542,6 +1120,14 @@ def reboot(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def dsm_info(self) -> dict[str, object] | str: + """ + Get DSM information. + + Returns + ------- + dict[str, object] or str + DSM information. + """ api_name = 'SYNO.DSM.Info' info = self.gen_list[api_name] api_path = info['path'] @@ -550,6 +1136,14 @@ def dsm_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_network_info(self) -> dict[str, object] | str: + """ + Get network information. + + Returns + ------- + dict[str, object] or str + Network information. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -559,6 +1153,14 @@ def get_network_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_volume_info(self) -> dict[str, object] | str: + """ + Get volume information. + + Returns + ------- + dict[str, object] or str + Volume information. + """ api_name = 'SYNO.Core.System' info = self.core_list[api_name] api_path = info['path'] @@ -568,6 +1170,14 @@ def get_volume_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def hardware_hibernation(self) -> dict[str, object] | str: + """ + Get hardware hibernation status. + + Returns + ------- + dict[str, object] or str + Hardware hibernation status. + """ api_name = 'SYNO.Core.Hardware.Hibernation' info = self.core_list[api_name] api_path = info['path'] @@ -576,6 +1186,14 @@ def hardware_hibernation(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def hardware_ups(self) -> dict[str, object] | str: + """ + Get hardware UPS status. + + Returns + ------- + dict[str, object] or str + Hardware UPS status. + """ api_name = 'SYNO.Core.ExternalDevice.UPS' info = self.core_list[api_name] api_path = info['path'] @@ -584,6 +1202,14 @@ def hardware_ups(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def terminal_info(self) -> dict[str, object] | str: + """ + Get terminal information. + + Returns + ------- + dict[str, object] or str + Terminal information. + """ api_name = 'SYNO.Core.Terminal' info = self.core_list[api_name] api_path = info['path'] @@ -592,6 +1218,14 @@ def terminal_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def snmp_info(self) -> dict[str, object] | str: + """ + Get SNMP information. + + Returns + ------- + dict[str, object] or str + SNMP information. + """ api_name = 'SYNO.Core.SNMP' info = self.core_list[api_name] api_path = info['path'] @@ -600,6 +1234,14 @@ def snmp_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def process(self) -> dict[str, object] | str: + """ + Get system process information. + + Returns + ------- + dict[str, object] or str + System process information. + """ api_name = 'SYNO.Core.System.Process' info = self.core_list[api_name] api_path = info['path'] @@ -608,6 +1250,14 @@ def process(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def storage(self) -> dict[str, object] | str: + """ + Get storage information. + + Returns + ------- + dict[str, object] or str + Storage information. + """ api_name = 'SYNO.Storage.CGI.Storage' info = self.gen_list[api_name] api_path = info['path'] @@ -616,6 +1266,14 @@ def storage(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def external_device_storage_usb(self) -> dict[str, object] | str: + """ + Get USB storage device information. + + Returns + ------- + dict[str, object] or str + USB storage device information. + """ api_name = 'SYNO.Core.ExternalDevice.Storage.USB' info = self.gen_list[api_name] api_path = info['path'] @@ -625,6 +1283,14 @@ def external_device_storage_usb(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def external_device_storage_esata(self) -> dict[str, object] | str: + """ + Get eSATA storage device information. + + Returns + ------- + dict[str, object] or str + eSATA storage device information. + """ api_name = 'SYNO.Core.ExternalDevice.Storage.eSATA' info = self.gen_list[api_name] api_path = info['path'] @@ -634,6 +1300,14 @@ def external_device_storage_esata(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def file_index_resource(self) -> dict[str, object] | str: + """ + Get file indexing status. + + Returns + ------- + dict[str, object] or str + File indexing status. + """ api_name = 'SYNO.Finder.FileIndexing.Status' info = self.gen_list[api_name] api_path = info['path'] @@ -642,6 +1316,14 @@ def file_index_resource(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def cms_info(self) -> dict[str, object] | str: + """ + Get CMS information. + + Returns + ------- + dict[str, object] or str + CMS information. + """ api_name = 'SYNO.Core.CMS.Info' info = self.gen_list[api_name] api_path = info['path'] @@ -649,16 +1331,15 @@ def cms_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) - # TODO {'error': {'code': 2502}, 'success': False} - '''def service_port_info(self) -> dict[str, object] | str: - api_name = 'SYNO.Core.Service.PortInfo' - info = self.gen_list[api_name] - api_path = info['path'] - req_param = {'version': info['maxVersion'], 'method': 'load', 'target': ['port_forward']} - - return self.request_data(api_name, api_path, req_param)''' - def port_forwarding_rules(self) -> dict[str, object] | str: + """ + Get port forwarding rules. + + Returns + ------- + dict[str, object] or str + Port forwarding rules. + """ api_name = 'SYNO.Core.PortForwarding.Rules' info = self.gen_list[api_name] api_path = info['path'] @@ -667,6 +1348,14 @@ def port_forwarding_rules(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def port_forwarding_router_conf(self) -> dict[str, object] | str: + """ + Get port forwarding router configuration. + + Returns + ------- + dict[str, object] or str + Port forwarding router configuration. + """ api_name = 'SYNO.Core.PortForwarding.RouterConf' info = self.gen_list[api_name] api_path = info['path'] @@ -675,6 +1364,14 @@ def port_forwarding_router_conf(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def disk_list(self) -> dict[str, object] | str: + """ + Get disk list. + + Returns + ------- + dict[str, object] or str + Disk list. + """ api_name = 'SYNO.Core.Polling.Data' info = self.gen_list[api_name] api_path = info['path'] @@ -683,6 +1380,14 @@ def disk_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ddns_provider_info(self) -> dict[str, object] | str: + """ + Get DDNS provider information. + + Returns + ------- + dict[str, object] or str + DDNS provider information. + """ api_name = 'SYNO.Core.DDNS.Provider' info = self.gen_list[api_name] api_path = info['path'] @@ -691,6 +1396,14 @@ def ddns_provider_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ddns_record_info(self) -> dict[str, object] | str: + """ + Get DDNS record information. + + Returns + ------- + dict[str, object] or str + DDNS record information. + """ api_name = 'SYNO.Core.DDNS.Record' info = self.gen_list[api_name] api_path = info['path'] @@ -699,6 +1412,14 @@ def ddns_record_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ddns_external_ip(self) -> dict[str, object] | str: + """ + Get DDNS external IP. + + Returns + ------- + dict[str, object] or str + DDNS external IP. + """ api_name = 'SYNO.Core.DDNS.ExtIP' info = self.gen_list[api_name] api_path = info['path'] @@ -708,6 +1429,14 @@ def ddns_external_ip(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ddns_synology(self) -> dict[str, object] | str: + """ + Get Synology DDNS information. + + Returns + ------- + dict[str, object] or str + Synology DDNS information. + """ api_name = 'SYNO.Core.DDNS.Synology' info = self.gen_list[api_name] api_path = info['path'] @@ -717,6 +1446,14 @@ def ddns_synology(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def iscsi_lun_info(self) -> dict[str, object] | str: + """ + Get iSCSI LUN information. + + Returns + ------- + dict[str, object] or str + iSCSI LUN information. + """ api_name = 'SYNO.Core.ISCSI.LUN' info = self.gen_list[api_name] api_path = info['path'] @@ -725,6 +1462,14 @@ def iscsi_lun_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def hddman(self) -> dict[str, object] | str: + """ + Get HDD manager information. + + Returns + ------- + dict[str, object] or str + HDD manager information. + """ api_name = 'SYNO.Storage.CGI.HddMan' info = self.gen_list[api_name] api_path = info['path'] @@ -733,6 +1478,14 @@ def hddman(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ftp_security_info(self) -> dict[str, object] | str: + """ + Get FTP security information. + + Returns + ------- + dict[str, object] or str + FTP security information. + """ api_name = 'SYNO.Core.FileServ.FTP.Security' info = self.core_list[api_name] api_path = info['path'] @@ -741,6 +1494,14 @@ def ftp_security_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def bandwidth_control_info(self) -> dict[str, object] | str: + """ + Get bandwidth control information. + + Returns + ------- + dict[str, object] or str + Bandwidth control information. + """ api_name = 'SYNO.Core.BandwidthControl.Protocol' info = self.core_list[api_name] api_path = info['path'] @@ -749,7 +1510,15 @@ def bandwidth_control_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) - def directory_domain_info(self) -> dict[str, object] | str: # TODO to test + def directory_domain_info(self) -> dict[str, object] | str: + """ + Get directory domain information. + + Returns + ------- + dict[str, object] or str + Directory domain information. + """ api_name = 'SYNO.Core.Directory.Domain' info = self.core_list[api_name] api_path = info['path'] @@ -757,7 +1526,15 @@ def directory_domain_info(self) -> dict[str, object] | str: # TODO to test return self.request_data(api_name, api_path, req_param) - def ws_transfer_info(self) -> dict[str, object] | str: # TODO to test + def ws_transfer_info(self) -> dict[str, object] | str: + """ + Get WS transfer information. + + Returns + ------- + dict[str, object] or str + WS transfer information. + """ api_name = 'SYNO.Core.FileServ.ServiceDiscovery.WSTransfer' info = self.core_list[api_name] api_path = info['path'] @@ -766,6 +1543,14 @@ def ws_transfer_info(self) -> dict[str, object] | str: # TODO to test return self.request_data(api_name, api_path, req_param) def ref_link_copy_info(self) -> dict[str, object] | str: + """ + Get reflink copy information. + + Returns + ------- + dict[str, object] or str + Reflink copy information. + """ api_name = 'SYNO.Core.FileServ.ReflinkCopy' info = self.core_list[api_name] api_path = info['path'] @@ -774,6 +1559,14 @@ def ref_link_copy_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def bonjour_service_info(self) -> dict[str, object] | str: + """ + Get Bonjour service information. + + Returns + ------- + dict[str, object] or str + Bonjour service information. + """ api_name = 'SYNO.Core.ExternalDevice.Printer.BonjourSharing' info = self.core_list[api_name] api_path = info['path'] @@ -782,6 +1575,14 @@ def bonjour_service_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def personal_photo_enable(self) -> dict[str, object] | str: + """ + Get personal photo enable status. + + Returns + ------- + dict[str, object] or str + Personal photo enable status. + """ api_name = 'SYNO.Core.User.Home' info = self.core_list[api_name] api_path = info['path'] @@ -790,6 +1591,14 @@ def personal_photo_enable(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def ftp_chroot_user(self) -> dict[str, object] | str: + """ + Get FTP chroot user information. + + Returns + ------- + dict[str, object] or str + FTP chroot user information. + """ api_name = 'SYNO.Core.FileServ.FTP.ChrootUser' info = self.core_list[api_name] api_path = info['path'] @@ -798,6 +1607,14 @@ def ftp_chroot_user(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def server_pair(self) -> dict[str, object] | str: + """ + Get server pair information. + + Returns + ------- + dict[str, object] or str + Server pair information. + """ api_name = 'SYNO.S2S.Server.Pair' info = self.gen_list[api_name] api_path = info['path'] @@ -807,6 +1624,23 @@ def server_pair(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def groups_info(self, offset: int = 0, limit: int = -1, name_only: bool = False) -> dict[str, object] | str: + """ + Get groups information. + + Parameters + ---------- + offset : int, optional + Offset for pagination. Defaults to 0. + limit : int, optional + Maximum number of groups to retrieve. Defaults to -1. + name_only : bool, optional + If True, returns only group names. Defaults to False. + + Returns + ------- + dict[str, object] or str + Groups information. + """ api_name = 'SYNO.Core.Group' info = self.core_list[api_name] api_path = info['path'] @@ -823,6 +1657,14 @@ def groups_info(self, offset: int = 0, limit: int = -1, name_only: bool = False) return self.request_data(api_name, api_path, req_param) def ldap_info(self) -> dict[str, object] | str: + """ + Get LDAP information. + + Returns + ------- + dict[str, object] or str + LDAP information. + """ api_name = 'SYNO.Core.Directory.LDAP' info = self.core_list[api_name] api_path = info['path'] @@ -840,6 +1682,14 @@ def ldap_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param)''' def sso_iwa_info(self) -> dict[str, object] | str: + """ + Get SSO IWA information. + + Returns + ------- + dict[str, object] or str + SSO IWA information. + """ api_name = 'SYNO.Core.Directory.SSO.IWA' info = self.core_list[api_name] api_path = info['path'] @@ -848,6 +1698,14 @@ def sso_iwa_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def sso_info(self) -> dict[str, object] | str: + """ + Get SSO information. + + Returns + ------- + dict[str, object] or str + SSO information. + """ api_name = 'SYNO.Core.Directory.SSO' info = self.core_list[api_name] api_path = info['path'] @@ -856,6 +1714,14 @@ def sso_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_interface_info(self) -> dict[str, object] | str: + """ + Get network interface information. + + Returns + ------- + dict[str, object] or str + Network interface information. + """ api_name = 'SYNO.Core.Network.Interface' info = self.core_list[api_name] api_path = info['path'] @@ -864,6 +1730,14 @@ def network_interface_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def proxy_info(self) -> dict[str, object] | str: + """ + Get proxy information. + + Returns + ------- + dict[str, object] or str + Proxy information. + """ api_name = 'SYNO.Core.Network.Proxy' info = self.core_list[api_name] api_path = info['path'] @@ -872,6 +1746,21 @@ def proxy_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def gateway_list(self, ip_type: str = 'ipv4', type: str = 'wan') -> dict[str, object] | str: + """ + Get gateway list. + + Parameters + ---------- + ip_type : str, optional + IP type (e.g., 'ipv4', 'ipv6'). Defaults to 'ipv4'. + type : str, optional + Gateway type (e.g., 'wan'). Defaults to 'wan'. + + Returns + ------- + dict[str, object] or str + Gateway list. + """ api_name = 'SYNO.Core.Network.Router.Gateway.List' info = self.core_list[api_name] api_path = info['path'] @@ -881,6 +1770,14 @@ def gateway_list(self, ip_type: str = 'ipv4', type: str = 'wan') -> dict[str, ob return self.request_data(api_name, api_path, req_param) def firewall_info(self) -> dict[str, object] | str: + """ + Get firewall information. + + Returns + ------- + dict[str, object] or str + Firewall information. + """ api_name = 'SYNO.Core.Security.Firewall.Profile' info = self.core_list[api_name] api_path = info['path'] @@ -901,6 +1798,14 @@ def firewall_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param)''' def auto_upgrade_status(self) -> dict[str, object] | str: + """ + Get auto upgrade status. + + Returns + ------- + dict[str, object] or str + Auto upgrade status. + """ api_name = 'SYNO.Core.Upgrade.AutoUpgrade' info = self.core_list[api_name] api_path = info['path'] @@ -909,6 +1814,14 @@ def auto_upgrade_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def upgrade_server_check(self) -> dict[str, object] | str: + """ + Check upgrade server. + + Returns + ------- + dict[str, object] or str + Upgrade server check result. + """ api_name = 'SYNO.Core.Upgrade.Server' info = self.core_list[api_name] api_path = info['path'] @@ -918,6 +1831,14 @@ def upgrade_server_check(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def alarm_rules_logs(self) -> dict[str, object] | str: + """ + Get alarm rules logs. + + Returns + ------- + dict[str, object] or str + Alarm rules logs. + """ api_name = 'SYNO.ResourceMonitor.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -927,6 +1848,14 @@ def alarm_rules_logs(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def alarm_rules_list(self) -> dict[str, object] | str: + """ + Get alarm rules list. + + Returns + ------- + dict[str, object] or str + Alarm rules list. + """ api_name = 'SYNO.ResourceMonitor.EventRule' info = self.gen_list[api_name] api_path = info['path'] @@ -935,6 +1864,14 @@ def alarm_rules_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def resource_monitor_settings_list(self) -> dict[str, object] | str: + """ + Get resource monitor settings. + + Returns + ------- + dict[str, object] or str + Resource monitor settings. + """ api_name = 'SYNO.ResourceMonitor.Setting' info = self.gen_list[api_name] api_path = info['path'] @@ -944,6 +1881,25 @@ def resource_monitor_settings_list(self) -> dict[str, object] | str: def file_handling_access(self, sort_direction: str = 'ASC', sort_by: str = 'service', limit: int = 50, offset: int = 0) -> dict[str, object] | str: + """ + Get file handling access information. + + Parameters + ---------- + sort_direction : str, optional + Sort direction ('ASC' or 'DESC'). Defaults to 'ASC'. + sort_by : str, optional + Field to sort by. Defaults to 'service'. + limit : int, optional + Maximum number of results. Defaults to 50. + offset : int, optional + Offset for pagination. Defaults to 0. + + Returns + ------- + dict[str, object] or str + File handling access information. + """ api_name = 'SYNO.Core.FileHandle' info = self.core_list[api_name] api_path = info['path'] @@ -953,6 +1909,19 @@ def file_handling_access(self, sort_direction: str = 'ASC', sort_by: str = 'serv return self.request_data(api_name, api_path, req_param) def list_service_group(self, interval=0) -> dict[str, object] | str: + """ + Get service group list. + + Parameters + ---------- + interval : int, optional + Interval for statistics. Defaults to 0. + + Returns + ------- + dict[str, object] or str + Service group list. + """ api_name = 'SYNO.Core.System.ProcessGroup' info = self.core_list[api_name] api_path = info['path'] @@ -962,6 +1931,14 @@ def list_service_group(self, interval=0) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def list_process_group(self) -> dict[str, object] | str: + """ + Get process group list. + + Returns + ------- + dict[str, object] or str + Process group list. + """ api_name = 'SYNO.Core.System.Process' info = self.core_list[api_name] api_path = info['path'] @@ -970,6 +1947,14 @@ def list_process_group(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def installed_package_list(self) -> dict[str, object] | str: + """ + Get installed package list. + + Returns + ------- + dict[str, object] or str + Installed package list. + """ api_name = 'SYNO.Core.Package' info = self.core_list[api_name] api_path = info['path'] @@ -988,6 +1973,14 @@ def installed_package_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def active_notifications(self) -> dict[str, object] | str: + """ + Get active notifications. + + Returns + ------- + dict[str, object] or str + Active notifications. + """ api_name = 'SYNO.Core.DSMNotify' info = self.core_list[api_name] api_path = info['path'] @@ -997,6 +1990,14 @@ def active_notifications(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_system_health(self) -> dict[str, object] | str: + """ + Get system health information. + + Returns + ------- + dict[str, object] or str + System health information. + """ api_name = 'SYNO.Core.System.SystemHealth' info = self.core_list[api_name] api_path = info['path'] @@ -1004,6 +2005,14 @@ def get_system_health(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def upgrade_status(self) -> dict[str, object] | str: + """ + Get upgrade status. + + Returns + ------- + dict[str, object] or str + Upgrade status. + """ api_name = 'SYNO.Core.Upgrade' info = self.core_list[api_name] api_path = info['path'] diff --git a/synology_api/core_user.py b/synology_api/core_user.py index 536fb66a..3dd86e21 100644 --- a/synology_api/core_user.py +++ b/synology_api/core_user.py @@ -1,98 +1,120 @@ +""" +Synology Core User API wrapper. + +This module provides a Python interface for managing users on Synology NAS devices, +including user creation, modification, deletion, group membership, password policies, +and password expiry. +""" + import json from typing import Any from . import base_api class User(base_api.BaseApi): - """Core User API implementation. - - Supported actions: - - Getters: - - Get all users - - Password policies - - Password expiry - - - Setters: - - Set user password policy - - - Actions: - - Create new user - - Modify user - - Delete user - - User join/leave group + """ + Core User API implementation. + + Methods + ------- + get_users(offset=0, limit=-1, sort_by="name", sort_direction="ASC", additional=[]) + Retrieve groups information. + get_user(name, additional=[]) + Retrieve user information. + create_user(...) + Create a new user. + modify_user(...) + Modify a user. + delete_user(name) + Delete a user. + affect_groups(name, join_groups=[], leave_groups=[]) + Affect or disaffect groups to a user. + affect_groups_status(task_id) + Get the status of a join task. + get_password_policy() + Get the password policy. + set_password_policy(...) + Set the password policy. + get_password_expiry() + Get the password expiry. + set_password_expiry(...) + Set the password expiry. + password_confirm(password) + Confirm password/session. + get_username_policy() + Get the username policy. + + Examples + -------- + See individual method docstrings for usage examples. """ def get_users( self, offset: int = 0, limit: int = -1, sort_by: str = "name", sort_direction: str = "ASC", additional: list[str] = [] ) -> dict[str, object]: - """Retrieve groups information. - - Parameters - ---------- - offset : int, optional - The offset of the groups to retrieve. Defaults to `0`. - - limit : int, optional - The maximum number of groups to retrieve. Defaults to `-1` . - - sort_by : str, optional - Sort by a specific field. Defaults to `"name"`. - - sort_direction : str, optional - The sort direction. Defaults to `"ASC"` else `"DESC"`. - - additional : list[str], optional - Additional fields to retrieve. Defaults to `[]`. - - All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change", "groups", "2fa_status"]`. - - - Returns - ------- - dict[str, object] - A dictionary containing the groups information. - - Examples - -------- - ```json - { - "data": { - "offset": 0, - "total": 5, - "users": [ - { - "description": "System default user", - "email": "", - "expired": "now", - "name": "admin", - "passwd_never_expire": true - }, - { - "description": "Guest", - "email": "", - "expired": "now", - "name": "guest", - "passwd_never_expire": true - }, - { - "description": "", - "email": "", - "expired": "normal", - "name": "test_api", - "passwd_never_expire": true - }, - { - "description": "test description", - "email": "testemail@test.com", - "expired": "normal", - "name": "test_user", - "passwd_never_expire": true - } - ] + """ + Retrieve groups information. + + Parameters + ---------- + offset : int, optional + The offset of the groups to retrieve. Defaults to `0`. + limit : int, optional + The maximum number of groups to retrieve. Defaults to `-1`. + sort_by : str, optional + Sort by a specific field. Defaults to `"name"`. + sort_direction : str, optional + The sort direction. Defaults to `"ASC"` else `"DESC"`. + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change", "groups", "2fa_status"]`. + + Returns + ------- + dict[str, object] + A dictionary containing the groups information. + + Examples + -------- + ```json + { + "data": { + "offset": 0, + "total": 5, + "users": [ + { + "description": "System default user", + "email": "", + "expired": "now", + "name": "admin", + "passwd_never_expire": true }, - "success": true - } - ``` + { + "description": "Guest", + "email": "", + "expired": "now", + "name": "guest", + "passwd_never_expire": true + }, + { + "description": "", + "email": "", + "expired": "normal", + "name": "test_api", + "passwd_never_expire": true + }, + { + "description": "test description", + "email": "testemail@test.com", + "expired": "normal", + "name": "test_user", + "passwd_never_expire": true + } + ] + }, + "success": true + } + ``` """ api_name = "SYNO.Core.User" info = self.core_list[api_name] @@ -111,48 +133,47 @@ def get_users( return self.request_data(api_name, api_path, req_param) def get_user(self, name: str, additional: list[str] = []) -> dict[str, object]: - """Retrieve a user information. - - Parameters - ---------- - name : str - The name of the user. - - additional : list[str], optional - Additional fields to retrieve. Defaults to `[]`. - - All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change","is_password_pending"]`. - - Returns - ------- - dict[str, object] - A dictionary containing the user information. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User", - "data": { - "users": [ - { - "cannot_chg_passwd": false, - "description": "", - "email": "", - "expired": "normal", - "is_password_pending": false, - "name": "test_api", - "passwd_never_expire": true, - "password_last_change": 19789, - "uid": 1027 - } - ] - }, - "method": "get", - "success": true, - "version": 1 - } - ``` + """ + Retrieve user information. + + Parameters + ---------- + name : str + The name of the user. + additional : list[str], optional + Additional fields to retrieve. Defaults to `[]`. + All fields known are: `["description","email","expired","cannot_chg_passwd","passwd_never_expire","password_last_change","is_password_pending"]`. + + Returns + ------- + dict[str, object] + A dictionary containing the user information. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User", + "data": { + "users": [ + { + "cannot_chg_passwd": false, + "description": "", + "email": "", + "expired": "normal", + "is_password_pending": false, + "name": "test_api", + "passwd_never_expire": true, + "password_last_change": 19789, + "uid": 1027 + } + ] + }, + "method": "get", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User" info = self.core_list[api_name] @@ -171,54 +192,47 @@ def create_user( self, name: str, password: str, description: str = "", email: str = "", expire: str = "never", cannot_chg_passwd: bool = False, passwd_never_expire: bool = True, notify_by_email: bool = False, send_password: bool = False ) -> dict[str, object]: - """Create a new user. - - Parameters - ---------- - name : str - The name of the user. - - password : str - The password of the user. - - description : str, optional - The description of the user. Defaults to `""`. - - email : str, optional - The email of the user. Defaults to `""`. - - expire : str, optional - The expiration date of the user. Defaults to `"never"`. - - cannot_chg_passwd : bool, optional - Whether the password can be changed. Defaults to `False`. - - passwd_never_expire : bool, optional - Whether the password should never expire. Defaults to `True`. - - notify_by_email : bool, optional - Whether to notify by email. Defaults to `False`. - - send_password : bool, optional - Whether to send the password. Defaults to `False`. - - Returns - ------- - dict[str, object] - A dictionary containing the user information. - - Examples - -------- - ```json + """ + Create a new user. + + Parameters + ---------- + name : str + The name of the user. + password : str + The password of the user. + description : str, optional + The description of the user. Defaults to `""`. + email : str, optional + The email of the user. Defaults to `""`. + expire : str, optional + The expiration date of the user. Defaults to `"never"`. + cannot_chg_passwd : bool, optional + Whether the password can be changed. Defaults to `False`. + passwd_never_expire : bool, optional + Whether the password should never expire. Defaults to `True`. + notify_by_email : bool, optional + Whether to notify by email. Defaults to `False`. + send_password : bool, optional + Whether to send the password. Defaults to `False`. + + Returns + ------- + dict[str, object] + A dictionary containing the user information. + + Examples + -------- + ```json + { + "data": { - "data": - { - "name":"toto", - "uid": 1030 - }, - "success": true - } - ``` + "name":"toto", + "uid": 1030 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.User" @@ -254,57 +268,49 @@ def modify_user( self, name: str, new_name: str, password: str = "", description: str = "", email: str = "", expire: str = "never", cannot_chg_passwd: bool = False, passwd_never_expire: bool = True, notify_by_email: bool = False, send_password: bool = False ) -> dict[str, object]: - """Modify a user. - - Parameters - ---------- - name : str - The name of the actual user. - - new_name : str - The new name of the user. - - password : str, optional - The password of the user. Defaults to `""`. - - description : str, optional - The description of the user. Defaults to `""`. - - email : str, optional - The email of the user. Defaults to `""`. - - expire : str, optional - The expiration date of the user. Defaults to `"never"`. - - cannot_chg_passwd : bool, optional - Whether the password can be changed. Defaults to `False`. - - passwd_never_expire : bool, optional - Whether the password should never expire. Defaults to `True`. - - notify_by_email : bool, optional - Whether to notify by email. Defaults to `False`. - - send_password : bool, optional - Whether to send the password. Defaults to `False`. - - Returns - ------- - dict[str, object] - A dictionary containing the user information. - - Examples - -------- - ```json - { - "data":{ - "name": "test_user2", - "password_last_change": 20106, - "uid": 1028 - }, - "success": true - } - ``` + """ + Modify a user. + + Parameters + ---------- + name : str + The name of the actual user. + new_name : str + The new name of the user. + password : str, optional + The password of the user. Defaults to `""`. + description : str, optional + The description of the user. Defaults to `""`. + email : str, optional + The email of the user. Defaults to `""`. + expire : str, optional + The expiration date of the user. Defaults to `"never"`. + cannot_chg_passwd : bool, optional + Whether the password can be changed. Defaults to `False`. + passwd_never_expire : bool, optional + Whether the password should never expire. Defaults to `True`. + notify_by_email : bool, optional + Whether to notify by email. Defaults to `False`. + send_password : bool, optional + Whether to send the password. Defaults to `False`. + + Returns + ------- + dict[str, object] + A dictionary containing the user information. + + Examples + -------- + ```json + { + "data":{ + "name": "test_user2", + "password_last_change": 20106, + "uid": 1028 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.User" info = self.core_list[api_name] @@ -333,29 +339,30 @@ def modify_user( return self.request_data(api_name, api_path, req_param, method="post") def delete_user(self, name: str) -> dict[str, object]: - """Delete a user. - - Parameters - ---------- - name : str - The name of the user to delete. - - Returns - ------- - dict[str, object] - A dictionary containing the user information. - - Examples - -------- - ```json - { - "data": { - "name": "toto", - "uid": 1030 - }, - "success": true - } - ``` + """ + Delete a user. + + Parameters + ---------- + name : str + The name of the user to delete. + + Returns + ------- + dict[str, object] + A dictionary containing the user information. + + Examples + -------- + ```json + { + "data": { + "name": "toto", + "uid": 1030 + }, + "success": true + } + ``` """ api_name = "SYNO.Core.User" info = self.core_list[api_name] @@ -369,40 +376,38 @@ def delete_user(self, name: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def affect_groups(self, name: str, join_groups: list[str] = [], leave_groups: list[str] = []) -> dict[str, object]: - """Affect or disaffect groups to a user. - - Tip: This request is asynchronous and will return a task id to check the status of the join task. Use `affect_groups_status` func to check the status of the task. - - Parameters - ---------- - name : str - The name of the user. - - join_groups : list[str] - The names of the groups to join. - - leave_groups : list[str] - The names of the groups to leave. - - - Returns - ------- - dict[str, object] - A dictionary containing the task id to check the status of the join task. Use `affect_groups_status` func to check the status of the task. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.Group", - "data": { - "task_id": "@administrators/groupbatch1737238746C6723E33" - }, - "method": "join", - "success": true, - "version": 1 - } - ``` + """ + Affect or disaffect groups to a user. + + Tip: This request is asynchronous and will return a task id to check the status of the join task. Use `affect_groups_status` func to check the status of the task. + + Parameters + ---------- + name : str + The name of the user. + join_groups : list[str] + The names of the groups to join. + leave_groups : list[str] + The names of the groups to leave. + + Returns + ------- + dict[str, object] + A dictionary containing the task id to check the status of the join task. Use `affect_groups_status` func to check the status of the task. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.Group", + "data": { + "task_id": "@administrators/groupbatch1737238746C6723E33" + }, + "method": "join", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.Group" @@ -418,44 +423,45 @@ def affect_groups(self, name: str, join_groups: list[str] = [], leave_groups: li return self.request_data(api_name, api_path, req_param) def affect_groups_status(self, task_id: str): - """Get the status of a join task. - - Parameters - ---------- - task_id : str - The task id of the join task. - - Returns - ------- - dict[str, object] - A dictionary containing the status of the join task. - - Examples - -------- - ```json - { + """ + Get the status of a join task. + + Parameters + ---------- + task_id : str + The task id of the join task. + + Returns + ------- + dict[str, object] + A dictionary containing the status of the join task. + + Examples + -------- + ```json + { + "data": { + "auto_remove": false, "data": { - "auto_remove": false, - "data": { - "name": "test_user2", - "pid": 18126, - "progress": 1, - "total": 1, - "uid": 1028 - }, - "finish": false, - "info": { - "api": "SYNO.Core.User.Group", - "group": "admin", - "method": "join", - "prefix": "groupbatch", - "version": 1 - }, - "success": true + "name": "test_user2", + "pid": 18126, + "progress": 1, + "total": 1, + "uid": 1028 + }, + "finish": false, + "info": { + "api": "SYNO.Core.User.Group", + "group": "admin", + "method": "join", + "prefix": "groupbatch", + "version": 1 }, "success": true - } - ``` + }, + "success": true + } + ``` """ api_name = "SYNO.Core.User.Group" info = self.core_list[api_name] @@ -468,36 +474,37 @@ def affect_groups_status(self, task_id: str): return self.request_data(api_name, api_path, req_param) def get_password_policy(self) -> dict[str, object]: - """Get the password policy. - - Returns - ------- - dict[str, object] - A dictionary containing the password policy information. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.PasswordPolicy", - "data": { - "enable_reset_passwd_by_email": false, - "password_must_change": false, - "strong_password": { - "exclude_username": true, - "history_num": 0, - "included_numeric_char": true, - "included_special_char": false, - "min_length": 8, - "min_length_enable": true, - "mixed_case": true - } - }, - "method": "get", - "success": true, - "version": 1 - } - ``` + """ + Get the password policy. + + Returns + ------- + dict[str, object] + A dictionary containing the password policy information. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.PasswordPolicy", + "data": { + "enable_reset_passwd_by_email": false, + "password_must_change": false, + "strong_password": { + "exclude_username": true, + "history_num": 0, + "included_numeric_char": true, + "included_special_char": false, + "min_length": 8, + "min_length_enable": true, + "mixed_case": true + } + }, + "method": "get", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.PasswordPolicy" info = self.core_list[api_name] @@ -514,56 +521,48 @@ def set_password_policy( min_length: int = 8, min_length_enable: bool = True, mixed_case: bool = True, exclude_common_password: bool = False, exclude_history: bool = False ) -> dict[str, object]: - """Set the password policy. - - Parameters - ---------- - enable_reset_passwd_by_email : bool, optional - Defaults to `False`. - - password_must_change : bool, optional - Defaults to `False`. - - exclude_username : bool, optional - Defaults to `True`. - - included_numeric_char : bool, optional - Defaults to `True`. - - included_special_char : bool, optional - Defaults to `False`. - - min_length : int, optional - Defaults to `8`. - - min_length_enable : bool, optional - Defaults to `True`. - - mixed_case : bool, optional - Defaults to `True`. - - exclude_common_password : bool, optional - Defaults to `False`. - - exclude_history : bool, optional - Defaults to `False`. - - Returns - ------- - dict[str, object] - A dictionary indicating the success of the operation. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.PasswordPolicy", - "data": {}, - "method": "set", - "success": true, - "version": 1 - } - ``` + """ + Set the password policy. + + Parameters + ---------- + enable_reset_passwd_by_email : bool, optional + Defaults to `False`. + password_must_change : bool, optional + Defaults to `False`. + exclude_username : bool, optional + Defaults to `True`. + included_numeric_char : bool, optional + Defaults to `True`. + included_special_char : bool, optional + Defaults to `False`. + min_length : int, optional + Defaults to `8`. + min_length_enable : bool, optional + Defaults to `True`. + mixed_case : bool, optional + Defaults to `True`. + exclude_common_password : bool, optional + Defaults to `False`. + exclude_history : bool, optional + Defaults to `False`. + + Returns + ------- + dict[str, object] + A dictionary indicating the success of the operation. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.PasswordPolicy", + "data": {}, + "method": "set", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.PasswordPolicy" @@ -588,31 +587,32 @@ def set_password_policy( return self.request_data(api_name, api_path, req_param) def get_password_expiry(self) -> dict[str, object]: - """Get the password expiry. - - Returns - ------- - dict[str, object] - A dictionary containing the password expiry information. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.PasswordExpiry", - "data": { - "allow_reset_after_expired": true, - "enable_login_prompt": false, - "enable_mail_notification": false, - "mail_notification_days": "", - "min_age_enable": false, - "password_expire_enable": false - }, - "method": "get", - "success": true, - "version": 1 - } - ``` + """ + Get the password expiry. + + Returns + ------- + dict[str, object] + A dictionary containing the password expiry information. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.PasswordExpiry", + "data": { + "allow_reset_after_expired": true, + "enable_login_prompt": false, + "enable_mail_notification": false, + "mail_notification_days": "", + "min_age_enable": false, + "password_expire_enable": false + }, + "method": "get", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.PasswordExpiry" info = self.core_list[api_name] @@ -628,52 +628,45 @@ def set_password_expiry( enable_login_prompt: bool = False, login_prompt_days: int = 1, allow_reset_after_expired: bool = True, enable_mail_notification: bool = False, never_expired_list: list[str] = [] ) -> dict[str, object]: - """Set the password expiry. - - Parameters - ---------- - password_expire_enable : bool, optional - Enable password expiry. Defaults to `False`. - - max_age : int, optional - Maximum time before password expiry. Defaults to `30`. - - min_age_enable : bool, optional - Enable minimum time before password expiry. Defaults to `False`. - - min_age : int, optional - Minimum time before password expiry. Defaults to `1`. - - enable_login_prompt : bool, optional - Enable login prompt. Defaults to `False`. - - login_prompt_days : int, optional - Days before login prompt. Defaults to `1`. - - allow_reset_after_expired : bool, optional - Allow reset after password expiry. Defaults to `True`. - - enable_mail_notification : bool, optional - Enable mail notification. Defaults to `False`. - - never_expired_list : list[str], optional - List of users that should never expire. - - Returns - ------- - dict[str, object] - A dictionary indicating the success of the operation. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.PasswordExpiry", - "method": "set", - "success": true, - "version": 1 - } - ``` + """ + Set the password expiry. + + Parameters + ---------- + password_expire_enable : bool, optional + Enable password expiry. Defaults to `False`. + max_age : int, optional + Maximum time before password expiry. Defaults to `30`. + min_age_enable : bool, optional + Enable minimum time before password expiry. Defaults to `False`. + min_age : int, optional + Minimum time before password expiry. Defaults to `1`. + enable_login_prompt : bool, optional + Enable login prompt. Defaults to `False`. + login_prompt_days : int, optional + Days before login prompt. Defaults to `1`. + allow_reset_after_expired : bool, optional + Allow reset after password expiry. Defaults to `True`. + enable_mail_notification : bool, optional + Enable mail notification. Defaults to `False`. + never_expired_list : list[str], optional + List of users that should never expire. + + Returns + ------- + dict[str, object] + A dictionary indicating the success of the operation. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.PasswordExpiry", + "method": "set", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.PasswordExpiry" @@ -695,30 +688,31 @@ def set_password_expiry( return self.request_data(api_name, api_path, req_param) def password_confirm(self, password: str) -> dict[str, object]: - """Issues a passowrd/session comparison to ensure the given password matches the auth of the current session. - - Note: This is needed by some APIs as a confirmation method, for example, when creating/modifying a scheduled task with root permissions, seldom needed by end users. - - Parameters - ---------- - password : str - The password with which the session was initiated. - - Returns - ------- - dict[str, object] - A dictionary containing a `SynoConfirmPWToken`, or an error message. - - Examples - -------- - ```json - { - "data": { - "SynoConfirmPWToken": "xxxxx" - }, - "success": true - } - ``` + """ + Confirm password/session to ensure the given password matches the auth of the current session. + + Note: This is needed by some APIs as a confirmation method, for example, when creating/modifying a scheduled task with root permissions, seldom needed by end users. + + Parameters + ---------- + password : str + The password with which the session was initiated. + + Returns + ------- + dict[str, object] + A dictionary containing a `SynoConfirmPWToken`, or an error message. + + Examples + -------- + ```json + { + "data": { + "SynoConfirmPWToken": "xxxxx" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.User.PasswordConfirm' info = self.core_list[api_name] @@ -735,24 +729,25 @@ def password_confirm(self, password: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param, method="post") def get_username_policy(self) -> dict[str, object]: - """Get the username policy (List of username that are not usable). - - Returns - ------- - dict[str, object] - A dictionary containing the username policy information. - - Examples - -------- - ```json - { - "api": "SYNO.Core.User.UsernamePolicy", - "data": ["root", "rootuser", "rootusr", "admin", "administrator", "adm", "adminuser", "adminusr", "user",…], - "method": "get", - "success": true, - "version": 1 - } - ``` + """ + Get the username policy (list of usernames that are not usable). + + Returns + ------- + dict[str, object] + A dictionary containing the username policy information. + + Examples + -------- + ```json + { + "api": "SYNO.Core.User.UsernamePolicy", + "data": ["root", "rootuser", "rootusr", "admin", "administrator", "adm", "adminuser", "adminusr", "user",…], + "method": "get", + "success": true, + "version": 1 + } + ``` """ api_name = "SYNO.Core.User.UsernamePolicy" info = self.core_list[api_name] diff --git a/synology_api/dhcp_server.py b/synology_api/dhcp_server.py index 367408e4..fd7bd4eb 100644 --- a/synology_api/dhcp_server.py +++ b/synology_api/dhcp_server.py @@ -1,3 +1,10 @@ +""" +Synology DHCP Server API wrapper. + +This module provides a Python interface for managing DHCP server, PXE, TFTP, and network +interfaces on Synology NAS devices. +""" + from __future__ import annotations from typing import Optional @@ -6,8 +13,27 @@ class DhcpServer(base_api.BaseApi): + """ + Core DHCP Server API implementation for Synology NAS. + + This class provides methods to retrieve and manage DHCP server, PXE, TFTP, and network + interface information. + """ def general_info(self, ifname: str = 'ovs_eth0') -> dict[str, object] | str: + """ + Get general DHCP server information for a given interface. + + Parameters + ---------- + ifname : str, optional + Interface name. Defaults to 'ovs_eth0'. + + Returns + ------- + dict[str, object] or str + General DHCP server information. + """ api_name = 'SYNO.Network.DHCPServer' info = self.gen_list[api_name] api_path = info['path'] @@ -17,6 +43,14 @@ def general_info(self, ifname: str = 'ovs_eth0') -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def vendor(self) -> dict[str, object] | str: + """ + Get DHCP vendor information. + + Returns + ------- + dict[str, object] or str + DHCP vendor information. + """ api_name = 'SYNO.Network.DHCPServer.Vendor' info = self.gen_list[api_name] api_path = info['path'] @@ -25,6 +59,14 @@ def vendor(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def pxe(self) -> dict[str, object] | str: + """ + Get PXE server information. + + Returns + ------- + dict[str, object] or str + PXE server information. + """ api_name = 'SYNO.Network.DHCPServer.PXE' info = self.gen_list[api_name] api_path = info['path'] @@ -33,6 +75,14 @@ def pxe(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def tftp(self) -> dict[str, object] | str: + """ + Get TFTP server information. + + Returns + ------- + dict[str, object] or str + TFTP server information. + """ api_name = 'SYNO.Core.TFTP' info = self.core_list[api_name] api_path = info['path'] @@ -41,6 +91,14 @@ def tftp(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_bond(self) -> dict[str, object] | str: + """ + Get network bond interface information. + + Returns + ------- + dict[str, object] or str + Network bond interface information. + """ api_name = 'SYNO.Core.Network.Bond' info = self.gen_list[api_name] api_path = info['path'] @@ -49,6 +107,14 @@ def network_bond(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def network_ethernet(self) -> dict[str, object] | str: + """ + Get network ethernet interface information. + + Returns + ------- + dict[str, object] or str + Network ethernet interface information. + """ api_name = 'SYNO.Core.Network.Ethernet' info = self.gen_list[api_name] api_path = info['path'] @@ -57,6 +123,19 @@ def network_ethernet(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def dhcp_clientlist(self, ifname: str = 'bond0') -> dict[str, object] | str: + """ + Get DHCP client list for a given interface. + + Parameters + ---------- + ifname : str, optional + Interface name. Defaults to 'bond0'. + + Returns + ------- + dict[str, object] or str + DHCP client list. + """ api_name = 'SYNO.Network.DHCPServer.ClientList' info = self.gen_list[api_name] api_path = info['path'] @@ -66,6 +145,19 @@ def dhcp_clientlist(self, ifname: str = 'bond0') -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def dhcp_reservations(self, ifname: str = 'bond0') -> dict[str, object] | str: + """ + Get DHCP reservations for a given interface. + + Parameters + ---------- + ifname : str, optional + Interface name. Defaults to 'bond0'. + + Returns + ------- + dict[str, object] or str + DHCP reservations. + """ api_name = 'SYNO.Network.DHCPServer.Reservation' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/directory_server.py b/synology_api/directory_server.py index f5a783a2..3750f69c 100644 --- a/synology_api/directory_server.py +++ b/synology_api/directory_server.py @@ -1,21 +1,25 @@ -"""directory_server.py works with base_api_core to provide AD capabilities.""" +"""Directory_server.py works with base_api_core to provide AD capabilities.""" + from __future__ import annotations import json +import time from typing import Optional, Any from . import base_api class DirectoryServer(base_api.BaseApi): - """The directory server API. + """ + The directory server API. - Not all items within this class use the Active Directory API. Some use the Synology Entry API which proxies - the request. Some are related to managing users in ways that are useful in the Directory Server context. For + Not all items within this class use the Active Directory API. Some use the Synology Entry API which proxies + the request. Some are related to managing users in ways that are useful in the Directory Server context. For example, sending a user password reset email, or updating the user information. This api works slightly differently than other similar APIs. There are multi-leveled calls where Synology makes requests on behalf of the original request and relays information back. Additionally, the query-string api item is not used often in this class as API is defined within the actual request. The APIs in this class are tested working against the following scenarios: + - Getters: - Get Active Directory information - List objects within a Base DN on the Active Directory Server @@ -36,43 +40,44 @@ class DirectoryServer(base_api.BaseApi): """ def get_directory_info(self) -> dict[str, object]: - """Gets directory info. - - Returns - ------- - dict[str, object] - Information about your domain. - - Examples - -------- - ```json - { + """ + Get directory info. + + Returns + ------- + dict[str, object] + Information about your domain. + + Examples + -------- + ```json + { + "data": { "data": { - "data": { - "domainBasicInfo": { - "realm": "MY.DOMAIN.COM", - "workgroup": "NETBIOSNAME" - }, - "domainControllers": [ - { - "cn": "AD", - "dn": "CN=AD,OU=Domain Controllers,DC=MY,DC=DOMAIN,DC=COM", - "dnshostname": "AD.MY.DOMAIN.COM", - "roles": [ - "pdc", - "rid", - "schema", - "naming", - "infrastructure" - ] - } + "domainBasicInfo": { + "realm": "MY.DOMAIN.COM", + "workgroup": "NETBIOSNAME" + }, + "domainControllers": [ + { + "cn": "AD", + "dn": "CN=AD,OU=Domain Controllers,DC=MY,DC=DOMAIN,DC=COM", + "dnshostname": "AD.MY.DOMAIN.COM", + "roles": [ + "pdc", + "rid", + "schema", + "naming", + "infrastructure" ] - }, - "status": "running" + } + ] }, - "success": true - } - ``` + "status": "running" + }, + "success": true + } + ``` """ api_name = 'SYNO.ActiveDirectory.Info' info = {'maxVersion': 3, 'minVersion': 1, @@ -89,68 +94,61 @@ def list_directory_objects(self, objectCategory: list[str] = [ "person", "group", "organizationalUnit", "computer", "container", "builtinDomain"] ) -> dict[str, object]: - """lists directory objects. - - Parameters - ---------- - basedn : str - The Base DN for the search. eg. `CN=Users,CN=MY,CN=DOMAIN,CN=COM" or CN=MY,CN=DOMAIN,CN=COM` - - offset : int, optional - When searching large data, you may wish to start at a certain number, e.g. for 10 at a time one - would set the limit to 10 and the offset by multiples of 10 for each request. - Defaults to `0` - - limit : int, optional - The numeric the number of maximum objects to return. - Defaults to `40` - - objectCategory : optional, list[str] - The categories of items to search. e.g. `["organizationalUnit","container","builtinDomain"]` for a list of - base server containers, and `["person","group","organizationalUnit","computer"]` for a list of contained objects. - Defaults to `["person","group","organizationalUnit","computer","container","builtinDomain"]` - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "data": [ - { - "accountExpiryTime": 910692730085, - "deletable": true, - "description": "This is a description of a user person", - "disabled": false, - "displayName": "John Doe", - "dn": "CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM", - "locked": false, - "mail": "jdoe@MY.EMAIL.COM", - "movable": true, - "name": "john", - "objectCategory": "person", - "passwordExpired": true, - "physicalDeliveryOfficeName": "official office of officers", - "primaryGroupToken": 0, - "renamable": true, - "sAMAccountName": "jdoe", - "showInAdvancedViewOnly": false, - "telephoneNumber": "123-444-5677" - }, - ], - "total": 99999 + """ + List directory objects. + + Parameters + ---------- + basedn : str + The Base DN for the search. E.g. `CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=MY,CN=DOMAIN,CN=COM`. + offset : int, optional + When searching large data, you may wish to start at a certain number, e.g. for 10 at a time one + would set the limit to 10 and the offset by multiples of 10 for each request. Defaults to `0`. + limit : int, optional + The number of maximum objects to return. Defaults to `40`. + objectCategory : list[str], optional + The categories of items to search. E.g. `["organizationalUnit","container","builtinDomain"]` for a list of + base server containers, and `["person","group","organizationalUnit","computer"]` for a list of contained objects. + Defaults to `["person","group","organizationalUnit","computer","container","builtinDomain"]`. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "data": [ + { + "accountExpiryTime": 910692730085, + "deletable": true, + "description": "This is a description of a user person", + "disabled": false, + "displayName": "John Doe", + "dn": "CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM", + "locked": false, + "mail": "jdoe@MY.EMAIL.COM", + "movable": true, + "name": "john", + "objectCategory": "person", + "passwordExpired": true, + "physicalDeliveryOfficeName": "official office of officers", + "primaryGroupToken": 0, + "renamable": true, + "sAMAccountName": "jdoe", + "showInAdvancedViewOnly": false, + "telephoneNumber": "123-444-5677" }, - "success": true - } - ``` + ], + "total": 99999 + }, + "success": true + } + ``` """ action = '"enum"' scope = '"one"' @@ -176,60 +174,51 @@ def create_new_user( change_password_next_logon: str = 'null', password_never_expire: str = 'true' ) -> dict[str, object]: - """Create a new user. - - Note: The user can be created in AD, but not able to log on until the next synchronization occurs. - - Note: Please note that synchronization with Synology is a separate step. - - Parameters - ---------- - logon_name : str - The desired username. E.g `jdoe`. - - email: str - The desired email. - - password : str - The plain-text password for the new user. E.g `Password123`. - - located_dn : str - The DN for the user. E.g `CN=Users,CN=MY,CN=DOMAIN,CN=COM`. - - description : str, optional - A description for the user. - - account_is_disabled : str - Set to 'true' if the account should be disabled Defaults to `False`. - - cannot_change_password : str, optional - Set to 'true' if the user cannot change the password Defaults to `False`. - - change_password_next_logon : str, optional - Set to 'true' if the user must change password on next logon Defaults to `False`. - - cannot_change_password : str, optional - Set to 'true' if the user cannot change the password Defaults to `False`. - - password_never_expire: str - Pwd Never Expire - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. The data dictionary contains an 'error', or it contains a 'dn' and a 'name'. - - Examples - -------- - ```json - { - 'data': { - 'dn': 'CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM', - 'name': 'NETBIOSNAME\\ababab' - }, - 'success': true - } - ``` + """ + Create a new user. + + Parameters + ---------- + logon_name : str + The desired username. E.g. `jdoe`. + email : str + The desired email. + password : str + The plain-text password for the new user. E.g. `Password123`. + located_dn : str + The DN for the user. E.g. `CN=Users,CN=MY,CN=DOMAIN,CN=COM`. + description : str, optional + A description for the user. + account_is_disabled : str + Set to 'true' if the account should be disabled. Defaults to `False`. + cannot_change_password : str, optional + Set to 'true' if the user cannot change the password. Defaults to `False`. + change_password_next_logon : str, optional + Set to 'true' if the user must change password on next logon. Defaults to `False`. + password_never_expire : str + Set to 'true' if the password never expires. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + + Notes + ----- + The user can be created in AD, but not able to log on until the next synchronization occurs. + Please note that synchronization with Synology is a separate step. + + Examples + -------- + ```json + { + 'data': { + 'dn': 'CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM', + 'name': 'NETBIOSNAME\\ababab' + }, + 'success': true + } + ``` """ api_name = "SYNO.ActiveDirectory.User" @@ -245,33 +234,36 @@ def create_new_user( def reset_password(self, username: str, ) -> dict[str, object]: - """Send a password reset email. - - This will trigger the password reset email from - Control Panel>Notification>Rules>System>Reset password for your account to be sent to the user. - - Info: In order to use this, Control Panel>User & Group>Advanced>"Allow non-administrator users to reset forgotten passwords via email" must be enabled. - - Parameters - ---------- - username : str - The username to reset. E.g. `My Group` - - Returns - ------- - dict[str, object] - The return object can be checked for the "success" to be a true or false. - - Examples - -------- - ```json - { - "data": { - "msg": 3 - }, - "success": true - } - ``` + """ + Send a password reset email. + + This will trigger the password reset email from + Control Panel>Notification>Rules>System>Reset password for your account to be sent to the user. + + Parameters + ---------- + username : str + The username to reset. E.g. `My Group`. + + Returns + ------- + dict[str, object] + The return object can be checked for the "success" to be a true or false. + + Notes + ----- + In order to use this, Control Panel>User & Group>Advanced>"Allow non-administrator users to reset forgotten passwords via email" must be enabled. + + Examples + -------- + ```json + { + "data": { + "msg": 3 + }, + "success": true + } + ``` """ api_name = 'SYNO.Auth.ForgotPwd' @@ -284,52 +276,49 @@ def reset_password(self, return self.request_data(api_name, api_path, req_param) def change_user_password(self, user_dn: str, password: str) -> dict[str, object]: - """Change the user's password. - - Info: This is a compound dual-level request where the synology API proxies your request to the Directory Server. - - Parameters - ---------- - user_dn: str - The user DN to be modified. eg. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM` - - password: str - The new password to be set. e.g. `Password123` - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ + """ + Change the user's password. + + Parameters + ---------- + user_dn : str + The user DN to be modified. E.g. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM`. + password : str + The new password to be set. E.g. `Password123`. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + + Notes + ----- + This is a compound dual-level request where the synology API proxies your request to the Directory Server. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.ActiveDirectory.User", + "data": [ { - "api": "SYNO.ActiveDirectory.User", - "data": [ - { - "code": 0, - "msg": "update record successfully" - } - ], - "method": "set", - "success": true, - "version": 2 + "code": 0, + "msg": "update record successfully" } - ] - }, - "success": true - } - ``` - + ], + "method": "set", + "success": true, + "version": 2 + } + ] + }, + "success": true + } + ``` """ api_name = "SYNO.Entry.Request" info = {'maxVersion': 1, 'minVersion': 1, @@ -350,38 +339,30 @@ def create_new_group( type: Optional[str] = 'security', scope: Optional[str] = 'global' ) -> dict[str, object]: - """Create a new AD group. - - Parameters - ---------- - name : str - The name of the group. E.g. `My Group` - - located_dn : str - - The DN to place the group in. eg. `CN=Groups,DC=MY,DC=DOMAIN,DC=COM` - email : str, optional - The email address used to reference this group. - Defaults to `""` - - description : str, optional - A description of the AD Group. - Defaults to `""` - - type : str, optional - Example Options: `security`, `distribution` - - (definitions from https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/compare-groups?view=o365-worldwide ) - - `distribution` (Distribution groups) are used for sending email + """ + Create a new AD group. + + Parameters + ---------- + name : str + The name of the group. E.g. `My Group`. + located_dn : str + The DN to place the group in. E.g. `CN=Groups,DC=MY,DC=DOMAIN,DC=COM`. + email : str, optional + The email address used to reference this group. Defaults to `""`. + description : str, optional + A description of the AD Group. Defaults to `""`. + type : str, optional + Example Options: `security`, `distribution`. Defaults to `"security"`. + + (definitions from https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/compare-groups?view=o365-worldwide ) + - `distribution` (Distribution groups) are used for sending email notifications to a group of people. - - `security` - Security groups are used for granting access to resources + - `security` - Security groups are used for granting access to resources such as SharePoint sites. - Defaults to `"security"` - - scope : str, optional - Example Options : `local`, `global`, `universal` - + scope : str, optional + Example Options: `local`, `global`, `universal`. Defaults to `"global"`. (Definitions from https://www.netwrix.com/active_directory_group_management.html ) - `local` (Domain Local Groups) should be used to manage permissions to @@ -404,24 +385,22 @@ def create_new_group( is stored in the Global Catalog and replicated forest-wide. Don’t use universal groups if you have only one domain. - Defaults to `"global"` - - Returns - ------- - dict[str, object] - A success object, and data object containing the new dn and the netbios name of the group. - - Examples - -------- - ```json - { - 'data': { - 'dn': 'CN=My Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM', - 'name': 'NETBIOSNAME\\My Group' - }, - 'success': true - } - ``` + Returns + ------- + dict[str, object] + A success object, and data object containing the new dn and the netbios name of the group. + + Examples + -------- + ```json + { + 'data': { + 'dn': 'CN=My Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM', + 'name': 'NETBIOSNAME\\My Group' + }, + 'success': true + } + ``` """ api_name = 'SYNO.ActiveDirectory.Group' info = {'maxVersion': 1, 'minVersion': 1, @@ -432,50 +411,47 @@ def create_new_group( return self.request_data(api_name, api_path, req_param) def add_user_to_group(self, userDn: str, groupDn: str) -> dict[str, object]: - """Adds a user as a member of a group. - - Parameters - ---------- - userDn : str - The fully qualified dn to add. eg. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` - - groupDn : str - the fully qualified dn of the group to which the user is to be added. e.g. `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM` - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ - { - "api": "SYNO.ActiveDirectory.Group.Member", - "data": { - "members": [ - "CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM" - ] - }, - "method": "add", - "success": true, - "version": 1 - } + """ + Add a user as a member of a group. + + Parameters + ---------- + userDn : str + The fully qualified dn to add. E.g. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM`. + groupDn : str + The fully qualified dn of the group to which the user is to be added. E.g. `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM`. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.ActiveDirectory.Group.Member", + "data": { + "members": [ + "CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM" ] - }, - "success": true - } - ``` + }, + "method": "add", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` """ - api_name = 'SYNO.Entry.Request' compound = '[{"api":"SYNO.ActiveDirectory.Group.Member","method":"add","version":"1","dn":"' + \ groupDn+'","members":["'+userDn+'"]}]' @@ -491,23 +467,26 @@ def add_user_to_group(self, userDn: str, groupDn: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def does_dn_exist(self, groupName: str) -> dict[str, object]: - """Checks if a container exists. This can be used to verifiy the username or group name is unique. - - Info: This will not check the container, only if a similarly named container already exists. + """ + Check if a container exists. - Parameters - ---------- - groupName : str - The user, or group's name. e.g. `jdoe` or `My Cool Group` + This can be used to verify the username or group name is unique. - Fully Qualified Domain Name such as `CN=My Cool Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM` are not successful. + Parameters + ---------- + groupName : str + The user, or group's name. E.g. `jdoe` or `My Cool Group`. + Fully Qualified Domain Name such as `CN=My Cool Group,CN=Groups,DC=MY,DC=DOMAIN,DC=COM` are not successful. + Improper case such as `my cool group` instead of `My Cool Group` are successful. - Improper case such as `my cool group` instead of `My Cool Group` are successful + Returns + ------- + dict[str, object] + `True` if the group exists. `False` if the group does not exist. - Returns - ------- - dict[str, object] - `True` if the group exists. `False` if the group does not exist + Notes + ----- + This will not check the container, only if a similarly named container already exists. """ api_name = 'SYNO.ActiveDirectory.Group' @@ -529,75 +508,67 @@ def modify_user_info(self, telephoneNumber: str = None, web: str = None ) -> dict[str, object]: - """Performs modification to user information within the Active Directory. - - Parameters - ---------- - user_dn : str - The user DN to be modified. eg. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM` - - firstName : str, optional - The First name of the user. e.g. `John` - - lastName : str, optional - The Last Name of the user. e.g. `Doe` - - displayName : str, optional - The Display name of the user. e.g. `John Doe` - - description : str, optional - The Descrition of the user. e.g. `The guy who just came in` - - initials : str, optional - The Initials of the user. e.g. `JD` - - physicalDeliveryOfficeName : str, optional - The office location in the user's place of business - - telephoneNumber : str, optional - The user's telephone number. - - web : str, optional - The user's website or location on the web where information can be obtained. - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": true, - "result": [ - { - "api": "SYNO.ActiveDirectory.User", - "error": { - "code": 10104, - "errors": [ - { - "code": 10237, - "msg": "ldb updaterecords: modify" - } - ] - }, - "method": "set", - "success": false, - "version": 2 - } + """ + Modify user information within the Active Directory. + + Parameters + ---------- + user_dn : str, optional + The user DN to be modified. E.g. `CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM`. + firstName : str, optional + The First name of the user. E.g. `John`. + lastName : str, optional + The Last Name of the user. E.g. `Doe`. + displayName : str, optional + The Display name of the user. E.g. `John Doe`. + description : str, optional + The Description of the user. E.g. `The guy who just came in`. + initials : str, optional + The Initials of the user. E.g. `JD`. + physicalDeliveryOfficeName : str, optional + The office location in the user's place of business. + telephoneNumber : str, optional + The user's telephone number. + web : str, optional + The user's website or location on the web where information can be obtained. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "has_fail": true, + "result": [ + { + "api": "SYNO.ActiveDirectory.User", + "error": { + "code": 10104, + "errors": [ + { + "code": 10237, + "msg": "ldb updaterecords: modify" + } ] - }, - "success": true - } - ``` + }, + "method": "set", + "success": false, + "version": 2 + } + ] + }, + "success": true + } + ``` """ class Person: + """Represents a user object for Active Directory modifications.""" firstName lastName displayName @@ -633,58 +604,54 @@ class Person: return val def setEntryRequest(self, modificationAPI: str, method: str, nameOfObject: str, jsonObject: Any) -> dict[str, object]: - """Performs modification to an object within the Active Directory. - - Parameters - ---------- - modificationAPI : str - API to be used - - method : str - Method to be called - - nameOfObject : str - The user DN to be modified. eg. `"CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM"` - - jsonObject : str - The json Object to be added, eg, a user object where the - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": true, - "result": [ - { - "api": "SYNO.ActiveDirectory.User", - "error": { - "code": 10104, - "errors": [ - { - "code": 10237, - "msg": "ldb updaterecords: modify" - } - ] - }, - "method": "set", - "success": false, - "version": 2 - } + """ + Modify an object within the Active Directory. + + Parameters + ---------- + modificationAPI : str + API to be used. + method : str + Method to be called. + nameOfObject : str + The user DN to be modified. E.g. `"CN=jdoe,CN=Users,DC=MY,DC=DOMAIN,DC=COM"`. + jsonObject : str + The json Object to be added, e.g., a user object. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "has_fail": true, + "result": [ + { + "api": "SYNO.ActiveDirectory.User", + "error": { + "code": 10104, + "errors": [ + { + "code": 10237, + "msg": "ldb updaterecords: modify" + } ] - }, - "success": true - } - ``` + }, + "method": "set", + "success": false, + "version": 2 + } + ] + }, + "success": true + } + ``` """ compound = [{"api": modificationAPI, "method": method, "version": 2, nameOfObject: [jsonObject]}] @@ -698,39 +665,38 @@ def setEntryRequest(self, modificationAPI: str, method: str, nameOfObject: str, return self.request_data(api_name, api_path, req_param, "post") def update_domain_records(self) -> dict[str, object]: - """Updates the Synology users and groups database with information from Directory Server. + """ + Update the Synology users and groups database with information from Directory Server. - This is a long-running and asynchronous task. You are given back a task_id, and you can use that task_id to check the status with the get_task_status(task_id) method. + This is a long-running and asynchronous task. You are given back a task_id, and you can use that task_id to check the status with the get_task_status(task_id) method. - Returns - ------- - dict[str, object] - The 'data' object contains the 'task_id' used to track with the getTaskStatus() method. + Returns + ------- + dict[str, object] + The 'data' object contains the 'task_id' used to track with the getTaskStatus() method. - The 'success' object will be true if the operation was successful. or false if failed. + Notes + ----- + Typical utilization of Update Domain requires starting the update job and waiting for + completion. Waiting involves using the getTaskStatus and can be accomplished via a busy-wait method such as the following: - Examples - -------- - ```json - { - "data": { - "task_id": "@administrators/DomainUpdate6146195136397F2" - }, - "success": true - } + ```python + updateResponse=directory.updateDomain() + status = directory.getTaskStatus(updateResponse['data']['task_id']) + while status['data']['status'] == 'updating': + status=directory.getTaskStatus(updateResponse['data']['task_id']) ``` - Note - ---- - Typical utilization of Update Domain requires starting the update job and waiting for - completion. Waiting involves using the getTaskStatus and can be accomplished via a busy-wait method such as the following: - - ```python - updateResponse=directory.updateDomain() - status = directory.getTaskStatus(updateResponse['data']['task_id']) - while status['data']['status'] == 'updating': - status=directory.getTaskStatus(updateResponse['data']['task_id']) - ``` + Examples + -------- + ```json + { + "data": { + "task_id": "@administrators/DomainUpdate6146195136397F2" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Directory.Domain' info = self.core_list[api_name] @@ -740,34 +706,34 @@ def update_domain_records(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_task_status(self, task_id: str) -> dict[str, object]: - """Gets the current status of a task running on the Directory Domain object. - - This is used to ensure the task is completed. For example, the primary utilization of this is when updating Synology's internal Domain user and group list. - - Until this method reports finish, the job is not completed, and it is not safe to operate under the assumption that users have been synchronized. - - Parameters - ---------- - task_id : str - The task ID to be tracked for status. - - Returns - ------- - dict[str, object] - The 'data' object contains the 'status' used to determine the current status. 'status' will be 'updating' or 'finish' if the job was started. - T - The 'success' object will be true if the operation was successful. or false if failed. - - Examples - -------- - ```json - { - 'data': { - 'status': 'updating' - }, - 'success': true - } - ``` + """ + Get the current status of a task running on the Directory Domain object. + + This is used to ensure the task is completed. For example, the primary utilization of this is when updating Synology's internal Domain user and group list. + + Until this method reports finish, the job is not completed, and it is not safe to operate under the assumption that users have been synchronized. + + Parameters + ---------- + task_id : str + The task ID to be tracked for status. + + Returns + ------- + dict[str, object] + The 'data' object contains the 'status' used to determine the current status. 'status' will be 'updating' or 'finish' if the job was started. + The 'success' object will be true if the operation was successful, or false if failed. + + Examples + -------- + ```json + { + 'data': { + 'status': 'updating' + }, + 'success': true + } + ``` """ api_name = 'SYNO.Core.Directory.Domain' @@ -778,51 +744,49 @@ def get_task_status(self, task_id: str) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def deleteItems(self, dnList: list[str]) -> dict[str, object]: - """Deletes an array of DNs from AD. - - Parameters - ---------- - dnList : list[str] - The fully qualified DN to be removed from the directory server. - eg. `["CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM","CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM"]` - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ - { - "api": "SYNO.ActiveDirectory.Polling", - "data": { - "data": [ - { - "dn": "CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM", - "status": {} - } - ], - "finished": true, - "total": 1 - }, - "method": "get", - "success": true, - "version": 1 - } - ] - }, - "success": true - } - ``` + """ + Delete an array of DNs from AD. + + Parameters + ---------- + dnList : list[str] + The fully qualified DN to be removed from the directory server. E.g. `["CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM","CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM"]`. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.ActiveDirectory.Polling", + "data": { + "data": [ + { + "dn": "CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM", + "status": {} + } + ], + "finished": true, + "total": 1 + }, + "method": "get", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.ActiveDirectory.Directory' info = {'maxVersion': 2, 'minVersion': 1, @@ -846,68 +810,71 @@ def deleteItems(self, dnList: list[str]) -> dict[str, object]: return returnValue def delete_item(self, dn: str) -> dict[str, object]: - """Deletes a DN from AD. - - Parameters - ---------- - dn : str - The fully qualified DN to be removed from the directory server. - eg. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM` - - Returns - ------- - dict[str, object] - The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. - - The first level is the success to the AD server. The second Data level is the status of the actual request. - - Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. - - Examples - -------- - ```json - { - "data": { - "has_fail": false, - "result": [ - { - "api": "SYNO.ActiveDirectory.Polling", - "data": { - "data": [ - { - "dn": "CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM", - "status": {} - } - ], - "finished": true, - "total": 1 - }, - "method": "get", - "success": true, - "version": 1 - } - ] - }, - "success": true - } - ``` + """ + Delete a DN from AD. + + Parameters + ---------- + dn : str + The fully qualified DN to be removed from the directory server. E.g. `CN=jdoe,CN=Users,CN=MY,CN=DOMAIN,CN=COM` or `CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM`. + + Returns + ------- + dict[str, object] + The result of this method is a dictionary object with a 'data' dictionary and a 'success' dictionary. + The first level is the success to the AD server. The second Data level is the status of the actual request. + Since this is a compound request, the data contains an object with it's own request and results contained within. The object will explain any issues with the request. + + Examples + -------- + ```json + { + "data": { + "has_fail": false, + "result": [ + { + "api": "SYNO.ActiveDirectory.Polling", + "data": { + "data": [ + { + "dn": "CN=My Group,CN=Groups,CN=MY,CN=DOMAIN,CN=COM", + "status": {} + } + ], + "finished": true, + "total": 1 + }, + "method": "get", + "success": true, + "version": 1 + } + ] + }, + "success": true + } + ``` """ items = [] items.append(dn) return self.deleteItems(items) def entryRequest(self, task_id: str) -> Any: - """Some requests require an entry. + """ + Perform an entry request for a task. - Delete for example requires an entry. If an entry is required, the task will not complete without an Entry Request. + Some requests require an entry. Delete, for example, requires an entry. If an entry is required, the task will not complete without an Entry Request. - Parameters - ---------- - task_id: str - The ID of the task to be checked. This is provided when making a request. + Parameters + ---------- + task_id : str + The ID of the task to be checked. This is provided when making a request. + An example Task ID may look like this + `@administrators/Synoads_SYNO.ActiveDirectory.Directory_delete6145EA17C4F03DA9`. - An example Task ID may look like this - `@administrators/Synoads_SYNO.ActiveDirectory.Directory_delete6145EA17C4F03DA9` + Returns + ------- + Any + The result of the entry request. """ api_name = 'SYNO.Entry.Request' info = {'maxVersion': 1, 'minVersion': 1, diff --git a/synology_api/docker_api.py b/synology_api/docker_api.py index 245fb11e..1db870c6 100644 --- a/synology_api/docker_api.py +++ b/synology_api/docker_api.py @@ -1,6 +1,4 @@ -""" -Docker API implementation for Synology NAS. -""" +"""Docker API implementation for Synology NAS.""" from __future__ import annotations from typing import Optional import json @@ -29,7 +27,6 @@ class Docker(base_api.BaseApi): - Get list of docker networks - Setters: - - - Actions: - Export container profile diff --git a/synology_api/downloadstation.py b/synology_api/downloadstation.py index ce30c1e8..60ea7069 100644 --- a/synology_api/downloadstation.py +++ b/synology_api/downloadstation.py @@ -1,9 +1,109 @@ +""" +Synology Download Station API wrapper. + +This module provides a Python interface for managing downloads, tasks, RSS feeds, and BT searches +on Synology NAS devices using the Download Station application. +""" + from __future__ import annotations + +import json from typing import Optional, Any + from . import base_api +from .utils import get_data_for_request_from_file class DownloadStation(base_api.BaseApi): + """ + Core Download Station API implementation for Synology NAS. + + This class provides methods to manage downloads, tasks, RSS feeds, and BT searches. + + Parameters + ---------- + ip_address : str + IP address or hostname of the Synology NAS. + port : str + Port number to connect to. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). + cert_verify : bool, optional + Verify SSL certificates (default is False). + dsm_version : int, optional + DSM version (default is 7). + debug : bool, optional + Enable debug output (default is True). + otp_code : Optional[str], optional + One-time password for 2FA (default is None). + device_id : Optional[str], optional + Device ID (default is None). + device_name : Optional[str], optional + Device name (default is None). + interactive_output : bool, optional + Enable interactive output (default is True). + download_st_version : int, optional + Download Station API version (default is None). + + Methods + ------- + get_info() + Get Download Station info. + get_config() + Get Download Station config. + set_server_config(...) + Set Download Station server config. + schedule_info() + Get schedule info. + schedule_set_config(...) + Set schedule config. + tasks_list(...) + List download tasks. + tasks_info(...) + Get info for specific tasks. + tasks_source(...) + Download task source. + create_task(...) + Create a new download task. + delete_task(...) + Delete a download task. + pause_task(...) + Pause a download task. + resume_task(...) + Resume a download task. + edit_task(...) + Edit a download task. + get_statistic_info() + Get Download Station statistics. + get_rss_info_list(...) + Get RSS site info list. + refresh_rss_site(...) + Refresh RSS site. + rss_feed_list(...) + Get RSS feed list. + rss_feed_filter_list(...) + Get RSS feed filter list. + rss_feed_filter_add(...) + Add RSS feed filter. + rss_feed_filter_set(...) + Set RSS feed filter. + rss_feed_filter_delete(...) + Delete RSS feed filter. + start_bt_search(...) + Start a BT search. + get_bt_search_results(...) + Get BT search results. + get_bt_search_category() + Get BT search categories. + clean_bt_search(...) + Clean BT search tasks. + get_bt_module() + Get BT search modules. + """ def __init__(self, ip_address: str, @@ -20,6 +120,38 @@ def __init__(self, interactive_output: bool = True, download_st_version: int = None ) -> None: + """ + Initialize the DownloadStation API wrapper. + + Parameters + ---------- + ip_address : str + IP address or hostname of the Synology NAS. + port : str + Port number to connect to. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP if False (default is False). + cert_verify : bool, optional + Verify SSL certificates (default is False). + dsm_version : int, optional + DSM version (default is 7). + debug : bool, optional + Enable debug output (default is True). + otp_code : Optional[str], optional + One-time password for 2FA (default is None). + device_id : Optional[str], optional + Device ID (default is None). + device_name : Optional[str], optional + Device name (default is None). + interactive_output : bool, optional + Enable interactive output (default is True). + download_st_version : int, optional + Download Station API version (default is None). + """ super(DownloadStation, self).__init__(ip_address, port, username, password, secure, cert_verify, dsm_version, debug, otp_code, device_id, device_name, 'DownloadStation') @@ -38,6 +170,14 @@ def __init__(self, self.download_st_version = '' def get_info(self) -> dict[str, object] | str: + """ + Get Download Station info. + + Returns + ------- + dict[str, object] or str + Download Station info. + """ api_name = 'SYNO.DownloadStation.Info' info = self.download_list[api_name] api_path = info['path'] @@ -46,6 +186,14 @@ def get_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_config(self) -> dict[str, object] | str: + """ + Get Download Station config. + + Returns + ------- + dict[str, object] or str + Download Station config. + """ api_name = 'SYNO.DownloadStation.Info' info = self.download_list[api_name] api_path = info['path'] @@ -66,7 +214,39 @@ def set_server_config(self, default_destination: Optional[str] = None, emule_default_destination: Optional[str] = None ) -> dict[str, object] | str: - + """ + Set Download Station server configuration. + + Parameters + ---------- + bt_max_download : Optional[int], optional + Maximum BT download speed. + bt_max_upload : Optional[int], optional + Maximum BT upload speed. + emule_max_download : Optional[int], optional + Maximum eMule download speed. + emule_max_upload : Optional[int], optional + Maximum eMule upload speed. + nzb_max_download : Optional[int], optional + Maximum NZB download speed. + http_max_download : Optional[int], optional + Maximum HTTP download speed. + ftp_max_download : Optional[int], optional + Maximum FTP download speed. + emule_enabled : Optional[bool], optional + Enable eMule. + unzip_service_enabled : Optional[bool], optional + Enable unzip service. + default_destination : Optional[str], optional + Default download destination. + emule_default_destination : Optional[str], optional + Default eMule download destination. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation.Info' info = self.download_list[api_name] api_path = info['path'] @@ -81,6 +261,14 @@ def set_server_config(self, return self.request_data(api_name, api_path, req_param) def schedule_info(self) -> dict[str, object] | str: + """ + Get Download Station schedule configuration. + + Returns + ------- + dict[str, object] or str + Schedule configuration. + """ api_name = 'SYNO.DownloadStation.Schedule' info = self.download_list[api_name] api_path = info['path'] @@ -89,6 +277,21 @@ def schedule_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def schedule_set_config(self, enabled: bool = False, emule_enabled: bool = False) -> dict[str, object] | str: + """ + Set Download Station schedule configuration. + + Parameters + ---------- + enabled : bool, optional + Enable schedule (default is False). + emule_enabled : bool, optional + Enable eMule schedule (default is False). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation.Schedule' info = self.download_list[api_name] api_path = info['path'] @@ -105,6 +308,23 @@ def tasks_list(self, offset: int = 0, limit: int = -1 ) -> dict[str, object] | str: + """ + List download tasks. + + Parameters + ---------- + additional_param : Optional[str or list[str]], optional + Additional fields to retrieve. + offset : int, optional + Offset for pagination (default is 0). + limit : int, optional + Maximum number of tasks to retrieve (default is -1). + + Returns + ------- + dict[str, object] or str + List of download tasks. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] @@ -115,31 +335,64 @@ def tasks_list(self, additional_param = ['detail', 'transfer', 'file', 'tracker', 'peer'] - if type(additional_param) is list: - req_param['additional'] = ",".join(additional_param) + req_param['additional'] = json.dumps(additional_param if isinstance( + additional_param, list) else [additional_param]) return self.request_data(api_name, api_path, req_param) def tasks_info(self, task_id, additional_param: Optional[str | list[str]] = None) -> dict[str, object] | str: + """ + Get information for specific download tasks. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + additional_param : Optional[str or list[str]], optional + Additional fields to retrieve. + + Returns + ------- + dict[str, object] or str + Task information. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] - req_param = {'version': info['maxVersion'], 'method': 'getinfo', + req_param = {'version': info['maxVersion'], 'method': 'get', 'id': task_id, 'additional': additional_param} if additional_param is None: additional_param = ['detail', 'transfer', 'file', 'tracker', 'peer'] + elif isinstance(additional_param, str): + additional_param = [additional_param] + elif isinstance(additional_param, list): + if not all(isinstance(a, str) for a in additional_param): + return "additional_param must be a string or a list of strings." + else: + return "additional_param must be a string or a list of strings." - if type(additional_param) is list: - req_param['additional'] = ",".join(additional_param) - - if type(task_id) is list: - req_param['id'] = ",".join(task_id) + req_param['additional'] = json.dumps(additional_param) + req_param['id'] = json.dumps( + task_id if isinstance(task_id, list) else [task_id]) return self.request_data(api_name, api_path, req_param) def tasks_source(self, task_id) -> bytes: + """ + Download task source. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + + Returns + ------- + bytes + Task source content. + """ # DownloadStation2 is required here api_name = 'SYNO.DownloadStation2.Task.Source' info = self.download_list[api_name] @@ -149,16 +402,126 @@ def tasks_source(self, task_id) -> bytes: return self.request_data(api_name, api_path, req_param, response_json=False).content - def create_task(self, url, destination) -> dict[str, object] | str: + def get_task_list(self, list_id: str) -> dict[str, any]: + """ + Get info from a task list containing the files to be downloaded. + + This is to be used after creating a task, and before starting the download. + + Parameters + ---------- + list_id : str + List ID returned by create_task. + + Returns + ------- + dict[str, any] + A dictionary containing a task list information. + + Examples + -------- + ```json + { + "data" : { + "files" : [ + { + "index" : 0, + "name" : "Pulp.Fiction.1994.2160p.4K.BluRay.x265.10bit.AAC5.1-[YTS.MX].mkv", + "size" : 2391069024 + }, + { + "index" : 1, + "name" : "YTSProxies.com.txt", + "size" : 604 + }, + { + "index" : 2, + "name" : "www.YTS.MX.jpg", + "size" : 53226 + } + ], + "size" : 7835426779, + "title" : "Pulp Fiction (1994) [2160p] [4K] [BluRay] [5.1] [YTS.MX]", + "type" : "bt" + }, + } + ``` + """ + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task.List' + info = self.download_list[api_name] + api_path = info['path'] + req_param = {'version': info['maxVersion'], + 'method': 'get', 'list_id': list_id} + + return self.request_data(api_name, api_path, req_param) + + def create_task(self, + url: Optional[str] = None, + file_path: Optional[str] = None, + destination: str = "", + ) -> dict[str, object] | str: + """ + Create a new download task. + + You can choose between a url or a file path (.torrent). + + Parameters + ---------- + url : str, optional + Download URL. Use either `url` or `file_path`. + file_path : str, optional + Path to a file (e.g. a .torrent) to download. + destination : str, optional + Download destination folder (default is ""). + + Returns + ------- + dict[str, object] or str + API response. + """ + # Validate only a url or a file path. + if bool(url) == bool(file_path): + raise ValueError("You can't specify both 'url' and 'file_path'") + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] + + if file_path: + fields = { + "api": api_name, + "method": "create", + "version": str(info["maxVersion"]), + "type": '"file"', + "file": '["torrent"]', + "destination": f'"{destination}"', + "create_list": "true" + } + data = get_data_for_request_from_file( + file_path=file_path, fields=fields, called_from='DownloadStation') + + return self.request_data(api_name, api_path, method='post', data=data, req_param={}) + req_param = {'version': info['maxVersion'], 'method': 'create', 'type': 'url', 'create_list': 'true', 'destination': destination, 'url': f'["{url}"]'} - return self.request_data(api_name, api_path, req_param) def delete_task(self, task_id: str, force: bool = False) -> dict[str, object] | str: + """ + Delete a download task. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + force : bool, optional + Force delete (default is False). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] @@ -171,6 +534,19 @@ def delete_task(self, task_id: str, force: bool = False) -> dict[str, object] | return self.request_data(api_name, api_path, param) def pause_task(self, task_id: str) -> dict[str, object] | str: + """ + Pause a download task. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] @@ -183,6 +559,19 @@ def pause_task(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, param) def resume_task(self, task_id: str) -> dict[str, object] | str: + """ + Resume a download task. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] @@ -195,6 +584,21 @@ def resume_task(self, task_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, param) def edit_task(self, task_id: str, destination: str = 'sharedfolder') -> dict[str, object] | str: + """ + Edit a download task. + + Parameters + ---------- + task_id : str or list[str] + Task ID(s). + destination : str, optional + New download destination (default is 'sharedfolder'). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.Task' info = self.download_list[api_name] api_path = info['path'] @@ -206,7 +610,67 @@ def edit_task(self, task_id: str, destination: str = 'sharedfolder') -> dict[str return self.request_data(api_name, api_path, param) + def download_task_list( + self, + list_id: str, + file_indexes: list[int], + destination: str, + create_subfolder: bool = True + ) -> dict[str, object] | str: + """ + Download files from a task list. + + Parameters + ---------- + list_id : str + Task list ID. + file_indexes : list[int] + List of file indexes to download. + For example, if `get_task_list()` returns `files: [{index: 0, name: "file1.txt"}, {index: 1, name: "file2.txt"}]`, then `file_indexes = [1]` will download only file2.txt. + destination : str + Download destination, e.g. 'sharedfolder/subfolder' + create_subfolder : bool, optional + Create subfolder. Defaults to `True` + + Returns + ------- + dict[str, object] or str + A dictionary containing the task_id for the started download task. + + Examples + -------- + ```json + { + 'data': { + 'task_id': 'username/SYNODLTaskListDownload1759340338C7C39ABA' + } + } + ``` + """ + api_name = 'SYNO.DownloadStation' + \ + self.download_st_version + '.Task.List.Polling' + info = self.download_list[api_name] + api_path = info['path'] + param = { + 'version': info['maxVersion'], + 'method': 'download', + 'list_id': list_id, + 'file_indexes': ",".join(map(str, file_indexes)), + 'destination': destination, + 'create_subfolder': create_subfolder + } + + return self.request_data(api_name, api_path, param) + def get_statistic_info(self) -> dict[str, object] | str: + """ + Get Download Station statistics. + + Returns + ------- + dict[str, object] or str + Statistics information. + """ api_name = 'SYNO.DownloadStation.Statistic' info = self.download_list[api_name] api_path = info['path'] @@ -215,6 +679,21 @@ def get_statistic_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, param) def get_rss_info_list(self, offset: Optional[int] = None, limit: Optional[int] = None) -> dict[str, object] | str: + """ + Get RSS site info list. + + Parameters + ---------- + offset : Optional[int], optional + Offset for pagination. + limit : Optional[int], optional + Maximum number of RSS sites to retrieve. + + Returns + ------- + dict[str, object] or str + RSS site info list. + """ api_name = 'SYNO.DownloadStation.RSS.Site' info = self.download_list[api_name] api_path = info['path'] @@ -228,6 +707,19 @@ def get_rss_info_list(self, offset: Optional[int] = None, limit: Optional[int] = return self.request_data(api_name, api_path, param) def refresh_rss_site(self, rss_id: Optional[str] = None) -> dict[str, object] | str: + """ + Refresh an RSS site. + + Parameters + ---------- + rss_id : Optional[str], optional + RSS site ID. + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation.RSS.Site' info = self.download_list[api_name] api_path = info['path'] @@ -235,7 +727,7 @@ def refresh_rss_site(self, rss_id: Optional[str] = None) -> dict[str, object] | 'method': 'refresh', 'id': rss_id} if rss_id is None: - return 'Enter a valid ID check if you have any with get_rss_list()' + return 'Enter a valid ID check if you have any with get_rss_info_list()' elif type(rss_id) is list: rss_id = ','.join(rss_id) param['id'] = rss_id @@ -247,13 +739,30 @@ def rss_feed_list(self, offset: Optional[int] = None, limit: Optional[int] = None ) -> dict[str, object] | str: + """ + Get RSS feed list. + + Parameters + ---------- + rss_id : Optional[str], optional + RSS site ID. + offset : Optional[int], optional + Offset for pagination. + limit : Optional[int], optional + Maximum number of RSS feeds to retrieve. + + Returns + ------- + dict[str, object] or str + RSS feed list. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.RSS.Feed' info = self.download_list[api_name] api_path = info['path'] param = {'version': info['maxVersion'], 'method': 'list', 'id': rss_id} if rss_id is None: - return 'Enter a valid ID check if you have any with get_rss_list()' + return 'Enter a valid ID check if you have any with get_rss_info_list()' elif type(rss_id) is list: rss_id = ','.join(rss_id) param['id'] = rss_id @@ -265,7 +774,185 @@ def rss_feed_list(self, return self.request_data(api_name, api_path, param) + def rss_feed_filter_list(self, + feed_id: Optional[int] = None, + offset: Optional[int] = None, + limit: Optional[int] = None + ) -> dict[str, object] | str: + """ + Get RSS feed filter list. + + Parameters + ---------- + feed_id : int, optional + RSS feed ID. + offset : int, optional + Offset for pagination. + limit : int, optional + Maximum number of filters to retrieve. + + Returns + ------- + dict[str, object] or str + RSS feed filter list. + """ + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.RSS.Filter' + info = self.download_list[api_name] + api_path = info['path'] + param = {'version': info['maxVersion'], + 'method': 'list', 'feed_id': feed_id} + + if feed_id is None: + return 'Enter a valid ID check if you have any with get_rss_info_list()' + + if offset is not None: + param['offset'] = offset + if limit is not None: + param['limit'] = limit + + return self.request_data(api_name, api_path, param) + + def rss_feed_filter_add(self, + feed_id: int = None, + filter_name: str = None, + match: str = None, + not_match: str = None, + destination: str = None, + is_regex: bool = False + ) -> dict[str, object] | str: + """ + Add RSS feed filter. + + Parameters + ---------- + feed_id : int + RSS feed ID. + filter_name : str + Filter name. + match : str + Match pattern. + not_match : str + Not match pattern. + destination : str + Download destination. + is_regex : bool, optional + Use regex for matching (default is False). + + Returns + ------- + dict[str, object] or str + API response. + """ + + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.RSS.Filter' + info = self.download_list[api_name] + api_path = info['path'] + + param = {'version': info['maxVersion'], 'method': 'add', 'feed_id': feed_id, + 'name': f'"{filter_name}"', 'match': f'"{match}"', 'not_match': f'"{not_match}"', + 'destination': f'"{destination}"', 'is_regex': str(is_regex).lower()} + + if type(is_regex) is not bool: + return 'Please set is_regex to True or False' + + if feed_id is None: + return 'Enter a valid ID check if you have any with get_rss_info_list()' + + return self.request_data(api_name, api_path, param) + + def rss_feed_filter_set(self, + filter_id: int = None, + filter_name: str = None, + match: str = None, + not_match: str = None, + destination: str = None, + is_regex: bool = False + ) -> dict[str, object] | str: + """ + Set RSS feed filter. + + Parameters + ---------- + filter_id : int + Filter ID. + filter_name : str + Filter name. + match : str + Match pattern. + not_match : str + Not match pattern. + destination : str + Download destination. + is_regex : bool, optional + Use regex for matching (default is False). + + Returns + ------- + dict[str, object] or str + API response. + """ + + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.RSS.Filter' + info = self.download_list[api_name] + api_path = info['path'] + + param = {'version': info['maxVersion'], 'method': 'set', 'feed_id': 'null', 'id': filter_id, + 'name': f'"{filter_name}"', 'match': f'"{match}"', 'not_match': f'"{not_match}"', + 'destination': f'"{destination}"', 'is_regex': str(is_regex).lower()} + + if type(is_regex) is not bool: + return 'Please set is_regex to True or False' + + if filter_id is None: + return 'Enter a valid ID check if you have any with rss_feed_filter_list()' + + return self.request_data(api_name, api_path, param) + + def rss_feed_filter_delete(self, + filter_id: int = None, + ) -> dict[str, object] | str: + """ + Delete RSS feed filter. + + Parameters + ---------- + filter_id : int + Filter ID. + + Returns + ------- + dict[str, object] or str + API response. + """ + + api_name = 'SYNO.DownloadStation' + self.download_st_version + '.RSS.Filter' + info = self.download_list[api_name] + api_path = info['path'] + + param = {'version': info['maxVersion'], + 'method': 'delete', 'id': filter_id} + + if filter_id is None: + return 'Enter a valid ID check if you have any with rss_feed_filter_list()' + + return self.request_data(api_name, api_path, param) + def start_bt_search(self, keyword: Optional[str] = None, module: str = 'all') -> dict[str, object] | str: + """ + Start a BT search. + + Parameters + ---------- + keyword : Optional[str], optional + Search keyword. + module : str, optional + BT search module (default is 'all'). + + Returns + ------- + dict[str, object] or str + BT search task information or message. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.BTSearch' info = self.download_list[api_name] api_path = info['path'] @@ -302,6 +989,31 @@ def get_bt_search_results(self, filter_category: Optional[str] = None, filter_title: Optional[str] = None ) -> dict[str, object] | str: + """ + Get BT search results. + + Parameters + ---------- + taskid : Optional[str], optional + BT search task ID. + offset : Optional[int], optional + Offset for pagination. + limit : Optional[int], optional + Maximum number of results to retrieve. + sort_by : Optional[str], optional + Field to sort by. + sort_direction : Optional[str], optional + Sort direction. + filter_category : Optional[str], optional + Filter by category. + filter_title : Optional[str], optional + Filter by title. + + Returns + ------- + dict[str, object] or str + BT search results. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.BTSearch' info = self.download_list[api_name] api_path = info['path'] @@ -321,6 +1033,14 @@ def get_bt_search_results(self, return self.request_data(api_name, api_path, param) def get_bt_search_category(self) -> dict[str, object] | str: + """ + Get BT search categories. + + Returns + ------- + dict[str, object] or str + BT search categories. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.BTSearch' info = self.download_list[api_name] api_path = info['path'] @@ -329,6 +1049,19 @@ def get_bt_search_category(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, param) def clean_bt_search(self, taskid: Optional[str | list[str]] = None) -> dict[str, object] | str: + """ + Clean BT search tasks. + + Parameters + ---------- + taskid : Optional[str or list[str]], optional + BT search task ID(s). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.BTSearch' info = self.download_list[api_name] api_path = info['path'] @@ -347,6 +1080,14 @@ def clean_bt_search(self, taskid: Optional[str | list[str]] = None) -> dict[str, return self.request_data(api_name, api_path, param) def get_bt_module(self) -> dict[str, object] | str: + """ + Get BT search modules. + + Returns + ------- + dict[str, object] or str + BT search modules. + """ api_name = 'SYNO.DownloadStation' + self.download_st_version + '.BTSearch' info = self.download_list[api_name] api_path = info['path'] diff --git a/synology_api/drive_admin_console.py b/synology_api/drive_admin_console.py index 298f68aa..6b6b7fa7 100644 --- a/synology_api/drive_admin_console.py +++ b/synology_api/drive_admin_console.py @@ -1,11 +1,32 @@ +""" +Synology Drive Admin Console API wrapper. + +This module provides a Python interface for managing Synology Drive Admin Console, +including status, configuration, connections, logs, shares, and settings. +""" + from __future__ import annotations from typing import Optional from . import base_api class AdminConsole(base_api.BaseApi): + """ + Synology Drive Admin Console API implementation. + + This class provides methods to retrieve and manage Synology Drive Admin Console status, + configuration, connections, logs, shares, and settings. + """ def status_info(self) -> dict[str, object] | str: + """ + Get Synology Drive status information. + + Returns + ------- + dict[str, object] or str + Status information. + """ api_name = 'SYNO.SynologyDrive' info = self.gen_list[api_name] api_path = info['path'] @@ -14,6 +35,14 @@ def status_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def config_info(self) -> dict[str, object] | str: + """ + Get Synology Drive configuration information. + + Returns + ------- + dict[str, object] or str + Configuration information. + """ api_name = 'SYNO.SynologyDrive.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -22,6 +51,14 @@ def config_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def connections(self) -> dict[str, object] | str: + """ + Get summary of Synology Drive connections. + + Returns + ------- + dict[str, object] or str + Connections summary. + """ api_name = 'SYNO.SynologyDrive.Connection' info = self.gen_list[api_name] api_path = info['path'] @@ -30,6 +67,14 @@ def connections(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def drive_check_user(self) -> dict[str, object] | str: + """ + Check user status in Synology Drive. + + Returns + ------- + dict[str, object] or str + User check result. + """ api_name = 'SYNO.SynologyDrive' info = self.gen_list[api_name] api_path = info['path'] @@ -38,6 +83,14 @@ def drive_check_user(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def active_connections(self) -> dict[str, object] | str: + """ + Get list of active Synology Drive connections. + + Returns + ------- + dict[str, object] or str + List of active connections. + """ api_name = 'SYNO.SynologyDrive.Connection' info = self.gen_list[api_name] api_path = info['path'] @@ -46,6 +99,14 @@ def active_connections(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def active_sync_connections(self) -> dict[str, object] | str: + """ + Get list of active Synology Drive ShareSync connections. + + Returns + ------- + dict[str, object] or str + List of active ShareSync connections. + """ api_name = 'SYNO.SynologyDriveShareSync.Connection' info = self.gen_list[api_name] api_path = info['path'] @@ -54,6 +115,14 @@ def active_sync_connections(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def share_active_list(self) -> dict[str, object] | str: + """ + Get list of active shares in Synology Drive. + + Returns + ------- + dict[str, object] or str + List of active shares. + """ api_name = 'SYNO.SynologyDrive.Share' info = self.gen_list[api_name] api_path = info['path'] @@ -61,16 +130,44 @@ def share_active_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) - def log(self, - share_type: str = 'all', - get_all: bool = False, - limit: int = 1000, - keyword: str = '', - date_from: int = 0, - date_to: int = 0, - username: str = '', - target: str = 'user' - ) -> dict[str, object] | str: + def log( + self, + share_type: str = 'all', + get_all: bool = False, + limit: int = 1000, + keyword: str = '', + date_from: int = 0, + date_to: int = 0, + username: str = '', + target: str = 'user' + ) -> dict[str, object] | str: + """ + Get Synology Drive logs. + + Parameters + ---------- + share_type : str, optional + Type of share to filter logs (default is 'all'). + get_all : bool, optional + Whether to get all logs (default is False). + limit : int, optional + Maximum number of logs to return (default is 1000). + keyword : str, optional + Keyword to filter logs (default is ''). + date_from : int, optional + Start date in epoch format (default is 0). + date_to : int, optional + End date in epoch format (default is 0). + username : str, optional + Username to filter logs (default is ''). + target : str, optional + Target type to filter logs (default is 'user'). + + Returns + ------- + dict[str, object] or str + Log information. + """ api_name = 'SYNO.SynologyDrive.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -89,6 +186,14 @@ def log(self, return self.request_data(api_name, api_path, req_param) def c2fs_share(self) -> dict[str, object] | str: + """ + Get list of C2FS shares. + + Returns + ------- + dict[str, object] or str + List of C2FS shares. + """ api_name = 'SYNO.C2FS.Share' info = self.gen_list[api_name] api_path = info['path'] @@ -97,6 +202,14 @@ def c2fs_share(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def settings(self) -> dict[str, object] | str: + """ + Get Synology Drive settings. + + Returns + ------- + dict[str, object] or str + Settings information. + """ api_name = 'SYNO.SynologyDrive.Settings' info = self.gen_list[api_name] api_path = info['path'] @@ -105,6 +218,14 @@ def settings(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def db_usage(self) -> dict[str, object] | str: + """ + Get Synology Drive database usage. + + Returns + ------- + dict[str, object] or str + Database usage information. + """ api_name = 'SYNO.SynologyDrive.DBUsage' info = self.gen_list[api_name] api_path = info['path'] @@ -113,6 +234,14 @@ def db_usage(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def delete_status(self) -> dict[str, object] | str: + """ + Get status of deleted nodes in Synology Drive. + + Returns + ------- + dict[str, object] or str + Delete status information. + """ api_name = 'SYNO.SynologyDrive.Node.Delete' info = self.gen_list[api_name] api_path = info['path'] @@ -121,6 +250,14 @@ def delete_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def file_property_transfer_status(self) -> dict[str, object] | str: + """ + Get file property transfer status for User Home migration. + + Returns + ------- + dict[str, object] or str + File property transfer status. + """ api_name = 'SYNO.SynologyDrive.Migration.UserHome' info = self.gen_list[api_name] api_path = info['path'] @@ -129,6 +266,23 @@ def file_property_transfer_status(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def user_sync_profile(self, user: str = '', start: int = 0, limit: str | int = 'null') -> dict[str, object] | str: + """ + Get user sync profile(s). + + Parameters + ---------- + user : str, optional + Username to filter profiles (default is ''). + start : int, optional + Start index for pagination (default is 0). + limit : str or int, optional + Maximum number of profiles to return (default is 'null'). + + Returns + ------- + dict[str, object] or str + User sync profile information. + """ api_name = 'SYNO.SynologyDrive.Profiles' info = self.gen_list[api_name] api_path = info['path'] @@ -138,6 +292,19 @@ def user_sync_profile(self, user: str = '', start: int = 0, limit: str | int = ' return self.request_data(api_name, api_path, req_param) def index_pause(self, time_pause: int = 60) -> dict[str, object] | str: + """ + Pause native client index for a specified duration. + + Parameters + ---------- + time_pause : int, optional + Pause duration in seconds (default is 60). + + Returns + ------- + dict[str, object] or str + API response. + """ api_name = 'SYNO.SynologyDrive.Index' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/error_codes.py b/synology_api/error_codes.py index 551546f3..a9d1c87c 100644 --- a/synology_api/error_codes.py +++ b/synology_api/error_codes.py @@ -1,3 +1,4 @@ +"""Synology API Error Codes.""" # source: pages 8 and 16 on PDF: # https://global.download.synology.com/download/Document/Software/DeveloperGuide/Os/DSM/All/enu/DSM_Login_Web_API_Guide_enu.pdf @@ -124,6 +125,37 @@ 420: 'Illegal file name on FAT file system', 421: 'Device or resource busy', 599: 'No such task of the file operation', + 800: 'A folder path of favorite folder is already added to user\'s favorites', + 801: 'A name of favorite folder conflicts with an existing folder path in the user\'s favorties', + 802: 'There are too many favorites to be added', + 900: 'Failed to delete file(s)/folder(s). More information in object', + 1000: 'Failed to copy files/folders. More information in object.', + 1001: 'Failed to move files/folders. More information in object.', + 1002: 'An error occurred at the destination. More information in object.', + 1003: 'Cannot overwrite or skip the existing file because no overwrite parameter is given.', + 1004: 'File cannot overwrite a folder with the same name, or folder cannot overwrite a file with the same name.', + 1006: 'Cannot copy/move file/folder with special characters to a FAT32 file system.', + 1007: 'Cannot copy/move a file bigger than 4G to a FAT32 file system.', + 1100: 'Failed to create a folder. More information in object.', + 1101: 'The number of folders to the parent folder would exceed the system limitation.', + 1200: 'Failed to rename it. more information in object.', + 1300: 'Failed to compress files/folders.', + 1301: ' Cannot create the archive because the given archive name is too long.', + 1400: 'Failed to extract files.', + 1401: 'Cannot open the file as archive.', + 1402: 'Failed to read archive data error', + 1403: 'Wrong password.', + 1404: 'Failed to get the file and dir list in an archive.', + 1405: 'Failed to find the item ID in an archive file.', + 1800: 'There is no Content-Length information in the HTTP header or the received size doesn\'t match the value of Content-Length information in the HTTP header', + 1801: 'Wait too long, no date can be received from client (Default maximum wait time is 3600 seconds)', + 1802: 'No filename information in the last part of file content', + 1803: 'Upload connection is cancelled', + 1804: 'Failed to upload oversized file to FAT file system', + 1805: 'Can\'t overwrite or skip the existing file, if no overwrite parameter is given', + 2000: 'Sharing link does not exist.', + 2001: 'Cannot generate sharing link because too many sharing links exist', + 2002: 'Failed to access sharing links', } # Source: https://global.synologydownload.com/download/Document/Software/DeveloperGuide/Package/Virtualization/All diff --git a/synology_api/event_scheduler.py b/synology_api/event_scheduler.py index 40cfd201..69efe5f0 100644 --- a/synology_api/event_scheduler.py +++ b/synology_api/event_scheduler.py @@ -1,3 +1,9 @@ +""" +Event Scheduler API module. + +This module provides the EventScheduler class for managing event-based tasks and power schedules +on Synology NAS devices via the SYNO.Core.EventScheduler API. +""" from __future__ import annotations from . import base_api from .core_sys_info import SysInfo @@ -6,26 +12,36 @@ class EventScheduler(base_api.BaseApi): - """Event Scheduler API implementation. - - This API provides functionality solely related to Event Tasks. For scheduled tasks, check `TaskScheduler`. - - Supported methods: - - Getters: - - Get task results - - Get result output - - Setters: - - Set task settings - - Set power schedule - - Actions: - - Enable task - - Disable task - - Run task - - Delete task - - Create task + """ + Event Scheduler API implementation. + + This API provides functionality solely related to Event Tasks. For scheduled tasks, check `TaskScheduler`. + + Methods + ------- + Getters: + - Get task results + - Get result output + Setters: + - Set task settings + - Set power schedule + Actions: + - Enable task + - Disable task + - Run task + - Delete task + - Create task """ def __get_root_token(self) -> str: + """ + Get the SynoConfirmPWToken for root operations. + + Returns + ------- + str + The SynoConfirmPWToken if successful, otherwise an empty string. + """ sys_info = SysInfo(ip_address=self.session._ip_address, port=self.session._port, username=self.session._username, password=self.session._password, secure=self.session._secure, cert_verify=self.session._verify, dsm_version=self.session._version, debug=self.session._debug, otp_code=self.session._otp_code, application=self.application) @@ -39,42 +55,43 @@ def get_task_results( self, task_name: str ) -> dict[str, object] | str: - """Retrieve the results list for a specific task. - - Parameters - ---------- - task_name : str - Name of the Event task to enable/disable. - - Returns - ------- - dict[str, object] - A dictionary containing the task results. - - Examples - -------- - ```json - { - "data": [ - { - "event_fire_time": "2024-09-13 03:17:47", - "exit_info": { - "exit_code": 0, - "exit_type": "stop" - }, - "extra": {}, - "pid": 16058, - "result_id": 115, - "run_time_env": {}, - "start_time": "2024-09-13 03:17:47", - "stop_time": "2024-09-13 03:17:47", - "task_name": "asd", - "trigger_event": "on_demand" - } - ], - "success": true - } - ``` + """ + Retrieve the results list for a specific task. + + Parameters + ---------- + task_name : str + Name of the Event task to enable/disable. + + Returns + ------- + dict[str, object] + A dictionary containing the task results. + + Examples + -------- + ```json + { + "data": [ + { + "event_fire_time": "2024-09-13 03:17:47", + "exit_info": { + "exit_code": 0, + "exit_type": "stop" + }, + "extra": {}, + "pid": 16058, + "result_id": 115, + "run_time_env": {}, + "start_time": "2024-09-13 03:17:47", + "stop_time": "2024-09-13 03:17:47", + "task_name": "asd", + "trigger_event": "on_demand" + } + ], + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' info = self.gen_list[api_name] @@ -92,32 +109,32 @@ def get_result_output( task_name: str, result_id: int ) -> dict[str, object] | str: - """Retrieve the output for a given result. - - Parameters - ---------- - task_name : str - Name of the Event task to enable/disable. - - result_id : int - ID of the result to retrieve. From get_task_results(). - - Returns - ------- - dict[str, object] - A dictionary containing the result output. - - Examples - -------- - ```json - { - "data": { - "script_in": "hello", - "script_out": "/volume3/datastore/scripts_output/asd/1726190267/script.log: line 1: hello: command not found\\n" - }, - "success": true - } - ``` + """ + Retrieve the output for a given result. + + Parameters + ---------- + task_name : str + Name of the Event task to enable/disable. + result_id : int + ID of the result to retrieve. From get_task_results(). + + Returns + ------- + dict[str, object] + A dictionary containing the result output. + + Examples + -------- + ```json + { + "data": { + "script_in": "hello", + "script_out": "/volume3/datastore/scripts_output/asd/1726190267/script.log: line 1: hello: command not found\\n" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' info = self.gen_list[api_name] @@ -136,29 +153,28 @@ def task_set_enable( task_name: str, enable: bool ) -> dict[str, object] | str: - """Enable or disable Event task. - - Parameters - ---------- - task_name : str - Name of the Event task to enable/disable. - - enable (bool): - Wheter to enable (`True`) or disable (`False`) the task. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the action. - - Examples - -------- - ```json - { - "success": true - } - ``` - + """ + Enable or disable Event task. + + Parameters + ---------- + task_name : str + Name of the Event task to enable/disable. + enable : bool + Whether to enable (`True`) or disable (`False`) the task. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the action. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' info = self.gen_list[api_name] @@ -176,25 +192,26 @@ def task_run( self, task_name: str ) -> dict[str, object] | str: - """Run a specific Event task. - - Parameters - ---------- - task_name : str - Name of the Event task to run. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the task execution. - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Run a specific Event task. + + Parameters + ---------- + task_name : str + Name of the Event task to run. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the task execution. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' @@ -212,26 +229,26 @@ def task_delete( self, task_name: str ) -> dict[str, object] | str: - """Delete a specific Event task. - - Parameters - ---------- - task_name : str - Name of the Event task to run. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the task deletion. - - Examples - -------- - ```json - ---------- - { - "success": true - } - ``` + """ + Delete a specific Event task. + + Parameters + ---------- + task_name : str + Name of the Event task to run. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the task deletion. + + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' @@ -257,61 +274,51 @@ def task_create_or_set( notify_email: str = '', notify_only_on_error: bool = False ) -> dict[str, object] | str: - """Create or modify an event-based task. - - Parameters - ---------- - action : str - Action to perform on the task. - - Possible values: - - `create` -> Creates a new task. - - `set` -> Modify an existing task. - - task_name : str - The name of the task. - - owner : dict[str, str] - Dictionary containing the owner's ID and name (e.g., `{"1026": "user1"}`). - - You can get the user UID by running `synouser --get your_user` in your NAS CLI. - - For root privileges, pass `{"0":"root"}`. - - trigger_event : str - The event that triggers the task. - - Possible values: - - `shutdown` - - `bootup` - - script : str - The script to be executed when the task is triggered. - - depend_on_task : list[str], optional - A list of event triggered task names that this task depends on (i.e., tasks that will be run before this one). Defaults to `[]`. - - enable : bool, optional - Whether to enable the task. Defaults to `True`. - - notify_email : str, optional - Email address to send notifications to. Defaults to `""`, thus disabling the notification feature. - - notify_only_on_error : bool, optional - If `True`, notifications are only sent when an error occurs. Defaults to `False`. - - Returns - ------- - dict[str, object] - A dictionary containing the result of the task creation or modification, or a strnig in case of an error. - - Examples - -------- - ```json - { - "success": true - } - ``` + """ + Create or modify an event-based task. + + Parameters + ---------- + action : str + Action to perform on the task. + + Possible values: + - `create` -> Create a new task. + - `set` -> Modify an existing task. + task_name : str + The name of the task. + owner : dict[str, str] + Dictionary containing the owner's ID and name (e.g., `{"1026": "user1"}`). + You can get the user UID by running `synouser --get your_user` in your NAS CLI. + For root privileges, pass `{"0":"root"}`. + trigger_event : str + The event that triggers the task. + Possible values: + - `shutdown` + - `bootup` + script : str + The script to be executed when the task is triggered. + depend_on_task : list[str], optional + A list of event triggered task names that this task depends on (i.e., tasks that will be run before this one). Defaults to `[]`. + enable : bool, optional + Whether to enable the task. Defaults to `True`. + notify_email : str, optional + Email address to send notifications to. Defaults to `""`, thus disabling the notification feature. + notify_only_on_error : bool, optional + If `True`, notifications are only sent when an error occurs. Defaults to `False`. + + Returns + ------- + dict[str, object] + A dictionary containing the result of the task creation or modification, or a string in case of an error. + + Examples + -------- + ```json + { + "success": true + } + ``` """ if action != 'create' and action != 'set': return {'error': f'action <{action}> is not valid.'} @@ -348,55 +355,57 @@ def task_create_or_set( return self.request_data(api_name, api_path, req_param) def set_power_schedule(self, poweron_tasks: List[dict] = [], poweroff_tasks: List[dict] = []) -> dict: - """Set the power schedule, poweron tasks and poweroff tasks - - Parameters - ---------- - poweron_tasks : List[dict], optional - List of tasks for power on. Defaults to `[]` - Example of a task: - ```python - { - "enabled": True, # Enable or not the task - "hour": 13, # Hour 0-23 - "min": 59, # Minutes 0-59 - "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday) - } - ``` - poweroff_tasks : List[dict], optional - List of tasks for power off. Defaults to `[]` - Example of a task: - ```python - { - "enabled": True, # Enable or not the task - "hour": 13, # Hour 0-23 - "min": 59, # Minutes 0-59 - "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thrusday, Friday, Saturday) - } - ``` - Returns - ------- - dict - List of tasks in power schedule - - Examples - -------- - ```json + """ + Set the power schedule, poweron tasks and poweroff tasks. + + Parameters + ---------- + poweron_tasks : List[dict], optional + List of tasks for power on. Defaults to `[]`. + Example of a task: + ```python { - "data": { - "poweroff_tasks": [], - "poweron_tasks": [ - { - "enabled": true, - "hour": 0, - "min": 0, - "weekdays": "1,2,3,4,5" - } - ] - }, - "success": true + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) } ``` + poweroff_tasks : List[dict], optional + List of tasks for power off. Defaults to `[]`. + Example of a task: + ```python + { + "enabled": True, # Enable or not the task + "hour": 13, # Hour 0-23 + "min": 59, # Minutes 0-59 + "weekdays": "0,1,2,3,4,5,6" # All days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday) + } + ``` + + Returns + ------- + dict + List of tasks in power schedule. + + Examples + -------- + ```json + { + "data": { + "poweroff_tasks": [], + "poweron_tasks": [ + { + "enabled": true, + "hour": 0, + "min": 0, + "weekdays": "1,2,3,4,5" + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Hardware.PowerSchedule' @@ -412,31 +421,32 @@ def set_power_schedule(self, poweron_tasks: List[dict] = [], poweroff_tasks: Lis return self.request_data(api_name, api_path, req_param) def load_power_schedule(self) -> dict: - """Load the power schedule, poweron tasks and poweroff tasks - - Returns - ------- - dict - List of tasks in power schedule - - Examples - -------- - ```json - { - "data": { - "poweroff_tasks": [], - "poweron_tasks": [ - { - "enabled": true, - "hour": 0, - "min": 0, - "weekdays": "1,2,3,4,5" - } - ] - }, - "success": true - } - ``` + """ + Load the power schedule, poweron tasks and poweroff tasks. + + Returns + ------- + dict + List of tasks in power schedule. + + Examples + -------- + ```json + { + "data": { + "poweroff_tasks": [], + "poweron_tasks": [ + { + "enabled": true, + "hour": 0, + "min": 0, + "weekdays": "1,2,3,4,5" + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Hardware.PowerSchedule' diff --git a/synology_api/exceptions.py b/synology_api/exceptions.py index aa12cd9a..3fb409e3 100644 --- a/synology_api/exceptions.py +++ b/synology_api/exceptions.py @@ -1,12 +1,40 @@ +""" +Exception classes for Synology API. + +This module defines custom exception classes for handling errors and error codes +returned by various Synology API endpoints. +""" + from .error_codes import error_codes, auth_error_codes, download_station_error_codes, file_station_error_codes, core_error_codes from .error_codes import virtualization_error_codes # Base exception: class SynoBaseException(Exception): - """Base class for an exception. Defines error_message.""" + """ + Base class for an exception. + + Defines error_message. + + Parameters + ---------- + error_message : str + The error message describing the exception. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_message: str, *args: object) -> None: + """ + Initialize SynoBaseException. + + Parameters + ---------- + error_message : str + The error message describing the exception. + *args : object + Additional arguments to pass to the base Exception. + """ super().__init__(*args) self.error_message = error_message return @@ -14,34 +42,110 @@ def __init__(self, error_message: str, *args: object) -> None: # Classes to reraise Exceptions from requests. class SynoConnectionError(SynoBaseException): - """Class to raise when a connection error occurs.""" + """ + Exception raised when a connection error occurs. + + Parameters + ---------- + error_message : str + The error message describing the connection error. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_message: str, *args: object) -> None: + """ + Initialize SynoConnectionError. + + Parameters + ---------- + error_message : str + The error message describing the connection error. + *args : object + Additional arguments to pass to the base Exception. + """ super().__init__(error_message=error_message, *args) return class HTTPError(SynoBaseException): - """Class to raise when a http error occurs.""" + """ + Exception raised when an HTTP error occurs. + + Parameters + ---------- + error_message : str + The error message describing the HTTP error. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_message: str, *args: object) -> None: + """ + Initialize HTTPError. + + Parameters + ---------- + error_message : str + The error message describing the HTTP error. + *args : object + Additional arguments to pass to the base Exception. + """ super().__init__(error_message, *args) return class JSONDecodeError(SynoBaseException): - """Class to raise when server fails to send JSON.""" + """ + Exception raised when the server fails to send valid JSON. + + Parameters + ---------- + error_message : str + The error message describing the JSON decode error. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_message: str, *args: object) -> None: + """ + Initialize JSONDecodeError. + + Parameters + ---------- + error_message : str + The error message describing the JSON decode error. + *args : object + Additional arguments to pass to the base Exception. + """ super().__init__(error_message, *args) return # Classes for when we receive an error code in the JSON from the server. class LoginError(SynoBaseException): - """Class for an error during login.""" + """ + Exception raised for an error during login. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize LoginError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code: int = error_code if error_code not in error_codes.keys(): super().__init__(error_message=auth_error_codes[error_code], *args) @@ -51,9 +155,28 @@ def __init__(self, error_code: int, *args: object) -> None: class LogoutError(SynoBaseException): - """Class for an error during logout.""" + """ + Exception raised for an error during logout. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize LogoutError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code: int = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -63,9 +186,28 @@ def __init__(self, error_code: int, *args: object) -> None: class DownloadStationError(SynoBaseException): - """Class for an error during a download station request.""" + """ + Exception raised for an error during a Download Station request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize DownloadStationError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code: int = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -78,9 +220,28 @@ def __init__(self, error_code: int, *args: object) -> None: class FileStationError(SynoBaseException): - """Class for an error during a file station request.""" + """ + Exception raised for an error during a File Station request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize FileStationError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code: int = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -93,9 +254,28 @@ def __init__(self, error_code: int, *args: object) -> None: class VirtualizationError(SynoBaseException): - """Class for an error during a virtualization request.""" + """ + Exception raised for an error during a virtualization request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize VirtualizationError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -108,10 +288,28 @@ def __init__(self, error_code: int, *args: object) -> None: class AudioStationError(SynoBaseException): - """Class for an error during an audio station request. NOTE: I can't find any documentation on the audio station - webAPI errors numbers and their respective messages.""" + """ + Exception raised for an error during an Audio Station request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize AudioStationError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -121,10 +319,28 @@ def __init__(self, error_code: int, *args: object) -> None: class ActiveBackupError(SynoBaseException): - """Class for an error during ActiveBackup request. NOTE: I can't find any documentation on error codes or their - respective messages.""" + """ + Exception raised for an error during an Active Backup request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize ActiveBackupError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -133,10 +349,28 @@ def __init__(self, error_code: int, *args: object) -> None: class ActiveBackupMicrosoftError(SynoBaseException): - """Class for an error during ActiveBackupMicrosoft request. NOTE: I can't find any documentation on error codes or their - respective messages.""" + """ + Exception raised for an error during an Active Backup Microsoft request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize ActiveBackupMicrosoftError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -145,9 +379,28 @@ def __init__(self, error_code: int, *args: object) -> None: class BackupError(SynoBaseException): - """Class for an error during backup request. NOTE: Again I can't find error code documentation.""" + """ + Exception raised for an error during a backup request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize BackupError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -157,9 +410,28 @@ def __init__(self, error_code: int, *args: object) -> None: class CertificateError(SynoBaseException): - """Class for an error during Core.Certificate request. NOTE: Lacking documentation.""" + """ + Exception raised for an error during a Core.Certificate request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize CertificateError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code]) @@ -169,9 +441,28 @@ def __init__(self, error_code: int, *args: object) -> None: class CloudSyncError(SynoBaseException): - """Class for an error during SYNO.CloudSync request. NOTE: Lacking documentation.""" + """ + Exception raised for an error during a SYNO.CloudSync request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize CloudSyncError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code]) @@ -181,9 +472,28 @@ def __init__(self, error_code: int, *args: object) -> None: class DHCPServerError(SynoBaseException): - """Class for an error during a DHCPServer request.""" + """ + Exception raised for an error during a DHCPServer request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize DHCPServerError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -193,9 +503,28 @@ def __init__(self, error_code: int, *args: object) -> None: class DirectoryServerError(SynoBaseException): - """Class for an error during a directory server request. NOTE: No docs on errors.""" + """ + Exception raised for an error during a Directory Server request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize DirectoryServerError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -205,9 +534,28 @@ def __init__(self, error_code: int, *args: object) -> None: class DockerError(SynoBaseException): - """Class for an error during a docker request. NOTE: No docs on errors.""" + """ + Exception raised for an error during a Docker request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize DockerError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -217,9 +565,28 @@ def __init__(self, error_code: int, *args: object) -> None: class DriveAdminError(SynoBaseException): - """Class for an error during a drive admin request. NOTE: No error docs.""" + """ + Exception raised for an error during a Drive Admin request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize DriveAdminError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -229,9 +596,28 @@ def __init__(self, error_code: int, *args: object) -> None: class LogCenterError(SynoBaseException): - """Class for an error during a LogCenter request. NOTE: No docs on errors.... again.""" + """ + Exception raised for an error during a LogCenter request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize LogCenterError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -241,9 +627,28 @@ def __init__(self, error_code: int, *args: object) -> None: class NoteStationError(SynoBaseException): - """Class for an error during a NoteStation request. NOTE: No error docs.""" + """ + Exception raised for an error during a NoteStation request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize NoteStationError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -253,9 +658,28 @@ def __init__(self, error_code: int, *args: object) -> None: class OAUTHError(SynoBaseException): - """Class for an error during a OAUTH request. NOTE: No error docs.""" + """ + Exception raised for an error during an OAUTH request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize OAUTHError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -265,9 +689,28 @@ def __init__(self, error_code: int, *args: object) -> None: class PhotosError(SynoBaseException): - """Class for an error during a Photos request. NOTE: No error docs.""" + """ + Exception raised for an error during a Photos request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize PhotosError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -277,9 +720,28 @@ def __init__(self, error_code: int, *args: object) -> None: class SecurityAdvisorError(SynoBaseException): - """Class for an error during a SecurityAdvisor request. NOTE: What docs?""" + """ + Exception raised for an error during a SecurityAdvisor request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize SecurityAdvisorError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -289,9 +751,28 @@ def __init__(self, error_code: int, *args: object) -> None: class TaskSchedulerError(SynoBaseException): - """Class for an error during TaskScheduler request. NOTE:... no docs on errors....""" + """ + Exception raised for an error during a TaskScheduler request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize TaskSchedulerError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -301,9 +782,28 @@ def __init__(self, error_code: int, *args: object) -> None: class EventSchedulerError(SynoBaseException): - """Class for an error during EventScheduler request. NOTE:... no docs on errors....""" + """ + Exception raised for an error during an EventScheduler request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize EventSchedulerError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -313,9 +813,28 @@ def __init__(self, error_code: int, *args: object) -> None: class UniversalSearchError(SynoBaseException): - """Class for an error during UniversalSearch request. NOTE:... no docs on errors....""" + """ + Exception raised for an error during a UniversalSearch request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize UniversalSearchError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -325,9 +844,28 @@ def __init__(self, error_code: int, *args: object) -> None: class USBCopyError(SynoBaseException): - """Class for an error during a USBCopy request. NOTE: No docs on errors.""" + """ + Exception raised for an error during a USBCopy request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize USBCopyError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -336,9 +874,28 @@ def __init__(self, error_code: int, *args: object) -> None: class VPNError(SynoBaseException): - """Class for an error during a VPN request. NOTE: No docs on errors.""" + """ + Exception raised for an error during a VPN request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize VPNError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -348,10 +905,28 @@ def __init__(self, error_code: int, *args: object) -> None: class CoreError(SynoBaseException): - """Class for an error during a SYNO.Core.* + """ + Exception raised for an error during a SYNO.Core.* request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize CoreError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in core_error_codes.keys(): super().__init__(error_message=core_error_codes[error_code], *args) @@ -361,11 +936,28 @@ def __init__(self, error_code: int, *args: object) -> None: class CoreSysInfoError(SynoBaseException): - """Class for an error during a 'SYNO.Backup.Service.NetworkBackup', SYNO.Storage.*, - 'SYNO.Finder.FileIndexing.Status', 'SYNO.S2S.Server.Pair', SYNO.ResourceMonitor.* + """ + Exception raised for an error during a CoreSysInfoError request. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. """ def __init__(self, error_code: int, *args: object) -> None: + """ + Initialize CoreSysInfoError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code if error_code in error_codes.keys(): super().__init__(error_message=error_codes[error_code], *args) @@ -375,9 +967,32 @@ def __init__(self, error_code: int, *args: object) -> None: class UndefinedError(SynoBaseException): - """Class for undefined errors.""" + """ + Exception raised for undefined errors. + + Parameters + ---------- + error_code : int + The error code returned by the API. + api_name : str + The name of the API where the error occurred. + *args : object + Additional arguments to pass to the base Exception. + """ def __init__(self, error_code: int, api_name: str, *args: object) -> None: + """ + Initialize UndefinedError. + + Parameters + ---------- + error_code : int + The error code returned by the API. + api_name : str + The name of the API where the error occurred. + *args : object + Additional arguments to pass to the base Exception. + """ self.error_code = error_code self.api_name = api_name super().__init__(error_message="Undefined Error: API: %s, Code: %i" % diff --git a/synology_api/filestation.py b/synology_api/filestation.py index 16e03d8f..010035c4 100644 --- a/synology_api/filestation.py +++ b/synology_api/filestation.py @@ -1,20 +1,72 @@ +""" +FileStation API module. + +This module provides the FileStation class for interacting with Synology NAS FileStation API, +allowing file management, search, upload, download, and background task operations. +""" + from __future__ import annotations + +import json from typing import Optional, Any import os import io import time from datetime import datetime +from urllib.parse import urljoin, urlencode import requests import tqdm from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor import sys +import warnings from urllib import parse from treelib import Tree from . import base_api +from .utils import validate_path, get_data_for_request_from_file class FileStation(base_api.BaseApi): + """ + FileStation API implementation. + + Provides methods to interact with Synology NAS FileStation API for file and folder operations, + search, upload, download, and background task management. + + Parameters + ---------- + ip_address : str + IP address of the Synology NAS. + port : str + Port number for the connection. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP otherwise. Default is False. + cert_verify : bool, optional + Verify SSL certificates if True. Default is False. + dsm_version : int, optional + DSM version of the Synology NAS. Default is 7. + debug : bool, optional + Enable debug output if True. Default is True. + otp_code : str, optional + One-time password for 2-step verification. Default is None. + device_id : str, optional + Device ID for authentication. Default is None. + device_name : str, optional + Name of the device. Default is None. + interactive_output : bool, optional + If True, enables interactive output. Default is False. + + Methods + ------- + get_info() + Get FileStation information. + get_list_share() + List shared folderss. + """ def __init__(self, ip_address: str, @@ -30,7 +82,36 @@ def __init__(self, device_name: Optional[str] = None, interactive_output: bool = True ) -> None: - + """ + Initialize FileStation API client. + + Parameters + ---------- + ip_address : str + IP address or hostname of the Synology NAS. + port : str + Port number for the API. + username : str + Username for authentication. + password : str + Password for authentication. + secure : bool, optional + Use HTTPS if True, HTTP if False. Default is False. + cert_verify : bool, optional + Verify SSL certificates if True. Default is False. + dsm_version : int, optional + DSM version. Default is 7. + debug : bool, optional + Enable debug output. Default is True. + otp_code : str, optional + One-time password for 2FA, if required. + device_id : str, optional + Device ID for authentication. + device_name : str, optional + Device name for authentication. + interactive_output : bool, optional + If True, outputs are formatted for interactive use. Default is True. + """ super(FileStation, self).__init__(ip_address, port, username, password, secure, cert_verify, dsm_version, debug, otp_code, device_id, device_name, 'FileStation') @@ -51,11 +132,19 @@ def __init__(self, self.session.get_api_list('FileStation') - self.file_station_list: Any = self.session.app_api_list + self.file_station_list: dict = self.session.app_api_list self.interactive_output: bool = interactive_output def get_info(self) -> dict[str, object] | str: + """ + Get FileStation information. + + Returns + ------- + dict[str, object] or str + FileStation information or error message. + """ api_name = 'SYNO.FileStation.Info' info = self.file_station_list[api_name] api_path = info['path'] @@ -71,7 +160,29 @@ def get_list_share(self, sort_direction: Optional[str] = None, onlywritable: bool = False ) -> dict[str, object] | str: - + """ + List shared folders. + + Parameters + ---------- + additional : str or list of str, optional + Additional attributes to include. + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + onlywritable : bool, optional + If True, only writable shares are listed. + + Returns + ------- + dict[str, object] or str + List of shared folders or error message. + """ api_name = 'SYNO.FileStation.List' info = self.file_station_list[api_name] api_path = info['path'] @@ -101,59 +212,101 @@ def get_file_list(self, pattern: Optional[str] = None, filetype: Optional[str] = None, goto_path: Optional[str] = None, - additional: Optional[str | list[str]] = None) -> dict[str, object] | str: - + additional: Optional[str | list[str]] = None) -> dict[str, object]: + """ + List files in a folder. + + Parameters + ---------- + folder_path : str, optional + Path to the folder. + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + pattern : str, optional + Pattern to filter files. + filetype : str, optional + File type filter. + goto_path : str, optional + Path to go to. + additional : str or list of str, optional + Additional attributes to include. + + Returns + ------- + dict[str, object] + List of files or error message. + """ api_name = 'SYNO.FileStation.List' info = self.file_station_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], 'method': 'list'} + if not isinstance(folder_path, str): + # break instead of return + raise ValueError('Enter a valid folder_path') + for key, val in locals().items(): if key not in ['self', 'api_name', 'info', 'api_path', 'req_param', 'additional']: if val is not None: req_param[str(key)] = val - if folder_path is None: - return 'Enter a valid folder_path' - if filetype is not None: req_param['filetype'] = str(req_param['filetype']).lower() if additional is None: additional = ['real_path', 'size', 'owner', 'time'] - if type(additional) is list: - additional = ','.join(additional) + # if type(additional) is list: + # additional = ','.join(additional) req_param['additional'] = additional return self.request_data(api_name, api_path, req_param) def get_file_info(self, - path: Optional[str] = None, - additional: Optional[str | list[str]] = None + path: str | list[str], + additional_param: Optional[str | list[str]] = None ) -> dict[str, object] | str: + """ + Get information about a file or files. + + Parameters + ---------- + path : str or list of str + Path(s) to the file(s). + additional_param : str or list of str, optional + Additional attributes to retrieve. + + Returns + ------- + dict[str, object] or str + File information or error message. + """ api_name = 'SYNO.FileStation.List' info = self.file_station_list[api_name] api_path = info['path'] - req_param = {'version': info['maxVersion'], 'method': 'getinfo'} - - if type(path) is list: - new_path = [] - [new_path.append('"' + x + '"') for x in path] - path = new_path - path = '[' + ','.join(path) + ']' - req_param['path'] = path - elif path is not None: - req_param['path'] = path - - if additional is None: - additional = ['real_path', 'size', 'owner', 'time'] - - if type(additional) is list: - additional = str(additional).replace("'", '"') + req_param = {'version': info['maxVersion'], + 'method': 'getinfo', + 'path': json.dumps(path)} + + if additional_param is None: + additional_param = ["real_path", "size", + "owner", "time", "perm", "type"] + elif isinstance(additional_param, str): + additional_param = [additional_param] + elif isinstance(additional_param, list): + if not all(isinstance(a, str) for a in additional_param): + return "additional_param must be a string or a list of strings." + else: + return "additional_param must be a string or a list of strings." - req_param['additional'] = additional + req_param['additional'] = json.dumps(additional_param) return self.request_data(api_name, api_path, req_param) @@ -177,7 +330,47 @@ def search_start(self, owner: Optional[str] = None, group: Optional[str] = None ) -> dict[str, object] | str: - + """ + Start a search task. + + Parameters + ---------- + folder_path : str, optional + Path to the folder where the search will start. + recursive : bool, optional + If True, the search will be recursive. + pattern : str, optional + Pattern to search for. + extension : str, optional + File extension to filter by. + filetype : str, optional + File type filter. + size_from : int, optional + Minimum file size. + size_to : int, optional + Maximum file size. + mtime_from : str or int, optional + Minimum modification time (Unix timestamp or formatted string). + mtime_to : str or int, optional + Maximum modification time (Unix timestamp or formatted string). + crtime_from : str or int, optional + Minimum creation time (Unix timestamp or formatted string). + crtime_to : str or int, optional + Maximum creation time (Unix timestamp or formatted string). + atime_from : str or int, optional + Minimum access time (Unix timestamp or formatted string). + atime_to : str or int, optional + Maximum access time (Unix timestamp or formatted string). + owner : str, optional + Owner filter. + group : str, optional + Group filter. + + Returns + ------- + dict[str, object] or str + Search task ID or error message. + """ api_name = 'SYNO.FileStation.Search' info = self.file_station_list[api_name] api_path = info['path'] @@ -234,6 +427,31 @@ def get_search_list(self, offset: Optional[int] = None, additional: Optional[str | list[str]] = None ) -> dict[str, object] | str: + """ + Get the results of a search task. + + Parameters + ---------- + task_id : str + Task ID of the search task. + filetype : str, optional + File type filter. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + offset : int, optional + Offset for pagination. + additional : str or list of str, optional + Additional attributes to include. + + Returns + ------- + dict[str, object] or str + Search results or error message. + """ api_name = 'SYNO.FileStation.Search' info = self.file_station_list[api_name] api_path = info['path'] @@ -264,13 +482,26 @@ def get_search_list(self, return self.request_data(api_name, api_path, req_param) def stop_search_task(self, taskid: str) -> dict[str, object] | str: + """ + Stop a search task. + + Parameters + ---------- + taskid : str + Task ID of the search task to stop. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Search' info = self.file_station_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], 'method': 'stop', 'taskid': self._search_taskid} - if taskid is None: + if taskid is None: # NOTE this is unreachable return 'Enter a valid taskid, choose between ' + str(self._search_taskid_list) self._search_taskid_list.remove(taskid) @@ -278,13 +509,21 @@ def stop_search_task(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def stop_all_search_task(self) -> str: + """ + Stop all running search tasks. + + Returns + ------- + str + Confirmation message. + """ api_name = 'SYNO.FileStation.Search' info = self.file_station_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], 'method': 'stop', 'taskid': ''} - assert len(self._search_taskid_list), 'Task list is empty' + \ + assert len(self._search_taskid_list), 'Task list is empty' +\ str(self._search_taskid_list) for task_id in self._search_taskid_list: @@ -303,7 +542,29 @@ def get_mount_point_list(self, sort_direction: Optional[str] = None, additional: Optional[str | list[str]] = None ) -> dict[str, object] | str: - + """ + List mount points. + + Parameters + ---------- + mount_type : str, optional + Type of mount point to filter by. + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + additional : str or list of str, optional + Additional attributes to include. + + Returns + ------- + dict[str, object] or str + List of mount points or error message. + """ api_name = 'SYNO.FileStation.VirtualFolder' info = self.file_station_list[api_name] api_path = info['path'] @@ -334,7 +595,27 @@ def get_favorite_list(self, status_filter: Optional[str] = None, additional: Optional[str | list[str]] = None ) -> dict[str, object] | str: - + """ + List favorite files and folders. + + Parameters + ---------- + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + status_filter : str, optional + Status filter. + additional : str or list of str, optional + Additional attributes to include. + + Returns + ------- + dict[str, object] or str + List of favorites or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -360,6 +641,23 @@ def add_a_favorite(self, name: Optional[str] = None, index: Optional[int] = None ) -> dict[str, object] | str: + """ + Add a file or folder to favorites. + + Parameters + ---------- + path : str + Path to the file or folder. + name : str, optional + Name for the favorite. + index : int, optional + Index for the favorite. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -376,6 +674,19 @@ def add_a_favorite(self, return self.request_data(api_name, api_path, req_param) def delete_a_favorite(self, path: Optional[str] = None) -> dict[str, object] | str: + """ + Delete a favorite. + + Parameters + ---------- + path : str, optional + Path to the favorite to delete. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -389,6 +700,14 @@ def delete_a_favorite(self, path: Optional[str] = None) -> dict[str, object] | s return self.request_data(api_name, api_path, req_param) def clear_broken_favorite(self) -> dict[str, object] | str: + """ + Clear broken favorites. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -397,6 +716,21 @@ def clear_broken_favorite(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def edit_favorite_name(self, path: str, new_name: str) -> dict[str, object] | str: + """ + Edit the name of a favorite. + + Parameters + ---------- + path : str + Path to the favorite. + new_name : str + New name for the favorite. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -415,6 +749,21 @@ def edit_favorite_name(self, path: str, new_name: str) -> dict[str, object] | st return self.request_data(api_name, api_path, req_param) def replace_all_favorite(self, path: str | list[str], name: str | list[str]): + """ + Replace all favorites with new paths and names. + + Parameters + ---------- + path : str or list of str + New path or list of new paths for the favorites. + name : str or list of str + New name or list of new names for the favorites. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Favorite' info = self.file_station_list[api_name] api_path = info['path'] @@ -439,6 +788,19 @@ def replace_all_favorite(self, path: str | list[str], name: str | list[str]): return self.request_data(api_name, api_path, req_param) def start_dir_size_calc(self, path: str) -> dict[str, object] | str: + """ + Start a directory size calculation task. + + Parameters + ---------- + path : str + Path to the directory. + + Returns + ------- + dict[str, object] or str + Task ID or error message. + """ api_name = 'SYNO.FileStation.DirSize' info = self.file_station_list[api_name] api_path = info['path'] @@ -473,6 +835,19 @@ def start_dir_size_calc(self, path: str) -> dict[str, object] | str: return output def stop_dir_size_calc(self, taskid: str) -> str: + """ + Stop a directory size calculation task. + + Parameters + ---------- + taskid : str + Task ID of the size calculation task to stop. + + Returns + ------- + str + Confirmation message. + """ api_name = 'SYNO.FileStation.DirSize' info = self.file_station_list[api_name] api_path = info['path'] @@ -490,6 +865,19 @@ def stop_dir_size_calc(self, taskid: str) -> str: return 'The task has been stopped' def get_dir_status(self, taskid: Optional[str] = None) -> dict[str, object] | str: + """ + Get the status of a directory size calculation task. + + Parameters + ---------- + taskid : str, optional + Task ID of the size calculation task. + + Returns + ------- + dict[str, object] or str + Task status or error message. + """ api_name = 'SYNO.FileStation.DirSize' info = self.file_station_list[api_name] api_path = info['path'] @@ -502,6 +890,19 @@ def get_dir_status(self, taskid: Optional[str] = None) -> dict[str, object] | st return self.request_data(api_name, api_path, req_param) def start_md5_calc(self, file_path: str) -> str | dict[str, object]: + """ + Start an MD5 calculation task. + + Parameters + ---------- + file_path : str + Path to the file. + + Returns + ------- + str or dict[str, object] + Task ID or error message. + """ api_name = 'SYNO.FileStation.MD5' info = self.file_station_list[api_name] api_path = info['path'] @@ -526,6 +927,19 @@ def start_md5_calc(self, file_path: str) -> str | dict[str, object]: return output def get_md5_status(self, taskid: Optional[str] = None) -> str | dict[str, object]: + """ + Get the status of an MD5 calculation task. + + Parameters + ---------- + taskid : str, optional + Task ID of the MD5 calculation task. + + Returns + ------- + str or dict[str, object] + Task status or error message. + """ api_name = 'SYNO.FileStation.MD5' info = self.file_station_list[api_name] api_path = info['path'] @@ -542,6 +956,19 @@ def get_md5_status(self, taskid: Optional[str] = None) -> str | dict[str, object return self.request_data(api_name, api_path, req_param) def stop_md5_calc(self, taskid: str) -> str: + """ + Stop an MD5 calculation task. + + Parameters + ---------- + taskid : str + Task ID of the MD5 calculation task to stop. + + Returns + ------- + str + Confirmation message. + """ api_name = 'SYNO.FileStation.DirSize' info = self.file_station_list[api_name] api_path = info['path'] @@ -564,6 +991,25 @@ def check_permissions(self, overwrite: Optional[bool] = None, create_only: Optional[bool] = None ) -> dict[str, object] | str: + """ + Check permissions for a file or folder. + + Parameters + ---------- + path : str + Path to the file or folder. + filename : str + Name of the file. + overwrite : bool, optional + If True, overwriting is allowed. + create_only : bool, optional + If True, only creation is allowed. + + Returns + ------- + dict[str, object] or str + Permission check result or error message. + """ api_name = 'SYNO.FileStation.CheckPermission' info = self.file_station_list[api_name] api_path = info['path'] @@ -590,53 +1036,58 @@ def upload_file(self, verify: bool = False, progress_bar: bool = True ) -> str | tuple[int, dict[str, object]]: + """ + Upload a file to the server. + + Parameters + ---------- + dest_path : str + Destination path on the server. + file_path : str + Path to the file to upload. + create_parents : bool, optional + If True, parent folders will be created. + overwrite : bool, optional + If True, existing files will be overwritten. + verify : bool, optional + If True, SSL certificates will be verified. + progress_bar : bool, optional + If True, shows a progress bar during upload. + + Returns + ------- + str or tuple[int, dict[str, object]] + Upload result or error message. + """ api_name = 'SYNO.FileStation.Upload' info = self.file_station_list[api_name] api_path = info['path'] - filename = os.path.basename(file_path) session = requests.session() - with open(file_path, 'rb') as payload: - url = ('%s%s' % (self.base_url, api_path)) + '?api=%s&version=%s&method=upload&_sid=%s' % ( - api_name, info['minVersion'], self._sid) - - encoder = MultipartEncoder({ - 'path': dest_path, - 'create_parents': str(create_parents).lower(), - 'overwrite': str(overwrite).lower(), - 'files': (filename, payload, 'application/octet-stream') - }) - - if progress_bar: - bar = tqdm.tqdm(desc='Upload Progress', - total=encoder.len, - dynamic_ncols=True, - unit='B', - unit_scale=True, - unit_divisor=1024 - ) - - monitor = MultipartEncoderMonitor( - encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) - - r = session.post( - url, - data=monitor, - verify=verify, - headers={"X-SYNO-TOKEN": self.session._syno_token, - 'Content-Type': monitor.content_type} - ) - - else: - r = session.post( - url, - data=encoder, - verify=verify, - headers={"X-SYNO-TOKEN": self.session._syno_token, - 'Content-Type': encoder.content_type} - ) - + base = urljoin(self.base_url, api_path) + url_params = { + "api": api_name, + "version": info["minVersion"], + "method": "upload", + "_sid": self._sid + } + + url = f"{base}?{urlencode(url_params)}" + encoder_params = { + 'path': dest_path, + 'create_parents': str(create_parents).lower(), + 'overwrite': str(overwrite).lower(), + } + data = get_data_for_request_from_file( + file_path=file_path, fields=encoder_params, called_from='FileStation', progress_bar=True) + r = session.post( + url, + data=data, + verify=verify, + headers={"X-SYNO-TOKEN": self.session._syno_token, + 'Content-Type': data.content_type} + ) session.close() if r.status_code != 200 or not r.json()['success']: return r.status_code, r.json() @@ -644,6 +1095,19 @@ def upload_file(self, return r.json() def get_shared_link_info(self, link_id: str) -> dict[str, object] | str: + """ + Get information about a shared link. + + Parameters + ---------- + link_id : str + ID of the shared link. + + Returns + ------- + dict[str, object] or str + Shared link information or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -663,7 +1127,27 @@ def get_shared_link_list(self, sort_direction: Optional[str] = None, force_clean: Optional[bool] = None ) -> dict[str, object] | str: - + """ + List shared links. + + Parameters + ---------- + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + force_clean : bool, optional + If True, forces a clean of the shared link list. + + Returns + ------- + dict[str, object] or str + List of shared links or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -683,6 +1167,27 @@ def create_sharing_link(self, date_available: Optional[str | int] = None, expire_times: int = 0 ) -> dict[str, object] | str: + """ + Create a shared link. + + Parameters + ---------- + path : str + Path to the file or folder to share. + password : str, optional + Password for the shared link. + date_expired : str or int, optional + Expiration date for the shared link (Unix timestamp or formatted string). + date_available : str or int, optional + Availability date for the shared link (Unix timestamp or formatted string). + expire_times : int, optional + Number of times the link can be accessed before expiring. + + Returns + ------- + dict[str, object] or str + Shared link details or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -706,6 +1211,19 @@ def create_sharing_link(self, return self.request_data(api_name, api_path, req_param) def delete_shared_link(self, link_id: str) -> dict[str, object] | str: + """ + Delete a shared link. + + Parameters + ---------- + link_id : str + ID of the shared link to delete. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -719,6 +1237,14 @@ def delete_shared_link(self, link_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def clear_invalid_shared_link(self) -> dict[str, object] | str: + """ + Clear invalid shared links. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -733,6 +1259,27 @@ def edit_shared_link(self, date_available: Optional[str | int] = None, expire_times: int = 0 ) -> dict[str, object] | str: + """ + Edit a shared link. + + Parameters + ---------- + link_id : str + ID of the shared link to edit. + password : str, optional + New password for the shared link. + date_expired : str or int, optional + New expiration date for the shared link (Unix timestamp or formatted string). + date_available : str or int, optional + New availability date for the shared link (Unix timestamp or formatted string). + expire_times : int, optional + New number of times the link can be accessed before expiring. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Sharing' info = self.file_station_list[api_name] api_path = info['path'] @@ -763,6 +1310,25 @@ def create_folder(self, force_parent: Optional[bool] = None, additional: Optional[str | list[str]] = None ) -> str | dict[str, object]: + """ + Create a new folder. + + Parameters + ---------- + folder_path : str or list of str + Path or list of paths where the folder should be created. + name : str or list of str + Name or list of names for the new folder. + force_parent : bool, optional + If True, parent folders will be created if they don't exist. + additional : str or list of str, optional + Additional attributes to include. + + Returns + ------- + str or dict[str, object] + Creation result or error message. + """ api_name = 'SYNO.FileStation.CreateFolder' info = self.file_station_list[api_name] api_path = info['path'] @@ -811,32 +1377,50 @@ def rename_folder(self, additional: Optional[str | list[str]] = None, search_taskid: Optional[str] = None ) -> dict[str, object] | str: + """ + Rename a file or a folder. + + Parameters + ---------- + path : str or list of str + Current path or list of paths of the files or folder(s) to rename. + name : str or list of str + New name or list of new names for the file or folder(s). + additional : str or list of str, optional + Additional attributes to include. + search_taskid : str, optional + Task ID of a search task. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + + Examples + -------- + >>> rename_folder('/Downloads/script.log', 'script1.log') + >>> rename_folder(['/Downloads/script.log','/Downloads/script.log'],['a.log', 'b.log']) + >>> rename_folder('/Downloads/script', 'code') + """ api_name = 'SYNO.FileStation.Rename' info = self.file_station_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], 'method': 'rename'} - if type(path) is list: - new_path = [] - [new_path.append('"' + x + '"') for x in path] - path = new_path - path = '[' + ','.join(path) + ']' - req_param['path'] = path - elif path is not None: - req_param['path'] = path + if isinstance(path, list) and isinstance(name, list): + if len(path) != len(name): + raise ValueError("Path and name must have the same length.") + elif isinstance(path, str) and isinstance(name, str): + pass # ok, both are strings else: - return 'Enter a valid folder path (folder path only ex. "/home/Drive/Downloads")' + raise TypeError( + "Path and name must be both lists or both strings.") - if type(name) is list: - new_path = [] - [new_path.append('"' + x + '"') for x in name] - name = new_path - name = '[' + ','.join(name) + ']' - req_param['name'] = name - elif name is not None: - req_param['name'] = name - else: - return 'Enter a valid new folder name (new folder name only ex. "New Folder")' + if validate_path(path) == False: + return 'Enter a valid folder path or file path (ex. /Downloads/script.log)' + + req_param['path'] = json.dumps(path) + req_param['name'] = json.dumps(name) if additional is None: additional = ['real_path', 'size', 'owner', 'time'] @@ -849,7 +1433,7 @@ def rename_folder(self, if search_taskid is not None: req_param['search_taskid'] = search_taskid - return self.request_data(api_name, api_path, req_param) + return self.request_data(api_name, api_path, req_param, method='post') def start_copy_move(self, path: str | list[str], @@ -859,6 +1443,41 @@ def start_copy_move(self, accurate_progress: Optional[bool] = None, search_taskid: Optional[str] = None ) -> str | dict[str, object]: + """ + Start a copy or move task. + + Parameters + ---------- + path : str or list of str + Source path or list of source paths to copy or move. + dest_folder_path : str or list of str + Destination folder path or list of destination folder paths. + overwrite : bool, optional + If True, existing files will be overwritten. + remove_src : bool, optional + If True, source files will be removed after copying. + accurate_progress : bool, optional + If True, shows accurate progress. + search_taskid : str, optional + Task ID of a search task. + + Returns + ------- + str or dict[str, object] + Task ID or error message. + + Examples + -------- + Start a simple move task: + You have to specify only the file on the path and not the dest folder. + + >>> fs = FileStation(**params) + >>> task_id = fs.start_copy_task( + ... path="/Media/Film/Action/movie1.mkv", + ... dest_folder_path="/Media/Film/Drama", + ... overwrite=True + ... ) + """ api_name = 'SYNO.FileStation.CopyMove' info = self.file_station_list[api_name] api_path = info['path'] @@ -907,6 +1526,19 @@ def start_copy_move(self, return output def get_copy_move_status(self, taskid: str) -> dict[str, object] | str: + """ + Get the status of a copy or move task. + + Parameters + ---------- + taskid : str + Task ID of the copy or move task. + + Returns + ------- + dict[str, object] or str + Task status or error message. + """ api_name = 'SYNO.FileStation.CopyMove' info = self.file_station_list[api_name] api_path = info['path'] @@ -920,6 +1552,19 @@ def get_copy_move_status(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def stop_copy_move_task(self, taskid: str) -> dict[str, object] | str: + """ + Stop a copy or move task. + + Parameters + ---------- + taskid : str + Task ID of the copy or move task to stop. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.CopyMove' info = self.file_station_list[api_name] api_path = info['path'] @@ -940,6 +1585,25 @@ def start_delete_task(self, recursive: Optional[bool] = None, search_taskid: Optional[str] = None ) -> dict[str, object] | str: + """ + Start a delete task. + + Parameters + ---------- + path : str or list of str + Path or list of paths to the file or folder to delete. + accurate_progress : bool, optional + If True, shows accurate progress. + recursive : bool, optional + If True, deletes folders recursively. + search_taskid : str, optional + Task ID of a search task. + + Returns + ------- + dict[str, object] or str + Task ID or error message. + """ api_name = 'SYNO.FileStation.Delete' info = self.file_station_list[api_name] api_path = info['path'] @@ -976,6 +1640,19 @@ def start_delete_task(self, return output def get_delete_status(self, taskid: str) -> dict[str, object] | str: + """ + Get the status of a delete task. + + Parameters + ---------- + taskid : str + Task ID of the delete task. + + Returns + ------- + dict[str, object] or str + Task status or error message. + """ api_name = 'SYNO.FileStation.Delete' info = self.file_station_list[api_name] api_path = info['path'] @@ -989,6 +1666,19 @@ def get_delete_status(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def stop_delete_task(self, taskid: str) -> dict[str, object] | str: + """ + Stop a delete task. + + Parameters + ---------- + taskid : str + Task ID of the delete task to stop. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Delete' info = self.file_station_list[api_name] api_path = info['path'] @@ -1007,6 +1697,25 @@ def delete_blocking_function(self, path: str, recursive: Optional[bool] = None, search_taskid: Optional[str] = None) -> dict[str, object] | str: + """ + Delete a file or folder (blocking function). + + This function will stop your script until done! Do not interrupt. + + Parameters + ---------- + path : str or list of str + Path or list of paths to the file or folder to delete. + recursive : bool, optional + If True, deletes folders recursively. + search_taskid : str, optional + Task ID of a search task. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Delete' info = self.file_station_list[api_name] api_path = info['path'] @@ -1042,6 +1751,33 @@ def start_extract_task(self, password: Optional[str] = None, item_id: Optional[str] = None ) -> dict[str, object] | str: + """ + Start an extract task. + + Parameters + ---------- + file_path : str + Path to the archive file. + dest_folder_path : str + Destination folder path where the files will be extracted. + overwrite : bool, optional + If True, existing files will be overwritten. + keep_dir : bool, optional + If True, the original directory structure will be kept. + create_subfolder : bool, optional + If True, a subfolder will be created for the extracted files. + codepage : str, optional + Codepage for the extraction. + password : str, optional + Password for the archive, if required. + item_id : str, optional + Item ID for the extraction task. + + Returns + ------- + dict[str, object] or str + Task ID or error message. + """ api_name = 'SYNO.FileStation.Extract' info = self.file_station_list[api_name] api_path = info['path'] @@ -1074,6 +1810,19 @@ def start_extract_task(self, return output def get_extract_status(self, taskid: str) -> dict[str, object] | str: + """ + Get the status of an extract task. + + Parameters + ---------- + taskid : str + Task ID of the extract task. + + Returns + ------- + dict[str, object] or str + Task status or error message. + """ api_name = 'SYNO.FileStation.Extract' info = self.file_station_list[api_name] api_path = info['path'] @@ -1087,6 +1836,19 @@ def get_extract_status(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def stop_extract_task(self, taskid: str) -> dict[str, object] | str: + """ + Stop an extract task. + + Parameters + ---------- + taskid : str + Task ID of the extract task to stop. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Extract' info = self.file_station_list[api_name] api_path = info['path'] @@ -1111,6 +1873,33 @@ def get_file_list_of_archive(self, password: Optional[str] = None, item_id: Optional[str] = None ) -> dict[str, object] | str: + """ + Get the list of files in an archive. + + Parameters + ---------- + file_path : str + Path to the archive file. + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + codepage : str, optional + Codepage for the file list. + password : str, optional + Password for the archive, if required. + item_id : str, optional + Item ID for the archive. + + Returns + ------- + dict[str, object] or str + List of files in the archive or error message. + """ api_name = 'SYNO.FileStation.Extract' info = self.file_station_list[api_name] api_path = info['path'] @@ -1134,6 +1923,29 @@ def start_file_compression(self, compress_format: Optional[str] = None, password: Optional[str] = None ) -> dict[str, object] | str | tuple[str]: + """ + Start a file compression task. + + Parameters + ---------- + path : str or list of str + Path or list of paths to the file or folder to compress. + dest_file_path : str + Destination file path for the compressed file. + level : int, optional + Compression level. + mode : str, optional + Compression mode. + compress_format : str, optional + Compression format. + password : str, optional + Password for the compressed file, if required. + + Returns + ------- + dict[str, object] or str + Task ID or error message. + """ api_name = 'SYNO.FileStation.Compress' info = self.file_station_list[api_name] api_path = info['path'] @@ -1179,6 +1991,19 @@ def start_file_compression(self, return output def get_compress_status(self, taskid: str) -> dict[str, object] | str: + """ + Get the status of a file compression task. + + Parameters + ---------- + taskid : str + Task ID of the compression task. + + Returns + ------- + dict[str, object] or str + Task status or error message. + """ api_name = 'SYNO.FileStation.Compress' info = self.file_station_list[api_name] api_path = info['path'] @@ -1192,6 +2017,19 @@ def get_compress_status(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def stop_compress_task(self, taskid: str) -> dict[str, object] | str: + """ + Stop a file compression task. + + Parameters + ---------- + taskid : str + Task ID of the compression task to stop. + + Returns + ------- + dict[str, object] or str + Response from the API or error message. + """ api_name = 'SYNO.FileStation.Compress' info = self.file_station_list[api_name] api_path = info['path'] @@ -1209,8 +2047,29 @@ def get_list_of_all_background_task(self, limit: Optional[int] = None, sort_by: Optional[str] = None, sort_direction: Optional[str] = None, - api_filter: Optional[str] = None + api_filter: Optional[str, list] = None ) -> dict[str, object] | str: + """ + Get a list of all background tasks. + + Parameters + ---------- + offset : int, optional + Offset for pagination. + limit : int, optional + Limit for pagination. + sort_by : str, optional + Field to sort by. + sort_direction : str, optional + Sort direction ('asc' or 'desc'). + api_filter : str, optional + API filter. + + Returns + ------- + dict[str, object] or str + List of background tasks or error message. + """ api_name = 'SYNO.FileStation.BackgroundTask' info = self.file_station_list[api_name] api_path = info['path'] @@ -1221,7 +2080,7 @@ def get_list_of_all_background_task(self, if val is not None: req_param[str(key)] = val - if type(api_filter) is list: + if isinstance(api_filter, list): new_path = [] [new_path.append('"' + x + '"') for x in api_filter] api_filter = new_path @@ -1237,7 +2096,27 @@ def get_file(self, chunk_size: int = 8192, verify: bool = False ) -> Optional[str]: - + """ + Download a file from the server. + + Parameters + ---------- + path : str + The file path starting with a shared folder to be downloaded. + mode : str + Mode for downloading the file ('open' to open in browser, 'download' to download to disk). + dest_path : str, optional + Destination path on the local machine (for 'download' mode). + chunk_size : int, optional + Chunk size for downloading. + verify : bool, optional + If True, SSL certificates will be verified. + + Returns + ------- + Optional[str] + None if successful, error message otherwise. + """ api_name = 'SYNO.FileStation.Download' info = self.file_station_list[api_name] api_path = info['path'] @@ -1275,35 +2154,64 @@ def get_file(self, r.raise_for_status() return io.BytesIO(r.content) - def generate_file_tree(self, folder_path: str, tree: Tree) -> None: - """Generate the file tree based on the folder path you give, you need to create the root node before call this function - - Parameters - ---------- - folder_path : str - Folder path to generate file tree - tree : Tree - Instance of the Tree of lib \"Treelib\" - + def generate_file_tree(self, + folder_path: str, + tree: Tree, + max_depth: Optional[int] = 1, + start_depth: Optional[int] = 0) -> None: + """ + Recursively generate the file tree based on the folder path you give constrained with. + + You need to create the root node before calling this function. + + Parameters + ---------- + folder_path : str + Folder path to generate file tree. + tree : Tree + Instance of the Tree from the `treelib` library. + max_depth : int, optional + Non-negative number of maximum depth of tree generation if node tree is directory, default to '1' to generate full tree. If 'max_depth=0' it will be equivalent to no recursion. + start_depth : int, optional + Non negative number to start to control tree generation default to '0'. """ - api_name = 'hotfix' # fix for docs_parser.py issue - data: dict = self.get_file_list( + if start_depth < 0: + start_depth = 0 + warnings.warn( + f"'start_depth={start_depth}'. It should not be less or than 0, setting 'start_depth' to 0!", + RuntimeWarning, + stacklevel=2 + ) + + assert start_depth <= max_depth, ValueError( + f"'start_depth' should not be greater than 'max_depth'. Got '{start_depth=}, {max_depth=}'") + assert isinstance(tree, Tree), ValueError( + "'tree' has to be a type of 'Tree'") + + data: dict[str, object] = self.get_file_list( folder_path=folder_path ).get("data") files = data.get("files") - file: dict - for file in files: - file_name: str = file.get("name") - file_path: str = file.get("path") - if file.get("isdir"): - - tree.create_node(file_name, file_path, parent=folder_path) - self.generate_file_tree(file_path, tree) + _file_info_getter = map(lambda x: ( + x.get('isdir'), x.get('name'), x.get('path')), files) + for isdir, file_name, file_path in _file_info_getter: + + if isdir and (start_depth >= max_depth): + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": True}) + + elif isdir: + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": False}) + self.generate_file_tree( + file_path, tree, max_depth, start_depth + 1) + else: - tree.create_node(file_name, file_path, parent=folder_path) + tree.create_node(file_name, file_path, parent=folder_path, data={ + "isdir": isdir, "max_depth": False}) # TODO SYNO.FileStation.Thumb to be done diff --git a/synology_api/log_center.py b/synology_api/log_center.py index f9335ce1..20c80e0c 100644 --- a/synology_api/log_center.py +++ b/synology_api/log_center.py @@ -1,11 +1,31 @@ +""" +Log Center API wrapper for Synology DSM. + +This module provides a class to interact with the Synology Log Center API. +""" + from __future__ import annotations from typing import Optional from . import base_api class LogCenter(base_api.BaseApi): + """ + Interface for Synology Log Center API. + + Provides methods to interact with log center features such as retrieving logs, + client status, remote archives, and storage settings. + """ def logcenter(self) -> dict[str, object] | str: + """ + Retrieve the list of log center receive rules. + + Returns + ------- + dict[str, object] or str + The API response containing the receive rules or an error message. + """ api_name = 'SYNO.LogCenter.RecvRule' info = self.gen_list[api_name] api_path = info['path'] @@ -14,6 +34,14 @@ def logcenter(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def client_status_cnt(self) -> dict[str, object] | str: + """ + Retrieve the count status from the syslog client. + + Returns + ------- + dict[str, object] or str + The API response containing the count status or an error message. + """ api_name = 'SYNO.Core.SyslogClient.Status' info = self.gen_list[api_name] api_path = info['path'] @@ -22,6 +50,14 @@ def client_status_cnt(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def client_status_eps(self) -> dict[str, object] | str: + """ + Retrieve the EPS (events per second) status from the syslog client. + + Returns + ------- + dict[str, object] or str + The API response containing the EPS status or an error message. + """ api_name = 'SYNO.Core.SyslogClient.Status' info = self.gen_list[api_name] api_path = info['path'] @@ -30,6 +66,14 @@ def client_status_eps(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def remote_log_archives(self) -> dict[str, object] | str: + """ + Retrieve the list of remote log archive subfolders. + + Returns + ------- + dict[str, object] or str + The API response containing remote archive subfolders or an error message. + """ api_name = 'SYNO.LogCenter.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -39,6 +83,14 @@ def remote_log_archives(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def display_logs(self) -> dict[str, object] | str: + """ + Retrieve the list of logs from the syslog client. + + Returns + ------- + dict[str, object] or str + The API response containing the logs or an error message. + """ api_name = 'SYNO.Core.SyslogClient.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -47,6 +99,14 @@ def display_logs(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def setting_storage_list(self) -> dict[str, object] | str: + """ + Retrieve the log center storage settings. + + Returns + ------- + dict[str, object] or str + The API response containing storage settings or an error message. + """ api_name = 'SYNO.LogCenter.Setting.Storage' info = self.gen_list[api_name] api_path = info['path'] @@ -55,6 +115,14 @@ def setting_storage_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def registry_send_list(self) -> dict[str, object] | str: + """ + Retrieve the list of log center client registry send settings. + + Returns + ------- + dict[str, object] or str + The API response containing registry send settings or an error message. + """ api_name = 'SYNO.LogCenter.Client' info = self.gen_list[api_name] api_path = info['path'] @@ -63,6 +131,14 @@ def registry_send_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def history(self) -> dict[str, object] | str: + """ + Retrieve the log center history. + + Returns + ------- + dict[str, object] or str + The API response containing the log center history or an error message. + """ api_name = 'SYNO.LogCenter.History' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/notestation.py b/synology_api/notestation.py index dbd91238..129d302d 100644 --- a/synology_api/notestation.py +++ b/synology_api/notestation.py @@ -1,11 +1,31 @@ +""" +NoteStation API wrapper for Synology DSM. + +This module provides a class to interact with the Synology NoteStation API. +""" + from __future__ import annotations from typing import Optional from . import base_api class NoteStation(base_api.BaseApi): + """ + Interface for Synology NoteStation API. + + Provides methods to interact with NoteStation features such as retrieving settings, + notebooks, tags, shortcuts, todos, smart notes, and individual notes. + """ def settings_info(self) -> dict[str, object] | str: + """ + Retrieve NoteStation settings information. + + Returns + ------- + dict[str, object] or str + The API response containing settings information or an error message. + """ api_name = 'SYNO.NoteStation.Setting' info = self.gen_list[api_name] api_path = info['path'] @@ -23,6 +43,14 @@ def settings_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param)''' def info(self) -> dict[str, object] | str: + """ + Retrieve NoteStation general information. + + Returns + ------- + dict[str, object] or str + The API response containing general information or an error message. + """ api_name = 'SYNO.NoteStation.Info' info = self.gen_list[api_name] api_path = info['path'] @@ -31,6 +59,14 @@ def info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def notebooks_info(self) -> dict[str, object] | str: + """ + Retrieve the list of notebooks. + + Returns + ------- + dict[str, object] or str + The API response containing the list of notebooks or an error message. + """ api_name = 'SYNO.NoteStation.Notebook' info = self.gen_list[api_name] api_path = info['path'] @@ -39,6 +75,14 @@ def notebooks_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def tags_info(self) -> dict[str, object] | str: + """ + Retrieve the list of tags. + + Returns + ------- + dict[str, object] or str + The API response containing the list of tags or an error message. + """ api_name = 'SYNO.NoteStation.Tag' info = self.gen_list[api_name] api_path = info['path'] @@ -47,6 +91,14 @@ def tags_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def shortcuts(self) -> dict[str, object] | str: + """ + Retrieve the list of shortcuts. + + Returns + ------- + dict[str, object] or str + The API response containing the list of shortcuts or an error message. + """ api_name = 'SYNO.NoteStation.Shortcut' info = self.gen_list[api_name] api_path = info['path'] @@ -55,6 +107,14 @@ def shortcuts(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def todo(self) -> dict[str, object] | str: + """ + Retrieve the list of todo items. + + Returns + ------- + dict[str, object] or str + The API response containing the list of todo items or an error message. + """ api_name = 'SYNO.NoteStation.Todo' info = self.gen_list[api_name] api_path = info['path'] @@ -64,6 +124,14 @@ def todo(self) -> dict[str, object] | str: # TODO need to investigate for additional params def smart(self) -> dict[str, object] | str: + """ + Retrieve the list of smart notes. + + Returns + ------- + dict[str, object] or str + The API response containing the list of smart notes or an error message. + """ api_name = 'SYNO.NoteStation.Smart' info = self.gen_list[api_name] api_path = info['path'] @@ -72,6 +140,14 @@ def smart(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def note_list(self) -> dict[str, object] | str: + """ + Retrieve the list of notes. + + Returns + ------- + dict[str, object] or str + The API response containing the list of notes or an error message. + """ api_name = 'SYNO.NoteStation.Note' info = self.gen_list[api_name] api_path = info['path'] @@ -80,6 +156,19 @@ def note_list(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def specific_note_id(self, note_id) -> dict[str, object] | str: + """ + Retrieve a specific note by its ID. + + Parameters + ---------- + note_id : str or int + The ID of the note to retrieve. + + Returns + ------- + dict[str, object] or str + The API response containing the note data or an error message. + """ api_name = 'SYNO.NoteStation.Note' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/oauth.py b/synology_api/oauth.py index b87f4382..5d91bd3f 100644 --- a/synology_api/oauth.py +++ b/synology_api/oauth.py @@ -1,11 +1,37 @@ +""" +OAuth API wrapper for Synology DSM. + +This module provides a class to interact with the Synology OAuth API. +""" + from __future__ import annotations from typing import Optional from . import base_api class OAuth(base_api.BaseApi): + """ + Interface for Synology OAuth API. + + Provides methods to interact with OAuth clients, tokens, and logs. + """ def clients(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: + """ + Retrieve the list of OAuth clients. + + Parameters + ---------- + offset : int, optional + The starting index of the client list. Default is 0. + limit : int, optional + The maximum number of clients to retrieve. Default is 20. + + Returns + ------- + dict[str, object] or str + The API response containing the list of clients or an error message. + """ api_name = 'SYNO.OAUTH.Client' info = self.gen_list[api_name] api_path = info['path'] @@ -15,6 +41,21 @@ def clients(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def tokens(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: + """ + Retrieve the list of OAuth tokens. + + Parameters + ---------- + offset : int, optional + The starting index of the token list. Default is 0. + limit : int, optional + The maximum number of tokens to retrieve. Default is 20. + + Returns + ------- + dict[str, object] or str + The API response containing the list of tokens or an error message. + """ api_name = 'SYNO.OAUTH.Token' info = self.gen_list[api_name] api_path = info['path'] @@ -24,6 +65,21 @@ def tokens(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def logs(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: + """ + Retrieve the list of OAuth logs. + + Parameters + ---------- + offset : int, optional + The starting index of the log list. Default is 0. + limit : int, optional + The maximum number of logs to retrieve. Default is 20. + + Returns + ------- + dict[str, object] or str + The API response containing the list of logs or an error message. + """ api_name = 'SYNO.OAUTH.Log' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/photos.py b/synology_api/photos.py index 8e937c6e..8cd10c21 100755 --- a/synology_api/photos.py +++ b/synology_api/photos.py @@ -1,3 +1,9 @@ +""" +Photos API wrapper for Synology DSM. + +This module provides a class to interact with the Synology Photos API. +""" + from __future__ import annotations from typing import Optional, Any from . import base_api @@ -5,6 +11,37 @@ class Photos(base_api.BaseApi): + """ + Interface for Synology Photos API. + + Provides methods to interact with Photos features such as retrieving user info, + folders, albums, sharing, and items. + + Parameters + ---------- + ip_address : str + The IP address or hostname of the Synology NAS. + port : str + The port number to connect to. + username : str + The username for authentication. + password : str + The password for authentication. + secure : bool, optional + Whether to use HTTPS. Default is False. + cert_verify : bool, optional + Whether to verify SSL certificates. Default is False. + dsm_version : int, optional + DSM version. Default is 7. + debug : bool, optional + Enable debug output. Default is True. + otp_code : str, optional + One-time password for 2FA, if required. + device_id : str, optional + Device ID for the session. + device_name : str, optional + Device name for the session. + """ def __init__(self, ip_address: str, @@ -19,6 +56,34 @@ def __init__(self, device_id: Optional[str] = None, device_name: Optional[str] = None ) -> None: + """ + Initialize the Photos API interface. + + Parameters + ---------- + ip_address : str + The IP address or hostname of the Synology NAS. + port : str + The port number to connect to. + username : str + The username for authentication. + password : str + The password for authentication. + secure : bool, optional + Whether to use HTTPS. Default is False. + cert_verify : bool, optional + Whether to verify SSL certificates. Default is False. + dsm_version : int, optional + DSM version. Default is 7. + debug : bool, optional + Enable debug output. Default is True. + otp_code : str, optional + One-time password for 2FA, if required. + device_id : str, optional + Device ID for the session. + device_name : str, optional + Device name for the session. + """ super(Photos, self).__init__(ip_address, port, username, password, secure, cert_verify, dsm_version, debug, otp_code, device_id, device_name, 'FotoStation') @@ -32,6 +97,14 @@ def __init__(self, self._userinfo: Any = None def get_userinfo(self) -> Any: + """ + Retrieve user information for the current session. + + Returns + ------- + Any + The user information data. + """ if self._userinfo is not None: return self._userinfo @@ -44,6 +117,19 @@ def get_userinfo(self) -> Any: return self._userinfo def get_folder(self, folder_id: int = 0) -> dict[str, object] | str: + """ + Retrieve information about a specific folder. + + Parameters + ---------- + folder_id : int, optional + The ID of the folder. Default is 0. + + Returns + ------- + dict[str, object] or str + The folder information or an error message. + """ api_name = 'SYNO.Foto.Browse.Folder' info = self.photos_list[api_name] api_path = info['path'] @@ -58,6 +144,25 @@ def list_folders(self, offset: int = 0, additional: str | list[str] = None ) -> dict[str, object] | str: + """ + List folders in Personal Space. + + Parameters + ---------- + folder_id : int, optional + The parent folder ID. Default is 0. + limit : int, optional + Maximum number of folders to return. Default is 1000. + offset : int, optional + Number of folders to skip. Default is 0. + additional : str or list of str, optional + Additional fields to include. + + Returns + ------- + dict[str, object] or str + The list of folders or an error message. + """ return self._list_folders(folder_id, limit, offset, additional, 'SYNO.Foto.Browse.Folder') def list_teams_folders(self, @@ -66,10 +171,50 @@ def list_teams_folders(self, offset: int = 0, additional: Optional[str | list[str]] = None ) -> dict[str, object] | str: + """ + List folders in Team Space. + + Parameters + ---------- + folder_id : int, optional + The parent folder ID. Default is 0. + limit : int, optional + Maximum number of folders to return. Default is 2000. + offset : int, optional + Number of folders to skip. Default is 0. + additional : str or list of str, optional + Additional fields to include. + + Returns + ------- + dict[str, object] or str + The list of team folders or an error message. + """ return self._list_folders(folder_id, limit, offset, additional, 'SYNO.FotoTeam.Browse.Folder') def _list_folders(self, folder_id: int, limit: int, offset: int, additional: Optional[str | list[str]], api_name: str) -> Any: + """ + Internal method to list folders. + + Parameters + ---------- + folder_id : int + The parent folder ID. + limit : int + Maximum number of folders to return. + offset : int + Number of folders to skip. + additional : str or list of str, optional + Additional fields to include. + api_name : str + API name to use. + + Returns + ------- + Any + The API response. + """ if additional is None: additional = [] info = self.photos_list[api_name] @@ -80,12 +225,53 @@ def _list_folders(self, folder_id: int, limit: int, offset: int, additional: Opt return self.request_data(api_name, api_path, req_param) def count_folders(self, folder_id: int = 0) -> dict[str, object] | str: + """ + Count folders in Personal Space. + + Parameters + ---------- + folder_id : int, optional + The parent folder ID. Default is 0. + + Returns + ------- + dict[str, object] or str + The count of folders or an error message. + """ return self._count_folders(folder_id, 'SYNO.Foto.Browse.Folder') def count_team_folders(self, folder_id: int = 0) -> dict[str, object] | str: + """ + Count folders in Team Space. + + Parameters + ---------- + folder_id : int, optional + The parent folder ID. Default is 0. + + Returns + ------- + dict[str, object] or str + The count of team folders or an error message. + """ return self._count_folders(folder_id, 'SYNO.FotoTeam.Browse.Folder') def _count_folders(self, folder_id: int, api_name: str) -> Any: + """ + Internal method to count folders. + + Parameters + ---------- + folder_id : int + The parent folder ID. + api_name : str + API name to use. + + Returns + ------- + Any + The API response. + """ info = self.photos_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], @@ -94,12 +280,55 @@ def _count_folders(self, folder_id: int, api_name: str) -> Any: return self.request_data(api_name, api_path, req_param) def lookup_folder(self, path: str) -> dict[str, object] | str: + """ + Lookup a folder by path in Personal Space. + + Parameters + ---------- + path : str + The folder path. + + Returns + ------- + dict[str, object] or str + The folder information or None if not found. + """ return self._lookup_folder(path, 'SYNO.FotoBrowse.Folder', 'SYNO.Foto.Browse.Folder') def lookup_team_folder(self, path: str) -> dict[str, object] | str: + """ + Lookup a folder by path in Team Space. + + Parameters + ---------- + path : str + The folder path. + + Returns + ------- + dict[str, object] or str + The folder information or None if not found. + """ return self._lookup_folder(path, 'SYNO.FotoTeam.Browse.Folder', 'SYNO.FotoTeam.Browse.Folder') def _lookup_folder(self, path: str, api_name_count: str, api_name_list: str) -> Optional[dict[str, object]]: + """ + Internal method to lookup a folder by path. + + Parameters + ---------- + path : str + The folder path. + api_name_count : str + API name for counting folders. + api_name_list : str + API name for listing folders. + + Returns + ------- + dict[str, object] or None + The folder information or None if not found. + """ parent = 0 found_path = '' folder = '' @@ -124,6 +353,21 @@ def _lookup_folder(self, path: str, api_name_count: str, api_name_list: str) -> return folder def get_album(self, album_id: str, additional: Optional[str | list[str]] = None) -> dict[str, object] | str: + """ + Retrieve information about a specific album. + + Parameters + ---------- + album_id : str + The album ID. + additional : str or list of str, optional + Additional fields to include. + + Returns + ------- + dict[str, object] or str + The album information or an error message. + """ if not isinstance(album_id, list): album_id = [album_id] if additional is None: @@ -137,6 +381,21 @@ def get_album(self, album_id: str, additional: Optional[str | list[str]] = None) return self.request_data(api_name, api_path, req_param) def list_albums(self, offset: int = 0, limit: int = 100) -> dict[str, object] | str: + """ + List albums. + + Parameters + ---------- + offset : int, optional + Number of albums to skip. Default is 0. + limit : int, optional + Maximum number of albums to return. Default is 100. + + Returns + ------- + dict[str, object] or str + The list of albums or an error message. + """ api_name = 'SYNO.Foto.Browse.Album' info = self.photos_list[api_name] api_path = info['path'] @@ -150,6 +409,23 @@ def suggest_condition(self, condition: Optional[list[str]] = None, user_id: Optional[str] = None ) -> dict[str, object] | str: + """ + Suggest album conditions based on a keyword. + + Parameters + ---------- + keyword : str + The keyword to suggest conditions for. + condition : list of str, optional + List of conditions to use. Default is ['general_tag']. + user_id : str, optional + User ID to use. If None, uses the current user. + + Returns + ------- + dict[str, object] or str + The suggested conditions or an error message. + """ if condition is None: condition = ['general_tag'] if user_id is None: @@ -164,6 +440,21 @@ def suggest_condition(self, return self.request_data(api_name, api_path, req_param) def create_album(self, name: str, condition: list[str]) -> dict[str, object] | str: + """ + Create a new album with the specified condition. + + Parameters + ---------- + name : str + The name of the album. + condition : list of str + The condition for the album. + + Returns + ------- + dict[str, object] or str + The API response for album creation. + """ api_name = 'SYNO.Foto.Browse.ConditionAlbum' info = self.photos_list[api_name] api_path = info['path'] @@ -173,6 +464,19 @@ def create_album(self, name: str, condition: list[str]) -> dict[str, object] | s return self.request_data(api_name, api_path, req_param) def delete_album(self, album_id: str) -> dict[str, object] | str: + """ + Delete an album by ID. + + Parameters + ---------- + album_id : str + The album ID. + + Returns + ------- + dict[str, object] or str + The API response for album deletion. + """ if not isinstance(album_id, list): album_id = [album_id] api_name = 'SYNO.Foto.Browse.Album' @@ -184,6 +488,21 @@ def delete_album(self, album_id: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def set_album_condition(self, folder_id: int, condition: list[str]) -> dict[str, object] | str: + """ + Set the condition for an album. + + Parameters + ---------- + folder_id : int + The folder ID. + condition : list of str + The condition to set. + + Returns + ------- + dict[str, object] or str + The API response for setting the condition. + """ api_name = 'SYNO.Foto.Browse.ConditionAlbum' info = self.photos_list[api_name] api_path = info['path'] @@ -198,6 +517,25 @@ def share_album(self, enabled: bool = True, expiration: int | str = 0 ) -> Any: + """ + Share an album with specified permissions. + + Parameters + ---------- + album_id : str + The album ID. + permission : str or list of str, optional + Permissions to set. + enabled : bool, optional + Whether sharing is enabled. Default is True. + expiration : int or str, optional + Expiration time for the share. Default is 0. + + Returns + ------- + Any + The API response for sharing the album. + """ self._share('SYNO.Foto.Sharing.Passphrase', policy='album', permission=permission, album_id=album_id, enabled=enabled, expiration=expiration) @@ -207,6 +545,25 @@ def share_team_folder(self, enabled: bool = True, expiration: int | str = 0 ) -> Any: + """ + Share a team folder with specified permissions. + + Parameters + ---------- + folder_id : int + The folder ID. + permission : str, optional + Permissions to set. + enabled : bool, optional + Whether sharing is enabled. Default is True. + expiration : int or str, optional + Expiration time for the share. Default is 0. + + Returns + ------- + Any + The API response for sharing the team folder. + """ self._share('SYNO.FotoTeam.Sharing.Passphrase', policy='folder', permission=permission, folder_id=folder_id, enabled=enabled, expiration=expiration) @@ -217,6 +574,27 @@ def _share(self, expiration: int | str, **kwargs ) -> dict[str, object] | Any: + """ + Internal method to share an album or folder. + + Parameters + ---------- + api_name : str + API name to use. + policy : str + Sharing policy. + permission : str + Permissions to set. + expiration : int or str + Expiration time for the share. + **kwargs + Additional keyword arguments. + + Returns + ------- + dict[str, object] or Any + The API response for sharing. + """ info = self.photos_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], @@ -236,6 +614,19 @@ def _share(self, return self.request_data(api_name, api_path, req_param) def list_shareable_users_and_groups(self, team_space_sharable_list: bool = False) -> dict[str, object] | str: + """ + List users and groups that can be shared with. + + Parameters + ---------- + team_space_sharable_list : bool, optional + Whether to include team space sharable list. Default is False. + + Returns + ------- + dict[str, object] or str + The list of users and groups or an error message. + """ api_name = 'SYNO.Foto.Sharing.Misc' info = self.photos_list[api_name] api_path = info['path'] @@ -247,44 +638,35 @@ def list_shareable_users_and_groups(self, team_space_sharable_list: bool = False def list_item_in_folders(self, offset: int = 0, limit: int = 0, folder_id: int = 0, sort_by: str = 'filename', sort_direction: str = 'desc', type: str = None, passphrase: str = None, additional: list = None) -> dict[str, object] | str: - """List all items in all folders in Personal Space - - Parameters - ---------- - offset : int - Specify how many shared folders are skipped before beginning to return listed shared folders. - - limit : int - Number of shared folders requested. Set to `0` to list all shared folders. - - folder_id : int - ID of folder - - sort_by : str, optional - Possible values: - - `filename` - - `filesize` - - `takentime` - - `item_type` - - sort_direction : str, optional - Possible values: `asc` or `desc`. Defaults to: `desc` - - passphrase : str, optional - Passphrase for a shared album - - additional : list[str] - Possible values: - `["thumbnail","resolution", "orientation", "video_convert", "video_meta", "provider_user_id", "exif", "tag", "description", "gps", "geocoding_id", "address", "person"]` - - type : str - Possible values: - - `photo`: Photo - - `video`: Video - - `live`: iPhone live photos' - """ - + List all items in all folders in Personal Space. + + Parameters + ---------- + offset : int + Specify how many shared folders are skipped before beginning to return listed shared folders. + limit : int + Number of shared folders requested. Set to `0` to list all shared folders. + folder_id : int + ID of folder. + sort_by : str, optional + Possible values: 'filename', 'filesize', 'takentime', 'item_type'. + sort_direction : str, optional + Possible values: 'asc' or 'desc'. Defaults to: 'desc'. + type : str, optional + Possible values: 'photo', 'video', 'live'. + passphrase : str, optional + Passphrase for a shared album. + additional : list, optional + Additional fields to include. + Possible values: + `["thumbnail","resolution", "orientation", "video_convert", "video_meta", "provider_user_id", "exif", "tag", "description", "gps", "geocoding_id", "address", "person"]`. + + Returns + ------- + dict[str, object] or str + The list of items or an error message. + """ api_name = 'SYNO.Foto.Browse.Item' info = self.photos_list[api_name] api_path = info['path'] @@ -301,6 +683,14 @@ def list_item_in_folders(self, offset: int = 0, limit: int = 0, folder_id: int = return self.request_data(api_name, api_path, req_param) def list_search_filters(self) -> dict[str, object] | str: + """ + List available search filters. + + Returns + ------- + dict[str, object] or str + The list of search filters or an error message. + """ api_name = 'SYNO.Foto.Search.Filter' info = self.photos_list[api_name] api_path = info['path'] @@ -309,6 +699,14 @@ def list_search_filters(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_guest_settings(self) -> dict[str, object] | str: + """ + Retrieve guest settings for Photos. + + Returns + ------- + dict[str, object] or str + The guest settings or an error message. + """ api_name = 'SYNO.Foto.Setting.Guest' info = self.photos_list[api_name] api_path = info['path'] diff --git a/synology_api/security_advisor.py b/synology_api/security_advisor.py index 18e4e128..03301d4e 100644 --- a/synology_api/security_advisor.py +++ b/synology_api/security_advisor.py @@ -1,11 +1,31 @@ +""" +Security Advisor API wrapper for Synology DSM. + +This module provides a class to interact with the Synology Security Advisor API. +""" + from __future__ import annotations from typing import Optional from . import base_api class SecurityAdvisor(base_api.BaseApi): + """ + Interface for Synology Security Advisor API. + + Provides methods to retrieve general info, scan results, checklists, + login activity, and configuration for Security Advisor. + """ def general_info(self) -> dict[str, object] | str: + """ + Retrieve general information about Security Advisor location configuration. + + Returns + ------- + dict[str, object] or str + The API response containing location configuration or an error message. + """ api_name = 'SYNO.SecurityAdvisor.Conf.Location' info = self.gen_list[api_name] api_path = info['path'] @@ -14,6 +34,14 @@ def general_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def security_scan(self) -> dict[str, object] | str: + """ + Retrieve the current security scan configuration. + + Returns + ------- + dict[str, object] or str + The API response containing security scan configuration or an error message. + """ api_name = 'SYNO.Core.SecurityScan.Conf' info = self.core_list[api_name] api_path = info['path'] @@ -22,6 +50,14 @@ def security_scan(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def checklist(self) -> dict[str, object] | str: + """ + Retrieve the checklist for the Security Advisor. + + Returns + ------- + dict[str, object] or str + The API response containing the checklist or an error message. + """ api_name = 'SYNO.SecurityAdvisor.Conf.Checklist' info = self.gen_list[api_name] api_path = info['path'] @@ -31,6 +67,21 @@ def checklist(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def login_activity(self, offset: int = 0, limit: int = 20) -> dict[str, object] | str: + """ + Retrieve login activity records. + + Parameters + ---------- + offset : int, optional + The starting index of the login activity list. Default is 0. + limit : int, optional + The maximum number of records to retrieve. Default is 20. + + Returns + ------- + dict[str, object] or str + The API response containing login activity records or an error message. + """ api_name = 'SYNO.SecurityAdvisor.LoginActivity' info = self.gen_list[api_name] api_path = info['path'] @@ -40,6 +91,14 @@ def login_activity(self, offset: int = 0, limit: int = 20) -> dict[str, object] return self.request_data(api_name, api_path, req_param) def advisor_config(self) -> dict[str, object] | str: + """ + Retrieve Security Advisor configuration. + + Returns + ------- + dict[str, object] or str + The API response containing advisor configuration or an error message. + """ api_name = 'SYNO.SecurityAdvisor.Conf' info = self.gen_list[api_name] api_path = info['path'] @@ -48,6 +107,14 @@ def advisor_config(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def scan_config(self) -> dict[str, object] | str: + """ + Retrieve custom group enumeration for security scan configuration. + + Returns + ------- + dict[str, object] or str + The API response containing custom group enumeration or an error message. + """ api_name = 'SYNO.Core.SecurityScan.Conf' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/snapshot.py b/synology_api/snapshot.py index 8716a8f4..7672247b 100644 --- a/synology_api/snapshot.py +++ b/synology_api/snapshot.py @@ -1,3 +1,10 @@ +""" +Snapshot Replication API wrapper for Synology DSM. + +This module provides a class to interact with the Synology Snapshot Replication APIs. +The implementation is based on network inspection, as there is no official documentation. +""" + from __future__ import annotations from typing import Optional from . import base_api @@ -5,59 +12,61 @@ class Snapshot(base_api.BaseApi): - """Class for interacting with Snapshot Replication APIs. - - This class implements APIs to manage snapshots. - There is no documentation for these APIs, so the implementation is based on network inspection. - - Supported methods: - - Getters: - - Get all share/LUN snapshots - - Get all replications - - Get all LUNs - - - Setters: - - Set snapshot attributes - - - Actions: - - Create share/LUN snapshot (WORM support only for share snaps ATM) - - Delete share/LUN snapshot - - Sync replication - - Examples - -------- - List snapshots for a share/LUN: - ```python - from synology_api import snapshot - ss = snapshot.Snapshot('IP', 'PORT', 'USER', 'PASSWORD') - - resp_share = ss.list_snapshots('share_name') - resp_lun = ss.list_snapshots_lun('src_lun_uuid') - - print(resp_share, resp_lun) - ``` - - Create a snapshot for a share/LUN: - ```python - resp_share = ss.create_snapshot('share_name') - resp_lun = create_snapshot_lun('lun_id') - - print(resp_share, resp_lun) - ``` - - Delete snapshots for a share: - ```python - resp_share = ss.delete_snapshots('share_name', ['snapshot_name']) - resp_lun = ss.delete_snapshots_lun(['snapshot_uuid']) - - print(resp_share, resp_lun) - ``` - - Set attributes for a snapshot: - ```python - resp = ss.set_snapshot_attr('share_name', 'snapshot_name', description='new description', lock=True) - print(resp) - ``` + """ + Class for interacting with Snapshot Replication APIs. + + This class implements APIs to manage snapshots. + There is no documentation for these APIs, so the implementation is based on network inspection. + + Methods + ------- + Getters: + - Get all share/LUN snapshots + - Get all replications + - Get all LUNs + + Setters: + - Set snapshot attributes + + Actions: + - Create share/LUN snapshot (WORM support only for share snaps ATM) + - Delete share/LUN snapshot + - Sync replication + + Examples + -------- + List snapshots for a share/LUN: + ```python + from synology_api import snapshot + ss = snapshot.Snapshot('IP', 'PORT', 'USER', 'PASSWORD') + + resp_share = ss.list_snapshots('share_name') + resp_lun = ss.list_snapshots_lun('src_lun_uuid') + + print(resp_share, resp_lun) + ``` + + Create a snapshot for a share/LUN: + ```python + resp_share = ss.create_snapshot('share_name') + resp_lun = create_snapshot_lun('lun_id') + + print(resp_share, resp_lun) + ``` + + Delete snapshots for a share: + ```python + resp_share = ss.delete_snapshots('share_name', ['snapshot_name']) + resp_lun = ss.delete_snapshots_lun(['snapshot_uuid']) + + print(resp_share, resp_lun) + ``` + + Set attributes for a snapshot: + ```python + resp = ss.set_snapshot_attr('share_name', 'snapshot_name', description='new description', lock=True) + print(resp) + ``` """ def list_snapshots( @@ -68,67 +77,58 @@ def list_snapshots( offset: int = 0, limit: int = -1 ) -> dict[str, object]: - """List snapshots for a share. - - Parameters - ---------- - share_name : str - Name of the share to list snapshots for. - - attribute_filter : list[str], optional - List of attributes filter to apply. Defaults to `[]` (no filter). - - - Each attribute filter is a string in the format of `"attr==value"` or `"attr=value"` and optionally prefixed with `!` to negate the filter. - - - The following are examples of valid attribute filters: - - `["!hide==true", "desc==abc"]` -> hide is not true and desc is exactly abc. - - `["desc=abc"]` -> desc has abc in it. - - additional_attribute : list[str], optional - List of snapshot attributes whose values are included in the response. Defaults to `[]` (only time is returned). - - - Note that not all attributes are available via API. The following are confirmed to work: - - `"desc"` - - `"lock"` - - `"worm_lock"` - - `"schedule_snapshot"` - - offset : int, optional - Offset to start listing from. Defaults to `0`. - - limit : int, optional - Number of snapshots to return. Defaults to `-1` (all). - - Returns - ------- - dict[str, object] - API response if successful, error message if not. + """ + List snapshots for a share. + + Parameters + ---------- + share_name : str + Name of the share to list snapshots for. + attribute_filter : list[str], optional + List of attributes filter to apply. Defaults to `[]` (no filter). + Each attribute filter is a string in the format of `"attr==value"` or `"attr=value"` and optionally prefixed with `!` to negate the filter. + The following are examples of valid attribute filters: + - `["!hide==true", "desc==abc"]` -> hide is not true and desc is exactly abc. + - `["desc=abc"]` -> desc has abc in it. + additional_attribute : list[str], optional + List of snapshot attributes whose values are included in the response. Defaults to `[]` (only time is returned). + Note that not all attributes are available via API. The following are confirmed to work: + - `"desc"` + - `"lock"` + - `"worm_lock"` + - `"schedule_snapshot"` + offset : int, optional + Offset to start listing from. Defaults to `0`. + limit : int, optional + Number of snapshots to return. Defaults to `-1` (all). + + Returns + ------- + dict[str, object] + API response if successful, error message if not. - Examples - -------- - ```json - { - "data": { - "snapshots": [ - { - "desc": "", - "lock": true, - "schedule_snapshot": false, - "time": "GMT+09-2023.09.11-23.23.40", - "worm_lock": true, - "worm_lock_begin": "1694442321", - "worm_lock_day": "1", - "worm_lock_end": "1694528721" - } - ], - "total": 1 - }, - "success": true - } - ``` + Examples + -------- + ```json + { + "data": { + "snapshots": [ + { + "desc": "", + "lock": true, + "schedule_snapshot": false, + "time": "GMT+09-2023.09.11-23.23.40", + "worm_lock": true, + "worm_lock_begin": "1694442321", + "worm_lock_day": "1", + "worm_lock_end": "1694528721" + } + ], + "total": 1 + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.Share.Snapshot' @@ -154,86 +154,83 @@ def list_snapshots_lun( src_lun_uuid: str, additional: list[str] = ["locked_app_keys", "is_worm_locked"] ) -> dict[str, object]: - """List snapshots for a LUN. - - Parameters - ---------- - src_lun_uuid : str - UUID of the source LUN to list snapshots for. - - additional : list[str], optional - Additional fields to retrieve. Specify `[]` to get only basic information. - - Defaults to `["locked_app_keys", "is_worm_locked"]` - - - Possible values: - - `"locked_app_keys"` -> If snapshot is preserved by the system, the locking package key will be returned. - - `"is_worm_locked"` -> Whether the snapshot is locked by WORM. - - Returns - ------- - dict[str, object] - Dictionary containing the LUN snapshots information. + """ + List snapshots for a LUN. + + Parameters + ---------- + src_lun_uuid : str + UUID of the source LUN to list snapshots for. + additional : list[str], optional + Additional fields to retrieve. Specify `[]` to get only basic information. + Defaults to `["locked_app_keys", "is_worm_locked"]` + Possible values: + - `"locked_app_keys"` -> If snapshot is preserved by the system, the locking package key will be returned. + - `"is_worm_locked"` -> Whether the snapshot is locked by WORM. + + Returns + ------- + dict[str, object] + Dictionary containing the LUN snapshots information. - Examples - -------- - ```json - { - "data": { - "count": 2, - "snapshots": [ - { - "create_time": 1742739365, - "description": "test", - "is_app_consistent": false, - "is_user_locked": true, - "is_worm_locked": false, - "locked_app_keys": [], - "mapped_size": 0, - "name": "SnapShot-1", - "parent_lun_id": 6, - "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "root_path": "/volume2", - "snapshot_id": 1, - "snapshot_time": 1742739365, - "status": "Healthy", - "taken_by": "user", - "total_size": 1073741824, - "type": 2, - "uuid": "fb388ec7-f23a-4011-8d24-08ad9b1fef34", - "version": "d4236543-510f-4269-ae73-7bc789aaa763", - "worm_lock_day": "0" - }, - { - "create_time": 1742833700, - "description": "Snapshot taken by [Synology API]", - "is_app_consistent": false, - "is_user_locked": false, - "is_worm_locked": false, - "locked_app_keys": [ - "SnapshotReplication-synodr-657f3c72-f357-400d-96df-bb8ae4e5051f" - ], - "mapped_size": 0, - "name": "SnapShot-2", - "parent_lun_id": 6, - "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "root_path": "/volume2", - "snapshot_id": 2, - "snapshot_time": 1742833700, - "status": "Healthy", - "taken_by": "user", - "total_size": 1073741824, - "type": 2, - "uuid": "e981770c-f56d-4cb2-b7a7-4c4b11ba8eaa", - "version": "58ee3b1a-192d-46fe-9cf3-0960e2a8670b", - "worm_lock_day": "0" - } - ] - }, - "success": true - } - ``` + Examples + -------- + ```json + { + "data": { + "count": 2, + "snapshots": [ + { + "create_time": 1742739365, + "description": "test", + "is_app_consistent": false, + "is_user_locked": true, + "is_worm_locked": false, + "locked_app_keys": [], + "mapped_size": 0, + "name": "SnapShot-1", + "parent_lun_id": 6, + "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "root_path": "/volume2", + "snapshot_id": 1, + "snapshot_time": 1742739365, + "status": "Healthy", + "taken_by": "user", + "total_size": 1073741824, + "type": 2, + "uuid": "fb388ec7-f23a-4011-8d24-08ad9b1fef34", + "version": "d4236543-510f-4269-ae73-7bc789aaa763", + "worm_lock_day": "0" + }, + { + "create_time": 1742833700, + "description": "Snapshot taken by [Synology API]", + "is_app_consistent": false, + "is_user_locked": false, + "is_worm_locked": false, + "locked_app_keys": [ + "SnapshotReplication-synodr-657f3c72-f357-400d-96df-bb8ae4e5051f" + ], + "mapped_size": 0, + "name": "SnapShot-2", + "parent_lun_id": 6, + "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "root_path": "/volume2", + "snapshot_id": 2, + "snapshot_time": 1742833700, + "status": "Healthy", + "taken_by": "user", + "total_size": 1073741824, + "type": 2, + "uuid": "e981770c-f56d-4cb2-b7a7-4c4b11ba8eaa", + "version": "58ee3b1a-192d-46fe-9cf3-0960e2a8670b", + "worm_lock_day": "0" + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.ISCSI.LUN' @@ -276,187 +273,178 @@ def list_luns( "snapshot_info", ] ) -> dict[str, object]: - """List available LUNs - - Parameters - ---------- - types : list[str], optional - Type of LUNS to retrieve. - - - Defaults to `[ "BLOCK", "FILE", "THIN", "ADV", "SINK", "CINDER", "CINDER_BLUN", "CINDER_BLUN_THICK", "BLUN", "BLUN_THICK", "BLUN_SINK", "BLUN_THICK_SINK" ]`. - - - Possible values: - - `"BLOCK"` - - `"FILE"` - - `"THIN"` - - `"ADV"` - - `"SINK"` - - `"CINDER"` - - `"CINDER_BLUN"` - - `"CINDER_BLUN_THICK"` - - `"BLUN"` - - `"BLUN_THICK"` - - `"BLUN_SINK"` - - `"BLUN_THICK_SINK"` - - additional_info : list[str], optional - Additional LUN information to include in the response. Specify `[]` to get only basic information. - - - Defaults to `[ "is_action_locked", "is_mapped", "extent_size", "allocated_size", "status", "allow_bkpobj", "flashcache_status", "family_config", "snapshot_info" ]`. - - - Possible values: - - `"is_action_locked"` - - `"is_mapped"` - - `"extent_size"` - - `"allocated_size"` - - `"status"` - - `"allow_bkpobj"` - - `"flashcache_status"` - - `"family_config"` - - `"snapshot_info"` - - Returns - ------- - dict[str, object] - A dictionary containing a list of LUNs present in the system. + """ + List available LUNs. + + Parameters + ---------- + types : list[str], optional + Type of LUNS to retrieve. + Defaults to `[ "BLOCK", "FILE", "THIN", "ADV", "SINK", "CINDER", "CINDER_BLUN", "CINDER_BLUN_THICK", "BLUN", "BLUN_THICK", "BLUN_SINK", "BLUN_THICK_SINK" ]`. + Possible values: + - `"BLOCK"` + - `"FILE"` + - `"THIN"` + - `"ADV"` + - `"SINK"` + - `"CINDER"` + - `"CINDER_BLUN"` + - `"CINDER_BLUN_THICK"` + - `"BLUN"` + - `"BLUN_THICK"` + - `"BLUN_SINK"` + - `"BLUN_THICK_SINK"` + additional_info : list[str], optional + Additional LUN information to include in the response. Specify `[]` to get only basic information. + Defaults to `[ "is_action_locked", "is_mapped", "extent_size", "allocated_size", "status", "allow_bkpobj", "flashcache_status", "family_config", "snapshot_info" ]`. + Possible values: + - `"is_action_locked"` + - `"is_mapped"` + - `"extent_size"` + - `"allocated_size"` + - `"status"` + - `"allow_bkpobj"` + - `"flashcache_status"` + - `"family_config"` + - `"snapshot_info"` + + Returns + ------- + dict[str, object] + A dictionary containing a list of LUNs present in the system. - Examples - -------- - ```json - { - "data": { - "luns": [ - { - "allocated_size": 0, - "block_size": 512, - "create_from": "", - "description": "", - "dev_attribs": [ - { - "dev_attrib": "emulate_3pc", - "enable": 1 - }, - { - "dev_attrib": "emulate_tpws", - "enable": 1 - }, - { - "dev_attrib": "emulate_caw", - "enable": 1 - }, - { - "dev_attrib": "emulate_tpu", - "enable": 1 - }, - { - "dev_attrib": "emulate_fua_write", - "enable": 0 - }, - { - "dev_attrib": "emulate_sync_cache", - "enable": 0 - }, - { - "dev_attrib": "can_snapshot", - "enable": 1 - } - ], - "dev_attribs_bitmap": 31, - "dev_config": "", - "dev_qos": { - "dev_limit": 0, - "dev_reservation": 0, - "dev_weight": 0, - "iops_enable": 0 + Examples + -------- + ```json + { + "data": { + "luns": [ + { + "allocated_size": 0, + "block_size": 512, + "create_from": "", + "description": "", + "dev_attribs": [ + { + "dev_attrib": "emulate_3pc", + "enable": 1 }, - "direct_io_pattern": 0, - "extent_size": 0, - "family_config": { - "parent_lun_name": "", - "parent_lun_uuid": "", - "parent_snapshot_time": 0, - "parent_snapshot_uuid": "" + { + "dev_attrib": "emulate_tpws", + "enable": 1 }, - "flashcache_id": -1, - "flashcache_status": "no_cache", - "is_action_locked": false, - "is_mapped": true, - "location": "/volume2", - "lun_id": 6, - "name": "LUN-1", - "restored_time": 0, - "retention": null, - "scheduled_task": [ - { - "general": { - "snap_rotate": true, - "snap_type": "app", - "task_enabled": false, - "task_name": "Task LUN-1", - "tid": -1, - "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - }, - "schedule": { - "date": "2025/3/24", - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "min": 0, - "monthly_week": [], - "next_trigger_time": "", - "repeat": 0, - "repeat_hour": 0, - "repeat_hour_store_config": null, - "repeat_min": 0, - "repeat_min_store_config": null, - "week_name": "0,1,2,3,4,5,6" - } + { + "dev_attrib": "emulate_caw", + "enable": 1 + }, + { + "dev_attrib": "emulate_tpu", + "enable": 1 + }, + { + "dev_attrib": "emulate_fua_write", + "enable": 0 + }, + { + "dev_attrib": "emulate_sync_cache", + "enable": 0 + }, + { + "dev_attrib": "can_snapshot", + "enable": 1 + } + ], + "dev_attribs_bitmap": 31, + "dev_config": "", + "dev_qos": { + "dev_limit": 0, + "dev_reservation": 0, + "dev_weight": 0, + "iops_enable": 0 + }, + "direct_io_pattern": 0, + "extent_size": 0, + "family_config": { + "parent_lun_name": "", + "parent_lun_uuid": "", + "parent_snapshot_time": 0, + "parent_snapshot_uuid": "" + }, + "flashcache_id": -1, + "flashcache_status": "no_cache", + "is_action_locked": false, + "is_mapped": true, + "location": "/volume2", + "lun_id": 6, + "name": "LUN-1", + "restored_time": 0, + "retention": null, + "scheduled_task": [ + { + "general": { + "snap_rotate": true, + "snap_type": "app", + "task_enabled": false, + "task_name": "Task LUN-1", + "tid": -1, + "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + }, + "schedule": { + "date": "2025/3/24", + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "min": 0, + "monthly_week": [], + "next_trigger_time": "", + "repeat": 0, + "repeat_hour": 0, + "repeat_hour_store_config": null, + "repeat_min": 0, + "repeat_min_store_config": null, + "week_name": "0,1,2,3,4,5,6" } - ], - "size": 1073741824, - "snapshots": [ - { - "create_time": 1742739365, - "description": "test", - "is_app_consistent": false, - "is_user_locked": true, - "mapped_size": 0, - "name": "SnapShot-1", - "parent_lun_id": 6, - "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "root_path": "/volume2", - "snapshot_id": 1, - "snapshot_time": 1742739365, - "status": { - "progress": { - "percent": -1, - "step": "waiting" - }, - "type": "Healthy" + } + ], + "size": 1073741824, + "snapshots": [ + { + "create_time": 1742739365, + "description": "test", + "is_app_consistent": false, + "is_user_locked": true, + "mapped_size": 0, + "name": "SnapShot-1", + "parent_lun_id": 6, + "parent_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "root_path": "/volume2", + "snapshot_id": 1, + "snapshot_time": 1742739365, + "status": { + "progress": { + "percent": -1, + "step": "waiting" }, - "taken_by": "user", - "total_size": 1073741824, - "type": 2, - "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "version": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - ], - "status": "normal", - "type": 263, - "type_str": "BLUN", - "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "vpd_unit_sn": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - ] - }, - "success": true - } - ``` - + "type": "Healthy" + }, + "taken_by": "user", + "total_size": 1073741824, + "type": 2, + "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "version": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + ], + "status": "normal", + "type": 263, + "type_str": "BLUN", + "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "vpd_unit_sn": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + ] + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.ISCSI.LUN' @@ -486,331 +474,328 @@ def list_replication_plans( "retention_lock_report" ] ) -> dict[str, object]: - """List replication plans. - - Parameters - ---------- - additional_info : list[str], optional - List of additional information to include in the response. Specify `[]` to get only basic information. - - - Defaults to `["sync_policy", "sync_report", "main_site_info", "dr_site_info", "can_do", "op_info", "last_op_info", "topology", "testfailover_info", "retention_lock_report"]`. - - - Possible values: - - `"sync_policy"` -> Information about the sync policy as schedule, retention, lock, etc. - - `"sync_report"` -> Information about the previous runs and their results / error count. - - `"main_site_info"` -> Information about the main site. - - `"dr_site_info"` -> Information about the destination site. - - `"can_do"` -> Information about the actions that can be performed on the replication plan. - - `"op_info"` -> Information about the current operation (restoring / syncing / etc.). - - `"last_op_info"` -> Information about the last operation. - - `"topology"` -> Information about the replication topology (main / dr site & plan information). - - `"testfailover_info"` -> Information about the previous test failover operation. - - `"retention_lock_report"` -> Information about the first / last snapshot. - - Returns - ------- - dict[str, object] - API response if successful, error message if not + """ + List replication plans. + + Parameters + ---------- + additional_info : list[str], optional + List of additional information to include in the response. Specify `[]` to get only basic information. + Defaults to `["sync_policy", "sync_report", "main_site_info", "dr_site_info", "can_do", "op_info", "last_op_info", "topology", "testfailover_info", "retention_lock_report"]`. + Possible values: + - `"sync_policy"` -> Information about the sync policy as schedule, retention, lock, etc. + - `"sync_report"` -> Information about the previous runs and their results / error count. + - `"main_site_info"` -> Information about the main site. + - `"dr_site_info"` -> Information about the destination site. + - `"can_do"` -> Information about the actions that can be performed on the replication plan. + - `"op_info"` -> Information about the current operation (restoring / syncing / etc.). + - `"last_op_info"` -> Information about the last operation. + - `"topology"` -> Information about the replication topology (main / dr site & plan information). + - `"testfailover_info"` -> Information about the previous test failover operation. + - `"retention_lock_report"` -> Information about the first / last snapshot. + + Returns + ------- + dict[str, object] + API response if successful, error message if not. - Examples - -------- - ```json - { - "data": { - "plans": [{ - "additional": { - "can_do": { - "can_cleanup_testfailover": false, - "can_delete": true, - "can_edit": true, - "can_export": false, - "can_failover": false, - "can_import": false, - "can_switchover": true, - "can_sync": true, - "can_testfailover": true, - "candidate_reprotect_new_mainsite": null - }, - "dr_site_info": { - "hostname": "hostname", - "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "op_info": { - "op_progress": { - "percentage": -1 - }, - "op_status": 1 - }, - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "role": 2, - "status": 1, - "target_id": "api-1", - "target_name": "api-1" - }, - "last_op_info": { - "err_code": 0, - "is_success": true, - "op_status": 16, - "update_time": 1742739562 - }, - "main_site_info": { - "hostname": "hostname", - "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "op_info": { - "op_progress": { - "percentage": -1 - }, - "op_status": 1 + Examples + -------- + ```json + { + "data": { + "plans": [{ + "additional": { + "can_do": { + "can_cleanup_testfailover": false, + "can_delete": true, + "can_edit": true, + "can_export": false, + "can_failover": false, + "can_import": false, + "can_switchover": true, + "can_sync": true, + "can_testfailover": true, + "candidate_reprotect_new_mainsite": null + }, + "dr_site_info": { + "hostname": "hostname", + "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "op_info": { + "op_progress": { + "percentage": -1 }, - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "role": 1, - "status": 1, - "target_id": "api", - "target_name": "api" + "op_status": 1 }, + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "role": 2, + "status": 1, + "target_id": "api-1", + "target_name": "api-1" + }, + "last_op_info": { + "err_code": 0, + "is_success": true, + "op_status": 16, + "update_time": 1742739562 + }, + "main_site_info": { + "hostname": "hostname", + "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "op_info": { "op_progress": { "percentage": -1 }, "op_status": 1 }, - "retention_lock_report": { - "first_snapshot": "GMT+01-2025.03.23-15.17.39", - "last_snapshot": "GMT+01-2025.03.23-15.18.46", - "retain_first": false + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "role": 1, + "status": 1, + "target_id": "api", + "target_name": "api" + }, + "op_info": { + "op_progress": { + "percentage": -1 }, - "sync_policy": { - "enabled": true, - "is_app_aware": false, - "is_send_encrypted": false, - "is_sync_local_snapshots": false, - "mode": 2, - "next_trigger_time": 1742770800, - "notify_time_in_min": 720, - "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", - "schedule": { - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "min": 0, - "repeat_hour": 0, - "repeat_min": 0, - "week_name": "0,1,2,3,4,5,6" - }, - "sync_window": { - "enabled": false, - "window": [ - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215 - ] - }, - "worm_lock_day": 7, - "worm_lock_enable": false, - "worm_lock_notify_time": 0 + "op_status": 1 + }, + "retention_lock_report": { + "first_snapshot": "GMT+01-2025.03.23-15.17.39", + "last_snapshot": "GMT+01-2025.03.23-15.18.46", + "retain_first": false + }, + "sync_policy": { + "enabled": true, + "is_app_aware": false, + "is_send_encrypted": false, + "is_sync_local_snapshots": false, + "mode": 2, + "next_trigger_time": 1742770800, + "notify_time_in_min": 720, + "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", + "schedule": { + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "min": 0, + "repeat_hour": 0, + "repeat_min": 0, + "week_name": "0,1,2,3,4,5,6" }, - "sync_report": { - "fail_sync_count": 0, - "recent_records": [ - { - "begin_time": 1742739460, - "current_speed": 0, - "data_size_byte": 750513392, - "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "elapsed_time": 37, - "extra": { - "site_task": { - "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "task_op": 2 - } - }, - "finish_time": 1742739497, - "is_done": true, - "is_stopped": false, - "is_success": true, - "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "readable_begin_time": "Sun Mar 23 15:17:40 2025", - "readable_finish_time": "Sun Mar 23 15:18:17 2025", - "snapshot_version": "GMT+01-2025.03.23-15.17.39", - "sync_size_byte": 750513392, - "total_size_byte": 750513392, - "update_time": 1742739497, - "version": 3 + "sync_window": { + "enabled": false, + "window": [ + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215 + ] + }, + "worm_lock_day": 7, + "worm_lock_enable": false, + "worm_lock_notify_time": 0 + }, + "sync_report": { + "fail_sync_count": 0, + "recent_records": [ + { + "begin_time": 1742739460, + "current_speed": 0, + "data_size_byte": 750513392, + "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "elapsed_time": 37, + "extra": { + "site_task": { + "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "task_op": 2 + } + }, + "finish_time": 1742739497, + "is_done": true, + "is_stopped": false, + "is_success": true, + "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "readable_begin_time": "Sun Mar 23 15:17:40 2025", + "readable_finish_time": "Sun Mar 23 15:18:17 2025", + "snapshot_version": "GMT+01-2025.03.23-15.17.39", + "sync_size_byte": 750513392, + "total_size_byte": 750513392, + "update_time": 1742739497, + "version": 3 + }, + { + "begin_time": 1742739528, + "current_speed": 0, + "data_size_byte": 8210, + "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "elapsed_time": 28, + "extra": { + "site_task": { + "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "task_op": 2 + } }, - { - "begin_time": 1742739528, - "current_speed": 0, - "data_size_byte": 8210, - "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "elapsed_time": 28, - "extra": { - "site_task": { - "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "task_op": 2 - } + "finish_time": 1742739556, + "is_done": true, + "is_stopped": false, + "is_success": true, + "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "readable_begin_time": "Sun Mar 23 15:18:48 2025", + "readable_finish_time": "Sun Mar 23 15:19:16 2025", + "snapshot_version": "GMT+01-2025.03.23-15.18.46", + "sync_size_byte": 8210, + "total_size_byte": 8210, + "update_time": 1742739556, + "version": 3 + } + ], + "success_sync_count": 2, + "syncing_record": null, + "total_success_sync_size_byte": 750521602, + "total_success_sync_time_sec": 65 + }, + "testfailover_info": null, + "topology": { + "links": [ + { + "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } + ], + "sites": [ + { + "addr": "", + "hostname": "hostname", + "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "plans": [ + { + "additional": { + "sync_policy": { + "enabled": true, + "is_app_aware": false, + "is_send_encrypted": false, + "is_sync_local_snapshots": false, + "mode": 2, + "next_trigger_time": 1742770800, + "notify_time_in_min": 720, + "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", + "schedule": { + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "min": 0, + "repeat_hour": 0, + "repeat_min": 0, + "week_name": "0,1,2,3,4,5,6" + }, + "sync_window": { + "enabled": false, + "window": [ + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215 + ] + }, + "worm_lock_day": 7, + "worm_lock_enable": false, + "worm_lock_notify_time": 0 + } + }, + "is_to_local": true, + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "remote_target_name": "api-1", + "role": 1, + "status": 1, + "target_id": "api", + "target_name": "api" }, - "finish_time": 1742739556, - "is_done": true, - "is_stopped": false, - "is_success": true, - "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "readable_begin_time": "Sun Mar 23 15:18:48 2025", - "readable_finish_time": "Sun Mar 23 15:19:16 2025", - "snapshot_version": "GMT+01-2025.03.23-15.18.46", - "sync_size_byte": 8210, - "total_size_byte": 8210, - "update_time": 1742739556, - "version": 3 - } - ], - "success_sync_count": 2, - "syncing_record": null, - "total_success_sync_size_byte": 750521602, - "total_success_sync_time_sec": 65 - }, - "testfailover_info": null, - "topology": { - "links": [ - { - "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - ], - "sites": [ - { - "addr": "", - "hostname": "hostname", - "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "plans": [ - { - "additional": { - "sync_policy": { - "enabled": true, - "is_app_aware": false, - "is_send_encrypted": false, - "is_sync_local_snapshots": false, - "mode": 2, - "next_trigger_time": 1742770800, - "notify_time_in_min": 720, - "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", - "schedule": { - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "min": 0, - "repeat_hour": 0, - "repeat_min": 0, - "week_name": "0,1,2,3,4,5,6" - }, - "sync_window": { - "enabled": false, - "window": [ - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215 - ] - }, - "worm_lock_day": 7, - "worm_lock_enable": false, - "worm_lock_notify_time": 0 - } - }, - "is_to_local": true, - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "remote_target_name": "api-1", - "role": 1, - "status": 1, - "target_id": "api", - "target_name": "api" + ], + "status": 1 + }, + { + "addr": "", + "hostname": "hostname2", + "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "plans": [ + { + "additional": { + "sync_policy": { + "enabled": true, + "is_app_aware": false, + "is_send_encrypted": true, + "is_sync_local_snapshots": false, + "mode": 2, + "next_trigger_time": 1742770800, + "notify_time_in_min": 720, + "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", + "schedule": { + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "min": 0, + "repeat_hour": 0, + "repeat_min": 0, + "week_name": "0,1,2,3,4,5,6" + }, + "sync_window": { + "enabled": false, + "window": [ + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215, + 16777215 + ] + }, + "worm_lock_day": 7, + "worm_lock_enable": false, + "worm_lock_notify_time": 0 + } }, - ], - "status": 1 - }, - { - "addr": "", - "hostname": "hostname2", - "node_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "plans": [ - { - "additional": { - "sync_policy": { - "enabled": true, - "is_app_aware": false, - "is_send_encrypted": true, - "is_sync_local_snapshots": false, - "mode": 2, - "next_trigger_time": 1742770800, - "notify_time_in_min": 720, - "readable_next_trigger_time": "Mon Mar 24 00:00:00 2025", - "schedule": { - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "min": 0, - "repeat_hour": 0, - "repeat_min": 0, - "week_name": "0,1,2,3,4,5,6" - }, - "sync_window": { - "enabled": false, - "window": [ - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215, - 16777215 - ] - }, - "worm_lock_day": 7, - "worm_lock_enable": false, - "worm_lock_notify_time": 0 - } - }, - "is_to_local": false, - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "remote_target_name": "api", - "role": 2, - "status": 1, - "target_id": "api", - "target_name": "api" - } - ], - "status": 1 - } - ], - "target": { - "target_id": "api", - "target_type": 2 + "is_to_local": false, + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "remote_target_name": "api", + "role": 2, + "status": 1, + "target_id": "api", + "target_name": "api" + } + ], + "status": 1 } + ], + "target": { + "target_id": "api", + "target_type": 2 } - }, - "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "is_to_local": true, - "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "role": 1, - "role_str": "mainsite", - "solution_type": 1, - "sync_mode": 2, - "target_id": "api", - "target_type": 2 - }] - }, - "success": true - } - ``` + } + }, + "dr_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "is_to_local": true, + "main_site": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "plan_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "role": 1, + "role_str": "mainsite", + "solution_type": 1, + "sync_mode": 2, + "target_id": "api", + "target_type": 2 + }] + }, + "success": true + } + ``` """ api_name = 'SYNO.DR.Plan' @@ -833,40 +818,36 @@ def create_snapshot( immutable: bool = False, immutable_days: int = 7, ) -> dict[str, object]: - """Create a snapshot for a share. - - Parameters - ---------- - share_name : str - Name of the share to create a snapshot for. - - description : str, optional - Description of the snapshot. Defaults to `""`. - - lock : bool, optional - Whether to lock the snapshot. Defaults to `False`. - - immutable : bool, optional - Whether to make the snapshot immutable. Defaults to `False`. - - immutable_days : int, optional - Number of days to make the snapshot immutable for. Defaults to `7`. - - Must be greater than `0`. Mandatory if immutable is `True`. - - Returns - ------- - dict[str, object] - API response if successful, error message if not. + """ + Create a snapshot for a share. + + Parameters + ---------- + share_name : str + Name of the share to create a snapshot for. + description : str, optional + Description of the snapshot. Defaults to `""`. + lock : bool, optional + Whether to lock the snapshot. Defaults to `False`. + immutable : bool, optional + Whether to make the snapshot immutable. Defaults to `False`. + immutable_days : int, optional + Number of days to make the snapshot immutable for. Defaults to `7`. + Must be greater than `0`. Mandatory if immutable is `True`. + + Returns + ------- + dict[str, object] + API response if successful, error message if not. - Examples - -------- - ```json - { - "data": "GMT+09-2023.09.12-00.33.20", - "success": true - } - ``` + Examples + -------- + ```json + { + "data": "GMT+09-2023.09.12-00.33.20", + "success": true + } + ``` """ api_name = 'SYNO.Core.Share.Snapshot' @@ -898,30 +879,32 @@ def delete_snapshots( share_name: str, snapshots: list[str] ) -> dict[str, object]: - """Delete snapshots for a share. - - Warning: This action removes data from the file system. Use with caution. + """ + Delete snapshots for a share. - Parameters - ---------- - share_name : str - Name of the share to delete snapshots for. + Parameters + ---------- + share_name : str + Name of the share to delete snapshots for. + snapshots : list[str] + List of snapshots to delete. - snapshots : list[str] - List of snapshots to delete. + Returns + ------- + dict[str, object] + API response if successful, error message if not. - Returns - ------- - dict[str, object] - API response if successful, error message if not. + Notes + ----- + Warning: This action removes data from the file system. Use with caution. - Examples - -------- - ```json - { - "success": true - } - ``` + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = 'SYNO.Core.Share.Snapshot' @@ -946,41 +929,37 @@ def set_snapshot_attr( immutable: Optional[bool] = None, immutable_days: Optional[int] = None ) -> dict[str, object]: - """Set attributes for a snapshot. - - Parameters - ---------- - share_name : str - Name of the share to set attributes for - - snapshot : str - Name of the snapshot to set attributes for - - description : str, optional - Description of the snapshot. Defaults to `None` (no change). - - lock : bool, optional - Whether to lock the snapshot. Defaults to `None` (no change). - - immutable : bool, optional - Whether to make the snapshot immutable. Defaults to `None` (no change). - - immutable_days : int, optional - Number of days to make the snapshot immutable for. Defaults to `None` (no change). - Must be greater than `0`. Mandatory if immutable is `True`. - - Returns - ------- - dict[str, object] - API response if successful, error message if not. + """ + Set attributes for a snapshot. + + Parameters + ---------- + share_name : str + Name of the share to set attributes for. + snapshot : str + Name of the snapshot to set attributes for. + description : str, optional + Description of the snapshot. Defaults to `None` (no change). + lock : bool, optional + Whether to lock the snapshot. Defaults to `None` (no change). + immutable : bool, optional + Whether to make the snapshot immutable. Defaults to `None` (no change). + immutable_days : int, optional + Number of days to make the snapshot immutable for. Defaults to `None` (no change). + Must be greater than `0`. Mandatory if immutable is `True`. + + Returns + ------- + dict[str, object] + API response if successful, error message if not. - Examples - -------- - ```json - { - "success": true - } - ``` + Examples + -------- + ```json + { + "success": true + } + ``` """ api_name = 'SYNO.Core.Share.Snapshot' @@ -1020,31 +999,30 @@ def sync_replication( lock_snapshot: bool = True, description: str = "Snapshot taken by [Synology API]", ) -> dict[str, object]: - """Trigger a sync for a replication plan. - - Parameters - ---------- - plan_id : str - ID of the replication plan to sync. - - lock_snapshot : bool, optional - Whether to lock the snapshot to prevent rotation. Defaults to `True`. - - description : str, optional - Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. - - Returns - ------- - dict[str, object] - API response if successful + """ + Trigger a sync for a replication plan. + + Parameters + ---------- + plan_id : str + ID of the replication plan to sync. + lock_snapshot : bool, optional + Whether to lock the snapshot to prevent rotation. Defaults to `True`. + description : str, optional + Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. + + Returns + ------- + dict[str, object] + API response if successful. - Examples - -------- - ```json - { - "success": true - } - ``` + Examples + -------- + ```json + { + "success": true + } + ``` """ plans = self.list_replication_plans( @@ -1078,40 +1056,40 @@ def create_snapshot_lun( lock: bool = True, app_aware: bool = True ) -> dict[str, object]: - """Create a snapshot for a LUN. - - Note: At the moment, it does not support creating WORM snapshots. - - Parameters - ---------- - lun_id : str - ID of the LUN to create a snapshot for - - description : str, optional - Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. - - lock : bool, optional - Whether to lock the snapshot. Defaults to `True`. - - app_aware : bool, optional - Whether to make the snapshot application aware. Defaults to `True`. - - Returns - ------- - dict[str, object] - API response if successful + """ + Create a snapshot for a LUN. + + Parameters + ---------- + lun_id : str + ID of the LUN to create a snapshot for. + description : str, optional + Description of the snapshot. Defaults to `Snapshot taken by [Synology API]`. + lock : bool, optional + Whether to lock the snapshot. Defaults to `True`. + app_aware : bool, optional + Whether to make the snapshot application aware. Defaults to `True`. + + Returns + ------- + dict[str, object] + API response if successful. + + Notes + ----- + At the moment, it does not support creating WORM snapshots. - Examples - -------- - ```json - { - "data": { - "snapshot_id": 4, - "snapshot_uuid": "31aa7808-9ffc-4689-bb70-262bb1665c9b" - }, - "success": true - } - ``` + Examples + -------- + ```json + { + "data": { + "snapshot_id": 4, + "snapshot_uuid": "31aa7808-9ffc-4689-bb70-262bb1665c9b" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.ISCSI.LUN' @@ -1130,41 +1108,42 @@ def create_snapshot_lun( return self.request_data(api_name, api_path, req_param) def delete_snapshots_lun(self, snapshot_uuids: list[str]) -> dict[str, object]: - """Delete snapshots for a LUN. - - Warning: This action removes data from the file system. Use with caution. - - Parameters - ---------- - snapshot_uuids : list[str] - List of UUIDs of the snapshots to delete. - - Returns - ------- - dict[str, object] - API response if successful. - + """ + Delete snapshots for a LUN. - If deletion fails, an error code is returned alonside the snapshot uuid: - ```json - { - "data": [ - { - "5c9bf4a7-05ea-4cb8-b9e0-e0b0ca1186b0": 18990540 - } - ], - "success": true - } - ``` + Parameters + ---------- + snapshot_uuids : list[str] + List of UUIDs of the snapshots to delete. - Examples - -------- + Returns + ------- + dict[str, object] + If deletion fails, an error code is returned alongside the snapshot uuid: ```json { - "data": [], + "data": [ + { + "5c9bf4a7-05ea-4cb8-b9e0-e0b0ca1186b0": 18990540 + } + ], "success": true } ``` + API response if successful. + + Notes + ----- + Warning: This action removes data from the file system. Use with caution. + + Examples + -------- + ```json + { + "data": [], + "success": true + } + ``` """ api_name = 'SYNO.Core.ISCSI.LUN' diff --git a/synology_api/surveillancestation.py b/synology_api/surveillancestation.py index bfb91e76..4570f724 100644 --- a/synology_api/surveillancestation.py +++ b/synology_api/surveillancestation.py @@ -1,11 +1,27 @@ +"""Synology Surveillance Station API Wrapper.""" from __future__ import annotations from typing import Optional, Any from . import base_api class SurveillanceStation(base_api.BaseApi): + """ + API wrapper for Synology Surveillance Station. + + Provides methods to interact with Surveillance Station features such as retrieving + station information and saving camera configurations. + """ def surveillance_station_info(self) -> dict[str, object] | str: + """ + Retrieve information about the Surveillance Station. + + Returns + ------- + dict[str, object] or str + A dictionary containing Surveillance Station information, or a string + with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Info' info = self.gen_list[api_name] api_path = info['path'] @@ -40,6 +56,71 @@ def camera_save(self, id: str = None, enableLowProfile: bool = None, recordSchedule: list[int] = None, rtspPathTimeout: int = None) -> dict[str, object] | str: + """ + Save or update camera configuration. + + Parameters + ---------- + id : str, optional + Camera ID. + name : str, optional + Camera name. + dsld : int, optional + Device slot ID. + newName : str, optional + New camera name. + ip : str, optional + Camera IP address. + port : int, optional + Camera port. + vendor : str, optional + Camera vendor. + model : str, optional + Camera model. + userName : str, optional + Username for camera authentication. + password : str, optional + Password for camera authentication. + videoCodec : int, optional + Video codec type. + audioCodec : int, optional + Audio codec type. + tvStandard : int, optional + TV standard. + channel : str, optional + Channel identifier. + userDefinePath : str, optional + User-defined path. + fov : str, optional + Field of view. + streamXX : Any, optional + Stream configuration. + recordTime : int, optional + Recording time. + preRecordTime : int, optional + Pre-recording time. + postRecordTime : int, optional + Post-recording time. + enableRecordingKeepDays : bool, optional + Enable recording retention by days. + recordingKeepDays : int, optional + Number of days to keep recordings. + enableRecordingKeepSize : bool, optional + Enable recording retention by size. + recordingKeepSize : int, optional + Maximum size for recordings. + enableLowProfile : bool, optional + Enable low profile recording. + recordSchedule : list of int, optional + Recording schedule. + rtspPathTimeout : int, optional + RTSP path timeout. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -62,7 +143,37 @@ def camera_list(self, idList: str = None, streamInfo: bool = None, blPrivilege: bool = None, camStm: int = None) -> dict[str, object] | str: - + """ + Retrieve a list of cameras from Surveillance Station. + + Parameters + ---------- + idList : str, optional + Comma-separated list of camera IDs to filter. + offset : int, optional + The starting index for the camera list. + limit : int, optional + The maximum number of cameras to return. + blFromCamList : bool, optional + Whether to retrieve from the camera list. + blIncludeDeletedCam : bool, optional + Whether to include deleted cameras. + privCamType : str, optional + Filter by camera privilege type. + basic : bool, optional + Whether to return only basic information. + streamInfo : bool, optional + Whether to include stream information. + blPrivilege : bool, optional + Whether to include privilege information. + camStm : int, optional + Camera stream type. + + Returns + ------- + dict[str, object] or str + Dictionary containing camera list information, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -87,21 +198,44 @@ def get_camera_info(self, deviceOutCap: bool = True, fisheye: bool = True, camAppInfo: bool = True) -> dict[str, object] | str: - ''' - This function return information about a camera. - - cameraIds : This parameter is named cameraIds in the API documentation but it refer to 1 camera ID - - privCamType: int = 1 - SYNO.SS.CamPriv.LIVEVIEW = 1; - SYNO.SS.CamPriv.PLAYBACK = 2; - SYNO.SS.CamPriv.LENS = 4; - SYNO.SS.CamPriv.AUDIO = 8; - SYNO.SS.CamPriv.DIGIOUT = 16; - - All other parameters must be let to default value - ''' - + """ + Return information about a camera. + + Parameters + ---------- + cameraIds : int, optional + Camera ID. Although named cameraIds in the API, it refers to a single camera ID. + privCamType : int, default=1 + Camera privilege type. Possible values: + 1: LIVEVIEW + 2: PLAYBACK + 4: LENS + 8: AUDIO + 16: DIGIOUT + blIncludeDeletedCam : bool, default=True + Whether to include deleted cameras. + basic : bool, default=True + Whether to return only basic information. + streamInfo : bool, default=True + Whether to include stream information. + optimize : bool, default=True + Whether to optimize the returned data. + ptz : bool, default=True + Whether to include PTZ (Pan-Tilt-Zoom) information. + eventDetection : bool, default=True + Whether to include event detection information. + deviceOutCap : bool, default=True + Whether to include device output capabilities. + fisheye : bool, default=True + Whether to include fisheye camera information. + camAppInfo : bool, default=True + Whether to include camera application information. + + Returns + ------- + dict[str, object] or str + Dictionary containing camera information, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -117,7 +251,21 @@ def get_camera_info(self, def camera_list_group(self, offset: int = None, limit: int = None) -> dict[str, object] | str: - + """ + Retrieve a list of camera groups from Surveillance Station. + + Parameters + ---------- + offset : int, optional + The starting index for the camera group list. + limit : int, optional + The maximum number of camera groups to return. + + Returns + ------- + dict[str, object] or str + Dictionary containing camera group information, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -135,9 +283,25 @@ def get_snapshot(self, name: str = None, dsld: int = None, profileType: int = 1) -> str: - ''' By default, the profileType is 1, which is the default profile. - Binary data is returned, so the response is not a json object. - ''' + """ + Retrieve a snapshot image from a camera. + + Parameters + ---------- + id : Any, optional + Camera identifier. + name : str, optional + Camera name. + dsld : int, optional + Device slot ID. + profileType : int, default=1 + Profile type for the snapshot (1 is the default profile). + + Returns + ------- + str + Binary data of the snapshot image. The response is not a JSON object. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -154,6 +318,21 @@ def get_snapshot(self, def enable_camera(self, idList: str = None, blIncludeDeletedCam: bool = False) -> dict[str, object] | str: + """ + Enable one or more cameras by their IDs. + + Parameters + ---------- + idList : str, optional + Comma-separated list of camera IDs to enable. + blIncludeDeletedCam : bool, optional + Whether to include deleted cameras in the operation. Default is False. + + Returns + ------- + dict[str, object] or str + Result of the enable operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -169,6 +348,21 @@ def enable_camera(self, def disable_camera(self, idList: str = None, blIncludeDeletedCam: bool = False) -> dict[str, object] | str: + """ + Disable one or more cameras by their IDs. + + Parameters + ---------- + idList : str, optional + Comma-separated list of camera IDs to disable. + blIncludeDeletedCam : bool, optional + Whether to include deleted cameras in the operation. Default is False. + + Returns + ------- + dict[str, object] or str + Result of the disable operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -183,6 +377,19 @@ def disable_camera(self, # TODO not working def get_capability_by_cam_id(self, cameraId: Any = None) -> dict[str, object] | str: + """ + Retrieve the capability information for a specific camera by its ID. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera for which to retrieve capability information. + + Returns + ------- + dict[str, object] or str + A dictionary containing the camera's capability information, or a string with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -193,6 +400,19 @@ def get_capability_by_cam_id(self, cameraId: Any = None) -> dict[str, object] | # TODO not working def count_occupied_size(self, camId: int = None) -> dict[str, object] | str: + """ + Retrieve the occupied storage size for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to retrieve the occupied size. + + Returns + ------- + dict[str, object] or str + A dictionary containing the occupied size information, or a string with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -203,6 +423,19 @@ def count_occupied_size(self, camId: int = None) -> dict[str, object] | str: # TODO not working def is_shortcut_valid(self, cameraId: int = None) -> dict[str, object] | str: + """ + Check if a camera shortcut is valid. + + Parameters + ---------- + cameraId : int, optional + The ID of the camera to validate the shortcut for. + + Returns + ------- + dict[str, object] or str + A dictionary with the validation result, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -212,6 +445,19 @@ def is_shortcut_valid(self, cameraId: int = None) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_live_path(self, idList: int = None) -> dict[str, object] | str: + """ + Retrieve the live view path for one or more cameras. + + Parameters + ---------- + idList : int, optional + Camera ID or comma-separated list of camera IDs for which to retrieve the live view path. + + Returns + ------- + dict[str, object] or str + Dictionary containing the live view path information, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera' info = self.gen_list[api_name] api_path = info['path'] @@ -221,6 +467,19 @@ def get_live_path(self, idList: int = None) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def audio_event_enum(self, camId: int = None) -> dict[str, object] | str: + """ + Enumerate audio events for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to enumerate audio events. + + Returns + ------- + dict[str, object] or str + Dictionary containing audio event enumeration, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -231,6 +490,19 @@ def audio_event_enum(self, camId: int = None) -> dict[str, object] | str: # TODO not working def alarm_event_enum(self, camId: int = None) -> dict[str, object] | str: + """ + Enumerate alarm events for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to enumerate alarm events. + + Returns + ------- + dict[str, object] or str + Dictionary containing alarm event enumeration, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -246,6 +518,31 @@ def md_parameter_save(self, camId: int = None, threshold: int = None, objectSize: int = None, percentage: int = None) -> dict[str, object] | str: + """ + Save motion detection parameters for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to save motion detection parameters. + source : int, optional + The source channel or stream index. + mode : int, optional + The motion detection mode. + sensitivity : int, optional + Sensitivity level for motion detection. + threshold : int, optional + Threshold value for motion detection. + objectSize : int, optional + Minimum object size to trigger detection. + percentage : int, optional + Minimum percentage of the detection area to trigger detection. + + Returns + ------- + dict[str, object] or str + Result of the save operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -259,6 +556,19 @@ def md_parameter_save(self, camId: int = None, return self.request_data(api_name, api_path, req_param) def motion_event_enum(self, camId: int = None) -> dict[str, object] | str: + """ + Enumerate motion events for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to enumerate motion events. + + Returns + ------- + dict[str, object] or str + Dictionary containing motion event enumeration, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -273,7 +583,27 @@ def motion_parameter_save(self, mode: int = None, keep: bool = None, level: int = None) -> dict[str, object] | str: - + """ + Save advanced motion detection parameters for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to save motion detection parameters. + source : int, optional + The source channel or stream index. + mode : int, optional + The motion detection mode. + keep : bool, optional + Whether to keep the current settings. + level : int, optional + Sensitivity level for advanced motion detection. + + Returns + ------- + dict[str, object] or str + Result of the save operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -291,7 +621,25 @@ def di_parameter_save(self, idx: int = None, keep: bool = None, normal: int = None) -> dict[str, object] | str: - + """ + Save digital input (DI) parameters for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to save DI parameters. + idx : int, optional + The index of the DI channel. + keep : bool, optional + Whether to keep the current DI settings. + normal : int, optional + The normal state value for the DI channel. + + Returns + ------- + dict[str, object] or str + Result of the save operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -309,7 +657,23 @@ def alarm_sts_polling(self, timeOut: int = None, # TODO not working keep: Any = None) -> dict[str, object] | str: - + """ + Poll the alarm status for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to poll alarm status. + timeOut : int, optional + Timeout value for the polling operation. + keep : Any, optional + Reserved for future use or additional options (currently not working). + + Returns + ------- + dict[str, object] or str + Dictionary containing alarm status polling result, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -328,7 +692,25 @@ def td_parameter_save(self, source: int = None, keep: Any = None, duration: int = None) -> dict[str, object] | str: - + """ + Save tamper detection (TD) parameters for a specific camera. + + Parameters + ---------- + camId : int, optional + The ID of the camera for which to save tamper detection parameters. + source : int, optional + The source channel or stream index. + keep : Any, optional + Whether to keep the current settings (reserved for future use). + duration : int, optional + Duration for the tamper detection event. + + Returns + ------- + dict[str, object] or str + Result of the save operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Event' info = self.gen_list[api_name] api_path = info['path'] @@ -342,7 +724,19 @@ def td_parameter_save(self, return self.request_data(api_name, api_path, req_param) def enumerate_camera_group(self, privCamType: int = None) -> dict[str, object] | str: - + """ + Enumerate camera groups in Surveillance Station. + + Parameters + ---------- + privCamType : int, optional + Camera privilege type to filter groups. + + Returns + ------- + dict[str, object] or str + Dictionary containing camera group enumeration, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Group' info = self.gen_list[api_name] api_path = info['path'] @@ -353,6 +747,19 @@ def enumerate_camera_group(self, privCamType: int = None) -> dict[str, object] | # TODO to check def save_specific_group(self, groupList: Any = None) -> dict[str, object] | str: + """ + Save or update a specific camera group in Surveillance Station. + + Parameters + ---------- + groupList : Any, optional + The list of groups to be saved or updated. + + Returns + ------- + dict[str, object] or str + Result of the save operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Group' info = self.gen_list[api_name] api_path = info['path'] @@ -362,6 +769,19 @@ def save_specific_group(self, groupList: Any = None) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def delete_specific_groups(self, Id: int = None) -> dict[str, object] | str: + """ + Delete specific camera groups in Surveillance Station. + + Parameters + ---------- + Id : int, optional + The ID of the camera group to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Group' info = self.gen_list[api_name] api_path = info['path'] @@ -376,6 +796,27 @@ def enumerate_group_information(self, camServerId: int = None, camlist: Any = None, # TODO not working actFromHost: bool = None) -> dict[str, object] | str: + """ + Enumerate group information for camera import in Surveillance Station. + + Parameters + ---------- + camServerId : int, optional + The ID of the camera server. + shareName : str, optional + The name of the shared folder. + archiveName : str, optional + The name of the archive. + camlist : Any, optional + List of cameras to include. + actFromHost : bool, optional + Whether the action is performed from the host. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the group information enumeration as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Import' info = self.gen_list[api_name] api_path = info['path'] @@ -392,6 +833,23 @@ def enumerate_camera_from_archive(self, shareName: str = None, archiveName: str = None, serverId: int = None) -> dict[str, object] | str: + """ + Enumerate cameras from a specified archive in Surveillance Station. + + Parameters + ---------- + shareName : str, optional + The name of the shared folder containing the archive. + archiveName : str, optional + The name of the archive to enumerate cameras from. + serverId : int, optional + The ID of the server associated with the archive. + + Returns + ------- + dict[str, object] or str + A dictionary containing camera enumeration details, or a string with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Camera.Import' info = self.gen_list[api_name] api_path = info['path'] @@ -407,6 +865,19 @@ def enumerate_camera_from_archive(self, def enumerate_archive_from_folder(self, # TODO not working shareName: str = None) -> dict[str, object] | str: + """ + Enumerate archives from a specified folder in Surveillance Station. + + Parameters + ---------- + shareName : str, optional + The name of the shared folder containing the archives. + + Returns + ------- + dict[str, object] or str + A dictionary containing archive enumeration details, or a string with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Camera.Import' info = self.gen_list[api_name] api_path = info['path'] @@ -429,6 +900,33 @@ def check_available_size_of_sdcard(self, model: str = None, # TODO not working ch: str = None) -> dict[str, object] | str: + """ + Check the available size of the SD card for a specific camera. + + Parameters + ---------- + camId : Any, optional + The ID of the camera. + host : str, optional + The host address of the camera. + port : str, optional + The port number for the camera connection. + user : str, optional + The username for authentication. + passw : str, optional + The password for authentication. + vendor : str, optional + The vendor of the camera. + model : str, optional + The model of the camera. + ch : str, optional + The channel identifier. (Currently not working). + + Returns + ------- + dict[str, object] or str + A dictionary containing the available size information, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Wizard' info = self.gen_list[api_name] api_path = info['path'] @@ -446,6 +944,14 @@ def check_available_size_of_sdcard(self, # TODO not working def check_licence_quota(self) -> dict[str, object] | str: + """ + Check the license quota for Surveillance Station cameras. + + Returns + ------- + dict[str, object] or str + A dictionary containing license quota information, or a string with error details if the request fails. + """ api_name = 'SYNO.SurveillanceStation.Camera.Wizard' info = self.gen_list[api_name] api_path = info['path'] @@ -464,6 +970,35 @@ def format_specific_sd_card(self, ch: str = None, # TODO not working timeout: int = None) -> dict[str, object] | str: + """ + Format the SD card of a specific camera. + + Parameters + ---------- + camId : Any, optional + The ID of the camera whose SD card is to be formatted. + host : str, optional + The host address of the camera. + port : str, optional + The port number for the camera connection. + user : str, optional + The username for authentication. + passw : str, optional + The password for authentication. + vendor : str, optional + The vendor of the camera. + model : str, optional + The model of the camera. + ch : str, optional + The channel identifier. + timeout : int, optional + Timeout value for the formatting operation. (Currently not working). + + Returns + ------- + dict[str, object] or str + A dictionary containing the result of the format operation, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Wizard' info = self.gen_list[api_name] api_path = info['path'] @@ -496,6 +1031,47 @@ def quick_create_single_camera(self, camUserName: str = None, # TODO to check camPassWord: str = None) -> dict[str, object] | str: + """ + Quickly create a single camera in Surveillance Station. + + Parameters + ---------- + camServerId : Any, optional + The ID of the camera server. + actFromHost : bool, optional + Whether the action is performed from the host. + camStreamingType : str, optional + The streaming type of the camera. + camName : str, optional + The name of the camera. + camIP : str, optional + The IP address of the camera. + camPort : str, optional + The port number of the camera. + camVendor : str, optional + The vendor of the camera. + camModel : str, optional + The model of the camera. + camMountType : int, optional + The mount type of the camera. + camChannel : str, optional + The channel of the camera. + camVideoType : str, optional + The video type of the camera. + camAudioType : str, optional + The audio type of the camera. + camSourcePath : str, optional + The source path for the camera stream. + camUserName : str, optional + The username for camera authentication. + camPassWord : str, optional + The password for camera authentication. (To be checked). + + Returns + ------- + dict[str, object] or str + Result of the quick create operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Wizard' info = self.gen_list[api_name] api_path = info['path'] @@ -514,6 +1090,25 @@ def move_camera_lens(self, speed: int = None, # TODO not working moveType: str = None) -> dict[str, object] | str: + """ + Move the camera lens in a specified direction with an optional speed and move type. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control. + direction : str, optional + The direction to move the lens (e.g., 'up', 'down', 'left', 'right'). + speed : int, optional + The speed at which to move the lens. + moveType : str, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the move operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -531,6 +1126,23 @@ def camera_lens_zoom(self, control: Any = None, # TODO not working moveType: str = None) -> dict[str, object] | str: + """ + Control the zoom function of a camera lens. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control. + control : Any, optional + The zoom control command or value. + moveType : str, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the zoom operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -548,6 +1160,23 @@ def list_preset_ptz_camera(self, offset: int = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + List preset positions for a PTZ (Pan-Tilt-Zoom) camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the PTZ camera to list presets for. + offset : int, optional + The starting index for the preset list. + limit : int, optional + The maximum number of presets to return. (Currently not working). + + Returns + ------- + dict[str, object] or str + Dictionary containing the list of PTZ presets, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -568,6 +1197,29 @@ def move_camera_lens_to_preset_position(self, type: Any = None, # TODO not working isPatrol: bool = None) -> dict[str, object] | str: + """ + Move the camera lens to a specified preset position. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control. + presetId : Any, optional + The ID of the preset position to move to. + position : Any, optional + The position value for the preset. + speed : Any, optional + The speed at which to move the lens. + type : Any, optional + The type of movement or preset. + isPatrol : bool, optional + Whether the movement is part of a patrol operation. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the move operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -585,6 +1237,23 @@ def list_patrol_cameras(self, offset: int = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + List patrols for a PTZ (Pan-Tilt-Zoom) camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the PTZ camera to list patrols for. + offset : int, optional + The starting index for the patrol list. + limit : int, optional + The maximum number of patrols to return. (Currently not working). + + Returns + ------- + dict[str, object] or str + Dictionary containing the list of PTZ patrols, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -601,6 +1270,21 @@ def force_cam_to_execute_patrol(self, cameraId: Any = None, # TODO not working patrolId: Any = None) -> dict[str, object] | str: + """ + Force a camera to execute a specified patrol. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to execute the patrol. + patrolId : Any, optional + The ID of the patrol to execute. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the patrol execution as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -618,6 +1302,23 @@ def focus_camera(self, control: Any = None, # TODO not working moveType: Any = None) -> dict[str, object] | str: + """ + Control the focus function of a camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control. + control : Any, optional + The focus control command or value. + moveType : Any, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the focus operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -635,6 +1336,23 @@ def control_camera_iris_in_out(self, control: Any = None, # TODO not working moveType: Any = None) -> dict[str, object] | str: + """ + Control the iris (in/out) function of a camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control. + control : Any, optional + The iris control command or value. + moveType : Any, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the iris control operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -649,6 +1367,19 @@ def control_camera_iris_in_out(self, # TODO not working def auto_focus(self, cameraId: Any = None) -> dict[str, object] | str: + """ + Perform an auto-focus operation on a specified camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to auto-focus. + + Returns + ------- + dict[str, object] or str + Result of the auto-focus operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -665,6 +1396,21 @@ def move_cam_lens_to_absolute_position(self, posX: int = None, # TODO not working posY: int = None) -> dict[str, object] | str: + """ + Move the camera lens to an absolute position. + + Parameters + ---------- + posX : int, optional + The X coordinate for the absolute position. + posY : int, optional + The Y coordinate for the absolute position. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the move operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -680,6 +1426,19 @@ def move_cam_lens_to_absolute_position(self, def move_cam_to_home_position(self, # TODO not working cameraId: Any = None) -> dict[str, object] | str: + """ + Move the camera to its home position. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to move to the home position. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the move operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -696,6 +1455,21 @@ def auto_pan_camera(self, cameraId: Any = None, # TODO not working moveType: str = None) -> dict[str, object] | str: + """ + Automatically pan the camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to auto-pan. + moveType : str, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the auto-pan operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -712,6 +1486,21 @@ def start_stop_object_tracking(self, cameraId: Any = None, # TODO not working moveType: str = None) -> dict[str, object] | str: + """ + Start or stop object tracking for a specified camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control object tracking. + moveType : str, optional + The type of movement (reserved for future use, currently not working). + + Returns + ------- + dict[str, object] or str + Result of the object tracking operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ' info = self.gen_list[api_name] api_path = info['path'] @@ -728,6 +1517,21 @@ def start_stop_external_recording(self, cameraId: Any = None, # TODO not working action: str = None) -> dict[str, object] | str: + """ + Start or stop external recording for a specified camera. + + Parameters + ---------- + cameraId : Any, optional + The ID of the camera to control external recording. + action : str, optional + The action to perform (e.g., 'start' or 'stop'). (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the external recording operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.ExternalRecording' info = self.gen_list[api_name] api_path = info['path'] @@ -748,6 +1552,31 @@ def query_event_list_by_filter(self, toTime: int = None, dsld: int = None, mountId: int = None) -> dict[str, object] | str: + """ + Query the event list by applying various filters. + + Parameters + ---------- + offset : int, optional + The starting index for the event list. + limit : int, optional + The maximum number of events to return. + cameraIds : str, optional + Comma-separated list of camera IDs to filter events. + fromTime : int, optional + Start time (timestamp) for filtering events. + toTime : int, optional + End time (timestamp) for filtering events. + dsld : int, optional + Device slot ID to filter events. + mountId : int, optional + Mount ID to filter events. + + Returns + ------- + dict[str, object] or str + Dictionary containing the filtered event list, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -763,6 +1592,21 @@ def query_event_list_by_filter(self, def delete_recordings(self, idList: int = None, dsld: int = None) -> dict[str, object] | str: + """ + Delete specific recordings from Surveillance Station. + + Parameters + ---------- + idList : int, optional + The ID or comma-separated list of IDs of the recordings to delete. + dsld : int, optional + Device slot ID associated with the recordings. + + Returns + ------- + dict[str, object] or str + Result of the delete operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -788,6 +1632,39 @@ def delete_events_by_filter(self, from_end: int = None, # TODO not working from_start: int = None) -> dict[str, object] | str: + """ + Delete events from Surveillance Station by applying various filters. + + Parameters + ---------- + reason : str, optional + The reason for deleting the events. + cameraIds : str, optional + Comma-separated list of camera IDs to filter events. + fromTime : Any, optional + Start time (timestamp) for filtering events. + toTime : Any, optional + End time (timestamp) for filtering events. + locked : int, optional + Whether to include locked events. + evtSrcType : int, optional + Event source type. + evtSrcId : int, optional + Event source ID. + blIncludeSnapshot : bool, optional + Whether to include snapshots in the deletion. + includeAllCam : bool, optional + Whether to include all cameras. + from_end : int, optional + End index for the filter range. + from_start : int, optional + Start index for the filter range. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the delete operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -802,6 +1679,14 @@ def delete_events_by_filter(self, # TODO not working def delete_all_recordings(self) -> dict[str, object] | str: + """ + Delete all recordings from Surveillance Station. + + Returns + ------- + dict[str, object] or str + Result of the delete operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -817,6 +1702,19 @@ def delete_all_recordings(self) -> dict[str, object] | str: def apply_settings_advance_tab(self, # TODO not working rotateUnrecogCam: bool = None) -> dict[str, object] | str: + """ + Apply advanced settings in the Surveillance Station recording tab. + + Parameters + ---------- + rotateUnrecogCam : bool, optional + Whether to rotate unrecognized cameras. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the apply operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -842,6 +1740,39 @@ def count_by_number_of_event(self, blIncludeSnapshot: bool = None, # TODO not working includeAllCam: bool = None) -> dict[str, object] | str: + """ + Count the number of events by category, with optional filters. + + Parameters + ---------- + offset : bool, optional + Whether to offset the results. + limit : int, optional + The maximum number of results to return. + reason : str, optional + The reason for filtering events. + cameraIds : str, optional + Comma-separated list of camera IDs to filter events. + fromTime : int, optional + Start time (timestamp) for filtering events. + toTime : int, optional + End time (timestamp) for filtering events. + locked : int, optional + Whether to include locked events. + evtSrcType : int, optional + Event source type. + evtSrcId : int, optional + Event source ID. + blIncludeSnapshot : bool, optional + Whether to include snapshots in the count. + includeAllCam : bool, optional + Whether to include all cameras. (Currently not working). + + Returns + ------- + dict[str, object] or str + Dictionary containing the event count by category, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -857,6 +1788,14 @@ def count_by_number_of_event(self, # TODO not working def keep_event_play_alive(self) -> dict[str, object] | str: + """ + Keep the event play session alive. + + Returns + ------- + dict[str, object] or str + Result of the keepalive operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -872,6 +1811,19 @@ def keep_event_play_alive(self) -> dict[str, object] | str: def stop_recording_event(self, # TODO not working idList: Any = None) -> dict[str, object] | str: + """ + Stop a recording event for the specified event IDs. + + Parameters + ---------- + idList : Any, optional + The ID or list of IDs of the events to stop recording. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the stop operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -886,6 +1838,14 @@ def stop_recording_event(self, # TODO not working def load_settings_in_advanced_tab(self) -> dict[str, object] | str: + """ + Load settings from the advanced tab in Surveillance Station. + + Returns + ------- + dict[str, object] or str + Dictionary containing the advanced settings, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -905,8 +1865,45 @@ def lock_selected_event(self, toTime: int = None, locked: int = None, evtSrcType: int = None, + evtSrcId: int = None, + blIncludeSnapshot: bool = None, + includeAllCam: bool = None, + from_end: int = None, # TODO not working - evtSrcId: int = None) -> dict[str, object] | str: + from_start: int = None) -> dict[str, object] | str: + """ + Lock selected events by applying various filters. + + Parameters + ---------- + reason : str, optional + The reason for locking the events. + cameraIds : str, optional + Comma-separated list of camera IDs to filter events. + fromTime : int, optional + Start time (timestamp) for filtering events. + toTime : int, optional + End time (timestamp) for filtering events. + locked : int, optional + Whether to lock the events. + evtSrcType : int, optional + Event source type. + evtSrcId : int, optional + Event source ID. + blIncludeSnapshot : bool, optional + Whether to include snapshots in the lock operation. + includeAllCam : bool, optional + Whether to include all cameras. + from_end : int, optional + End index for the filter range. + from_start : int, optional + Start index for the filter range. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the lock operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -923,6 +1920,21 @@ def unlock_selected_event(self, idList: str = None, # TODO not working dsld: int = None) -> dict[str, object] | str: + """ + Unlock selected events by their IDs. + + Parameters + ---------- + idList : str, optional + Comma-separated list of event IDs to unlock. + dsld : int, optional + Device slot ID associated with the events. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -944,6 +1956,31 @@ def unlock_selected_filter_event(self, evtSrcType: int = None, # TODO not working evtSrcId: int = None) -> dict[str, object] | str: + """ + Unlock events by applying various filters. + + Parameters + ---------- + reason : str, optional + The reason for unlocking the events. + cameraIds : str, optional + Comma-separated list of camera IDs to filter events. + fromTime : int, optional + Start time (timestamp) for filtering events. + toTime : int, optional + End time (timestamp) for filtering events. + locked : int, optional + Whether to unlock only locked events. + evtSrcType : int, optional + Event source type. + evtSrcId : int, optional + Event source ID. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -959,6 +1996,21 @@ def unlock_selected_filter_event(self, def lock_selected_recordings(self, idList: str = None, dsld: int = None) -> dict[str, object] | str: + """ + Lock selected recordings by their IDs. + + Parameters + ---------- + idList : str, optional + Comma-separated list of recording IDs to lock. + dsld : int, optional + Device slot ID associated with the recordings. + + Returns + ------- + dict[str, object] or str + Result of the lock operation as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -976,6 +2028,25 @@ def download_recordings(self, mountId: int = None, offsetTimeMs: int = None, playTimeMs: int = None) -> dict[str, object] | str: + """ + Download recordings by specifying recording ID and optional parameters. + + Parameters + ---------- + id : int, optional + The ID of the recording to download. + mountId : int, optional + The mount ID associated with the recording. + offsetTimeMs : int, optional + Offset time in milliseconds for the download. + playTimeMs : int, optional + Playback time in milliseconds for the download. + + Returns + ------- + dict[str, object] or str + The downloaded recording as a binary response, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -994,6 +2065,25 @@ def check_if_recording_playable(self, mountId: int = None, # TODO not working dsld: int = None) -> dict[str, object] | str: + """ + Check if a recording is playable by event ID and optional parameters. + + Parameters + ---------- + eventId : int, optional + The event ID of the recording to check. + chkDetail : bool, optional + Whether to check detailed information. + mountId : int, optional + The mount ID associated with the recording. + dsld : int, optional + Device slot ID. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the check as a dictionary, or a string with error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -1014,6 +2104,27 @@ def play_specific_recording(self, dsld: int = None, # TODO not working videoCodec: int = None) -> dict[str, object] | str: + """ + Stream a specific recording from Surveillance Station. + + Parameters + ---------- + recordingId : int, optional + The ID of the recording to play. + alertRecording : bool, optional + Whether the recording is an alert recording. + mountId : int, optional + The mount ID associated with the recording. + dsld : int, optional + Device slot ID. + videoCodec : int, optional + Video codec to use for streaming. (Currently not working). + + Returns + ------- + dict[str, object] or str + Streaming information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -1032,17 +2143,33 @@ def download_merged_recording_files(self, toTime: int = None, # TODO not working fileName: str = None) -> dict[str, object] | str: - """Download the merged files of UTC time range recordings of target camera. - If there are different resolution or codec within UTC time range, the recordings will merge as much as possible - and downlod file will be a zip file. - - This method will start a task which have keep-alive mechanism. - Use GetRangeExportProgress method to get newest progress and keep-alive. - After receiving progress 100, use OnRangeExportDone method to download exported recording within 1 - minutes. - If you want to cancel range export task, just do not send GetRangeExportProgress method or - OnRangeExportDone method. System will cleanup processed files itself.""" - + """ + Download merged files of recordings within a UTC time range for a target camera. + + If there are different resolutions or codecs within the time range, recordings will be merged as much as possible, + and the download file will be a zip file. + + This method starts a task with a keep-alive mechanism. + Use GetRangeExportProgress to get the latest progress and keep-alive. + After receiving progress 100, use OnRangeExportDone to download the exported recording within 1 minute. + To cancel the export task, do not send GetRangeExportProgress or OnRangeExportDone; the system will clean up processed files. + + Parameters + ---------- + camId : int, optional + The camera ID to export recordings from. + fromTime : int, optional + Start UTC timestamp for the export range. + toTime : int, optional + End UTC timestamp for the export range. + fileName : str, optional + Name of the output file. (Currently not working). + + Returns + ------- + dict[str, object] or str + Task information for the export or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -1057,6 +2184,19 @@ def download_merged_recording_files(self, # TODO not working def get_newest_progress_keep_alive(self, dlid: int = None) -> dict[str, object] | str: + """ + Get the latest progress of a range export task and keep the task alive. + + Parameters + ---------- + dlid : int, optional + The download task ID. + + Returns + ------- + dict[str, object] or str + Progress information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -1074,21 +2214,36 @@ def download_recording_from_target(self, dlid: int = None, # TODO not working fileName: str = None) -> dict[str, object] | str: - """Response - MP4 or zip file data. - The response type can be found in fileExt of GetRangeExportProgress method response when progress 100. - - Note - GetRangeExportProgress method must be sent within 1 minute after corresponding RangeExport method task - is completed, otherwise the exported recordings will be cleared. - - 2.3.11.20 API Error Code - Code Description - 400 Execution failed. - 401 Parameter invalid. - 405 CMS server connection failed. - 414 Some events not exist. - 439 Too many items selected.""" + """ + Download the exported recording file from a completed range export task. + + Parameters + ---------- + dlid : int, optional + The download task ID. + fileName : str, optional + Name of the file to download. (Currently not working). + + Returns + ------- + dict[str, object] or str + Downloaded file data or error details. + + Notes + ----- + GetRangeExportProgress must be called within 1 minute after the corresponding RangeExport task is completed, + otherwise the exported recordings will be cleared. + + Response: Returns MP4 or zip file data. The response type can be found in the fileExt field of the GetRangeExportProgress + response when progress is 100. + + API Error Codes: + 400 : Execution failed. + 401 : Parameter invalid. + 405 : CMS server connection failed. + 414 : Some events do not exist. + 439 : Too many items selected. + """ api_name = 'SYNO.SurveillanceStation.Recording' info = self.gen_list[api_name] @@ -1106,6 +2261,21 @@ def download_recording_from_target(self, def handle_load_event_export(self, start: int = None, limit: bool = None) -> dict[str, object] | str: + """ + Load exported event recordings with optional pagination. + + Parameters + ---------- + start : int, optional + The starting index for loading events. + limit : bool, optional + The maximum number of events to load. + + Returns + ------- + dict[str, object] or str + Exported event information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1122,6 +2292,23 @@ def check_name_export_event(self, dsId: int = None, name: int = None, share: str = None) -> dict[str, object] | str: + """ + Check if an export event name is valid or already exists. + + Parameters + ---------- + dsId : int, optional + The data source ID. + name : int, optional + The name to check for the export event. + share : str, optional + The share name associated with the export event. + + Returns + ------- + dict[str, object] or str + Result of the name check or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1136,6 +2323,19 @@ def check_name_export_event(self, def get_camera_information_list(self, dslld: int = None) -> dict[str, object] | str: + """ + Retrieve the list of camera information for event export. + + Parameters + ---------- + dslld : int, optional + The ID of the data source (recording server) to query cameras from. + + Returns + ------- + dict[str, object] or str + Camera information list or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1153,6 +2353,25 @@ def check_destination_folder_availability(self, startTime: int = None, stopTime: int = None, camIdList: str = None) -> dict[str, object] | str: + """ + Check if the destination folder has enough available space for export. + + Parameters + ---------- + freeSize : int, optional + Required free size in bytes. + startTime : int, optional + Start time of the export range (UTC timestamp). + stopTime : int, optional + End time of the export range (UTC timestamp). + camIdList : str, optional + Comma-separated list of camera IDs to check. + + Returns + ------- + dict[str, object] or str + Availability information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1176,6 +2395,35 @@ def handle_save_event_export(self, stop_time: int = None, isoverwrite: int = None, camlistid: str = None) -> dict[str, object] | str: + """ + Save an event export task with the specified parameters. + + Parameters + ---------- + name : str, optional + Name of the export task. + srcDsId : int, optional + Source data source ID. + dstDsId : int, optional + Destination data source ID. + dstdir : str, optional + Destination directory for export. + freesize : int, optional + Required free size in bytes. + start_time : int, optional + Start time of the export range (UTC timestamp). + stop_time : int, optional + End time of the export range (UTC timestamp). + isoverwrite : int, optional + Whether to overwrite existing files (1 for true, 0 for false). + camlistid : str, optional + Comma-separated list of camera IDs to export. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1192,6 +2440,23 @@ def get_event_export_info_from_recording_server(self, start_time: int = None, stop_time: int = None, camlistid: str = None) -> dict[str, object] | str: + """ + Retrieve event export information from the recording server. + + Parameters + ---------- + start_time : int, optional + Start time of the export range (UTC timestamp). + stop_time : int, optional + End time of the export range (UTC timestamp). + camlistid : str, optional + Comma-separated list of camera IDs. + + Returns + ------- + dict[str, object] or str + Export information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Export' info = self.gen_list[api_name] api_path = info['path'] @@ -1205,6 +2470,14 @@ def get_event_export_info_from_recording_server(self, return self.request_data(api_name, api_path, req_param) def load_event_mount(self) -> dict[str, object] | str: + """ + Load event mount information for export. + + Returns + ------- + dict[str, object] or str + Mount information or error details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Mount' info = self.gen_list[api_name] api_path = info['path'] @@ -1221,12 +2494,25 @@ def redirect_webapi_to_target_ds(self, dsId: int = None, # TODO not working webAPI: Any = None) -> dict[str, object] | str: - """webAPI Array of `webAPI_info` - - Example: - `webAPI={"api": "SYNO.SurveillanceStation.AddOns", "version": 1, "method": - "List"}` """ - + """ + Redirect a WebAPI request to a target DiskStation. + + Parameters + ---------- + dsId : int, optional + Target DiskStation ID. + webAPI : Any, optional + WebAPI information to redirect (array of webAPI_info). + + Returns + ------- + dict[str, object] or str + Result of the redirect operation or error details. + + Examples + -------- + webAPI={"api": "SYNO.SurveillanceStation.AddOns", "version": 1, "method": "List"} + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1243,6 +2529,21 @@ def modify_share_privilege(self, privSet: int = None, # TODO not working shareName: str = None) -> dict[str, object] | str: + """ + Modify the share privilege settings in Surveillance Station CMS. + + Parameters + ---------- + privSet : int, optional + Privilege set value. + shareName : str, optional + Name of the share to modify. + + Returns + ------- + dict[str, object] or str + Result of the privilege modification or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1264,6 +2565,31 @@ def apply_option_settings(self, nvr_enable: bool = None, # TODO not working nvr_lang: str = None) -> dict[str, object] | str: + """ + Apply option settings for Surveillance Station CMS. + + Parameters + ---------- + central_auto_video_relay : bool, optional + Enable or disable central auto video relay. + central_enable : bool, optional + Enable or disable central management. + central_mode : str, optional + Set the central management mode. + central_rec_mask_mode : bool, optional + Enable or disable central recording mask mode. + central_rec_sync_time : bool, optional + Enable or disable central recording time synchronization. + nvr_enable : bool, optional + Enable or disable NVR. + nvr_lang : str, optional + Set the NVR language. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the apply operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1279,6 +2605,19 @@ def apply_option_settings(self, def get_cms_info(self, # TODO not working isPolling: bool = None) -> dict[str, object] | str: + """ + Retrieve CMS (Central Management System) information. + + Parameters + ---------- + isPolling : bool, optional + Whether to poll for CMS information. (Currently not working). + + Returns + ------- + dict[str, object] or str + CMS information or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1296,6 +2635,23 @@ def get_log_recording_data_from_target_ds(self, syncTargetId: int = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + Retrieve log recording data from a target DiskStation. + + Parameters + ---------- + syncType : int, optional + Type of synchronization. + syncTargetId : int, optional + ID of the target DiskStation for synchronization. + limit : int, optional + Limit the number of records returned. (Currently not working). + + Returns + ------- + dict[str, object] or str + Log recording data or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1309,6 +2665,14 @@ def get_log_recording_data_from_target_ds(self, return self.request_data(api_name, api_path, req_param) def get_samba_service(self) -> dict[str, object] | str: # TODO not working + """ + Check if the Samba service is enabled on the CMS. + + Returns + ------- + dict[str, object] or str + Samba service status or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1319,6 +2683,14 @@ def get_samba_service(self) -> dict[str, object] | str: # TODO not working # TODO not working def check_if_samba_on_and_rec_enabled(self) -> dict[str, object] | str: + """ + Check if Samba is enabled and recording is enabled on the CMS. + + Returns + ------- + dict[str, object] or str + Status of Samba and recording or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1329,6 +2701,19 @@ def check_if_samba_on_and_rec_enabled(self) -> dict[str, object] | str: def get_encoded_single_image_of_camera(self, camId: int = None) -> dict[str, object] | str: + """ + Retrieve an encoded single image (snapshot) from a specified camera. + + Parameters + ---------- + camId : int, optional + ID of the camera to get the snapshot from. + + Returns + ------- + dict[str, object] or str + Encoded image data or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1344,6 +2729,19 @@ def get_encoded_single_image_of_camera(self, def get_cms_status(self, # TODO not working camId: int = None) -> dict[str, object] | str: + """ + Retrieve the status of the CMS. + + Parameters + ---------- + camId : int, optional + ID of the camera to check status for. (Currently not working). + + Returns + ------- + dict[str, object] or str + CMS status or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1358,6 +2756,14 @@ def get_cms_status(self, # TODO not working def enable_smb_service(self) -> dict[str, object] | str: + """ + Enable the Samba service on the CMS. + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1367,6 +2773,14 @@ def enable_smb_service(self) -> dict[str, object] | str: # TODO not working def notify_slave_ds_to_disconnect(self) -> dict[str, object] | str: + """ + Notify a slave DiskStation to disconnect from the CMS. + + Returns + ------- + dict[str, object] or str + Result of the notification or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1377,6 +2791,19 @@ def notify_slave_ds_to_disconnect(self) -> dict[str, object] | str: def lock_recording_server_prevent_setting_change(self, # TODO not working locked: bool = None) -> dict[str, object] | str: + """ + Lock the recording server to prevent setting changes. + + Parameters + ---------- + locked : bool, optional + Whether to lock the server. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the lock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS' info = self.gen_list[api_name] api_path = info['path'] @@ -1394,6 +2821,25 @@ def enable_ds_into_recording_server(self, adminPasswd: str = None, central_rec_mask_mode: str = None, central_rec_sync_time: str = None) -> dict[str, object] | str: + """ + Enable a DiskStation as a recording server in the CMS. + + Parameters + ---------- + adminUsername : str, optional + Administrator username. + adminPasswd : str, optional + Administrator password. + central_rec_mask_mode : str, optional + Central recording mask mode. + central_rec_sync_time : str, optional + Central recording synchronization time. + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1411,6 +2857,25 @@ def unpair_recording_servers(self, key: str = None, mac: str = None, cmsMode: int = None) -> dict[str, object] | str: + """ + Unpair recording servers from the CMS. + + Parameters + ---------- + adminUsername : str, optional + Administrator username. + key : str, optional + Key for unpairing. + mac : str, optional + MAC address of the server. + cmsMode : int, optional + CMS mode. + + Returns + ------- + dict[str, object] or str + Result of the unpair operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1424,6 +2889,14 @@ def unpair_recording_servers(self, return self.request_data(api_name, api_path, req_param) def get_free_memory_size(self) -> dict[str, object] | str: + """ + Retrieve the free memory size from the target DiskStation. + + Returns + ------- + dict[str, object] or str + Free memory size information or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1438,6 +2911,27 @@ def handle_slave_ds(self, mac: str = None, # TODO to check masterAuthKey: str = None) -> dict[str, object] | str: + """ + Handle slave DiskStation operations such as locking or authentication. + + Parameters + ---------- + lock : bool, optional + Whether to lock the slave DiskStation. + adminUsername : str, optional + Administrator username. + key : str, optional + Authentication key. + mac : str, optional + MAC address of the slave DiskStation. + masterAuthKey : str, optional + Master authentication key. (To check). + + Returns + ------- + dict[str, object] or str + Result of the operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1452,6 +2946,19 @@ def handle_slave_ds(self, def get_target_ds_info(self, slaveDslp: str = None) -> dict[str, object] | str: + """ + Retrieve information about the target slave DiskStation. + + Parameters + ---------- + slaveDslp : str, optional + Slave DiskStation IP or identifier. + + Returns + ------- + dict[str, object] or str + Target DiskStation information or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1468,6 +2975,23 @@ def logout_slave_ds(self, adminUsername: str = None, key: str = None, mac: str = None) -> dict[str, object] | str: + """ + Log out a slave DiskStation from the CMS. + + Parameters + ---------- + adminUsername : str, optional + Administrator username. + key : str, optional + Authentication key. + mac : str, optional + MAC address of the slave DiskStation. + + Returns + ------- + dict[str, object] or str + Result of the logout operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1491,6 +3015,35 @@ def pair_slave_ds(self, cms_masked: bool = None, # TODO not working cms_sync_time: bool = None) -> dict[str, object] | str: + """ + Pair a slave DiskStation with the CMS. + + Parameters + ---------- + dsname : str, optional + Name of the slave DiskStation. + slaveDslp : str, optional + Slave DiskStation IP or identifier. + port : int, optional + Port number for connection. + masterAuthKey : str, optional + Master authentication key. + model : str, optional + Model of the slave DiskStation. + mac : str, optional + MAC address of the slave DiskStation. + cms_locked : bool, optional + Whether the CMS is locked. + cms_masked : bool, optional + Whether the CMS is masked. + cms_sync_time : bool, optional + Synchronize time with CMS. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the pairing operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1518,11 +3071,51 @@ def login_slave_ds(self, cms_masked: bool = None, # TODO not working cms_sync_time: bool = None) -> dict[str, object] | str: - """2.3.15.9 API Error Code + """ + Log in a slave DiskStation to the CMS. + + Parameters + ---------- + adminUsername : str, optional + Administrator username. + key : str, optional + Authentication key. + mac : str, optional + MAC address of the slave DiskStation. + masterAuthKey : str, optional + Master authentication key. + hostName : str, optional + Hostname of the slave DiskStation. + hostPort : int, optional + Port number for connection. + ignoreAuthError : str, optional + Ignore authentication errors. + hostDisconnect : bool, optional + Whether to disconnect the host. + blUpdateVolSpace : bool, optional + Update volume space information. + enable_rec : bool, optional + Enable recording. + cms_locked : bool, optional + Whether the CMS is locked. + cms_masked : bool, optional + Whether the CMS is masked. + cms_sync_time : bool, optional + Synchronize time with CMS. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the login operation or error details. + + Notes + ----- + 2.3.15.9 API Error Code Code Description 400 Execution failed. 401 Invalid parameter. - 415 message connect failed. """ + 415 message connect failed. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] @@ -1552,6 +3145,45 @@ def save_slave_ds(self, cms_masked: bool = None, # TODO not working cms_sync_time: bool = None) -> dict[str, object] | str: + """ + Save or update a slave DiskStation's configuration in the CMS. + + Parameters + ---------- + slavedsName : str, optional + Name of the slave DiskStation. + slavedsModel : str, optional + Model of the slave DiskStation. + slavedsPort : int, optional + Port number used by the slave DiskStation. + slavedsVersion : str, optional + Version of the slave DiskStation. + slavedsMaxCamNum : int, optional + Maximum number of cameras supported by the slave DiskStation. + slavedsId : str, optional + Identifier for the slave DiskStation. + slavedsIP : str, optional + IP address of the slave DiskStation. + slavedsEnable : int, optional + Enable status of the slave DiskStation. + slavedsCamCnt : bool, optional + Number of cameras currently connected to the slave DiskStation. + adminUsername : str, optional + Administrator username for authentication. + adminPasswd : str, optional + Administrator password for authentication. + cms_locked : bool, optional + Whether the CMS is locked. + cms_masked : bool, optional + Whether the CMS is masked. + cms_sync_time : bool, optional + Synchronize time with CMS. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.GetDsStatus' info = self.gen_list[api_name] api_path = info['path'] @@ -1570,6 +3202,27 @@ def load_slave_ds_list(self, blRuntimeInfo: bool = None, dslds: str = None, sortInfo: int = None) -> dict[str, object] | str: + """ + Load the list of slave DiskStations from the CMS. + + Parameters + ---------- + blNeedStatus : bool, optional + Whether to include status information. + blGetSortInfo : bool, optional + Whether to include sorting information. + blRuntimeInfo : bool, optional + Whether to include runtime information. + dslds : str, optional + Comma-separated list of DiskStation IDs to load. + sortInfo : int, optional + Sorting information. + + Returns + ------- + dict[str, object] or str + List of slave DiskStations or error details. + """ api_name = 'SYNO.SurveillanceStation.CMS.SlavedsList' info = self.gen_list[api_name] api_path = info['path'] @@ -1597,6 +3250,45 @@ def count_number_of_logs(self, dsId: str = None, srcType: int = None, timezoneOffset: int = None) -> dict[str, object] | str: + """ + Count the number of logs in Surveillance Station based on various filters. + + Parameters + ---------- + slavedsName : str, optional + Name of the slave DiskStation. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of logs to count. + level : str, optional + Log level filter. + filterCamera : str, optional + Filter by camera. + cameraIds : str, optional + Comma-separated list of camera IDs. + dsfrom : int, optional + Start time (timestamp). + to : int, optional + End time (timestamp). + keyword : str, optional + Keyword to search in logs. + keywordDsId : str, optional + DiskStation ID for keyword search. + time2String : str, optional + Time string for filtering. + dsId : str, optional + DiskStation ID. + srcType : int, optional + Source type filter. + timezoneOffset : int, optional + Timezone offset. + + Returns + ------- + dict[str, object] or str + Count of logs or error details. + """ api_name = 'SYNO.SurveillanceStation.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -1606,10 +3298,7 @@ def count_number_of_logs(self, for key, val in locals().items(): if key not in ['self', 'api_name', 'info', 'api_path', 'req_param']: if val is not None: - if key == 'dsfrom': - req_param[str('from')] = val - else: - req_param[str(key)] = val + req_param[str(key)] = val return self.request_data(api_name, api_path, req_param) @@ -1625,6 +3314,39 @@ def clear_selected_logs(self, keywordDsId: str = None, srcType: int = None, timezoneOffset: int = None) -> dict[str, object] | str: + """ + Clear selected logs from Surveillance Station based on various filters. + + Parameters + ---------- + blClearAll : bool, optional + Whether to clear all logs. + level : int, optional + Log level filter. + dsId : int, optional + DiskStation ID. + filterCamera : str, optional + Filter by camera. + cameraIds : str, optional + Comma-separated list of camera IDs. + dsfrom : int, optional + Start time (timestamp). + to : int, optional + End time (timestamp). + keyword : str, optional + Keyword to search in logs. + keywordDsId : str, optional + DiskStation ID for keyword search. + srcType : int, optional + Source type filter. + timezoneOffset : int, optional + Timezone offset. + + Returns + ------- + dict[str, object] or str + Result of the clear operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -1656,6 +3378,47 @@ def get_information_log(self, all: bool = None, blIncludeRecCnt: str = None, blIncludeAuInfo: str = None) -> dict[str, object] | str: + """ + Retrieve information logs from Surveillance Station based on various filters. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of logs to retrieve. + level : str, optional + Log level filter. + filterCamera : str, optional + Filter by camera. + cameraIds : str, optional + Comma-separated list of camera IDs. + dsfrom : int, optional + Start time (timestamp). + to : int, optional + End time (timestamp). + keyword : str, optional + Keyword to search in logs. + keywordDsId : str, optional + DiskStation ID for keyword search. + time2String : str, optional + Time string for filtering. + dsId : int, optional + DiskStation ID. + srcType : int, optional + Source type filter. + all : bool, optional + Whether to retrieve all logs. + blIncludeRecCnt : str, optional + Include recording count information. + blIncludeAuInfo : str, optional + Include additional information. + + Returns + ------- + dict[str, object] or str + List of information logs or error details. + """ api_name = 'SYNO.SurveillanceStation.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -1672,6 +3435,14 @@ def get_information_log(self, return self.request_data(api_name, api_path, req_param) def get_advanced_settings_logs(self) -> dict[str, object] | str: + """ + Retrieve advanced log settings from Surveillance Station. + + Returns + ------- + dict[str, object] or str + Advanced log settings or error details. + """ api_name = 'SYNO.SurveillanceStation.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -1681,6 +3452,21 @@ def get_advanced_settings_logs(self) -> dict[str, object] | str: def set_advanced_setting_logs(self, data: Any = None) -> dict[str, object] | str: + """ + Set advanced log settings in Surveillance Station. + + Parameters + ---------- + data : Any, optional + List of log type settings to apply. + Example: + data=\\[\\{"SSLogType":321912835,"enable":1\\},\\{"SSLogType":321912836,"enable":0\\}\\] + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -1696,6 +3482,19 @@ def set_advanced_setting_logs(self, def load_license_data(self, # TODO not working num_only: int = None) -> dict[str, object] | str: + """ + Load license data from Surveillance Station. + + Parameters + ---------- + num_only : int, optional + If set, only the number of licenses will be returned. + + Returns + ------- + dict[str, object] or str + License data or error details. + """ api_name = 'SYNO.SurveillanceStation.License' info = self.gen_list[api_name] api_path = info['path'] @@ -1708,6 +3507,23 @@ def check_license_quota(self, camList: Any = None, # TODO not working camServerId: int = None) -> dict[str, object] | str: + """ + Check the license quota for cameras in Surveillance Station. + + Parameters + ---------- + camList : Any, optional + List of camera information dictionaries. + Example: + camList = \\[\\{"ip": "10.13.22.141", "model": "DCS-3110", "vendor": "DLink", "port": 80\\}\\] + camServerId : int, optional + Camera server ID. + + Returns + ------- + dict[str, object] or str + License quota information or error details. + """ api_name = 'SYNO.SurveillanceStation.License' info = self.gen_list[api_name] api_path = info['path'] @@ -1728,6 +3544,23 @@ def get_http_video_stream(self, writeHeader: bool = None, analyevent: bool = None, mountId: int = None) -> dict[str, object] | str: + """ + Retrieve an HTTP video event stream from Surveillance Station. + + Parameters + ---------- + writeHeader : bool, optional + Whether to include headers in the stream. + analyevent : bool, optional + Whether to analyze events in the stream. + mountId : int, optional + Mount ID for the stream. + + Returns + ------- + dict[str, object] or str + Video stream data or error details. + """ api_name = 'SYNO.SurveillanceStation.Stream' info = self.gen_list[api_name] api_path = info['path'] @@ -1767,6 +3600,67 @@ def save_action_rule(self, userName: str = None, # TODO not working password: str = None) -> dict[str, object] | str: + """ + Save or update an action rule in Surveillance Station. + + Parameters + ---------- + id : int, optional + Action rule ID. + name : str, optional + Name of the action rule. + ruleType : int, optional + Type of the rule. + actType : int, optional + Action type. + evtSrc : int, optional + Event source. + evtDsId : int, optional + Event DiskStation ID. + evtDevId : int, optional + Event device ID. + evtId : int, optional + Event ID. + evtItem : int, optional + Event item. + evtMinIntvl : int, optional + Minimum interval between events. + Actions : Any, optional + List of actions to perform. + actSchedule : str, optional + Action schedule. + Id : int, optional + Alternative action rule ID. + actSrc : int, optional + Action source. + actDsId : int, optional + Action DiskStation ID. + actDevId : int, optional + Action device ID. + actId : int, optional + Action ID. + actTimes : int, optional + Number of times to perform the action. + actTimeUnit : int, optional + Time unit for the action. + actTimeDur : int, optional + Duration for the action. + actItemId : int, optional + Action item ID. + actRetPos : int, optional + Action return position. + extUrl : str, optional + External URL for the action. + userName : str, optional + Username for authentication. + password : str, optional + Password for authentication. (Currently not working). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1781,6 +3675,14 @@ def save_action_rule(self, # TODO not working def download_action_rule(self) -> dict[str, object] | str: + """ + Download the history of action rules from Surveillance Station. + + Returns + ------- + dict[str, object] or str + Downloaded action rule history or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1791,6 +3693,14 @@ def download_action_rule(self) -> dict[str, object] | str: # TODO not working def send_data_2_player(self) -> dict[str, object] | str: + """ + Send data to the Surveillance Station player. + + Returns + ------- + dict[str, object] or str + Result of the send operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1801,6 +3711,19 @@ def send_data_2_player(self) -> dict[str, object] | str: # TODO not working def delete_all_histories_of_action_rule(self, idList: str = None) -> dict[str, object] | str: + """ + Delete all histories of specified action rules. + + Parameters + ---------- + idList : str, optional + Comma-separated list of action rule IDs to delete histories for. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1810,6 +3733,21 @@ def delete_all_histories_of_action_rule(self, idList: str = None) -> dict[str, o return self.request_data(api_name, api_path, req_param) def list_action_rules(self, start: str = None, limit: int = None) -> dict[str, object] | str: + """ + List action rules in Surveillance Station. + + Parameters + ---------- + start : str, optional + Start index for pagination. + limit : int, optional + Maximum number of action rules to return. + + Returns + ------- + dict[str, object] or str + List of action rules or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1820,6 +3758,19 @@ def list_action_rules(self, start: str = None, limit: int = None) -> dict[str, o # TODO not working def disable_action_rules(self, idList: str = None) -> dict[str, object] | str: + """ + Disable specified action rules in Surveillance Station. + + Parameters + ---------- + idList : str, optional + Comma-separated list of action rule IDs to disable. + + Returns + ------- + dict[str, object] or str + Result of the disable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1830,6 +3781,19 @@ def disable_action_rules(self, idList: str = None) -> dict[str, object] | str: # TODO not working def enable_action_rules(self, idList: str = None) -> dict[str, object] | str: + """ + Enable specified action rules in Surveillance Station. + + Parameters + ---------- + idList : str, optional + Comma-separated list of action rule IDs to enable. + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1840,6 +3804,21 @@ def enable_action_rules(self, idList: str = None) -> dict[str, object] | str: # TODO not working def list_history_action_rules(self, start: int = None, limit: int = None) -> dict[str, object] | str: + """ + List the history of action rules in Surveillance Station. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of history records to return. + + Returns + ------- + dict[str, object] or str + List of action rule histories or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1850,6 +3829,19 @@ def list_history_action_rules(self, start: int = None, limit: int = None) -> dic # TODO not working def delete_action_rule(self, idList: str = None) -> dict[str, object] | str: + """ + Delete specified action rules from Surveillance Station. + + Parameters + ---------- + idList : str, optional + Comma-separated list of action rule IDs to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ActionRule' info = self.gen_list[api_name] api_path = info['path'] @@ -1863,6 +3855,25 @@ def get_list_of_emaps(self, limit: str = None, emapIds: int = None, includeItems: int = None) -> dict[str, object] | str: + """ + Retrieve a list of eMaps from Surveillance Station. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : str, optional + Maximum number of eMaps to return. + emapIds : int, optional + Specific eMap IDs to retrieve. + includeItems : int, optional + Whether to include items in the eMap. + + Returns + ------- + dict[str, object] or str + List of eMaps or error details. + """ api_name = 'SYNO.SurveillanceStation.Emap' info = self.gen_list[api_name] api_path = info['path'] @@ -1879,6 +3890,21 @@ def get_specific_emaps_setting(self, emapIds: int = None, # TODO to check includeImage: int = None) -> dict[str, object] | str: + """ + Retrieve specific eMap settings from Surveillance Station. + + Parameters + ---------- + emapIds : int, optional + The ID(s) of the eMap(s) to retrieve settings for. + includeImage : int, optional + Whether to include the eMap image in the response. + + Returns + ------- + dict[str, object] or str + The eMap settings or error details. + """ api_name = 'SYNO.SurveillanceStation.Emap' info = self.gen_list[api_name] api_path = info['path'] @@ -1894,6 +3920,19 @@ def get_specific_emaps_setting(self, def get_emap_image(self, # TODO to check filename: str = None) -> dict[str, object] | str: + """ + Retrieve an eMap image from Surveillance Station. + + Parameters + ---------- + filename : str, optional + The filename of the eMap image to retrieve. + + Returns + ------- + dict[str, object] or str + The eMap image data or error details. + """ api_name = 'SYNO.SurveillanceStation.Emap.Image' info = self.gen_list[api_name] api_path = info['path'] @@ -1908,6 +3947,14 @@ def get_emap_image(self, # TODO to check def get_autorized_ds_token(self) -> dict[str, object] | str: + """ + Retrieve an authorized DiskStation token for notifications. + + Returns + ------- + dict[str, object] or str + The authorized token or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1921,6 +3968,23 @@ def set_message_event(self, subject: str = None, # TODO not working content: str = None) -> dict[str, object] | str: + """ + Set a customized message event in Surveillance Station. + + Parameters + ---------- + eventTypes : str, optional + The type(s) of event(s) to set the message for. + subject : str, optional + The subject of the message. + content : str, optional + The content of the message. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1937,6 +4001,19 @@ def set_message_event(self, def get_message_event(self, # TODO not working eventTypes: int = None) -> dict[str, object] | str: + """ + Retrieve a customized message event from Surveillance Station. + + Parameters + ---------- + eventTypes : int, optional + The type(s) of event(s) to retrieve the message for. + + Returns + ------- + dict[str, object] or str + The message event data or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1953,6 +4030,19 @@ def get_message_event(self, def set_notification_sender_name(self, # TODO not working ss_pkg_name: str = None) -> dict[str, object] | str: + """ + Set the sender name for Surveillance Station notifications. + + Parameters + ---------- + ss_pkg_name : str, optional + The sender name to set. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1967,6 +4057,14 @@ def set_notification_sender_name(self, # TODO not working def get_notification_sender_name(self) -> dict[str, object] | str: + """ + Retrieve the sender name for Surveillance Station notifications. + + Returns + ------- + dict[str, object] or str + The sender name or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1978,6 +4076,21 @@ def set_advanced_notification_setting(self, blSyncDSMNotify: bool = None, # TODO to check blCompactMsg: bool = None) -> dict[str, object] | str: + """ + Set advanced notification settings in Surveillance Station. + + Parameters + ---------- + blSyncDSMNotify : bool, optional + Whether to synchronize DSM notifications. + blCompactMsg : bool, optional + Whether to enable compact message format. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -1992,6 +4105,14 @@ def set_advanced_notification_setting(self, # TODO not working def get_advanced_notification_setting(self) -> dict[str, object] | str: + """ + Retrieve advanced notification settings from Surveillance Station. + + Returns + ------- + dict[str, object] or str + The advanced notification settings or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification' info = self.gen_list[api_name] api_path = info['path'] @@ -2016,6 +4137,47 @@ def send_test_mesg_to_primary_secondary_phone(self, hasSysSms: bool = None, # TODO to check apiId: str = None) -> dict[str, object] | str: + """ + Send a test message to the primary and secondary phone numbers via SMS. + + Parameters + ---------- + smsEnable : bool, optional + Whether SMS notifications are enabled. + smsMethod : int, optional + The SMS sending method. + smsProvider : str, optional + The SMS provider name. + userName : str, optional + Username for SMS provider authentication. + password : str, optional + Password for SMS provider authentication. + confirmPassword : str, optional + Confirmation of the password. + primaryPhoneCode : str, optional + Country code for the primary phone. + primaryPhonePrefix : str, optional + Prefix for the primary phone. + secondaryPhoneCode : str, optional + Country code for the secondary phone. + secondaryPhonePrefix : str, optional + Prefix for the secondary phone. + secondaryPhoneNumber : str, optional + The secondary phone number. + setMinMessageInterval : bool, optional + Whether to set a minimum message interval. + minMessageInterval : int, optional + The minimum interval between messages. + hasSysSms : bool, optional + Whether system SMS is enabled. + apiId : str, optional + The API ID for the SMS provider. + + Returns + ------- + dict[str, object] or str + Result of the test message operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS' info = self.gen_list[api_name] api_path = info['path'] @@ -2030,6 +4192,14 @@ def send_test_mesg_to_primary_secondary_phone(self, return self.request_data(api_name, api_path, req_param) def get_setting_notification_sms(self) -> dict[str, object] | str: + """ + Retrieve the SMS notification settings from Surveillance Station. + + Returns + ------- + dict[str, object] or str + The SMS notification settings or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS' info = self.gen_list[api_name] api_path = info['path'] @@ -2053,6 +4223,47 @@ def set_sms_service_setting(self, minMessageInterval: int = None, hasSysSms: bool = None, apiId: str = None) -> dict[str, object] | str: + """ + Set the SMS service settings for Surveillance Station notifications. + + Parameters + ---------- + smsEnable : bool, optional + Whether SMS notifications are enabled. + smsMethod : int, optional + The SMS sending method. + smsProvider : str, optional + The SMS provider name. + userName : str, optional + Username for SMS provider authentication. + password : str, optional + Password for SMS provider authentication. + confirmPassword : str, optional + Confirmation of the password. + primaryPhoneCode : str, optional + Country code for the primary phone. + primaryPhonePrefix : str, optional + Prefix for the primary phone. + secondaryPhoneCode : str, optional + Country code for the secondary phone. + secondaryPhonePrefix : str, optional + Prefix for the secondary phone. + secondaryPhoneNumber : str, optional + The secondary phone number. + setMinMessageInterval : bool, optional + Whether to set a minimum message interval. + minMessageInterval : int, optional + The minimum interval between messages. + hasSysSms : bool, optional + Whether system SMS is enabled. + apiId : str, optional + The API ID for the SMS provider. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS' info = self.gen_list[api_name] api_path = info['path'] @@ -2075,6 +4286,33 @@ def send_test_sms(self, synoMailEnable: bool = None, # TODO to check mail_recipient: str = None) -> dict[str, object] | str: + """ + Send a test SMS notification from Surveillance Station. + + Parameters + ---------- + attachSnapshot : bool, optional + Whether to attach a snapshot to the SMS. + enableInterval : bool, optional + Whether to enable message interval. + mobileEnable : bool, optional + Whether to enable mobile notifications. + msgInterval : str, optional + The interval between messages. + primaryEmail : str, optional + The primary email address for notifications. + secondaryEmail : str, optional + The secondary email address for notifications. + synoMailEnable : bool, optional + Whether to enable Synology Mail notifications. + mail_recipient : str, optional + The recipient of the test mail. + + Returns + ------- + dict[str, object] or str + Result of the test SMS operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS' info = self.gen_list[api_name] api_path = info['path'] @@ -2098,6 +4336,33 @@ def send_test_mail(self, synoMailEnable: bool = None, # TODO to check mail_recipient: str = None) -> dict[str, object] | str: + """ + Send a test verification mail for Surveillance Station notifications. + + Parameters + ---------- + attachSnapshot : bool, optional + Whether to attach a snapshot to the email. + enableInterval : bool, optional + Whether to enable message interval. + mobileEnable : bool, optional + Whether to enable mobile notifications. + msgInterval : str, optional + The interval between messages. + primaryEmail : str, optional + The primary email address for notifications. + secondaryEmail : str, optional + The secondary email address for notifications. + synoMailEnable : bool, optional + Whether to enable Synology Mail notifications. + mail_recipient : str, optional + The recipient of the test mail. + + Returns + ------- + dict[str, object] or str + Result of the test mail operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.PushService' info = self.gen_list[api_name] api_path = info['path'] @@ -2120,6 +4385,33 @@ def list_mobile_paired_devices(self, secondaryEmail: str = None, synoMailEnable: bool = None, mail_recipient: str = None) -> dict[str, object] | str: + """ + List mobile devices paired with Surveillance Station for push notifications. + + Parameters + ---------- + attachSnapshot : bool, optional + Whether to attach a snapshot to the notification. + enableInterval : bool, optional + Whether to enable message interval. + mobileEnable : bool, optional + Whether to enable mobile notifications. + msgInterval : str, optional + The interval between messages. + primaryEmail : str, optional + The primary email address for notifications. + secondaryEmail : str, optional + The secondary email address for notifications. + synoMailEnable : bool, optional + Whether to enable Synology Mail notifications. + mail_recipient : str, optional + The recipient of the notification. + + Returns + ------- + dict[str, object] or str + List of paired mobile devices or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.PushService' info = self.gen_list[api_name] api_path = info['path'] @@ -2135,6 +4427,19 @@ def list_mobile_paired_devices(self, def unpair_device(self, targetIds: str = None) -> dict[str, object] | str: + """ + Unpair a mobile device from Surveillance Station notifications. + + Parameters + ---------- + targetIds : str, optional + The ID(s) of the device(s) to unpair. + + Returns + ------- + dict[str, object] or str + Result of the unpair operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.PushService' info = self.gen_list[api_name] api_path = info['path'] @@ -2150,6 +4455,19 @@ def unpair_device(self, def get_controller_access_schedule(self, # TODO to check targetIds: str = None) -> dict[str, object] | str: + """ + Retrieve the access control controller schedule from Surveillance Station. + + Parameters + ---------- + targetIds : str, optional + The ID(s) of the controllers to retrieve the schedule for. + + Returns + ------- + dict[str, object] or str + The controller access schedule or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2167,6 +4485,21 @@ def get_camera_alarm_schedule(self, cameraId: int = None, # TODO to check alarmdx: int = None) -> dict[str, object] | str: + """ + Retrieve the alarm schedule for a specific camera. + + Parameters + ---------- + cameraId : int, optional + The ID of the camera. + alarmdx : int, optional + Additional alarm parameter (to check). + + Returns + ------- + dict[str, object] or str + The camera alarm schedule or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2183,6 +4516,19 @@ def get_camera_alarm_schedule(self, def get_sys_dependent_schedule(self, # TODO to check eventGroupTypes: int = None) -> dict[str, object] | str: + """ + Retrieve the system dependent schedule for Surveillance Station events. + + Parameters + ---------- + eventGroupTypes : int, optional + The type(s) of event groups to retrieve the schedule for. + + Returns + ------- + dict[str, object] or str + The system dependent schedule or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2203,6 +4549,27 @@ def set_batch_schedule(self, cameraGroupIds: str = None, # TODO to check filter: int = None) -> dict[str, object] | str: + """ + Set batch schedules for events, cameras, or camera groups. + + Parameters + ---------- + eventTypes : str, optional + The type(s) of events to schedule. + schedule : Any, optional + The schedule data to apply. + cameraIds : str, optional + The IDs of cameras to apply the schedule to. + cameraGroupIds : str, optional + The IDs of camera groups to apply the schedule to. + filter : int, optional + Additional filter parameter (to check). + + Returns + ------- + dict[str, object] or str + Result of the batch schedule operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2219,6 +4586,19 @@ def set_batch_schedule(self, def get_access_ctrl_door_schedule(self, # TODO to check doorId: str = None) -> dict[str, object] | str: + """ + Retrieve the access control door schedule from Surveillance Station. + + Parameters + ---------- + doorId : str, optional + The ID of the door to retrieve the schedule for. + + Returns + ------- + dict[str, object] or str + The door schedule or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2235,6 +4615,19 @@ def get_access_ctrl_door_schedule(self, def get_camera_schedule(self, # TODO to check cameraId: str = None) -> dict[str, object] | str: + """ + Retrieve the schedule for a specific camera. + + Parameters + ---------- + cameraId : str, optional + The ID of the camera to retrieve the schedule for. + + Returns + ------- + dict[str, object] or str + The camera schedule or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2252,6 +4645,21 @@ def set_sys_dependent_schedule(self, eventType: int = None, # TODO to check schedule: Any = None) -> dict[str, object] | str: + """ + Set the system dependent schedule for Surveillance Station events. + + Parameters + ---------- + eventType : int, optional + The type of event to set the schedule for. + schedule : Any, optional + The schedule data to apply. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2270,6 +4678,23 @@ def set_controller_access_schedule(self, schedule: Any = None, # TODO to check doorId: int = None) -> dict[str, object] | str: + """ + Set the access control schedule for a controller or door. + + Parameters + ---------- + eventType : int, optional + The type of event to set the schedule for. + schedule : Any, optional + The schedule data to apply. + doorId : int, optional + The ID of the door to set the schedule for. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2288,6 +4713,23 @@ def set_camera_schedule(self, schedule: Any = None, # TODO to check cameraId: Any = None) -> dict[str, object] | str: + """ + Set the schedule for a specific camera in Surveillance Station. + + Parameters + ---------- + eventType : int, optional + The type of event to set the schedule for. + schedule : Any, optional + The schedule data to apply. + cameraId : Any, optional + The ID of the camera to set the schedule for. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Schedule' info = self.gen_list[api_name] api_path = info['path'] @@ -2302,6 +4744,14 @@ def set_camera_schedule(self, return self.request_data(api_name, api_path, req_param) def get_notification_email_string(self) -> dict[str, object] | str: + """ + Retrieve the notification email settings string from Surveillance Station. + + Returns + ------- + dict[str, object] or str + The notification email settings or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Email' info = self.gen_list[api_name] api_path = info['path'] @@ -2312,6 +4762,19 @@ def get_notification_email_string(self) -> dict[str, object] | str: def set_adv_tab_info_filter(self, # TODO to check X: int = None) -> dict[str, object] | str: + """ + Set the advanced tab information filter for notification emails. + + Parameters + ---------- + X : int, optional + The filter value to set (to check). + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.Email' info = self.gen_list[api_name] api_path = info['path'] @@ -2331,6 +4794,29 @@ def create_sms_service_provider(self, providerTemplate: str = None, providerSepChar: str = None, providerNeedSSL: bool = None) -> dict[str, object] | str: + """ + Create a new SMS service provider for Surveillance Station notifications. + + Parameters + ---------- + providerName : str, optional + The name of the SMS provider. + providerPort : int, optional + The port used by the provider. + providerUrl : str, optional + The URL of the provider. + providerTemplate : str, optional + The message template for the provider. + providerSepChar : str, optional + The separator character used by the provider. + providerNeedSSL : bool, optional + Whether SSL is required for the provider. + + Returns + ------- + dict[str, object] or str + Result of the create operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS.ServiceProvider' info = self.gen_list[api_name] api_path = info['path'] @@ -2344,6 +4830,14 @@ def create_sms_service_provider(self, return self.request_data(api_name, api_path, req_param) def list_sms_provider(self) -> dict[str, object] | str: + """ + List all SMS service providers configured in Surveillance Station. + + Returns + ------- + dict[str, object] or str + List of SMS providers or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS.ServiceProvider' info = self.gen_list[api_name] api_path = info['path'] @@ -2354,6 +4848,19 @@ def list_sms_provider(self) -> dict[str, object] | str: def delete_sms_service_provider(self, # TODO to check providerName: str = None) -> dict[str, object] | str: + """ + Delete an SMS service provider from Surveillance Station. + + Parameters + ---------- + providerName : str, optional + The name of the SMS provider to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Notification.SMS.ServiceProvider' info = self.gen_list[api_name] api_path = info['path'] @@ -2367,6 +4874,14 @@ def delete_sms_service_provider(self, return self.request_data(api_name, api_path, req_param) def get_addson_to_update(self) -> dict[str, object] | str: + """ + Retrieve information about add-ons that require updates in Surveillance Station. + + Returns + ------- + dict[str, object] or str + Add-on update information or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2378,6 +4893,21 @@ def enable_specific_addon(self, service: int = None, # TODO to check servicename: str = None) -> dict[str, object] | str: + """ + Enable a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to enable. + servicename : str, optional + The name of the add-on service to enable. + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2393,6 +4923,19 @@ def enable_specific_addon(self, def get_specific_addon_update_info(self, # TODO to check service: int = None) -> dict[str, object] | str: + """ + Retrieve update information for a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to check for updates. + + Returns + ------- + dict[str, object] or str + Update information or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2409,6 +4952,19 @@ def get_specific_addon_update_info(self, def get_specific_addon_info(self, # TODO to check service: int = None) -> dict[str, object] | str: + """ + Retrieve information for a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to retrieve information for. + + Returns + ------- + dict[str, object] or str + Add-on information or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2422,6 +4978,14 @@ def get_specific_addon_info(self, return self.request_data(api_name, api_path, req_param) def get_total_addon_info(self) -> dict[str, object] | str: # TODO to check + """ + Retrieve information about all add-ons in Surveillance Station. + + Returns + ------- + dict[str, object] or str + List of all add-ons or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2433,6 +4997,21 @@ def update_addon_package(self, service: int = None, # TODO to check filePath: str = None) -> dict[str, object] | str: + """ + Update an add-on package in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to update. + filePath : str, optional + The file path to the add-on package (to check). + + Returns + ------- + dict[str, object] or str + Result of the update operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2448,6 +5027,19 @@ def update_addon_package(self, def check_addon_status(self, # TODO to check service: int = None) -> dict[str, object] | str: + """ + Check the enable status of a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to check (to check). + + Returns + ------- + dict[str, object] or str + Status information or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2465,6 +5057,21 @@ def disable_addon(self, service: int = None, # TODO to check serviceName: str = None) -> dict[str, object] | str: + """ + Disable a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to disable. + serviceName : str, optional + The name of the add-on service to disable (to check). + + Returns + ------- + dict[str, object] or str + Result of the disable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2481,6 +5088,21 @@ def set_addon_autoupdate(self, service: int = None, # TODO to check BlEnabled: Any = None) -> dict[str, object] | str: + """ + Set the auto-update setting for a specific add-on in Surveillance Station. + + Parameters + ---------- + service : int, optional + The ID of the add-on service to configure. + BlEnabled : Any, optional + Whether auto-update is enabled (to check). + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AddOns' info = self.gen_list[api_name] api_path = info['path'] @@ -2496,6 +5118,19 @@ def set_addon_autoupdate(self, def delete_specific_camera_recording_server(self, # TODO to check camIdList: str = None) -> dict[str, object] | str: + """ + Delete a specific camera recording server in Surveillance Station. + + Parameters + ---------- + camIdList : str, optional + List of camera IDs to delete from the recording server (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2511,6 +5146,19 @@ def delete_specific_camera_recording_server(self, def get_camera_event_analytic(self, # TODO to check camIdList: str = None) -> dict[str, object] | str: + """ + Retrieve camera event analytics from Surveillance Station. + + Parameters + ---------- + camIdList : str, optional + List of camera IDs to retrieve analytics for (to check). + + Returns + ------- + dict[str, object] or str + Analytics data or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2527,6 +5175,21 @@ def delete_selected_events(self, dsIdList: str = None, # TODO to check idList: str = None) -> dict[str, object] | str: + """ + Delete selected events from Surveillance Station. + + Parameters + ---------- + dsIdList : str, optional + List of DS IDs for which to delete events. + idList : str, optional + List of event IDs to delete (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2542,6 +5205,19 @@ def delete_selected_events(self, def delete_specific_camera_events(self, # TODO to check camIdList: str = None) -> dict[str, object] | str: + """ + Delete events for specific cameras in Surveillance Station. + + Parameters + ---------- + camIdList : str, optional + List of camera IDs for which to delete events (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2558,6 +5234,21 @@ def get_analytic_history(self, camIdList: str = None, # TODO to check typeListstring: str = None) -> dict[str, object] | str: + """ + Retrieve analytic history for cameras in Surveillance Station. + + Parameters + ---------- + camIdList : str, optional + List of camera IDs to retrieve history for. + typeListstring : str, optional + List of analytic types as a string (to check). + + Returns + ------- + dict[str, object] or str + Analytic history data or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2576,6 +5267,25 @@ def get_analytic_history_by_filter(self, lock: int = None, # TODO to check typeList: str = None) -> dict[str, object] | str: + """ + Retrieve analytic history for cameras by filter in Surveillance Station. + + Parameters + ---------- + camIdList : str, optional + List of camera IDs to filter. + dsId : int, optional + The DS ID to filter. + lock : int, optional + Lock status to filter. + typeList : str, optional + List of analytic types as a string (to check). + + Returns + ------- + dict[str, object] or str + Filtered analytic history data or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2592,6 +5302,21 @@ def unklock_selected_events(self, dsId: int = None, # TODO to check idList: str = None) -> dict[str, object] | str: + """ + Unlock selected events in Surveillance Station. + + Parameters + ---------- + dsId : int, optional + The DS ID for which to unlock events. + idList : str, optional + List of event IDs to unlock (to check). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2607,6 +5332,19 @@ def unklock_selected_events(self, def set_camera_analytic_trigger(self, # TODO to check trigCamIdList: str = None) -> dict[str, object] | str: + """ + Trigger camera analytics for specified cameras in Surveillance Station. + + Parameters + ---------- + trigCamIdList : str, optional + List of camera IDs to trigger analytics for (to check). + + Returns + ------- + dict[str, object] or str + Result of the trigger operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2622,6 +5360,19 @@ def set_camera_analytic_trigger(self, def flush_event_header(self, # TODO to check eventId: str = None) -> dict[str, object] | str: + """ + Flush the header of a specific event in Surveillance Station. + + Parameters + ---------- + eventId : str, optional + The ID of the event to flush the header for (to check). + + Returns + ------- + dict[str, object] or str + Result of the flush operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2639,6 +5390,21 @@ def lock_selected_events(self, dsId: int = None, # TODO to check idList: str = None) -> dict[str, object] | str: + """ + Lock selected events in Surveillance Station. + + Parameters + ---------- + dsId : int, optional + The DS ID for which to lock events. + idList : str, optional + List of event IDs to lock (to check). + + Returns + ------- + dict[str, object] or str + Result of the lock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2655,6 +5421,21 @@ def get_analytic_event_from_rec_server(self, camIdList: str = None, # TODO to check idList: int = None) -> dict[str, object] | str: + """ + Retrieve analytic event counts from the recording server for specified cameras. + + Parameters + ---------- + camIdList : str, optional + Comma-separated list of camera IDs to query. + idList : int, optional + Additional ID list parameter (to check). + + Returns + ------- + dict[str, object] or str + Analytic event count data or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert' info = self.gen_list[api_name] api_path = info['path'] @@ -2681,6 +5462,39 @@ def save_analytic_settings(self, objSize: int = None, # TODO to check region: str = None) -> dict[str, object] | str: + """ + Save analytic settings for a specific camera. + + Parameters + ---------- + camId : int, optional + Camera ID to apply settings to. + type : int, optional + Type of analytic. + showFrame : bool, optional + Whether to display the frame. + showLine : bool, optional + Whether to display lines. + showVirtualFence : bool, optional + Whether to display virtual fences. + beep : bool, optional + Whether to enable beep on event. + sens : int, optional + Sensitivity setting. + dwellTime : int, optional + Dwell time setting. + direction : int, optional + Direction setting. + objSize : int, optional + Object size setting. + region : str, optional + Region definition (to check). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Alert.Setting' info = self.gen_list[api_name] api_path = info['path'] @@ -2696,6 +5510,19 @@ def save_analytic_settings(self, def check_if_snapshot_exist(self, # TODO to check id: int = None) -> dict[str, object] | str: + """ + Check if a snapshot exists for a given ID. + + Parameters + ---------- + id : int, optional + Snapshot ID to check (to check). + + Returns + ------- + dict[str, object] or str + Existence status or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2716,6 +5543,29 @@ def save_snapshot_modification(self, byteSize: int = None, # TODO to check imageData: str = None) -> dict[str, object] | str: + """ + Save modifications to a snapshot. + + Parameters + ---------- + id : int, optional + Snapshot ID to modify. + createCopy : bool, optional + Whether to create a copy of the snapshot. + width : int, optional + Width of the snapshot. + height : int, optional + Height of the snapshot. + byteSize : int, optional + Size of the snapshot in bytes. + imageData : str, optional + Image data (to check). + + Returns + ------- + dict[str, object] or str + Result of the modification or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2736,6 +5586,29 @@ def count_snapshot_by_category(self, byteSize: int = None, # TODO to check imageData: str = None) -> dict[str, object] | str: + """ + Count snapshots by category within a specified range. + + Parameters + ---------- + keyword : str, optional + Keyword to filter snapshots. + dsfrom : int, optional + Start timestamp. + to : int, optional + End timestamp. + timezoneOffset : int, optional + Timezone offset. + byteSize : int, optional + Size of the snapshot in bytes. + imageData : str, optional + Image data (to check). + + Returns + ------- + dict[str, object] or str + Count data or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2758,6 +5631,25 @@ def check_any_locked_snapshot(self, to: int = None, # TODO to check keyword: str = None) -> dict[str, object] | str: + """ + Check if any locked snapshots exist within a specified range. + + Parameters + ---------- + id : str, optional + Snapshot ID(s) to check. + dsfrom : int, optional + Start timestamp. + to : int, optional + End timestamp. + keyword : str, optional + Keyword to filter snapshots (to check). + + Returns + ------- + dict[str, object] or str + Lock status or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2779,6 +5671,23 @@ def unlock_snapshot_by_filter(self, to: int = None, # TODO to check keyword: str = None) -> dict[str, object] | str: + """ + Unlock snapshots by filter within a specified range. + + Parameters + ---------- + dsfrom : int, optional + Start timestamp. + to : int, optional + End timestamp. + keyword : str, optional + Keyword to filter snapshots (to check). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2806,6 +5715,37 @@ def list_snapshot_information(self, blIncludeRecCnt: bool = None, # TODO to check camId: int = None) -> dict[str, object] | str: + """ + List snapshot information with optional filters. + + Parameters + ---------- + idList : str, optional + Comma-separated list of snapshot IDs. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + dsfrom : int, optional + Start timestamp. + to : int, optional + End timestamp. + keyword : str, optional + Keyword to filter snapshots. + imgSize : int, optional + Image size filter. + blIncludeAuInfo : bool, optional + Whether to include additional info. + blIncludeRecCnt : bool, optional + Whether to include recording count. + camId : int, optional + Camera ID filter (to check). + + Returns + ------- + dict[str, object] or str + List of snapshot information or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2824,6 +5764,19 @@ def list_snapshot_information(self, def unlock_snapshot(self, # TODO to check objList: Any = None) -> dict[str, object] | str: + """ + Unlock specific snapshots. + + Parameters + ---------- + objList : Any, optional + List of snapshot objects to unlock (to check). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2841,6 +5794,23 @@ def take_snapshot(self, camId: int = None, # TODO to check blSave: bool = None) -> dict[str, object] | str: + """ + Take a snapshot for a specific camera and DS. + + Parameters + ---------- + dsId : int, optional + DS ID for the snapshot. + camId : int, optional + Camera ID for the snapshot. + blSave : bool, optional + Whether to save the snapshot (to check). + + Returns + ------- + dict[str, object] or str + Result of the snapshot operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2855,6 +5825,14 @@ def take_snapshot(self, # TODO to check def get_snapshot_setting_function(self) -> dict[str, object] | str: + """ + Retrieve the snapshot setting function. + + Returns + ------- + dict[str, object] or str + Snapshot setting information or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2868,6 +5846,25 @@ def delete_snapshot_by_filter(self, to: int = None, # TODO to check keyword: str = None) -> dict[str, object] | str: + """ + Delete snapshots by filter within a specified range. + + Parameters + ---------- + deleteAllCommand : bool, optional + Whether to delete all snapshots. + dsfrom : int, optional + Start timestamp. + to : int, optional + End timestamp. + keyword : str, optional + Keyword to filter snapshots (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2887,6 +5884,21 @@ def get_snapshot_image(self, id: int = None, # TODO to modify for download? imgSize: int = None) -> dict[str, object] | str: + """ + Retrieve a snapshot image by ID. + + Parameters + ---------- + id : int, optional + Snapshot ID to retrieve. + imgSize : int, optional + Image size (to modify for download?). + + Returns + ------- + dict[str, object] or str + Snapshot image data or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2901,6 +5913,19 @@ def get_snapshot_image(self, def lock_snapshot_image(self, objList: Any = None) -> dict[str, object] | str: + """ + Lock specific snapshot images. + + Parameters + ---------- + objList : Any, optional + List of snapshot objects to lock. + + Returns + ------- + dict[str, object] or str + Result of the lock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2913,9 +5938,23 @@ def lock_snapshot_image(self, return self.request_data(api_name, api_path, req_param) + # TODO: fix typo def downld_single_snapshot(self, # TODO not working id: int = None) -> dict[str, object] | str: + """ + Download a single snapshot by ID. + + Parameters + ---------- + id : int, optional + Snapshot ID to download (not working). + + Returns + ------- + dict[str, object] or str + Download result or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2935,6 +5974,29 @@ def save_new_snapshot_setting(self, limitSizeInGb: int = None, addTimestamp: bool = None, timestampPosition: int = None) -> dict[str, object] | str: + """ + Save new snapshot settings. + + Parameters + ---------- + dispSnapshot : bool, optional + Whether to display snapshots. + dispDuration : int, optional + Display duration for snapshots. + limitTotalSize : bool, optional + Whether to limit total snapshot size. + limitSizeInGb : int, optional + Limit size in GB. + addTimestamp : bool, optional + Whether to add a timestamp to snapshots. + timestampPosition : int, optional + Position of the timestamp. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2955,6 +6017,29 @@ def save_snapshot(self, byteSize: int = None, # TODO to check imageData: str = None) -> dict[str, object] | str: + """ + Save a new snapshot. + + Parameters + ---------- + camName : str, optional + Name of the camera. + createdTm : int, optional + Creation timestamp. + width : int, optional + Width of the snapshot. + height : int, optional + Height of the snapshot. + byteSize : int, optional + Size of the snapshot in bytes. + imageData : str, optional + Image data (to check). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2969,6 +6054,19 @@ def save_snapshot(self, def check_snapshot_status(self, dispSnapshot: bool = None) -> dict[str, object] | str: + """ + Check the status of snapshot display. + + Parameters + ---------- + dispSnapshot : bool, optional + Whether to display snapshots. + + Returns + ------- + dict[str, object] or str + Status information or error details. + """ api_name = 'SYNO.SurveillanceStation.SnapShot' info = self.gen_list[api_name] api_path = info['path'] @@ -2985,6 +6083,19 @@ def check_snapshot_status(self, def enable_visualstation(self, # TODO to check vslist: str = None) -> dict[str, object] | str: + """ + Enable VisualStation devices. + + Parameters + ---------- + vslist : str, optional + Comma-separated list of VisualStation IDs to enable (to check). + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3005,6 +6116,29 @@ def update_vs_network_config(self, blDhcp: bool = None, # TODO to check name: str = None) -> dict[str, object] | str: + """ + Update the network configuration for a VisualStation device. + + Parameters + ---------- + vsMAc : str, optional + MAC address of the VisualStation. + ip : str, optional + IP address to assign. + mask : str, optional + Subnet mask. + gateway : str, optional + Gateway address. + blDhcp : bool, optional + Whether to use DHCP. + name : str, optional + Name of the VisualStation (to check). + + Returns + ------- + dict[str, object] or str + Result of the update operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3020,6 +6154,19 @@ def update_vs_network_config(self, def lock_visualstation_by_id(self, # TODO to check vslist: str = None) -> dict[str, object] | str: + """ + Lock VisualStation devices by ID. + + Parameters + ---------- + vslist : str, optional + Comma-separated list of VisualStation IDs to lock (to check). + + Returns + ------- + dict[str, object] or str + Result of the lock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3034,6 +6181,14 @@ def lock_visualstation_by_id(self, # TODO to check def enumerate_vs_owner_info(self) -> dict[str, object] | str: + """ + Enumerate VisualStation owner information. + + Returns + ------- + dict[str, object] or str + Owner information or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3044,6 +6199,19 @@ def enumerate_vs_owner_info(self) -> dict[str, object] | str: def unlock_visualstation_by_id(self, # TODO to check vslist: str = None) -> dict[str, object] | str: + """ + Unlock VisualStation devices by ID. + + Parameters + ---------- + vslist : str, optional + Comma-separated list of VisualStation IDs to unlock (to check). + + Returns + ------- + dict[str, object] or str + Result of the unlock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3059,6 +6227,19 @@ def unlock_visualstation_by_id(self, def disable_visualstation_by_id(self, # TODO to check vslist: str = None) -> dict[str, object] | str: + """ + Disable VisualStation devices by ID. + + Parameters + ---------- + vslist : str, optional + Comma-separated list of VisualStation IDs to disable (to check). + + Returns + ------- + dict[str, object] or str + Result of the disable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3074,6 +6255,19 @@ def disable_visualstation_by_id(self, def delete_specific_visualstation(self, # TODO to check vslist: str = None) -> dict[str, object] | str: + """ + Delete specific VisualStation devices by ID. + + Parameters + ---------- + vslist : str, optional + Comma-separated list of VisualStation IDs to delete (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation' info = self.gen_list[api_name] api_path = info['path'] @@ -3089,6 +6283,19 @@ def delete_specific_visualstation(self, def enumerate_layout_visualstation(self, # TODO to check vsId: int = None) -> dict[str, object] | str: + """ + Enumerate VisualStation layouts. + + Parameters + ---------- + vsId : int, optional + VisualStation ID to filter layouts (to check). + + Returns + ------- + dict[str, object] or str + Layout information or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Layout' info = self.gen_list[api_name] api_path = info['path'] @@ -3112,6 +6319,35 @@ def save_layout_information(self, channelList: Any = None, # TODO to check customPosList: str = None) -> dict[str, object] | str: + """ + Save layout information for a VisualStation. + + Parameters + ---------- + id : int, optional + Layout ID. + vsId : int, optional + VisualStation ID. + name : str, optional + Name of the layout. + canGrpId : int, optional + Camera group ID. + isDefault : int, optional + Whether this is the default layout. + isFixAspectRatio : int, optional + Whether to fix the aspect ratio. + layoutType : int, optional + Type of the layout. + channelList : Any, optional + List of channels in the layout. + customPosList : str, optional + Custom position list (to check). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Layout' info = self.gen_list[api_name] api_path = info['path'] @@ -3128,6 +6364,21 @@ def delete_layout_visualstation(self, id: int = None, # TODO to check vsId: int = None) -> dict[str, object] | str: + """ + Delete a VisualStation layout. + + Parameters + ---------- + id : int, optional + Layout ID to delete. + vsId : int, optional + VisualStation ID (to check). + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Layout' info = self.gen_list[api_name] api_path = info['path'] @@ -3142,6 +6393,14 @@ def delete_layout_visualstation(self, # TODO to check def clear_visualstation_search_result(self) -> dict[str, object] | str: + """ + Clear VisualStation search results. + + Returns + ------- + dict[str, object] or str + Result of the clear operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -3152,6 +6411,19 @@ def clear_visualstation_search_result(self) -> dict[str, object] | str: def get_visualstation_ip_info(self, # TODO to check ip: int = None) -> dict[str, object] | str: + """ + Retrieve VisualStation IP information. + + Parameters + ---------- + ip : int, optional + IP address to search for (to check). + + Returns + ------- + dict[str, object] or str + IP information or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -3166,6 +6438,14 @@ def get_visualstation_ip_info(self, # TODO to check def stop_previous_visualstation_search(self) -> dict[str, object] | str: + """ + Stop the previous VisualStation search operation. + + Returns + ------- + dict[str, object] or str + Result of the stop operation or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -3176,6 +6456,19 @@ def stop_previous_visualstation_search(self) -> dict[str, object] | str: def get_visualstation_list(self, # TODO to check offset: int = None) -> dict[str, object] | str: + """ + Retrieve the list of VisualStation devices. + + Parameters + ---------- + offset : int, optional + Offset for pagination (to check). + + Returns + ------- + dict[str, object] or str + List of VisualStation devices or error details. + """ api_name = 'SYNO.SurveillanceStation.VisualStation.Layout' info = self.gen_list[api_name] api_path = info['path'] @@ -3189,6 +6482,14 @@ def get_visualstation_list(self, return self.request_data(api_name, api_path, req_param) def get_number_of_controller(self) -> dict[str, object] | str: + """ + Get the number of controllers in the system. + + Returns + ------- + dict[str, object] or str + Number of controllers or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3197,6 +6498,19 @@ def get_number_of_controller(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_cardholder_count(self, filterKeyword: str = None) -> dict[str, object] | str: + """ + Get the count of cardholders, optionally filtered by keyword. + + Parameters + ---------- + filterKeyword : str, optional + Keyword to filter cardholders. + + Returns + ------- + dict[str, object] or str + Cardholder count or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3211,6 +6525,14 @@ def get_cardholder_count(self, filterKeyword: str = None) -> dict[str, object] | return self.request_data(api_name, api_path, req_param) def enum_all_controllers_logger(self) -> dict[str, object] | str: + """ + Enumerate all controller logger configurations. + + Returns + ------- + dict[str, object] or str + Logger configuration information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3222,6 +6544,21 @@ def get_cardholder_photo(self, photo_name: str = None, # TODO to check isRedirectCgi: bool = None) -> dict[str, object] | str: + """ + Retrieve a cardholder's photo. + + Parameters + ---------- + photo_name : str, optional + Name of the photo file. + isRedirectCgi : bool, optional + Whether to redirect to CGI for the photo (to check). + + Returns + ------- + dict[str, object] or str + Photo data or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3249,6 +6586,43 @@ def get_log_count(self, doorIds: str = None, eventTypes: str = None, update: int = None) -> dict[str, object] | str: + """ + Get the count of logs with optional filters. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + filterType : int, optional + Type of filter to apply. + filterEventSource : Any, optional + Event source filter. + filterSource : int, optional + Source filter. + filterEventSourceItem : int, optional + Event source item filter. + filterTimeFrom : int, optional + Start time for filtering. + filterTimeTo : int, optional + End time for filtering. + filterKeyword : str, optional + Keyword to filter logs. + timezoneOffset : int, optional + Timezone offset. + doorIds : str, optional + Door IDs filter. + eventTypes : str, optional + Event types filter. + update : int, optional + Update flag. + + Returns + ------- + dict[str, object] or str + Log count or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3268,6 +6642,27 @@ def get_cardholder_info(self, filterKeyword: str = None, filterStatus: int = None, filterCtrlerId: int = None) -> dict[str, object] | str: + """ + Retrieve cardholder information with optional filters. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + filterKeyword : str, optional + Keyword to filter cardholders. + filterStatus : int, optional + Status filter. + filterCtrlerId : int, optional + Controller ID filter. + + Returns + ------- + dict[str, object] or str + Cardholder information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3284,6 +6679,21 @@ def retrieve_last_access_credential(self, ctrlerId: int = None, # TODO to check idPtId: int = None) -> dict[str, object] | str: + """ + Retrieve the last access credential for a controller. + + Parameters + ---------- + ctrlerId : int, optional + Controller ID. + idPtId : int, optional + ID/point ID (to check). + + Returns + ------- + dict[str, object] or str + Last access credential information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3300,6 +6710,21 @@ def retrieve_last_access_credential(self, def enable_disable_controller(self, blEnable: bool = None, arrayJson: str = None) -> dict[str, object] | str: + """ + Enable or disable controllers. + + Parameters + ---------- + blEnable : bool, optional + Whether to enable (True) or disable (False) controllers. + arrayJson : str, optional + JSON array of controller IDs. + + Returns + ------- + dict[str, object] or str + Result of the operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3323,6 +6748,37 @@ def acknowledge_all_alarm_level_log(self, doorIds: str = None, eventTypes: str = None, update: int = None) -> dict[str, object] | str: + """ + Acknowledge all alarm level logs with optional filters. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + filterEventSource : Any, optional + Event source filter. + filterSource : int, optional + Source filter. + filterEventSourceItem : str, optional + Event source item filter. + filterTimeFrom : int, optional + Start time for filtering. + filterKeyword : str, optional + Keyword to filter logs. + doorIds : str, optional + Door IDs filter. + eventTypes : str, optional + Event types filter. + update : int, optional + Update flag. + + Returns + ------- + dict[str, object] or str + Result of the acknowledge operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3338,6 +6794,28 @@ def acknowledge_all_alarm_level_log(self, def modify_controller_logger_config(self, # TODO to check data: Any = None) -> dict[str, object] | str: + """ + Modify the logger configuration for a controller. + + Parameters + ---------- + data : Any, optional + Logger configuration data (see example in docstring). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + + Notes + ----- + Example data: + data = { + "log_evt": "11111111111111111111111111111111111111", + "id": 97, + "log_alarm": "00111111111111111111111111111111111111" + } + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3357,6 +6835,23 @@ def modify_controller_logger_config(self, def save_controller_settings(self, arrayJson: str = None) -> dict[str, object] | str: + """ + Save controller settings for Surveillance Station. + + Parameters + ---------- + arrayJson : str, optional + JSON string representing controller settings. Example: + \\[\\{"enable": true, "id": 97, "name": "ctrler1", "host": "10.13.12.173", "port": 80, + "model": "A1001", "username": "root", "password": "Q__Q-__-", "time_server": + "SurveillanceStation", "time_zone": "Fiji", "door": \\[\\{"id": 231, "name": "FrontDoor", + "enable_cam": true, "cam_ds_id": 0, "cam_id": 13\\}\\]\\}\\] + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3364,10 +6859,10 @@ def save_controller_settings(self, """arrayJson example: - arrayJson="[{\"enable\":true,\"id\":97,\"name\":\"ctrler1\",\"host\":\"10.13.12.173\",\"port\":80, + arrayJson="\\[\\{\"enable\":true,\"id\":97,\"name\":\"ctrler1\",\"host\":\"10.13.12.173\",\"port\":80, \"model\":\"A1001\",\"username\":\"root\",\"password\":\"Q__Q-__-\",\"time_server\": - \"SurveillanceStation\",\"time_zone\":\"Fiji\",\"door\":[{\"id\":231,\"name\":\"FrontDoor\", - \"enable_cam\":true,\"cam_ds_id\":0,\"cam_id\":13}]}]\" """ + \"SurveillanceStation\",\"time_zone\":\"Fiji\",\"door\":\\[\\{\"id\":231,\"name\":\"FrontDoor\", + \"enable_cam\":true,\"cam_ds_id\":0,\"cam_id\":13\\}\\]\\}\\]\" """ for key, val in locals().items(): if key not in ['self', 'api_name', 'info', 'api_path', 'req_param']: @@ -3390,6 +6885,41 @@ def download_filtered_logs(self, eventTypes: str = None, # TODO to modify for download? update: int = None) -> dict[str, object] | str: + """ + Download filtered logs from Surveillance Station. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + filterType : int, optional + Type of filter to apply. + filterEventSource : int, optional + Event source filter. + filterSource : int, optional + Source filter. + filterEventSourceItem : str, optional + Event source item filter. + filterTimeFrom : int, optional + Start time for filtering. + filterTimeTo : int, optional + End time for filtering. + filterKeyword : str, optional + Keyword to filter logs. + doorIds : str, optional + Door IDs filter. + eventTypes : str, optional + Event types filter. + update : int, optional + Update flag. + + Returns + ------- + dict[str, object] or str + Downloaded log data or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3409,6 +6939,27 @@ def get_door_name_from_controller(self, userName: str = None, # TODO to check password: int = None) -> dict[str, object] | str: + """ + Retrieve door names from a specific controller. + + Parameters + ---------- + ctrlerId : int, optional + Controller ID. + ip : str, optional + Controller IP address. + port : int, optional + Controller port. + userName : str, optional + Username for authentication. + password : int, optional + Password for authentication (to check). + + Returns + ------- + dict[str, object] or str + Door names or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3428,6 +6979,27 @@ def test_connection_and_authentication(self, userName: str = None, # TODO to check password: int = None) -> dict[str, object] | str: + """ + Test connection and authentication to a controller. + + Parameters + ---------- + ctrlerId : int, optional + Controller ID. + ip : str, optional + Controller IP address. + port : int, optional + Controller port. + userName : str, optional + Username for authentication. + password : int, optional + Password for authentication (to check). + + Returns + ------- + dict[str, object] or str + Result of the test or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3447,6 +7019,27 @@ def enumerate_controller_list_info(self, blIncludeRecCnt: bool = None, # TODO to check blIncludeAuInfo: bool = None) -> dict[str, object] | str: + """ + Enumerate controller list information. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + update : int, optional + Update flag. + blIncludeRecCnt : bool, optional + Whether to include record count. + blIncludeAuInfo : bool, optional + Whether to include additional info (to check). + + Returns + ------- + dict[str, object] or str + Controller list information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3461,6 +7054,19 @@ def enumerate_controller_list_info(self, def save_cardholder_setting(self, arrayJson: str = None) -> dict[str, object] | str: + """ + Save cardholder settings. + + Parameters + ---------- + arrayJson : str, optional + JSON string representing cardholder settings. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3475,6 +7081,19 @@ def save_cardholder_setting(self, def enumerate_door_info(self, DoorIds: str = None) -> dict[str, object] | str: + """ + Enumerate door information. + + Parameters + ---------- + DoorIds : str, optional + Comma-separated list of door IDs. + + Returns + ------- + dict[str, object] or str + Door information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3498,6 +7117,37 @@ def clear_logs_surveillance_station(self, doorIds: str = None, eventTypes: str = None, update: int = None) -> dict[str, object] | str: + """ + Clear logs in Surveillance Station with optional filters. + + Parameters + ---------- + filterType : int, optional + Type of filter to apply. + filterEventSource : Any, optional + Event source filter. + filterSource : int, optional + Source filter. + filterEventSourceItem : str, optional + Event source item filter. + filterTimeFrom : int, optional + Start time for filtering. + filterTimeTo : int, optional + End time for filtering. + filterKeyword : str, optional + Keyword to filter logs. + doorIds : str, optional + Door IDs filter. + eventTypes : str, optional + Event types filter. + update : int, optional + Update flag. + + Returns + ------- + dict[str, object] or str + Result of the clear operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3511,6 +7161,14 @@ def clear_logs_surveillance_station(self, return self.request_data(api_name, api_path, req_param) def list_all_user_privilege(self) -> dict[str, object] | str: + """ + List all user privileges in Surveillance Station. + + Returns + ------- + dict[str, object] or str + List of user privileges or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3527,6 +7185,21 @@ def manual_lock_operation(self, doorId: int = None, # TODO to check operation: int = None) -> dict[str, object] | str: + """ + Perform a manual lock or unlock operation on a door. + + Parameters + ---------- + doorId : int, optional + Door ID to operate on. + operation : int, optional + Operation code (to check). + + Returns + ------- + dict[str, object] or str + Result of the operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3541,6 +7214,19 @@ def manual_lock_operation(self, def save_user_door_priv_setting(self, arrayJson: str = None) -> dict[str, object] | str: + """ + Save user door privilege settings. + + Parameters + ---------- + arrayJson : str, optional + JSON string representing user door privilege settings. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3569,6 +7255,47 @@ def list_all_logs(self, update: int = None, blIncludeRecCnt: bool = None, blIncludeAuInfo: bool = None) -> dict[str, object] | str: + """ + List all logs in Surveillance Station with optional filters. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + filterType : int, optional + Type of filter to apply. + filterEventSource : Any, optional + Event source filter. + filterSource : int, optional + Source filter. + filterEventSourceItem : str, optional + Event source item filter. + filterTimeFrom : int, optional + Start time for filtering. + filterTimeTo : int, optional + End time for filtering. + filterKeyword : str, optional + Keyword to filter logs. + timezoneOffset : int, optional + Timezone offset. + doorIds : str, optional + Door IDs filter. + eventTypes : str, optional + Event types filter. + update : int, optional + Update flag. + blIncludeRecCnt : bool, optional + Whether to include record count. + blIncludeAuInfo : bool, optional + Whether to include additional info. + + Returns + ------- + dict[str, object] or str + List of logs or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3582,6 +7309,19 @@ def list_all_logs(self, return self.request_data(api_name, api_path, req_param) def delete_selected_controller(self, ids: str = None) -> dict[str, object] | str: + """ + Delete selected controllers from Surveillance Station. + + Parameters + ---------- + ids : str, optional + Comma-separated string of controller IDs to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3596,6 +7336,19 @@ def delete_selected_controller(self, ids: str = None) -> dict[str, object] | str # TODO to check def retrieve_data_from_controller(self, ctrlerId: str = None) -> dict[str, object] | str: + """ + Retrieve data from a specific controller. + + Parameters + ---------- + ctrlerId : str, optional + ID of the controller to retrieve data from. + + Returns + ------- + dict[str, object] or str + Retrieved data or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3609,6 +7362,19 @@ def retrieve_data_from_controller(self, ctrlerId: str = None) -> dict[str, objec return self.request_data(api_name, api_path, req_param) def block_cardholder(self, arrayJson: str = None) -> dict[str, object] | str: + """ + Block cardholders in Surveillance Station. + + Parameters + ---------- + arrayJson : str, optional + JSON string representing cardholder(s) to block. + + Returns + ------- + dict[str, object] or str + Result of the block operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3623,6 +7389,14 @@ def block_cardholder(self, arrayJson: str = None) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_controller_count(self) -> dict[str, object] | str: + """ + Get the count of controllers by category. + + Returns + ------- + dict[str, object] or str + Controller count or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler' info = self.gen_list[api_name] api_path = info['path'] @@ -3632,6 +7406,14 @@ def get_controller_count(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def start_controller_search(self) -> dict[str, object] | str: + """ + Start searching for controllers. + + Returns + ------- + dict[str, object] or str + Result of the search operation or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -3639,13 +7421,28 @@ def start_controller_search(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) - def get_controller_search_result(self, - pid: int = None, - offset: int = None) -> dict[str, object] | str: + def get_controller_search_info(self, + pid: int = None, + offset: int = None) -> dict[str, object] | str: + """ + Get information about the current controller search. + + Parameters + ---------- + pid : int, optional + Process ID of the search. + offset : int, optional + Offset for paginated results. + + Returns + ------- + dict[str, object] or str + Search information or error details. + """ api_name = 'SYNO.SurveillanceStation.AxisAcsCtrler.Search' info = self.gen_list[api_name] api_path = info['path'] - req_param = {'version': info['maxVersion'], 'method': 'InfoGet'} + req_param = {'version': info['maxVersion'], 'method': 'GetInfo'} for key, val in locals().items(): if key not in ['self', 'api_name', 'info', 'api_path', 'req_param']: @@ -3657,6 +7454,19 @@ def get_controller_search_result(self, def enumerate_digital_output(self, # TODO to check camId: int = None) -> dict[str, object] | str: + """ + Enumerate digital output devices. + + Parameters + ---------- + camId : int, optional + Camera ID to filter digital outputs. + + Returns + ------- + dict[str, object] or str + List of digital outputs or error details. + """ api_name = 'SYNO.SurveillanceStation.DigitalOutput' info = self.gen_list[api_name] api_path = info['path'] @@ -3676,6 +7486,27 @@ def save_digital_output_parameters(self, normal_state: int = None, # TODO to check trigger_state: bool = None) -> dict[str, object] | str: + """ + Save parameters for a digital output device. + + Parameters + ---------- + camId : int, optional + Camera ID. + idx : int, optional + Index of the digital output. + keep_setting : bool, optional + Whether to keep the current setting. + normal_state : int, optional + Normal state value. + trigger_state : bool, optional + Trigger state value. + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.DigitalOutput' info = self.gen_list[api_name] api_path = info['path'] @@ -3697,6 +7528,31 @@ def long_polling_digital_output_status(self, trigger: bool = None, # TODO to check timeOut: int = None) -> dict[str, object] | str: + """ + Perform long polling to get the status of a digital output. + + Parameters + ---------- + camId : int, optional + Camera ID. + idx : int, optional + Index of the digital output. + keep : bool, optional + Whether to keep polling. + setNormalCap : bool, optional + Set normal capability. + normal : int, optional + Normal state value. + trigger : bool, optional + Trigger state value. + timeOut : int, optional + Timeout for polling. + + Returns + ------- + dict[str, object] or str + Status information or error details. + """ api_name = 'SYNO.SurveillanceStation.DigitalOutput' info = self.gen_list[api_name] api_path = info['path'] @@ -3713,6 +7569,21 @@ def trigger_external_event(self, eventId: int = None, # TODO to check eventName: str = None) -> dict[str, object] | str: + """ + Trigger an external event in Surveillance Station. + + Parameters + ---------- + eventId : int, optional + ID of the event to trigger. + eventName : str, optional + Name of the event to trigger. + + Returns + ------- + dict[str, object] or str + Result of the trigger operation or error details. + """ api_name = 'SYNO.SurveillanceStation.ExternalEvent' info = self.gen_list[api_name] api_path = info['path'] @@ -3731,6 +7602,25 @@ def get_list_io_modules(self, blFromList: bool = None, # TODO to check ownerDsId: int = None) -> dict[str, object] | str: + """ + Get a list of I/O modules. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + blFromList : bool, optional + Whether to get from list. + ownerDsId : int, optional + Owner device station ID. + + Returns + ------- + dict[str, object] or str + List of I/O modules or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3752,6 +7642,31 @@ def get_io_port_list(self, Vendor: str = None, # TODO to check Model: str = None) -> dict[str, object] | str: + """ + Get a list of I/O ports for a module. + + Parameters + ---------- + Id : int, optional + Module ID. + Port : int, optional + Port number. + IP : str, optional + IP address. + User : str, optional + Username. + Pass : str, optional + Password. + Vendor : str, optional + Vendor name. + Model : str, optional + Model name. + + Returns + ------- + dict[str, object] or str + List of I/O ports or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3766,6 +7681,14 @@ def get_io_port_list(self, # TODO to check def get_supported_list_io_modules(self) -> dict[str, object] | str: + """ + Get a list of supported I/O module vendor models. + + Returns + ------- + dict[str, object] or str + List of supported vendor models or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3790,6 +7713,45 @@ def save_setting_io_module(self, ntpEnable: bool = None, # TODO to check DIOdata: Any = None) -> dict[str, object] | str: + """ + Save or update the settings for an I/O module in Surveillance Station. + + Parameters + ---------- + name : str, optional + Name of the I/O module. + id : int, optional + ID of the I/O module. + ownerDsId : int, optional + Owner device station ID. + vendor : str, optional + Vendor name of the I/O module. + model : str, optional + Model name of the I/O module. + ip : str, optional + IP address of the I/O module. + port : int, optional + Port number for the I/O module. + userName : str, optional + Username for authentication. + enabled : bool, optional + Whether the I/O module is enabled. + status : int, optional + Status code of the I/O module. + timeServer : str, optional + Time server address. + passWord : str, optional + Password for authentication. + ntpEnable : bool, optional + Whether NTP is enabled. + DIOdata : Any, optional + Digital I/O data (structure to be checked). + + Returns + ------- + dict[str, object] or str + Result of the save operation or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3805,6 +7767,19 @@ def save_setting_io_module(self, def enable_io_modules(self, # TODO to check iomlist: str = None) -> dict[str, object] | str: + """ + Enable specified I/O modules. + + Parameters + ---------- + iomlist : str, optional + Comma-separated list of I/O module IDs to enable. + + Returns + ------- + dict[str, object] or str + Result of the enable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3820,6 +7795,19 @@ def enable_io_modules(self, def disable_io_modules(self, # TODO to check iomlist: str = None) -> dict[str, object] | str: + """ + Disable specified I/O modules. + + Parameters + ---------- + iomlist : str, optional + Comma-separated list of I/O module IDs to disable. + + Returns + ------- + dict[str, object] or str + Result of the disable operation or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3835,6 +7823,19 @@ def disable_io_modules(self, def delete_io_modules(self, # TODO to check iomlist: str = None) -> dict[str, object] | str: + """ + Delete specified I/O modules. + + Parameters + ---------- + iomlist : str, optional + Comma-separated list of I/O module IDs to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3855,6 +7856,29 @@ def test_connection_to_io_module(self, passWord: str = None, # TODO to check model: str = None) -> dict[str, object] | str: + """ + Test the connection to a specified I/O module. + + Parameters + ---------- + id : int, optional + ID of the I/O module. + port : str, optional + Port number for the I/O module. + ip : str, optional + IP address of the I/O module. + userName : str, optional + Username for authentication. + passWord : str, optional + Password for authentication. + model : str, optional + Model name of the I/O module. + + Returns + ------- + dict[str, object] or str + Result of the connection test or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3871,6 +7895,21 @@ def get_capability_io_module(self, vendor: str = None, # TODO to check model: str = None) -> dict[str, object] | str: + """ + Get the capability information for a specified I/O module. + + Parameters + ---------- + vendor : str, optional + Vendor name of the I/O module. + model : str, optional + Model name of the I/O module. + + Returns + ------- + dict[str, object] or str + Capability information or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3887,6 +7926,21 @@ def configure_io_port_setting(self, id: int = None, # TODO to check DIOdata: Any = None) -> dict[str, object] | str: + """ + Configure the port settings for a specified I/O module. + + Parameters + ---------- + id : int, optional + ID of the I/O module. + DIOdata : Any, optional + Digital I/O data for port configuration (structure to be checked). + + Returns + ------- + dict[str, object] or str + Result of the configuration or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3904,6 +7958,23 @@ def poll_trigger_state_io_module(self, list: Any = None, # TODO to check timeOut: int = None) -> dict[str, object] | str: + """ + Poll the trigger state of digital input (DI) ports for a specified I/O module. + + Parameters + ---------- + Id : int, optional + ID of the I/O module. + list : Any, optional + List of DI ports to poll (structure to be checked). + timeOut : int, optional + Timeout for polling operation. + + Returns + ------- + dict[str, object] or str + Polling result or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3923,6 +7994,27 @@ def poll_do_trigger_module(self, trigger: bool = None, # TODO to check timeOut: int = None) -> dict[str, object] | str: + """ + Poll the trigger state of digital output (DO) ports for a specified I/O module. + + Parameters + ---------- + id : int, optional + ID of the I/O module. + idx : int, optional + Index of the DO port. + normal : int, optional + Normal state value. + trigger : bool, optional + Trigger state. + timeOut : int, optional + Timeout for polling operation. + + Returns + ------- + dict[str, object] or str + Polling result or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3937,6 +8029,14 @@ def poll_do_trigger_module(self, # TODO to check def get_number_of_devices(self) -> dict[str, object] | str: + """ + Get the number of I/O devices for each device station. + + Returns + ------- + dict[str, object] or str + Number of devices or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3955,6 +8055,25 @@ def get_category_count_io_module(self, ownerDsId: int = None, # TODO to check blFromList: bool = None) -> dict[str, object] | str: + """ + Get the count of I/O modules by category. + + Parameters + ---------- + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + ownerDsId : int, optional + Owner device station ID. + blFromList : bool, optional + Whether to get count from a list (to be checked). + + Returns + ------- + dict[str, object] or str + Count by category or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule' info = self.gen_list[api_name] api_path = info['path'] @@ -3969,20 +8088,36 @@ def get_category_count_io_module(self, return self.request_data(api_name, api_path, req_param) def start_search_io_module(self) -> dict[str, object] | str: + """ + Start searching for I/O modules. + + Returns + ------- + dict[str, object] or str + Result of the search operation or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule.Search' info = self.gen_list[api_name] api_path = info['path'] req_param = {'version': info['maxVersion'], 'method': 'Start'} - for key, val in locals().items(): - if key not in ['self', 'api_name', 'info', 'api_path', 'req_param']: - if val is not None: - req_param[str(key)] = val - return self.request_data(api_name, api_path, req_param) def get_search_io_module_info(self, pid: int = None) -> dict[str, object] | str: + """ + Get information about the current I/O module search. + + Parameters + ---------- + pid : int, optional + Process ID of the search. + + Returns + ------- + dict[str, object] or str + Search information or error details. + """ api_name = 'SYNO.SurveillanceStation.IOModule.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -3998,6 +8133,19 @@ def get_search_io_module_info(self, def get_current_camera_status(self, # TODO not working id_list: str = None) -> dict[str, object] | str: + """ + Get the current status of specified cameras. + + Parameters + ---------- + id_list : str, optional + Comma-separated list of camera IDs. + + Returns + ------- + dict[str, object] or str + Camera status information or error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Status' info = self.gen_list[api_name] api_path = info['path'] @@ -4013,6 +8161,19 @@ def get_current_camera_status(self, def enum_preset_camera_list(self, # TODO not working cameraId: Any = None) -> dict[str, object] | str: + """ + Enumerate the list of presets for a specified camera. + + Parameters + ---------- + cameraId : Any, optional + ID of the camera. + + Returns + ------- + dict[str, object] or str + List of camera presets or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4028,6 +8189,19 @@ def enum_preset_camera_list(self, def get_preset_camera_capability(self, # TODO not working cameraId: int = None) -> dict[str, object] | str: + """ + Get the capability information for camera presets. + + Parameters + ---------- + cameraId : int, optional + ID of the camera. + + Returns + ------- + dict[str, object] or str + Preset capability information or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4046,6 +8220,25 @@ def record_current_camera_position(self, speed: int = None, # TODO not working name: str = None) -> dict[str, object] | str: + """ + Record the current position of a camera as a preset. + + Parameters + ---------- + cameraId : int, optional + ID of the camera. + position : int, optional + Preset position index. + speed : int, optional + Speed for moving to the preset. + name : str, optional + Name for the preset. + + Returns + ------- + dict[str, object] or str + Result of the record operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4062,6 +8255,21 @@ def delete_list_preset_camera(self, cameraId: Any = None, # TODO not working position: str = None) -> dict[str, object] | str: + """ + Delete specified presets from a camera. + + Parameters + ---------- + cameraId : Any, optional + ID of the camera. + position : str, optional + Preset position(s) to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4080,6 +8288,25 @@ def go_specific_preset_by_given_speed(self, speed: int = None, # TODO not working type: int = None) -> dict[str, object] | str: + """ + Move a camera to a specific preset position at a given speed. + + Parameters + ---------- + cameraId : Any, optional + ID of the camera. + position : int, optional + Preset position index. + speed : int, optional + Speed for moving to the preset. + type : int, optional + Type of preset move (to be checked). + + Returns + ------- + dict[str, object] or str + Result of the move operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4096,6 +8323,21 @@ def set_current_camera_position(self, cameraId: Any = None, # TODO not working bindPosition: int = None) -> dict[str, object] | str: + """ + Set the current position of a camera as the home position. + + Parameters + ---------- + cameraId : Any, optional + ID of the camera. + bindPosition : int, optional + Position to bind as home. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Preset' info = self.gen_list[api_name] api_path = info['path'] @@ -4110,6 +8352,19 @@ def set_current_camera_position(self, def enum_patrol_list(self, cam: Any = None) -> dict[str, object] | str: + """ + Enumerate the list of patrols for a specified camera. + + Parameters + ---------- + cam : Any, optional + Camera identifier. + + Returns + ------- + dict[str, object] or str + List of patrols or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4124,6 +8379,19 @@ def enum_patrol_list(self, def enum_patrol_name_list(self, camId: Any = None) -> dict[str, object] | str: + """ + Enumerate the list of patrol names for a specified camera. + + Parameters + ---------- + camId : Any, optional + Camera identifier. + + Returns + ------- + dict[str, object] or str + List of patrol names or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4139,6 +8407,19 @@ def enum_patrol_name_list(self, def load_patrol_detail(self, # TODO not working id: int = None) -> dict[str, object] | str: + """ + Load the details of a specific patrol. + + Parameters + ---------- + id : int, optional + Patrol ID. + + Returns + ------- + dict[str, object] or str + Patrol details or error information. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4159,6 +8440,29 @@ def add_or_modify_patrol(self, name: str = None, # TODO not working presetList: Any = None) -> dict[str, object] | str: + """ + Add or modify a patrol for a camera. + + Parameters + ---------- + camId : Any, optional + Camera identifier. + id : int, optional + Patrol ID. + stayTime : int, optional + Stay time at each preset. + speed : int, optional + Patrol speed. + name : str, optional + Name of the patrol. + presetList : Any, optional + List of presets for the patrol (structure to be checked). + + Returns + ------- + dict[str, object] or str + Result of the add/modify operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4175,6 +8479,21 @@ def delete_specific_patrol(self, camId: Any = None, # TODO not working patrolId: str = None) -> dict[str, object] | str: + """ + Delete a specific patrol from a camera. + + Parameters + ---------- + camId : Any, optional + Camera identifier. + patrolId : str, optional + Patrol ID to delete. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4190,6 +8509,21 @@ def delete_specific_patrol(self, def run_patrol(self, camId: Any = None, id: int = None) -> dict[str, object] | str: # TODO not working + """ + Run a specified patrol on a camera. + + Parameters + ---------- + camId : Any, optional + Camera identifier. + id : int, optional + Patrol ID. + + Returns + ------- + dict[str, object] or str + Result of the run operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4204,6 +8538,19 @@ def run_patrol(self, def stop_patrol(self, camId: Any = None) -> dict[str, object] | str: # TODO not working + """ + Stop the currently running patrol on a camera. + + Parameters + ---------- + camId : Any, optional + Camera identifier. + + Returns + ------- + dict[str, object] or str + Result of the stop operation or error details. + """ api_name = 'SYNO.SurveillanceStation.PTZ.Patrol' info = self.gen_list[api_name] api_path = info['path'] @@ -4217,6 +8564,14 @@ def stop_patrol(self, return self.request_data(api_name, api_path, req_param) def start_camera_search_process(self) -> dict[str, object] | str: + """ + Start searching for cameras. + + Returns + ------- + dict[str, object] or str + Result of the search operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -4227,6 +8582,21 @@ def start_camera_search_process(self) -> dict[str, object] | str: def get_camera_search_info(self, pid: int = None, offset: int = None) -> dict[str, object] | str: + """ + Get information about the current camera search. + + Parameters + ---------- + pid : int, optional + Process ID of the search. + offset : int, optional + Offset for pagination. + + Returns + ------- + dict[str, object] or str + Search information or error details. + """ api_name = 'SYNO.SurveillanceStation.Camera.Search' info = self.gen_list[api_name] api_path = info['path'] @@ -4241,6 +8611,19 @@ def get_camera_search_info(self, def toggle_home_mode(self, on: bool = None) -> dict[str, object] | str: + """ + Toggle the Home Mode in Surveillance Station. + + Parameters + ---------- + on : bool, optional + Whether to enable (True) or disable (False) Home Mode. + + Returns + ------- + dict[str, object] or str + Result of the toggle operation or error details. + """ api_name = 'SYNO.SurveillanceStation.HomeMode' info = self.gen_list[api_name] api_path = info['path'] @@ -4255,6 +8638,19 @@ def toggle_home_mode(self, def get_home_mode_settings(self, need_mobiles: bool = None) -> dict[str, object] | str: + """ + Get the current Home Mode settings. + + Parameters + ---------- + need_mobiles : bool, optional + Whether to include mobile device information. + + Returns + ------- + dict[str, object] or str + Home Mode settings or error details. + """ api_name = 'SYNO.SurveillanceStation.HomeMode' info = self.gen_list[api_name] api_path = info['path'] @@ -4275,6 +8671,29 @@ def get_transaction_list(self, start: int = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + Get a list of device transactions with optional filters. + + Parameters + ---------- + filterIds : str, optional + Comma-separated list of transaction IDs to filter. + filterDsIds : str, optional + Comma-separated list of device station IDs to filter. + filterEnable : bool, optional + Filter by enabled status. + filterStatus : int, optional + Filter by status code. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + + Returns + ------- + dict[str, object] or str + List of transactions or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Device' info = self.gen_list[api_name] api_path = info['path'] @@ -4299,6 +8718,37 @@ def get_all_transaction_list(self, start: int = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + Get a list of all transactions with optional filters. + + Parameters + ---------- + filterIds : str, optional + Comma-separated list of transaction IDs to filter. + dsId : int, optional + Device station ID. + filterTimeFrom : Any, optional + Start time for filtering. + filterStatus : int, optional + Filter by status code. + filterLock : bool, optional + Filter by lock status. + filterTimeTo : Any, optional + End time for filtering. + filterTimeRangeIntersect : bool, optional + Whether to intersect time ranges. + filterKeyword : str, optional + Keyword for filtering. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + + Returns + ------- + dict[str, object] or str + List of transactions or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4322,6 +8772,37 @@ def lock_history_records(self, filterKeyword: str = None, start: int = None, limit: int = None) -> dict[str, object] | str: + """ + Lock specified history records. + + Parameters + ---------- + filterIds : str, optional + Comma-separated list of record IDs to lock. + dsId : int, optional + Device station ID. + filterStatus : int, optional + Filter by status code. + filterLock : bool, optional + Filter by lock status. + filterTimeFrom : Any, optional + Start time for filtering. + filterTimeTo : Any, optional + End time for filtering. + filterTimeRangeIntersect : bool, optional + Whether to intersect time ranges. + filterKeyword : str, optional + Keyword for filtering. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + + Returns + ------- + dict[str, object] or str + Result of the lock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4345,6 +8826,37 @@ def unlock_history_records(self, filterKeyword: str = None, start: int = None, limit: int = None) -> dict[str, object] | str: + """ + Unlock specified history records. + + Parameters + ---------- + filterIds : str, optional + Comma-separated list of record IDs to unlock. + dsId : int, optional + Device station ID. + filterStatus : int, optional + Filter by status code. + filterLock : bool, optional + Filter by lock status. + filterTimeFrom : Any, optional + Start time for filtering. + filterTimeTo : Any, optional + End time for filtering. + filterTimeRangeIntersect : bool, optional + Whether to intersect time ranges. + filterKeyword : str, optional + Keyword for filtering. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + + Returns + ------- + dict[str, object] or str + Result of the unlock operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4368,6 +8880,37 @@ def delete_history_records(self, filterKeyword: str = None, start: int = None, limit: int = None) -> dict[str, object] | str: + """ + Delete specified history records. + + Parameters + ---------- + filterIds : str, optional + Comma-separated list of record IDs to delete. + dsId : int, optional + Device station ID. + filterStatus : int, optional + Filter by status code. + filterLock : bool, optional + Filter by lock status. + filterTimeFrom : Any, optional + Start time for filtering. + filterTimeTo : Any, optional + End time for filtering. + filterTimeRangeIntersect : bool, optional + Whether to intersect time ranges. + filterKeyword : str, optional + Keyword for filtering. + start : int, optional + Start index for pagination. + limit : int, optional + Maximum number of results to return. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4385,6 +8928,23 @@ def start_session_with_specified_session_id(self, session_id: str = None, # TODO not working timeout: int = None) -> dict[str, object] | str: + """ + Start a session with a specified session ID. + + Parameters + ---------- + device_name : str, optional + Name of the device. + session_id : str, optional + Session ID to start. + timeout : int, optional + Timeout for the session. + + Returns + ------- + dict[str, object] or str + Result of the start operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4401,6 +8961,21 @@ def complete_session_with_specified_id(self, device_name: str = None, # TODO not working session_id: str = None) -> dict[str, object] | str: + """ + Complete a session with a specified session ID. + + Parameters + ---------- + device_name : str, optional + Name of the device. + session_id : str, optional + Session ID to complete. + + Returns + ------- + dict[str, object] or str + Result of the complete operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4417,6 +8992,21 @@ def cancel_session_with_specified_session_id(self, device_name: str = None, # TODO not working session_id: str = None) -> dict[str, object] | str: + """ + Cancel a session with a specified session ID. + + Parameters + ---------- + device_name : str, optional + Name of the device. + session_id : str, optional + Session ID to cancel. + + Returns + ------- + dict[str, object] or str + Result of the cancel operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4434,6 +9024,23 @@ def carry_data_into_session_id(self, session_id: str = None, # TODO not working content: str = None) -> dict[str, object] | str: + """ + Append data to a session with a specified session ID. + + Parameters + ---------- + device_name : str, optional + Name of the device. + session_id : str, optional + Session ID to append data to. + content : str, optional + Data content to append. + + Returns + ------- + dict[str, object] or str + Result of the append operation or error details. + """ api_name = 'SYNO.SurveillanceStation.Transactions.Transaction' info = self.gen_list[api_name] api_path = info['path'] @@ -4471,6 +9078,63 @@ def add_edit_active_vault_task(self, storagePath: str = None, # TODO to check type: int = None) -> dict[str, object] | str: + """ + Add or edit an active vault task for archiving. + + Parameters + ---------- + blCustomFolder : bool, optional + Whether to use a custom folder for storage. + blLimitBySize : bool, optional + Whether to limit the archive by size. + blRotateFile : bool, optional + Whether to enable file rotation. + blSrcRecNoOverlap : bool, optional + Whether to avoid overlapping source recordings. + blUseRecDet : bool, optional + Whether to use recording detection. + camId : Any, optional + Camera ID. + camInfo : Any, optional + Camera information. + dayLimit : int, optional + Day limit for the archive. + didCode : str, optional + Device code. + dsSerial : str, optional + Device serial number. + execTime : Any, optional + Execution time. + hostname : str, optional + Hostname of the source server. + id : int, optional + Task ID (for editing). + name : str, optional + Name of the task. + passwd : str, optional + Password for authentication. + port : str, optional + Port number. + recEndTm : Any, optional + Recording end time. + recMode : str, optional + Recording mode. + recSchedule : str, optional + Recording schedule. + recStartTm : Any, optional + Recording start time. + schedule : str, optional + Task schedule. + storagePath : str, optional + Path for storage. + type : int, optional + Type of the task. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4493,6 +9157,33 @@ def login_source_server_get_info(self, didCode: str = None, # TODO not working srcDsId: int = None) -> dict[str, object] | str: + """ + Log in to the source server and retrieve information. + + Parameters + ---------- + port : str, optional + Port number of the source server. + hostname : str, optional + Hostname of the source server. + protocol : bool, optional + Protocol to use (e.g., HTTPS). + username : str, optional + Username for authentication. + passwd : str, optional + Password for authentication. + archId : int, optional + Archive ID. + didCode : str, optional + Device code. + srcDsId : int, optional + Source device ID (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4508,6 +9199,21 @@ def login_source_server_get_info(self, def delete_archive_vault_task(self, id: int = None, keepRec: bool = None) -> dict[str, object] | str: + """ + Delete an archive vault task. + + Parameters + ---------- + id : int, optional + Task ID to delete. + keepRec : bool, optional + Whether to keep the recordings. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4521,6 +9227,14 @@ def delete_archive_vault_task(self, return self.request_data(api_name, api_path, req_param) def list_exist_archive_vault(self) -> dict[str, object] | str: + """ + List all existing archive vault tasks. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4536,6 +9250,19 @@ def list_exist_archive_vault(self) -> dict[str, object] | str: def enable_archive_vault_task(self, # TODO not working id: int = None) -> dict[str, object] | str: + """ + Enable an archive vault task. + + Parameters + ---------- + id : int, optional + Task ID to enable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4550,6 +9277,19 @@ def enable_archive_vault_task(self, def disable_archive_vault_task(self, id: int = None) -> dict[str, object] | str: + """ + Disable an archive vault task. + + Parameters + ---------- + id : int, optional + Task ID to disable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4566,6 +9306,21 @@ def disable_archive_vault_batchedit_task(self, taskIds: str = None, # TODO not working attrs: Any = None) -> dict[str, object] | str: + """ + Batch edit (disable) archive vault tasks. + + Parameters + ---------- + taskIds : str, optional + Comma-separated list of task IDs. + attrs : Any, optional + Additional attributes for batch edit (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4581,6 +9336,19 @@ def disable_archive_vault_batchedit_task(self, def get_batch_edit_progress(self, # TODO not working pid: int = None) -> dict[str, object] | str: + """ + Get the progress of a batch edit operation. + + Parameters + ---------- + pid : int, optional + Process ID of the batch edit operation (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4597,6 +9365,19 @@ def get_batch_edit_progress(self, def get_batchedit_proress_info(self, # TODO not working pid: int = None) -> dict[str, object] | str: + """ + Get detailed information about batch edit progress. + + Parameters + ---------- + pid : int, optional + Process ID of the batch edit operation (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4612,6 +9393,19 @@ def get_batchedit_proress_info(self, def clean_batchedit_progress_data(self, pid: int = None) -> dict[str, object] | str: + """ + Clean up batch edit progress data. + + Parameters + ---------- + pid : int, optional + Process ID of the batch edit operation. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Archiving.Pull' info = self.gen_list[api_name] api_path = info['path'] @@ -4626,6 +9420,14 @@ def clean_batchedit_progress_data(self, return self.request_data(api_name, api_path, req_param) def get_youtube_live_broadcast_setting(self) -> dict[str, object] | str: + """ + Get the current YouTube Live broadcast settings. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.YoutubeLive' info = self.gen_list[api_name] api_path = info['path'] @@ -4639,6 +9441,27 @@ def set_youtube_live_broadcast_info(self, cam_id: int = None, stream_profile: int = None, live_on: bool = None) -> dict[str, object] | str: + """ + Set YouTube Live broadcast information. + + Parameters + ---------- + rtmp_path : str, optional + RTMP path for the broadcast. + key : str, optional + Stream key. + cam_id : int, optional + Camera ID. + stream_profile : int, optional + Stream profile. + live_on : bool, optional + Whether to enable live broadcast. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.YoutubeLive' info = self.gen_list[api_name] api_path = info['path'] @@ -4652,6 +9475,14 @@ def set_youtube_live_broadcast_info(self, return self.request_data(api_name, api_path, req_param) def close_youtube_live_broadcast(self) -> dict[str, object] | str: + """ + Close the current YouTube Live broadcast. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.YoutubeLive' info = self.gen_list[api_name] api_path = info['path'] @@ -4661,6 +9492,14 @@ def close_youtube_live_broadcast(self) -> dict[str, object] | str: # TODO not working def get_deep_video_analytic(self) -> dict[str, object] | str: + """ + Get the list of deep video analytic tasks. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4702,6 +9541,81 @@ def create_edit_DVA_task(self, people_hint_pos: str = None, # TODO not working blEditMode: bool = None) -> dict[str, object] | str: + """ + Create or edit a Deep Video Analytics (DVA) task. + + Parameters + ---------- + analyze_type : int, optional + Type of analysis to perform. + actFromHost : bool, optional + Whether the action is triggered from the host. + name : str, optional + Name of the DVA task. + camera_id : int, optional + ID of the camera associated with the task. + enable : bool, optional + Whether to enable the task. + enable_recording : bool, optional + Whether to enable recording for the task. + pre_rec_time : int, optional + Pre-recording time in seconds. + post_rec_time : int, optional + Post-recording time in seconds. + event_integration : int, optional + Event integration setting. + region_type : int, optional + Type of detection region. + det_region_cnt : int, optional + Number of detection regions. + det_region : int, optional + Detection region configuration. + people_mode : int, optional + People counting mode. + reset_cnt_frequency : int, optional + Frequency for resetting the counter. + reset_weekday : int, optional + Weekday for counter reset. + reset_date : int, optional + Date for counter reset. + reset_time_minute : int, optional + Minute for counter reset. + reset_time_hour : int, optional + Hour for counter reset. + fence_dir_flag : int, optional + Fence direction flag. + people_display_pos : int, optional + Display position for people counting. + stream_profile : int, optional + Stream profile to use. + people_enable_stay_max : bool, optional + Whether to enable maximum stay for people. + intrusion_detect_target : int, optional + Target for intrusion detection. + min_obj_size : Any, optional + Minimum object size for detection. + min_obj_size_option : int, optional + Option for minimum object size. + enable_min_duration : int, optional + Enable minimum duration for detection. + people_display_info : int, optional + Display information for people counting. + people_enter : int, optional + Number of people entering. + people_stay_max : int, optional + Maximum number of people staying. + people_region : str, optional + Region for people counting. + people_hint_pos : str, optional + Hint position for people counting. + blEditMode : bool, optional + Edit mode flag (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4716,6 +9630,19 @@ def create_edit_DVA_task(self, def delete_dva_task(self, ids: str = None) -> dict[str, object] | str: # TODO not working + """ + Delete a Deep Video Analytics (DVA) task. + + Parameters + ---------- + ids : str, optional + Comma-separated list of DVA task IDs to delete. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4730,6 +9657,19 @@ def delete_dva_task(self, def enable_dva_task(self, ids: str = None) -> dict[str, object] | str: # TODO not working + """ + Enable one or more Deep Video Analytics (DVA) tasks. + + Parameters + ---------- + ids : str, optional + Comma-separated list of DVA task IDs to enable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4745,6 +9685,19 @@ def enable_dva_task(self, def disable_dva_task(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Disable one or more Deep Video Analytics (DVA) tasks. + + Parameters + ---------- + ids : str, optional + Comma-separated list of DVA task IDs to disable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4760,6 +9713,19 @@ def disable_dva_task(self, def reset_counter_people_counting_task(self, # TODO not working taskId: str = None) -> dict[str, object] | str: + """ + Reset the people counting counter for a specific DVA task. + + Parameters + ---------- + taskId : str, optional + ID of the people counting task to reset. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA' info = self.gen_list[api_name] api_path = info['path'] @@ -4779,6 +9745,25 @@ def get_people_enter_leave_count(self, timeEnd: str = None, timezone: int = None, ) -> dict[str, object] | str: # TODO not working + """ + Get the count of people entering and leaving for specified DVA tasks. + + Parameters + ---------- + ids : str, optional + Comma-separated list of DVA task IDs. + timeStart : str, optional + Start time for the count (ISO format or timestamp). + timeEnd : str, optional + End time for the count (ISO format or timestamp). + timezone : int, optional + Timezone offset. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Report' info = self.gen_list[api_name] api_path = info['path'] @@ -4799,6 +9784,29 @@ def get_people_count_of_day(self, timestamp: int = None, # TODO not working blOccupancy: int = None) -> dict[str, object] | str: + """ + Get the people count report for a specific day. + + Parameters + ---------- + ids : str, optional + Comma-separated list of DVA task IDs. + interval : int, optional + Interval for the report. + intervalUnit : int, optional + Unit for the interval. + timezone : int, optional + Timezone offset. + timestamp : int, optional + Timestamp for the report. + blOccupancy : int, optional + Occupancy flag (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Report' info = self.gen_list[api_name] api_path = info['path'] @@ -4815,6 +9823,21 @@ def list_people_counting_task(self, taskList: str = None, # TODO not working limit: int = None) -> dict[str, object] | str: + """ + List people counting tasks. + + Parameters + ---------- + taskList : str, optional + Comma-separated list of task IDs to list. + limit : int, optional + Limit the number of tasks returned (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -4831,6 +9854,21 @@ def delete_recording_file_of_detection(self, slaveDsParam: str = None, # TODO not working deleteMethod: int = None) -> dict[str, object] | str: + """ + Delete recording files associated with detection events. + + Parameters + ---------- + slaveDsParam : str, optional + Parameters for the slave device. + deleteMethod : int, optional + Method for deletion (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -4848,6 +9886,23 @@ def get_info_of_task_and_frame(self, taskId: int = None, # TODO not working blAlertEvt: bool = None) -> dict[str, object] | str: + """ + Get analytic result information for a specific task and frame. + + Parameters + ---------- + eventId : int, optional + Event ID to query. + taskId : int, optional + Task ID to query. + blAlertEvt : bool, optional + Alert event flag (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -4865,6 +9920,21 @@ def lock_recording_file_of_detection(self, dsId: int = None, # TODO not working idList: int = None) -> dict[str, object] | str: + """ + Lock recording files associated with detection events. + + Parameters + ---------- + dsId : int, optional + Device server ID. + idList : int, optional + List of recording file IDs to lock (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -4881,6 +9951,21 @@ def unlock_recording_file_of_detection(self, dsId: int = None, # TODO not working idList: str = None) -> dict[str, object] | str: + """ + Unlock recording files associated with detection events. + + Parameters + ---------- + dsId : int, optional + Device server ID. + idList : str, optional + List of recording file IDs to unlock (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.Recording' info = self.gen_list[api_name] api_path = info['path'] @@ -4895,6 +9980,14 @@ def unlock_recording_file_of_detection(self, # TODO not working def get_info_people_counting_task(self) -> dict[str, object] | str: + """ + Get information about people counting tasks. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -4920,6 +10013,39 @@ def create_people_counting_task(self, resert_tome_hour: int = None, # TODO not working resert_tome_minute: int = None) -> dict[str, object] | str: + """ + Create a new people counting task. + + Parameters + ---------- + enable : bool, optional + Whether to enable the task. + task_ids : str, optional + Comma-separated list of task IDs. + owner_ds_id : int, optional + Owner device server ID. + name : str, optional + Name of the task. + people_display_info : str, optional + Display information for people counting. + people_enable_stay_max : int, optional + Enable maximum stay for people. + reset_cnt_frequency : int, optional + Frequency for resetting the counter. + resert_date : int, optional + Date for counter reset. + resert_weekday : int, optional + Weekday for counter reset. + resert_tome_hour : int, optional + Hour for counter reset. + resert_tome_minute : int, optional + Minute for counter reset (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -4945,6 +10071,39 @@ def modify_setting_of_people_counting_task(self, resert_tome_hour: int = None, # TODO not working resert_tome_minute: int = None) -> dict[str, object] | str: + """ + Modify the settings of an existing people counting task. + + Parameters + ---------- + enable : bool, optional + Whether to enable the task. + id : int, optional + ID of the task to modify. + task_ids : str, optional + Comma-separated list of task IDs. + name : str, optional + Name of the task. + people_display_info : int, optional + Display information for people counting. + people_enable_max : int, optional + Enable maximum stay for people. + reset_cnt_frequency : int, optional + Frequency for resetting the counter. + resert_date : int, optional + Date for counter reset. + resert_weekday : int, optional + Weekday for counter reset. + resert_tome_hour : int, optional + Hour for counter reset. + resert_tome_minute : int, optional + Minute for counter reset (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -4960,6 +10119,19 @@ def modify_setting_of_people_counting_task(self, def delete_task_group(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Delete a people counting task group. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task group IDs to delete. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -4975,6 +10147,19 @@ def delete_task_group(self, def start_count_people_task_in_groups(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Enable people counting tasks in specified groups. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task group IDs to enable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -4990,6 +10175,19 @@ def start_count_people_task_in_groups(self, def stop_count_people_task_in_groups(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Disable people counting tasks in specified groups. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task group IDs to disable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -5005,6 +10203,19 @@ def stop_count_people_task_in_groups(self, def get_number_counting_task_group(self, # TODO not working id: int = None) -> dict[str, object] | str: + """ + Get the people count for a specific task group. + + Parameters + ---------- + id : int, optional + ID of the task group. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -5020,6 +10231,19 @@ def get_number_counting_task_group(self, def lock_recording_file_result(self, # TODO not working id: int = None) -> dict[str, object] | str: + """ + Reset the people count for a specific IVA task group. + + Parameters + ---------- + id : int, optional + ID of the IVA task group. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.IVA.TaskGroup' info = self.gen_list[api_name] api_path = info['path'] @@ -5038,6 +10262,23 @@ def get_face_list_task(self, ownerDsId: int = None, blOnlyEnableDs: bool = None, ) -> dict[str, object] | str: # TODO not working + """ + Retrieve the list of face detection tasks. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task IDs to filter. + ownerDsId : int, optional + ID of the owner DiskStation. + blOnlyEnableDs : bool, optional + Whether to include only enabled DiskStations. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5084,6 +10325,81 @@ def create_or_edit_task(self, scheduleOn: bool = None, # TODO not working ignore_bad_quality: bool = None) -> dict[str, object] | str: + """ + Create or edit a face detection task. + + Parameters + ---------- + id : int, optional + Task ID. + id_on_rec_server : int, optional + Task ID on the recording server. + camera_id : int, optional + Camera ID. + camera_id_on_rec : int, optional + Camera ID on the recording server. + owner_ds_id : int, optional + Owner DiskStation ID. + enable : bool, optional + Whether to enable the task. + blEditMode : bool, optional + Edit mode flag. + stream_profile : int, optional + Stream profile index. + name : str, optional + Name of the task. + similarity : float, optional + Similarity threshold for face recognition. + allowed_color : int, optional + Color code for allowed faces. + allowed_list : Any, optional + List of allowed faces. + blocked_color : int, optional + Color code for blocked faces. + blocked_list : Any, optional + List of blocked faces. + vip_color : int, optional + Color code for VIP faces. + vip_list : Any, optional + List of VIP faces. + recognized_color : int, optional + Color code for recognized faces. + unrecognized_color : int, optional + Color code for unrecognized faces. + deleted : bool, optional + Whether the task is deleted. + det_region : str, optional + Detection region. + det_region_cnt : int, optional + Number of detection regions. + region_type : int, optional + Type of region. + display_info : int, optional + Display information. + display_type : int, optional + Display type. + frame_display_info : int, optional + Frame display information. + enable_min_ogj_size : bool, optional + Enable minimum object size. + min_ogj_size : float, optional + Minimum object size. + post_rec_time : int, optional + Post-recording time in seconds. + pre_rec_time : int, optional + Pre-recording time in seconds. + schedule : str, optional + Task schedule. + scheduleOn : bool, optional + Whether the schedule is enabled. + ignore_bad_quality : bool, optional + Ignore bad quality flag (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5100,6 +10416,21 @@ def delete_face_task(self, ids: str = None, # TODO not working keepRecording: bool = None) -> dict[str, object] | str: + """ + Delete one or more face detection tasks. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task IDs to delete. + keepRecording : bool, optional + Whether to keep the associated recordings (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5115,6 +10446,19 @@ def delete_face_task(self, def enable_task_to_start_detection_recording(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Enable face detection tasks to start detection and recording. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task IDs to enable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5130,6 +10474,19 @@ def enable_task_to_start_detection_recording(self, def disable_task_to_stop_detection_recording(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Disable face detection tasks to stop detection and recording. + + Parameters + ---------- + ids : str, optional + Comma-separated list of task IDs to disable. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5145,6 +10502,19 @@ def disable_task_to_stop_detection_recording(self, def list_task_with_privilege_to_watch(self, # TODO not working ids: int = None) -> dict[str, object] | str: + """ + List face detection tasks with privilege to watch. + + Parameters + ---------- + ids : int, optional + Task group ID to filter. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5163,6 +10533,23 @@ def create_face_group(self, description: str = None, # TODO not working update_registered_face: Any = None) -> dict[str, object] | str: + """ + Create a new face group. + + Parameters + ---------- + name : str, optional + Name of the face group. + description : str, optional + Description of the face group. + update_registered_face : Any, optional + Registered face update information (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5179,6 +10566,19 @@ def create_face_group(self, def disable_face_grooup(self, # TODO not working ids: Any = None) -> dict[str, object] | str: + """ + Delete (disable) one or more face groups. + + Parameters + ---------- + ids : Any, optional + IDs of the face groups to delete (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5197,6 +10597,25 @@ def edit_face_group(self, description: str = None, update_registered_face: Any = None, id: int = None) -> dict[str, object] | str: # TODO not working + """ + Edit an existing face group. + + Parameters + ---------- + name : str, optional + Name of the face group. + description : str, optional + Description of the face group. + update_registered_face : Any, optional + Registered face update information. + id : int, optional + ID of the face group to edit. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5213,6 +10632,21 @@ def get_face_group_list(self, id_only: bool = None, # TODO not working filter: Any = None) -> dict[str, object] | str: + """ + Retrieve the list of face groups. + + Parameters + ---------- + id_only : bool, optional + Whether to return only IDs. + filter : Any, optional + Filter criteria (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5228,6 +10662,19 @@ def get_face_group_list(self, def count_face_groups(self, # TODO not working filter: Any = None) -> dict[str, object] | str: + """ + Count the number of face groups. + + Parameters + ---------- + filter : Any, optional + Filter criteria (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5244,6 +10691,21 @@ def detect_faces_image(self, image_data: str = None, # TODO not working image_size: int = None) -> dict[str, object] | str: + """ + Detect faces in an image. + + Parameters + ---------- + image_data : str, optional + Base64-encoded image data. + image_size : int, optional + Size of the image (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5269,6 +10731,37 @@ def create_registered_face(self, update_unrecognized_captured_face: bool = None, # TODO not working append_image_data: bool = None) -> dict[str, object] | str: + """ + Create a new registered face. + + Parameters + ---------- + account : str, optional + Account associated with the face. + name : str, optional + Name of the person. + description : str, optional + Description of the face. + image_data : str, optional + Base64-encoded image data. + image_size : int, optional + Size of the image. + face : Any, optional + Face data. + update_face_group : Any, optional + Face group update information. + captured_face_id : int, optional + ID of the captured face. + update_unrecognized_captured_face : bool, optional + Whether to update unrecognized captured face. + append_image_data : bool, optional + Append image data flag (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5285,6 +10778,19 @@ def create_registered_face(self, def delete_registered_face(self, # TODO not working ids: Any = None) -> dict[str, object] | str: + """ + Delete one or more registered faces. + + Parameters + ---------- + ids : Any, optional + IDs of the registered faces to delete (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5311,6 +10817,39 @@ def edit_registered_face(self, update_unrecognized_captured_face: bool = None, append_image_data: bool = None, ) -> dict[str, object] | str: # TODO not working + """ + Edit an existing registered face. + + Parameters + ---------- + id : int, optional + ID of the registered face. + account : str, optional + Account associated with the face. + name : str, optional + Name of the person. + description : str, optional + Description of the face. + image_data : str, optional + Base64-encoded image data. + image_size : int, optional + Size of the image. + face : Any, optional + Face data. + update_face_group : Any, optional + Face group update information. + captured_face_id : int, optional + ID of the captured face. + update_unrecognized_captured_face : bool, optional + Whether to update unrecognized captured face. + append_image_data : bool, optional + Append image data flag. + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5329,6 +10868,23 @@ def list_registered_face(self, filter: Any = None, append_image_data: bool = None, ) -> dict[str, object] | str: # TODO not working + """ + List registered faces. + + Parameters + ---------- + id_only : bool, optional + Whether to return only IDs. + filter : Any, optional + Filter criteria. + append_image_data : bool, optional + Whether to append image data (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5345,6 +10901,19 @@ def list_registered_face(self, def count_registered_face(self, # TODO not working filter: Any = None) -> dict[str, object] | str: + """ + Count the number of registered faces. + + Parameters + ---------- + filter : Any, optional + Filter criteria (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5362,6 +10931,21 @@ def search_registered_face(self, keywords: str = None, # TODO not working append_image_data: bool = None) -> dict[str, object] | str: + """ + Search for registered faces by keywords. + + Parameters + ---------- + keywords : str, optional + Search keywords. + append_image_data : bool, optional + Whether to append image data (not working). + + Returns + ------- + dict of str to object or str + API response from the request. + """ api_name = 'SYNO.SurveillanceStation.Face' info = self.gen_list[api_name] api_path = info['path'] @@ -5382,6 +10966,27 @@ def get_face_result_list(self, limit: int = None, # TODO not working slaveDsParam: int = None) -> dict[str, object] | str: + """ + Retrieve a list of face recognition results. + + Parameters + ---------- + filter : Any, optional + Filter criteria for the face results. + blIncludeSnapshot : bool, optional + Whether to include snapshot images in the results. + blIncludeRegisteredFace : bool, optional + Whether to include registered face information. + limit : int, optional + Maximum number of results to return. + slaveDsParam : int, optional + Additional parameter for slave DiskStation (not working). + + Returns + ------- + dict of str to object or str + API response containing the list of face recognition results. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5398,6 +11003,21 @@ def delete_face_result(self, filter: Any = None, # TODO not working slaveDsParam: Any = None) -> dict[str, object] | str: + """ + Delete face recognition results. + + Parameters + ---------- + filter : Any, optional + Filter criteria for selecting face results to delete. + slaveDsParam : Any, optional + Additional parameter for slave DiskStation (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the delete operation. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5414,6 +11034,21 @@ def lock_face_result(self, filter: Any = None, # TODO not working slaveDsParam: Any = None) -> dict[str, object] | str: + """ + Lock face recognition results to prevent modification or deletion. + + Parameters + ---------- + filter : Any, optional + Filter criteria for selecting face results to lock. + slaveDsParam : Any, optional + Additional parameter for slave DiskStation (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the lock operation. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5430,6 +11065,21 @@ def unlock_face_result(self, filter: Any = None, # TODO not working slaveDsParam: Any = None) -> dict[str, object] | str: + """ + Unlock face recognition results to allow modification or deletion. + + Parameters + ---------- + filter : Any, optional + Filter criteria for selecting face results to unlock. + slaveDsParam : Any, optional + Additional parameter for slave DiskStation (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the unlock operation. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5445,6 +11095,19 @@ def unlock_face_result(self, def get_recording_file_of_face_info(self, # TODO not working capturedFaceId: int = None) -> dict[str, object] | str: + """ + Retrieve the recording file associated with a specific captured face. + + Parameters + ---------- + capturedFaceId : int, optional + ID of the captured face (not working). + + Returns + ------- + dict of str to object or str + API response containing the recording file information. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5464,6 +11127,27 @@ def get_recognition_face_information(self, endTime: int = None, # TODO not working blIncludeRegisteredFace: int = None) -> dict[str, object] | str: + """ + Retrieve analytic results for face recognition events. + + Parameters + ---------- + taskId : int, optional + ID of the face recognition task. + eventId : int, optional + ID of the event. + startTime : int, optional + Start time for the query (timestamp). + endTime : int, optional + End time for the query (timestamp). + blIncludeRegisteredFace : int, optional + Whether to include registered face information (not working). + + Returns + ------- + dict of str to object or str + API response containing analytic results. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5481,6 +11165,21 @@ def correct_face_result(self, id: int = None, # TODO not working registered_face_id: int = None) -> dict[str, object] | str: + """ + Correct the result of a face recognition event by associating it with a registered face. + + Parameters + ---------- + id : int, optional + ID of the face recognition result to correct. + registered_face_id : int, optional + ID of the registered face to associate (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the correction. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5496,6 +11195,19 @@ def correct_face_result(self, def mark_face_result_as_stranger(self, # TODO not working ids: str = None) -> dict[str, object] | str: + """ + Mark one or more face recognition results as strangers. + + Parameters + ---------- + ids : str, optional + Comma-separated list of face result IDs to mark as strangers (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the operation. + """ api_name = 'SYNO.SurveillanceStation.Face.Result' info = self.gen_list[api_name] api_path = info['path'] @@ -5517,6 +11229,31 @@ def add_new_bookmark(self, timestamp: Any = None, comment: str = None, ) -> dict[str, object] | str: # TODO not working + """ + Add a new bookmark to a recording. + + Parameters + ---------- + id : int, optional + ID of the bookmark. + eventId : int, optional + ID of the associated event. + cameraId : int, optional + ID of the camera. + archId : int, optional + ID of the archive. + name : str, optional + Name of the bookmark. + timestamp : Any, optional + Timestamp for the bookmark. + comment : str, optional + Comment for the bookmark. + + Returns + ------- + dict of str to object or str + API response indicating the result of the add operation. + """ api_name = 'SYNO.SurveillanceStation.Recording.Bookmark' info = self.gen_list[api_name] api_path = info['path'] @@ -5532,6 +11269,19 @@ def add_new_bookmark(self, def delete_bookmark(self, # TODO not working bookmarkIds: Any = None) -> dict[str, object] | str: + """ + Delete one or more bookmarks from recordings. + + Parameters + ---------- + bookmarkIds : Any, optional + IDs of the bookmarks to delete (not working). + + Returns + ------- + dict of str to object or str + API response indicating the result of the delete operation. + """ api_name = 'SYNO.SurveillanceStation.Recording.Bookmark' info = self.gen_list[api_name] api_path = info['path'] @@ -5551,6 +11301,27 @@ def list_bookmark_detail(self, fromTime: int = None, # TODO not working toTime: int = None) -> dict[str, object] | str: + """ + List details of bookmarks for recordings. + + Parameters + ---------- + offset : int, optional + Offset for pagination. + limit : int, optional + Maximum number of bookmarks to return. + cameraIds : str, optional + Comma-separated list of camera IDs to filter. + fromTime : int, optional + Start time for filtering bookmarks (timestamp). + toTime : int, optional + End time for filtering bookmarks (not working). + + Returns + ------- + dict of str to object or str + API response containing bookmark details. + """ api_name = 'SYNO.SurveillanceStation.Recording.Bookmark' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/task_scheduler.py b/synology_api/task_scheduler.py index d343b3bc..2c439c8e 100644 --- a/synology_api/task_scheduler.py +++ b/synology_api/task_scheduler.py @@ -1,3 +1,4 @@ +"""Task Scheduler API implementation for Synology DSM.""" from __future__ import annotations from . import base_api from .core_user import User @@ -5,6 +6,40 @@ class _Schedule(): + """ + Schedule configuration class for Synology DSM task scheduling. + + This class encapsulates the parameters required to define a schedule for a task, + such as frequency, days, dates, repeat patterns, and time settings. + + Parameters + ---------- + run_frequently : bool, optional + If True, the schedule runs frequently (default is True). + run_days : str, optional + Comma-separated string of week days to run the task (default is '0,1,2,3,4,5,6'). + run_date : str, optional + Specific date to run the task (default is ''). + repeat : str, optional + Repeat pattern for the schedule, e.g., 'Daily' (default is 'Daily'). + monthly_week : list of str, optional + List of weeks in the month to run the task (default is empty list). + start_time_h : int, optional + Start time hour for the schedule (default is 0). + start_time_m : int, optional + Start time minute for the schedule (default is 0). + same_day_repeat_h : int, optional + Repeat interval in hours within the same day (default is 0). + same_day_repeat_m : int, optional + Repeat interval in minutes within the same day (default is 0). + same_day_repeat_until : int, optional + Time (in minutes) until which the same day repeat is active (default is 0). + + See Also + -------- + TaskScheduler : Main API class for managing scheduled tasks. + """ + def __init__( self, run_frequently: bool = True, # date_type @@ -18,6 +53,32 @@ def __init__( same_day_repeat_m: int = 0, same_day_repeat_until: int = 0, ): + """ + Initialize a schedule configuration for a Synology DSM task. + + Parameters + ---------- + run_frequently : bool, optional + If True, the schedule runs frequently (default is True). + run_days : str, optional + Comma-separated string of week days to run the task (default is '0,1,2,3,4,5,6'). + run_date : str, optional + Specific date to run the task (default is ''). + repeat : str, optional + Repeat pattern for the schedule, e.g., 'Daily' (default is 'Daily'). + monthly_week : list of str, optional + List of weeks in the month to run the task (default is empty list). + start_time_h : int, optional + Start time hour for the schedule (default is 0). + start_time_m : int, optional + Start time minute for the schedule (default is 0). + same_day_repeat_h : int, optional + Repeat interval in hours within the same day (default is 0). + same_day_repeat_m : int, optional + Repeat interval in minutes within the same day (default is 0). + same_day_repeat_until : int, optional + Time (in minutes) until which the same day repeat is active (default is 0). + """ self.run_frequently = run_frequently self.run_days = run_days self.run_date = run_date @@ -30,6 +91,24 @@ def __init__( self.same_day_repeat_until = same_day_repeat_until def _generate_dict(self) -> dict: + """ + Generate a dictionary representation of the schedule configuration. + + This method converts the schedule parameters into a dictionary format + suitable for use with the Synology DSM Task Scheduler API. + + Returns + ------- + dict + Dictionary containing the schedule configuration, including date type, + repeat modality, start time, repeat intervals, and other relevant fields. + + Notes + ----- + - The `repeat_date` field is set based on the `repeat` and `run_frequently` attributes. + - The `monthly_week` field is JSON-encoded. + - The `last_work_hour` defaults to `start_time_h` if `same_day_repeat_until` is not set. + """ schedule_dict = { 'date_type': 0 if self.run_frequently else 1, 'monthly_week': json.dumps(self.monthly_week), @@ -75,7 +154,8 @@ def _generate_dict(self) -> dict: class TaskScheduler(base_api.BaseApi): - """Task Scheduler API implementation. + """ + Task Scheduler API implementation. This API provides the functionality to get information related to the scheduler settings and current tasks. @@ -97,6 +177,17 @@ class TaskScheduler(base_api.BaseApi): """ def __get_root_token(self) -> str: + """ + Retrieve a root confirmation token for privileged operations. + + This method authenticates the current user and retrieves a Synology DSM root confirmation token, + which is required for executing privileged actions (e.g., creating or modifying root-owned tasks). + + Returns + ------- + str + The SynoConfirmPWToken if authentication is successful, otherwise an empty string. + """ user_api = User(ip_address=self.session._ip_address, port=self.session._port, username=self.session._username, password=self.session._password, secure=self.session._secure, cert_verify=self.session._verify, dsm_version=self.session._version, debug=self.session._debug, otp_code=self.session._otp_code, application=self.application) @@ -107,25 +198,26 @@ def __get_root_token(self) -> str: return '' def get_output_config(self) -> dict[str, object]: - """Retrieve tasks output configuration. - - Returns - ------- - dict[str, object] - A dictionary containing a list of the tasks and information related to them. - - Examples - -------- - ```json - { - "data": { - "enable_output": true, - "output_path": "share/scripts_output", - "type": "esynoscheduler", - }, - "success": true - } - ``` + """ + Retrieve tasks output configuration. + + Returns + ------- + dict[str, object] + A dictionary containing a list of the tasks and information related to them. + + Examples + -------- + ```json + { + "data": { + "enable_output": true, + "output_path": "share/scripts_output", + "type": "esynoscheduler", + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.EventScheduler' info = self.gen_list[api_name] @@ -145,76 +237,77 @@ def get_task_list( offset: int = 0, limit: int = 50 ) -> dict[str, object]: - """List all present scheduled tasks and event triggered tasks. - - Parameters - ---------- - sort_by : str, optional - The field to sort tasks by. Defaults to `"next_trigger_time"`. - - Possible values: - - "next_trigger_time" - - "name" - - "type" - - "action" - - "owner" - - sort_direction : str, optional - The sort direction. Defaults to `"ASC"`. - - Possible values: - - "ASC" - - "DESC" - - offset : int, optional - Task offset for pagination. Defaults to `0`. - - limit : int, optional - Number of tasks to retrieve. Defaults to `50`. - - Returns - ------- - dict[str, object] - A dictionary containing a list of the tasks and information related to them. - - Examples - -------- - ```json - { - "data": { - "tasks": [ - { - "action": "Run: rsync -aP --delete /volume1/test/ /volume1/test2/", - "can_delete": true, - "can_edit": true, - "can_run": true, - "enable": false, - "id": 13, - "name": "Sync folders", - "next_trigger_time": "2024-09-09 12:26", - "owner": "root", - "real_owner": "root", - "type": "script" - }, - { - "action": "Run: echo hello > /tmp/awacate.out", - "can_delete": true, - "can_edit": true, - "can_run": true, - "enable": true, - "id": 11, - "name": "TEST_CRONTAB", - "next_trigger_time": "2024-09-10 00:00", - "owner": "root", - "real_owner": "root", - "type": "script" - } - ] - "total": 2 - }, - "success": true - } - ``` + """ + List all present scheduled tasks and event triggered tasks. + + Parameters + ---------- + sort_by : str, optional + The field to sort tasks by. Defaults to `"next_trigger_time"`. + + Possible values: + - "next_trigger_time" + - "name" + - "type" + - "action" + - "owner" + + sort_direction : str, optional + The sort direction. Defaults to `"ASC"`. + + Possible values: + - "ASC" + - "DESC" + + offset : int, optional + Task offset for pagination. Defaults to `0`. + + limit : int, optional + Number of tasks to retrieve. Defaults to `50`. + + Returns + ------- + dict[str, object] + A dictionary containing a list of the tasks and information related to them. + + Examples + -------- + ```json + { + "data": { + "tasks": [ + { + "action": "Run: rsync -aP --delete /volume1/test/ /volume1/test2/", + "can_delete": true, + "can_edit": true, + "can_run": true, + "enable": false, + "id": 13, + "name": "Sync folders", + "next_trigger_time": "2024-09-09 12:26", + "owner": "root", + "real_owner": "root", + "type": "script" + }, + { + "action": "Run: echo hello > /tmp/awacate.out", + "can_delete": true, + "can_edit": true, + "can_run": true, + "enable": true, + "id": 11, + "name": "TEST_CRONTAB", + "next_trigger_time": "2024-09-10 00:00", + "owner": "root", + "real_owner": "root", + "type": "script" + } + ] + "total": 2 + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.TaskScheduler' info = self.gen_list[api_name] @@ -236,68 +329,67 @@ def get_task_config( real_owner: str, type: str = '' ) -> dict[str, object]: - """Retrieve the configuration for a specific task or list of all the available services and their corresponding IDs. - - Parameters - ---------- - task_id : int - The ID of the task to retrieve the configuration for. Pass `-1` to get a list of all available services with their IDs. - - real_owner : str - The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. - - type : str, optional - The type of task (e.g., 'service'). Pass "service" to get a list of all available services with their IDs. Defaults to `""`. - - Returns - ------- - dict[str, object] - A dictionary containing the task configuration. - - Examples - -------- - ```json - { - "data": { - "action": "Run: echo hello > /tmp/awacate.out", - "can_edit_name": true, - "can_edit_owner": true, - "enable": true, - "extra": { - "notify_enable": false, - "notify_if_error": false, - "notify_mail": "", - "script": "echo hello > /tmp/awacate.out" - }, - "id": 11, - "name": "TEST_CRONTAB", - "owner": "root", - "real_owner": "root", - "schedule": { - "date": "2024/9/11", - "date_type": 0, - "hour": 0, - "last_work_hour": 0, - "minute": 0, - "monthly_week": [], - "repeat_date": 1001, - "repeat_hour": 0, - "repeat_hour_store_config": [ - 1..23 - ], - "repeat_min": 0, - "repeat_min_store_config": [ - 1, - ... - ], - "version": 4, - "week_day": "0,1,2,3,4,5,6" - }, - "type": "script" + """ + Retrieve the configuration for a specific task or list all available services and their corresponding IDs. + + Parameters + ---------- + task_id : int + The ID of the task to retrieve the configuration for. Pass `-1` to get a list of all available services with their IDs. + real_owner : str + The real owner of the task, usually `root`. You can double check from the result of `get_task_config()`. + type : str, optional + The type of task (e.g., 'service'). Pass `"service"` to get a list of all available services with their IDs. Defaults to `""`. + + Returns + ------- + dict[str, object] + A dictionary containing the task configuration. + + Examples + -------- + ```json + { + "data": { + "action": "Run: echo hello > /tmp/awacate.out", + "can_edit_name": true, + "can_edit_owner": true, + "enable": true, + "extra": { + "notify_enable": false, + "notify_if_error": false, + "notify_mail": "", + "script": "echo hello > /tmp/awacate.out" }, - "success": true - } - ``` + "id": 11, + "name": "TEST_CRONTAB", + "owner": "root", + "real_owner": "root", + "schedule": { + "date": "2024/9/11", + "date_type": 0, + "hour": 0, + "last_work_hour": 0, + "minute": 0, + "monthly_week": [], + "repeat_date": 1001, + "repeat_hour": 0, + "repeat_hour_store_config": [ + 1..23 + ], + "repeat_min": 0, + "repeat_min_store_config": [ + 1, + ... + ], + "version": 4, + "week_day": "0,1,2,3,4,5,6" + }, + "type": "script" + }, + "success": true + } + ``` """ api_name = 'SYNO.Core.TaskScheduler' info = self.gen_list[api_name] @@ -318,41 +410,42 @@ def get_task_results( self, task_id: int ) -> dict[str, object]: - """Retrieve the results list for a specific task. - - Parameters - ---------- - task_id : int - The ID of the task to retrieve the results for. - - Returns - ------- - dict[str, object] - A dictionary containing the task results. - - Examples - -------- - ```json - { - "data": [ - { - "exit_code": 127, - "exit_type": "by_signal", - "start_time": "2024-09-11 00:00:01", - "stop_time": "2024-09-11 00:00:06", - "timestamp": "1726005601" - }, - { - "exit_code": 0, - "exit_type": "normal", - "start_time": "2024-06-01 00:00:01", - "stop_time": "2024-06-01 00:00:02", - "timestamp": "1717192801" - } - ], - "success": true - } - ``` + """ + Retrieve the results list for a specific task. + + Parameters + ---------- + task_id : int + The ID of the task to retrieve the results for. + + Returns + ------- + dict[str, object] + A dictionary containing the task results. + + Examples + -------- + ```json + { + "data": [ + { + "exit_code": 127, + "exit_type": "by_signal", + "start_time": "2024-09-11 00:00:01", + "stop_time": "2024-09-11 00:00:06", + "timestamp": "1726005601" + }, + { + "exit_code": 0, + "exit_type": "normal", + "start_time": "2024-06-01 00:00:01", + "stop_time": "2024-06-01 00:00:02", + "timestamp": "1717192801" + } + ], + "success": true + } + ``` """ api_name = 'SYNO.Core.TaskScheduler' info = self.gen_list[api_name] @@ -414,7 +507,8 @@ def set_output_config( enable_output: bool, output_path: str = '' ) -> dict[str, object]: - """Configure the output settings for tasks results. + """ + Configure the output settings for tasks results. Parameters ---------- @@ -422,7 +516,7 @@ def set_output_config( Whether to enable result logging or not. output_path : str, optional - The path where the result logs will be stored, e.g. `share/scripts_output'`. Defaults to `""`. + The path where the result logs will be stored, e.g. `share/scripts_output`. Defaults to `""`. Returns ------- @@ -456,7 +550,8 @@ def task_set_enable( real_owner: str, enable: bool ) -> dict[str, object]: - """Enable or disable a task. + """ + Enable or disable a task. Parameters ---------- @@ -504,7 +599,8 @@ def task_run( task_id: int, real_owner: str ) -> dict[str, object]: - """Run a specific task. + """ + Run a specific task. Parameters ---------- @@ -548,7 +644,8 @@ def task_delete( task_id: int, real_owner: str ) -> dict[str, object]: - """Delete a specific task. + """ + Delete a specific task. Parameters ---------- @@ -606,7 +703,8 @@ def create_script_task( notify_email: str = '', notify_only_on_error: bool = False ) -> dict[str, object]: - """Create a new Script task with the provided schedule and notification settings. + """ + Create a new Script task with the provided schedule and notification settings. Tip: If the task needs to run with root privileges, please specify the owner as "root". @@ -753,7 +851,8 @@ def modify_script_task( notify_email: str = '', notify_only_on_error: bool = False ) -> dict[str, object]: - """Modify settings of a Script task. + """ + Modify settings of a Script task. Warning: This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. @@ -901,88 +1000,74 @@ def create_beep_control_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Create a new Beep Control task with the provided schedule and beep duration. - - Parameters - ---------- - task_name : str - The name of the task. - - owner : str - The task owner. - - beep_duration : int, optional - The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. - - enable : bool, optional - Whether the task should be enabled upon creation. Defaults to `True`. - - run_frequently : bool, optional - Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. - - run_days : str, optional - Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). - - run_date : str, optional - The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. - - repeat : str, optional - How often the task should repeat. Defaults to `'daily'`. - - Possible values: - - `daily` -> Only when 'run_frequently=True' - - `weekly` -> Only when 'run_frequently=True' - - `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' - - `no_repeat` -> Only when 'run_frequently=False' - - `every_3_months` -> Only when 'run_frequently=False' - - `every_6_months` -> Only when 'run_frequently=False' - - `yearly` -> Only when 'run_frequently=False' - - - monthly_week : list[str], optional - If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. - Defaults to `[]`. - - start_time_h : int, optional - Hour at which the task should start. Defaults to `0`. - - start_time_m : int, optional - Minute at which the task should start. Defaults to `0`. - - same_day_repeat_h : int, optional - Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. - Set to `0` to disable same-day repeats. Defaults to `0`. - - Possible values: `0..23` - - The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_m : int, optional - Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. - Set to `0` to disable same-day repeats. Defaults to `0`. - - Posible values: `1`, `5`, `10`, `15`, `20`, `30` - - The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_until : int, optional - Last hour of the day when the task can repeat. Defaults to `start_time_h`. - - Returns - ------- - dict[str, object] - A dictionary with the id of the created task. - - Examples - -------- - ```json - { - "data": { - "id": 20 - }, - "success": true - } - ``` + """ + Create a new Beep Control task with the provided schedule and beep duration. + + Parameters + ---------- + task_name : str + The name of the task. + owner : str + The task owner. + enable : bool, optional + Whether the task should be enabled upon creation. Defaults to True. + beep_duration : int, optional + The amount of seconds the beep will be triggered for. Defaults to 60. + run_frequently : bool, optional + Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to True. + run_days : str, optional + Days of the week when the task should run, used if `run_frequently` is set to True, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to '0,1,2,3,4,5,6'. + run_date : str, optional + The specific date the task should run, used if `run_frequently` is set to False. Format: yyyy/m/d (no prefix zeros). Defaults to "". + repeat : str, optional + How often the task should repeat. Defaults to 'daily'. + + Possible values: + - 'daily' -> Only when run_frequently=True + - 'weekly' -> Only when run_frequently=True + - 'monthly' -> Works for both run_frequently=True and run_frequently=False + - 'no_repeat' -> Only when run_frequently=False + - 'every_3_months' -> Only when run_frequently=False + - 'every_6_months' -> Only when run_frequently=False + - 'yearly' -> Only when run_frequently=False + monthly_week : list[str], optional + If run_frequently=True and repeat='monthly', specifies the weeks the task should run, e.g., ['first', 'third']. Defaults to []. + start_time_h : int, optional + Hour at which the task should start. Defaults to 0. + start_time_m : int, optional + Minute at which the task should start. Defaults to 0. + same_day_repeat_h : int, optional + Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. + Set to 0 to disable same-day repeats. Defaults to 0. + + Possible values: 0..23 + + The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time, if both are passed, same_day_repeat_h will be prioritized. + same_day_repeat_m : int, optional + Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. + Set to 0 to disable same-day repeats. Defaults to 0. + + Possible values: 1, 5, 10, 15, 20, 30 + + The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time, if both are passed, same_day_repeat_h will be prioritized. + same_day_repeat_until : int, optional + Last hour of the day when the task can repeat. Defaults to start_time_h. + + Returns + ------- + dict[str, object] + A dictionary with the id of the created task. + + Examples + -------- + ```json + { + "data": { + "id": 20 + }, + "success": true + } + ``` """ schedule = _Schedule(run_frequently, run_days, run_date, repeat, monthly_week, start_time_h, start_time_m, @@ -1028,92 +1113,82 @@ def modify_beep_control_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Modify settings of a Beep Control task. - - Warning: This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. - - Parameters - ---------- - task_name : str - The name of the task. - - real_owner : str - The task owner. - - beep_duration : int, optional - The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. - - enable : bool, optional - Whether the task should be enabled upon creation. Defaults to `True`. - - run_frequently : bool, optional - Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. - - run_days : str, optional - Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). - - run_date : str, optional - The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. - - repeat : str, optional - How often the task should repeat. Defaults to `'daily'`. - - Possible values: - - `daily` -> Only when 'run_frequently=True' - - `weekly` -> Only when 'run_frequently=True' - - `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' - - `no_repeat` -> Only when 'run_frequently=False' - - `every_3_months` -> Only when 'run_frequently=False' - - `every_6_months` -> Only when 'run_frequently=False' - - `yearly` -> Only when 'run_frequently=False' - - monthly_week : list[str], optional - If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. - - start_time_h : int, optional - Hour at which the task should start. Defaults to `0`. - - start_time_m : int, optional - Minute at which the task should start. Defaults to `0`. - - same_day_repeat_h : int, optional - Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0`. - - Possible values: `0..23` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_m : int, optional - Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0`. - - Posible values: `1`, `5`, `10`, `15`, `20`, `30` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_until : int, optional - Last hour of the day when the task can repeat. Defaults to `start_time_h`. - - Returns - ------- - dict[str, object] - A dictionary with the id of the created task. - - Examples - -------- - ```json - { - "data": { - "id": 20 - }, - "success": true - } - ``` """ - + Modify settings of a Beep Control task. + + Parameters + ---------- + task_id : int + The ID of the task to modify. + task_name : str + The name of the task. + real_owner : str + The task owner. + enable : bool, optional + Whether the task should be enabled upon modification. Defaults to `True`. + beep_duration : int, optional + The amount of seconds the beep will be triggered for, in seconds. Defaults to `60`. + run_frequently : bool, optional + Determines whether the task runs on a recurring schedule (`True`) or only on a specific date (`False`). Defaults to `True`. + run_days : str, optional + Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). + run_date : str, optional + The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. + repeat : str, optional + How often the task should repeat. Defaults to `'daily'`. + + Possible values: + - `daily` -> Only when `run_frequently=True` + - `weekly` -> Only when `run_frequently=True` + - `monthly` -> Works for both `run_frequently=True` and `run_frequently=False` + - `no_repeat` -> Only when `run_frequently=False` + - `every_3_months` -> Only when `run_frequently=False` + - `every_6_months` -> Only when `run_frequently=False` + - `yearly` -> Only when `run_frequently=False` + monthly_week : list[str], optional + If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to `[]`. + start_time_h : int, optional + Hour at which the task should start. Defaults to `0`. + start_time_m : int, optional + Minute at which the task should start. Defaults to `0`. + same_day_repeat_h : int, optional + Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. + Set to `0` to disable same-day repeats. Defaults to `0`. + + Possible values: `0..23` + + Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + same_day_repeat_m : int, optional + Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. + Set to `0` to disable same-day repeats. Defaults to `0`. + + Possible values: `1`, `5`, `10`, `15`, `20`, `30` + + Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + same_day_repeat_until : int, optional + Last hour of the day when the task can repeat. Defaults to `start_time_h`. + + Returns + ------- + dict[str, object] + A dictionary with the id of the modified task. + + Notes + ----- + Warning: This method overwrites all the settings of the task, so if you only want to change one setting, + you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. + + Examples + -------- + ```json + { + "data": { + "id": 20 + }, + "success": true + } + ``` + """ schedule = _Schedule(run_frequently, run_days, run_date, repeat, monthly_week, start_time_h, start_time_m, same_day_repeat_h, same_day_repeat_m, same_day_repeat_until) @@ -1157,7 +1232,8 @@ def create_service_control_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Create a new Service Control task with the provided schedule and services to start/stop. + """ + Create a new Service Control task with the provided schedule and services to start/stop. Parameters ---------- @@ -1167,7 +1243,7 @@ def create_service_control_task( owner : str The task owner. - services (list): + services : list[dict] A list containing the services and their type to be influenced by the specified action (start / stop). To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. @@ -1309,7 +1385,8 @@ def modify_service_control_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Modify settings of a Service Control task. + """ + Modify settings of a Service Control task. Warning: This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. @@ -1324,7 +1401,7 @@ def modify_service_control_task( real_owner : str The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. - services (list): + services : list[dict] A list containing the services and their type to be influenced by the specified action (start / stop). To get a list of all the available services and their corresponding IDs, call `get_task_config(task_id=-1, real_owner=your_username, type='service')`. @@ -1468,95 +1545,76 @@ def create_recycle_bin_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Create a new Recycle Bin Control task with the provided schedule and services to start/stop. - - Parameters - ---------- - task_name : str - The name of the task. - - owner : str - The task owner. - - clean_all_shares : bool - Whether the task should empty the recycle bins of all shares or not, if set to `False`, shares must be specified. - - shares : list[str], optional - List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to `[]`. - - policy (dict): - Determines what files will be deleted from the recycle bins. - - Possible values are: - - `{"policy": "clean_all"}` -> Clean all files - - `{"policy": "time", "time": int}` -> Clean all files older than X days, days being possed as value for "time" key. - - `{"policy": "size", "size": int , "sort_type": int}` -> Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". - - Possible values for "sort_type" are: - - `0` -> Delete bigger files first - - `1` -> Delete older files first - - enable : bool, optional - Whether the task should be enabled upon creation. Defaults to `True`. - - run_frequently : bool, optional - Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. - - run_days : str, optional - Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). - - run_date : str, optional - The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). - Defaults to `""`. - - repeat : str, optional - How often the task should repeat. Defaults to `'daily'`. - - Possible values: - - `daily` -> Only when 'run_frequently=True' - - `weekly` -> Only when 'run_frequently=True' - - `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' - - `no_repeat` -> Only when 'run_frequently=False' - - `every_3_months` -> Only when 'run_frequently=False' - - `every_6_months` -> Only when 'run_frequently=False' - - `yearly` -> Only when 'run_frequently=False' - - monthly_week : list[str], optional - If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. - - Defaults to `[]`. - - start_time_h : int, optional - Hour at which the task should start. Defaults to `0`. - - start_time_m : int, optional - Minute at which the task should start. Defaults to `0`. - - same_day_repeat_h : int, optional - Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). - - Possible values: `0..23` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_m : int, optional - Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). - - Posible values: `1`, `5`, `10`, `15`, `20`, `30` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_until : int, optional - Last hour of the day when the task can repeat. Defaults to `start_time_h`. - - Returns - ------- - dict[str, object] - A dictionary with the id of the created task. + """ + Create a new Recycle Bin Control task with the provided schedule and policy. + + Parameters + ---------- + task_name : str + The name of the task. + owner : str + The task owner. + clean_all_shares : bool + Whether the task should empty the recycle bins of all shares. If set to False, `shares` must be specified. + policy : dict + Determines what files will be deleted from the recycle bins. + + Possible values are: + - \\{"policy": "clean_all"\\}: Clean all files. + - \\{"policy": "time", "time": int\\}: Clean all files older than X days, where X is the value for "time". + - \\{"policy": "size", "size": int, "sort_type": int\\}: Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". + + Possible values for "sort_type": + - 0: Delete bigger files first. + - 1: Delete older files first. + shares : list[str], optional + List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to []. + enable : bool, optional + Whether the task should be enabled upon creation. Defaults to True. + run_frequently : bool, optional + Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to True. + run_days : str, optional + Days of the week when the task should run, used if `run_frequently` is True, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to '0,1,2,3,4,5,6'. + run_date : str, optional + The specific date the task should run, used if `run_frequently` is False. Format: yyyy/m/d (no prefix zeros). Defaults to "". + repeat : str, optional + How often the task should repeat. Defaults to 'daily'. + + Possible values: + - 'daily' (only when run_frequently=True) + - 'weekly' (only when run_frequently=True) + - 'monthly' (works for both run_frequently=True and run_frequently=False) + - 'no_repeat' (only when run_frequently=False) + - 'every_3_months' (only when run_frequently=False) + - 'every_6_months' (only when run_frequently=False) + - 'yearly' (only when run_frequently=False) + monthly_week : list[str], optional + If run_frequently=True and repeat='monthly', specifies the weeks the task should run, e.g., ['first', 'third']. Defaults to []. + start_time_h : int, optional + Hour at which the task should start. Defaults to 0. + start_time_m : int, optional + Minute at which the task should start. Defaults to 0. + same_day_repeat_h : int, optional + Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. + Set to 0 to disable same-day repeats. Defaults to 0. + + Possible values: 0..23 + + Note: The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time; if both are passed, same_day_repeat_h will be prioritized. + same_day_repeat_m : int, optional + Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. + Set to 0 to disable same-day repeats. Defaults to 0. + + Possible values: 1, 5, 10, 15, 20, 30 + + Note: The args same_day_repeat_h and same_day_repeat_m cannot be used at the same time; if both are passed, same_day_repeat_h will be prioritized. + same_day_repeat_until : int, optional + Last hour of the day when the task can repeat. Defaults to start_time_h. + + Returns + ------- + dict[str, object] + A dictionary with the id of the created task. Examples -------- @@ -1621,111 +1679,94 @@ def modify_recycle_bin_task( same_day_repeat_m: int = 0, same_day_repeat_until: int = -1 ) -> dict[str, object]: - """Modify settings of a Recycle Bin Control task. - - Warning: This method overwrites all the settings of the task, so if you only want to change one setting, you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. - - Parameters - ---------- - task_id : int - The ID of the task. - - task_name : str - The name of the task. - - real_owner : str - The task real owner, usually it is `root`, you can double check from the result of `get_task_config()`. - - clean_all_shares : bool - Whether the task should empty the recycle bins of all shares or not, if set to `False`, shares must be specified. - - shares : list[str], optional - List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to `[]`. - - policy (dict): - Determines what files will be deleted from the recycle bins. - - Possible values are: - - `{"policy": "clean_all"}` -> Clean all files - - `{"policy": "time", "time": int}` -> Clean all files older than X days, days being possed as value for "time" key. - - `{"policy": "size", "size": int , "sort_type": int}` -> Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". - - Possible values for "sort_type" are: - - `0` -> Delete bigger files first - - `1` -> Delete older files first - - enable : bool, optional - Whether the task should be enabled upon creation. Defaults to `True`. - - run_frequently : bool, optional - Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. - - run_days : str, optional - Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'` (Daily). - - run_date : str, optional - The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). - Defaults to `""`. - - repeat : str, optional - How often the task should repeat. Defaults to `'daily'`. - - Possible values: - - `daily` -> Only when 'run_frequently=True' - - `weekly` -> Only when 'run_frequently=True' - - `monthly` -> Works for both 'run_frequently=True' and 'run_frequently=False' - - `no_repeat` -> Only when 'run_frequently=False' - - `every_3_months` -> Only when 'run_frequently=False' - - `every_6_months` -> Only when 'run_frequently=False' - - `yearly` -> Only when 'run_frequently=False' - - monthly_week : list[str], optional - If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. - - Defaults to `[]`. - - start_time_h : int, optional - Hour at which the task should start. Defaults to `0`. - - start_time_m : int, optional - Minute at which the task should start. Defaults to `0`. - - same_day_repeat_h : int, optional - Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). - - Possible values: `0..23` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_m : int, optional - Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. - - Set to `0` to disable same-day repeats. Defaults to `0` (disable same day repeat). - - Posible values: `1`, `5`, `10`, `15`, `20`, `30` - - Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. - - same_day_repeat_until : int, optional - Last hour of the day when the task can repeat. Defaults to `start_time_h`. - - Returns - ------- - dict[str, object] - A dictionary with the id of the created task. - - Examples - -------- - ```json - { - "data": { - "id": 20 - }, - "success": true - } - ``` + """ + Modify settings of a Recycle Bin Control task. + + Parameters + ---------- + task_id : int + The ID of the task. + task_name : str + The name of the task. + real_owner : str + The task real owner, usually it is `root`. You can double check from the result of `get_task_config()`. + clean_all_shares : bool + Whether the task should empty the recycle bins of all shares. If set to `False`, `shares` must be specified. + policy : dict + Determines what files will be deleted from the recycle bins. + + Possible values are: + - \\{"policy": "clean_all"\\}: Clean all files. + - \\{"policy": "time", "time": int\\}: Clean all files older than X days, where X is the value for "time". + - \\{"policy": "size", "size": int, "sort_type": int\\}: Clean files until recycle bin size reaches given "size" in MB, delete files by "sort_type". + + Possible values for "sort_type": + - 0: Delete bigger files first. + - 1: Delete older files first. + shares : list[str], optional + List of shares of which to clean the recycle bins. Pass only the name of the shares without slashes, e.g. `shares=['photo', 'web']`. Defaults to []. + enable : bool, optional + Whether the task should be enabled upon modification. Defaults to `True`. + run_frequently : bool, optional + Determines whether the task runs on a recurring schedule (True) or only on a specific date (False). Defaults to `True`. + run_days : str, optional + Days of the week when the task should run, used if `run_frequently` is set to `True`, specified as a comma-separated list (e.g., '0,1,2' for Sunday, Monday, Tuesday). Defaults to `'0,1,2,3,4,5,6'`. + run_date : str, optional + The specific date the task should run, used if `run_frequently` is set to `False`. Format: `yyyy/m/d` (no prefix zeros). Defaults to `""`. + repeat : str, optional + How often the task should repeat. Defaults to `'daily'`. + + Possible values: + - `daily` (only when run_frequently=True) + - `weekly` (only when run_frequently=True) + - `monthly` (works for both run_frequently=True and run_frequently=False) + - `no_repeat` (only when run_frequently=False) + - `every_3_months` (only when run_frequently=False) + - `every_6_months` (only when run_frequently=False) + - `yearly` (only when run_frequently=False) + monthly_week : list[str], optional + If `run_frequently=True` and `repeat='monthly'`, specifies the weeks the task should run, e.g., `['first', 'third']`. Defaults to []. + start_time_h : int, optional + Hour at which the task should start. Defaults to `0`. + start_time_m : int, optional + Minute at which the task should start. Defaults to `0`. + same_day_repeat_h : int, optional + Number of hours between repeated executions on the same day (run every x hours), if "Continue running within the same day" is desired. + Set to `0` to disable same-day repeats. Defaults to `0`. + + Possible values: `0..23` + + Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + same_day_repeat_m : int, optional + Number of minutes between repeated executions on the same day (run every x minutes), if "Continue running within the same day" is desired. + Set to `0` to disable same-day repeats. Defaults to `0`. + + Possible values: `1`, `5`, `10`, `15`, `20`, `30` + + Info: The args `same_day_repeat_h` and `same_day_repeat_m` cannot be used at the same time, if both are passed, `same_day_repeat_h` will be prioritized. + same_day_repeat_until : int, optional + Last hour of the day when the task can repeat. Defaults to `start_time_h`. + + Returns + ------- + dict[str, object] + A dictionary with the id of the modified task. + + Notes + ----- + Warning: This method overwrites all the settings of the task, so if you only want to change one setting, + you can fetch the current task configuration with `get_task_config()` and pass all the settings to this method. + + Examples + -------- + ```json + { + "data": { + "id": 20 + }, + "success": true + } + ``` """ schedule = _Schedule(run_frequently, run_days, run_date, repeat, monthly_week, start_time_h, start_time_m, diff --git a/synology_api/universal_search.py b/synology_api/universal_search.py index 2605c7cb..b2d1ba4e 100644 --- a/synology_api/universal_search.py +++ b/synology_api/universal_search.py @@ -1,11 +1,30 @@ +"""Synology Universal Search API Wrapper.""" from __future__ import annotations from typing import Optional, Any from . import base_api class UniversalSearch(base_api.BaseApi): + """ + API wrapper for Synology Universal Search. + + Provides methods to perform keyword-based searches using Synology's Universal Search API. + """ def search(self, keyword: str) -> dict[str, object] | str: + """ + Search for files and metadata matching the given keyword. + + Parameters + ---------- + keyword : str + The search keyword. + + Returns + ------- + dict[str, object] or str + Search results as a dictionary, or a string with error details. + """ api_name = 'SYNO.Finder.FileIndexing.Search' info = self.gen_list[api_name] api_path = info['path'] diff --git a/synology_api/usb_copy.py b/synology_api/usb_copy.py index d318dd42..9390893a 100644 --- a/synology_api/usb_copy.py +++ b/synology_api/usb_copy.py @@ -1,42 +1,45 @@ +"""USB Copy API wrapper for Synology NAS.""" from __future__ import annotations from typing import Optional from . import base_api class USBCopy(base_api.BaseApi): - """USB Copy Implementation. + """ + USB Copy API wrapper for Synology NAS. - Supported methods: - - Getters: - - Get package settings - - Get package logs - - Get task settings + Methods + ------- + Getters: + - Get package settings + - Get package logs + - Get task settings - - Actions: - - Enable / Disable task + Actions: + - Enable / Disable task """ def get_package_settings(self) -> dict[str, object]: - """Retrieve package settings. + """ + Retrieve package settings. - Returns - ------- - dict[str, object] - Parsed JSON into `dict` + Returns + ------- + dict[str, object] + Parsed JSON into a dictionary. - Examples - -------- - ```python + Examples + -------- + ```python { - "data" : { - "beep_on_task_start_end" : True, - "log_rotate_count" : 100000, - "repo_volume_path" : "/volume2" + "data": { + "beep_on_task_start_end": True, + "log_rotate_count": 100000, + "repo_volume_path": "/volume2" }, - "success" : True + "success": True } - ``` - + ``` """ api_name = 'SYNO.USBCopy' info = self.gen_list[api_name] @@ -47,42 +50,41 @@ def get_package_settings(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def get_package_logs(self, offset: int = 0, limit: int = 200) -> dict[str, object]: - """Retrieve package logs. - - Parameters - ---------- - offset : int - Defaults to `0`. - - limit : int - Defaults to `200`. - - Returns - ------- - dict[str, object] - Parsed response JSON into `dict` - - Examples - -------- - ```python + """ + Retrieve package logs. + + Parameters + ---------- + offset : int, optional + Offset for logs. Defaults to 0. + limit : int, optional + Maximum number of logs to retrieve. Defaults to 200. + + Returns + ------- + dict[str, object] + Parsed response JSON into a dictionary. + + Examples + -------- + ```python { - "data" : { - "count" : 1, - "log_list" : [ + "data": { + "count": 1, + "log_list": [ { - "description_id" : 101, - "description_parameter" : "[\"asdf\"]", - "error" : 0, - "log_type" : 1, - "task_id" : 2, - "timestamp" : 1738341351 - }, + "description_id": 101, + "description_parameter": "[\"asdf\"]", + "error": 0, + "log_type": 1, + "task_id": 2, + "timestamp": 1738341351 + } ] }, - "success" : True + "success": True } - ``` - + ``` """ api_name = 'SYNO.USBCopy' info = self.gen_list[api_name] @@ -93,57 +95,57 @@ def get_package_logs(self, offset: int = 0, limit: int = 200) -> dict[str, objec return self.request_data(api_name, api_path, req_param) def get_task_settings(self, task_id: int) -> dict[str, object]: - """Retrieve task settings + """ + Retrieve task settings. - Parameters - ---------- - task_id: int - Task ID to retrieve info for + Parameters + ---------- + task_id : int + Task ID to retrieve info for. - Returns - ------- - dict[str, object] - Parsed response JSON into `dict` + Returns + ------- + dict[str, object] + Parsed response JSON into a dictionary. - Examples - -------- - ```python + Examples + -------- + ```python { - "data" : { - "task" : { - "conflict_policy" : "rename", - "copy_file_path" : "", - "copy_strategy" : "versioning", - "default_device_port" : "NA", - "destination_path" : "[USB]", - "eject_when_task_done" : True, - "enable_rotation" : False, - "error_code" : 0, - "id" : 2, - "is_default_task" : False, - "is_ds_mounted" : False, - "is_task_runnable" : False, - "is_usb_mounted" : False, - "latest_finish_time" : 1738341351, - "max_version_count" : 256, - "name" : "asdf", - "next_run_time" : "N/A", - "not_keep_dir_structure" : False, - "remove_src_file" : False, - "rename_photo_video" : False, - "rotation_policy" : "oldest_version", - "run_when_plug_in" : False, - "schedule_id" : 13, - "smart_create_date_dir" : False, - "source_path" : "/music", - "status" : "unmounted", - "type" : "export_general" + "data": { + "task": { + "conflict_policy": "rename", + "copy_file_path": "", + "copy_strategy": "versioning", + "default_device_port": "NA", + "destination_path": "[USB]", + "eject_when_task_done": True, + "enable_rotation": False, + "error_code": 0, + "id": 2, + "is_default_task": False, + "is_ds_mounted": False, + "is_task_runnable": False, + "is_usb_mounted": False, + "latest_finish_time": 1738341351, + "max_version_count": 256, + "name": "asdf", + "next_run_time": "N/A", + "not_keep_dir_structure": False, + "remove_src_file": False, + "rename_photo_video": False, + "rotation_policy": "oldest_version", + "run_when_plug_in": False, + "schedule_id": 13, + "smart_create_date_dir": False, + "source_path": "/music", + "status": "unmounted", + "type": "export_general" } }, - "success" : True + "success": True } - ``` - + ``` """ api_name = 'SYNO.USBCopy' info = self.gen_list[api_name] @@ -154,29 +156,28 @@ def get_task_settings(self, task_id: int) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def toggle_task(self, task_id: int, enable: bool = True) -> dict[str, object]: - """Enable or disable USB Copy task - - Parameters - ---------- - task_id : int - Task ID to apply the setting to. - - enable : bool - Whether to enable (`True`) or disable (`False`) USB Copy. Defaults to `True`. - - Returns - ------- - dict[str, object] - Parsed response JSON into `dict` - - Examples - -------- - ```python + """ + Enable or disable a USB Copy task. + + Parameters + ---------- + task_id : int + Task ID to apply the setting to. + enable : bool, optional + Whether to enable (True) or disable (False) the USB Copy task. Defaults to True. + + Returns + ------- + dict[str, object] + Parsed response JSON into a dictionary. + + Examples + -------- + ```python { "success": True } - ``` - + ``` """ api_name = 'SYNO.USBCopy' info = self.gen_list[api_name] diff --git a/synology_api/utils.py b/synology_api/utils.py index cc2e8aa2..ffa27e26 100644 --- a/synology_api/utils.py +++ b/synology_api/utils.py @@ -1,10 +1,35 @@ +"""Utility functions for Synology API operations.""" import json +import mimetypes +import re +import secrets import sys # my_package/my_module.py -__all__ = ['merge_dicts', 'make_folder_meta_list_from_path', 'parse_config'] +__all__ = ['merge_dicts', 'make_folder_meta_list_from_path', + 'get_data_for_request_from_file', 'generate_gecko_boundary', 'validate_path'] + +from pathlib import Path + +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor +from tqdm import tqdm def merge_dicts(x, y): + """ + Merge two dictionaries. + + Parameters + ---------- + x : dict + The first dictionary. + y : dict + The second dictionary. + + Returns + ------- + dict + A new dictionary containing the merged keys and values from both input dictionaries. + """ z = x.copy() # start with keys and values of x z.update(y) # modifies z with keys and values of y return z @@ -14,11 +39,15 @@ def make_folder_meta_list_from_path(path): """ Create a list of folder metadata dictionaries from a given path. - Args: - path (str): The file path to be split into folder metadata. + Parameters + ---------- + path : str + The file path to be split into folder metadata. - Returns: - list: A list of dictionaries containing folder metadata. + Returns + ------- + list of dict + A list of dictionaries containing folder metadata for each folder in the path. """ folder_list = [] path_list = path.split('/') # Split the path into components @@ -36,3 +65,159 @@ def make_folder_meta_list_from_path(path): }) return folder_list + + +def get_data_for_request_from_file(file_path: str, + fields: dict[str, str | tuple], + progress_bar: bool = True, + called_from: str = 'DownloadStation'): + """ + Build and return a ``MultipartEncoder`` or a ``MultipartEncoderMonitor`` to upload a file via ``request_data`` (POST multipart/form-data). + + Parameters + ---------- + file_path : str + The file path to be parsed. + fields : dict[str, str | tuple] + Dictionary of form fields used to build the multipart payload. + Each key represents a form field name. + The value can be: + - a string (for standard text fields) + - a tuple ``(filename, fileobj, mimetype)`` for file fields. + progress_bar : bool + Whether to show a progress bar when uploading file or not. + called_from : str + The name of the calling class. (ex 'FileStation') + + Returns + ------- + MultipartEncoder | MultipartEncoderMonitor + The multipart payload object to pass to your HTTP client. When a monitor is returned, + access its underlying encoder via ``monitor.encoder`` and supply + ``headers = {"Content-Type": monitor.content_type}`` (or ``encoder.content_type``). + """ + + p = Path(file_path).expanduser().resolve() + if not p.is_file(): + raise FileNotFoundError(f"File not found: {p}") + + size_value = p.stat().st_size + boundary = generate_gecko_boundary() + fields["size"] = str(size_value) + mime_type, _ = mimetypes.guess_type(p.name) + mime_type = mime_type or "application/octet-stream" + + if called_from == 'DownloadStation': + fields["torrent"] = (p.name, p.open("rb"), mime_type) + elif called_from == 'FileStation': + fields["files"] = (p.name, p.open("rb"), mime_type) + + encoder = MultipartEncoder(fields=fields, boundary=boundary) + print(encoder) + if progress_bar: + pbar = tqdm(total=encoder.len, unit="B", unit_scale=True, + unit_divisor=1024, desc="Upload Progress") + monitor = MultipartEncoderMonitor( + encoder, lambda m: pbar.update(m.bytes_read - pbar.n) + ) + return monitor + return encoder + + +def generate_gecko_boundary(): + """ + Generate a boundary for MultiPartEncoder. + + Returns + ------- + str: + The random boundary ----geckoformboundary{random_hex} for the MultiPartEncoder. + """ + random_hex = secrets.token_hex(16) # 16 byte = 32 caratteri esadecimali + return f"----geckoformboundary{random_hex}" + + +def validate_path(path: str | list[str]) -> bool: + """ + Validate the format of a Synology FileStation path. + + The function checks whether a given path string (or list of paths) follows + the basic formatting rules required by Synology FileStation APIs. + + Parameters + ---------- + path : str or list of str + The path or list of paths to validate. Each path can represent + either a file or directory. + + Returns + ------- + bool + True if the path (or all paths in the list) are valid according to + FileStation rules, False otherwise. + + Notes + ----- + - Must start with a forward slash ('/'). + - Must not contain any of the forbidden characters: * ? " < > | + - May contain internal spaces (e.g., '/My Folder/file name.txt'). + - Must not end with a space, tab, or slash. + - If the path contains a file extension, no spaces or characters are allowed + after the last period (e.g., '/Media/script.log extra' is invalid). + - Optionally allows paths without extensions (e.g., '/Media/script'). + + Examples + -------- + >>> validate_path('/Downloads/script.log') + True + >>> validate_path('/Downloads/script log.txt') + True + >>> validate_path('/Downloads/script') + True + >>> validate_path('/Downloads/script.log extra') + False + >>> validate_path('/Downloads/script.log ') + False + >>> validate_path('/Downloads/folder/') + False + >>> validate_path('Downloads/script.log') + False + """ + + def _is_valid(single_path: str) -> bool: + """ + Validate a single Synology FileStation path. + + Parameters + ---------- + single_path : str + The path to validate. + + Returns + ------- + bool + True if the given path is a valid Synology FileStation path. + """ + path_pattern = re.compile(r'^/[^*?"<>|]+$') + if not isinstance(single_path, str): + return False + + if not path_pattern.match(single_path): + return False + + if path[-1] in (' ', '\t', '/'): + return False + + parts = single_path.rsplit('.', 1) + if len(parts) == 2 and ' ' in parts[1]: + return False + + return True + + if isinstance(path, str): + return _is_valid(path) + + if isinstance(path, list): + return all(isinstance(p, str) and _is_valid(p) for p in path) + + return False diff --git a/synology_api/virtualization.py b/synology_api/virtualization.py index 872a6299..e561a642 100644 --- a/synology_api/virtualization.py +++ b/synology_api/virtualization.py @@ -1,9 +1,43 @@ +""" +Virtualization API wrapper for Synology Virtual Machine Manager. + +This module provides the Virtualization class for managing tasks, networks, storage, hosts, VMs, and images +on Synology NAS devices via the Virtual Machine Manager API. +""" + from __future__ import annotations from typing import Optional, Any from . import base_api class Virtualization(base_api.BaseApi): + """ + API wrapper for Synology Virtual Machine Manager. + + Provides methods to manage tasks, networks, storage, hosts, VMs, and images. + + Parameters + ---------- + ip_address : str + IP address of the Synology NAS. + port : str + Port number to connect to. + username : str + DSM username. + password : str + DSM password. + secure : bool, optional + Use HTTPS if True. Default is False. + cert_verify : bool, optional + Verify SSL certificate if True. Default is False. + dsm_version : int, optional + DSM version. Default is 7. + debug : bool, optional + Enable debug mode. Default is True. + otp_code : str, optional + One-time password for 2FA, if required. + """ + def __init__(self, ip_address: str, port: str, @@ -15,6 +49,30 @@ def __init__(self, debug: bool = True, otp_code: Optional[str] = None ) -> None: + """ + Initialize the Virtualization API wrapper. + + Parameters + ---------- + ip_address : str + IP address of the Synology NAS. + port : str + Port number. + username : str + DSM username. + password : str + DSM password. + secure : bool, optional + Use HTTPS if True. Default is False. + cert_verify : bool, optional + Verify SSL certificate if True. Default is False. + dsm_version : int, optional + DSM version. Default is 7. + debug : bool, optional + Enable debug mode. Default is True. + otp_code : str, optional + One-time password for 2FA, if required. + """ super(Virtualization, self).__init__(ip_address, port, username, password, secure, cert_verify, dsm_version, debug, otp_code) @@ -32,6 +90,14 @@ def __init__(self, self.file_station_list: Any = self.session.app_api_list def get_task_list(self) -> list[str]: + """ + Get the list of virtualization tasks. + + Returns + ------- + list of str + List of task IDs. + """ api_name = 'SYNO.Virtualization.API.Task.Info' info = self.file_station_list[api_name] api_path = info['path'] @@ -42,6 +108,19 @@ def get_task_list(self) -> list[str]: return self._taskid_list def clear_task(self, taskid: str) -> dict[str, object] | str: + """ + Clear a specific task by its ID. + + Parameters + ---------- + taskid : str + Task ID to clear. + + Returns + ------- + dict[str, object] or str + Result of the clear operation or error message. + """ api_name = 'SYNO.Virtualization.API.Task.Info' info = self.file_station_list[api_name] api_path = info['path'] @@ -55,6 +134,19 @@ def clear_task(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_task_info(self, taskid: str) -> dict[str, object] | str: + """ + Get information about a specific task. + + Parameters + ---------- + taskid : str + Task ID to retrieve information for. + + Returns + ------- + dict[str, object] or str + Task information or error message. + """ api_name = 'SYNO.Virtualization.API.Task.Info' info = self.file_station_list[api_name] api_path = info['path'] @@ -68,6 +160,14 @@ def get_task_info(self, taskid: str) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def get_network_group_list(self) -> list[dict[str, object]]: + """ + Get the list of network groups. + + Returns + ------- + list of dict + List of network group information. + """ api_name = 'SYNO.Virtualization.API.Network' info = self.file_station_list[api_name] api_path = info['path'] @@ -79,6 +179,14 @@ def get_network_group_list(self) -> list[dict[str, object]]: return self._network_group_list def get_storage_operation(self) -> list[str]: + """ + Get the list of storage operations. + + Returns + ------- + list of str + List of storage operation information. + """ api_name = 'SYNO.Virtualization.API.Storage' info = self.file_station_list[api_name] api_path = info['path'] @@ -89,6 +197,14 @@ def get_storage_operation(self) -> list[str]: return self._storages_list def get_host_operation(self) -> list[str]: + """ + Get the list of host operations. + + Returns + ------- + list of str + List of host operation information. + """ api_name = 'SYNO.Virtualization.API.Host' info = self.file_station_list[api_name] api_path = info['path'] @@ -100,6 +216,19 @@ def get_host_operation(self) -> list[str]: return self._host_operation_list def get_vm_operation(self, additional: bool = False) -> list[dict[str, object]]: + """ + Get the list of virtual machines. + + Parameters + ---------- + additional : bool, optional + Whether to include additional information. Default is False. + + Returns + ------- + list of dict + List of VM information. + """ api_name = 'SYNO.Virtualization.API.Guest' info = self.file_station_list[api_name] api_path = info['path'] @@ -116,11 +245,29 @@ def get_vm_operation(self, additional: bool = False) -> list[dict[str, object]]: return info - def get_specific_vm_info(self, - additional: Optional[str | list[str]] = None, - guest_id: Optional[str] = None, - guest_name: Optional[str] = None - ) -> dict[str, object] | str: + def get_specific_vm_info( + self, + additional: Optional[str | list[str]] = None, + guest_id: Optional[str] = None, + guest_name: Optional[str] = None + ) -> dict[str, object] | str: + """ + Get information about a specific virtual machine. + + Parameters + ---------- + additional : str or list of str, optional + Additional fields to include. + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + + Returns + ------- + dict[str, object] or str + VM information or error message. + """ api_name = 'SYNO.Virtualization.API.Guest' info = self.file_station_list[api_name] api_path = info['path'] @@ -137,15 +284,41 @@ def get_specific_vm_info(self, return self.request_data(api_name, api_path, req_param) - def set_vm_property(self, - guest_id: Optional[str] = None, - guest_name: Optional[str] = None, - autorun: Optional[int] = None, - description: Optional[str] = None, - new_guest_name: Optional[str] = None, - vcpu_num: Optional[int] = None, - vram_size: Optional[int] = None - ) -> dict[str, object] | str: + def set_vm_property( + self, + guest_id: Optional[str] = None, + guest_name: Optional[str] = None, + autorun: Optional[int] = None, + description: Optional[str] = None, + new_guest_name: Optional[str] = None, + vcpu_num: Optional[int] = None, + vram_size: Optional[int] = None + ) -> dict[str, object] | str: + """ + Set properties for a virtual machine. + + Parameters + ---------- + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + autorun : int, optional + Autorun setting (0: off, 1: last state, 2: on). + description : str, optional + VM description. + new_guest_name : str, optional + New VM name. + vcpu_num : int, optional + Number of virtual CPUs. + vram_size : int, optional + RAM size in MB. + + Returns + ------- + dict[str, object] or str + Result of the set operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest' info = self.file_station_list[api_name] api_path = info['path'] @@ -186,6 +359,21 @@ def set_vm_property(self, return self.request_data(api_name, api_path, req_param) def delete_vm(self, guest_id: Optional[str] = None, guest_name: Optional[str] = None) -> dict[str, object] | str: + """ + Delete a virtual machine. + + Parameters + ---------- + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest' info = self.file_station_list[api_name] api_path = info['path'] @@ -202,12 +390,32 @@ def delete_vm(self, guest_id: Optional[str] = None, guest_name: Optional[str] = return self.request_data(api_name, api_path, req_param) - def vm_power_on(self, - guest_id: Optional[str] = None, - guest_name: Optional[str] = None, - host_id: Optional[str] = None, - host_name: Optional[str] = None - ) -> dict[str, object] | str: + def vm_power_on( + self, + guest_id: Optional[str] = None, + guest_name: Optional[str] = None, + host_id: Optional[str] = None, + host_name: Optional[str] = None + ) -> dict[str, object] | str: + """ + Power on a virtual machine. + + Parameters + ---------- + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + host_id : str, optional + Host ID. + host_name : str, optional + Host name. + + Returns + ------- + dict[str, object] or str + Result of the power on operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest.Action' info = self.file_station_list[api_name] api_path = info['path'] @@ -233,10 +441,26 @@ def vm_power_on(self, return self.request_data(api_name, api_path, req_param) - def vm_force_power_off(self, - guest_id: Optional[str] = None, - guest_name: Optional[str] = None - ) -> dict[str, object] | str: + def vm_force_power_off( + self, + guest_id: Optional[str] = None, + guest_name: Optional[str] = None + ) -> dict[str, object] | str: + """ + Force power off a virtual machine. + + Parameters + ---------- + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + + Returns + ------- + dict[str, object] or str + Result of the power off operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest.Action' info = self.file_station_list[api_name] api_path = info['path'] @@ -254,6 +478,21 @@ def vm_force_power_off(self, return self.request_data(api_name, api_path, req_param) def vm_shut_down(self, guest_id: Optional[str] = None, guest_name: Optional[str] = None) -> dict[str, object] | str: + """ + Shut down a virtual machine. + + Parameters + ---------- + guest_id : str, optional + Guest VM ID. + guest_name : str, optional + Guest VM name. + + Returns + ------- + dict[str, object] or str + Result of the shutdown operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest.Action' info = self.file_station_list[api_name] api_path = info['path'] @@ -271,6 +510,14 @@ def vm_shut_down(self, guest_id: Optional[str] = None, guest_name: Optional[str] return self.request_data(api_name, api_path, req_param) def get_images_list(self) -> dict[str, object]: + """ + Get the list of VM images. + + Returns + ------- + dict[str, object] + Dictionary containing image information. + """ api_name = 'SYNO.Virtualization.API.Guest.Image' info = self.file_station_list[api_name] api_path = info['path'] @@ -279,6 +526,21 @@ def get_images_list(self) -> dict[str, object]: return self.request_data(api_name, api_path, req_param) def delete_image(self, image_id: Optional[str] = None, image_name: Optional[str] = None) -> dict[str, object] | str: + """ + Delete a VM image. + + Parameters + ---------- + image_id : str, optional + Image ID. + image_name : str, optional + Image name. + + Returns + ------- + dict[str, object] or str + Result of the delete operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest.Image' info = self.file_station_list[api_name] api_path = info['path'] @@ -295,14 +557,38 @@ def delete_image(self, image_id: Optional[str] = None, image_name: Optional[str] return self.request_data(api_name, api_path, req_param) - def create_image(self, - auto_clean_task: bool = True, - storage_names: Optional[str] = None, - storage_ids: Optional[str] = None, - type: Optional[str] = None, - ds_file_path: Optional[str] = None, - image_name: Optional[str] = None - ) -> dict[str, object] | str: + def create_image( + self, + auto_clean_task: bool = True, + storage_names: Optional[str] = None, + storage_ids: Optional[str] = None, + type: Optional[str] = None, + ds_file_path: Optional[str] = None, + image_name: Optional[str] = None + ) -> dict[str, object] | str: + """ + Create a new VM image. + + Parameters + ---------- + auto_clean_task : bool, optional + Whether to auto-clean the task after creation. Default is True. + storage_names : str, optional + Storage names. + storage_ids : str, optional + Storage IDs. + type : str, optional + Image type ('disk', 'vdsm', or 'iso'). + ds_file_path : str, optional + File path (should begin with a shared folder). + image_name : str, optional + Name of the image. + + Returns + ------- + dict[str, object] or str + Result of the create operation or error message. + """ api_name = 'SYNO.Virtualization.API.Guest.Image' info = self.file_station_list[api_name] api_path = info['path'] diff --git a/synology_api/vpn.py b/synology_api/vpn.py index f33e1d14..93badd51 100644 --- a/synology_api/vpn.py +++ b/synology_api/vpn.py @@ -1,3 +1,4 @@ +"""VPN API Wrapper for Synology NAS.""" from __future__ import annotations from io import BytesIO from zipfile import ZipFile @@ -6,8 +7,22 @@ class VPN(base_api.BaseApi): + """ + API wrapper for Synology VPN Server. + + Provides methods to retrieve VPN settings, active connections, logs, network interfaces, + security autoblock settings, permissions, and VPN protocol-specific settings. + """ def settings_list(self) -> dict[str, object] | str: + """ + Retrieve VPN server settings. + + Returns + ------- + dict[str, object] or str + VPN server settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Settings.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -21,6 +36,25 @@ def active_connections_list(self, start: int = 0, limit: int = 100 ) -> dict[str, object] | str: + """ + Retrieve a list of active VPN connections. + + Parameters + ---------- + sort : str, optional + Field to sort by. Default is 'login_time'. + sort_dir : str, optional + Sort direction ('ASC' or 'DESC'). Default is 'DESC'. + start : int, optional + Pagination start index. Default is 0. + limit : int, optional + Maximum number of results to return. Default is 100. + + Returns + ------- + dict[str, object] or str + Active connections as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Management.Connection' info = self.gen_list[api_name] api_path = info['path'] @@ -30,6 +64,23 @@ def active_connections_list(self, return self.request_data(api_name, api_path, req_param) def log_list(self, start: int = 0, limit: int = 50, prtltype: int = 0) -> dict[str, object] | str: + """ + Retrieve VPN server logs. + + Parameters + ---------- + start : int, optional + Pagination start index. Default is 0. + limit : int, optional + Maximum number of logs to return. Default is 50. + prtltype : int, optional + Protocol type filter. Default is 0 (all). + + Returns + ------- + dict[str, object] or str + Logs as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Management.Log' info = self.gen_list[api_name] api_path = info['path'] @@ -39,6 +90,14 @@ def log_list(self, start: int = 0, limit: int = 50, prtltype: int = 0) -> dict[s return self.request_data(api_name, api_path, req_param) def network_interface_setting(self) -> dict[str, object] | str: + """ + Retrieve VPN network interface settings. + + Returns + ------- + dict[str, object] or str + Network interface settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Management.Interface' info = self.gen_list[api_name] api_path = info['path'] @@ -47,6 +106,14 @@ def network_interface_setting(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def security_autoblock_setting(self) -> dict[str, object] | str: + """ + Retrieve security autoblock settings. + + Returns + ------- + dict[str, object] or str + Autoblock settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.Core.Security.AutoBlock' info = self.gen_list[api_name] api_path = info['path'] @@ -55,6 +122,21 @@ def security_autoblock_setting(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def permission_setting(self, start: int = 0, limit: int = 100) -> dict[str, object] | str: + """ + Retrieve VPN permission settings. + + Parameters + ---------- + start : int, optional + Pagination start index. Default is 0. + limit : int, optional + Maximum number of results to return. Default is 100. + + Returns + ------- + dict[str, object] or str + Permission settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Management.Account' info = self.gen_list[api_name] api_path = info['path'] @@ -64,6 +146,14 @@ def permission_setting(self, start: int = 0, limit: int = 100) -> dict[str, obje return self.request_data(api_name, api_path, req_param) def pptp_settings_info(self) -> dict[str, object] | str: + """ + Retrieve PPTP VPN settings. + + Returns + ------- + dict[str, object] or str + PPTP settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Settings.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -73,6 +163,14 @@ def pptp_settings_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def openvpn_settings_info(self) -> dict[str, object] | str: + """ + Retrieve OpenVPN settings. + + Returns + ------- + dict[str, object] or str + OpenVPN settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Settings.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -82,6 +180,14 @@ def openvpn_settings_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def l2tp_settings_info(self) -> dict[str, object] | str: + """ + Retrieve L2TP VPN settings. + + Returns + ------- + dict[str, object] or str + L2TP settings as a dictionary, or an error message as a string. + """ api_name = 'SYNO.VPNServer.Settings.Config' info = self.gen_list[api_name] api_path = info['path'] @@ -91,17 +197,18 @@ def l2tp_settings_info(self) -> dict[str, object] | str: return self.request_data(api_name, api_path, req_param) def openvpn_export_configuration(self, as_zip_file=False) -> bytes | ZipFile: - """Downloads the openvpn\.zip containing the VPNConfig\.ovpn file + """ + Download the OpenVPN configuration as a zip file or bytes. - Parameters - ---------- - as_zip_file : bool - If the bytes should be converted to a ZipFile + Parameters + ---------- + as_zip_file : bool, optional + If True, return a ZipFile object. If False, return bytes. Default is False. - Returns - ------- - dict[str, object] - A dictionary containing the OpenVPN configuration file as bytes or a ZipFile object if `as_zip_file` is True. + Returns + ------- + bytes or ZipFile + The OpenVPN configuration file as bytes, or a ZipFile object if `as_zip_file` is True. """ api_name = 'SYNO.VPNServer.Settings.Certificate' info = self.gen_list[api_name] diff --git a/tests/test_syno_api.py b/tests/test_syno_api.py index eb6321fc..e30b0be6 100644 --- a/tests/test_syno_api.py +++ b/tests/test_syno_api.py @@ -3,6 +3,7 @@ from unittest import TestCase import unittest from synology_api.filestation import FileStation +from synology_api.downloadstation import DownloadStation from synology_api.surveillancestation import SurveillanceStation import os import pathlib @@ -43,6 +44,21 @@ def test_syno_filestation_login(self): self.assertIsNotNone(shares_list) self.assertEqual(shares_list.__len__(), 2) + def test_syno_downloadstation_login(self): + ds = DownloadStation(ip_address=self.config["synology_ip"], port=self.config["synology_port"], + username=self.config["synology_user"], + password=self.config["synology_password"], + secure=bool(self.config["synology_secure"]), cert_verify=False, + dsm_version=int(self.config["dsm_version"]), debug=True, + otp_code=self.config["otp_code"]) + self.assertIsNotNone(ds) + self.assertIsNotNone(ds.session) + self.assertIsNotNone(ds.session.sid) + self.assertIsNot(ds.session.sid, '') + tasks_list = ds.tasks_list() + self.assertIsNotNone(tasks_list) + self.assertEqual(tasks_list.__len__(), 2) + def test_syno_surveillancestation_login(self): ss = SurveillanceStation(ip_address=self.config["synology_ip"], port=self.config["synology_port"], username=self.config["synology_user"],