You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
recyclarr/src/TrashLib/Services/CustomFormat/Guide/CustomFormatLoader.cs

60 lines
2.2 KiB

using System.IO.Abstractions;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using Common;
using Common.Extensions;
using Newtonsoft.Json;
using Serilog;
using TrashLib.Services.CustomFormat.Models;
namespace TrashLib.Services.CustomFormat.Guide;
public class CustomFormatLoader : ICustomFormatLoader
{
private readonly ILogger _log;
private readonly ICustomFormatParser _parser;
private readonly ICustomFormatCategoryParser _categoryParser;
public CustomFormatLoader(ILogger log, ICustomFormatParser parser, ICustomFormatCategoryParser categoryParser)
{
_log = log;
_parser = parser;
_categoryParser = categoryParser;
}
public ICollection<CustomFormatData> LoadAllCustomFormatsAtPaths(
IEnumerable<IDirectoryInfo> jsonPaths,
IFileInfo collectionOfCustomFormats)
{
var categories = _categoryParser.Parse(collectionOfCustomFormats).AsReadOnly();
var jsonFiles = JsonUtils.GetJsonFilesInDirectories(jsonPaths, _log);
return jsonFiles.ToObservable()
.Select(x => Observable.Defer(() => LoadJsonFromFile(x, categories)))
.Merge(8)
.NotNull()
.ToEnumerable()
.ToList();
}
private IObservable<CustomFormatData?> LoadJsonFromFile(IFileInfo file,
IReadOnlyCollection<CustomFormatCategoryItem> categories)
{
return Observable.Using(file.OpenText, x => x.ReadToEndAsync().ToObservable())
.Select(x =>
{
var cf = _parser.ParseCustomFormatData(x, file.Name);
var matchingCategory = categories.FirstOrDefault(y =>
{
var fileName = Path.GetFileNameWithoutExtension(cf.FileName);
return y.CfName.EqualsIgnoreCase(cf.Name) || y.CfAnchor.EqualsIgnoreCase(fileName);
});
return cf with {Category = matchingCategory?.CategoryName};
})
.Catch((JsonException e) =>
{
_log.Warning("Failed to parse JSON file: {File} ({Reason})", file.Name, e.Message);
return Observable.Empty<CustomFormatData>();
});
}
}