mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 17:25:32 +00:00
Seperation of concerns: Seperated used File Management form Overall FIle Management
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
8
HaWeb/FileHelpers/IXMLProvider.cs
Normal file
8
HaWeb/FileHelpers/IXMLProvider.cs
Normal 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);
|
||||
}
|
||||
77
HaWeb/FileHelpers/XMLProvider.cs
Normal file
77
HaWeb/FileHelpers/XMLProvider.cs
Normal 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
25
HaWeb/Models/FileList.cs
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class CommentRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class DocumentRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class EditsRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace HaWeb.Settings.XMLRoots;
|
||||
using System.Xml.Linq;
|
||||
using HaWeb.Models;
|
||||
using HaWeb.XMLParser;
|
||||
|
||||
public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot {
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user