Initial commit

This commit is contained in:
2022-07-06 21:35:05 +02:00
commit b2494052ff
97220 changed files with 2449256 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
using System;
namespace Gos.Core
{
public static class Cache
{
public static class Duration
{
public static TimeSpan Long = TimeSpan.FromDays(7);
}
public static class CacheKeys
{
public static class Msd
{
private const string Prefix = nameof(Msd);
public static string All()
{
return $"{Prefix}_{nameof(All)}";
}
public static string ByCode(string code)
{
return $"{Prefix}_{nameof(ByCode)}_{code}";
}
}
public static class PartOfSpeech
{
private const string Prefix = nameof(PartOfSpeech);
public static string ByCode(string code)
{
return $"{Prefix}_{nameof(ByCode)}_{code}";
}
}
}
}
}
+24
View File
@@ -0,0 +1,24 @@
namespace Gos.Core
{
public static class ConfigurationKey
{
private const string Prefix = "GOS";
public static string SoundFilesFolder => $"{Prefix}:{nameof(SoundFilesFolder)}";
public static class Database
{
public static string ConnectionString => $"{Prefix}:{nameof(Database)}:{nameof(ConnectionString)}";
}
public static class Elastic
{
public static string ConnectionString => $"{Prefix}:{nameof(Elastic)}:{nameof(ConnectionString)}";
}
public static class Logging
{
public static string LogPath => $"{Prefix}:{nameof(Logging)}:{nameof(LogPath)}";
}
}
}
+39
View File
@@ -0,0 +1,39 @@
using System.Xml.Linq;
namespace Gos.Core
{
public static class Constants
{
public const string TeiNamespace = "http://www.tei-c.org/ns/1.0";
public const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";
public const string IncludeNamespace = "http://www.w3.org/2001/XInclude";
public static readonly XNamespace TeiNs;
public static readonly XNamespace XmlNs;
public static readonly XNamespace IncludeNs;
static Constants()
{
TeiNs = XNamespace.Get(TeiNamespace);
XmlNs = XNamespace.Get(XmlNamespace);
IncludeNs = XNamespace.Get(IncludeNamespace);
}
public static class InterfaceLanguages
{
public static string English = "en";
public static string EnglishName = "English";
public static string Slovene = "sl";
public static string SloveneName = "Slovenščina";
}
public static class Formats
{
public static string CountsFormat = "#,##0";
}
public static class Search
{
public static int DefaultPageSize = 20;
}
}
}
+21
View File
@@ -0,0 +1,21 @@
using System;
namespace Gos.Core.Entities
{
public class AuditLog : BaseEntity
{
public long DurationMs { get; set; }
public DateTime EndDate { get; set; }
public string Message { get; set; }
public string ObjectType { get; set; }
public string SessionId { get; set; }
public DateTime StartDate { get; set; }
public string TraceIdentifier { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public abstract class BaseEntity : IEntity
{
public int Id { get; set; }
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace Gos.Core.Entities
{
public class CorpusCounter : BaseEntity
{
public int Discourses { get; set; }
public int Statements { get; set; }
public int Words { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Gos.Core.Entities
{
public class CorpusForm : BaseEntity
{
public string StandardForm { get; set; }
public string Lemma { get; set; }
}
}
+29
View File
@@ -0,0 +1,29 @@
using System;
namespace Gos.Core.Entities
{
public class Discourse : BaseEntity
{
public DiscourseChannel Channel { get; set; }
public string Code { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public DiscourseEvent Event { get; set; }
public int Length { get; set; }
public string Location { get; set; }
public int NumberOfSpeakers { get; set; }
public DiscourseRegion Region { get; set; }
public string Source { get; set; }
public DiscourseType Type { get; set; }
}
}
+23
View File
@@ -0,0 +1,23 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class DiscourseChannel : BaseEntity, ILocalizableEntity<DiscourseChannelTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<DiscourseChannelTranslation> Translations { get; set; } = new();
}
public enum DiscourseChannelKeys
{
Radio = 1,
Televizija = 2,
OsebniStik = 3,
Telefon = 4,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class DiscourseChannelTranslation : Translation<DiscourseChannelTranslation>
{
public string Title { get; set; }
}
}
+42
View File
@@ -0,0 +1,42 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class DiscourseEvent : BaseEntity, ILocalizableEntity<DiscourseEventTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<DiscourseEventTranslation> Translations { get; set; } = new();
}
public enum DiscourseEventKeys
{
NovinarskiPrispevek = 1,
ModeriraniPogovorTv = 2,
ModeriranaOddaja = 3,
ResnicnostniSov = 4,
SportniPrenos = 5,
ModeriraniProgram = 6,
ModeriraniPogovorRadio = 7,
OsnovnosolskaUcnaUra = 8,
SrednjesolskaUcnaUra = 9,
Tecaj = 10,
FakultetnoPredavanje = 11,
JavnoPredavanje = 12,
FormalniDelovniSestanek = 13,
NeformalniDelovniSestanek = 14,
Konzultacija = 15,
Storitev = 16,
FormalniRazgovor = 17,
ProdajaTrgovina = 18,
Svetovanje = 19,
Informacije = 20,
Tajnistvo = 21,
PogovorVDruzini = 22,
PogovorMedPrijateljiZnanci = 23,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class DiscourseEventTranslation : Translation<DiscourseEventTranslation>
{
public string Title { get; set; }
}
}
+43
View File
@@ -0,0 +1,43 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class DiscourseRegion : BaseEntity, ILocalizableEntity<DiscourseRegionTranslation>
{
public string ShortTitle
{
get => Translations[CultureInfo.CurrentCulture].ShortTitle;
set => Translations[CultureInfo.CurrentCulture].ShortTitle = value;
}
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<DiscourseRegionTranslation> Translations { get; set; } = new();
}
public enum DiscourseRegionKeys
{
Celjska = 1,
Novogoriska = 2,
Krska = 3,
Koprska = 4,
Kranjska = 5,
Ljubljanska = 6,
Mariborska = 7,
Murskosoboska = 8,
Novomeska = 9,
Postojnska = 10,
Slovenjgraska = 11,
CelotnaSlovenija = 12,
SeverovzhodnaSlovenija = 13,
JugozahodnaSlovenija = 14,
Avstrija = 15,
Italija = 16,
Madzarska = 17,
Neznano = 18,
}
}
@@ -0,0 +1,9 @@
namespace Gos.Core.Entities
{
public class DiscourseRegionTranslation : Translation<DiscourseRegionTranslation>
{
public string ShortTitle { get; set; }
public string Title { get; set; }
}
}
+29
View File
@@ -0,0 +1,29 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class DiscourseType : BaseEntity, ILocalizableEntity<DiscourseTypeTranslation>
{
public string ShortTitle
{
get => Translations[CultureInfo.CurrentCulture].ShortTitle;
set => Translations[CultureInfo.CurrentCulture].ShortTitle = value;
}
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<DiscourseTypeTranslation> Translations { get; set; } = new();
}
public enum DiscourseTypeKeys
{
JavniInformativnoIzobrazevalni = 1,
JavniRazvedrilni = 2,
NejavniNezasebni = 3,
NejavniZasebni = 4,
}
}
@@ -0,0 +1,9 @@
namespace Gos.Core.Entities
{
public class DiscourseTypeTranslation : Translation<DiscourseTypeTranslation>
{
public string ShortTitle { get; set; }
public string Title { get; set; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public interface IEntity
{
int Id { get; set; }
}
}
@@ -0,0 +1,8 @@
namespace Gos.Core.Entities
{
public interface ILocalizableEntity<TTranslation>
where TTranslation : Translation<TTranslation>, new()
{
TranslationCollection<TTranslation> Translations { get; set; }
}
}
+17
View File
@@ -0,0 +1,17 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class Msd : BaseEntity, ILocalizableEntity<MsdTranslation>
{
public string Code { get; set; }
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<MsdTranslation> Translations { get; set; } = new();
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class MsdTranslation : Translation<MsdTranslation>
{
public string Title { get; set; }
}
}
+22
View File
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Globalization;
namespace Gos.Core.Entities
{
public class PartOfSpeech : BaseEntity, ILocalizableEntity<PartOfSpeechTranslation>
{
public List<PartOfSpeechAttribute> Attributes { get; set; } = new();
public string Code { get; set; }
public short RecordOrder { get; set; }
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<PartOfSpeechTranslation> Translations { get; set; } = new();
}
}
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Globalization;
namespace Gos.Core.Entities
{
public class PartOfSpeechAttribute : BaseEntity, ILocalizableEntity<PartOfSpeechAttributeTranslation>
{
public short RecordOrder { get; set; }
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<PartOfSpeechAttributeTranslation> Translations { get; set; } = new();
public List<PartOfSpeechAttributeValue> Values { get; set; } = new();
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class PartOfSpeechAttributeTranslation : Translation<PartOfSpeechAttributeTranslation>
{
public string Title { get; set; }
}
}
@@ -0,0 +1,19 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class PartOfSpeechAttributeValue : BaseEntity, ILocalizableEntity<PartOfSpeechAttributeValueTranslation>
{
public string Code { get; set; }
public short RecordOrder { get; set; }
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<PartOfSpeechAttributeValueTranslation> Translations { get; set; } = new();
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class PartOfSpeechAttributeValueTranslation : Translation<PartOfSpeechAttributeValueTranslation>
{
public string Title { get; set; }
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class PartOfSpeechTranslation : Translation<PartOfSpeechTranslation>
{
public string Title { get; set; }
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace Gos.Core.Entities
{
public class Segment : BaseEntity
{
public int Order { get; set; }
public string SoundFile { get; set; }
public Statement Statement { get; set; }
}
}
+21
View File
@@ -0,0 +1,21 @@
namespace Gos.Core.Entities
{
public class Speaker : BaseEntity
{
public SpeakerAge Age { get; set; }
public string Code { get; set; }
public SpeakerEducation Education { get; set; }
public SpeakerLanguage Language { get; set; }
public SpeakerRegion Region1 { get; set; }
public SpeakerRegion Region2 { get; set; }
public SpeakerRegion Region3 { get; set; }
public SpeakerSex Sex { get; set; }
}
}
+27
View File
@@ -0,0 +1,27 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class SpeakerAge : BaseEntity, ILocalizableEntity<SpeakerAgeTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<SpeakerAgeTranslation> Translations { get; set; } = new();
}
public enum SpeakerAgeKeys
{
Do10Let = 1,
Od10Do14Let = 2,
Od15Do18Let = 3,
Od19Do24Let = 4,
Od25Do34Let = 5,
Od35Do59Let = 6,
Nad60Let = 7,
Neznano = 8,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class SpeakerAgeTranslation : Translation<SpeakerAgeTranslation>
{
public string Title { get; set; }
}
}
+24
View File
@@ -0,0 +1,24 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class SpeakerEducation : BaseEntity, ILocalizableEntity<SpeakerEducationTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<SpeakerEducationTranslation> Translations { get; set; } = new();
}
public enum SpeakerEducationKeys
{
OsAliManj = 1,
SrednjaSola = 2,
VisjaAliVisokaSola = 3,
FakultetaAliVec = 4,
Neznano = 5,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class SpeakerEducationTranslation : Translation<SpeakerEducationTranslation>
{
public string Title { get; set; }
}
}
+31
View File
@@ -0,0 +1,31 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class SpeakerLanguage : BaseEntity, ILocalizableEntity<SpeakerLanguageTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<SpeakerLanguageTranslation> Translations { get; set; } = new();
}
public enum SpeakerLanguageKeys
{
Slovenscina = 1,
Anglescina = 2,
Nemscina = 3,
Italijanscina = 4,
Madzarscina = 5,
Juznoslovanski = 6,
Albanscina = 7,
DrugiSlovanski = 8,
DrugiGermanski = 9,
DrugiRomanski = 10,
Neindoevropski = 11,
Neznano = 12,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class SpeakerLanguageTranslation : Translation<SpeakerLanguageTranslation>
{
public string Title { get; set; }
}
}
+41
View File
@@ -0,0 +1,41 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class SpeakerRegion : BaseEntity, ILocalizableEntity<SpeakerRegionTranslation>
{
public string ShortTitle
{
get => Translations[CultureInfo.CurrentCulture].ShortTitle;
set => Translations[CultureInfo.CurrentCulture].ShortTitle = value;
}
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<SpeakerRegionTranslation> Translations { get; set; } = new();
}
public enum SpeakerRegionKeys
{
Celjska = 1,
Novogoriska = 2,
Krska = 3,
Koprska = 4,
Kranjska = 5,
Ljubljanska = 6,
Mariborska = 7,
Murskosoboska = 8,
Novomeska = 9,
Postojnska = 10,
Slovenjgraska = 11,
Avstrija = 12,
Italija = 13,
Madzarska = 14,
Tujina = 15,
Neznano = 16,
}
}
@@ -0,0 +1,9 @@
namespace Gos.Core.Entities
{
public class SpeakerRegionTranslation : Translation<SpeakerRegionTranslation>
{
public string ShortTitle { get; set; }
public string Title { get; set; }
}
}
+22
View File
@@ -0,0 +1,22 @@
using System.Globalization;
namespace Gos.Core.Entities
{
public class SpeakerSex : BaseEntity, ILocalizableEntity<SpeakerSexTranslation>
{
public string Title
{
get => Translations[CultureInfo.CurrentCulture].Title;
set => Translations[CultureInfo.CurrentCulture].Title = value;
}
public TranslationCollection<SpeakerSexTranslation> Translations { get; set; } = new();
}
public enum SpeakerSexKeys
{
Moski = 1,
Zenski = 2,
Neznano = 3,
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Entities
{
public class SpeakerSexTranslation : Translation<SpeakerSexTranslation>
{
public string Title { get; set; }
}
}
+13
View File
@@ -0,0 +1,13 @@
namespace Gos.Core.Entities
{
public class Statement : BaseEntity
{
public string Code { get; set; }
public Discourse Discourse { get; set; }
public int Order { get; set; }
public Speaker Speaker { get; set; }
}
}
+32
View File
@@ -0,0 +1,32 @@
using Gos.Core.Model;
namespace Gos.Core.Entities
{
public class Token : BaseEntity
{
public string ConversationalForm { get; set; }
public int DiscourseOrder { get; set; }
public string Lemma { get; set; }
public string Msd { get; set; }
public int Order { get; set; }
public Segment Segment { get; set; }
public string StandardForm { get; set; }
public TokenType Type { get; set; }
public Token()
{
}
public Token(TokenType type)
{
Type = type;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace Gos.Core.Entities
{
public abstract class Translation<T>
where T : Translation<T>, new()
{
public string CultureName { get; set; }
public int Id { get; set; }
}
}
@@ -0,0 +1,41 @@
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
namespace Gos.Core.Entities
{
public class TranslationCollection<T> : Collection<T>
where T : Translation<T>, new()
{
public T this[CultureInfo culture]
{
get
{
var translation = this.FirstOrDefault(t => t.CultureName == culture.Name);
if (translation == null)
{
translation = new T();
translation.CultureName = culture.Name;
Add(translation);
}
return translation;
}
set
{
var translation = this.FirstOrDefault(t => t.CultureName == culture.Name);
if (translation != null)
{
Remove(translation);
}
Add(value);
}
}
public bool HasCulture(CultureInfo culture)
{
return this.Any(t => t.CultureName == culture.Name);
}
}
}
@@ -0,0 +1,58 @@
using System;
namespace Gos.Core.Extensions
{
public static class ArrayExtensions
{
public static void ForEach(this Array array, Action<Array, int[]> action)
{
if (array.LongLength == 0)
{
return;
}
var walker = new ArrayTraverse(array);
do
{
action(array, walker.Position);
}
while (walker.Step());
}
}
internal class ArrayTraverse
{
public int[] Position;
private readonly int[] maxLengths;
public ArrayTraverse(Array array)
{
maxLengths = new int[array.Rank];
for (var i = 0; i < array.Rank; ++i)
{
maxLengths[i] = array.GetLength(i) - 1;
}
Position = new int[array.Rank];
}
public bool Step()
{
for (var i = 0; i < Position.Length; ++i)
{
if (Position[i] < maxLengths[i])
{
Position[i]++;
for (var j = 0; j < i; j++)
{
Position[j] = 0;
}
return true;
}
}
return false;
}
}
}
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gos.Core.Entities;
using Gos.Core.Model;
using Gos.ServiceModel.Requests.Concordance;
namespace Gos.Core.Extensions
{
public static class ConcordanceExtensions
{
public static void SetToken(this Concordance concordance, Token token, int position)
{
switch (position)
{
case -10:
concordance.TokenLeft10 = token;
break;
case -9:
concordance.TokenLeft9 = token;
break;
case -8:
concordance.TokenLeft8 = token;
break;
case -7:
concordance.TokenLeft7 = token;
break;
case -6:
concordance.TokenLeft6 = token;
break;
case -5:
concordance.TokenLeft5 = token;
break;
case -4:
concordance.TokenLeft4 = token;
break;
case -3:
concordance.TokenLeft3 = token;
break;
case -2:
concordance.TokenLeft2 = token;
break;
case -1:
concordance.TokenLeft1 = token;
break;
case 0:
concordance.Token = token;
break;
case 1:
concordance.TokenRight1 = token;
break;
case 2:
concordance.TokenRight2 = token;
break;
case 3:
concordance.TokenRight3 = token;
break;
case 4:
concordance.TokenRight4 = token;
break;
case 5:
concordance.TokenRight5 = token;
break;
case 6:
concordance.TokenRight6 = token;
break;
case 7:
concordance.TokenRight7 = token;
break;
case 8:
concordance.TokenRight8 = token;
break;
case 9:
concordance.TokenRight9 = token;
break;
case 10:
concordance.TokenRight10 = token;
break;
default:
throw new Exception($"Invalid position {position}. Position should be between -10 and 10");
}
}
private static string ToForm(IEnumerable<ConcordanceToken> tokens, Func<ConcordanceToken, string> formFunc)
{
if (tokens == null)
{
return null;
}
var sb = new StringBuilder();
foreach (var token in tokens)
{
var form = formFunc(token);
if (string.IsNullOrEmpty(form))
{
continue;
}
if (sb.Length > 0)
{
sb.Append(' ');
}
sb.Append(form);
}
return sb.ToString();
}
public static string ToConversationalFormText(this IEnumerable<ConcordanceToken> tokens)
{
return ToForm(tokens, token => token.ConversationalForm);
}
public static string ToStandardFormText(this IEnumerable<ConcordanceToken> tokens)
{
return ToForm(tokens, token => token.StandardForm);
}
}
}
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Linq;
namespace Gos.Core.Extensions
{
public static class EnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[]
{
Enumerable.Empty<T>()
};
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) => from accseq in accumulator
from item in sequence
select accseq.Concat(
new[]
{
item
}));
}
public static bool IsNullOrEmpty<TSource>(this IEnumerable<TSource> collection)
{
return collection == null || !collection.Any();
}
}
}
+138
View File
@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Gos.Core.Extensions
{
/// <summary>
/// https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net-c-specifically
/// https://github.com/Burtsev-Alexey/net-object-deep-copy/blob/master/ObjectExtensions.cs
/// </summary>
public static class ObjectExtensions
{
private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance);
public static object Copy(this object originalObject)
{
return InternalCopy(originalObject, new Dictionary<object, object>(new ReferenceEqualityComparer()));
}
public static T Copy<T>(this T original)
{
return (T)Copy((object)original);
}
public static bool IsPrimitive(this Type type)
{
if (type == typeof(string))
{
return true;
}
return type.IsValueType & type.IsPrimitive;
}
private static void CopyFields(
object originalObject,
IDictionary<object, object> visited,
object cloneObject,
Type typeToReflect,
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy,
Func<FieldInfo, bool> filter = null)
{
foreach (var fieldInfo in typeToReflect.GetFields(bindingFlags))
{
if (filter != null && filter(fieldInfo) == false)
{
continue;
}
if (IsPrimitive(fieldInfo.FieldType))
{
continue;
}
var originalFieldValue = fieldInfo.GetValue(originalObject);
var clonedFieldValue = InternalCopy(originalFieldValue, visited);
fieldInfo.SetValue(cloneObject, clonedFieldValue);
}
}
private static object InternalCopy(object originalObject, IDictionary<object, object> visited)
{
if (originalObject == null)
{
return null;
}
var typeToReflect = originalObject.GetType();
if (IsPrimitive(typeToReflect))
{
return originalObject;
}
if (visited.ContainsKey(originalObject))
{
return visited[originalObject];
}
if (typeof(Delegate).IsAssignableFrom(typeToReflect))
{
return null;
}
var cloneObject = CloneMethod.Invoke(originalObject, null);
if (typeToReflect.IsArray)
{
var arrayType = typeToReflect.GetElementType();
if (IsPrimitive(arrayType) == false)
{
var clonedArray = (Array)cloneObject;
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
}
}
visited.Add(originalObject, cloneObject);
CopyFields(originalObject, visited, cloneObject, typeToReflect);
RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect);
return cloneObject;
}
private static void RecursiveCopyBaseTypePrivateFields(
object originalObject,
IDictionary<object, object> visited,
object cloneObject,
Type typeToReflect)
{
if (typeToReflect.BaseType != null)
{
RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
CopyFields(
originalObject,
visited,
cloneObject,
typeToReflect.BaseType,
BindingFlags.Instance | BindingFlags.NonPublic,
info => info.IsPrivate);
}
}
}
public class ReferenceEqualityComparer : EqualityComparer<object>
{
public override bool Equals(object x, object y)
{
return ReferenceEquals(x, y);
}
public override int GetHashCode(object obj)
{
if (obj == null)
{
return 0;
}
return obj.GetHashCode();
}
}
}
@@ -0,0 +1,32 @@
using Gos.Core.Search.Queries;
using Gos.ServiceModel.Interfaces;
namespace Gos.Core.Extensions
{
public static class QueryExtensions
{
public static TQuery WithFilters<TQuery>(this TQuery query, ServiceModel.Requests.Search request)
where TQuery : Query
{
query.DiscourseTypeIds = request.DiscourseTypeIds;
query.DiscourseChannelIds = request.DiscourseChannelIds;
query.DiscourseEventIds = request.DiscourseEventIds;
query.DiscourseRegionIds = request.DiscourseRegionIds;
query.DiscourseYears = request.DiscourseYears;
query.SpeakerAgeIds = request.SpeakerAgeIds;
query.SpeakerEducationIds = request.SpeakerEducationIds;
query.SpeakerLanguageIds = request.SpeakerLanguageIds;
query.SpeakerRegionIds = request.SpeakerRegionIds;
query.SpeakerSexIds = request.SpeakerSexIds;
return query;
}
public static TQuery WithPageInfo<TQuery>(this TQuery query, IPagedSearch request)
where TQuery : Query
{
query.From = request.From;
query.Size = request.Size;
return query;
}
}
}
@@ -0,0 +1,30 @@
using System.Linq;
using System.Linq.Expressions;
namespace Gos.Core.Extensions
{
public static class QueryableExtensions
{
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string orderByProperty, bool desc)
{
// https://stackoverflow.com/a/7265354
var command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(
typeof(Queryable),
command,
new[]
{
type,
property.PropertyType
},
source.Expression,
Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<TEntity>(resultExpression);
}
}
}
@@ -0,0 +1,43 @@
using Gos.Core.Entities;
using Gos.Core.Model;
namespace Gos.Core.Extensions
{
public static class TokenExtensions
{
public static Token WithConversationForm(this Token token, string conversationalForm)
{
token.ConversationalForm = conversationalForm?.Trim();
return token;
}
public static Token WithLemma(this Token token, string lemma)
{
token.Lemma = lemma?.Trim();
return token;
}
public static Token WithMsd(this Token token, string msd)
{
if (!string.IsNullOrEmpty(msd) && msd.ToLower().StartsWith("mte:"))
{
msd = msd[4..];
}
token.Msd = msd;
return token;
}
public static Token WithStandardForm(this Token token, string standardForm)
{
token.StandardForm = standardForm?.Trim();
return token;
}
public static Token WithType(this Token token, TokenType type)
{
token.Type = type;
return token;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Gos.ServiceModel\Gos.ServiceModel.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,7 @@
namespace Gos.Core.Interfaces
{
public interface ISessionIdResolver
{
string Resolve();
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Interfaces
{
public interface ITraceIdentifierResolver
{
string Resolve();
}
}
+51
View File
@@ -0,0 +1,51 @@
using Gos.Core.Entities;
namespace Gos.Core.Model
{
public class Concordance
{
public Statement Statement { get; set; }
public Token Token { get; set; }
public Token TokenLeft1 { get; set; }
public Token TokenLeft10 { get; set; }
public Token TokenLeft2 { get; set; }
public Token TokenLeft3 { get; set; }
public Token TokenLeft4 { get; set; }
public Token TokenLeft5 { get; set; }
public Token TokenLeft6 { get; set; }
public Token TokenLeft7 { get; set; }
public Token TokenLeft8 { get; set; }
public Token TokenLeft9 { get; set; }
public Token TokenRight1 { get; set; }
public Token TokenRight10 { get; set; }
public Token TokenRight2 { get; set; }
public Token TokenRight3 { get; set; }
public Token TokenRight4 { get; set; }
public Token TokenRight5 { get; set; }
public Token TokenRight6 { get; set; }
public Token TokenRight7 { get; set; }
public Token TokenRight8 { get; set; }
public Token TokenRight9 { get; set; }
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Gos.Core.Model
{
public enum TokenType
{
Word,
Character,
}
}
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using Gos.Core.Search.Queries;
namespace Gos.Core.Search.Aggregations
{
public interface IAggregator
{
IDictionary<string, int> Get<TQuery>(TQuery query)
where TQuery : Query;
}
}
@@ -0,0 +1,9 @@
using Gos.ServiceModel.Enums;
namespace Gos.Core.Search.Aggregations
{
public interface IAggregatorFactory
{
IAggregator GetAggregator(AggregationType aggregationType);
}
}
+22
View File
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Gos.Core.Search.Queries;
namespace Gos.Core.Search
{
public interface ISearchEngine
{
Task Commit();
Task CreateSchema();
Task DeleteSchema();
Task Index<TEntity>(IEnumerable<TEntity> entities)
where TEntity : class;
TResult Search<TQuery, TResult>(TQuery query)
where TQuery : Query
where TResult : QueryResult;
}
}
@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQuery : Query
{
public ConcordanceQueryMainWord MainWord { get; set; }
public bool ReturnRandomRows { get; set; }
public List<ConcordanceQueryWordInContext> WordsInContext { get; set; }
}
}
@@ -0,0 +1,6 @@
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQueryMainWord : ConcordanceQueryWord
{
}
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQueryResult : QueryResult
{
public List<ConcordanceQueryResultItem> Items { get; set; }
}
}
@@ -0,0 +1,11 @@
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQueryResultItem
{
public int DiscourseId { get; set; }
public int StatementOrder { get; set; }
public int TokenOrder { get; set; }
}
}
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using Gos.ServiceModel.Enums;
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQueryWord
{
public string ConversationalForm { get; set; }
public List<string> Lemmas { get; set; }
public List<string> Msds { get; set; }
public ConditionType PartOfSpeechCondition { get; set; }
public int? PartOfSpeechId { get; set; }
public string StandardForm { get; set; }
}
}
@@ -0,0 +1,15 @@
using Gos.ServiceModel.Enums;
namespace Gos.Core.Search.Queries.Concordance
{
public class ConcordanceQueryWordInContext : ConcordanceQueryWord
{
public ConditionType Condition { get; set; }
public DistanceType DistanceType { get; set; }
public int LeftPosition { get; set; }
public int RightPosition { get; set; }
}
}
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using Gos.ServiceModel.Enums;
namespace Gos.Core.Search.Queries.List
{
public class ListQuery : Query
{
public ConditionType Condition { get; set; }
public string ConversationalForm { get; set; }
public string Query { get; set; }
public bool GroupByMsd { get; set; }
public List<string> Lemmas { get; set; }
public List<string> Msds { get; set; }
public List<int> PartOfSpeechIds { get; set; }
public string StandardForm { get; set; }
public TranscriptionType TranscriptionType { get; set; }
}
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Gos.Core.Search.Queries.List
{
public class ListQueryResult : QueryResult
{
public List<ListQueryResultItem> Items { get; set; }
}
}
@@ -0,0 +1,13 @@
namespace Gos.Core.Search.Queries.List
{
public class ListQueryResultItem
{
public string ConversationalForm { get; set; }
public int Frequency { get; set; }
public string Msd { get; set; }
public string StandardForm { get; set; }
}
}
+38
View File
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using Gos.Core.Extensions;
namespace Gos.Core.Search.Queries
{
public abstract class Query : ICloneable
{
public List<int> DiscourseTypeIds { get; set; }
public List<int> DiscourseChannelIds { get; set; }
public List<int> DiscourseEventIds { get; set; }
public List<int> DiscourseRegionIds { get; set; }
public List<int> DiscourseYears { get; set; }
public int From { get; set; } = 0;
public int Size { get; set; } = 20;
public List<int> SpeakerAgeIds { get; set; }
public List<int> SpeakerEducationIds { get; set; }
public List<int> SpeakerLanguageIds { get; set; }
public List<int> SpeakerRegionIds { get; set; }
public List<int> SpeakerSexIds { get; set; }
public object Clone()
{
return this.Copy();
}
}
}
@@ -0,0 +1,7 @@
namespace Gos.Core.Search.Queries
{
public abstract class QueryResult
{
public long Total { get; set; }
}
}