Implemented download log files (not in service). Refactored backupservice to handle log file splitting. Improved a few interfaces and added some unit tests around them.
This commit is contained in:
parent
30352403cf
commit
bbb4240e20
22 changed files with 292 additions and 46 deletions
|
|
@ -3,11 +3,8 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using API.Extensions;
|
||||
using API.Interfaces;
|
||||
using API.Interfaces.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NetVips;
|
||||
|
|
@ -20,7 +17,7 @@ namespace API.Services
|
|||
public class ArchiveService : IArchiveService
|
||||
{
|
||||
private readonly ILogger<ArchiveService> _logger;
|
||||
private const int ThumbnailWidth = 320;
|
||||
private const int ThumbnailWidth = 320; // 153w x 230h TODO: Look into optimizing the images to be smaller
|
||||
|
||||
public ArchiveService(ILogger<ArchiveService> logger)
|
||||
{
|
||||
|
|
@ -94,7 +91,7 @@ namespace API.Services
|
|||
{
|
||||
using var stream = entry.Open();
|
||||
using var ms = new MemoryStream();
|
||||
stream.CopyTo(ms);
|
||||
stream.CopyTo(ms); // TODO: Check if we can use CopyToAsync here
|
||||
var data = ms.ToArray();
|
||||
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ using System.IO.Compression;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Entities.Enums;
|
||||
using API.Extensions;
|
||||
using API.Interfaces;
|
||||
using API.Interfaces.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Services
|
||||
|
|
@ -18,22 +20,36 @@ namespace API.Services
|
|||
private readonly IDirectoryService _directoryService;
|
||||
private readonly string _tempDirectory = Path.Join(Directory.GetCurrentDirectory(), "temp");
|
||||
|
||||
private readonly IList<string> _backupFiles = new List<string>()
|
||||
{
|
||||
"appsettings.json",
|
||||
"Hangfire.db",
|
||||
"Hangfire-log.db",
|
||||
"kavita.db",
|
||||
"kavita.db-shm",
|
||||
"kavita.db-wal",
|
||||
"kavita.log",
|
||||
};
|
||||
private readonly IList<string> _backupFiles;
|
||||
|
||||
public BackupService(IUnitOfWork unitOfWork, ILogger<BackupService> logger, IDirectoryService directoryService)
|
||||
public BackupService(IUnitOfWork unitOfWork, ILogger<BackupService> logger, IDirectoryService directoryService, IConfiguration config)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_logger = logger;
|
||||
_directoryService = directoryService;
|
||||
var maxRollingFiles = config.GetMaxRollingFiles();
|
||||
var loggingSection = config.GetLoggingFileName();
|
||||
|
||||
var multipleFileRegex = maxRollingFiles > 0 ? @"\d*" : string.Empty;
|
||||
var fi = new FileInfo(loggingSection);
|
||||
|
||||
|
||||
var files = maxRollingFiles > 0
|
||||
? _directoryService.GetFiles(Directory.GetCurrentDirectory(), $@"{fi.Name}{multipleFileRegex}\.log")
|
||||
: new string[] {"kavita.log"};
|
||||
_backupFiles = new List<string>()
|
||||
{
|
||||
"appsettings.json",
|
||||
"Hangfire.db",
|
||||
"Hangfire-log.db",
|
||||
"kavita.db",
|
||||
"kavita.db-shm", // This wont always be there
|
||||
"kavita.db-wal", // This wont always be there
|
||||
};
|
||||
foreach (var file in files.Select(f => (new FileInfo(f)).Name).ToList())
|
||||
{
|
||||
_backupFiles.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
public void BackupDatabase()
|
||||
|
|
@ -59,14 +75,10 @@ namespace API.Services
|
|||
|
||||
var tempDirectory = Path.Join(_tempDirectory, dateString);
|
||||
_directoryService.ExistOrCreate(tempDirectory);
|
||||
|
||||
|
||||
foreach (var file in _backupFiles)
|
||||
{
|
||||
var originalFile = new FileInfo(Path.Join(Directory.GetCurrentDirectory(), file));
|
||||
originalFile.CopyTo(Path.Join(tempDirectory, originalFile.Name));
|
||||
}
|
||||
|
||||
_directoryService.ClearDirectory(tempDirectory);
|
||||
|
||||
_directoryService.CopyFilesToDirectory(
|
||||
_backupFiles.Select(file => Path.Join(Directory.GetCurrentDirectory(), file)).ToList(), tempDirectory);
|
||||
try
|
||||
{
|
||||
ZipFile.CreateFromDirectory(tempDirectory, zipPath);
|
||||
|
|
@ -79,5 +91,6 @@ namespace API.Services
|
|||
_directoryService.ClearAndDeleteDirectory(tempDirectory);
|
||||
_logger.LogInformation("Database backup completed");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ namespace API.Services
|
|||
if (page <= (mangaFile.NumberOfPages + pagesSoFar))
|
||||
{
|
||||
var path = GetCachePath(chapter.Id);
|
||||
var files = _directoryService.GetFiles(path, Parser.Parser.ImageFileExtensions);
|
||||
var files = _directoryService.GetFilesWithExtension(path, Parser.Parser.ImageFileExtensions);
|
||||
Array.Sort(files, _numericComparer);
|
||||
|
||||
// Since array is 0 based, we need to keep that in account (only affects last image)
|
||||
|
|
|
|||
|
|
@ -39,8 +39,23 @@ namespace API.Services
|
|||
.Where(file =>
|
||||
reSearchPattern.IsMatch(Path.GetExtension(file)));
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFiles(string path, string searchPatternExpression = "",
|
||||
SearchOption searchOption = SearchOption.TopDirectoryOnly)
|
||||
{
|
||||
if (searchPatternExpression != string.Empty)
|
||||
{
|
||||
if (!Directory.Exists(path)) return ImmutableList<string>.Empty;
|
||||
var reSearchPattern = new Regex(searchPatternExpression, RegexOptions.IgnoreCase);
|
||||
return Directory.EnumerateFiles(path, "*", searchOption)
|
||||
.Where(file =>
|
||||
reSearchPattern.IsMatch(file));
|
||||
}
|
||||
|
||||
return !Directory.Exists(path) ? Array.Empty<string>() : Directory.GetFiles(path);
|
||||
}
|
||||
|
||||
public string[] GetFiles(string path, string searchPatternExpression = "")
|
||||
public string[] GetFilesWithExtension(string path, string searchPatternExpression = "")
|
||||
{
|
||||
if (searchPatternExpression != string.Empty)
|
||||
{
|
||||
|
|
@ -70,6 +85,15 @@ namespace API.Services
|
|||
{
|
||||
DirectoryInfo di = new DirectoryInfo(directoryPath);
|
||||
|
||||
ClearDirectory(directoryPath);
|
||||
|
||||
di.Delete(true);
|
||||
}
|
||||
|
||||
public void ClearDirectory(string directoryPath)
|
||||
{
|
||||
DirectoryInfo di = new DirectoryInfo(directoryPath);
|
||||
|
||||
foreach (var file in di.EnumerateFiles())
|
||||
{
|
||||
file.Delete();
|
||||
|
|
@ -78,8 +102,35 @@ namespace API.Services
|
|||
{
|
||||
dir.Delete(true);
|
||||
}
|
||||
|
||||
di.Delete(true);
|
||||
}
|
||||
|
||||
public bool CopyFilesToDirectory(IEnumerable<string> filePaths, string directoryPath)
|
||||
{
|
||||
string currentFile = null;
|
||||
try
|
||||
{
|
||||
foreach (var file in filePaths)
|
||||
{
|
||||
currentFile = file;
|
||||
var fileInfo = new FileInfo(file);
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
fileInfo.CopyTo(Path.Join(directoryPath, fileInfo.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Tried to copy {File} but it doesn't exist", file);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unable to copy {File} to {DirectoryPath}", currentFile, directoryPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerable<string> ListDirectory(string rootPath)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ namespace API.Services
|
|||
|
||||
public TokenService(IConfiguration config, UserManager<AppUser> userManager)
|
||||
{
|
||||
|
||||
_userManager = userManager;
|
||||
_key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"]));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue