mirror of
https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
synced 2025-10-29 09:15:33 +00:00
Formatted everything; completed upload capabilities
This commit is contained in:
13
HaWeb/.vscode/launch.json
vendored
13
HaWeb/.vscode/launch.json
vendored
@@ -1,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach",
|
||||||
|
"processName": "HaWeb",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
// Use hover for the description of the existing attributes
|
// Use hover for the description of the existing attributes
|
||||||
@@ -24,12 +30,7 @@
|
|||||||
},
|
},
|
||||||
"sourceFileMap": {
|
"sourceFileMap": {
|
||||||
"/Views": "${workspaceFolder}/Views"
|
"/Views": "${workspaceFolder}/Views"
|
||||||
}
|
},
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": ".NET Core Attach",
|
|
||||||
"type": "coreclr",
|
|
||||||
"request": "attach"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -4,14 +4,12 @@ using HaDocument.Interfaces;
|
|||||||
using HaXMLReader.Interfaces;
|
using HaXMLReader.Interfaces;
|
||||||
using Microsoft.FeatureManagement.Mvc;
|
using Microsoft.FeatureManagement.Mvc;
|
||||||
|
|
||||||
public class AdminController : Controller
|
public class AdminController : Controller {
|
||||||
{
|
|
||||||
// DI
|
// DI
|
||||||
private ILibrary _lib;
|
private ILibrary _lib;
|
||||||
private IReaderService _readerService;
|
private IReaderService _readerService;
|
||||||
|
|
||||||
public AdminController(ILibrary lib, IReaderService readerService)
|
public AdminController(ILibrary lib, IReaderService readerService) {
|
||||||
{
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
}
|
}
|
||||||
@@ -19,8 +17,7 @@ public class AdminController : Controller
|
|||||||
|
|
||||||
[Route("Admin")]
|
[Route("Admin")]
|
||||||
[FeatureGate(Features.AdminService)]
|
[FeatureGate(Features.AdminService)]
|
||||||
public IActionResult Index()
|
public IActionResult Index() {
|
||||||
{
|
|
||||||
return Redirect("/Admin/Upload");
|
return Redirect("/Admin/Upload");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,7 @@ using HaDocument.Models;
|
|||||||
|
|
||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
public class Briefecontroller : Controller
|
public class Briefecontroller : Controller {
|
||||||
{
|
|
||||||
[BindProperty(SupportsGet = true)]
|
[BindProperty(SupportsGet = true)]
|
||||||
public string? id { get; set; }
|
public string? id { get; set; }
|
||||||
|
|
||||||
@@ -16,16 +15,14 @@ public class Briefecontroller : Controller
|
|||||||
private ILibrary _lib;
|
private ILibrary _lib;
|
||||||
private IReaderService _readerService;
|
private IReaderService _readerService;
|
||||||
|
|
||||||
public Briefecontroller(ILibrary lib, IReaderService readerService)
|
public Briefecontroller(ILibrary lib, IReaderService readerService) {
|
||||||
{
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("Briefe")]
|
[Route("Briefe")]
|
||||||
[Route("Briefe/{id?}")]
|
[Route("Briefe/{id?}")]
|
||||||
public IActionResult Index(string? id)
|
public IActionResult Index(string? id) {
|
||||||
{
|
|
||||||
// Setup settings and variables
|
// Setup settings and variables
|
||||||
var url = "/Briefe/";
|
var url = "/Briefe/";
|
||||||
var defaultID = "1";
|
var defaultID = "1";
|
||||||
@@ -79,19 +76,16 @@ public class Briefecontroller : Controller
|
|||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IActionResult error404()
|
private IActionResult error404() {
|
||||||
{
|
|
||||||
Response.StatusCode = 404;
|
Response.StatusCode = 404;
|
||||||
return Redirect("/Error404");
|
return Redirect("/Error404");
|
||||||
}
|
}
|
||||||
|
|
||||||
private BriefeMetaViewModel generateMetaViewModel(Meta meta, bool hasMarginals)
|
private BriefeMetaViewModel generateMetaViewModel(Meta meta, bool hasMarginals) {
|
||||||
{
|
|
||||||
var senders = meta.Senders.Select(x => _lib.Persons[x].Name) ?? new List<string>();
|
var senders = meta.Senders.Select(x => _lib.Persons[x].Name) ?? new List<string>();
|
||||||
var recivers = meta.Receivers.Select(x => _lib.Persons[x].Name) ?? new List<string>();
|
var recivers = meta.Receivers.Select(x => _lib.Persons[x].Name) ?? new List<string>();
|
||||||
var zhstring = meta.ZH != null ? HaWeb.HTMLHelpers.LetterHelpers.CreateZHString(meta) : null;
|
var zhstring = meta.ZH != null ? HaWeb.HTMLHelpers.LetterHelpers.CreateZHString(meta) : null;
|
||||||
return new BriefeMetaViewModel(meta, hasMarginals, false)
|
return new BriefeMetaViewModel(meta, hasMarginals, false) {
|
||||||
{
|
|
||||||
ParsedZHString = zhstring,
|
ParsedZHString = zhstring,
|
||||||
ParsedSenders = HTMLHelpers.StringHelpers.GetEnumerationString(senders),
|
ParsedSenders = HTMLHelpers.StringHelpers.GetEnumerationString(senders),
|
||||||
ParsedReceivers = HTMLHelpers.StringHelpers.GetEnumerationString(recivers)
|
ParsedReceivers = HTMLHelpers.StringHelpers.GetEnumerationString(recivers)
|
||||||
|
|||||||
@@ -5,40 +5,32 @@ using HaWeb.Models;
|
|||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
[Route("Edition/[action]")]
|
[Route("Edition/[action]")]
|
||||||
public class EditionController : Controller
|
public class EditionController : Controller {
|
||||||
{
|
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public IActionResult Error()
|
public IActionResult Error() {
|
||||||
{
|
|
||||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
}
|
}
|
||||||
public IActionResult Kontakt()
|
public IActionResult Kontakt() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Mitwirkende()
|
public IActionResult Mitwirkende() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Richtlinien()
|
public IActionResult Richtlinien() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Werkausgabe()
|
public IActionResult Werkausgabe() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Editionsgeschichte()
|
public IActionResult Editionsgeschichte() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Datenschutzerklaerung()
|
public IActionResult Datenschutzerklaerung() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,7 @@ using HaWeb.Models;
|
|||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
|
|
||||||
public class ErrorController : Controller
|
public class ErrorController : Controller {
|
||||||
{
|
|
||||||
[Route("Error404/")]
|
[Route("Error404/")]
|
||||||
public IActionResult ErrorNotFound() {
|
public IActionResult ErrorNotFound() {
|
||||||
return View();
|
return View();
|
||||||
|
|||||||
@@ -4,18 +4,15 @@ using HaWeb.Models;
|
|||||||
|
|
||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
public class HomeController : Controller
|
public class HomeController : Controller {
|
||||||
{
|
|
||||||
|
|
||||||
[Route("")]
|
[Route("")]
|
||||||
public IActionResult Index()
|
public IActionResult Index() {
|
||||||
{
|
|
||||||
return Redirect("/Suche");
|
return Redirect("/Suche");
|
||||||
}
|
}
|
||||||
|
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public IActionResult Error()
|
public IActionResult Error() {
|
||||||
{
|
|
||||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ using HaWeb.Models;
|
|||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
|
|
||||||
public class LegacyContoller : Controller
|
public class LegacyContoller : Controller {
|
||||||
{
|
|
||||||
[Route("Supplementa/")]
|
[Route("Supplementa/")]
|
||||||
[Route("Supplementa/Register")]
|
[Route("Supplementa/Register")]
|
||||||
[Route("Supplementa/Register/{id?}")]
|
[Route("Supplementa/Register/{id?}")]
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ using System.Collections.Concurrent;
|
|||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
[Route("Register/[action]/{id?}")]
|
[Route("Register/[action]/{id?}")]
|
||||||
public class RegisterController : Controller
|
public class RegisterController : Controller {
|
||||||
{
|
|
||||||
[BindProperty(SupportsGet = true)]
|
[BindProperty(SupportsGet = true)]
|
||||||
public string? search { get; set; }
|
public string? search { get; set; }
|
||||||
|
|
||||||
@@ -24,14 +23,12 @@ public class RegisterController : Controller
|
|||||||
private ILibrary _lib;
|
private ILibrary _lib;
|
||||||
private IReaderService _readerService;
|
private IReaderService _readerService;
|
||||||
|
|
||||||
public RegisterController(ILibrary lib, IReaderService readerService)
|
public RegisterController(ILibrary lib, IReaderService readerService) {
|
||||||
{
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Register(string? id)
|
public IActionResult Register(string? id) {
|
||||||
{
|
|
||||||
// Setup settings and variables
|
// Setup settings and variables
|
||||||
var url = "/Register/Register/";
|
var url = "/Register/Register/";
|
||||||
var category = "neuzeit";
|
var category = "neuzeit";
|
||||||
@@ -52,15 +49,12 @@ public class RegisterController : Controller
|
|||||||
|
|
||||||
// Parsing
|
// Parsing
|
||||||
var res = new List<CommentModel>();
|
var res = new List<CommentModel>();
|
||||||
foreach (var comm in comments)
|
foreach (var comm in comments) {
|
||||||
{
|
|
||||||
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
||||||
List<string>? parsedSubComments = null;
|
List<string>? parsedSubComments = null;
|
||||||
if (comm.Kommentare != null)
|
if (comm.Kommentare != null) {
|
||||||
{
|
|
||||||
parsedSubComments = new List<string>();
|
parsedSubComments = new List<string>();
|
||||||
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order))
|
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order)) {
|
||||||
{
|
|
||||||
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,8 +62,7 @@ public class RegisterController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Model instantiation
|
// Model instantiation
|
||||||
var model = new RegisterViewModel(category, this.id, res, title)
|
var model = new RegisterViewModel(category, this.id, res, title) {
|
||||||
{
|
|
||||||
AvailableCategories = availableCategories,
|
AvailableCategories = availableCategories,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,8 +70,7 @@ public class RegisterController : Controller
|
|||||||
return View("Index", model);
|
return View("Index", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Bibelstellen(string? id)
|
public IActionResult Bibelstellen(string? id) {
|
||||||
{
|
|
||||||
// Setup settings and variables
|
// Setup settings and variables
|
||||||
var url = "/Register/Bibelstellen/";
|
var url = "/Register/Bibelstellen/";
|
||||||
var category = "bibel";
|
var category = "bibel";
|
||||||
@@ -99,15 +91,12 @@ public class RegisterController : Controller
|
|||||||
|
|
||||||
// Parsing
|
// Parsing
|
||||||
var res = new List<CommentModel>();
|
var res = new List<CommentModel>();
|
||||||
foreach (var comm in comments)
|
foreach (var comm in comments) {
|
||||||
{
|
|
||||||
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
||||||
List<string>? parsedSubComments = null;
|
List<string>? parsedSubComments = null;
|
||||||
if (comm.Kommentare != null)
|
if (comm.Kommentare != null) {
|
||||||
{
|
|
||||||
parsedSubComments = new List<string>();
|
parsedSubComments = new List<string>();
|
||||||
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Lemma.Length).ThenBy(x => x.Value.Lemma))
|
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Lemma.Length).ThenBy(x => x.Value.Lemma)) {
|
||||||
{
|
|
||||||
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,8 +104,7 @@ public class RegisterController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Model instantiation
|
// Model instantiation
|
||||||
var model = new RegisterViewModel(category, this.id, res, title)
|
var model = new RegisterViewModel(category, this.id, res, title) {
|
||||||
{
|
|
||||||
AvailableCategories = availableCategories,
|
AvailableCategories = availableCategories,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,8 +112,7 @@ public class RegisterController : Controller
|
|||||||
return View("Index", model);
|
return View("Index", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Forschung(string? id)
|
public IActionResult Forschung(string? id) {
|
||||||
{
|
|
||||||
// Setup settings and variables
|
// Setup settings and variables
|
||||||
var url = "/Register/Forschung/";
|
var url = "/Register/Forschung/";
|
||||||
var category = "forschung";
|
var category = "forschung";
|
||||||
@@ -144,8 +131,7 @@ public class RegisterController : Controller
|
|||||||
IOrderedEnumerable<Comment>? comments = null;
|
IOrderedEnumerable<Comment>? comments = null;
|
||||||
if (this.id == "EDITIONEN") {
|
if (this.id == "EDITIONEN") {
|
||||||
comments = _lib.CommentsByCategory[this.id.ToLower()].OrderBy(x => x.Index);
|
comments = _lib.CommentsByCategory[this.id.ToLower()].OrderBy(x => x.Index);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
comments = _lib.CommentsByCategoryLetter[category][this.id].OrderBy(x => x.Index);
|
comments = _lib.CommentsByCategoryLetter[category][this.id].OrderBy(x => x.Index);
|
||||||
}
|
}
|
||||||
var availableCategories = _lib.CommentsByCategoryLetter[category].Select(x => (x.Key.ToUpper(), url + x.Key.ToUpper())).OrderBy(x => x.Item1).ToList();
|
var availableCategories = _lib.CommentsByCategoryLetter[category].Select(x => (x.Key.ToUpper(), url + x.Key.ToUpper())).OrderBy(x => x.Item1).ToList();
|
||||||
@@ -154,15 +140,12 @@ public class RegisterController : Controller
|
|||||||
|
|
||||||
// Parsing
|
// Parsing
|
||||||
var res = new List<CommentModel>();
|
var res = new List<CommentModel>();
|
||||||
foreach (var comm in comments)
|
foreach (var comm in comments) {
|
||||||
{
|
|
||||||
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
var parsedComment = HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, comm, category, Settings.ParsingState.CommentType.Comment);
|
||||||
List<string>? parsedSubComments = null;
|
List<string>? parsedSubComments = null;
|
||||||
if (comm.Kommentare != null)
|
if (comm.Kommentare != null) {
|
||||||
{
|
|
||||||
parsedSubComments = new List<string>();
|
parsedSubComments = new List<string>();
|
||||||
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order))
|
foreach (var subcomm in comm.Kommentare.OrderBy(x => x.Value.Order)) {
|
||||||
{
|
|
||||||
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
parsedSubComments.Add(HTMLHelpers.CommentHelpers.CreateHTML(_lib, _readerService, subcomm.Value, category, Settings.ParsingState.CommentType.Subcomment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,8 +153,7 @@ public class RegisterController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Model instantiation
|
// Model instantiation
|
||||||
var model = new RegisterViewModel(category, this.id, res, title)
|
var model = new RegisterViewModel(category, this.id, res, title) {
|
||||||
{
|
|
||||||
AvailableCategories = availableCategories,
|
AvailableCategories = availableCategories,
|
||||||
AvailableSideCategories = AvailableSideCategories
|
AvailableSideCategories = AvailableSideCategories
|
||||||
};
|
};
|
||||||
@@ -180,22 +162,18 @@ public class RegisterController : Controller
|
|||||||
return View("Index", model);
|
return View("Index", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void normalizeID(string? id, string defaultid)
|
private void normalizeID(string? id, string defaultid) {
|
||||||
{
|
|
||||||
this.id = this.id.ToUpper();
|
this.id = this.id.ToUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool validationCheck(HashSet<string> permitted)
|
private bool validationCheck(HashSet<string> permitted) {
|
||||||
{
|
if (!permitted.Contains(id)) {
|
||||||
if (!permitted.Contains(id))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IActionResult error404()
|
private IActionResult error404() {
|
||||||
{
|
|
||||||
Response.StatusCode = 404;
|
Response.StatusCode = 404;
|
||||||
return Redirect("/Error404");
|
return Redirect("/Error404");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,15 @@ using HaWeb.Models;
|
|||||||
|
|
||||||
namespace HaWeb.Controllers;
|
namespace HaWeb.Controllers;
|
||||||
|
|
||||||
public class SucheController : Controller
|
public class SucheController : Controller {
|
||||||
{
|
|
||||||
|
|
||||||
[Route("Suche")]
|
[Route("Suche")]
|
||||||
public IActionResult Index()
|
public IActionResult Index() {
|
||||||
{
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
public IActionResult Error()
|
public IActionResult Error() {
|
||||||
{
|
|
||||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,12 @@ using HaDocument.Interfaces;
|
|||||||
using HaXMLReader.Interfaces;
|
using HaXMLReader.Interfaces;
|
||||||
using Microsoft.FeatureManagement.Mvc;
|
using Microsoft.FeatureManagement.Mvc;
|
||||||
|
|
||||||
public class UpdateController : Controller
|
public class UpdateController : Controller {
|
||||||
{
|
|
||||||
// DI
|
// DI
|
||||||
private ILibrary _lib;
|
private ILibrary _lib;
|
||||||
private IReaderService _readerService;
|
private IReaderService _readerService;
|
||||||
|
|
||||||
public UpdateController(ILibrary lib, IReaderService readerService)
|
public UpdateController(ILibrary lib, IReaderService readerService) {
|
||||||
{
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
}
|
}
|
||||||
@@ -19,8 +17,7 @@ public class UpdateController : Controller
|
|||||||
|
|
||||||
[Route("Admin/Update")]
|
[Route("Admin/Update")]
|
||||||
[FeatureGate(Features.UpdateService)]
|
[FeatureGate(Features.UpdateService)]
|
||||||
public IActionResult Index()
|
public IActionResult Index() {
|
||||||
{
|
|
||||||
return View("../Admin/Upload/Index");
|
return View("../Admin/Upload/Index");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,8 +21,7 @@ using System.Xml.Linq;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
public class UploadController : Controller
|
public class UploadController : Controller {
|
||||||
{
|
|
||||||
// DI
|
// DI
|
||||||
private ILibrary _lib;
|
private ILibrary _lib;
|
||||||
private IReaderService _readerService;
|
private IReaderService _readerService;
|
||||||
@@ -35,8 +34,7 @@ public class UploadController : Controller
|
|||||||
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
||||||
|
|
||||||
|
|
||||||
public UploadController(ILibrary lib, IReaderService readerService, IXMLService xmlService, IConfiguration config)
|
public UploadController(ILibrary lib, IReaderService readerService, IXMLService xmlService, IConfiguration config) {
|
||||||
{
|
|
||||||
_lib = lib;
|
_lib = lib;
|
||||||
_readerService = readerService;
|
_readerService = readerService;
|
||||||
_xmlService = xmlService;
|
_xmlService = xmlService;
|
||||||
@@ -49,27 +47,28 @@ public class UploadController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Admin/Upload")]
|
[Route("Admin/Upload/{id?}")]
|
||||||
[FeatureGate(Features.UploadService)]
|
[FeatureGate(Features.UploadService)]
|
||||||
[GenerateAntiforgeryTokenCookie]
|
[GenerateAntiforgeryTokenCookie]
|
||||||
public IActionResult Index()
|
public IActionResult Index(string? id) {
|
||||||
{
|
|
||||||
var model = new UploadViewModel();
|
var model = new UploadViewModel();
|
||||||
model.AvailableRoots = _xmlService.GetRoots().Select(x => (x.Type, "")).ToList();
|
model.AvailableRoots = _xmlService.GetRoots();
|
||||||
|
model.UsedFiles = _xmlService.GetUsed();
|
||||||
|
var hello = "mama";
|
||||||
return View("../Admin/Upload/Index", model);
|
return View("../Admin/Upload/Index", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// UPLOAD ////
|
//// UPLOAD ////
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("Admin/Upload")]
|
[Route("Admin/Upload")]
|
||||||
[DisableFormValueModelBinding]
|
[DisableFormValueModelBinding]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public async Task<IActionResult> Post() {
|
public async Task<IActionResult> Post() {
|
||||||
//// 1. Stage: Check Request format and request spec
|
List<XMLRootDocument>? docs = null;
|
||||||
|
//// 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)
|
||||||
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
|
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) {
|
||||||
{
|
|
||||||
ModelState.AddModelError("Error", $"Wrong / No Content Type on the Request");
|
ModelState.AddModelError("Error", $"Wrong / No Content Type on the Request");
|
||||||
return BadRequest(ModelState);
|
return BadRequest(ModelState);
|
||||||
}
|
}
|
||||||
@@ -80,80 +79,63 @@ public class UploadController : Controller
|
|||||||
MultipartSection? section = null;
|
MultipartSection? section = null;
|
||||||
try {
|
try {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (section != null)
|
while (section != null) {
|
||||||
{
|
|
||||||
// Multipart document content disposition header read for a section:
|
// Multipart document content disposition header read for a section:
|
||||||
// Starts with boundary, contains field name, content-dispo, filename, content-type
|
// Starts with boundary, contains field name, content-dispo, filename, content-type
|
||||||
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
||||||
if (hasContentDispositionHeader && contentDisposition != null)
|
if (hasContentDispositionHeader && contentDisposition != null) {
|
||||||
{
|
|
||||||
// Checks if it is a section with content-disposition, name, filename
|
// Checks if it is a section with content-disposition, name, filename
|
||||||
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
|
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition)) {
|
||||||
{
|
|
||||||
ModelState.AddModelError("Error", $"Wrong Content-Dispostion Headers in Multipart Document");
|
ModelState.AddModelError("Error", $"Wrong Content-Dispostion Headers in Multipart Document");
|
||||||
return BadRequest(ModelState);
|
return BadRequest(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// 2. Stage: Check File. Sanity checks on the file on a byte level, extension checking, is it empty etc.
|
//// 2. Stage: Check File. Sanity checks on the file on a byte level, extension checking, is it empty etc.
|
||||||
var streamedFileContent = await XMLFileHelpers.ProcessStreamedFile(
|
var streamedFileContent = await XMLFileHelpers.ProcessStreamedFile(
|
||||||
section, contentDisposition, ModelState,
|
section, contentDisposition, ModelState,
|
||||||
_permittedExtensions, _fileSizeLimit);
|
_permittedExtensions, _fileSizeLimit);
|
||||||
if (!ModelState.IsValid || streamedFileContent == null)
|
if (!ModelState.IsValid || streamedFileContent == null)
|
||||||
return BadRequest(ModelState);
|
return BadRequest(ModelState);
|
||||||
|
|
||||||
//// 3. Stage: Valid XML checking using a simple XDocument.Load()
|
//// 3. Stage: Valid XML checking using a simple XDocument.Load()
|
||||||
var xdocument = await XDocumentFileHelper.ProcessStreamedFile(streamedFileContent, ModelState);
|
var xdocument = await XDocumentFileHelper.ProcessStreamedFile(streamedFileContent, ModelState);
|
||||||
if (!ModelState.IsValid || xdocument == null)
|
if (!ModelState.IsValid || xdocument == null)
|
||||||
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 docs = _xmlService.ProbeHamannFile(xdocument, ModelState);
|
var retdocs = await _xmlService.ProbeHamannFile(xdocument, ModelState);
|
||||||
if (!ModelState.IsValid || docs == null || !docs.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 docs) {
|
foreach (var doc in retdocs) {
|
||||||
var type = doc.Prefix;
|
await _xmlService.UpdateAvailableFiles(doc, _targetFilePath, ModelState);
|
||||||
var directory = Path.Combine(_targetFilePath, type);
|
if (!ModelState.IsValid) return StatusCode(500, ModelState);
|
||||||
if (!Directory.Exists(directory))
|
if (docs == null) docs = new List<XMLRootDocument>();
|
||||||
Directory.CreateDirectory(directory);
|
docs.Add(doc);
|
||||||
var path = Path.Combine(directory, doc.FileName);
|
|
||||||
try {
|
|
||||||
using (var targetStream = System.IO.File.Create(path))
|
|
||||||
await doc.Save(targetStream, ModelState);
|
|
||||||
if (!ModelState.IsValid) return StatusCode(500, ModelState);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
ModelState.AddModelError("Error", "Speichern der Datei fehlgeschlagen: " + ex.Message);
|
|
||||||
return StatusCode(500, ModelState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. State: Returning Ok, and redirecting
|
|
||||||
JsonSerializerOptions options = new() {
|
|
||||||
ReferenceHandler = ReferenceHandler.Preserve
|
|
||||||
};
|
|
||||||
|
|
||||||
string json = JsonSerializer.Serialize(docs);
|
|
||||||
return Created(nameof(UploadController), json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Success! Return Last Created File View
|
// 6. Stage: Success! Returning Ok, and redirecting
|
||||||
return Created(nameof(UploadController), null);
|
JsonSerializerOptions options = new() {
|
||||||
|
ReferenceHandler = ReferenceHandler.Preserve,
|
||||||
|
Converters = {
|
||||||
|
new IdentificationStringJSONConverter()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
string json = JsonSerializer.Serialize(docs);
|
||||||
|
return Created(nameof(UploadController), json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,12 +3,10 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
public static class MultipartRequestHelper
|
public static class MultipartRequestHelper {
|
||||||
{
|
|
||||||
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq"
|
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq"
|
||||||
// The spec at https://tools.ietf.org/html/rfc2046#section-5.1 states that 70 characters is a reasonable limit.
|
// The spec at https://tools.ietf.org/html/rfc2046#section-5.1 states that 70 characters is a reasonable limit.
|
||||||
public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit)
|
public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit) {
|
||||||
{
|
|
||||||
var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;
|
var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(boundary))
|
if (string.IsNullOrWhiteSpace(boundary))
|
||||||
@@ -23,8 +21,7 @@ public static class MultipartRequestHelper
|
|||||||
public static bool IsMultipartContentType(string? contentType)
|
public static bool IsMultipartContentType(string? contentType)
|
||||||
=> !string.IsNullOrEmpty(contentType) && contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
|
=> !string.IsNullOrEmpty(contentType) && contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||||
|
|
||||||
public static bool HasFormDataContentDisposition(ContentDispositionHeaderValue contentDisposition)
|
public static bool HasFormDataContentDisposition(ContentDispositionHeaderValue contentDisposition) {
|
||||||
{
|
|
||||||
// Content-Disposition: form-data; name="key";
|
// Content-Disposition: form-data; name="key";
|
||||||
return contentDisposition != null
|
return contentDisposition != null
|
||||||
&& contentDisposition.DispositionType.Equals("form-data")
|
&& contentDisposition.DispositionType.Equals("form-data")
|
||||||
@@ -32,8 +29,7 @@ public static class MultipartRequestHelper
|
|||||||
&& string.IsNullOrEmpty(contentDisposition.FileNameStar.Value);
|
&& string.IsNullOrEmpty(contentDisposition.FileNameStar.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasFileContentDisposition(ContentDispositionHeaderValue? contentDisposition)
|
public static bool HasFileContentDisposition(ContentDispositionHeaderValue? contentDisposition) {
|
||||||
{
|
|
||||||
return contentDisposition != null
|
return contentDisposition != null
|
||||||
&& contentDisposition.DispositionType.Equals("form-data")
|
&& contentDisposition.DispositionType.Equals("form-data")
|
||||||
&& (!string.IsNullOrEmpty(contentDisposition.FileName.Value)
|
&& (!string.IsNullOrEmpty(contentDisposition.FileName.Value)
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ using System.Xml;
|
|||||||
|
|
||||||
public static class XDocumentFileHelper {
|
public static class XDocumentFileHelper {
|
||||||
|
|
||||||
private readonly static XmlReaderSettings _Settings = new XmlReaderSettings()
|
private readonly static XmlReaderSettings _Settings = new XmlReaderSettings() {
|
||||||
{
|
|
||||||
CloseInput = true,
|
CloseInput = true,
|
||||||
CheckCharacters = false,
|
CheckCharacters = false,
|
||||||
ConformanceLevel = ConformanceLevel.Fragment,
|
ConformanceLevel = ConformanceLevel.Fragment,
|
||||||
@@ -17,19 +16,14 @@ public static class XDocumentFileHelper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static async Task<XDocument?> ProcessStreamedFile(byte[] bytes, ModelStateDictionary modelState) {
|
public static async Task<XDocument?> ProcessStreamedFile(byte[] bytes, ModelStateDictionary modelState) {
|
||||||
try
|
try {
|
||||||
{
|
using (var stream = new MemoryStream(bytes)) {
|
||||||
using (var stream = new MemoryStream(bytes))
|
using (var xmlreader = XmlReader.Create(stream, _Settings)) {
|
||||||
{
|
|
||||||
using (var xmlreader = XmlReader.Create(stream, _Settings))
|
|
||||||
{
|
|
||||||
return XDocument.Load(xmlreader, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
|
return XDocument.Load(xmlreader, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
modelState.AddModelError("Error", $"Kein gültiges XML-Dokument geladen. Error: {ex.Message}");
|
modelState.AddModelError("Error", $"Kein gültiges XML-Dokument geladen. Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
|
||||||
public static class XMLFileHelpers
|
public static class XMLFileHelpers {
|
||||||
{
|
|
||||||
// File Signatures Database (https://www.filesignatures.net/)
|
// File Signatures Database (https://www.filesignatures.net/)
|
||||||
private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
|
private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
|
||||||
{
|
{
|
||||||
@@ -142,19 +141,15 @@ public static class XMLFileHelpers
|
|||||||
|
|
||||||
public static async Task<byte[]?> ProcessStreamedFile(
|
public static async Task<byte[]?> ProcessStreamedFile(
|
||||||
MultipartSection section, ContentDispositionHeaderValue contentDisposition,
|
MultipartSection section, ContentDispositionHeaderValue contentDisposition,
|
||||||
ModelStateDictionary modelState, string[] permittedExtensions, long sizeLimit)
|
ModelStateDictionary modelState, string[] permittedExtensions, long sizeLimit) {
|
||||||
{
|
try {
|
||||||
try
|
using (var memoryStream = new MemoryStream()) {
|
||||||
{
|
|
||||||
using (var memoryStream = new MemoryStream())
|
|
||||||
{
|
|
||||||
await section.Body.CopyToAsync(memoryStream);
|
await section.Body.CopyToAsync(memoryStream);
|
||||||
|
|
||||||
// Check if the file is empty or exceeds the size limit.
|
// Check if the file is empty or exceeds the size limit.
|
||||||
if (memoryStream.Length == 0)
|
if (memoryStream.Length == 0)
|
||||||
modelState.AddModelError("Error", "The file is empty.");
|
modelState.AddModelError("Error", "The file is empty.");
|
||||||
else if (memoryStream.Length > sizeLimit)
|
else if (memoryStream.Length > sizeLimit) {
|
||||||
{
|
|
||||||
var megabyteSizeLimit = sizeLimit / 1048576;
|
var megabyteSizeLimit = sizeLimit / 1048576;
|
||||||
modelState.AddModelError("Error", $"The file exceeds {megabyteSizeLimit:N1} MB.");
|
modelState.AddModelError("Error", $"The file exceeds {megabyteSizeLimit:N1} MB.");
|
||||||
}
|
}
|
||||||
@@ -168,17 +163,14 @@ public static class XMLFileHelpers
|
|||||||
// Return the File as a byte array
|
// Return the File as a byte array
|
||||||
else return memoryStream.ToArray();
|
else return memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
modelState.AddModelError("Error", $"The upload failed. Error: {ex.Message}");
|
modelState.AddModelError("Error", $"The upload failed. Error: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions)
|
private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions) {
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)
|
if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -189,8 +181,7 @@ public static class XMLFileHelpers
|
|||||||
|
|
||||||
data.Position = 0;
|
data.Position = 0;
|
||||||
|
|
||||||
using (var reader = new BinaryReader(data))
|
using (var reader = new BinaryReader(data)) {
|
||||||
{
|
|
||||||
var signatures = _fileSignature[ext];
|
var signatures = _fileSignature[ext];
|
||||||
var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
|
var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
|
||||||
return signatures.Any(signature =>
|
return signatures.Any(signature =>
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
public class GenerateAntiforgeryTokenCookieAttribute : ResultFilterAttribute
|
public class GenerateAntiforgeryTokenCookieAttribute : ResultFilterAttribute {
|
||||||
{
|
public override void OnResultExecuting(ResultExecutingContext context) {
|
||||||
public override void OnResultExecuting(ResultExecutingContext context)
|
|
||||||
{
|
|
||||||
var antiforgery = context.HttpContext.RequestServices.GetService<IAntiforgery>();
|
var antiforgery = context.HttpContext.RequestServices.GetService<IAntiforgery>();
|
||||||
|
|
||||||
// Send the request token as a JavaScript-readable cookie
|
// Send the request token as a JavaScript-readable cookie
|
||||||
@@ -19,8 +17,7 @@ public class GenerateAntiforgeryTokenCookieAttribute : ResultFilterAttribute
|
|||||||
new CookieOptions() { HttpOnly = false });
|
new CookieOptions() { HttpOnly = false });
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnResultExecuted(ResultExecutedContext context)
|
public override void OnResultExecuted(ResultExecutedContext context) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,17 +4,14 @@ using Microsoft.AspNetCore.Mvc.Filters;
|
|||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
|
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter {
|
||||||
{
|
public void OnResourceExecuting(ResourceExecutingContext context) {
|
||||||
public void OnResourceExecuting(ResourceExecutingContext context)
|
|
||||||
{
|
|
||||||
var factories = context.ValueProviderFactories;
|
var factories = context.ValueProviderFactories;
|
||||||
factories.RemoveType<FormValueProviderFactory>();
|
factories.RemoveType<FormValueProviderFactory>();
|
||||||
factories.RemoveType<FormFileValueProviderFactory>();
|
factories.RemoveType<FormFileValueProviderFactory>();
|
||||||
factories.RemoveType<JQueryFormValueProviderFactory>();
|
factories.RemoveType<JQueryFormValueProviderFactory>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
public void OnResourceExecuted(ResourceExecutedContext context) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,14 @@ using HaWeb.Settings.ParsingRules;
|
|||||||
using HaWeb.Settings.ParsingState;
|
using HaWeb.Settings.ParsingState;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
public static class CommentHelpers
|
public static class CommentHelpers {
|
||||||
{
|
|
||||||
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
||||||
private static readonly string BACKLINKSCLASS = HaWeb.Settings.CSSClasses.BACKLINKSCLASS;
|
private static readonly string BACKLINKSCLASS = HaWeb.Settings.CSSClasses.BACKLINKSCLASS;
|
||||||
private static readonly string LETLINKCLASS = HaWeb.Settings.CSSClasses.LETLINKCLASS;
|
private static readonly string LETLINKCLASS = HaWeb.Settings.CSSClasses.LETLINKCLASS;
|
||||||
private static readonly string COMMENTHEADCLASS = HaWeb.Settings.CSSClasses.COMMENTHEADCLASS;
|
private static readonly string COMMENTHEADCLASS = HaWeb.Settings.CSSClasses.COMMENTHEADCLASS;
|
||||||
private static readonly string BACKLINKSHKBCLASS = HaWeb.Settings.CSSClasses.BACKLINKSHKBCLASS;
|
private static readonly string BACKLINKSHKBCLASS = HaWeb.Settings.CSSClasses.BACKLINKSHKBCLASS;
|
||||||
|
|
||||||
public static string CreateHTML(ILibrary lib, IReaderService readerService, Comment comment, string category, CommentType type)
|
public static string CreateHTML(ILibrary lib, IReaderService readerService, Comment comment, string category, CommentType type) {
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var rd = readerService.RequestStringReader(comment.Lemma);
|
var rd = readerService.RequestStringReader(comment.Lemma);
|
||||||
var commentState = new CommentState(category, type);
|
var commentState = new CommentState(category, type);
|
||||||
@@ -28,17 +26,13 @@ public static class CommentHelpers
|
|||||||
.Where(x => lib.Metas.ContainsKey(x.Letter))
|
.Where(x => lib.Metas.ContainsKey(x.Letter))
|
||||||
.OrderBy(x => lib.Metas[x.Letter].Sort)
|
.OrderBy(x => lib.Metas[x.Letter].Sort)
|
||||||
.ThenBy(x => lib.Metas[x.Letter].Order) : null;
|
.ThenBy(x => lib.Metas[x.Letter].Order) : null;
|
||||||
if (backlinks != null)
|
if (backlinks != null) {
|
||||||
{
|
|
||||||
sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, BACKLINKSCLASS));
|
sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, BACKLINKSCLASS));
|
||||||
var arrow = false;
|
var arrow = false;
|
||||||
foreach (var blk in backlinks)
|
foreach (var blk in backlinks) {
|
||||||
{
|
|
||||||
var let = lib.Metas.ContainsKey(blk.Letter) ? lib.Metas[blk.Letter] : null;
|
var let = lib.Metas.ContainsKey(blk.Letter) ? lib.Metas[blk.Letter] : null;
|
||||||
if (let != null)
|
if (let != null) {
|
||||||
{
|
if (!arrow) {
|
||||||
if (!arrow)
|
|
||||||
{
|
|
||||||
sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, BACKLINKSHKBCLASS));
|
sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, BACKLINKSHKBCLASS));
|
||||||
sb.Append("HKB ");
|
sb.Append("HKB ");
|
||||||
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT));
|
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT));
|
||||||
|
|||||||
@@ -14,36 +14,27 @@ public static class ConversionHelpers {
|
|||||||
{'M', 1000}
|
{'M', 1000}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static int RomanToInteger(string roman)
|
public static int RomanToInteger(string roman) {
|
||||||
{
|
|
||||||
var ro = roman.ToUpper();
|
var ro = roman.ToUpper();
|
||||||
int number = 0;
|
int number = 0;
|
||||||
for (int i = 0; i < roman.Length; i++)
|
for (int i = 0; i < roman.Length; i++) {
|
||||||
{
|
if (RomanMap.ContainsKey(ro[i]) && (i + 1 >= ro.Length || RomanMap.ContainsKey(ro[i + 1]))) {
|
||||||
if (RomanMap.ContainsKey(ro[i]) && (i + 1 >= ro.Length || RomanMap.ContainsKey(ro[i + 1])))
|
if (i + 1 < ro.Length && RomanMap[ro[i]] < RomanMap[ro[i + 1]]) {
|
||||||
{
|
|
||||||
if (i + 1 < ro.Length && RomanMap[ro[i]] < RomanMap[ro[i + 1]])
|
|
||||||
{
|
|
||||||
number -= RomanMap[ro[i]];
|
number -= RomanMap[ro[i]];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
number += RomanMap[ro[i]];
|
number += RomanMap[ro[i]];
|
||||||
}
|
}
|
||||||
}
|
} else return 0;
|
||||||
else return 0;
|
|
||||||
}
|
}
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int RomanOrNumberToInt(string number)
|
public static int RomanOrNumberToInt(string number) {
|
||||||
{
|
|
||||||
var a = 0;
|
var a = 0;
|
||||||
if (Int32.TryParse(number, out a)) return a;
|
if (Int32.TryParse(number, out a)) return a;
|
||||||
else return RomanToInteger(number);
|
else return RomanToInteger(number);
|
||||||
}
|
}
|
||||||
public static string ToRoman(int number)
|
public static string ToRoman(int number) {
|
||||||
{
|
|
||||||
if ((number < 0) || (number > 3999)) return string.Empty;
|
if ((number < 0) || (number > 3999)) return string.Empty;
|
||||||
if (number < 1) return string.Empty;
|
if (number < 1) return string.Empty;
|
||||||
if (number >= 1000) return "M" + ToRoman(number - 1000);
|
if (number >= 1000) return "M" + ToRoman(number - 1000);
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ using System.Xml.Linq;
|
|||||||
using HaWeb.Settings.ParsingState;
|
using HaWeb.Settings.ParsingState;
|
||||||
using HaWeb.Settings.ParsingRules;
|
using HaWeb.Settings.ParsingRules;
|
||||||
|
|
||||||
public static class LetterHelpers
|
public static class LetterHelpers {
|
||||||
{
|
public static LetterState CreateLetter(ILibrary lib, IReaderService readerService, Meta meta, Letter letter, IEnumerable<Marginal>? marginals, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits) {
|
||||||
public static LetterState CreateLetter(ILibrary lib, IReaderService readerService, Meta meta, Letter letter, IEnumerable<Marginal>? marginals, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits)
|
|
||||||
{
|
|
||||||
var rd = readerService.RequestStringReader(letter.Element);
|
var rd = readerService.RequestStringReader(letter.Element);
|
||||||
var letterState = new LetterState(lib, readerService, meta, marginals, hands, edits);
|
var letterState = new LetterState(lib, readerService, meta, marginals, hands, edits);
|
||||||
new HaWeb.HTMLParser.XMLHelper<LetterState>(letterState, rd, letterState.sb_lettertext, LetterRules.OTagRules, LetterRules.STagRules, LetterRules.CTagRules, LetterRules.TextRules, LetterRules.WhitespaceRules);
|
new HaWeb.HTMLParser.XMLHelper<LetterState>(letterState, rd, letterState.sb_lettertext, LetterRules.OTagRules, LetterRules.STagRules, LetterRules.CTagRules, LetterRules.TextRules, LetterRules.WhitespaceRules);
|
||||||
@@ -23,8 +21,7 @@ public static class LetterHelpers
|
|||||||
return letterState;
|
return letterState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TraditionState CreateTraditions(ILibrary lib, IReaderService readerService, IEnumerable<Marginal>? marginals, Tradition tradition, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits)
|
public static TraditionState CreateTraditions(ILibrary lib, IReaderService readerService, IEnumerable<Marginal>? marginals, Tradition tradition, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits) {
|
||||||
{
|
|
||||||
var rd = readerService.RequestStringReader(tradition.Element);
|
var rd = readerService.RequestStringReader(tradition.Element);
|
||||||
var traditionState = new TraditionState(lib, rd, readerService, marginals, hands, edits);
|
var traditionState = new TraditionState(lib, rd, readerService, marginals, hands, edits);
|
||||||
new HaWeb.HTMLParser.XMLHelper<TraditionState>(traditionState, rd, traditionState.sb_tradition, TraditionRules.OTagRules, TraditionRules.STagRules, TraditionRules.CTagRules, TraditionRules.TextRules, TraditionRules.WhitespaceRules);
|
new HaWeb.HTMLParser.XMLHelper<TraditionState>(traditionState, rd, traditionState.sb_tradition, TraditionRules.OTagRules, TraditionRules.STagRules, TraditionRules.CTagRules, TraditionRules.TextRules, TraditionRules.WhitespaceRules);
|
||||||
@@ -33,13 +30,11 @@ public static class LetterHelpers
|
|||||||
return traditionState;
|
return traditionState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<(string, string, string, string, string, string)> CreateEdits(ILibrary lib, IReaderService readerService, IEnumerable<Editreason> editreasons)
|
public static List<(string, string, string, string, string, string)> CreateEdits(ILibrary lib, IReaderService readerService, IEnumerable<Editreason> editreasons) {
|
||||||
{
|
|
||||||
editreasons = editreasons.OrderBy(x => HaWeb.HTMLHelpers.ConversionHelpers.RomanOrNumberToInt(x.StartPage)).ThenBy(x => HaWeb.HTMLHelpers.ConversionHelpers.RomanOrNumberToInt(x.StartLine));
|
editreasons = editreasons.OrderBy(x => HaWeb.HTMLHelpers.ConversionHelpers.RomanOrNumberToInt(x.StartPage)).ThenBy(x => HaWeb.HTMLHelpers.ConversionHelpers.RomanOrNumberToInt(x.StartLine));
|
||||||
var editstrings = new List<(string, string, string, string, string, string)>();
|
var editstrings = new List<(string, string, string, string, string, string)>();
|
||||||
var editsState = new EditState();
|
var editsState = new EditState();
|
||||||
foreach (var edit in editreasons)
|
foreach (var edit in editreasons) {
|
||||||
{
|
|
||||||
var currstring = edit.StartPage + "/" + edit.StartLine;
|
var currstring = edit.StartPage + "/" + edit.StartLine;
|
||||||
var endstring = "";
|
var endstring = "";
|
||||||
var refstring = "";
|
var refstring = "";
|
||||||
@@ -49,8 +44,7 @@ public static class LetterHelpers
|
|||||||
endstring += edit.EndLine;
|
endstring += edit.EndLine;
|
||||||
|
|
||||||
editsState.sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "edit"));
|
editsState.sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "edit"));
|
||||||
if (!String.IsNullOrWhiteSpace(edit.Reference))
|
if (!String.IsNullOrWhiteSpace(edit.Reference)) {
|
||||||
{
|
|
||||||
var sb2 = new StringBuilder();
|
var sb2 = new StringBuilder();
|
||||||
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "reference"));
|
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "reference"));
|
||||||
var rd = readerService.RequestStringReader(edit.Reference);
|
var rd = readerService.RequestStringReader(edit.Reference);
|
||||||
@@ -58,8 +52,7 @@ public static class LetterHelpers
|
|||||||
rd.Read();
|
rd.Read();
|
||||||
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
|
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
|
||||||
// Old: (edit.StartPage != edit.EndPage || edit.StartLine != edit.EndLine) &&
|
// Old: (edit.StartPage != edit.EndPage || edit.StartLine != edit.EndLine) &&
|
||||||
if (XElement.Parse(sb2.ToString()).Value.ToString().Length >= 20)
|
if (XElement.Parse(sb2.ToString()).Value.ToString().Length >= 20) {
|
||||||
{
|
|
||||||
var text = XElement.Parse(sb2.ToString()).Value.ToString();
|
var text = XElement.Parse(sb2.ToString()).Value.ToString();
|
||||||
text = text.ToString().Split(' ').Take(1).First() + " […] " + text.ToString().Split(' ').TakeLast(1).First();
|
text = text.ToString().Split(' ').Take(1).First() + " […] " + text.ToString().Split(' ').TakeLast(1).First();
|
||||||
var sb3 = new StringBuilder();
|
var sb3 = new StringBuilder();
|
||||||
@@ -67,12 +60,10 @@ public static class LetterHelpers
|
|||||||
sb3.Append(text);
|
sb3.Append(text);
|
||||||
sb3.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
|
sb3.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
|
||||||
refstring = sb3.ToString();
|
refstring = sb3.ToString();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
refstring = sb2.ToString();
|
refstring = sb2.ToString();
|
||||||
}
|
}
|
||||||
if (!String.IsNullOrWhiteSpace(edit.Element))
|
if (!String.IsNullOrWhiteSpace(edit.Element)) {
|
||||||
{
|
|
||||||
editsState.sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "corrections"));
|
editsState.sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "corrections"));
|
||||||
var rd = readerService.RequestStringReader(edit.Element);
|
var rd = readerService.RequestStringReader(edit.Element);
|
||||||
new HaWeb.HTMLParser.XMLHelper<EditState>(editsState, rd, editsState.sb_edits, EditRules.OTagRules, EditRules.STagRules, EditRules.CTagRules, EditRules.TextRules, EditRules.WhitespaceRules);
|
new HaWeb.HTMLParser.XMLHelper<EditState>(editsState, rd, editsState.sb_edits, EditRules.OTagRules, EditRules.STagRules, EditRules.CTagRules, EditRules.TextRules, EditRules.WhitespaceRules);
|
||||||
@@ -86,11 +77,9 @@ public static class LetterHelpers
|
|||||||
return editstrings;
|
return editstrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<(string, string, string, string, string)> CreateHands(ILibrary lib, ImmutableList<Hand> hands)
|
public static List<(string, string, string, string, string)> CreateHands(ILibrary lib, ImmutableList<Hand> hands) {
|
||||||
{
|
|
||||||
var handstrings = new List<(string, string, string, string, string)>();
|
var handstrings = new List<(string, string, string, string, string)>();
|
||||||
foreach (var hand in hands.OrderBy(x => x.StartPage.Length).ThenBy(x => x.StartPage).ThenBy(x => x.StartLine.Length).ThenBy(x => x.StartLine))
|
foreach (var hand in hands.OrderBy(x => x.StartPage.Length).ThenBy(x => x.StartPage).ThenBy(x => x.StartLine.Length).ThenBy(x => x.StartLine)) {
|
||||||
{
|
|
||||||
var currstring = hand.StartPage + "/" + hand.StartLine;
|
var currstring = hand.StartPage + "/" + hand.StartLine;
|
||||||
var endstring = "";
|
var endstring = "";
|
||||||
var personstring = "";
|
var personstring = "";
|
||||||
@@ -100,8 +89,7 @@ public static class LetterHelpers
|
|||||||
if (hand.StartLine != hand.EndLine)
|
if (hand.StartLine != hand.EndLine)
|
||||||
endstring += hand.EndLine;
|
endstring += hand.EndLine;
|
||||||
var persons = lib.HandPersons.Where(x => x.Key == hand.Person);
|
var persons = lib.HandPersons.Where(x => x.Key == hand.Person);
|
||||||
if (persons.Any())
|
if (persons.Any()) {
|
||||||
{
|
|
||||||
personstring += " " + persons.FirstOrDefault().Value.Name;
|
personstring += " " + persons.FirstOrDefault().Value.Name;
|
||||||
handstrings.Add((currstring, endstring, personstring, hand.StartPage, hand.StartLine));
|
handstrings.Add((currstring, endstring, personstring, hand.StartPage, hand.StartLine));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,21 +37,20 @@ public class LinkHelper {
|
|||||||
if (tag.Name == "wwwlink" || tag.Name == "intlink" || tag.Name == "link") {
|
if (tag.Name == "wwwlink" || tag.Name == "intlink" || tag.Name == "link") {
|
||||||
if (tag.EndTag && _followlinksinthis) {
|
if (tag.EndTag && _followlinksinthis) {
|
||||||
_sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("a"));
|
_sb.Append(HTMLHelpers.TagHelpers.CreateEndElement("a"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (tag.Name == "wwwlink" && tag.Values.ContainsKey("address") && _followlinksinthis)
|
if (tag.Name == "wwwlink" && tag.Values.ContainsKey("address") && _followlinksinthis)
|
||||||
_sb.Append(HTMLHelpers.TagHelpers.CreateCustomElement("a",
|
_sb.Append(HTMLHelpers.TagHelpers.CreateCustomElement("a",
|
||||||
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "class", Value = WWWLINKCLASS },
|
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "class", Value = WWWLINKCLASS },
|
||||||
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "href", Value = tag["address"]},
|
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "href", Value = tag["address"] },
|
||||||
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "target", Value = "_blank"},
|
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "target", Value = "_blank" },
|
||||||
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "rel", Value = "noopener noreferrer"}));
|
new HaWeb.HTMLHelpers.TagHelpers.Attribute() { Name = "rel", Value = "noopener noreferrer" }));
|
||||||
if (tag.Name == "intlink" && tag.Values.ContainsKey("letter") && _lib.Metas.ContainsKey(tag["letter"])) {
|
if (tag.Name == "intlink" && tag.Values.ContainsKey("letter") && _lib.Metas.ContainsKey(tag["letter"])) {
|
||||||
var letter = _lib.Metas[tag["letter"]];
|
var letter = _lib.Metas[tag["letter"]];
|
||||||
_sb.Append(HTMLHelpers.TagHelpers.CreateElement("a", LETLINKCLASS, "/Briefe/" + letter.Autopsic + "#" + tag["page"] + "-" + tag["line"]));
|
_sb.Append(HTMLHelpers.TagHelpers.CreateElement("a", LETLINKCLASS, "/Briefe/" + letter.Autopsic + "#" + tag["page"] + "-" + tag["line"]));
|
||||||
if (!tag.Values.ContainsKey("linktext") || tag.Values["linktext"] == "true") {
|
if (!tag.Values.ContainsKey("linktext") || tag.Values["linktext"] == "true") {
|
||||||
var linkstring = "";
|
var linkstring = "";
|
||||||
var ZHstring = "";
|
var ZHstring = "";
|
||||||
var pglnstring= "";
|
var pglnstring = "";
|
||||||
linkstring += "HKB " + letter.Autopsic;
|
linkstring += "HKB " + letter.Autopsic;
|
||||||
if (tag.Values.ContainsKey("page")) {
|
if (tag.Values.ContainsKey("page")) {
|
||||||
pglnstring += tag["page"];
|
pglnstring += tag["page"];
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ using System.Web;
|
|||||||
|
|
||||||
namespace HaWeb.HTMLHelpers;
|
namespace HaWeb.HTMLHelpers;
|
||||||
public static class StringHelpers {
|
public static class StringHelpers {
|
||||||
public static string GetEnumerationString(IEnumerable<string> strlist)
|
public static string GetEnumerationString(IEnumerable<string> strlist) {
|
||||||
{
|
|
||||||
var res = "";
|
var res = "";
|
||||||
foreach (var str in strlist)
|
foreach (var str in strlist) {
|
||||||
{
|
|
||||||
if (str != strlist.First())
|
if (str != strlist.First())
|
||||||
if (str == strlist.Last())
|
if (str == strlist.Last())
|
||||||
res += " und " + str;
|
res += " und " + str;
|
||||||
|
|||||||
@@ -3,16 +3,13 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
public static class TagHelpers
|
public static class TagHelpers {
|
||||||
{
|
public struct Attribute {
|
||||||
public struct Attribute
|
|
||||||
{
|
|
||||||
public string Name;
|
public string Name;
|
||||||
public string Value;
|
public string Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string CreateElement(string elementname, string classes = "", string ids = "")
|
public static string CreateElement(string elementname, string classes = "", string ids = "") {
|
||||||
{
|
|
||||||
string res = "<" + elementname;
|
string res = "<" + elementname;
|
||||||
if (!String.IsNullOrWhiteSpace(classes))
|
if (!String.IsNullOrWhiteSpace(classes))
|
||||||
if (elementname == "button")
|
if (elementname == "button")
|
||||||
@@ -27,13 +24,10 @@ public static class TagHelpers
|
|||||||
return res + ">";
|
return res + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string CreateCustomElement(string elementname, params Attribute[] attributes)
|
public static string CreateCustomElement(string elementname, params Attribute[] attributes) {
|
||||||
{
|
|
||||||
string res = "<" + elementname;
|
string res = "<" + elementname;
|
||||||
if (!(attributes.Length == 0))
|
if (!(attributes.Length == 0)) {
|
||||||
{
|
foreach (var attrib in attributes) {
|
||||||
foreach (var attrib in attributes)
|
|
||||||
{
|
|
||||||
res += CreateAttribute(attrib);
|
res += CreateAttribute(attrib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,8 +41,7 @@ public static class TagHelpers
|
|||||||
public static string CreateAttribute(Attribute attr)
|
public static string CreateAttribute(Attribute attr)
|
||||||
=> " " + attr.Name + "=\"" + attr.Value + "\" ";
|
=> " " + attr.Name + "=\"" + attr.Value + "\" ";
|
||||||
|
|
||||||
public static string CreateEmptyElement(string elementname, string classes = "", string ids = "")
|
public static string CreateEmptyElement(string elementname, string classes = "", string ids = "") {
|
||||||
{
|
|
||||||
string res = "<" + elementname;
|
string res = "<" + elementname;
|
||||||
if (!String.IsNullOrWhiteSpace(classes))
|
if (!String.IsNullOrWhiteSpace(classes))
|
||||||
res += CreateAttribute(new Attribute() { Name = "class", Value = classes });
|
res += CreateAttribute(new Attribute() { Name = "class", Value = classes });
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
using HaDocument.Models;
|
using HaDocument.Models;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
public class BriefeMetaViewModel
|
public class BriefeMetaViewModel {
|
||||||
{
|
|
||||||
public Meta Meta { get; private set; }
|
public Meta Meta { get; private set; }
|
||||||
public bool HasMarginals { get; private set; }
|
public bool HasMarginals { get; private set; }
|
||||||
public bool ShowZHData { get; private set; }
|
public bool ShowZHData { get; private set; }
|
||||||
@@ -12,11 +11,9 @@ public class BriefeMetaViewModel
|
|||||||
private string? _ParsedReceivers;
|
private string? _ParsedReceivers;
|
||||||
private string? _ParsedZHString;
|
private string? _ParsedZHString;
|
||||||
|
|
||||||
public string? ParsedSenders
|
public string? ParsedSenders {
|
||||||
{
|
|
||||||
get => _ParsedSenders;
|
get => _ParsedSenders;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedSenders = HttpUtility.HtmlEncode(value);
|
_ParsedSenders = HttpUtility.HtmlEncode(value);
|
||||||
else
|
else
|
||||||
@@ -24,11 +21,9 @@ public class BriefeMetaViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? ParsedReceivers
|
public string? ParsedReceivers {
|
||||||
{
|
|
||||||
get => _ParsedReceivers;
|
get => _ParsedReceivers;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedReceivers = HttpUtility.HtmlEncode(value);
|
_ParsedReceivers = HttpUtility.HtmlEncode(value);
|
||||||
else
|
else
|
||||||
@@ -37,11 +32,9 @@ public class BriefeMetaViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? ParsedZHString
|
public string? ParsedZHString {
|
||||||
{
|
|
||||||
get => _ParsedZHString;
|
get => _ParsedZHString;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedZHString = HttpUtility.HtmlEncode(value);
|
_ParsedZHString = HttpUtility.HtmlEncode(value);
|
||||||
else
|
else
|
||||||
@@ -54,8 +47,7 @@ public class BriefeMetaViewModel
|
|||||||
public (BriefeMetaViewModel, string)? Prev { get; set; }
|
public (BriefeMetaViewModel, string)? Prev { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public BriefeMetaViewModel(Meta meta, bool hasMarginals, bool showZHData)
|
public BriefeMetaViewModel(Meta meta, bool hasMarginals, bool showZHData) {
|
||||||
{
|
|
||||||
Meta = meta;
|
Meta = meta;
|
||||||
HasMarginals = hasMarginals;
|
HasMarginals = hasMarginals;
|
||||||
ShowZHData = showZHData;
|
ShowZHData = showZHData;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
|
||||||
public class BriefeViewModel
|
public class BriefeViewModel {
|
||||||
{
|
|
||||||
public string Id { get; private set; }
|
public string Id { get; private set; }
|
||||||
public string Index { get; private set; }
|
public string Index { get; private set; }
|
||||||
public BriefeMetaViewModel MetaData { get; private set; }
|
public BriefeMetaViewModel MetaData { get; private set; }
|
||||||
@@ -17,11 +16,9 @@ public class BriefeViewModel
|
|||||||
public bool MinWidthTrad { get; set; } = false;
|
public bool MinWidthTrad { get; set; } = false;
|
||||||
|
|
||||||
// From, Until, Reference, Edit, sartpage, startline
|
// From, Until, Reference, Edit, sartpage, startline
|
||||||
public List<(string, string, string, string, string, string)>? ParsedEdits
|
public List<(string, string, string, string, string, string)>? ParsedEdits {
|
||||||
{
|
|
||||||
get => _ParsedEdits;
|
get => _ParsedEdits;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedEdits = value.Select(x => (
|
_ParsedEdits = value.Select(x => (
|
||||||
HttpUtility.HtmlEncode(x.Item1),
|
HttpUtility.HtmlEncode(x.Item1),
|
||||||
@@ -37,11 +34,9 @@ public class BriefeViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// From, Until, Person, startpage, startline
|
// From, Until, Person, startpage, startline
|
||||||
public List<(string, string, string, string, string)>? ParsedHands
|
public List<(string, string, string, string, string)>? ParsedHands {
|
||||||
{
|
|
||||||
get => _ParsedHands;
|
get => _ParsedHands;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedHands = value.Select(x => (
|
_ParsedHands = value.Select(x => (
|
||||||
HttpUtility.HtmlEncode(x.Item1),
|
HttpUtility.HtmlEncode(x.Item1),
|
||||||
@@ -56,11 +51,9 @@ public class BriefeViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Page, Line, Element
|
// Page, Line, Element
|
||||||
public List<(string, string, string)>? ParsedMarginals
|
public List<(string, string, string)>? ParsedMarginals {
|
||||||
{
|
|
||||||
get => _ParsedMarginals;
|
get => _ParsedMarginals;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_ParsedMarginals = value.Select(x => (
|
_ParsedMarginals = value.Select(x => (
|
||||||
HttpUtility.HtmlEncode(x.Item1),
|
HttpUtility.HtmlEncode(x.Item1),
|
||||||
@@ -72,8 +65,7 @@ public class BriefeViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BriefeViewModel(string id, string index, BriefeMetaViewModel meta)
|
public BriefeViewModel(string id, string index, BriefeMetaViewModel meta) {
|
||||||
{
|
|
||||||
Id = id;
|
Id = id;
|
||||||
Index = index;
|
Index = index;
|
||||||
MetaData = meta;
|
MetaData = meta;
|
||||||
|
|||||||
@@ -5,13 +5,11 @@ using System.Text;
|
|||||||
using HaXMLReader.Interfaces;
|
using HaXMLReader.Interfaces;
|
||||||
using HaXMLReader.EvArgs;
|
using HaXMLReader.EvArgs;
|
||||||
|
|
||||||
public class CommentModel
|
public class CommentModel {
|
||||||
{
|
|
||||||
public string ParsedComment { get; private set; }
|
public string ParsedComment { get; private set; }
|
||||||
public List<string>? ParsedSubComments { get; private set; }
|
public List<string>? ParsedSubComments { get; private set; }
|
||||||
|
|
||||||
public CommentModel(string parsedComment, List<string>? parsedSubComments)
|
public CommentModel(string parsedComment, List<string>? parsedSubComments) {
|
||||||
{
|
|
||||||
this.ParsedComment = parsedComment;
|
this.ParsedComment = parsedComment;
|
||||||
this.ParsedSubComments = parsedSubComments;
|
this.ParsedSubComments = parsedSubComments;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
|
|
||||||
public class ErrorViewModel
|
public class ErrorViewModel {
|
||||||
{
|
|
||||||
public string? RequestId { get; set; }
|
public string? RequestId { get; set; }
|
||||||
|
|
||||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
|
||||||
public class RegisterViewModel
|
public class RegisterViewModel {
|
||||||
{
|
|
||||||
public string Category { get; private set; }
|
public string Category { get; private set; }
|
||||||
public string Id { get; private set; }
|
public string Id { get; private set; }
|
||||||
public string Title { get; private set; }
|
public string Title { get; private set; }
|
||||||
@@ -15,11 +14,9 @@ public class RegisterViewModel
|
|||||||
public List<CommentModel> ParsedComments { get; private set; }
|
public List<CommentModel> ParsedComments { get; private set; }
|
||||||
|
|
||||||
// Title, URL
|
// Title, URL
|
||||||
public List<(string, string)>? AvailableCategories
|
public List<(string, string)>? AvailableCategories {
|
||||||
{
|
|
||||||
get => _AvailableCategories;
|
get => _AvailableCategories;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_AvailableCategories = value.Select(x => (
|
_AvailableCategories = value.Select(x => (
|
||||||
HttpUtility.HtmlEncode(x.Item1),
|
HttpUtility.HtmlEncode(x.Item1),
|
||||||
@@ -31,11 +28,9 @@ public class RegisterViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Title, URL
|
// Title, URL
|
||||||
public List<(string, string)>? AvailableSideCategories
|
public List<(string, string)>? AvailableSideCategories {
|
||||||
{
|
|
||||||
get => _AvailableSideCategories;
|
get => _AvailableSideCategories;
|
||||||
set
|
set {
|
||||||
{
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
_AvailableSideCategories = value.Select(x => (
|
_AvailableSideCategories = value.Select(x => (
|
||||||
HttpUtility.HtmlEncode(x.Item1),
|
HttpUtility.HtmlEncode(x.Item1),
|
||||||
@@ -46,8 +41,7 @@ public class RegisterViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterViewModel(string category, string id, List<CommentModel> parsedComments, string title)
|
public RegisterViewModel(string category, string id, List<CommentModel> parsedComments, string title) {
|
||||||
{
|
|
||||||
this.Category = HttpUtility.HtmlAttributeEncode(category);
|
this.Category = HttpUtility.HtmlAttributeEncode(category);
|
||||||
this.Id = HttpUtility.HtmlAttributeEncode(id);
|
this.Id = HttpUtility.HtmlAttributeEncode(id);
|
||||||
this.ParsedComments = parsedComments;
|
this.ParsedComments = parsedComments;
|
||||||
|
|||||||
@@ -26,10 +26,8 @@ public class DocumentResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LetterComparer : IComparer<DocumentSearchResult>
|
public class LetterComparer : IComparer<DocumentSearchResult> {
|
||||||
{
|
public int Compare(DocumentSearchResult first, DocumentSearchResult second) {
|
||||||
public int Compare(DocumentSearchResult first, DocumentSearchResult second)
|
|
||||||
{
|
|
||||||
var cmp = new DefaultComparer();
|
var cmp = new DefaultComparer();
|
||||||
return cmp.Compare(first.MetaData, second.MetaData);
|
return cmp.Compare(first.MetaData, second.MetaData);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
namespace HaWeb.Models;
|
namespace HaWeb.Models;
|
||||||
|
using HaWeb.XMLParser;
|
||||||
|
|
||||||
public class UploadViewModel {
|
public class UploadViewModel {
|
||||||
public List<(string, string)>? AvailableRoots { get; set; }
|
public List<IXMLRoot>? AvailableRoots { get; set; }
|
||||||
|
public List<XMLRootDocument>? AvailableFiles { get; set; }
|
||||||
|
public Dictionary<string, List<XMLRootDocument>>? UsedFiles { get; set; }
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,7 @@ using HaXMLReader.Interfaces;
|
|||||||
using HaDocument.Interfaces;
|
using HaDocument.Interfaces;
|
||||||
using HaWeb.XMLParser;
|
using HaWeb.XMLParser;
|
||||||
using Microsoft.FeatureManagement;
|
using Microsoft.FeatureManagement;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
@@ -14,12 +12,23 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
builder.Services.AddControllersWithViews();
|
builder.Services.AddControllersWithViews();
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
// // To list physical files from a path provided by configuration:
|
// // To get files from a path provided by configuration:
|
||||||
// var physicalProvider = new PhysicalFileProvider(Configuration.GetValue<string>("StoredFilesPath"));
|
string? filepath = null;
|
||||||
// // To list physical files in the temporary files folder, use:
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
||||||
// //var physicalProvider = new PhysicalFileProvider(Path.GetTempPath());
|
filepath = builder.Configuration.GetValue<string>("StoredFilePathWindows");
|
||||||
// services.AddSingleton<IFileProvider>(physicalProvider);
|
}
|
||||||
|
else {
|
||||||
|
filepath = builder.Configuration.GetValue<string>("StoredFilePathLinux");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filepath == null) {
|
||||||
|
throw new Exception("You need to set a specific Filepath, either StoredFilePathWindows or StoredFilePathLinux");
|
||||||
|
}
|
||||||
|
|
||||||
|
var physicalProvider = new PhysicalFileProvider(filepath);
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<IFileProvider>(physicalProvider);
|
||||||
builder.Services.AddSingleton<ILibrary>(HaDocument.Document.Create(new Options()));
|
builder.Services.AddSingleton<ILibrary>(HaDocument.Document.Create(new Options()));
|
||||||
builder.Services.AddTransient<IReaderService, ReaderService>();
|
builder.Services.AddTransient<IReaderService, ReaderService>();
|
||||||
builder.Services.AddSingleton<IXMLService, XMLService>();
|
builder.Services.AddSingleton<IXMLService, XMLService>();
|
||||||
|
|||||||
@@ -42,3 +42,5 @@ TODO Kommentare und min-size von ha-lettertetx
|
|||||||
TODO Word-wrap before align, tabs
|
TODO Word-wrap before align, tabs
|
||||||
TODO pills are not mobile friendly (hover / click)
|
TODO pills are not mobile friendly (hover / click)
|
||||||
TODO Evtl alignment von center / right an der letzten oder nächsten zeile
|
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
|
||||||
@@ -63,7 +63,7 @@ public static class CSSClasses {
|
|||||||
|
|
||||||
// Zeilen:
|
// Zeilen:
|
||||||
public const string ZHLINECLASS = "ha-zhline";
|
public const string ZHLINECLASS = "ha-zhline";
|
||||||
public const string FIRSTLINECLASS ="ha-firstline";
|
public const string FIRSTLINECLASS = "ha-firstline";
|
||||||
public const string ZHBREAKCLASS = "ha-zhbreak";
|
public const string ZHBREAKCLASS = "ha-zhbreak";
|
||||||
public const string LINELINECLASS = "ha-hr";
|
public const string LINELINECLASS = "ha-hr";
|
||||||
public const string LINEINDENTCLASS = "ha-indent-"; // TODO: GEN
|
public const string LINEINDENTCLASS = "ha-indent-"; // TODO: GEN
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace HaWeb;
|
namespace HaWeb;
|
||||||
|
|
||||||
public static class Features
|
public static class Features {
|
||||||
{
|
|
||||||
public const string AdminService = "AdminService";
|
public const string AdminService = "AdminService";
|
||||||
public const string UploadService = "UploadService";
|
public const string UploadService = "UploadService";
|
||||||
public const string UpdateService = "UpdateService";
|
public const string UpdateService = "UpdateService";
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, HaWeb.HTMLParser.XMLHel
|
|||||||
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.LetterState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.LetterState>>)>;
|
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.LetterState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.LetterState>>)>;
|
||||||
|
|
||||||
// TODO: stringbuilder als Rückgabeparameter des XMHelpers ist eigentlich auch Part vom State
|
// TODO: stringbuilder als Rückgabeparameter des XMHelpers ist eigentlich auch Part vom State
|
||||||
public class LetterRules
|
public class LetterRules {
|
||||||
{
|
|
||||||
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
||||||
|
|
||||||
private static readonly string LEMMACLASS = HaWeb.Settings.CSSClasses.LEMMACLASS;
|
private static readonly string LEMMACLASS = HaWeb.Settings.CSSClasses.LEMMACLASS;
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ using TagFuncList = List<(Func<HaXMLReader.EvArgs.Tag, HaWeb.HTMLParser.XMLHelpe
|
|||||||
using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Text, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>>)>;
|
using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Text, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>>)>;
|
||||||
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>>)>;
|
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace, HaWeb.HTMLParser.XMLHelper<HaWeb.Settings.ParsingState.TraditionState>>)>;
|
||||||
|
|
||||||
public static class TraditionRules
|
public static class TraditionRules {
|
||||||
{
|
|
||||||
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
|
||||||
|
|
||||||
private static readonly string LEMMACLASS = HaWeb.Settings.CSSClasses.LEMMACLASS;
|
private static readonly string LEMMACLASS = HaWeb.Settings.CSSClasses.LEMMACLASS;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using System.Linq;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
public class LetterState : HaWeb.HTMLParser.IState {
|
public class LetterState : HaWeb.HTMLParser.IState {
|
||||||
// Input
|
// Input
|
||||||
internal ILibrary Lib;
|
internal ILibrary Lib;
|
||||||
internal IReaderService ReaderService;
|
internal IReaderService ReaderService;
|
||||||
internal Meta Meta;
|
internal Meta Meta;
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ public class TraditionState : HaWeb.HTMLParser.IState {
|
|||||||
|
|
||||||
internal IReader rd_tradition;
|
internal IReader rd_tradition;
|
||||||
|
|
||||||
public TraditionState(ILibrary lib, IReader reader, IReaderService readerService, IEnumerable<Marginal>? marginals, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits)
|
public TraditionState(ILibrary lib, IReader reader, IReaderService readerService, IEnumerable<Marginal>? marginals, IEnumerable<Hand>? hands, IEnumerable<Editreason>? edits) {
|
||||||
{
|
|
||||||
Lib = lib;
|
Lib = lib;
|
||||||
rd_tradition = reader;
|
rd_tradition = reader;
|
||||||
Marginals = marginals;
|
Marginals = marginals;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using HaWeb.XMLParser;
|
|||||||
public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {
|
public class DescriptionsRoot : HaWeb.XMLParser.IXMLRoot {
|
||||||
public string Type { get; } = "Metadaten";
|
public string Type { get; } = "Metadaten";
|
||||||
public string Prefix { get; } = "metadaten";
|
public string Prefix { get; } = "metadaten";
|
||||||
public string[] XPathContainer { get; } = {".//data/descriptions", ".//descriptions" };
|
public string[] XPathContainer { get; } = { ".//data/descriptions", ".//descriptions" };
|
||||||
|
|
||||||
public Predicate<XElement> IsCollectedObject { get; } = (elem) => {
|
public Predicate<XElement> IsCollectedObject { get; } = (elem) => {
|
||||||
if (elem.Name == "letterDesc") return true;
|
if (elem.Name == "letterDesc") return true;
|
||||||
|
|||||||
@@ -1,57 +1,79 @@
|
|||||||
@model UploadViewModel;
|
@model UploadViewModel;
|
||||||
Hello from Upload Index!
|
|
||||||
|
|
||||||
<form id="uploadForm" action="Upload" method="post"
|
<div class="ha-adminuploadfields">
|
||||||
enctype="multipart/form-data" onsubmit="AJAXSubmit(this);return false;">
|
@foreach (var item in Model.AvailableRoots.OrderBy(x => x.Type)) {
|
||||||
<dl>
|
<div class="ha-uploadfield">
|
||||||
<dt>
|
<div class="ha-uploadfieldname">@item.Type</div>
|
||||||
<label for="file">File</label>
|
@if (Model.UsedFiles != null && Model.UsedFiles.ContainsKey(item.Prefix)) {
|
||||||
</dt>
|
@foreach(var file in Model.UsedFiles[item.Prefix]) {
|
||||||
<dd>
|
<span>@file.File.Name</span>
|
||||||
<input id="file" type="file" name="file" />
|
}
|
||||||
</dd>
|
}
|
||||||
</dl>
|
|
||||||
|
|
||||||
<input class="btn" type="submit" value="Upload" />
|
|
||||||
|
|
||||||
<div style="margin-top:15px">
|
|
||||||
<output form="uploadForm" name="result"></output>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
}
|
||||||
|
<form class="ha-uploadform" id="uploadForm" action="Upload" method="post" enctype="multipart/form-data">
|
||||||
@foreach (var item in Model.AvailableRoots.OrderBy(x => x.Item1))
|
<label class="filelabel" id="dropzone">
|
||||||
{
|
<input class="hidden" id="file" type="file" accept=".xml" name="file" />
|
||||||
<div>@item.Item1</div>
|
Upload2 es
|
||||||
}
|
</label>
|
||||||
|
<div class="ha-uploadmessage">
|
||||||
|
<output form="uploadForm" name="result"></output>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
|
|
||||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
|
||||||
asp-fallback-test="window.jQuery"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
async function AJAXSubmit (oFormElement) {
|
const dropHandler = function (formelement, ev, dropzone) {
|
||||||
const formData = new FormData(oFormElement);
|
ev.preventDefault();
|
||||||
|
|
||||||
try {
|
if (ev.dataTransfer.items) {
|
||||||
const response = await fetch(oFormElement.action, {
|
if (ev.dataTransfer.items[0].kind === 'file') {
|
||||||
|
var file = ev.dataTransfer.items[0].getAsFile();
|
||||||
|
AJAXSubmit(formelement, file);
|
||||||
|
} else {
|
||||||
|
var file = ev.dataTransfer.files[0];
|
||||||
|
AJAXSubmit(formelement, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragOverHandler = function (ev, dropzone) {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragLeaveHander = function (ev, dropzone) {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragEnterHandler = function (ev, dropzone) {
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AJAXSubmit = async function (oFormElement, file = null) {
|
||||||
|
var fd = new FormData();
|
||||||
|
if (file !== null) fd.append("file", file);
|
||||||
|
else fd = new FormData(oFormElement);
|
||||||
|
oFormElement.elements.namedItem("result").value = "Wait";
|
||||||
|
await fetch(oFormElement.action, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'RequestVerificationToken': getCookie('RequestVerificationToken')
|
'RequestVerificationToken': getCookie('RequestVerificationToken')
|
||||||
},
|
},
|
||||||
body: formData
|
body: fd
|
||||||
});
|
})
|
||||||
|
.then(response => response.json())
|
||||||
oFormElement.elements.namedItem("result").value =
|
.then(json => {
|
||||||
'Result: ' + response.status + ' ' + response.statusText;
|
if ("Error" in json) {
|
||||||
} catch (error) {
|
oFormElement.elements.namedItem("result").value = json.Error;
|
||||||
console.error('Error:', error);
|
} else {
|
||||||
}
|
oFormElement.elements.namedItem("result").value = "Erfolg!";
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch ((e) => console.error('Error:', error))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
@@ -59,5 +81,18 @@ Hello from Upload Index!
|
|||||||
var parts = value.split("; " + name + "=");
|
var parts = value.split("; " + name + "=");
|
||||||
if (parts.length == 2) return parts.pop().split(";").shift();
|
if (parts.length == 2) return parts.pop().split(";").shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function () {
|
||||||
|
var submitelement = document.getElementById("file");
|
||||||
|
var formelement = document.getElementById("uploadForm");
|
||||||
|
var dropzone = document.getElementById("dropzone");
|
||||||
|
submitelement.addEventListener("change", () => AJAXSubmit(formelement));
|
||||||
|
dropzone.addEventListener("drop", (ev) => dropHandler(formelement, ev, dropzone));
|
||||||
|
dropzone.addEventListener("dragover", (ev) => dragOverHandler(ev, dropzone));
|
||||||
|
dropzone.addEventListener("dragleave", (ev) => dragLeaveHander(ev, dropzone));
|
||||||
|
dropzone.addEventListener("dragenter", (ev) => dragEnterHandler(ev, dropzone));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,46 +7,44 @@
|
|||||||
if (Model.MinWidthTrad)
|
if (Model.MinWidthTrad)
|
||||||
minwidthtrads = "ha-minwidth";
|
minwidthtrads = "ha-minwidth";
|
||||||
}
|
}
|
||||||
<div class="ha-twilighttogglebar">
|
<div class="ha-letterheader">
|
||||||
<div class="ha-letterheader">
|
@await Html.PartialAsync("/Views/Shared/_LetterHead.cshtml", Model.MetaData)
|
||||||
@await Html.PartialAsync("/Views/Shared/_LetterHead.cshtml", Model.MetaData)
|
<div class="ha-letterheadernav">
|
||||||
<div class="ha-letterheadernav">
|
<div class="ha-lettertabs">
|
||||||
<div class="ha-lettertabs">
|
@if (Model.ParsedText != null && !String.IsNullOrWhiteSpace(Model.ParsedText))
|
||||||
@if (Model.ParsedText != null && !String.IsNullOrWhiteSpace(Model.ParsedText))
|
|
||||||
{
|
|
||||||
<a class="" id="ha-lettertextbtn">Brieftext</a>
|
|
||||||
@if (Model.ParsedMarginals != null)
|
|
||||||
{
|
|
||||||
<a class="ha-marginalsbtn " id="ha-marginalsbtn">Stellenkommentar</a>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<a class="" id="ha-additionsbtn">Überlieferung & Textkritik</a>
|
|
||||||
<a class="">PDF</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (Model.MetaData.Next != null || Model.MetaData.Prev != null)
|
|
||||||
{
|
{
|
||||||
<div class="ha-lettermetalinks">
|
<a class="" id="ha-lettertextbtn">Brieftext</a>
|
||||||
@if (Model.MetaData.Prev != null)
|
@if (Model.ParsedMarginals != null)
|
||||||
{
|
{
|
||||||
<a href="@Model.MetaData.Prev.Value.Item2">
|
<a class="ha-marginalsbtn " id="ha-marginalsbtn">Stellenkommentar</a>
|
||||||
@Model.MetaData.Prev.Value.Item1.Meta.Autopsic ◀
|
}
|
||||||
</a>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="ha-hkb">
|
|
||||||
HKB
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (Model.MetaData.Next != null)
|
|
||||||
{
|
|
||||||
<a href="@Model.MetaData.Next.Value.Item2">
|
|
||||||
▶ @Model.MetaData.Next.Value.Item1.Meta.Autopsic
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
<a class="" id="ha-additionsbtn">Überlieferung & Textkritik</a>
|
||||||
|
<a class="">PDF</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (Model.MetaData.Next != null || Model.MetaData.Prev != null)
|
||||||
|
{
|
||||||
|
<div class="ha-lettermetalinks">
|
||||||
|
@if (Model.MetaData.Prev != null)
|
||||||
|
{
|
||||||
|
<a href="@Model.MetaData.Prev.Value.Item2">
|
||||||
|
@Model.MetaData.Prev.Value.Item1.Meta.Autopsic ◀
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="ha-hkb">
|
||||||
|
HKB
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (Model.MetaData.Next != null)
|
||||||
|
{
|
||||||
|
<a href="@Model.MetaData.Next.Value.Item2">
|
||||||
|
▶ @Model.MetaData.Next.Value.Item1.Meta.Autopsic
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
<div class="flex grow shrink-0">
|
<div class="flex grow shrink-0">
|
||||||
<div class="ha-themetoggles">
|
<div class="ha-themetoggles">
|
||||||
<input type="radio" id="ha-toggledark" name="ha-themetoggle">
|
<input type="radio" id="ha-toggledark" name="ha-themetoggle">
|
||||||
<input type="radio" id="ha-toggletwilight" name="ha-themetoggle">
|
|
||||||
<input type="radio" id="ha-togglebright" name="ha-themetoggle">
|
<input type="radio" id="ha-togglebright" name="ha-themetoggle">
|
||||||
<label for="ha-toggledark"></label>
|
<label for="ha-toggledark"></label>
|
||||||
<label for="ha-toggletwilight"></label>
|
|
||||||
<label for="ha-togglebright"></label>
|
<label for="ha-togglebright"></label>
|
||||||
<div class="ha-themetoggleslider">
|
<div class="ha-themetoggleslider">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ public interface IXMLRoot {
|
|||||||
var elements = root.XPathSelectElements(p);
|
var elements = root.XPathSelectElements(p);
|
||||||
if (elements != null && elements.Any()) {
|
if (elements != null && elements.Any()) {
|
||||||
if (ret == null) ret = new List<XElement>();
|
if (ret == null) ret = new List<XElement>();
|
||||||
ret.AddRange(elements);
|
foreach (var e in elements)
|
||||||
|
if (!ret.Contains(e)) ret.Add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate certain metadat fields to display about this root
|
// Generate certain metadata fields to display about this root
|
||||||
public abstract List<(string, string?)>? GenerateFields(XMLRootDocument document);
|
public abstract List<(string, string?)>? GenerateFields(XMLRootDocument document);
|
||||||
|
|
||||||
// Generate an identification string of which the hash will be the filename.
|
// Generate an identification string of which the hash will be the filename.
|
||||||
|
|||||||
@@ -5,5 +5,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|||||||
public interface IXMLService {
|
public interface IXMLService {
|
||||||
public IXMLRoot? GetRoot(string name);
|
public IXMLRoot? GetRoot(string name);
|
||||||
public List<IXMLRoot>? GetRoots();
|
public List<IXMLRoot>? GetRoots();
|
||||||
public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState);
|
public Task<List<XMLRootDocument>?> ProbeHamannFile(XDocument document, ModelStateDictionary ModelState);
|
||||||
|
public Task UpdateAvailableFiles(XMLRootDocument doc, string basefilepath, ModelStateDictionary ModelState);
|
||||||
|
public Dictionary<string, List<XMLRootDocument>> GetUsed();
|
||||||
}
|
}
|
||||||
34
HaWeb/XMLParser/JSONConverters.cs
Normal file
34
HaWeb/XMLParser/JSONConverters.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
namespace HaWeb.XMLParser;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
||||||
|
public class IdentificationStringJSONConverter : JsonConverter<(string?, string?)>
|
||||||
|
{
|
||||||
|
public override (string?, string?) Read(
|
||||||
|
ref Utf8JsonReader reader,
|
||||||
|
Type typeToConvert,
|
||||||
|
JsonSerializerOptions options) {
|
||||||
|
var s = reader.GetString();
|
||||||
|
if (s == null) return (null, null);
|
||||||
|
var split = s.Split('-');
|
||||||
|
string? str1 = null;
|
||||||
|
if (!String.IsNullOrWhiteSpace(split[0])) str1 = split[0];
|
||||||
|
if (s.Length > 1 && !String.IsNullOrWhiteSpace(split[1])) return (str1, split[1]);
|
||||||
|
else return (str1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(
|
||||||
|
Utf8JsonWriter writer,
|
||||||
|
(string?, string?) value,
|
||||||
|
JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value.Item1 == null && value.Item2 == null) return;
|
||||||
|
var res = "";
|
||||||
|
if (value.Item1 != null) res += value.Item1;
|
||||||
|
if (value.Item2 != null) res += "-" + value.Item2;
|
||||||
|
writer.WriteStringValue(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,42 +2,45 @@ namespace HaWeb.XMLParser;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
public class XMLRootDocument {
|
public class XMLRootDocument {
|
||||||
private XElement? _Element;
|
private XElement? _Element;
|
||||||
private string? _filename;
|
private string? _filename;
|
||||||
private string? _path;
|
|
||||||
private IXMLService _xmlService;
|
private IXMLService _xmlService;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public XElement Root {
|
public XElement Root {
|
||||||
get {
|
get {
|
||||||
if (_Element == null) {
|
if (_Element == null) {
|
||||||
_Element = GetElement();
|
_Element = _GetElement();
|
||||||
}
|
}
|
||||||
return _Element;
|
return _Element;
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string FileName { get {
|
public string FileName {
|
||||||
if (_filename == null)
|
get {
|
||||||
_filename = _CreateFilename();
|
if (_filename == null)
|
||||||
return _filename;
|
_filename = _CreateFilename();
|
||||||
} }
|
return _filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public IFileInfo? File { get; private set; }
|
||||||
public string Prefix { get; private set; }
|
public string Prefix { get; private set; }
|
||||||
public DateTime Date { get; private set; }
|
public DateTime Date { get; private set; }
|
||||||
|
public bool Used { get; private set; } = false;
|
||||||
|
|
||||||
public (string?, string?) IdentificationString { get; private set; }
|
public (string?, string?) IdentificationString { get; private set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public List<(string, string)>? Fields { get; set; }
|
public List<(string, string)>? Fields { get; set; }
|
||||||
|
|
||||||
// Entry point for file reading
|
// Entry point for file reading
|
||||||
public XMLRootDocument(IXMLService xmlService, string prefix, (string?, string?) idString, DateTime date, string path) {
|
public XMLRootDocument(IXMLService xmlService, IFileInfo file) {
|
||||||
_xmlService = xmlService;
|
_xmlService = xmlService;
|
||||||
_path = path;
|
SetFile(file);
|
||||||
Prefix = prefix;
|
|
||||||
IdentificationString = idString;
|
|
||||||
Date = date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point for XML upload reading
|
// Entry point for XML upload reading
|
||||||
@@ -49,6 +52,19 @@ public class XMLRootDocument {
|
|||||||
_Element = element;
|
_Element = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetFile(IFileInfo file) {
|
||||||
|
File = file;
|
||||||
|
Date = file.LastModified.DateTime;
|
||||||
|
_GenerateFieldsFromFilename(file.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetUsed(bool used) {
|
||||||
|
Used = used;
|
||||||
|
if (used && _Element == null) {
|
||||||
|
_GetElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string _CreateFilename() {
|
private string _CreateFilename() {
|
||||||
var filename = _removeInvalidChars(Prefix) + "_";
|
var filename = _removeInvalidChars(Prefix) + "_";
|
||||||
if (!String.IsNullOrWhiteSpace(IdentificationString.Item1)) {
|
if (!String.IsNullOrWhiteSpace(IdentificationString.Item1)) {
|
||||||
@@ -69,28 +85,39 @@ public class XMLRootDocument {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private XElement GetElement() {
|
private void _GenerateFieldsFromFilename(string filename) {
|
||||||
if (_path == null || String.IsNullOrWhiteSpace(_path))
|
var split = filename.Split('_');
|
||||||
|
Prefix = split[0];
|
||||||
|
if (split.Length == 3) {
|
||||||
|
IdentificationString = (null, split[1]);
|
||||||
|
} else if (split.Length == 4) {
|
||||||
|
IdentificationString = (split[1], split[2]);
|
||||||
|
} else {
|
||||||
|
IdentificationString = (null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private XElement _GetElement() {
|
||||||
|
if (File == null || String.IsNullOrWhiteSpace(File.PhysicalPath) || !File.Exists)
|
||||||
throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden.");
|
throw new Exception("Es ist kein Pfad für die XML-Datei vorhanden.");
|
||||||
|
|
||||||
var root = _xmlService.GetRoot(Prefix);
|
var root = _xmlService.GetRoot(Prefix);
|
||||||
if (root == null)
|
if (root == null)
|
||||||
throw new Exception("Kein gültiges Hamann-Dokument: " + _path + "Vom Prefix: " + Prefix);
|
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
||||||
|
|
||||||
XDocument? doc = null;
|
XDocument? doc = null;
|
||||||
try {
|
try {
|
||||||
doc = XDocument.Load(_path, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
|
doc = XDocument.Load(File.PhysicalPath, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex) {
|
|
||||||
throw new Exception("Fehler beim Lesen des Dokuments: " + ex.Message);
|
throw new Exception("Fehler beim Lesen des Dokuments: " + ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc == null || doc.Root == null)
|
if (doc == null || doc.Root == null)
|
||||||
throw new Exception("Das Dokument ist ungültig und kann nicht gelesen werden: " + _path);
|
throw new Exception("Das Dokument ist ungültig und kann nicht gelesen werden: " + File.PhysicalPath);
|
||||||
|
|
||||||
var element = root.IsTypeOf(doc.Root);
|
var element = root.IsTypeOf(doc.Root);
|
||||||
if (element == null || !element.Any())
|
if (element == null || !element.Any())
|
||||||
throw new Exception("Kein gültiges Hamann-Dokument: " + _path + "Vom Prefix: " + Prefix);
|
throw new Exception("Kein gültiges Hamann-Dokument: " + File.PhysicalPath + "Vom Prefix: " + Prefix);
|
||||||
|
|
||||||
return element.First();
|
return element.First();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,43 @@ namespace HaWeb.XMLParser;
|
|||||||
using HaWeb.Settings.XMLRoots;
|
using HaWeb.Settings.XMLRoots;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.FeatureManagement;
|
||||||
|
|
||||||
public class XMLService : IXMLService {
|
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, IXMLRoot>? _Roots;
|
private Dictionary<string, IXMLRoot>? _Roots;
|
||||||
|
|
||||||
public XMLService() {
|
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
|
||||||
var types = _GetAllTypesThatImplementInterface<IXMLRoot>().ToList();
|
var types = _GetAllTypesThatImplementInterface<IXMLRoot>().ToList();
|
||||||
types.ForEach( x => {
|
types.ForEach( x => {
|
||||||
if (this._Roots == null) this._Roots = new Dictionary<string, IXMLRoot>();
|
if (this._Roots == null) this._Roots = new Dictionary<string, IXMLRoot>();
|
||||||
var instance = (IXMLRoot)Activator.CreateInstance(x)!;
|
var instance = (IXMLRoot)Activator.CreateInstance(x)!;
|
||||||
if (instance != null) this._Roots.Add(instance.Prefix, instance);
|
if (instance != null) this._Roots.Add(instance.Prefix, instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (_Roots == null || !_Roots.Any())
|
||||||
|
throw new Exception("No classes for upload endpoints were found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IXMLRoot? GetRoot(string name) {
|
public IXMLRoot? GetRoot(string name) {
|
||||||
@@ -22,7 +48,7 @@ public class XMLService : IXMLService {
|
|||||||
|
|
||||||
public List<IXMLRoot>? GetRoots() => this._Roots == null ? null : this._Roots.Values.ToList();
|
public List<IXMLRoot>? GetRoots() => this._Roots == null ? null : this._Roots.Values.ToList();
|
||||||
|
|
||||||
public List<XMLRootDocument>? ProbeHamannFile(XDocument document, ModelStateDictionary ModelState) {
|
public async Task<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;
|
||||||
@@ -43,6 +69,63 @@ public class XMLService : IXMLService {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateAvailableFiles() {
|
||||||
|
_availableFilesObj = _GetAvailableFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoDetermineUsed(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) {
|
private XMLRootDocument _createXMLRootDocument(IXMLRoot Root, XElement element) {
|
||||||
var doc = new XMLRootDocument(this, Root.Prefix, Root.GenerateIdentificationString(element), element);
|
var doc = new XMLRootDocument(this, Root.Prefix, Root.GenerateIdentificationString(element), element);
|
||||||
doc.Fields = Root.GenerateFields(doc);
|
doc.Fields = Root.GenerateFields(doc);
|
||||||
@@ -56,4 +139,63 @@ public class XMLService : IXMLService {
|
|||||||
.Where(type => typeof(T).IsAssignableFrom(type) && !type.IsInterface);
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
16
HaWeb/omnisharp.json
Normal file
16
HaWeb/omnisharp.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"FormattingOptions": {
|
||||||
|
"NewLinesForBracesInLambdaExpressionBody": false,
|
||||||
|
"NewLinesForBracesInAnonymousMethods": false,
|
||||||
|
"NewLinesForBracesInAnonymousTypes": false,
|
||||||
|
"NewLinesForBracesInControlBlocks": false,
|
||||||
|
"NewLinesForBracesInTypes": false,
|
||||||
|
"NewLinesForBracesInMethods": false,
|
||||||
|
"NewLinesForBracesInProperties": false,
|
||||||
|
"NewLinesForBracesInObjectCollectionArrayInitializers": false,
|
||||||
|
"NewLinesForBracesInAccessors": false,
|
||||||
|
"NewLineForElse": false,
|
||||||
|
"NewLineForCatch": false,
|
||||||
|
"NewLineForFinally": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -468,6 +468,14 @@ Ensure the default browser behavior of the `hidden` attribute.
|
|||||||
--tw-backdrop-sepia: ;
|
--tw-backdrop-sepia: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 100ms;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
|
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
|
||||||
|
|
||||||
/* Everything related to theme color */
|
/* Everything related to theme color */
|
||||||
@@ -570,21 +578,36 @@ body {
|
|||||||
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
||||||
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
|
transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggledark:checked ~ .ha-themetoggleslider {
|
.dark .ha-footer .ha-themetoggles {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(30 41 59 / var(--tw-bg-opacity));
|
background-color: rgb(30 41 59 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggletwilight:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-toggledark:checked ~ .ha-themetoggleslider {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
background-color: rgb(226 232 240 / var(--tw-bg-opacity));
|
||||||
|
transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(248 250 252 / var(--tw-bg-opacity));
|
background-color: rgb(248 250 252 / var(--tw-bg-opacity));
|
||||||
|
transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-static {
|
.ha-static {
|
||||||
@@ -1013,6 +1036,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist, .ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
.ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist, .ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(241 245 249 / var(--tw-bg-opacity));
|
||||||
padding-bottom: 0.25rem;
|
padding-bottom: 0.25rem;
|
||||||
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||||
@@ -1020,6 +1045,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dark .ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist, .dark .ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
.dark .ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist, .dark .ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(71 85 105 / var(--tw-bg-opacity));
|
||||||
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||||
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
||||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
@@ -1115,6 +1142,8 @@ body {
|
|||||||
color: rgb(31 41 55 / var(--tw-text-opacity)) !important;
|
color: rgb(31 41 55 / var(--tw-text-opacity)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Classes */
|
||||||
|
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -1258,7 +1287,7 @@ body {
|
|||||||
.ha-footer .ha-themetoggles {
|
.ha-footer .ha-themetoggles {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
width: 49px;
|
width: 34px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-radius: 1.5rem;
|
border-radius: 1.5rem;
|
||||||
padding-left: 0.125rem;
|
padding-left: 0.125rem;
|
||||||
@@ -1305,12 +1334,8 @@ body {
|
|||||||
left: 0.25rem;
|
left: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggletwilight:checked ~ .ha-themetoggleslider {
|
|
||||||
left: 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
||||||
left: 34px;
|
left: 19px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Classes for static pages */
|
/* Classes for static pages */
|
||||||
@@ -2254,6 +2279,7 @@ body {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
-moz-column-gap: 1.5rem;
|
-moz-column-gap: 1.5rem;
|
||||||
column-gap: 1.5rem;
|
column-gap: 1.5rem;
|
||||||
|
padding-right: 0.25rem;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
@@ -2791,6 +2817,10 @@ body {
|
|||||||
width: 2rem;
|
width: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-w-\[25\%\] {
|
||||||
|
max-width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
.shrink-0 {
|
.shrink-0 {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -2827,6 +2857,10 @@ body {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gap-5 {
|
||||||
|
gap: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.overflow-hidden {
|
.overflow-hidden {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
|
* {
|
||||||
|
@apply transition-colors duration-100
|
||||||
|
}
|
||||||
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
|
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
|
||||||
|
|
||||||
/* Everything related to theme color */
|
/* Everything related to theme color */
|
||||||
@@ -118,19 +121,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles {
|
.ha-footer .ha-themetoggles {
|
||||||
@apply bg-slate-200 shadow-inner
|
@apply bg-slate-200 dark:bg-slate-800 transition-colors duration-300 shadow-inner
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggledark:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-toggledark:checked ~ .ha-themetoggleslider {
|
||||||
@apply bg-slate-800
|
@apply bg-slate-200 transition-colors duration-300
|
||||||
}
|
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggletwilight:checked ~ .ha-themetoggleslider {
|
|
||||||
@apply bg-slate-500
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
||||||
@apply bg-slate-50
|
@apply bg-slate-50 transition-colors duration-300
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-static {
|
.ha-static {
|
||||||
@@ -278,7 +277,7 @@
|
|||||||
|
|
||||||
.ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist,
|
.ha-tradzhtext .ha-marginalbox.ha-expanded-box .ha-marginallist,
|
||||||
.ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
.ha-lettertext .ha-marginalbox.ha-expanded-box .ha-marginallist {
|
||||||
@apply shadow-md dark:shadow-lg pb-1
|
@apply shadow-md dark:shadow-lg pb-1 bg-slate-100 dark:bg-slate-600
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-tradzhtext .ha-btn-collapsed-box,
|
.ha-tradzhtext .ha-btn-collapsed-box,
|
||||||
@@ -322,7 +321,7 @@
|
|||||||
@apply !text-hamannHighlight dark:!text-gray-800
|
@apply !text-hamannHighlight dark:!text-gray-800
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Classes */
|
||||||
body {
|
body {
|
||||||
@apply text-base desktop:text-lg w-full h-full;
|
@apply text-base desktop:text-lg w-full h-full;
|
||||||
}
|
}
|
||||||
@@ -373,7 +372,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles {
|
.ha-footer .ha-themetoggles {
|
||||||
@apply whitespace-nowrap relative px-0.5 rounded-3xl h-4 w-[49px]
|
@apply whitespace-nowrap relative px-0.5 rounded-3xl h-4 w-[34px]
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles * {
|
.ha-footer .ha-themetoggles * {
|
||||||
@@ -396,12 +395,8 @@
|
|||||||
@apply left-1
|
@apply left-1
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-toggletwilight:checked ~ .ha-themetoggleslider {
|
|
||||||
@apply left-[19px]
|
|
||||||
}
|
|
||||||
|
|
||||||
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
.ha-footer .ha-themetoggles #ha-togglebright:checked ~ .ha-themetoggleslider {
|
||||||
@apply left-[34px]
|
@apply left-[19px]
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Classes for static pages */
|
/* Classes for static pages */
|
||||||
@@ -898,7 +893,7 @@
|
|||||||
|
|
||||||
.ha-tradzhtext .ha-marginalbox .ha-marginallist,
|
.ha-tradzhtext .ha-marginalbox .ha-marginallist,
|
||||||
.ha-lettertext .ha-marginalbox .ha-marginallist {
|
.ha-lettertext .ha-marginalbox .ha-marginallist {
|
||||||
@apply text-sm leading-tight flex flex-wrap gap-x-6
|
@apply text-sm leading-tight flex flex-wrap gap-x-6 pr-1
|
||||||
}
|
}
|
||||||
|
|
||||||
.ha-tradzhtext .ha-marginalbox .ha-marginallist .ha-marginal,
|
.ha-tradzhtext .ha-marginalbox .ha-marginallist .ha-marginal,
|
||||||
|
|||||||
@@ -221,21 +221,8 @@ const go_to_dark = function () {
|
|||||||
document.documentElement.classList.add("dark");
|
document.documentElement.classList.add("dark");
|
||||||
};
|
};
|
||||||
|
|
||||||
const go_to_twilight = function () {
|
|
||||||
document.documentElement.classList.remove("dark");
|
|
||||||
let elements = document.getElementsByClassName("ha-twilighttogglebar");
|
|
||||||
for (let el of elements) {
|
|
||||||
el.classList.add("dark");
|
|
||||||
}
|
|
||||||
localStorage.setItem("theme", "ha-toggletwilight");
|
|
||||||
};
|
|
||||||
|
|
||||||
const go_to_bright = function () {
|
const go_to_bright = function () {
|
||||||
document.documentElement.classList.remove("dark");
|
document.documentElement.classList.remove("dark");
|
||||||
let elements = document.getElementsByClassName("ha-twilighttogglebar");
|
|
||||||
for (let el of elements) {
|
|
||||||
el.classList.remove("dark");
|
|
||||||
}
|
|
||||||
localStorage.setItem("theme", "ha-togglebright");
|
localStorage.setItem("theme", "ha-togglebright");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -335,7 +322,6 @@ window.addEventListener("load", function () {
|
|||||||
// Register theme toggler
|
// Register theme toggler
|
||||||
if (
|
if (
|
||||||
document.getElementById("ha-togglebright") !== null &&
|
document.getElementById("ha-togglebright") !== null &&
|
||||||
document.getElementById("ha-toggletwilight") !== null &&
|
|
||||||
this.document.getElementById("ha-toggledark") !== null
|
this.document.getElementById("ha-toggledark") !== null
|
||||||
) {
|
) {
|
||||||
document
|
document
|
||||||
@@ -344,9 +330,6 @@ window.addEventListener("load", function () {
|
|||||||
document
|
document
|
||||||
.getElementById("ha-toggledark")
|
.getElementById("ha-toggledark")
|
||||||
.addEventListener("click", go_to_dark);
|
.addEventListener("click", go_to_dark);
|
||||||
document
|
|
||||||
.getElementById("ha-toggletwilight")
|
|
||||||
.addEventListener("click", go_to_twilight);
|
|
||||||
}
|
}
|
||||||
get_theme_settings("ha-togglebright");
|
get_theme_settings("ha-togglebright");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<opus><definitions></definitions></opus>
|
<opus></opus>
|
||||||
Reference in New Issue
Block a user