From 65a0a41f84e1d5a1aeff5ac669413b4c0197c1b8 Mon Sep 17 00:00:00 2001 From: KOUNOIKE Yuusuke Date: Sun, 2 Apr 2023 04:32:29 +0900 Subject: [PATCH] =?UTF-8?q?=E3=81=82=E3=81=84=E3=81=BE=E3=81=84=E6=A4=9C?= =?UTF-8?q?=E7=B4=A2=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/bot.go | 2 +- config/config.go | 3 ++- docker-compose/config.yml.example | 1 + dtv/auto_search.go | 43 +++++++++++++++++++++++-------- dtv/dtv_usecase.go | 4 ++- dtv/on_ok_emoji_add.go | 4 +-- dtv/on_program_updated.go | 4 +-- go.mod | 5 ++-- go.sum | 4 +-- 9 files changed, 48 insertions(+), 22 deletions(-) diff --git a/cmd/bot.go b/cmd/bot.go index aae7626..f3bc143 100644 --- a/cmd/bot.go +++ b/cmd/bot.go @@ -181,7 +181,7 @@ func (c *BotCommand) Execute(ctx context.Context, f *flag.FlagSet, args ...inter scheduler := gocron.NewScheduler(time.FixedZone("JST", 9*60*60)) // scheduler.SetMaxConcurrentJobs(10, gocron.RescheduleMode) - usecase, err := dtv.NewDTVUsecase(config, asynqClient, asynqInspector, discordClient, mirakcClient, scheduler, queries, logger, config.Match.KanaMatch) + usecase, err := dtv.NewDTVUsecase(config, asynqClient, asynqInspector, discordClient, mirakcClient, scheduler, queries, logger, config.Match.KanaMatch, config.Match.FuzzyMatch) if err != nil { logger.Error("can't create DTVUsecase", zap.Error(err)) } diff --git a/config/config.go b/config/config.go index 3a05f49..cff358a 100644 --- a/config/config.go +++ b/config/config.go @@ -32,6 +32,7 @@ type Config struct { EncodeCommandTemplate string `required:"true" env:"ENCODING_COMMAND"` } Match struct { - KanaMatch bool `default:"true" env:"KANA_MATCH"` + KanaMatch bool `default:"true" env:"KANA_MATCH"` + FuzzyMatch bool `default:"true" env:"FUZZY_MATCH"` } } diff --git a/docker-compose/config.yml.example b/docker-compose/config.yml.example index 1c59dc3..215feaf 100644 --- a/docker-compose/config.yml.example +++ b/docker-compose/config.yml.example @@ -23,3 +23,4 @@ encoding: encodecommandtemplate: "ffmpeg -i {{.InputPath}} {{.OutputPath}} -y" match: kanamatch: true + fuzzymatch: true diff --git a/dtv/auto_search.go b/dtv/auto_search.go index b8c3060..be173c0 100644 --- a/dtv/auto_search.go +++ b/dtv/auto_search.go @@ -7,6 +7,7 @@ import ( "github.com/ikawaha/kagome/tokenizer" "github.com/kounoike/dtv-discord-go/db" "github.com/kounoike/dtv-discord-go/discord" + "github.com/lithammer/fuzzysearch/fuzzy" "go.uber.org/zap" "golang.org/x/text/width" "gopkg.in/ini.v1" @@ -53,21 +54,41 @@ func normalizeString(str string, kanaMatch bool) string { } } -func (a *AutoSearch) IsMatchProgram(program *AutoSearchProgram) bool { - if a.Title != "" && !strings.Contains(program.Title, a.Title) { - return false - } - if a.Genre != "" && !strings.Contains(program.Genre, a.Genre) { - return false +func (a *AutoSearch) IsMatchProgram(program *AutoSearchProgram, fuzzyMatch bool) bool { + if fuzzyMatch { + if a.Title != "" && !fuzzy.Match(a.Title, program.Title) { + return false + } + if a.Genre != "" && !fuzzy.Match(a.Genre, program.Genre) { + return false + } + return true + } else { + if a.Title != "" && !strings.Contains(program.Title, a.Title) { + return false + } + if a.Genre != "" && !strings.Contains(program.Genre, a.Genre) { + return false + } + return true } - return true } -func (a *AutoSearch) IsMatchService(serviceName string, kanaMatch bool) bool { - if a.Channel == "" || strings.Contains(normalizeString(serviceName, kanaMatch), normalizeString(a.Channel, kanaMatch)) { - return true +func (a *AutoSearch) IsMatchService(serviceName string, kanaMatch bool, fuzzyMatch bool) bool { + if fuzzyMatch { + asNormalized := normalizeString(a.Channel, kanaMatch) + serviceNormalized := normalizeString(serviceName, kanaMatch) + if a.Channel == "" || fuzzy.Match(asNormalized, serviceNormalized) { + return true + } else { + return false + } } else { - return false + if a.Channel == "" || strings.Contains(normalizeString(serviceName, kanaMatch), normalizeString(a.Channel, kanaMatch)) { + return true + } else { + return false + } } } diff --git a/dtv/dtv_usecase.go b/dtv/dtv_usecase.go index 69eef75..254fb07 100644 --- a/dtv/dtv_usecase.go +++ b/dtv/dtv_usecase.go @@ -26,13 +26,14 @@ type DTVUsecase struct { outputPathTmpl *template.Template autoSearchChannel *discordgo.Channel kanaMatch bool + fuzzyMatch bool } func fold(str string) string { return width.Fold.String(str) } -func NewDTVUsecase(cfg config.Config, asynqClient *asynq.Client, inspector *asynq.Inspector, discordClient *discord_client.DiscordClient, mirakcClient *mirakc_client.MirakcClient, scheduler *gocron.Scheduler, queries *db.Queries, logger *zap.Logger, kanaMatch bool) (*DTVUsecase, error) { +func NewDTVUsecase(cfg config.Config, asynqClient *asynq.Client, inspector *asynq.Inspector, discordClient *discord_client.DiscordClient, mirakcClient *mirakc_client.MirakcClient, scheduler *gocron.Scheduler, queries *db.Queries, logger *zap.Logger, kanaMatch bool, fuzzyMatch bool) (*DTVUsecase, error) { funcMap := map[string]interface{}{ "fold": fold, } @@ -55,5 +56,6 @@ func NewDTVUsecase(cfg config.Config, asynqClient *asynq.Client, inspector *asyn contentPathTmpl: contentTmpl, outputPathTmpl: outputTmpl, kanaMatch: kanaMatch, + fuzzyMatch: fuzzyMatch, }, nil } diff --git a/dtv/on_ok_emoji_add.go b/dtv/on_ok_emoji_add.go index a6adff2..b30bfd5 100644 --- a/dtv/on_ok_emoji_add.go +++ b/dtv/on_ok_emoji_add.go @@ -52,7 +52,7 @@ func (dtv *DTVUsecase) OnOkEmojiAdd(ctx context.Context, reaction *discordgo.Mes } for _, service := range services { - if autoSearch.IsMatchService(service.Name, dtv.kanaMatch) { + if autoSearch.IsMatchService(service.Name, dtv.kanaMatch, dtv.fuzzyMatch) { programs, err := dtv.mirakc.ListPrograms(uint(service.ID)) if err != nil { dtv.logger.Warn("ListPrograms error", zap.Error(err)) @@ -60,7 +60,7 @@ func (dtv *DTVUsecase) OnOkEmojiAdd(ctx context.Context, reaction *discordgo.Mes } for _, program := range programs { asp := NewAutoSearchProgram(program, dtv.kanaMatch) - if autoSearch.IsMatchProgram(asp) { + if autoSearch.IsMatchProgram(asp, dtv.fuzzyMatch) { // NOTE: DBに入ってるか確認する _, err := dtv.queries.GetProgram(ctx, program.ID) if errors.Cause(err) == sql.ErrNoRows { diff --git a/dtv/on_program_updated.go b/dtv/on_program_updated.go index 54ad5ca..74581a7 100644 --- a/dtv/on_program_updated.go +++ b/dtv/on_program_updated.go @@ -73,8 +73,8 @@ func (dtv *DTVUsecase) onProgramsUpdated(ctx context.Context, serviceId uint) er } asp := NewAutoSearchProgram(p, dtv.kanaMatch) for _, as := range autoSearchList { - dtv.logger.Debug("matching", zap.String("p.Name", p.Name), zap.String("asp.Title", asp.Title), zap.String("as.Title", as.Title), zap.Bool("isMatch", as.IsMatchProgram(asp))) - if as.IsMatchProgram(asp) { + // dtv.logger.Debug("matching", zap.String("p.Name", p.Name), zap.String("asp.Title", asp.Title), zap.String("as.Title", as.Title), zap.Bool("isMatch", as.IsMatchProgram(asp, dtv.fuzzyMatch))) + if as.IsMatchProgram(asp, dtv.fuzzyMatch) { dtv.logger.Debug("program matched", zap.String("program.Name", p.Name), zap.String("as.Title", as.Title)) err := dtv.sendAutoSearchMatchMessage(ctx, msg, p, service, as) if err != nil { diff --git a/go.mod b/go.mod index 0e2ef4a..44e22fd 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,16 @@ go 1.20 require ( github.com/alessio/shellescape v1.4.1 github.com/bwmarrin/discordgo v0.27.1 + github.com/go-co-op/gocron v1.19.0 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.7.0 github.com/google/subcommands v1.2.0 github.com/hibiken/asynq v0.24.0 + github.com/ikawaha/kagome v1.11.2 github.com/jinzhu/configor v1.2.1 github.com/json-iterator/go v1.1.12 github.com/lestrrat-go/backoff/v2 v2.0.8 + github.com/lithammer/fuzzysearch v1.1.5 github.com/mattn/go-shellwords v1.0.12 github.com/pkg/errors v0.9.1 github.com/r3labs/sse/v2 v2.10.0 @@ -26,14 +29,12 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/go-co-op/gocron v1.19.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/ikawaha/kagome v1.11.2 // indirect github.com/lestrrat-go/option v1.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index 76f3382..2e0d591 100644 --- a/go.sum +++ b/go.sum @@ -295,6 +295,8 @@ github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFe github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c= +github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= @@ -434,7 +436,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= @@ -464,7 +465,6 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=