/
AstroJohn
/
MailRobot
Обзор
Документация
Войти
/
AstroJohn
/
MailRobot
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CsParser/ParserBase.cs
413 строк
13 KB
AstroJohn
FD-VHF-2026
31 июл 2026, 14:39
31 июл 2026, 14:39
47d39af
Код
Авторство
О чём код?
using System; using Common; using DbContext; using LogProcessingModels.Parsing; using LogProcessingModels.PrefixResolving; namespace CsParser { public abstract class ParserBase { public void Initialize(ParserParameters parameters, IPrefixResolver prefixResolver, string connectionString) { Parameters = parameters; PrefixResolver = prefixResolver; ConnectionString = connectionString; if (connectionString.IsNullOrEmpty()) return; using var context = new CrossCheckDb(connectionString); InitializeInternal(context); } protected virtual void InitializeInternal(CrossCheckDb context) { } protected IPrefixResolver PrefixResolver { get; private set; } protected string ConnectionString { get; private set; } public ParserParameters Parameters { get; private set; } public abstract bool CheckOperatorsTagForRussianCallsigns { get; } public abstract bool FailedIfNotCheckedQsoTimeDuringContest { get; } public static bool IsNumeric(string s) { return float.TryParse(s, out _); } public static string Left(string s, int len) { if (s == null) return null; if (s.Length < len) return s; return s.Substring(0, len); } public static string Right(string s, int len) { if (s == null) return null; if (s.Length < len) return s; return s.Substring(s.Length - len, len); } public static string Mid(string s, int start, int len) { if (s == null) return null; if (start >= s.Length) return string.Empty; if (start < 0) start = 0; if (len > s.Length - start) len = s.Length - start; return s.Substring(start, len); } public static string Replace(string s, string what, string replace) { return s?.Replace(what, replace); } public static string Replace(string s, char what, char replace) { return s.Replace(what, replace); } public static string Trim(string s) { return s.Trim(); } public static int InStr(string s, string search) { return s.IndexOf(search, StringComparison.Ordinal); } public static int InStr(string s, char search) { return s.IndexOf(search); } public static bool IsRussianCallsign(string callsign) { return callsign.IsRussianCallsign(); } /// <summary> /// Проверка корректности позывного (содержит только заглавные английские буквы, цифры и дробь) /// </summary> public static bool IsValidCallsign(string callSign) { var res = false; if (callSign.Length <= 2) return false; foreach (var ch in callSign) { if ( ch is >= 'A' and <= 'Z' || ch is >= '0' and <= '9' || ch == '/' || ch == '-' ) res = true; else { res = false; break; } } return res; } /// <summary> /// Проверка корректности рапорта /// </summary> public static bool IsValidReport(string report) { if ( report.Length < 2 || report.Length > 3 || report.Contains("0") ) return false; if (IsNumeric(report)) { if ( Convert.ToInt32(report) >= 11 && Convert.ToInt32(report) <= 59 || Convert.ToInt32(report) >= 111 && Convert.ToInt32(report) <= 599 ) return true; } if (!IsNumeric(Left(report, 2))) return false; if ( Convert.ToInt32(Left(report, 2)) >= 11 && Convert.ToInt32(Left(report, 2)) <= 59 ) return true; return false; } public static bool IsValidAuroralReport(string report) { if ( report.Length != 3 || report.Contains("0") || !report.EndsWith("A") ) return false; var rs = report.Left(2); if (IsNumeric(rs)) { if ( Convert.ToInt32(rs) >= 11 && Convert.ToInt32(rs) <= 59 ) return true; } return false; } /// <summary> /// Проверка корректности рапорта /// </summary> public static bool IsValidReportFT8(string report, out string parsedReport) { if (int.TryParse(report, out var parsedReportInt)) { if (parsedReportInt is <= 20 and >= -40) { parsedReport = parsedReportInt.ToString("D"); return true; } if (parsedReportInt is <= 59 and >= 11) { parsedReport = parsedReportInt.ToString("D"); return true; } } parsedReport = null; return false; } /// <summary> /// Проверка корректности вида работы /// </summary> /// <param name="ediModeCode">Цифровой код вида работы</param> /// <param name="modeOut"></param> /// <returns></returns> /// <remarks></remarks> public static bool IsValidMode(string ediModeCode, out string modeOut) { modeOut = string.Empty; if (ediModeCode == "1") modeOut = "SSB"; else if (ediModeCode == "2") modeOut = "CW"; else if (ediModeCode == "6") modeOut = "FM"; else if (ediModeCode == "0") modeOut = "FT8"; else if (ediModeCode == "7") modeOut = "FT8"; else if (ediModeCode == "FT8") modeOut = "FT8"; else return false; return true; } /// <summary> /// Проверка корректности позывного (содержит только заглавные английские буквы, цифры и дробь) /// </summary> public static bool IsValidLocator(string locator) { bool res; if (locator.Length == 6) { System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex(@"\p{Lu}{2}\d{2}\p{Lu}{2}"); res = regEx.Matches(locator).Count == 1; } else res = false; return res; } public static string SpecialTimeFormat(DateTime value) { return value.Year + "-" + Right("0" + value.Month, 2) + "-" + Right("0" + value.Day, 2) + " " + Right("0" + value.Hour, 2) + ":" + Right("0" + value.Minute, 2); } public virtual void CheckFreqFormat(string value, ParsedQSO qso) { if (!string.IsNullOrEmpty(value) && IsNumeric(value)) { var frequency = Convert.ToInt32(value); qso.Freq = frequency; if (frequency >= 1800 & frequency <= 2000) qso.Band = "1"; else if (frequency >= 3500 & frequency <= 4000) qso.Band = "3"; else if (frequency >= 7000 & frequency <= 7200) qso.Band = "7"; else if (frequency >= 14000 & frequency <= 14350) qso.Band = "14"; else if (frequency >= 21000 & frequency <= 21450) qso.Band = "21"; else if (frequency >= 28000 & frequency <= 29700) qso.Band = "28"; } } protected virtual void CheckQsoTimeDuringContest(ParsedQSO parsedQso, bool failedIfNotChecked, int lineNumber) { if (parsedQso != null) { if ( parsedQso.Time < Parameters.DateStart || parsedQso.Time > Parameters.DateEnd ) { var msgEn = $"Invalid date and/or time: {parsedQso.Time:dd.MM.yyyy HH:mm}. " + $"The contest was spending from {Parameters.DateStart:dd.MM.yyyy HH:mm} till {Parameters.DateEnd:dd.MM.yyyy HH:mm}."; var msgRu = $"Неверное время и/или дата: {parsedQso.Time:dd.MM.yyyy HH:mm}. " + $"Соревнования проводились с {Parameters.DateStart:dd.MM.yyyy HH:mm} по {Parameters.DateEnd:dd.MM.yyyy HH:mm}."; if (failedIfNotChecked) { parsedQso.ParseResult.Type = PARSE_ERROR_TYPE.BAD; parsedQso.ParseResult.AddError(msgEn, lineNumber); parsedQso.ParseResult.AddErrorRu(msgRu, lineNumber); } else if (parsedQso.ParseResult.Type == PARSE_ERROR_TYPE.NONE) { parsedQso.ParseResult.Type = PARSE_ERROR_TYPE.WARNING; parsedQso.ParseResult.AddWarning(msgEn, lineNumber); parsedQso.ParseResult.AddWarningRu(msgRu, lineNumber); } } } } protected virtual string GetCategoryIndicatorForFileName(ParsedLog parsedLog) { var categoryIndicator = string.Empty; if ( parsedLog.ParseResult.Type == LOG_PARSE_ERROR_TYPE.NONE || parsedLog.ParseResult.Type == LOG_PARSE_ERROR_TYPE.WARNING ) { categoryIndicator = string.Empty; if (parsedLog.Category.IndexOf("20M-15M-10M", StringComparison.Ordinal) >= 0) { categoryIndicator = ".HB"; } if (parsedLog.Category.IndexOf("160M-80M-40M", StringComparison.Ordinal) >= 0) { categoryIndicator = ".LB"; } if (!parsedLog.Band.IsNullOrEmpty()) { categoryIndicator = " " + parsedLog.Band; } } else if (parsedLog.Callsign != string.Empty) { if (parsedLog.Band != string.Empty) { categoryIndicator = " " + parsedLog.Band; } else { categoryIndicator = string.Empty; } } return categoryIndicator; } protected virtual string GetTourIndicatorForFileName(ParsedLog parsedLog) { return string.Empty; } /// <summary> /// Форматирование порядкового номера 1 => 001 /// </summary> /// <param name="serialNr"></param> /// <returns></returns> /// <remarks></remarks> protected string FormatSerialNr(string serialNr) { var res = serialNr; if (int.TryParse(serialNr, out var value)) { res = value >= 1000 ? $"{value:D}" : $"{value:D3}"; } return res; } protected virtual bool IsMultiOpCategory(ParsedLog parsedLog) { var category = parsedLog.Category ?? string.Empty; return category.Contains("MULTI-OP") || category.Contains("MOST") || category.Contains("MOMT") || category.Contains("MO2T"); } protected virtual bool IsCheckLog(ParsedLog parsedLog) { var category = parsedLog.Category ?? string.Empty; return category.Contains("CHECK"); } } }