LANCommander/LANCommander.Server/UI/Pages/Settings/Tools/OrphanedFiles.razor

135 lines
4.4 KiB
Text

@page "/Settings/Tools/OrphanedFiles"
@using LANCommander.Helpers;
@using LANCommander.Server.Models;
@attribute [Authorize(Roles = RoleService.AdministratorRoleName)]
@inject DatabaseServiceFactory DatabaseServiceFactory
<PageHeader>
<PageHeaderTitle>Orphaned Files</PageHeaderTitle>
<PageHeaderExtra>
<Popconfirm OnConfirm="DeleteAll" Title="Delete all orphan files?" Disabled="@(!Orphans.Any())">
<Button Type="@ButtonType.Primary" Disabled="@(!Orphans.Any())">Delete All</Button>
</Popconfirm>
</PageHeaderExtra>
</PageHeader>
<div style="padding: 0 24px;">
<p>
These files exist on the server, but aren't linked in the database. Use this tool to identify and delete orphaned files.
</p>
<Table TItem="OrphanedFile" DataSource="@Orphans" Loading="@Loading" PageSize="25" Responsive>
<PropertyColumn Property="f => f.Path" />
<PropertyColumn Property="f => f.Size" Sortable>
@ByteSizeLib.ByteSize.FromBytes(context.Size).ToString()
</PropertyColumn>
<PropertyColumn Property="f => f.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable />
<ActionColumn Title="" Style="text-align: right">
<Space Direction="DirectionVHType.Horizontal">
<SpaceItem>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this file?">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
</Popconfirm>
</SpaceItem>
</Space>
</ActionColumn>
</Table>
</div>
@code {
ICollection<OrphanedFile> Orphans = new List<OrphanedFile>();
bool Loading = true;
readonly Settings Settings = SettingService.GetSettings();
protected override async Task OnInitializedAsync()
{
await LoadData();
}
async Task LoadData()
{
Loading = true;
Orphans = new List<OrphanedFile>();
using (var archiveService = DatabaseServiceFactory.Create<ArchiveService>())
using (var storageLocationService = DatabaseServiceFactory.Create<StorageLocationService>())
using (var mediaService = DatabaseServiceFactory.Create<MediaService>())
{
var storageLocations = await storageLocationService.GetAsync();
var archives = await archiveService.GetAsync();
var archiveFiles = archives.Select(a => archiveService.GetArchiveFileLocation(a));
foreach (var storageLocation in storageLocations.Where(l => l.Type == SDK.Enums.StorageLocationType.Archive))
{
var localArchiveFiles = Directory.GetFiles(storageLocation.Path);
foreach (var file in localArchiveFiles.Where(f => !archiveFiles.Contains(f)))
{
var fileInfo = new FileInfo(file);
Orphans.Add(new OrphanedFile
{
Path = file,
Size = fileInfo.Length,
CreatedOn = fileInfo.CreationTime
});
}
}
var media = await mediaService.GetAsync();
var mediaFiles = media.Select(m => MediaService.GetMediaPath(m));
foreach (var storageLocation in storageLocations.Where(l => l.Type == SDK.Enums.StorageLocationType.Media))
{
var localMediaFiles = Directory.GetFiles(storageLocation.Path);
foreach (var file in localMediaFiles.Where(f => !mediaFiles.Contains(f)))
{
var fileInfo = new FileInfo(file);
Orphans.Add(new OrphanedFile
{
Path = file,
Size = fileInfo.Length,
CreatedOn = fileInfo.CreationTime
});
}
}
}
Orphans = Orphans.OrderByDescending(f => f.Size).ToList();
Loading = false;
}
async Task Delete(OrphanedFile file)
{
Loading = true;
FileHelpers.DeleteIfExists(file.Path);
await LoadData();
Loading = false;
await InvokeAsync(StateHasChanged);
}
async Task DeleteAll()
{
Loading = true;
foreach (var file in Orphans)
{
FileHelpers.DeleteIfExists(file.Path);
}
await LoadData();
Loading = false;
await InvokeAsync(StateHasChanged);
}
}