Added Upload functionality; still a bit janky in selecting the files to use...

This commit is contained in:
schnulller
2022-06-05 21:04:22 +02:00
parent 0d33dcd4e5
commit b5aae5ddf0
27 changed files with 188456 additions and 40 deletions

View File

@@ -156,6 +156,8 @@ namespace HaDocument.Reactors {
(_availableVolumes == null && _availableYearRange.Item1 == 0 && _availableYearRange.Item2 == 0) (_availableVolumes == null && _availableYearRange.Item1 == 0 && _availableYearRange.Item2 == 0)
) { ) {
var ZHInfo = !inZH ? null : new ZHInfo(AltLineNumbering, dateChanged, Volume, Page); var ZHInfo = !inZH ? null : new ZHInfo(AltLineNumbering, dateChanged, Volume, Page);
if (Autopsic == "0")
System.Diagnostics.Debugger.Break();
var meta = new Meta( var meta = new Meta(
Index, Index,
Autopsic, Autopsic,

View File

@@ -50,7 +50,7 @@ public class APIController : Controller {
[Route("API/Syntaxcheck/{id}")] [Route("API/Syntaxcheck/{id}")]
[DisableFormValueModelBinding] [DisableFormValueModelBinding]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
[FeatureGate(Features.AdminService)] [FeatureGate(Features.UploadService, Features.AdminService)]
public async Task<IActionResult> SyntaxCheck(string id) { public async Task<IActionResult> SyntaxCheck(string id) {
return Ok(); return Ok();
} }
@@ -60,8 +60,8 @@ public class APIController : Controller {
[Route("API/Upload")] [Route("API/Upload")]
[DisableFormValueModelBinding] [DisableFormValueModelBinding]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
[FeatureGate(Features.UploadService)] [FeatureGate(Features.UploadService, Features.AdminService)]
public async Task<IActionResult> Upload(string? id) { public async Task<IActionResult> Upload() {
List<XMLRootDocument>? docs = null; List<XMLRootDocument>? docs = null;
//// 1. Stage: Check Request format and request spec //// 1. Stage: Check Request format and request spec
// Checks the Content-Type Field (must be multipart + Boundary) // Checks the Content-Type Field (must be multipart + Boundary)
@@ -114,19 +114,18 @@ public class APIController : Controller {
return UnprocessableEntity(ModelState); return UnprocessableEntity(ModelState);
//// 4. Stage: Is it a Hamann-Document? What kind? //// 4. Stage: Is it a Hamann-Document? What kind?
var retdocs = await _xmlService.ProbeHamannFile(xdocument, ModelState); var retdocs = _xmlService.ProbeHamannFile(xdocument, ModelState);
if (!ModelState.IsValid || retdocs == null || !retdocs.Any()) if (!ModelState.IsValid || retdocs == null || !retdocs.Any())
return UnprocessableEntity(ModelState); return UnprocessableEntity(ModelState);
//// 5. Stage: Saving the File(s) //// 5. Stage: Saving the File(s)
foreach (var doc in retdocs) { foreach (var doc in retdocs) {
// Physical saving // Physical saving
var task = _xmlProvider.Save(doc, _targetFilePath, ModelState); await _xmlProvider.Save(doc, _targetFilePath, ModelState);
// Setting the new docuemnt as used // Setting the new docuemnt as used
_xmlService.Use(doc); _xmlService.Use(doc);
// Unsetting all old docuemnts as ununsed // Unsetting all old docuemnts as ununsed
_xmlService.AutoUse(doc.Prefix); _xmlService.AutoUse(doc.Prefix);
await task;
if (!ModelState.IsValid) return StatusCode(500, ModelState); if (!ModelState.IsValid) return StatusCode(500, ModelState);
if (docs == null) docs = new List<XMLRootDocument>(); if (docs == null) docs = new List<XMLRootDocument>();
docs.Add(doc); docs.Add(doc);
@@ -137,6 +136,7 @@ public class APIController : Controller {
section = await reader.ReadNextSectionAsync(); section = await reader.ReadNextSectionAsync();
} catch (Exception ex) { } catch (Exception ex) {
ModelState.AddModelError("Error", "The Request is bad: " + ex.Message); ModelState.AddModelError("Error", "The Request is bad: " + ex.Message);
return BadRequest(ModelState);
} }
} }
@@ -151,4 +151,24 @@ public class APIController : Controller {
string json = JsonSerializer.Serialize(docs); string json = JsonSerializer.Serialize(docs);
return Created(nameof(UploadController), json); return Created(nameof(UploadController), json);
} }
//// PUBLISH ////
[HttpPost]
[Route("API/LocalPublish")]
[DisableFormValueModelBinding]
[ValidateAntiForgeryToken]
[FeatureGate(Features.LocalPublishService, Features.AdminService, Features.UploadService)]
public async Task<IActionResult> LocalPublish() {
var element = _xmlService.MergeUsedDocuments(ModelState);
if (!ModelState.IsValid || element == null)
return BadRequest(ModelState);
var savedfile = await _xmlProvider.SaveHamannFile(element, _targetFilePath, ModelState);
if (!ModelState.IsValid || savedfile == null)
return BadRequest(ModelState);
_ = _lib.SetLibrary(savedfile.PhysicalPath, ModelState);
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok();
}
} }

View File

@@ -31,8 +31,8 @@ public class Briefecontroller : Controller {
// Normalisation and Validation, (some) data aquisition // Normalisation and Validation, (some) data aquisition
if (id == null) return Redirect(url + defaultID); if (id == null) return Redirect(url + defaultID);
this.id = id.ToLower(); id = id.ToLower();
var preliminarymeta = lib.Metas.Where(x => x.Value.Autopsic == this.id); var preliminarymeta = lib.Metas.Where(x => x.Value.Autopsic == id);
if (preliminarymeta == null || !preliminarymeta.Any()) return error404(); if (preliminarymeta == null || !preliminarymeta.Any()) return error404();
// Get all neccessary data // Get all neccessary data
@@ -54,7 +54,7 @@ public class Briefecontroller : Controller {
// Model creation // Model creation
var hasMarginals = false; var hasMarginals = false;
if (marginals != null && marginals.Any()) hasMarginals = true; if (marginals != null && marginals.Any()) hasMarginals = true;
var model = new BriefeViewModel(this.id, index, generateMetaViewModel(lib, meta, hasMarginals)); var model = new BriefeViewModel(id, index, generateMetaViewModel(lib, meta, hasMarginals));
if (nextmeta != null) model.MetaData.Next = (generateMetaViewModel(lib, nextmeta, false), url + nextmeta.Autopsic); if (nextmeta != null) model.MetaData.Next = (generateMetaViewModel(lib, nextmeta, false), url + nextmeta.Autopsic);
if (prevmeta != null) model.MetaData.Prev = (generateMetaViewModel(lib, prevmeta, false), url + prevmeta.Autopsic); if (prevmeta != null) model.MetaData.Prev = (generateMetaViewModel(lib, prevmeta, false), url + prevmeta.Autopsic);
if (hands != null && hands.Any()) model.ParsedHands = HaWeb.HTMLHelpers.LetterHelpers.CreateHands(lib, hands); if (hands != null && hands.Any()) model.ParsedHands = HaWeb.HTMLHelpers.LetterHelpers.CreateHands(lib, hands);

View File

@@ -1,5 +1,6 @@
namespace HaWeb.FileHelpers; namespace HaWeb.FileHelpers;
using HaDocument.Interfaces; using HaDocument.Interfaces;
using Microsoft.AspNetCore.Mvc.ModelBinding;
public class HaDocumentWrapper : IHaDocumentWrappper { public class HaDocumentWrapper : IHaDocumentWrappper {
public ILibrary Library; public ILibrary Library;
@@ -13,6 +14,18 @@ public class HaDocumentWrapper : IHaDocumentWrappper {
return Library; return Library;
} }
public ILibrary? SetLibrary(string filepath, ModelStateDictionary ModelState) {
try
{
Library = HaDocument.Document.Create(new HaWeb.Settings.HaDocumentOptions() { HamannXMLFilePath = filepath });
}
catch (Exception ex) {
ModelState.AddModelError("Error:", "Das Dokument konnte nicht geparst werden: " + ex.Message);
return null;
}
return Library;
}
public ILibrary GetLibrary() { public ILibrary GetLibrary() {
return Library; return Library;
} }

View File

@@ -1,7 +1,9 @@
namespace HaWeb.FileHelpers; namespace HaWeb.FileHelpers;
using HaDocument.Interfaces; using HaDocument.Interfaces;
using Microsoft.AspNetCore.Mvc.ModelBinding;
public interface IHaDocumentWrappper { public interface IHaDocumentWrappper {
public ILibrary SetLibrary(); public ILibrary SetLibrary();
public ILibrary? SetLibrary(string filepath, ModelStateDictionary ModelState);
public ILibrary GetLibrary(); public ILibrary GetLibrary();
} }

View File

@@ -1,8 +1,12 @@
namespace HaWeb.FileHelpers; namespace HaWeb.FileHelpers;
using Microsoft.Extensions.FileProviders;
using System.Xml.Linq;
using HaWeb.Models; using HaWeb.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
public interface IXMLProvider { public interface IXMLProvider {
public FileList? GetFiles(string prefix); public FileList? GetFiles(string prefix);
public Task Save(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState); public Task Save(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState);
public Task<IFileInfo?> SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState);
} }

View File

@@ -3,11 +3,13 @@ using Microsoft.Extensions.FileProviders;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using HaWeb.Models; using HaWeb.Models;
using HaWeb.XMLParser; using HaWeb.XMLParser;
using System.Xml.Linq;
public class XMLProvider : IXMLProvider { public class XMLProvider : IXMLProvider {
private IFileProvider _fileProvider; private IFileProvider _fileProvider;
private Dictionary<string, FileList?>? _Files; private Dictionary<string, FileList?>? _Files;
private Dictionary<string, IXMLRoot>? _Roots; private Dictionary<string, IXMLRoot>? _Roots;
private List<IFileInfo>? _HamannFiles;
public XMLProvider(IFileProvider provider, IXMLService xmlservice) { public XMLProvider(IFileProvider provider, IXMLService xmlservice) {
_fileProvider = provider; _fileProvider = provider;
@@ -53,6 +55,35 @@ public class XMLProvider : IXMLProvider {
_Files[doc.Prefix]!.Add(doc); _Files[doc.Prefix]!.Add(doc);
} }
public async Task<IFileInfo?> SaveHamannFile(XElement element, string basefilepath, ModelStateDictionary ModelState) {
var date = DateTime.Now;
var filename = "hamann_" + date.Year + "-" + date.Month + "-" + date.Day + ".xml";
var directory = Path.Combine(basefilepath, "hamann");
var path = Path.Combine(directory, filename);
try {
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
using (var targetStream = System.IO.File.Create(path))
await element.SaveAsync(targetStream, SaveOptions.DisableFormatting, new CancellationToken());
}
catch (Exception ex) {
ModelState.AddModelError("Error", "Die Datei konnte nicht gespeichert werden: " + ex.Message);
return null;
}
var info = _fileProvider.GetFileInfo(Path.Combine("hamann", filename));
if (info == null) {
ModelState.AddModelError("Error", "Auf die neu erstellte Dtaei konnte nicht zugegriffen werden.");
return null;
}
if (_HamannFiles == null) _HamannFiles = new List<IFileInfo>();
_HamannFiles.Add(info);
return info;
}
private Dictionary<string, FileList?>? _ScanFiles() { private Dictionary<string, FileList?>? _ScanFiles() {
if (_Roots == null) return null; if (_Roots == null) return null;
Dictionary<string, FileList?>? res = null; Dictionary<string, FileList?>? res = null;

View File

@@ -53,7 +53,7 @@ public class XMLRootDocument {
XMLRoot = xmlRoot; XMLRoot = xmlRoot;
Prefix = prefix; Prefix = prefix;
IdentificationString = idString; IdentificationString = idString;
Date = DateTime.Today; Date = DateTime.Now;
_Element = element; _Element = element;
} }

View File

@@ -1,7 +1,14 @@
namespace HaWeb; namespace HaWeb;
public static class Features { public static class Features {
// If Admin Pages are reachable
public const string AdminService = "AdminService"; public const string AdminService = "AdminService";
// If the Upload of files is possible, also syntaxcheck and crossreference check
public const string UploadService = "UploadService"; public const string UploadService = "UploadService";
public const string UpdateService = "UpdateService"; // If uploaded Files can be published locally
public const string LocalPublishService = "LocalPublishService";
// If this server can publish files remotely (e.g. www.hamann-ausgabe.de)
public const string RemotePublishService = "RemotePublishService";
// If this server can accept files from a remote authenticated source
public const string RemotePublishSourceService = "RemotePublishSourceService";
} }

View File

@@ -5,5 +5,5 @@ class HaDocumentOptions : IHaDocumentOptions {
public string HamannXMLFilePath { get; set; } = @"Hamann.xml"; public string HamannXMLFilePath { get; set; } = @"Hamann.xml";
public string[] AvailableVolumes { get; set; } = { }; public string[] AvailableVolumes { get; set; } = { };
public bool NormalizeWhitespace { get; set; } = true; public bool NormalizeWhitespace { get; set; } = true;
public (int, int) AvailableYearRange {get; set; } = (1751, 1788); public (int, int) AvailableYearRange {get; set; } = (1700, 1790);
} }

View File

@@ -43,4 +43,10 @@ public class CommentRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("kommentare") == null)
file.AddFirst(new XElement("kommentare"));
file.Element("kommentare")!.AddFirst(document.Root);
}
} }

View File

@@ -13,12 +13,12 @@ public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {
return false; return false;
}; };
public Func<XElement, string?> GetKey { get; } = (elem) => { // public Func<XElement, string?> GetKey { get; } = (elem) => {
var index = elem.Attribute("ref"); // var index = elem.Attribute("ref");
if (index != null && !String.IsNullOrWhiteSpace(index.Value)) // if (index != null && !String.IsNullOrWhiteSpace(index.Value))
return index.Value; // return index.Value;
else return null; // else return null;
}; // };
public List<(string, string?)>? GenerateFields(XMLRootDocument document) { public List<(string, string?)>? GenerateFields(XMLRootDocument document) {
return null; return null;
@@ -38,4 +38,14 @@ public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("descriptions") == null)
file.AddFirst(new XElement("descriptions"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("descriptions");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -2,6 +2,7 @@ namespace HaWeb.Settings.XMLRoots;
using System.Xml.Linq; using System.Xml.Linq;
using HaWeb.Models; using HaWeb.Models;
using HaWeb.XMLParser; using HaWeb.XMLParser;
using System.IO;
public class DocumentRoot : HaWeb.XMLParser.IXMLRoot { public class DocumentRoot : HaWeb.XMLParser.IXMLRoot {
public string Type { get; } = "Brieftext"; public string Type { get; } = "Brieftext";
@@ -38,4 +39,14 @@ public class DocumentRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("document") == null)
file.AddFirst(new XElement("document"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("document");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -38,4 +38,14 @@ public class EditsRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("edits") == null)
file.AddFirst(new XElement("edits"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("edits");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -38,4 +38,14 @@ public class MarginalsRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("marginalien") == null)
file.AddFirst(new XElement("marginalien"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("marginalien");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -36,4 +36,14 @@ public class ReferencesRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("definitions") == null)
file.AddFirst(new XElement("definitions"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("definitions");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -38,4 +38,13 @@ public class TraditionsRoot : HaWeb.XMLParser.IXMLRoot {
return opus; return opus;
} }
public void MergeIntoFile(XElement file, XMLRootDocument document) {
if (file.Element("traditions") == null)
file.AddFirst(new XElement("traditions"));
var elements = document.Root.Elements().Where(x => IsCollectedObject(x));
var root = file.Element("traditions");
foreach (var element in elements) {
root!.Add(element);
}
}
} }

View File

@@ -36,14 +36,13 @@
</div> </div>
</form> </form>
<form class="ha-publishform" action="Upload" method="post" enctype="multipart/form-data"> <form class="ha-publishform" id="ha-publishform" asp-controller="API" asp-action="LocalPublish" method="post" enctype="multipart/form-data">
<label class="filelabel"> <label class="ha-uploadfilelabel" id="ha-uploadfilelabel">
<input class="hidden" type="file" accept=".xml" name="file" />
Veröffentlichen Veröffentlichen
</label> </label>
<div class="ha-uploadmessage"> <div class="ha-publishmessage" id="ha-publishmessage">
@* Fehler!<br/> *@
<output form="uploadForm" name="result"></output> <output form="uploadForm" name="publish-result"></output>
</div> </div>
</form> </form>
</div> </div>
@@ -119,6 +118,27 @@
ev.preventDefault(); ev.preventDefault();
} }
const LOCALPUBLISHSubmit = async function (oFormElement) {
var fd = new FormData();
document.getElementById("ha-publishmessage").style.opacity = "0";
await fetch(oFormElement.action, {
method: 'POST',
headers: {
'RequestVerificationToken': getCookie('RequestVerificationToken')
}
})
.then(response => response.json())
.then(json => {
if ("Error" in json) {
document.getElementById("ha-publishmessage").style.opacity = "1";
oFormElement.elements.namedItem("update-result").value = json.Error;
} else {
oFormElement.elements.namedItem("update-result").value = "Erfolg!";
}
})
.catch ((e) => console.log('Error:', e))
}
const UPLOADSubmit = async function (oFormElement, file = null) { const UPLOADSubmit = async function (oFormElement, file = null) {
var fd = new FormData(); var fd = new FormData();
if (file !== null) fd.append("file", file); if (file !== null) fd.append("file", file);
@@ -159,6 +179,9 @@
var submitelement = document.getElementById("file"); var submitelement = document.getElementById("file");
var formelement = document.getElementById("uploadForm"); var formelement = document.getElementById("uploadForm");
var dropzone = document.getElementById("dropzone"); var dropzone = document.getElementById("dropzone");
var publishelement = document.getElementById("ha-publishform");
var publishbutton = document.getElementById("ha-uploadfilelabel");
publishbutton.addEventListener("click", () => LOCALPUBLISHSubmit(publishelement));
submitelement.addEventListener("change", () => UPLOADSubmit(formelement)); submitelement.addEventListener("change", () => UPLOADSubmit(formelement));
dropzone.addEventListener("drop", (ev) => dropHandler(formelement, ev, dropzone)); dropzone.addEventListener("drop", (ev) => dropHandler(formelement, ev, dropzone));
dropzone.addEventListener("dragover", (ev) => dragOverHandler(ev, dropzone)); dropzone.addEventListener("dragover", (ev) => dragOverHandler(ev, dropzone));

View File

@@ -17,7 +17,7 @@ public interface IXMLRoot {
public abstract Predicate<XElement> IsCollectedObject { get; } public abstract Predicate<XElement> IsCollectedObject { get; }
// Gets the Key of a collected object // Gets the Key of a collected object
public abstract Func<XElement, string?> GetKey { get; } // public abstract Func<XElement, string?> GetKey { get; }
// Can the Root be found within that document? // Can the Root be found within that document?
public List<XElement>? IsTypeOf(XElement root) { public List<XElement>? IsTypeOf(XElement root) {
@@ -45,18 +45,20 @@ public interface IXMLRoot {
// Further deciding which of two documents replaces which // Further deciding which of two documents replaces which
public abstract bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2); public abstract bool Replaces(XMLRootDocument doc1, XMLRootDocument doc2);
public Dictionary<string, XElement>? GetCollectedObjects(XMLRootDocument document) { // public Dictionary<string, XElement>? GetCollectedObjects(XMLRootDocument document) {
Dictionary<string, XElement>? ret = null; // Dictionary<string, XElement>? ret = null;
var root = document.Root; // var root = document.Root;
root.Elements().Where(x => this.IsCollectedObject(x)).ToList().ForEach(x => { // root.Elements().Where(x => this.IsCollectedObject(x)).ToList().ForEach(x => {
var id = this.GetKey(x); // var id = this.GetKey(x);
if (id != null) { // if (id != null) {
if (ret == null) ret = new Dictionary<string, XElement>(); // if (ret == null) ret = new Dictionary<string, XElement>();
ret.Add(id, x); // ret.Add(id, x);
} // }
}); // });
return ret; // return ret;
} // }
public abstract XElement CreateHamannDocument(XElement element); public abstract XElement CreateHamannDocument(XElement element);
public abstract void MergeIntoFile(XElement file, XMLRootDocument document);
} }

View File

@@ -7,8 +7,9 @@ public interface IXMLService {
public IXMLRoot? GetRoot(string name); public IXMLRoot? GetRoot(string name);
public List<IXMLRoot>? GetRootsList(); public List<IXMLRoot>? GetRootsList();
public Dictionary<string, IXMLRoot>? GetRootsDictionary(); public Dictionary<string, IXMLRoot>? GetRootsDictionary();
public Task<List<XMLRootDocument>?> ProbeHamannFile(XDocument document, ModelStateDictionary ModelState); public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState);
public Dictionary<string, FileList?>? GetUsedDictionary(); public Dictionary<string, FileList?>? GetUsedDictionary();
public XElement? MergeUsedDocuments(ModelStateDictionary ModelState);
public void Use(XMLRootDocument doc); public void Use(XMLRootDocument doc);
public void AutoUse(string prefix); public void AutoUse(string prefix);
public void AutoUse(FileList filelist); public void AutoUse(FileList filelist);

View File

@@ -30,7 +30,7 @@ public class XMLService : IXMLService {
public Dictionary<string, IXMLRoot>? GetRootsDictionary() => this._Roots == null ? null : this._Roots; public Dictionary<string, IXMLRoot>? GetRootsDictionary() => this._Roots == null ? null : this._Roots;
public async Task<List<XMLRootDocument>?> ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) { public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) {
if (document.Root!.Name != "opus") { if (document.Root!.Name != "opus") {
ModelState.AddModelError("Error", "A valid Hamann-Docuemnt must begin with <opus>"); ModelState.AddModelError("Error", "A valid Hamann-Docuemnt must begin with <opus>");
return null; return null;
@@ -86,6 +86,27 @@ public class XMLService : IXMLService {
} }
} }
public XElement? MergeUsedDocuments(ModelStateDictionary ModelState) {
if (_Used == null || _Roots == null) {
ModelState.AddModelError("Error", "Keine Dokumente ausgewählt");
return null;
}
var opus = new XElement("opus");
foreach (var category in _Used) {
if (category.Value == null || category.Value.GetFileList() == null || !category.Value.GetFileList()!.Any()) {
ModelState.AddModelError("Error", _Roots![category.Key].Type + " nicht vorhanden.");
return null;
}
var documents = category.Value.GetFileList();
foreach (var document in documents!) {
document.XMLRoot.MergeIntoFile(opus, document);
}
}
return opus;
}
private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) { private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) {
var doc = new XMLRootDocument(Root, Root.Prefix, Root.GenerateIdentificationString(element), element); var doc = new XMLRootDocument(Root, Root.Prefix, Root.GenerateIdentificationString(element), element);
doc.Fields = Root.GenerateFields(doc); doc.Fields = Root.GenerateFields(doc);

View File

@@ -8,7 +8,9 @@
"FeatureManagement": { "FeatureManagement": {
"AdminService": true, "AdminService": true,
"UploadService": true, "UploadService": true,
"UpdateService": false "LocalPublishService": true,
"RemotePublishService": false,
"RemotePublishSourceService": false
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"StoredFilePathLinux": "/home/simon/Downloads/test/", "StoredFilePathLinux": "/home/simon/Downloads/test/",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

23946
XML/neuexml/2022-05-23meta.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,243 @@
<?xml version="1.0" encoding="utf-8"?>
<opus>
<data>
<definitions>
<structureDefs>
<structureDef index="1" level="1" type="volume" friendlyName="Band {1}" />
<structureDef index="2" level="2" type="letter" friendlyName="Brief {2}" />
<structureDef index="3" level="3" type="letterSection" friendlyName="Abschnitt {3}" />
</structureDefs>
<personDefs>
<personDef index="-1" name="Unbekannt" />
<personDef index="1" name="Johann Georg Hamann" vorname="Johann Georg" nachname="Hamann" />
<personDef index="2" name="Gottlob Jacob Sahme" vorname="Gottlob Jacob" nachname="Sahme" />
<personDef index="3" name="Philipp Belger" vorname="Philipp" nachname="Belger" />
<personDef index="4" name="Ein Studienfreund" nachname="Studienfreund"/>
<personDef index="5" name="Johann Christoph Hamann (Vater)" vorname="Johann Christoph" nachname="Hamann" />
<personDef index="6" name="Maria Magdalena Hamann (Mutter)" vorname="Maria Magdalena" nachname="Hamann" />
<personDef index="7" name="Johann Gottlieb Kreutzfeld" vorname="Johann Gottlieb" nachname="Kreutzfeld" />
<personDef index="8" name="Johann Gotthelf Lindner" vorname="Johann Gotthelf" nachname="Lindner" />
<personDef index="9" name="Daniel Pegelow" vorname="Daniel" nachname="Pegelow" />
<personDef index="10" name="Johann Christoph Hamann (Bruder)" vorname="Johann Christoph" nachname="Hamann" />
<personDef index="11" name="Barbara Helena von Budberg, geb. von Zimmermann" vorname="Barbara Helena von" nachname="Budberg" />
<personDef index="12" name="Marianne Lindner, geb. Courtan" vorname="Marianne" nachname="Lindner" />
<personDef index="13" name="Arnold Corman" vorname="Arnold" nachname="Corman" />
<personDef index="14" name="George Bassa" vorname="George" nachname="Bassa" />
<personDef index="15" name="Johann Ehregott Friedrich Lindner" vorname="Johann Ehregott Friedrich" nachname="Lindner" />
<personDef index="16" name="Johann Christoph Berens" vorname="Johann Christoph" nachname="Berens" />
<personDef index="17" name="Arend Berens" vorname="Arend" nachname="Berens" />
<personDef index="18" name="Johann Christoph Ruprecht" vorname="Johann Christoph" nachname="Ruprecht" />
<personDef index="19" name="Senel" vorname="[unbek. Vorname]" nachname="Senel"/>
<personDef index="20" name="" />
<personDef index="21" name="Gottlob Immanuel Lindner" vorname="Gottlob Immanuel" nachname="Lindner" />
<personDef index="22" name="Peter Christoph Baron von Witten" vorname="Peter Christoph Baron von" nachname="Witten"/>
<personDef index="23" name="Joseph Johann Baron von Witten" vorname="Joseph Johann Baron von" nachname="Witten" />
<personDef index="24" name="" />
<personDef index="25" name="" />
<personDef index="26" name="" />
<personDef index="27" name="" />
<personDef index="28" name="" />
<personDef index="29" name="" />
<personDef index="30" name="" />
<personDef index="31" name="Immanuel Kant" vorname="Immanuel" nachname="Kant" />
<personDef index="32" name="," />
<personDef index="33" name="Georg David Kypke" vorname="Georg David" nachname="Kypke" />
<personDef index="34" name="" />
<personDef index="35" name="Christ Anton Tottien" vorname="Christ Anton" nachname="Tottien" />
<personDef index="36" name="Moses Mendelssohn" vorname="Moses" nachname="Mendelssohn" />
<personDef index="37" name="Friedrich Nicolai" vorname="Friedrich" nachname="Nicolai" />
<personDef index="38" name="Sebastian Friedrich Trescho" vorname="Sebastian Friedrich" nachname="Trescho" />
<personDef index="39" name="Friedrich Carl von Moser" vorname="Friedrich Carl von" nachname="Moser" />
<personDef index="40" name="Die Königlich Preußische Kriegs- und Domänen-Kammer zu Königsberg i. Pr." nachname="Kriegs- und Domänenkammer"/>
<personDef index="41" name="Johann Gottfried Herder" vorname="Johann Gottfried" nachname="Herder" />
<personDef index="42" name="Die Königlich Preußische Regierung zu Königsberg in Preußen" nachname="Regierung" />
<personDef index="43" name="" />
<personDef index="44" name="Christian Gottlieb Arndt" vorname="Christian Gottlieb" nachname="Arndt" />
<personDef index="45" name="Johann Christian Buchholtz" vorname="Johann Christian" nachname="Buchholtz" />
<personDef index="46" name="Das Königliche Pupillen-Kollegium" nachname="Pupillen-Kollegium" />
<personDef index="47" name="Friedrich II. (Preußen)" nachname="Friedrich II."/>
<personDef index="48" name="Kriegsrat Hindersin" nachname="Hindersin"/>
<personDef index="49" name="Johann Friedrich Hartknoch" vorname="Johann Friedrich" nachname="Hartknoch" />
<personDef index="50" name="Johann August Eberhard" vorname="Johann August" nachname="Eberhard" />
<personDef index="51" name="Johann Jakob Kanter" vorname="Johann Jakob" nachname="Kanter"/>
<personDef index="52" name="Der Geheime Ausschuß der G. v. V. Frey Mäurer Loge zu Königsberg in Preußen" nachname="Frey Mäurer Loge"/>
<personDef index="53" name="Jacob Friedrich Hinz" vorname="Jacob Friedrich" nachname="Hinz" />
<personDef index="54" name="Carl Theophilus Guichard" vorname="Carl Theophilus" nachname="Guichard" />
<personDef index="55" name="Johann Joachim Christoph Bode" vorname="Johann Joachim Christoph" nachname="Bode" />
<personDef index="56" name="Accise und Zoll-Direktor Stockmar" nachname="Stockmar"/>
<personDef index="57" name="" />
<personDef index="58" name="" />
<personDef index="59" name="Albertine Hartknoch, geb. Toussaint" vorname="Albertine" nachname="Hartknoch" />
<personDef index="60" name="Johann Friedrich Reichardt" vorname="Johann Friedrich" nachname="Reichardt" />
<personDef index="61" name="Matthias Claudius" vorname="Matthias" nachname="Claudius" />
<personDef index="62" name="Johann August Starck" vorname="Johann August" nachname="Starck" />
<personDef index="63" name="Catharina Dorothea Güldenhorn, geb. Herder" vorname="Catharina Dorothea" nachname="Güldenhorn"/>
<personDef index="64" name="Rebecca Claudius" vorname="Rebecca" nachname="Claudius"/>
<personDef index="65" name="" />
<personDef index="66" name="" />
<personDef index="67" name="Sophie Marianne Courtan, geb. Toussaint" vorname="Sophie Marianne" nachname="Courtan"/>
<personDef index="68" name="Die General-Administration" nachname="General-Administration" />
<personDef index="69" name="Witwe Blom" nachname="Blom" />
<personDef index="70" name="" />
<personDef index="71" name="Dr. Laubmeyer" nachname="Laubmeyer"/>
<personDef index="72" name="Christoph Kaufmann" vorname="Christoph" nachname="Kaufmann" />
<personDef index="73" name="Johann Ehrmann" vorname="Johann" nachname="Ehrmann" />
<personDef index="74" name="" />
<personDef index="75" name="vmtl. Samuel Lippmann Löwen" vorname="Samuel Lippmann" nachname="Löwen" />
<personDef index="76" name="Johann Caspar Lavater" vorname="Johann Caspar" nachname="Lavater" />
<personDef index="77" name="Elise Kaufmann, geb. Ziegler" vorname="Elise" nachname="Kaufmann"/>
<personDef index="78" name="Caroline Charlotte Amalie Reichsgräfin von Keyserling, geb. von Truchseß-Waldburg" vorname="Caroline Charlotte Amalie Reichsgräfin von" nachname="Keyserling"/>
<personDef index="79" name="" />
<personDef index="80" name="" />
<personDef index="81" name="" />
<personDef index="82" name="" />
<personDef index="83" name="Hans Jacob von Auerswald" vorname="Hans Jacob von" nachname="Auerswald"/>
<personDef index="84" name="" />
<personDef index="85" name="Caroline Stoltz" vorname="Caroline" nachname="Stoltz"/>
<personDef index="86" name="Johann Caspar Häfeli" vorname="Johann Caspar" nachname="Häfeli"/>
<personDef index="87" name="Christian Jakob Kraus" vorname="Christian Jakob" nachname="Kraus" />
<personDef index="88" name="Friedrich Gottlieb Klopstock" vorname="Friedrich Gottlieb" nachname="Klopstock" />
<personDef index="89" name="Caroline Herder, geb. Flachsland" vorname="Caroline" nachname="Herder"/>
<personDef index="90" name="Johann Friedrich Kleuker" vorname="Johann Friedrich" nachname="Kleuker" />
<personDef index="91" name="Heinrich Christian Reichsgraf von Keyserling" vorname="Heinrich Christian Reichsgraf von" nachname="Keyserling"/>
<personDef index="92" name="Johann Heinrich Voß" vorname="Johann Heinrich" nachname="Voß"/>
<personDef index="93" name="August Herder" vorname="August" nachname="Herder"/>
<personDef index="94" name="Johann Georg Müller" vorname="Johann Georg" nachname="Müller" />
<personDef index="95" name="Friedrich Heinrich Jacobi" vorname="Friedrich Heinrich" nachname="Jacobi" />
<personDef index="96" name="" />
<personDef index="97" name="Johann George Scheffner" vorname="Johann George" nachname="Scheffner" />
<personDef index="98" name="Johann Michael Hamann (Sohn)" vorname="Johann Michael" nachname="Hamann" />
<personDef index="99" name="" />
<personDef index="100" name="Dirk Graf van Hogendorp" vorname="Hogendorp" nachname="Dirk Graf van" />
<personDef index="101" name="Samuel Wolff Friedländer" vorname="Samuel Wolff" nachname="Friedländer" />
<personDef index="102" name="" />
<personDef index="103" name="Susanne Elisabeth Scheffner" vorname="Susanne Elisabeth" nachname="Scheffner" />
<personDef index="104" name="Eberhard Gaupp" vorname="Eberhard" nachname="Gaupp" />
<personDef index="105" name="Christian Hill" vorname="Christian" nachname="Hill" />
<personDef index="106" name="Franz Kaspar Bucholtz" vorname="Franz Kaspar" nachname="Bucholtz" />
<personDef index="107" name="Elisabeth Regina Hamann (Tochter)" vorname="Elisabeth Regina" nachname="Hamann" />
<personDef index="108" name="Die Provinzial-Direktion" nachname="Provinzial-Direktion" />
<personDef index="109" name="" />
<personDef index="110" name="Elisa von der Recke" vorname="Elisa von der" nachname="Recke"/>
<personDef index="111" name="Die Königliche General-Accise- und Zoll-Administration" nachname="General-Accise- und Zoll-Administration"/>
<personDef index="112" name="Heinrich Schenk" vorname="Heinrich" nachname="Schenk"/>
<personDef index="113" name="" />
<personDef index="114" name="Thomas Wizenmann" vorname="Thomas" nachname="Wizenmann"/>
<personDef index="115" name="" />
<personDef index="116" name="Gottfried Leberecht Masius" vorname="Gottfried Leberecht" nachname="Masius" />
<personDef index="117" name="" />
<personDef index="118" name="Finanzrat von Köpke" nachname="Köpke" />
<personDef index="119" name="Minister von Werder" nachname="Werder"/>
<personDef index="120" name="Johann Ernst von Druffel" vorname="Johann Ernst von" nachname="Druffel" />
<personDef index="121" name="Finanzbeamter Gomm" nachname="Gomm"/>
<personDef index="122" name="Fürstin Amalia von Gallitzin" vorname="Fürstin Amalia von" nachname="Gallitzin"/>
<personDef index="123" name="" />
<personDef index="124" name="" />
<personDef index="125" name="Johann Gottlieb Steudel" vorname="Johann Gottlieb" nachname="Steudel" />
<personDef index="126" name="" />
<personDef index="127" name="Abraham Jakob Penzel" vorname="Abraham Jakob" nachname="Penzel"/>
<personDef index="128" name="Johann Ludwig Garbe" vorname="Johann Ludwig" nachname="Garbe"/>
<personDef index="129" name="Martinus Maletius" vorname="Martinus" nachname="Maletius"/>
</personDefs>
<handDefs>
<handDef index="-1" name="Unbekannt" />
<handDef index="1" name="Johann Christoph Hamann (Bruder)" />
<handDef index="2" name="Johann Christoph Hamann (Vater)" />
<handDef index="3" name="Gottlob Immanuel Lindner" />
<handDef index="4" name="Johann Christoph Berens" />
<handDef index="5" name="Georg David Kypke" />
<handDef index="6" name="Moses Mendelssohn" />
<handDef index="7" name="Johann Friedrich Hartknoch" />
<handDef index="8" name="Johann Georg Hamann" />
<handDef index="9" name="Johann Jakob Kanter" />
<handDef index="10" name="Johann Gottlieb Kreutzfeld" />
<handDef index="11" name="Johann Caspar Lavater" />
<handDef index="12" name="Christoph Kaufmann" />
<handDef index="13" name="Elise Kaufmann, geb. Ziegler" />
<handDef index="14" name="Johann Gottfried Herder" />
<handDef index="15" name="Caroline Herder" />
<handDef index="16" name="Johann Ehrmann" />
<handDef index="17" name="Matthias Claudius" />
<handDef index="18" name="Johann Friedrich Kleuker" />
<handDef index="19" name="Friedrich Heinrich Jacobi" />
<handDef index="20" name="Friedrich Nicolai" />
<handDef index="21" name="Daniel Pegelow" />
<handDef index="22" name="Johann Ehrmann oder eine Schreibhilfe Johann Caspar Lavaters" />
<handDef index="23" name="Johann Michael Hamann (Sohn)" />
<handDef index="24" name="Arnold Corman" />
<handDef index="25" name="Franz Kaspar Bucholtz" />
<handDef index="26" name="vermutlich George Bassa" />
<handDef index="27" name="Sophie Marianne Courtan" />
<handDef index="28" name="Christian Jakob Kraus" />
<handDef index="29" name="Helene Jacobi" />
<handDef index="30" name="David Friedländer" />
<handDef index="31" name="August Herder" />
<handDef index="32" name="Heinrich Schenk" />
</handDefs>
<locationDefs>
<locationDef index="-1" name="unbekannt" />
<locationDef index="1" name="Berlin" />
<locationDef index="2" name="Königsberg" />
<locationDef index="3" name="Memel" />
<locationDef index="4" name="Mitau" />
<locationDef index="5" name="Kegeln" />
<locationDef index="6" name="Riga" />
<locationDef index="7" name="Grünhof" />
<locationDef index="8" name="Meyhof" />
<locationDef index="9" name="Berlin" />
<locationDef index="10" name="London" />
<locationDef index="11" name="Berenshof" />
<locationDef index="12" name="Trutenau" />
<locationDef index="13" name="Elbing" />
<locationDef index="14" name="Frankfurt am Main" />
<locationDef index="15" name="Lübeck" />
<locationDef index="16" name="Warschau" />
<locationDef index="17" name="St. Petersburg" />
<locationDef index="18" name="Nantes" />
<locationDef index="19" name="Zürich" />
<locationDef index="20" name="Mohrungen" />
<locationDef index="21" name="Schloß Hegi bei Winterthur" />
<locationDef index="22" name="Weimar" />
<locationDef index="23" name="Bückeburg" />
<locationDef index="24" name="Potsdam" />
<locationDef index="25" name="Hamburg" />
<locationDef index="26" name="Darmstadt" />
<locationDef index="27" name="Narva" />
<locationDef index="28" name="Dessau" />
<locationDef index="29" name="Wandsbeck" />
<locationDef index="30" name="Krappitz" />
<locationDef index="31" name="Leipzig" />
<locationDef index="32" name="Drubenalken" />
<locationDef index="33" name="Eutin" />
<locationDef index="34" name="Pempelfort" />
<locationDef index="35" name="Kapstadt" />
<locationDef index="36" name="Richterswil" />
<locationDef index="37" name="Düsseldorf" />
<locationDef index="38" name="Schaffhausen" />
<locationDef index="39" name="Münster" />
<locationDef index="40" name="Osnabrück" />
<locationDef index="41" name="Richmont" />
<locationDef index="42" name="Magdeburg" />
<locationDef index="43" name="Welbergen" />
</locationDefs>
<sourceDefs>
<!-- Quelle für den gesetzten Text bei Emmendationen.
Wird referenziert durch ref="" in <recte>
Nächstes Mal mit ausgeben! -->
<sourceDef index="1" name="Ohne Beleg emendiert" />
<sourceDef index="2" name="BdI, 1940" />
<sourceDef index="3" name="nur BdI Aufl. 1 (1955): Berichtigungen [abgekürzt: BdI1]" /> <!-- Zum Zeitpunkt des Anlegens der Korrekturverzeichnisse zum 1. Band waren bis auf Brief 111 alle autographen Briefe verschollen. -->
<sourceDef index="4" name="nur BdI Aufl. 2 (1988): Berichtigungen [abgekürzt: BdI2]" />
<sourceDef index="5" name="beide: BdI1 und BdI2 Berichtigungen" />
<sourceDef index="6" name="Autograph" />
<sourceDef index="7" name="Apograph" />
<sourceDef index="8" name="BdII, 1940" />
<sourceDef index="9" name="nur BdII Aufl. 1: Berichtigungen [abgekürzt: BdII1]" />
<sourceDef index="10" name="nur BdII Aufl. 2: Berichtigungen [abgekürzt: BdII2]" />
<sourceDef index="11" name="beide: BdII1 und BdII2 Berichtigungen" />
<sourceDef index="12" name="BdIII: Nachtrag zu BdII [aus einer Abschrift Lavaters] betrifft nur BdII 221f" />
</sourceDefs>
</definitions>
</data>
</opus>

File diff suppressed because it is too large Load Diff