add option to get storage usage per library (#242)

See how much space each library uses.
This commit is contained in:
Kilian von Pflugk 2024-08-10 10:25:06 +00:00 committed by GitHub
parent bf5402d2bd
commit 92aa5fef88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 93 additions and 4 deletions

View File

@ -647,7 +647,7 @@
<input type="checkbox" id="eraseSeasonCacheCheckbox" style="margin-left: 10px;">
<label for="eraseSeasonCacheCheckbox" style="margin-left: 5px;">Erase cached fingerprint files</label>
</div>
<hr />
<br />
<button id="btnEraseIntroTimestamps">
Erase all introduction timestamps (globally)
@ -662,6 +662,15 @@
<input type="checkbox" id="eraseModeCacheCheckbox" style="margin-left: 10px;">
<label for="eraseModeCacheCheckbox" style="margin-left: 5px;">Erase cached fingerprint files</label>
</details>
<details id="storage">
<br />
<summary>Storage Usage</summary>
<div class="fieldDescription">
See how much space each library uses.
</div>
<textarea id="storage" rows="20" cols="75" readonly></textarea>
</details>
</fieldset>
</div>
</div>
@ -683,6 +692,7 @@
// settings elements
var visualizer = document.querySelector("details#visualizer");
var support = document.querySelector("details#support");
var storage = document.querySelector("details#storage");
var btnEraseIntroTimestamps = document.querySelector("button#btnEraseIntroTimestamps");
var btnEraseCreditTimestamps = document.querySelector("button#btnEraseCreditTimestamps");
@ -852,6 +862,21 @@
}
}
// fetch the storage whenever the detail section is opened.
async function storageToggled() {
if (!storage.open) {
return;
}
// Fetch the support bundle
const bundle = await fetchWithAuth("IntroSkipper/Storage", "GET", null);
const bundleText = await bundle.text();
// Display it to the user
const ta = document.querySelector("textarea#storage");
ta.value = bundleText;
}
// show changed, populate seasons
async function showChanged() {
clearSelect(selectSeason);
@ -1149,6 +1174,7 @@
visualizer.addEventListener("toggle", visualizerToggled);
support.addEventListener("toggle", supportToggled);
storage.addEventListener("toggle", storageToggled);
txtOffset.addEventListener("change", renderTroubleshooter);
selectShow.addEventListener("change", showChanged);
selectSeason.addEventListener("change", seasonChanged);

View File

@ -1,9 +1,11 @@
using System;
using System.Globalization;
using System.IO;
using System.Net.Mime;
using System.Text;
using MediaBrowser.Common;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Library;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@ -19,6 +21,7 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper.Controllers;
[Route("IntroSkipper")]
public class TroubleshootingController : ControllerBase
{
private readonly ILibraryManager _libraryManager;
private readonly IApplicationHost _applicationHost;
private readonly ILogger<TroubleshootingController> _logger;
@ -26,11 +29,14 @@ public class TroubleshootingController : ControllerBase
/// Initializes a new instance of the <see cref="TroubleshootingController"/> class.
/// </summary>
/// <param name="applicationHost">Application host.</param>
/// <param name="libraryManager">Library Manager.</param>
/// <param name="logger">Logger.</param>
public TroubleshootingController(
IApplicationHost applicationHost,
ILibraryManager libraryManager,
ILogger<TroubleshootingController> logger)
{
_libraryManager = libraryManager;
_applicationHost = applicationHost;
_logger = logger;
}
@ -85,4 +91,61 @@ public class TroubleshootingController : ControllerBase
return bundle.ToString();
}
/// <summary>
/// Gets a Markdown formatted support bundle.
/// </summary>
/// <response code="200">Support bundle created.</response>
/// <returns>Support bundle.</returns>
[HttpGet("Storage")]
[Produces(MediaTypeNames.Text.Plain)]
public ActionResult<string> GetFreeSpace()
{
ArgumentNullException.ThrowIfNull(Plugin.Instance);
var bundle = new StringBuilder();
var libraries = _libraryManager.GetVirtualFolders();
foreach (var library in libraries)
{
try
{
DriveInfo driveInfo = new DriveInfo(library.Locations[0]);
// Get available free space in bytes
long availableFreeSpace = driveInfo.AvailableFreeSpace;
// Get total size of the drive in bytes
long totalSize = driveInfo.TotalSize;
// Get total used space in Percentage
double usedSpacePercentage = totalSize > 0 ? (totalSize - availableFreeSpace) / (double)totalSize * 100 : 0;
bundle.Append(CultureInfo.CurrentCulture, $"Library: {library.Name}\n");
bundle.Append(CultureInfo.CurrentCulture, $"Drive: {driveInfo.Name}\n");
bundle.Append(CultureInfo.CurrentCulture, $"Total Size: {GetHumanReadableSize(totalSize)}\n");
bundle.Append(CultureInfo.CurrentCulture, $"Available Free Space: {GetHumanReadableSize(availableFreeSpace)}\n");
bundle.Append(CultureInfo.CurrentCulture, $"Total used in Percentage: {Math.Round(usedSpacePercentage, 2)}%\n\n");
}
catch (Exception ex)
{
_logger.LogWarning("Unable to get DriveInfo: {Exception}", ex);
}
}
return bundle.ToString().TrimEnd('\n');
}
private string GetHumanReadableSize(long bytes)
{
string[] sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len = len / 1024;
}
return $"{len:0.##} {sizes[order]}";
}
}