< Summary - Jellyfin

Information
Class: Jellyfin.Api.Controllers.EnvironmentController
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Controllers/EnvironmentController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 40
Coverable lines: 40
Total lines: 197
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 30
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
GetDirectoryContents(...)0%2040%
ValidatePath(...)0%342180%
GetDrives()100%210%
GetParentPath(...)0%7280%
GetDefaultDirectoryBrowser()100%210%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Controllers/EnvironmentController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.ComponentModel.DataAnnotations;
 4using System.IO;
 5using System.Linq;
 6using Jellyfin.Api.Constants;
 7using Jellyfin.Api.Models.EnvironmentDtos;
 8using MediaBrowser.Common.Api;
 9using MediaBrowser.Common.Extensions;
 10using MediaBrowser.Model.IO;
 11using Microsoft.AspNetCore.Authorization;
 12using Microsoft.AspNetCore.Http;
 13using Microsoft.AspNetCore.Mvc;
 14using Microsoft.Extensions.Logging;
 15
 16namespace Jellyfin.Api.Controllers;
 17
 18/// <summary>
 19/// Environment Controller.
 20/// </summary>
 21[Authorize(Policy = Policies.FirstTimeSetupOrElevated)]
 22public class EnvironmentController : BaseJellyfinApiController
 23{
 24    private const char UncSeparator = '\\';
 25    private const string UncStartPrefix = @"\\";
 26
 27    private readonly IFileSystem _fileSystem;
 28    private readonly ILogger<EnvironmentController> _logger;
 29
 30    /// <summary>
 31    /// Initializes a new instance of the <see cref="EnvironmentController"/> class.
 32    /// </summary>
 33    /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 34    /// <param name="logger">Instance of the <see cref="ILogger{EnvironmentController}"/> interface.</param>
 035    public EnvironmentController(IFileSystem fileSystem, ILogger<EnvironmentController> logger)
 36    {
 037        _fileSystem = fileSystem;
 038        _logger = logger;
 039    }
 40
 41    /// <summary>
 42    /// Gets the contents of a given directory in the file system.
 43    /// </summary>
 44    /// <param name="path">The path.</param>
 45    /// <param name="includeFiles">An optional filter to include or exclude files from the results. true/false.</param>
 46    /// <param name="includeDirectories">An optional filter to include or exclude folders from the results. true/false.<
 47    /// <response code="200">Directory contents returned.</response>
 48    /// <returns>Directory contents.</returns>
 49    [HttpGet("DirectoryContents")]
 50    [ProducesResponseType(StatusCodes.Status200OK)]
 51    public IEnumerable<FileSystemEntryInfo> GetDirectoryContents(
 52        [FromQuery, Required] string path,
 53        [FromQuery] bool includeFiles = false,
 54        [FromQuery] bool includeDirectories = false)
 55    {
 056        if (path.StartsWith(UncStartPrefix, StringComparison.OrdinalIgnoreCase)
 057            && path.LastIndexOf(UncSeparator) == 1)
 58        {
 059            return Array.Empty<FileSystemEntryInfo>();
 60        }
 61
 062        var entries =
 063            _fileSystem.GetFileSystemEntries(path)
 064                .Where(i => (i.IsDirectory && includeDirectories) || (!i.IsDirectory && includeFiles))
 065                .OrderBy(i => i.FullName);
 66
 067        return entries.Select(f => new FileSystemEntryInfo(f.Name, f.FullName, f.IsDirectory ? FileSystemEntryType.Direc
 68    }
 69
 70    /// <summary>
 71    /// Validates path.
 72    /// </summary>
 73    /// <param name="validatePathDto">Validate request object.</param>
 74    /// <response code="204">Path validated.</response>
 75    /// <response code="404">Path not found.</response>
 76    /// <returns>Validation status.</returns>
 77    [HttpPost("ValidatePath")]
 78    [ProducesResponseType(StatusCodes.Status204NoContent)]
 79    [ProducesResponseType(StatusCodes.Status404NotFound)]
 80    public ActionResult ValidatePath([FromBody, Required] ValidatePathDto validatePathDto)
 81    {
 082        if (validatePathDto.IsFile.HasValue)
 83        {
 084            if (validatePathDto.IsFile.Value)
 85            {
 086                if (!System.IO.File.Exists(validatePathDto.Path))
 87                {
 088                    return NotFound();
 89                }
 90            }
 91            else
 92            {
 093                if (!Directory.Exists(validatePathDto.Path))
 94                {
 095                    return NotFound();
 96                }
 97            }
 98        }
 99        else
 100        {
 0101            if (!System.IO.File.Exists(validatePathDto.Path) && !Directory.Exists(validatePathDto.Path))
 102            {
 0103                return NotFound();
 104            }
 105
 0106            if (validatePathDto.ValidateWritable)
 107            {
 0108                if (validatePathDto.Path is null)
 109                {
 0110                    throw new ResourceNotFoundException(nameof(validatePathDto.Path));
 111                }
 112
 0113                var file = Path.Combine(validatePathDto.Path, Guid.NewGuid().ToString());
 114                try
 115                {
 0116                    System.IO.File.WriteAllText(file, string.Empty);
 0117                }
 118                finally
 119                {
 0120                    if (System.IO.File.Exists(file))
 121                    {
 0122                        System.IO.File.Delete(file);
 123                    }
 0124                }
 125            }
 126        }
 127
 0128        return NoContent();
 129    }
 130
 131    /// <summary>
 132    /// Gets network paths.
 133    /// </summary>
 134    /// <response code="200">Empty array returned.</response>
 135    /// <returns>List of entries.</returns>
 136    [Obsolete("This endpoint is obsolete.")]
 137    [HttpGet("NetworkShares")]
 138    [ProducesResponseType(StatusCodes.Status200OK)]
 139    public ActionResult<IEnumerable<FileSystemEntryInfo>> GetNetworkShares()
 140    {
 141        _logger.LogWarning("Obsolete endpoint accessed: /Environment/NetworkShares");
 142        return Array.Empty<FileSystemEntryInfo>();
 143    }
 144
 145    /// <summary>
 146    /// Gets available drives from the server's file system.
 147    /// </summary>
 148    /// <response code="200">List of entries returned.</response>
 149    /// <returns>List of entries.</returns>
 150    [HttpGet("Drives")]
 151    [ProducesResponseType(StatusCodes.Status200OK)]
 152    public IEnumerable<FileSystemEntryInfo> GetDrives()
 153    {
 0154        return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo(d.Name, d.FullName, FileSystemEntryType.Direc
 155    }
 156
 157    /// <summary>
 158    /// Gets the parent path of a given path.
 159    /// </summary>
 160    /// <param name="path">The path.</param>
 161    /// <returns>Parent path.</returns>
 162    [HttpGet("ParentPath")]
 163    [ProducesResponseType(StatusCodes.Status200OK)]
 164    public ActionResult<string?> GetParentPath([FromQuery, Required] string path)
 165    {
 0166        string? parent = Path.GetDirectoryName(path);
 0167        if (string.IsNullOrEmpty(parent))
 168        {
 169            // Check if unc share
 0170            var index = path.LastIndexOf(UncSeparator);
 171
 0172            if (index != -1 && path[0] == UncSeparator)
 173            {
 0174                parent = path.Substring(0, index);
 175
 0176                if (string.IsNullOrWhiteSpace(parent.TrimStart(UncSeparator)))
 177                {
 0178                    parent = null;
 179                }
 180            }
 181        }
 182
 0183        return parent;
 184    }
 185
 186    /// <summary>
 187    /// Get Default directory browser.
 188    /// </summary>
 189    /// <response code="200">Default directory browser returned.</response>
 190    /// <returns>Default directory browser.</returns>
 191    [HttpGet("DefaultDirectoryBrowser")]
 192    [ProducesResponseType(StatusCodes.Status200OK)]
 193    public ActionResult<DefaultDirectoryBrowserInfoDto> GetDefaultDirectoryBrowser()
 194    {
 0195        return new DefaultDirectoryBrowserInfoDto();
 196    }
 197}