Вынести условия-предикаты в extension-методы
HasUser из 13 endpoint-файлов сведён в AuthHelpers.HasUser; 15 приватных предикатов заменены extension-методами с удалением дублирующих приватных методов: IsCommunicationFailure, IsTransportFailure, IsPrivateEndpoint, IsConfigured, IsTrue, IsExpired, IsFailedLogin/IsSuccessfulLogin, HasChanges, HasBudget, HasAnyTerm, IsCurrencyLetter, IsEmojiCodePoint, ContainsFooterHint, IsTypeLabel.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
namespace Deal.Modules.Pipeline.Application.Parse;
|
||||
|
||||
/// <summary>
|
||||
/// Расширения кодовых точек для чистки текста сообщений.
|
||||
/// </summary>
|
||||
internal static class CodePointExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Входит ли кодовая точка в эмодзи-диапазоны прототипа (pipeline.py _EMOJI_RE L137–145).
|
||||
/// </summary>
|
||||
/// <param name="codePoint">Кодовая точка (BMP или доп. плоскость).</param>
|
||||
/// <returns>True — декоративный символ, подлежащий удалению.</returns>
|
||||
public static bool IsEmojiCodePoint(this int codePoint) =>
|
||||
codePoint is >= 0x1F000 and <= 0x1FAFF
|
||||
or >= 0x2600 and <= 0x27BF
|
||||
or >= 0x2B00 and <= 0x2BFF
|
||||
or 0xFE0F;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ public static class MessageTextCleaner
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsEmojiCodePoint(codePoint))
|
||||
if (codePoint.IsEmojiCodePoint())
|
||||
{
|
||||
index += length - 1;
|
||||
continue;
|
||||
@@ -245,17 +245,6 @@ public static class MessageTextCleaner
|
||||
return current;
|
||||
}
|
||||
|
||||
// Входит ли кодовая точка в эмодзи-диапазоны прототипа (L137–145).
|
||||
// codePoint: Кодовая точка (BMP или доп. плоскость).
|
||||
// Возвращает: True — декоративный символ, подлежащий удалению.
|
||||
private static bool IsEmojiCodePoint(int codePoint)
|
||||
{
|
||||
return codePoint is >= 0x1F000 and <= 0x1FAFF
|
||||
or >= 0x2600 and <= 0x27BF
|
||||
or >= 0x2B00 and <= 0x2BFF
|
||||
or 0xFE0F;
|
||||
}
|
||||
|
||||
// Обрезка по границе последнего переноса/пробела в первых limit кодовых точках
|
||||
// (прототип L184–192): выбирается перенос (или пробел), если он после середины лимита; иначе режем жёстко.
|
||||
// value: Текст длиннее лимита.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Deal.Modules.Pipeline.Application.Parse;
|
||||
|
||||
/// <summary>
|
||||
/// Расширения строк для разбора текста сообщений.
|
||||
/// </summary>
|
||||
internal static class StringExtensions
|
||||
{
|
||||
// Служебные строки/фразы футеров агрегаторов: «суть» с ними — не структура, а шум (python L288–291).
|
||||
private static readonly string[] FooterHintsArray =
|
||||
{
|
||||
"откликнуться через", "runello", "больше вакансий", "teletype", "при отклике укажите",
|
||||
"больше заявок", "узнать подробнее", "написать в лс", "пишите в лс",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Содержит ли текст служебный футер-хинт (python L267/L275: сравнение с casefold-текстом).
|
||||
/// </summary>
|
||||
/// <param name="text">Текст (в любом регистре; null трактуется как пустая строка).</param>
|
||||
/// <returns>True — текст похож на футер агрегатора/служебную строку.</returns>
|
||||
public static bool ContainsFooterHint(this string text)
|
||||
{
|
||||
string lower = text.ToLowerInvariant();
|
||||
foreach (string hint in FooterHintsArray)
|
||||
{
|
||||
if (lower.Contains(hint, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Deal.Modules.Pipeline.Application.Parse;
|
||||
/// Карточка всегда собирается из одних и тех же блоков — Компания → Формат → О задаче → Требования →
|
||||
/// Будет плюсом → Условия (1:1 с cardPrompt); недостающие блоки пропускаются. Если структурированных полей нет
|
||||
/// (<see cref="ParsedCardContent.Summary"/> от локального/старого разбора) — суть сохраняется как есть, но
|
||||
/// отбрасывается, когда похожа на служебный футер агрегаторов (<see cref="FooterHints"/>); тогда «О задаче»
|
||||
/// отбрасывается, когда похожа на служебный футер агрегаторов (<see cref="StringExtensions.ContainsFooterHint(string)"/>); тогда «О задаче»
|
||||
/// собирается из содержательных строк текста (<see cref="LocalSummary"/>, с префиксом «О задаче: »).
|
||||
/// </remarks>
|
||||
public static class SummaryComposer
|
||||
@@ -43,13 +43,6 @@ public static class SummaryComposer
|
||||
"вакансия", "вакансию", "фриланс",
|
||||
};
|
||||
|
||||
// Служебные строки/фразы футеров агрегаторов: «суть» с ними — не структура, а шум (python L288–291).
|
||||
private static readonly string[] FooterHintsArray =
|
||||
{
|
||||
"откликнуться через", "runello", "больше вакансий", "teletype", "при отклике укажите",
|
||||
"больше заявок", "узнать подробнее", "написать в лс", "пишите в лс",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Собирает «О заявке» из структурированных полей либо текста (python compose_summary L225–284).
|
||||
/// </summary>
|
||||
@@ -105,7 +98,7 @@ public static class SummaryComposer
|
||||
// Структурированных полей нет. «summary» разбора часто является копией исходника/шумом — если в нём есть
|
||||
// футеры/хэштеги-мусор, не используем его (python L264–268).
|
||||
string legacy = MessageTextCleaner.CleanShort(source.Summary);
|
||||
if (legacy.Length > 0 && !ContainsFooterHint(legacy))
|
||||
if (legacy.Length > 0 && !legacy.ContainsFooterHint())
|
||||
{
|
||||
return legacy;
|
||||
}
|
||||
@@ -121,7 +114,7 @@ public static class SummaryComposer
|
||||
}
|
||||
|
||||
string lower = line.ToLowerInvariant();
|
||||
if (line.StartsWith('#') || lower.StartsWith("**#") || ContainsFooterHint(lower))
|
||||
if (line.StartsWith('#') || lower.StartsWith("**#") || lower.ContainsFooterHint())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -205,21 +198,4 @@ public static class SummaryComposer
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Содержит ли текст служебный футер-хинт (python L267/L275: сравнение с casefold-текстом).
|
||||
// text: Текст (в любом регистре).
|
||||
// Возвращает: True — текст похож на футер агрегатора/служебную строку.
|
||||
private static bool ContainsFooterHint(string text)
|
||||
{
|
||||
string lower = text.ToLowerInvariant();
|
||||
foreach (string hint in FooterHintsArray)
|
||||
{
|
||||
if (lower.Contains(hint, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user