224 lines
9.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using gehGassi.Core.Services;
using gehGassi.Domain.Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace gehGassi.Web.Services
{
/// <summary>
/// Service der den Umgang mit Ländern vereinfacht
/// </summary>
public class CountryService : ICountryService
{
private readonly IDistributedCache _memoryCache;
private readonly IOptions<CountryServiceOptions> _options;
private readonly IWebHostEnvironment _hostingEnvironment;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="memoryCache">Instanz eines IDistributedCache</param>
/// <param name="options">Instanz von CountryServiceOptions</param>
/// <param name="hostingEnvironment">Instanz eines IHostingEnvironment</param>
public CountryService(IDistributedCache memoryCache, IOptions<CountryServiceOptions> options, IWebHostEnvironment hostingEnvironment)
{
_memoryCache = memoryCache;
_options = options;
_hostingEnvironment = hostingEnvironment;
Init();
}
/// <summary>
/// Initialisiert den Service
/// </summary>
private void Init()
{
var path = Path.Combine(_hostingEnvironment.WebRootPath, _options.Value.Directory);
foreach (var language in _options.Value.Languages)
{
var countryFile = Path.Combine(path + "\\" + language + "\\world.json");
if (File.Exists(countryFile))
{
var json = File.ReadAllText(countryFile);
var countries = JsonConvert.DeserializeObject<List<Country>>(json);
var options = new DistributedCacheEntryOptions();
options.SetSlidingExpiration(TimeSpan.FromMinutes(15));
var jsonString = JsonSerializer.Serialize(countries);
_memoryCache.SetString("Countries_" + language.ToUpper(), jsonString, options);
}
}
//Bundesländer laden
var subdivisionFile = Path.Combine(path + "\\subdivisions.json");
if (File.Exists(subdivisionFile))
{
var json = File.ReadAllText(subdivisionFile);
var subdivisions = JsonConvert.DeserializeObject<List<State>>(json);
var options = new DistributedCacheEntryOptions();
options.SetSlidingExpiration(TimeSpan.FromMinutes(15));
var jsonString = JsonSerializer.Serialize(subdivisions);
_memoryCache.SetString("States", jsonString, options);
}
}
/// <summary>
/// Gibt eine Liste aller Länder zurück
/// </summary>
/// <returns>Liste</returns>
public List<Country> GetCountries()
{
var dummy = _memoryCache.GetString("Countries_EN");
if (string.IsNullOrWhiteSpace(dummy))
Init();
var countriesJson = _memoryCache.GetString("Countries_" + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToUpper());
if (string.IsNullOrWhiteSpace(countriesJson))
countriesJson = _memoryCache.GetString("Countries_EN");
var countries = JsonSerializer.Deserialize<List<Country>>(countriesJson);
countries.ForEach(c => c.Iso2 = c.Iso2.ToUpper());
return (countries ?? throw new InvalidOperationException()).OrderBy(c => c.Name).ToList();
}
/// <summary>
/// Gibt ein Land anhand des Codes zurück
/// </summary>
/// <param name="countryCode">ISO2</param>
/// <returns>Land oder null, wenn nicht gefunden</returns>
public Country GetCountry(string countryCode)
{
var country = GetCountries().FirstOrDefault(c => String.Equals(c.Iso2, countryCode, StringComparison.CurrentCultureIgnoreCase));
return country;
}
/// <summary>
/// Gibt eine Liste von Bundesländern zurück
/// </summary>
/// <returns>Liste von Bundesländern</returns>
public List<State> GetStates()
{
var statesJson = _memoryCache.GetString("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
Init();
statesJson = _memoryCache.GetString("States");
}
var states = JsonSerializer.Deserialize<List<State>>(statesJson);
return states;
}
/// <summary>
/// Gibt eine Liste von Bundesländern / Staaten eines Landes zurück
/// </summary>
/// <param name="countryCode">ISO2 des Landes</param>
/// <returns>Liste von Bundesländern</returns>
public List<State> GetStates(string countryCode)
{
if (string.IsNullOrWhiteSpace(countryCode))
countryCode = "";
var statesJson = _memoryCache.GetString("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
Init();
statesJson = _memoryCache.GetString("States");
}
var states = JsonSerializer.Deserialize<List<State>>(statesJson);
return states != null ? states.Where(c => c.Iso2 == countryCode.ToUpper()).OrderBy(c => c.Name).ToList() : new List<State>();
}
/// <summary>
/// Gibt ein Bundesland / Staat eines Landes zurück
/// </summary>
/// <param name="countryCode">ISO2 des Landes</param>
/// <param name="stateCode">Code des Bundeslandes</param>
/// <returns>Bundesland oder null, wenn nicht gefunden</returns>
public State GetState(string countryCode, string stateCode)
{
var states = GetStates(countryCode);
return states.FirstOrDefault(c => c.Code == stateCode);
}
/// <summary>
/// Gibt eine Liste der Ländercodes zurück die zu einem Filter passen
/// </summary>
/// <param name="filter">Filter</param>
/// <param name="operatorValue">Operator der angewendet werden soll</param>
/// <returns>Liste gefundener Ländercodes</returns>
public List<string> FindCountryCodes(string filter, string operatorValue)
{
var countries = GetCountries();
if(operatorValue == "equals")
return (from country in countries where country.Name.ToLower().Equals(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "notequals")
return (from country in countries where country.Name.ToLower().Equals(filter.ToLower()) == false select country.Iso2).ToList();
if (operatorValue == "startswith")
return (from country in countries where country.Name.ToLower().StartsWith(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "endswith")
return (from country in countries where country.Name.ToLower().EndsWith(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "contains")
return (from country in countries where country.Name.ToLower().Contains(filter.ToLower()) select country.Iso2).ToList();
return new List<string>();
}
/// <summary>
/// Gibt eine Liste der Bundesland-Codes zurück die zu einem Filter passen
/// </summary>
/// <param name="filter">Filter</param>
/// <param name="operatorValue">Operator der angewendet werden soll</param>
/// <returns>Liste gefundener Bundeslandcodes</returns>
public List<string> FindStateCodes(string filter, string operatorValue)
{
var states = GetStates();
if (operatorValue == "equals")
return (from state in states where state.Name.ToLower().Equals(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "notequals")
return (from state in states where state.Name.ToLower().Equals(filter.ToLower()) == false select state.Code).ToList();
if (operatorValue == "startswith")
return (from state in states where state.Name.ToLower().StartsWith(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "endswith")
return (from state in states where state.Name.ToLower().EndsWith(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "contains")
return (from state in states where state.Name.ToLower().Contains(filter.ToLower()) select state.Code).ToList();
return new List<string>();
}
}
/// <summary>
/// Einstellungen für den Country-Service
/// </summary>
public class CountryServiceOptions
{
/// <summary>
/// ERstellt eine Instanz
/// </summary>
public CountryServiceOptions()
{
}
/// <summary>
/// Verfügbare Sprachen
/// </summary>
public List<string> Languages { get; set; }
/// <summary>
/// Basis-Directory in welchem die Sprachdateien für die Länderauswahl zu finden sind
/// </summary>
public string Directory { get; set; }
}
}