Skip to content

Commit

Permalink
More Polishing (#428)
Browse files Browse the repository at this point in the history
# Added
- Added: Added a new button on admin dashboard to clear cache for the whole server

# Changed
- Changed: Moved the download logs to the new System page
- Changed: Tag Badges now show the correct cursor to help indication actions. For example, Collection badges on series detail page can be clicked, while type cannot.

# Fixed
- Fixed: Fixed an issue in develop builds where Pagination no longer worked due to Header not being exposed
- Fixed: After Scanning a series, clear out any cached chapters

=======================================================
* After Scanning a series, clear out any cached chapters.


* Implemented cursor overrides for tag badges

* Fixed pagination no longer working due to Pagination header not being able to be read from the UI.

* Fixed some css things with icons within tagbadges not taking the selection mode styling

* Moved download logs button to the system page

* Implemented the ability to clear cache for the whole server from admin dashboard

* Removed debug code

* Up the Regex Timeout for the Github Build System
  • Loading branch information
majora2007 authored Jul 25, 2021
1 parent 107b702 commit 4f34617
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 36 deletions.
3 changes: 2 additions & 1 deletion API.Tests/Services/ScannerServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ScannerServiceTests : IDisposable
private readonly IImageService _imageService = Substitute.For<IImageService>();
private readonly ILogger<MetadataService> _metadataLogger = Substitute.For<ILogger<MetadataService>>();
private readonly IDirectoryService _directoryService = Substitute.For<IDirectoryService>();
private readonly ICacheService _cacheService = Substitute.For<ICacheService>();

private readonly DbConnection _connection;
private readonly DataContext _context;
Expand All @@ -53,7 +54,7 @@ public ScannerServiceTests()


IMetadataService metadataService = Substitute.For<MetadataService>(unitOfWork, _metadataLogger, _archiveService, _bookService, _imageService);
_scannerService = new ScannerService(unitOfWork, _logger, _archiveService, metadataService, _bookService);
_scannerService = new ScannerService(unitOfWork, _logger, _archiveService, metadataService, _bookService, _cacheService);
}

private async Task<bool> SeedDb()
Expand Down
13 changes: 12 additions & 1 deletion API/Controllers/ServerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ public class ServerController : BaseApiController
private readonly IConfiguration _config;
private readonly IBackupService _backupService;
private readonly IArchiveService _archiveService;
private readonly ICacheService _cacheService;

public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger, IConfiguration config,
IBackupService backupService, IArchiveService archiveService)
IBackupService backupService, IArchiveService archiveService, ICacheService cacheService)
{
_applicationLifetime = applicationLifetime;
_logger = logger;
_config = config;
_backupService = backupService;
_archiveService = archiveService;
_cacheService = cacheService;
}

[HttpPost("restart")]
Expand All @@ -42,6 +44,15 @@ public ActionResult RestartServer()
return Ok();
}

[HttpPost("clear-cache")]
public ActionResult ClearCache()
{
_logger.LogInformation("{UserName} is clearing cache of server from admin dashboard", User.GetUsername());
_cacheService.Cleanup();

return Ok();
}

/// <summary>
/// Returns non-sensitive information about the current system
/// </summary>
Expand Down
1 change: 0 additions & 1 deletion API/Extensions/DirectoryInfoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ private static void FlattenDirectory(DirectoryInfo root, DirectoryInfo directory

foreach (var subDirectory in directory.EnumerateDirectories())
{
Console.WriteLine($"Flattening {subDirectory}");
FlattenDirectory(root, subDirectory, ref directoryIndex);
}
}
Expand Down
11 changes: 6 additions & 5 deletions API/Interfaces/Services/ICacheService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using API.Entities;

namespace API.Interfaces.Services
Expand All @@ -22,11 +23,11 @@ public interface ICacheService
/// Clears cache directory of all volumes. This can be invoked from deleting a library or a series.
/// </summary>
/// <param name="chapterIds">Volumes that belong to that library. Assume the library might have been deleted before this invocation.</param>
void CleanupChapters(int[] chapterIds);
void CleanupChapters(IEnumerable<int> chapterIds);


