diff --git a/core/src/main/java/dev/felnull/itts/core/ITTSRuntime.java b/core/src/main/java/dev/felnull/itts/core/ITTSRuntime.java index 16259b0..2142575 100644 --- a/core/src/main/java/dev/felnull/itts/core/ITTSRuntime.java +++ b/core/src/main/java/dev/felnull/itts/core/ITTSRuntime.java @@ -5,6 +5,7 @@ import dev.felnull.itts.core.cache.CacheManager; import dev.felnull.itts.core.config.ConfigManager; import dev.felnull.itts.core.dict.DictionaryManager; +import dev.felnull.itts.core.dict.DomainListManager; import dev.felnull.itts.core.discord.Bot; import dev.felnull.itts.core.savedata.SaveDataManager; import dev.felnull.itts.core.tts.TTSManager; @@ -99,6 +100,11 @@ public class ITTSRuntime { */ private final VoiceAudioManager voiceAudioManager = new VoiceAudioManager(); + /** + * ドメイン名リストマネージャー + */ + private final DomainListManager domainListManager = new DomainListManager(); + /** * 辞書マネージャー */ @@ -148,7 +154,7 @@ private ITTSRuntime(ITTSRuntimeContext runtimeContext) { this.configManager = new ConfigManager(runtimeContext.getConfigContext()); this.cacheManager = new CacheManager(runtimeContext.getGlobalCacheAccessFactory()); - this.managers = ImmutableList.of(configManager, voiceManager); + this.managers = ImmutableList.of(configManager, voiceManager, domainListManager); } /** @@ -265,6 +271,9 @@ public DictionaryManager getDictionaryManager() { return dictionaryManager; } + public DomainListManager getDomainListManager() { + return domainListManager; + } public ITTSNetworkManager getNetworkManager() { return networkManager; diff --git a/core/src/main/java/dev/felnull/itts/core/ITTSRuntimeUse.java b/core/src/main/java/dev/felnull/itts/core/ITTSRuntimeUse.java index 8c7c8f3..28208bb 100644 --- a/core/src/main/java/dev/felnull/itts/core/ITTSRuntimeUse.java +++ b/core/src/main/java/dev/felnull/itts/core/ITTSRuntimeUse.java @@ -4,6 +4,7 @@ import dev.felnull.itts.core.cache.CacheManager; import dev.felnull.itts.core.config.ConfigManager; import dev.felnull.itts.core.dict.DictionaryManager; +import dev.felnull.itts.core.dict.DomainListManager; import dev.felnull.itts.core.discord.Bot; import dev.felnull.itts.core.tts.TTSManager; import dev.felnull.itts.core.voice.VoiceManager; @@ -63,6 +64,10 @@ default DictionaryManager getDictionaryManager() { return getITTSRuntime().getDictionaryManager(); } + default DomainListManager getDomainListManager() { + return getITTSRuntime().getDomainListManager(); + } + default VoiceManager getVoiceManager() { return getITTSRuntime().getVoiceManager(); } diff --git a/core/src/main/java/dev/felnull/itts/core/dict/AbbreviationDictionary.java b/core/src/main/java/dev/felnull/itts/core/dict/AbbreviationDictionary.java index f6acf91..0cb467b 100644 --- a/core/src/main/java/dev/felnull/itts/core/dict/AbbreviationDictionary.java +++ b/core/src/main/java/dev/felnull/itts/core/dict/AbbreviationDictionary.java @@ -29,11 +29,11 @@ public class AbbreviationDictionary implements Dictionary { Matcher matcher = pattern.matcher(s); return matcher.find(); })*/ - .addOption(1, "ドメインショウリャク", s -> { + /*.addOption(1, "ドメインショウリャク", s -> { Pattern pattern = Pattern.compile("^([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\\.)+[a-zA-Z]{2,}$"); Matcher matcher = pattern.matcher(s); return matcher.find(); - }) + })*/ .addOption(1, "アイピーブイフォーショウリャク", s -> { Pattern pattern = Pattern.compile("^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"); Matcher matcher = pattern.matcher(s); @@ -61,9 +61,15 @@ public class AbbreviationDictionary implements Dictionary { */ private final URLReplacer urlReplacer = new URLReplacer("ユーアルエルショウリャク"); + /** + * ドメインリプレーサー + */ + private final DomainReplacer domainReplacer = new DomainReplacer("ドメインショウリャク"); + @Override public @NotNull String apply(@NotNull String text, long guildId) { text = urlReplacer.replace(text); + text = domainReplacer.replace(text); text = CODE_BLOCK_REGEX.matcher(text).replaceAll("コードブロックショウリャク"); return regexUtil.replaceText(text); } diff --git a/core/src/main/java/dev/felnull/itts/core/dict/DomainListManager.java b/core/src/main/java/dev/felnull/itts/core/dict/DomainListManager.java new file mode 100644 index 0000000..63feaa2 --- /dev/null +++ b/core/src/main/java/dev/felnull/itts/core/dict/DomainListManager.java @@ -0,0 +1,64 @@ +package dev.felnull.itts.core.dict; + +import dev.felnull.itts.core.ITTSBaseManager; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * TLDリストマネージャー + **/ + +public class DomainListManager implements ITTSBaseManager { + + /** + * 取得先URL + */ + private static final URI IANA_DATA_URI = URI.create("https://data.iana.org/TLD/tlds-alpha-by-domain.txt"); + + /** + * 読み込み済みTLDリスト + */ + private Pattern domainPattern; + + @Override + public @NotNull CompletableFuture init() { + return CompletableFuture.runAsync(() -> { + try { + HttpClient hc = getNetworkManager().getHttpClient(); + HttpRequest request = HttpRequest.newBuilder().uri(IANA_DATA_URI).GET().build(); + + HttpResponse res = hc.send(request, HttpResponse.BodyHandlers.ofString()); + + String processedDomains = res.body().lines() + .filter(line -> !line.startsWith("#")) + .filter(list -> !list.isBlank()) + .map(String::trim) + .map(String::toLowerCase) + .map(Pattern::quote) + .collect(Collectors.joining("|")); + + String regex = "\\b[a-zA-Z0-9.-]+\\.(?i:" + processedDomains + ")\\b"; + domainPattern = Pattern.compile(regex); + } catch (IOException | InterruptedException e) { + getITTSLogger().error("failed to get domain list."); + } + }, getAsyncExecutor()); + } + + /** + * 読み込み済みTLDゲッター + * + * @return ドメイン検知正規表現 + */ + public @Nullable Pattern getPattern() { + return domainPattern; + } +} diff --git a/core/src/main/java/dev/felnull/itts/core/dict/DomainReplacer.java b/core/src/main/java/dev/felnull/itts/core/dict/DomainReplacer.java new file mode 100644 index 0000000..b8934a3 --- /dev/null +++ b/core/src/main/java/dev/felnull/itts/core/dict/DomainReplacer.java @@ -0,0 +1,39 @@ +package dev.felnull.itts.core.dict; + +import dev.felnull.itts.core.ITTSRuntimeUse; +import java.util.regex.Pattern; + +/** + * ドメインを置き換える処理 + */ +public class DomainReplacer implements ITTSRuntimeUse { + + /** + * 置き換えるテキスト + */ + private final String replacedText; + + /** + * コンストラクタ + * + * @param replacedText 置き換えるテキスト + */ + public DomainReplacer(String replacedText) { + this.replacedText = replacedText; + } + + /** + * テキスト置き換え + * + * @param text テキスト + * @return 置き換えられたテキスト + */ + public String replace(String text) { + Pattern domainPattern = getDomainListManager().getPattern(); + if (domainPattern != null) { + return domainPattern.matcher(text).replaceAll(replacedText); + } + + return text; + } +}