2020-06-29 04:44:35 +02:00
|
|
|
using System;
|
2017-12-03 15:35:52 +01:00
|
|
|
using System.Collections.Generic;
|
2019-04-26 01:13:17 +02:00
|
|
|
using System.Globalization;
|
2017-12-03 15:35:52 +01:00
|
|
|
using System.Linq;
|
2023-05-19 03:42:09 +02:00
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using ExchangeSharp;
|
2017-12-03 15:35:52 +01:00
|
|
|
|
|
|
|
namespace BTCPayServer
|
|
|
|
{
|
|
|
|
public class SearchString
|
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
private const char FilterSeparator = ',';
|
|
|
|
private const char ValueSeparator = ':';
|
|
|
|
|
|
|
|
private readonly string _originalString;
|
|
|
|
private readonly int _timezoneOffset;
|
|
|
|
|
|
|
|
public SearchString(string str, int timezoneOffset = 0)
|
2017-12-03 15:35:52 +01:00
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
str ??= string.Empty;
|
2017-12-03 15:35:52 +01:00
|
|
|
str = str.Trim();
|
2023-05-19 03:42:09 +02:00
|
|
|
_originalString = str;
|
|
|
|
_timezoneOffset = timezoneOffset;
|
|
|
|
TextSearch = _originalString;
|
|
|
|
var splitted = str.Split(new [] { FilterSeparator }, StringSplitOptions.RemoveEmptyEntries);
|
2017-12-03 15:35:52 +01:00
|
|
|
Filters
|
|
|
|
= splitted
|
2023-05-19 03:42:09 +02:00
|
|
|
.Select(t => t.Split(new [] { ValueSeparator }, 2, StringSplitOptions.RemoveEmptyEntries))
|
2017-12-03 15:35:52 +01:00
|
|
|
.Where(kv => kv.Length == 2)
|
2023-05-19 03:42:09 +02:00
|
|
|
.Select(kv => new KeyValuePair<string, string>(UnifyKey(kv[0]), kv[1]))
|
2018-04-26 04:01:59 +02:00
|
|
|
.ToMultiValueDictionary(o => o.Key, o => o.Value);
|
2017-12-03 15:35:52 +01:00
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
var val = splitted.FirstOrDefault(a => a.IndexOf(ValueSeparator, StringComparison.OrdinalIgnoreCase) == -1);
|
|
|
|
TextSearch = val != null ? val.Trim() : string.Empty;
|
2017-12-03 15:35:52 +01:00
|
|
|
}
|
|
|
|
|
2019-04-26 01:13:17 +02:00
|
|
|
public string TextSearch { get; private set; }
|
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
public MultiValueDictionary<string, string> Filters { get; }
|
2017-12-03 15:35:52 +01:00
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
return _originalString;
|
|
|
|
}
|
|
|
|
|
|
|
|
public string Toggle(string key, string value)
|
|
|
|
{
|
|
|
|
key = UnifyKey(key);
|
|
|
|
var keyValue = $"{key}{ValueSeparator}{value}";
|
|
|
|
var prependOnInsert = string.IsNullOrEmpty(ToString()) ? string.Empty : $"{ToString()}{FilterSeparator}";
|
|
|
|
if (!ContainsFilter(key)) return Finalize($"{prependOnInsert}{keyValue}");
|
|
|
|
|
|
|
|
var boolFilter = GetFilterBool(key);
|
|
|
|
if (boolFilter != null)
|
|
|
|
{
|
|
|
|
return Finalize(ToString().Replace(keyValue, string.Empty));
|
|
|
|
}
|
|
|
|
|
|
|
|
var dateFilter = GetFilterDate(key, _timezoneOffset);
|
|
|
|
if (dateFilter != null)
|
|
|
|
{
|
|
|
|
var current = GetFilterArray(key).First();
|
|
|
|
var oldValue = $"{key}{ValueSeparator}{current}";
|
|
|
|
var newValue = string.IsNullOrEmpty(value) || current == value ? string.Empty : keyValue;
|
|
|
|
return Finalize(_originalString.Replace(oldValue, newValue));
|
|
|
|
}
|
|
|
|
|
|
|
|
var arrayFilter = GetFilterArray(key);
|
|
|
|
if (arrayFilter != null)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(value))
|
|
|
|
{
|
|
|
|
return Finalize(arrayFilter.Aggregate(ToString(), (current, filter) =>
|
|
|
|
current.Replace($"{key}{ValueSeparator}{filter}", string.Empty)));
|
|
|
|
}
|
|
|
|
return Finalize(arrayFilter.Contains(value)
|
|
|
|
? ToString().Replace(keyValue, string.Empty)
|
|
|
|
: $"{prependOnInsert}{keyValue}"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Finalize(ToString());
|
|
|
|
}
|
|
|
|
|
|
|
|
public string WithoutSearchText()
|
|
|
|
{
|
|
|
|
return string.IsNullOrEmpty(TextSearch)
|
|
|
|
? Finalize(ToString())
|
|
|
|
: Finalize(ToString()).Replace(TextSearch, string.Empty);
|
2017-12-03 15:35:52 +01:00
|
|
|
}
|
2019-04-26 01:13:17 +02:00
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
public string[] GetFilterArray(string key)
|
2019-04-26 01:13:17 +02:00
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
key = UnifyKey(key);
|
2019-04-26 01:13:17 +02:00
|
|
|
return Filters.ContainsKey(key) ? Filters[key].ToArray() : null;
|
|
|
|
}
|
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
public bool? GetFilterBool(string key)
|
2019-04-26 01:13:17 +02:00
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
key = UnifyKey(key);
|
2019-04-26 01:13:17 +02:00
|
|
|
if (!Filters.ContainsKey(key))
|
|
|
|
return null;
|
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
return bool.TryParse(Filters[key].First(), out var r) ? r : null;
|
2019-04-26 01:13:17 +02:00
|
|
|
}
|
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
public DateTimeOffset? GetFilterDate(string key, int timezoneOffset)
|
2019-04-26 01:13:17 +02:00
|
|
|
{
|
2023-05-19 03:42:09 +02:00
|
|
|
key = UnifyKey(key);
|
2019-04-26 01:13:17 +02:00
|
|
|
if (!Filters.ContainsKey(key))
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var val = Filters[key].First();
|
2023-05-19 03:42:09 +02:00
|
|
|
switch (val)
|
|
|
|
{
|
|
|
|
// handle special string values
|
|
|
|
case "-24h":
|
|
|
|
case "-1d":
|
|
|
|
return DateTimeOffset.UtcNow.AddDays(-1).AddMinutes(timezoneOffset);
|
|
|
|
case "-3d":
|
|
|
|
return DateTimeOffset.UtcNow.AddDays(-3).AddMinutes(timezoneOffset);
|
|
|
|
case "-7d":
|
|
|
|
return DateTimeOffset.UtcNow.AddDays(-7).AddMinutes(timezoneOffset);
|
|
|
|
}
|
2020-07-27 23:45:50 +02:00
|
|
|
|
|
|
|
// default parsing logic
|
2023-05-19 03:42:09 +02:00
|
|
|
var success = DateTimeOffset.TryParse(val, null, DateTimeStyles.AssumeUniversal, out var r);
|
2019-04-26 01:13:17 +02:00
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
r = r.AddMinutes(timezoneOffset);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2021-12-31 08:36:38 +01:00
|
|
|
|
2023-05-19 03:42:09 +02:00
|
|
|
public bool ContainsFilter(string key)
|
|
|
|
{
|
|
|
|
return Filters.ContainsKey(UnifyKey(key));
|
|
|
|
}
|
|
|
|
|
|
|
|
private string UnifyKey(string key)
|
|
|
|
{
|
|
|
|
return key.ToLowerInvariant().Trim();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static string Finalize(string str)
|
|
|
|
{
|
|
|
|
var value = str.TrimStart(FilterSeparator).TrimEnd(FilterSeparator);
|
|
|
|
return string.IsNullOrEmpty(value) ? " " : value;
|
|
|
|
}
|
2017-12-03 15:35:52 +01:00
|
|
|
}
|
|
|
|
}
|