/// <summary>
/// Returns the absolute path of a cached page.
/// Returns the absolute path of a cached page.
/// </summary>
/// <param name="chapter">Chapter entity with Files populated.</param>
/// <param name="page">Page number to look for</param>
Expand All @@ -35,4 +36,4 @@ public interface ICacheService

void EnsureCacheDirectory();
}
}
}
5 changes: 3 additions & 2 deletions API/Parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class Parser
{
public const string DefaultChapter = "0";
public const string DefaultVolume = "0";
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(250);
private static readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(500);

public const string ImageFileExtensions = @"^(\.png|\.jpeg|\.jpg)";
public const string ArchiveFileExtensions = @"\.cbz|\.zip|\.rar|\.cbr|\.tar.gz|\.7zip|\.7z|\.cb7|\.cbt";
Expand Down Expand Up @@ -507,7 +507,8 @@ public static class Parser
// If SP\d+ is in the filename, we force treat it as a special regardless if volume or chapter might have been found.
private static readonly Regex SpecialMarkerRegex = new Regex(
@"(?<Special>SP\d+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled
RegexOptions.IgnoreCase | RegexOptions.Compiled,
RegexTimeout
);


Expand Down
1 change: 0 additions & 1 deletion API/Services/ArchiveService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ private static ComicInfo FindComicInfoXml(IEnumerable<IArchiveEntry> entries)
entry.WriteTo(ms);
ms.Position = 0;


var serializer = new XmlSerializer(typeof(ComicInfo));
var info = (ComicInfo) serializer.Deserialize(ms);
return info;
Expand Down
1 change: 0 additions & 1 deletion API/Services/BookService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ public void ExtractPdfImages(string fileFilePath, string targetDirectory)
using var stream = StreamManager.GetStream("BookService.GetPdfPage");
for (var pageNumber = 0; pageNumber < pages; pageNumber++)
{
// IDEA! Move stream out and use the same stream
GetPdfPage(docReader, pageNumber, stream);
File.WriteAllBytes(Path.Combine(targetDirectory, "Page-" + pageNumber + ".png"), stream.ToArray());
}
Expand Down
3 changes: 2 additions & 1 deletion API/Services/CacheService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -113,7 +114,7 @@ public void Cleanup()
_logger.LogInformation("Cache directory purged");
}

public void CleanupChapters(int[] chapterIds)
public void CleanupChapters(IEnumerable<int> chapterIds)
{
_logger.LogInformation("Running Cache cleanup on Volumes");

Expand Down
6 changes: 5 additions & 1 deletion API/Services/Tasks/ScannerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@ public class ScannerService : IScannerService
private readonly IArchiveService _archiveService;
private readonly IMetadataService _metadataService;
private readonly IBookService _bookService;
private readonly ICacheService _cacheService;
private readonly NaturalSortComparer _naturalSort = new ();

public ScannerService(IUnitOfWork unitOfWork, ILogger<ScannerService> logger, IArchiveService archiveService,
IMetadataService metadataService, IBookService bookService)
IMetadataService metadataService, IBookService bookService, ICacheService cacheService)
{
_unitOfWork = unitOfWork;
_logger = logger;
_archiveService = archiveService;
_metadataService = metadataService;
_bookService = bookService;
_cacheService = cacheService;
}

