From 62112d51ac46d8882519f803272d34e80a353971 Mon Sep 17 00:00:00 2001 From: xxxsen Date: Mon, 26 Aug 2024 22:07:46 +0800 Subject: [PATCH 1/2] feat: add njav source --- searcher/decoder/config.go | 5 ++- searcher/plugin/constant.go | 1 + searcher/plugin/njav.go | 85 +++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 searcher/plugin/njav.go diff --git a/searcher/decoder/config.go b/searcher/decoder/config.go index 8002c37..b6b65c0 100644 --- a/searcher/decoder/config.go +++ b/searcher/decoder/config.go @@ -1,5 +1,7 @@ package decoder +import "strconv" + type StringParseFunc func(v string) string type StringListParseFunc func(v []string) []string type NumberParseFunc func(v string) int64 @@ -32,7 +34,8 @@ func defaultStringListParser(vs []string) []string { } func defaultNumberParser(v string) int64 { - return 0 + res, _ := strconv.ParseInt(v, 10, 64) + return res } func defaultStringProcessor(v string) string { diff --git a/searcher/plugin/constant.go b/searcher/plugin/constant.go index 501066d..8cc641a 100644 --- a/searcher/plugin/constant.go +++ b/searcher/plugin/constant.go @@ -12,4 +12,5 @@ const ( SSJavDB = "javdb" SS18AV = "18av" SSTKTube = "tktube" + SSNJav = "njav" ) diff --git a/searcher/plugin/njav.go b/searcher/plugin/njav.go new file mode 100644 index 0000000..d7af465 --- /dev/null +++ b/searcher/plugin/njav.go @@ -0,0 +1,85 @@ +package plugin + +import ( + "fmt" + "net/http" + "strings" + "yamdc/model" + "yamdc/number" + "yamdc/searcher/decoder" + "yamdc/searcher/parser" +) + +type njav struct { + DefaultPlugin +} + +func (p *njav) OnMakeHTTPRequest(ctx *PluginContext, number *number.Number) (*http.Request, error) { + nid := number.GetNumberID() + nid = strings.ReplaceAll(nid, "_", "-") //将下划线替换为中划线 + ctx.SetKey("number", nid) + uri := fmt.Sprintf("https://njavtv.com/cn/search/%s", nid) + return http.NewRequest(http.MethodGet, uri, nil) +} + +func (p *njav) OnHandleHTTPRequest(ctx *PluginContext, invoker HTTPInvoker, req *http.Request) (*http.Response, error) { + numberId := strings.ToUpper(ctx.GetKeyOrDefault("number", "").(string)) + return HandleXPathTwoStepSearch(ctx, invoker, req, &XPathTwoStepContext{ + Ps: []*XPathPair{ + { + Name: "links", + XPath: `//div[@class="my-2 text-sm text-nord4 truncate"]/a[@class="text-secondary group-hover:text-primary"]/@href`, + }, + { + Name: "title", + XPath: `//div[@class="my-2 text-sm text-nord4 truncate"]/a[@class="text-secondary group-hover:text-primary"]/text()`, + }, + }, + LinkSelector: func(ps []*XPathPair) (string, bool, error) { + links := ps[0].Result + titles := ps[1].Result + for i, link := range links { + title := titles[i] + title = strings.ToUpper(title) + if strings.Contains(title, numberId) { + return link, true, nil + } + } + return "", false, nil + }, + ValidStatusCode: []int{http.StatusOK}, + CheckResultCountMatch: true, + }) + +} + +func (p *njav) OnDecodeHTTPData(ctx *PluginContext, data []byte) (*model.AvMeta, bool, error) { + dec := decoder.XPathHtmlDecoder{ + NumberExpr: `//div[@class="text-secondary" and contains(span[text()], "番号:")]/span[@class="font-medium"]/text()`, + TitleExpr: `//div[@class="text-secondary" and contains(span[text()], "标题:")]/span[@class="font-medium"]/text()`, + PlotExpr: "", + ActorListExpr: `//meta[@property="og:video:actor"]/@content`, + ReleaseDateExpr: `//div[@class="text-secondary" and contains(span[text()], "发行日期:")]/time[@class="font-medium"]/text()`, + DurationExpr: `//meta[@property="og:video:duration"]/@content`, + StudioExpr: `//div[@class="text-secondary" and contains(span[text()], "发行商:")]/a[@class="text-nord13 font-medium"]/text()`, + LabelExpr: `//div[@class="text-secondary" and contains(span[text()], "标籤:")]/a[@class="text-nord13 font-medium"]/text()`, + DirectorExpr: `//div[@class="text-secondary" and contains(span[text()], "导演:")]/a[@class="text-nord13 font-medium"]/text()`, + SeriesExpr: `//div[@class="text-secondary" and contains(span[text()], "系列:")]/a[@class="text-nord13 font-medium"]/text()`, + GenreListExpr: `//div[@class="text-secondary" and contains(span[text()], "类型:")]/a[@class="text-nord13 font-medium"]/text()`, + CoverExpr: `//link[@rel="preload" and @as="image"]/@href`, + PosterExpr: "", + SampleImageListExpr: "", + } + meta, err := dec.DecodeHTML(data, decoder.WithReleaseDateParser(parser.DefaultReleaseDateParser(ctx.GetContext()))) + if err != nil { + return nil, false, err + } + if len(meta.Number) == 0 { + return nil, false, nil + } + return meta, true, nil +} + +func init() { + Register(SSNJav, PluginToCreator(&njav{})) +} From 0d2f8107e9662d5bb9b84d54c78bf5346b5dadad Mon Sep 17 00:00:00 2001 From: xxxsen Date: Tue, 27 Aug 2024 20:27:29 +0800 Subject: [PATCH 2/2] chore: add to default list --- config/config.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index b4d160a..6fff13e 100644 --- a/config/config.go +++ b/config/config.go @@ -41,13 +41,14 @@ func defaultConfig() *Config { "jav321", "caribpr", "18av", + "njav", "freejavbt", "tktube", "avsox", }, CategoryPlugins: []CategoryPlugin{ //如果存在分配配置, 那么当番号被识别为特定分类的场景下, 将会使用分类插件直接查询 - {Name: "FC2", Plugins: []string{"fc2", "18av", "freejavbt", "tktube", "avsox"}}, + {Name: "FC2", Plugins: []string{"fc2", "18av", "njav", "freejavbt", "tktube", "avsox"}}, }, Handlers: []string{ "image_transcoder",