aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Controllers')
-rw-r--r--Jellyfin.Api/Controllers/BackupController.cs127
-rw-r--r--Jellyfin.Api/Controllers/MediaSegmentsController.cs5
-rw-r--r--Jellyfin.Api/Controllers/SyncPlayController.cs2
-rw-r--r--Jellyfin.Api/Controllers/SystemController.cs1
4 files changed, 131 insertions, 4 deletions
diff --git a/Jellyfin.Api/Controllers/BackupController.cs b/Jellyfin.Api/Controllers/BackupController.cs
new file mode 100644
index 000000000..aa908ee30
--- /dev/null
+++ b/Jellyfin.Api/Controllers/BackupController.cs
@@ -0,0 +1,127 @@
+using System.IO;
+using System.Threading.Tasks;
+using Jellyfin.Server.Implementations.SystemBackupService;
+using MediaBrowser.Common.Api;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.SystemBackupService;
+using Microsoft.AspNetCore.Authentication.OAuth.Claims;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+
+namespace Jellyfin.Api.Controllers;
+
+/// <summary>
+/// The backup controller.
+/// </summary>
+[Authorize(Policy = Policies.RequiresElevation)]
+public class BackupController : BaseJellyfinApiController
+{
+ private readonly IBackupService _backupService;
+ private readonly IApplicationPaths _applicationPaths;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BackupController"/> class.
+ /// </summary>
+ /// <param name="backupService">Instance of the <see cref="IBackupService"/> interface.</param>
+ /// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
+ public BackupController(IBackupService backupService, IApplicationPaths applicationPaths)
+ {
+ _backupService = backupService;
+ _applicationPaths = applicationPaths;
+ }
+
+ /// <summary>
+ /// Creates a new Backup.
+ /// </summary>
+ /// <param name="backupOptions">The backup options.</param>
+ /// <response code="200">Backup created.</response>
+ /// <response code="403">User does not have permission to retrieve information.</response>
+ /// <returns>The created backup manifest.</returns>
+ [HttpPost("Create")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public async Task<ActionResult<BackupManifestDto>> CreateBackup([FromBody] BackupOptionsDto backupOptions)
+ {
+ return Ok(await _backupService.CreateBackupAsync(backupOptions ?? new()).ConfigureAwait(false));
+ }
+
+ /// <summary>
+ /// Restores to a backup by restarting the server and applying the backup.
+ /// </summary>
+ /// <param name="archiveRestoreDto">The data to start a restore process.</param>
+ /// <response code="204">Backup restore started.</response>
+ /// <response code="403">User does not have permission to retrieve information.</response>
+ /// <returns>No-Content.</returns>
+ [HttpPost("Restore")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public IActionResult StartRestoreBackup([FromBody, BindRequired] BackupRestoreRequestDto archiveRestoreDto)
+ {
+ var archivePath = SanitizePath(archiveRestoreDto.ArchiveFileName);
+ if (!System.IO.File.Exists(archivePath))
+ {
+ return NotFound();
+ }
+
+ _backupService.ScheduleRestoreAndRestartServer(archivePath);
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Gets a list of all currently present backups in the backup directory.
+ /// </summary>
+ /// <response code="200">Backups available.</response>
+ /// <response code="403">User does not have permission to retrieve information.</response>
+ /// <returns>The list of backups.</returns>
+ [HttpGet]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public async Task<ActionResult<BackupManifestDto[]>> ListBackups()
+ {
+ return Ok(await _backupService.EnumerateBackups().ConfigureAwait(false));
+ }
+
+ /// <summary>
+ /// Gets the descriptor from an existing archive is present.
+ /// </summary>
+ /// <param name="path">The data to start a restore process.</param>
+ /// <response code="200">Backup archive manifest.</response>
+ /// <response code="204">Not a valid jellyfin Archive.</response>
+ /// <response code="404">Not a valid path.</response>
+ /// <response code="403">User does not have permission to retrieve information.</response>
+ /// <returns>The backup manifest.</returns>
+ [HttpGet("Manifest")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public async Task<ActionResult<BackupManifestDto>> GetBackup([BindRequired] string path)
+ {
+ var backupPath = SanitizePath(path);
+
+ if (!System.IO.File.Exists(backupPath))
+ {
+ return NotFound();
+ }
+
+ var manifest = await _backupService.GetBackupManifest(backupPath).ConfigureAwait(false);
+ if (manifest is null)
+ {
+ return NoContent();
+ }
+
+ return Ok(manifest);
+ }
+
+ [NonAction]
+ private string SanitizePath(string path)
+ {
+ // sanitize path
+ var archiveRestorePath = Path.GetFileName(Path.GetFullPath(path));
+ var archivePath = Path.Combine(_applicationPaths.BackupPath, archiveRestorePath);
+ return archivePath;
+ }
+}
diff --git a/Jellyfin.Api/Controllers/MediaSegmentsController.cs b/Jellyfin.Api/Controllers/MediaSegmentsController.cs
index e30e2b54e..b8836d7cf 100644
--- a/Jellyfin.Api/Controllers/MediaSegmentsController.cs
+++ b/Jellyfin.Api/Controllers/MediaSegmentsController.cs
@@ -5,9 +5,9 @@ using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Database.Implementations.Enums;
-using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaSegments;
using MediaBrowser.Model.MediaSegments;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Authorization;
@@ -55,7 +55,8 @@ public class MediaSegmentsController : BaseJellyfinApiController
return NotFound();
}
- var items = await _mediaSegmentManager.GetSegmentsAsync(item, includeSegmentTypes).ConfigureAwait(false);
+ var libraryOptions = _libraryManager.GetLibraryOptions(item);
+ var items = await _mediaSegmentManager.GetSegmentsAsync(item, includeSegmentTypes, libraryOptions).ConfigureAwait(false);
return Ok(new QueryResult<MediaSegmentDto>(items.ToArray()));
}
}
diff --git a/Jellyfin.Api/Controllers/SyncPlayController.cs b/Jellyfin.Api/Controllers/SyncPlayController.cs
index fbab2a784..3d6874079 100644
--- a/Jellyfin.Api/Controllers/SyncPlayController.cs
+++ b/Jellyfin.Api/Controllers/SyncPlayController.cs
@@ -125,7 +125,7 @@ public class SyncPlayController : BaseJellyfinApiController
{
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
var group = _syncPlayManager.GetGroup(currentSession, id);
- return group == null ? NotFound() : Ok(group);
+ return group is null ? NotFound() : Ok(group);
}
/// <summary>
diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs
index 07a1f7650..450225c37 100644
--- a/Jellyfin.Api/Controllers/SystemController.cs
+++ b/Jellyfin.Api/Controllers/SystemController.cs
@@ -5,7 +5,6 @@ using System.IO;
using System.Linq;
using System.Net.Mime;
using Jellyfin.Api.Attributes;
-using Jellyfin.Api.Constants;
using Jellyfin.Api.Models.SystemInfoDtos;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Configuration;