[DisableConcurrentExecution(timeoutInSeconds: 360)]
Expand All @@ -46,6 +48,7 @@ public async Task ScanSeries(int libraryId, int seriesId, bool forceUpdate, Canc
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(seriesId);
var library = await _unitOfWork.LibraryRepository.GetFullLibraryForIdAsync(libraryId, seriesId);
var dirs = FindHighestDirectoriesFromFiles(library, files);
var chapterIds = await _unitOfWork.SeriesRepository.GetChapterIdsForSeriesAsync(new []{ seriesId });

_logger.LogInformation("Beginning file scan on {SeriesName}", series.Name);
var scanner = new ParseScannedFiles(_bookService, _logger);
Expand All @@ -71,6 +74,7 @@ public async Task ScanSeries(int libraryId, int seriesId, bool forceUpdate, Canc
totalFiles, parsedSeries.Keys.Count, sw.ElapsedMilliseconds + scanElapsedTime, series.Name);
CleanupUserProgress();
BackgroundJob.Enqueue(() => _metadataService.RefreshMetadata(libraryId, forceUpdate));
BackgroundJob.Enqueue(() => _cacheService.CleanupChapters(chapterIds));
}
else
{
Expand Down
6 changes: 5 additions & 1 deletion API/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJo
// Ordering is important. Cors, authentication, authorization
if (env.IsDevelopment())
{
app.UseCors(policy => policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200").WithExposedHeaders("Content-Disposition"));
app.UseCors(policy => policy
.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:4200")
.WithExposedHeaders("Content-Disposition", "Pagination"));
}

app.UseResponseCaching();
Expand Down
4 changes: 4 additions & 0 deletions UI/Web/src/app/_services/server.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ export class ServerService {
getServerInfo() {
return this.httpClient.get<ServerInfo>(this.baseUrl + 'server/server-info');
}

clearCache() {
return this.httpClient.post(this.baseUrl + 'server/clear-cache', {});
}
}
4 changes: 0 additions & 4 deletions UI/Web/src/app/admin/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
<div class="container">
<h2>Admin Dashboard</h2>

<div class="float-right">
<button class="btn btn-secondary" (click)="fetchLogs()">Download Logs</button>
</div>

<ul ngbNav #nav="ngbNav" [(activeId)]="active" class="nav-tabs">
<li *ngFor="let tab of tabs" [ngbNavItem]="tab">
<a ngbNavLink routerLink="." [fragment]="tab.fragment">{{ tab.title | titlecase }}</a>
Expand Down
9 changes: 1 addition & 8 deletions UI/Web/src/app/admin/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { ServerService } from 'src/app/_services/server.service';
import { saveAs } from 'file-saver';
import { Title } from '@angular/platform-browser';
import { DownloadService } from 'src/app/shared/_services/download.service';



Expand All @@ -25,7 +23,7 @@ export class DashboardComponent implements OnInit {
active = this.tabs[0];

constructor(public route: ActivatedRoute, private serverService: ServerService,
private toastr: ToastrService, private titleService: Title, private downloadService: DownloadService) {
private toastr: ToastrService, private titleService: Title) {
this.route.fragment.subscribe(frag => {
const tab = this.tabs.filter(item => item.fragment === frag);
if (tab.length > 0) {
Expand All @@ -46,9 +44,4 @@ export class DashboardComponent implements OnInit {
setTimeout(() => this.toastr.success('Please reload.'), 1000);
});
}

fetchLogs() {
this.downloadService.downloadLogs();
}

}
13 changes: 13 additions & 0 deletions UI/Web/src/app/admin/manage-system/manage-system.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
<div class="container-fluid">

<div class="float-right">
<button class="btn btn-secondary mr-2" (click)="clearCache()" [disabled]="clearCacheInProgress">
<ng-container *ngIf="clearCacheInProgress">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<span class="sr-only">Loading...</span>
</ng-container>
Clear Cache
</button>
<button class="btn btn-secondary" (click)="downloadService.downloadLogs()">
Download Logs
</button>
</div>

<h3>About System</h3>
<hr/>
<div class="form-group" *ngIf="serverInfo">
Expand Down
15 changes: 14 additions & 1 deletion UI/Web/src/app/admin/manage-system/manage-system.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Title } from '@angular/platform-browser';
import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators';
import { DownloadService } from 'src/app/shared/_services/download.service';
import { ServerService } from 'src/app/_services/server.service';
import { SettingsService } from '../settings.service';
import { ServerInfo } from '../_models/server-info';
Expand All @@ -18,7 +20,10 @@ export class ManageSystemComponent implements OnInit {
serverSettings!: ServerSettings;
serverInfo!: ServerInfo;

constructor(private settingsService: SettingsService, private toastr: ToastrService, private serverService: ServerService) { }
clearCacheInProgress: boolean = false;

constructor(private settingsService: SettingsService, private toastr: ToastrService,
private serverService: ServerService, public downloadService: DownloadService) { }

ngOnInit(): void {

Expand Down Expand Up @@ -58,4 +63,12 @@ export class ManageSystemComponent implements OnInit {
});
}

clearCache() {
this.clearCacheInProgress = true;
this.serverService.clearCache().subscribe(res => {
this.clearCacheInProgress = false;
this.toastr.success('Cache has been cleared');
});
}

}
7 changes: 4 additions & 3 deletions UI/Web/src/app/library-detail/library-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ export class LibraryDetailComponent implements OnInit {
}

loadPage() {
if (this.pagination == undefined || this.pagination == null) {
this.pagination = {currentPage: 0, itemsPerPage: 30, totalItems: 0, totalPages: 1};
}

const page = this.route.snapshot.queryParamMap.get('page');
if (page != null) {
if (this.pagination == undefined || this.pagination == null) {
this.pagination = {currentPage: 0, itemsPerPage: 30, totalItems: 0, totalPages: 1};
}
this.pagination.currentPage = parseInt(page, 10);
}
this.loadingSeries = true;
Expand Down
6 changes: 3 additions & 3 deletions UI/Web/src/app/series-detail/series-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ <h2>
<h5>Genres</h5>
</div>
<div class="col-md-8">
<app-tag-badge *ngFor="let genre of seriesMetadata.genres">{{genre}}</app-tag-badge>
<app-tag-badge *ngFor="let genre of seriesMetadata.genres" [selectionMode]="TagBadgeCursor.Clickable">{{genre}}</app-tag-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.tags && seriesMetadata.tags.length > 0">
<div class="col-md-4">
<h5>Collections</h5>
</div>
<div class="col-md-8">
<app-tag-badge *ngFor="let tag of seriesMetadata.tags" a11y-click="13,32" class="clickable" routerLink="/collections/{{tag.id}}">
<app-tag-badge *ngFor="let tag of seriesMetadata.tags" a11y-click="13,32" class="clickable" routerLink="/collections/{{tag.id}}" [selectionMode]="TagBadgeCursor.Clickable">
{{tag.title}}
</app-tag-badge>
</div>
Expand All @@ -85,7 +85,7 @@ <h5>People</h5>
<h5>Type</h5>
</div>
<div class="col-md-8">
<app-tag-badge><app-series-format [format]="series.format">{{utilityService.mangaFormat(series.format)}}</app-series-format></app-tag-badge>
<app-tag-badge [selectionMode]="TagBadgeCursor.NotAllowed"><app-series-format [format]="series.format">{{utilityService.mangaFormat(series.format)}}</app-series-format></app-tag-badge>
</div>
</div>
</div>
Expand Down
5 changes: 5 additions & 0 deletions UI/Web/src/app/series-detail/series-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators';
import { ConfirmConfig } from '../shared/confirm-dialog/_models/confirm-config';
import { ConfirmService } from '../shared/confirm.service';
import { TagBadgeCursor } from '../shared/tag-badge/tag-badge.component';
import { CardDetailsModalComponent } from '../shared/_modals/card-details-modal/card-details-modal.component';
import { DownloadService } from '../shared/_services/download.service';
import { UtilityService } from '../shared/_services/utility.service';
Expand Down Expand Up @@ -74,6 +75,10 @@ export class SeriesDetailComponent implements OnInit {
return MangaFormat;
}

get TagBadgeCursor(): typeof TagBadgeCursor {
return TagBadgeCursor;
}

constructor(private route: ActivatedRoute, private seriesService: SeriesService,
private ratingConfig: NgbRatingConfig, private router: Router,
private modalService: NgbModal, public readerService: ReaderService,
Expand Down
2 changes: 1 addition & 1 deletion UI/Web/src/app/shared/tag-badge/tag-badge.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div class="tagbadge">
<div class="tagbadge {{cursor}}">
<ng-content></ng-content>
</div>
24 changes: 24 additions & 0 deletions UI/Web/src/app/shared/tag-badge/tag-badge.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,28 @@ $bdr-color: #f2f2f2;
margin-right: 0px;
cursor: pointer;
}
}

::ng-deep .selectable-cursor {
cursor: default !important;

i {
cursor: default !important;
}
}

::ng-deep .not-allowed-cursor {
cursor: not-allowed !important;

i {
cursor: not-allowed !important;
}
}

::ng-deep .clickable-cursor {
cursor: pointer !important;

i {
cursor: pointer !important;
}
}
Loading

0 comments on commit 4f34617

Please sign in to comment.