Seperation of concerns: Seperated used File Management form Overall FIle Management

This commit is contained in:
schnulller
2022-06-05 15:18:32 +02:00
parent abc27c6d04
commit c95059b2e8
22 changed files with 211 additions and 186 deletions

View File

@@ -21,6 +21,7 @@ namespace HaDocument
private static ILibrary _library;
public static ILibrary Create(IHaDocumentOptions Settings) {
Console.WriteLine("PARSING");
SettingsValidator.Validate(Settings);
_settings = Settings;
_createReader();

View File

@@ -8,6 +8,7 @@ using Microsoft.Net.Http.Headers;
using HaWeb.Filters;
using HaWeb.FileHelpers;
using HaWeb.XMLParser;
using HaWeb.Models;
using System.Text.Json.Serialization;
using System.Text.Json;
using HaDocument.Interfaces;
@@ -25,14 +26,16 @@ public class APIController : Controller {
private readonly long _fileSizeLimit;
private readonly string _targetFilePath;
private readonly IXMLService _xmlService;
private readonly IXMLProvider _xmlProvider;
// Options
private static readonly string[] _permittedExtensions = { ".xml" };
private static readonly FormOptions _defaultFormOptions = new FormOptions();
public APIController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IConfiguration config) {
public APIController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IXMLProvider xmlProvider, IConfiguration config) {
_lib = lib;
_xmlProvider = xmlProvider;
_readerService = readerService;
_xmlService = xmlService;
_fileSizeLimit = config.GetValue<long>("FileSizeLimit");
@@ -117,7 +120,13 @@ public class APIController : Controller {
//// 5. Stage: Saving the File(s)
foreach (var doc in retdocs) {
await _xmlService.UpdateAvailableFiles(doc, _targetFilePath, ModelState);
// Physical saving
var task = _xmlProvider.Save(doc, _targetFilePath, ModelState);
// Setting the new docuemnt as used
_xmlService.Use(doc);
// Unsetting all old docuemnts as ununsed
_xmlService.AutoUse(doc.Prefix);
await task;
if (!ModelState.IsValid) return StatusCode(500, ModelState);
if (docs == null) docs = new List<XMLRootDocument>();
docs.Add(doc);

View File

@@ -18,16 +18,18 @@ public class UploadController : Controller {
private readonly long _fileSizeLimit;
private readonly string _targetFilePath;
private readonly IXMLService _xmlService;
private readonly IXMLProvider _xmlProvider;
// Options
private static readonly string[] _permittedExtensions = { ".xml" };
private static readonly FormOptions _defaultFormOptions = new FormOptions();
public UploadController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IConfiguration config) {
public UploadController(IHaDocumentWrappper lib, IReaderService readerService, IXMLService xmlService, IXMLProvider xmlProvider, IConfiguration config) {
_lib = lib;
_readerService = readerService;
_xmlService = xmlService;
_xmlProvider = xmlProvider;
_fileSizeLimit = config.GetValue<long>("FileSizeLimit");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
_targetFilePath = config.GetValue<string>("StoredFilePathWindows");
@@ -42,23 +44,25 @@ public class UploadController : Controller {
[GenerateAntiforgeryTokenCookie]
public IActionResult Index(string? id) {
if (id != null) {
id = id.ToLower();
var root = _xmlService.GetRoot(id);
if (root == null) return error404();
var roots = _xmlService.GetRoots();
var roots = _xmlService.GetRootsList();
if (roots == null) return error404();
var usedFiles = _xmlService.GetUsed();
var availableFiles = _xmlService.GetAvailableFiles(id);
var usedFiles = _xmlService.GetUsedDictionary();
var availableFiles = _xmlProvider.GetFiles(id);
var model = new UploadViewModel(root.Type, id, roots, availableFiles, usedFiles);
return View("../Admin/Upload/Index", model);
}
else {
var roots = _xmlService.GetRoots();
var roots = _xmlService.GetRootsList();
if (roots == null) return error404();
var usedFiles = _xmlService.GetUsed();
var usedFiles = _xmlService.GetUsedDictionary();
var model = new UploadViewModel("Upload", id, roots, null, usedFiles);
return View("../Admin/Upload/Index", model);

View File

@@ -0,0 +1,8 @@
namespace HaWeb.FileHelpers;
using HaWeb.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding;
public interface IXMLProvider {
public FileList? GetFiles(string prefix);
public Task Save(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState);
}

View File

@@ -0,0 +1,77 @@
namespace HaWeb.FileHelpers;
using Microsoft.Extensions.FileProviders;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using HaWeb.Models;
using HaWeb.XMLParser;
public class XMLProvider : IXMLProvider {
private IFileProvider _fileProvider;
private Dictionary<string, FileList?>? _Files;
private Dictionary<string, IXMLRoot>? _Roots;
public XMLProvider(IFileProvider provider, IXMLService xmlservice) {
_fileProvider = provider;
_Roots = xmlservice.GetRootsDictionary();
_Files = _ScanFiles();
}
public FileList? GetFiles(string prefix)
=> _Files != null && _Files.ContainsKey(prefix) ? _Files[prefix] : null;
// Saves a Document as file and adds it to the collection
public async Task Save(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState) {
var type = doc.Prefix;
var directory = Path.Combine(basefilepath, type);
var path = Path.Combine(directory, doc.FileName);
try {
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
using (var targetStream = System.IO.File.Create(path))
await doc.Save(targetStream, ModelState);
}
catch (Exception ex) {
ModelState.AddModelError("Error", "Speichern der Datei fehlgeschlagen: " + ex.Message);
return;
}
var info = _fileProvider.GetFileInfo(Path.Combine(doc.Prefix, doc.FileName));
if (info == null) {
ModelState.AddModelError("Error", "Auf die neu erstellte Dtaei konnte nicht zugegriffen werden.");
return;
}
doc.SetFile(info);
if (_Files == null) _Files = new Dictionary<string, FileList?>();
if (!_Files.ContainsKey(doc.Prefix)) _Files.Add(doc.Prefix, new FileList(doc.XMLRoot));
_Files[doc.Prefix]!.Add(doc);
}
private Dictionary<string, FileList?>? _ScanFiles() {
if (_Roots == null) return null;
Dictionary<string, FileList?>? res = null;
var dirs = _fileProvider.GetDirectoryContents(string.Empty).Where(x => x.IsDirectory);
foreach (var dir in dirs) {
if (_Roots.ContainsKey(dir.Name)) {
if (_Files == null) _Files = new Dictionary<string, FileList?>();
if (res == null) res = new Dictionary<string, FileList?>();
res.Add(dir.Name, _ScanFiles(dir.Name));
}
}
return res;
}
private FileList? _ScanFiles(string prefix) {
if (_Roots == null) return null;
FileList? res = null;
var files = _fileProvider.GetDirectoryContents(prefix).Where(x => !x.IsDirectory && x.Name.StartsWith(prefix) && x.Name.EndsWith(".xml"));
foreach (var file in files) {
if (_Roots == null || !_Roots.ContainsKey(prefix))
throw new Exception("Attempting to read a File from an unrecognized Prefix: " + prefix);
if (res == null) res = new FileList(_Roots[prefix]);
res.Add(new XMLRootDocument(_Roots[prefix], file));
}
return res;
}
}

25
HaWeb/Models/FileList.cs Normal file
View File

@@ -0,0 +1,25 @@
namespace HaWeb.Models;
using HaWeb.XMLParser;
using System.Text.Json.Serialization;
public class FileList {
private HashSet<XMLRootDocument>? _Files;
[JsonIgnore]
public IXMLRoot XMLRoot { get; private set; }
public FileList(IXMLRoot xmlRoot) {
XMLRoot = xmlRoot;
}
public void Add(XMLRootDocument document) {
if (document.Prefix != XMLRoot.Prefix)
throw new Exception("Diese Liste kann nur Elemente des Typs " + XMLRoot.Prefix + " enthalten");
if (_Files == null) _Files = new HashSet<XMLRootDocument>();
if (!_Files.Contains(document)) _Files.Add(document);
}
public List<XMLRootDocument>? GetFileList()
=> this._Files != null ? this._Files.ToList() : null;
}

View File

@@ -5,11 +5,11 @@ public class UploadViewModel {
public string ActiveTitle { get; private set; }
public string? Prefix { get; private set; }
public List<IXMLRoot>? AvailableRoots { get; private set; }
public List<XMLRootDocument>? AvailableFiles { get; private set; }
public Dictionary<string, List<XMLRootDocument>>? UsedFiles { get; private set; }
public FileList? AvailableFiles { get; private set; }
public Dictionary<string, FileList>? UsedFiles { get; private set; }
public UploadViewModel(string title, string? prefix, List<IXMLRoot>? roots, List<XMLRootDocument>? availableFiles, Dictionary<string, List<XMLRootDocument>>? usedFiles) {
public UploadViewModel(string title, string? prefix, List<IXMLRoot>? roots, FileList? availableFiles, Dictionary<string, FileList>? usedFiles) {
Prefix = prefix;
ActiveTitle = title;
AvailableRoots = roots;

View File

@@ -1,13 +1,14 @@
namespace HaWeb.XMLParser;
namespace HaWeb.Models;
using System.Xml.Linq;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.FileProviders;
using HaWeb.XMLParser;
public class XMLRootDocument {
private XElement? _Element;
private string? _filename;
private IXMLService _xmlService;
public IXMLRoot XMLRoot { get; private set; }
[JsonIgnore]
public XElement Root {
@@ -31,21 +32,20 @@ public class XMLRootDocument {
public IFileInfo? File { get; private set; }
public string Prefix { get; private set; }
public DateTime Date { get; private set; }
public bool Used { get; private set; } = false;
public (string?, string?) IdentificationString { get; private set; }
[JsonIgnore]
public List<(string, string)>? Fields { get; set; }
public List<(string, string?)>? Fields { get; set; }
// Entry point for file reading
public XMLRootDocument(IXMLService xmlService, IFileInfo file) {
_xmlService = xmlService;
public XMLRootDocument(IXMLRoot xmlRoot, IFileInfo file) {
XMLRoot = xmlRoot;
Prefix = xmlRoot.Prefix;
SetFile(file);
}
// Entry point for XML upload reading
public XMLRootDocument(IXMLService xmlService, string prefix, (string?, string?) idString, XElement element) {
_xmlService = xmlService;
public XMLRootDocument(IXMLRoot xmlRoot, string prefix, (string?, string?) idString, XElement element) {
XMLRoot = xmlRoot;
Prefix = prefix;
IdentificationString = idString;
Date = DateTime.Today;
@@ -58,13 +58,6 @@ public class XMLRootDocument {
_GenerateFieldsFromFilename(file.Name);
}
public void SetUsed(bool used) {
Used = used;
if (used && _Element == null) {
_GetElement();
}
}
private string _CreateFilename() {
var filename = _removeInvalidChars(Prefix) + "_";
if (!String.IsNullOrWhiteSpace(IdentificationString.Item1)) {
@@ -101,7 +94,7 @@ public class XMLRootDocument {
if (File == null || String.IsNullOrWhiteSpace(File.PhysicalPath) || !File.Exists)
throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden.");
var root = _xmlService.GetRoot(Prefix);
var root = XMLRoot;
if (root == null)
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
@@ -123,7 +116,7 @@ public class XMLRootDocument {
}
public async Task Save(Stream stream, ModelStateDictionary state) {
var root = _xmlService.GetRoot(Prefix);
var root = XMLRoot;
if (root == null) {
state.AddModelError("Error", "No corresponding Root Element found.");
return;

View File

@@ -2,6 +2,7 @@ using HaXMLReader;
using HaXMLReader.Interfaces;
using HaDocument.Interfaces;
using HaWeb.XMLParser;
using HaWeb.FileHelpers;
using Microsoft.FeatureManagement;
using System.Runtime.InteropServices;
using Microsoft.Extensions.FileProviders;
@@ -13,6 +14,7 @@ builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
// // To get files from a path provided by configuration:
// TODO: Test Read / Write Access
string? filepath = null;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
filepath = builder.Configuration.GetValue<string>("StoredFilePathWindows");
@@ -27,10 +29,10 @@ if (filepath == null) {
var physicalProvider = new PhysicalFileProvider(filepath);
builder.Services.AddSingleton<IFileProvider>(physicalProvider);
builder.Services.AddSingleton<HaWeb.FileHelpers.IHaDocumentWrappper, HaWeb.FileHelpers.HaDocumentWrapper>();
builder.Services.AddTransient<IReaderService, ReaderService>();
builder.Services.AddSingleton<IXMLProvider, XMLProvider>();
builder.Services.AddSingleton<IXMLService, XMLService>();
builder.Services.AddFeatureManagement();
@@ -45,7 +47,6 @@ if (!app.Environment.IsDevelopment())
app.UseHttpsRedirection();
}
// app.UseWebOptimizer();
app.UseAuthorization();
app.UseStaticFiles();
app.MapControllers();

View File

@@ -44,3 +44,6 @@ TODO pills are not mobile friendly (hover / click)
TODO Evtl alignment von center / right an der letzten oder nächsten zeile
TODO Abhärten des Konstruktors von XMLRootDokument für von außerhalb platzierte Dokumente
TODO XML-Check im Client
TODO Lock für die Liste
TODO Up-Button
TODO Neue Forschungsliteratur einsenden

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class CommentRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class DocumentRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class EditsRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -1,5 +1,6 @@
namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using HaWeb.Models;
using HaWeb.XMLParser;
public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot {

View File

@@ -6,14 +6,14 @@
<div class="ha-uploadfieldname">@item.Type</div>
@if (Model.UsedFiles != null && Model.UsedFiles.ContainsKey(item.Prefix)) {
<div class="ha-uploadusedfiles">
@foreach(var file in Model.UsedFiles[item.Prefix]) {
@if (file == Model.UsedFiles[item.Prefix].Last())
@foreach(var file in Model.UsedFiles[item.Prefix].GetFileList()!) {
@if (file == Model.UsedFiles[item.Prefix].GetFileList()!.Last())
{
<span class="ha-uploadusedfile">@file.File.Name</span>
<span class="ha-uploadusedfile">@file.FileName</span>
}
else
{
<span class="ha-uploadusedfile">@file.File.Name;</span>
<span class="ha-uploadusedfile">@file.FileName;</span>
}
}
</div>
@@ -56,7 +56,7 @@
<div class="ha-usedfilesheader">
<div class="ha-usedfilesheaderlist">
@if(Model.UsedFiles != null && Model.UsedFiles.ContainsKey(Model.Prefix)) {
@foreach (var item in Model.UsedFiles[Model.Prefix])
@foreach (var item in Model.UsedFiles[Model.Prefix].GetFileList())
{
<div class="ha-usedfilesheaderfile">@item.File.Name</div>
}

View File

@@ -1,6 +1,7 @@
namespace HaWeb.XMLParser;
using System.Xml.Linq;
using System.Xml.XPath;
using HaWeb.Models;
public interface IXMLRoot {
// Name of the IXMLRoot

View File

@@ -1,12 +1,15 @@
namespace HaWeb.XMLParser;
using System.Xml.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using HaWeb.Models;
public interface IXMLService {
public IXMLRoot? GetRoot(string name);
public List<IXMLRoot>? GetRoots();
public List<IXMLRoot>? GetRootsList();
public Dictionary<string, IXMLRoot>? GetRootsDictionary();
public Task<List<XMLRootDocument>?> ProbeHamannFile(XDocument document, ModelStateDictionary ModelState);
public Task UpdateAvailableFiles(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState);
public Dictionary<string, List<XMLRootDocument>> GetUsed();
public List<XMLRootDocument>? GetAvailableFiles(string prefix);
public Dictionary<string, FileList?>? GetUsedDictionary();
public void Use(XMLRootDocument doc);
public void AutoUse(string prefix);
public void AutoUse(FileList filelist);
}

View File

@@ -1,35 +1,14 @@
namespace HaWeb.XMLParser;
using HaWeb.Settings.XMLRoots;
using System.Xml.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.FileProviders;
using Microsoft.FeatureManagement;
using HaWeb.Models;
public class XMLService : IXMLService {
private Dictionary<string, List<XMLRootDocument>?>? _availableFilesObj;
private Dictionary<string, List<XMLRootDocument>?>? _availableFiles {
get {
if (_availableFilesObj == null) {
_availableFilesObj = _GetAvailableFiles();
AutoDetermineUsed();
}
return _availableFilesObj;
} }
private IFileProvider _fileProvider;
private IFeatureManager _featureManager;
private Dictionary<string, FileList?>? _Used;
private Dictionary<string, IXMLRoot>? _Roots;
public bool UploadEnabled = false;
public bool UpdateEnabled = false;
public XMLService(IFileProvider provider, IFeatureManager featureManager) {
_fileProvider = provider;
_featureManager = featureManager;
if (provider == null)
throw new Exception("To Upload Files you need a FileProvider");
// Getting all classes which implement IXMLRoot for possible upload endpoints
public XMLService() {
// Getting all classes which implement IXMLRoot for possible document endpoints
var types = _GetAllTypesThatImplementInterface<IXMLRoot>().ToList();
types.ForEach( x => {
if (this._Roots == null) this._Roots = new Dictionary<string, IXMLRoot>();
@@ -42,11 +21,14 @@ public class XMLService : IXMLService {
}
public IXMLRoot? GetRoot(string name) {
if (_Roots == null) return null;
_Roots.TryGetValue(name, out var root);
return root;
}
public List<IXMLRoot>? GetRoots() => this._Roots == null ? null : this._Roots.Values.ToList();
public List<IXMLRoot>? GetRootsList() => this._Roots == null ? null : this._Roots.Values.ToList();
public Dictionary<string, IXMLRoot>? GetRootsDictionary() => this._Roots == null ? null : this._Roots;
public async Task<List<XMLRootDocument>?> ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) {
if (document.Root!.Name != "opus") {
@@ -69,72 +51,43 @@ public class XMLService : IXMLService {
return res;
}
public void UpdateAvailableFiles() {
_availableFilesObj = _GetAvailableFiles();
public Dictionary<string, FileList?>? GetUsedDictionary()
=> this._Used;
// Adds a document and sets it to used
public void Use(XMLRootDocument doc) {
if (_Used == null) _Used = new Dictionary<string, FileList?>();
if (!_Used.ContainsKey(doc.Prefix)) _Used.Add(doc.Prefix, new FileList(doc.XMLRoot));
_Used[doc.Prefix]!.Add(doc);
}
public void UpdateAvailableFiles(string prefix) {
if (_availableFilesObj == null) {
UpdateAvailableFiles();
return;
}
if (_availableFilesObj.ContainsKey(prefix))
_availableFilesObj.Remove(prefix);
if (_fileProvider.GetDirectoryContents(prefix).Exists) {
_availableFilesObj.Add(prefix, _GetAvailableFiles(prefix));
// Performs detection of using on the specified document type
public void AutoUse(string prefix) {
if (_Used == null || !_Used.ContainsKey(prefix)) return;
AutoUse(_Used[prefix]!);
}
AutoDetermineUsed(prefix);
// Performs detection of using given a list of files
public void AutoUse(FileList filelist) {
FileList? res = null;
var list = filelist.GetFileList();
var prefix = filelist.XMLRoot.Prefix;
if (list == null) return;
if (_Used != null && _Used.ContainsKey(prefix)) _Used.Remove(prefix);
// TODO: Item1
var lookup = list.ToLookup(x => x.IdentificationString.Item2);
foreach (var idstring in lookup) {
var ordered = idstring.OrderBy(x => x.Date);
if (res == null) res = new FileList(filelist.XMLRoot);
Use(ordered.Last());
}
public List<XMLRootDocument>? GetAvailableFiles(string prefix) {
if (_Roots == null || _availableFiles == null) return null;
if(!_Roots.ContainsKey(prefix) || !_availableFiles.ContainsKey(prefix)) return null;
return _availableFiles[prefix];
}
public async Task UpdateAvailableFiles(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState) {
await _setEnabled();
if (!UploadEnabled) {
ModelState.AddModelError("Error", "The uploading of files is deactivated");
return;
}
await _Save(doc, basefilepath, ModelState);
if (!ModelState.IsValid) return;
UpdateAvailableFiles(doc.Prefix);
}
private async Task _Save(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState) {
var type = doc.Prefix;
var directory = Path.Combine(basefilepath, type);
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
var path = Path.Combine(directory, doc.FileName);
try {
using (var targetStream = System.IO.File.Create(path))
await doc.Save(targetStream, ModelState);
}
catch (Exception ex) {
ModelState.AddModelError("Error", "Speichern der Datei fehlgeschlagen: " + ex.Message);
return;
}
var info = _fileProvider.GetFileInfo(Path.Combine(doc.Prefix, doc.FileName));
if (info == null) {
ModelState.AddModelError("Error", "Auf die neu erstellte Dtaei konnte nicht zugegriffen werden");
return;
}
doc.SetFile(info);
UpdateAvailableFiles(type);
}
private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) {
var doc = new XMLRootDocument(this, Root.Prefix, Root.GenerateIdentificationString(element), element);
var doc = new XMLRootDocument(Root, Root.Prefix, Root.GenerateIdentificationString(element), element);
doc.Fields = Root.GenerateFields(doc);
return doc;
}
@@ -145,64 +98,4 @@ public class XMLService : IXMLService {
.GetTypes()
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
}
private async Task _setEnabled() {
if (await _featureManager.IsEnabledAsync(HaWeb.Features.UploadService))
UploadEnabled = true;
if (await _featureManager.IsEnabledAsync(HaWeb.Features.UpdateService))
UpdateEnabled = true;
}
private Dictionary<string, List<XMLRootDocument>?>? _GetAvailableFiles() {
if (_Roots == null) return null;
Dictionary<string, List<XMLRootDocument>?>? res = null;
var dirs = _fileProvider.GetDirectoryContents(string.Empty).Where(x => x.IsDirectory);
foreach(var dir in dirs) {
if(_Roots.ContainsKey(dir.Name)) {
if (res == null) res = new Dictionary<string, List<XMLRootDocument>?>();
res.Add(dir.Name, _GetAvailableFiles(dir.Name));
}
}
return res;
}
private List<XMLRootDocument>? _GetAvailableFiles(string prefix) {
List<XMLRootDocument>? res = null;
var files = _fileProvider.GetDirectoryContents(prefix).Where(x => !x.IsDirectory && x.Name.StartsWith(prefix) && x.Name.EndsWith(".xml"));
foreach (var file in files) {
if (res == null) res = new List<XMLRootDocument>();
res.Add(new XMLRootDocument(this, file));
}
return res;
}
public void AutoDetermineUsed() {
if (_availableFilesObj == null) return;
foreach (var (prefix, _) in _availableFilesObj)
AutoDetermineUsed(prefix);
}
public void AutoDetermineUsed(string prefix) {
if (_Roots == null || _availableFilesObj == null) return;
_Roots.TryGetValue(prefix, out var root);
_availableFilesObj.TryGetValue(prefix, out var files);
if (files == null || root == null) return;
//TODO: Item1
var lookup = files.ToLookup(x => x.IdentificationString.Item2);
foreach (var idstring in lookup) {
var ordered = idstring.OrderBy(x => x.Date);
ordered.Last().SetUsed(true);
ordered.Take(ordered.Count() - 1).ToList().ForEach(x => x.SetUsed(false));
}
}
public Dictionary<string, List<XMLRootDocument>>? GetUsed() {
if (_availableFiles == null) return null;
return _availableFiles
.Where(x => x.Value != null)
.Select(x => x.Value!.Where(x => x.Used).ToList())
.Where(x => x.Any())
.ToDictionary(x => x.First().Prefix);
}
}

View File

@@ -30,7 +30,7 @@ namespace HamannPrinter
EndYearTextBox.Text = "1762"; // DEV
XmlFileBox.Text = @"D:\dev\source\hamann-ausgabe-core\XML\XML"; // DEV
OutputDirBox.Text = @"D:\dev\source\hamann-ausgabe-core\XML\Ausg"; // DEV
Act(); // DEV
//Act(); // DEV
}
private void SingleDocChanged(object sender, RoutedEventArgs e)