mirror of
				https://github.com/Theodor-Springmann-Stiftung/hamann-ausgabe-core.git
				synced 2025-11-03 19:55:32 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			222 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Linq;
 | 
						|
using System.Threading.Tasks;
 | 
						|
using Microsoft.AspNetCore.Mvc;
 | 
						|
using Microsoft.AspNetCore.Mvc.RazorPages;
 | 
						|
using HaDocument.Interfaces;
 | 
						|
using System.Collections.Immutable;
 | 
						|
using HaDocument.Models;
 | 
						|
using HaDocument.Comparers;
 | 
						|
using HaXMLReader.EvArgs;
 | 
						|
using HaLive.Models;
 | 
						|
using HaXMLReader.Interfaces;
 | 
						|
using System.Collections.Concurrent;
 | 
						|
 | 
						|
namespace HaLive.Pages
 | 
						|
{
 | 
						|
    public class IndexModel : PageModel
 | 
						|
    {
 | 
						|
        const int MAX_SRESULTS = 1000;
 | 
						|
        const int MINLETTPG = 90;
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string fdletter { get; set; }= "";
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string search { get; set; } = "";
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string person { get; set; } = "";
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string havolume { get; set; } = "";
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string hapage { get; set; } = "";
 | 
						|
 | 
						|
        [BindProperty(SupportsGet = true)]
 | 
						|
        public string selpage { get; set; } = "";
 | 
						|
 | 
						|
        public enum IndexState {
 | 
						|
            Initial,
 | 
						|
            Search,
 | 
						|
            ZHLookup,
 | 
						|
            PersonLookup
 | 
						|
        }
 | 
						|
 | 
						|
        public enum IndexFailState {
 | 
						|
            None,
 | 
						|
            SearchTooManyResults,
 | 
						|
            SearchNoResult,
 | 
						|
            ZHNotFound,
 | 
						|
            LetterNotFound
 | 
						|
        }
 | 
						|
 | 
						|
        public int cleanpage { get; set; } = 0;
 | 
						|
 | 
						|
        public IndexState State { get; set; } = IndexState.Initial;
 | 
						|
        public IndexFailState FailState { get; set; } = IndexFailState.None;
 | 
						|
        public List<List<IGrouping<int, DocumentSearchResult>>> Result = null;
 | 
						|
        public ImmutableSortedSet<Person> SelectedPersons = null;
 | 
						|
 | 
						|
        private ILibrary _lib;
 | 
						|
        private IReaderService _readerService;
 | 
						|
 | 
						|
        public IndexModel(ILibrary lib, IReaderService readerservice) {
 | 
						|
            _lib = lib;
 | 
						|
            _readerService = readerservice;
 | 
						|
            PrepareData();
 | 
						|
        }
 | 
						|
 | 
						|
        private void PrepareData() {
 | 
						|
            // Create a list of persons
 | 
						|
            var _SelectedPersons = new List<Person>(100);
 | 
						|
            foreach (var letter in _lib.MetasByDate) {
 | 
						|
                foreach (var sender in letter.Senders) {
 | 
						|
                    var p = _lib.Persons[sender];
 | 
						|
                    if (!_SelectedPersons.Contains(p)) {
 | 
						|
                        _SelectedPersons.Add(p);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                foreach (var receiver in letter.Receivers) {
 | 
						|
                    var p = _lib.Persons[receiver];
 | 
						|
                    if (!_SelectedPersons.Contains(p)) {
 | 
						|
                        _SelectedPersons.Add(p);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            SelectedPersons = _SelectedPersons.ToImmutableSortedSet(new PersonComparer());
 | 
						|
        }
 | 
						|
 | 
						|
        public IActionResult OnGet() {
 | 
						|
            if (!String.IsNullOrWhiteSpace(fdletter)) {
 | 
						|
                if (_lib.Metas.Where(x => x.Value.Autopsic == fdletter).Any())
 | 
						|
                    return Redirect("/Briefe/" + fdletter);
 | 
						|
                else
 | 
						|
                    FailState = IndexFailState.LetterNotFound;
 | 
						|
                State = IndexState.Initial;
 | 
						|
                return Default();
 | 
						|
            }
 | 
						|
            // State detection and Execution
 | 
						|
            if (!String.IsNullOrWhiteSpace(search)) {
 | 
						|
                State = IndexState.Search;
 | 
						|
                return Search();
 | 
						|
            }
 | 
						|
            else if (!String.IsNullOrWhiteSpace(person)) {
 | 
						|
                State = IndexState.PersonLookup;
 | 
						|
                return PersonLookup();
 | 
						|
            }
 | 
						|
            else if (!String.IsNullOrWhiteSpace(havolume) ||
 | 
						|
                     !String.IsNullOrWhiteSpace(hapage)) {
 | 
						|
                State = IndexState.ZHLookup;
 | 
						|
                return ZHLookup();
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                State = IndexState.Initial;
 | 
						|
                return Default();
 | 
						|
            }
 | 
						|
        }
 | 
						|
        
 | 
						|
        internal ActionResult Search() {
 | 
						|
            var ret = new ConcurrentBag<DocumentSearchResult>();
 | 
						|
            var searchin = _lib.MetasByDate.Select(x => new DocumentSearchResult(x)).ToImmutableSortedSet(new LetterComparer());
 | 
						|
            var cnt = 0; //TODO: Nicht in threads manipulieren
 | 
						|
            Parallel.ForEach (searchin, (letter, state) => {
 | 
						|
                if (cnt > 1000) {
 | 
						|
                    FailState = IndexFailState.SearchTooManyResults;
 | 
						|
                    state.Break();
 | 
						|
                }
 | 
						|
                var x = new DocumentSearch(letter, _readerService.RequestStringReader(_lib.Letters[letter.MetaData.Index].Element), search);
 | 
						|
                cnt = cnt + x.Act().Results.Count;
 | 
						|
                if (x._searchResult.Results.Count > 0 ) ret.Add(x._searchResult);
 | 
						|
            });
 | 
						|
            if (ret.Count() == 0) {
 | 
						|
                FailState = IndexFailState.SearchNoResult;
 | 
						|
            }
 | 
						|
            return Execute(ret);
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult ZHLookup() {
 | 
						|
            var ret = ImmutableSortedSet.CreateBuilder(new LetterComparer());
 | 
						|
            ImmutableDictionary<string, ImmutableDictionary<string, string>> pagedic;
 | 
						|
            var selvolume = _lib.Structure.TryGetValue(havolume.Trim(), out pagedic);
 | 
						|
            if (selvolume) {
 | 
						|
                ImmutableDictionary<string, string> linedic;
 | 
						|
                var selpage = pagedic.TryGetValue(hapage.Trim(), out linedic); 
 | 
						|
                if (selpage) {
 | 
						|
                    foreach (var entry in linedic) {
 | 
						|
                        ret.Add(_lib.MetasByDate.Where(x => x.Index == entry.Value).Select(x => new DocumentSearchResult(x)).First());
 | 
						|
                    }
 | 
						|
                    if (ret.Count == 1) {
 | 
						|
                        return Redirect("/Briefe/" + ret.First().MetaData.Autopsic + "#" + hapage + "-1");
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    FailState = IndexFailState.ZHNotFound;
 | 
						|
                    return Execute(ret);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                return FatalError();
 | 
						|
            }
 | 
						|
            return Execute(ret);
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult PersonLookup() {
 | 
						|
            return Execute(_lib.MetasByDate
 | 
						|
                .Where(x => x.Senders.Contains(person) || x.Receivers.Contains(person))
 | 
						|
                .Select(x => new DocumentSearchResult(x)));
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult Default() {
 | 
						|
            return Execute(_lib.MetasByDate
 | 
						|
                .Select(x => new DocumentSearchResult(x)));
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult Execute(IEnumerable<DocumentSearchResult> _result) {
 | 
						|
            if (_result == null) FatalError();
 | 
						|
            var res = _result.OrderBy(x => x, new LetterComparer()).ToLookup(x => x.MetaData.Sort.Year, x => x);
 | 
						|
            return Paginate(res);
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult Paginate(ILookup<int, DocumentSearchResult> _result) {
 | 
						|
            if (_result == null) return Return();
 | 
						|
            var curr = new List<IGrouping<int, DocumentSearchResult>>();
 | 
						|
            Result = new List<List<IGrouping<int, DocumentSearchResult>>>();
 | 
						|
            foreach (var elem in _result) {
 | 
						|
                curr.Add(elem);
 | 
						|
                if (curr.SelectMany(x => x).Count() > MINLETTPG || elem == _result.Last()) {
 | 
						|
                    Result.Add(new List<IGrouping<int, DocumentSearchResult>>(curr));
 | 
						|
                    curr.Clear();
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (!String.IsNullOrWhiteSpace(selpage)) {
 | 
						|
                int no;
 | 
						|
                var isNo = Int32.TryParse(selpage, out no);
 | 
						|
                if (!isNo ||
 | 
						|
                    Result.Count < no || 
 | 
						|
                    no <= 0) {
 | 
						|
                    return FatalError();
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    cleanpage = no - 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                selpage = "1";
 | 
						|
            }
 | 
						|
            return Return();
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult FatalError() {
 | 
						|
            Response.StatusCode = 404;
 | 
						|
            return RedirectToPage("/Error");
 | 
						|
        }
 | 
						|
 | 
						|
        internal ActionResult Return() {
 | 
						|
            return Page();
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |