reviewer-basic/basic.go (179 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package basic import ( "embed" "encoding/json" "fmt" "strings" "github.com/apache/answer-plugins/reviewer-basic/i18n" "github.com/apache/answer-plugins/util" "github.com/apache/answer/plugin" myI18n "github.com/segmentfault/pacman/i18n" ) //go:embed info.yaml var Info embed.FS type Reviewer struct { Config *ReviewerConfig } const ( OptionNone = "none" OptionAll = "all" OptionFirst = "first" ) type ReviewerConfig struct { PostAllNeedReview bool `json:"review_post_all"` PostNeedReview bool `json:"review_post"` PostReviewOption string `json:"review_post_option"` PostReviewKeywords string `json:"review_post_keywords"` PostDisallowedKeywords string `json:"disallowed_keywords"` } func init() { plugin.Register(&Reviewer{ Config: &ReviewerConfig{}, }) } func (r *Reviewer) Info() plugin.Info { info := &util.Info{} info.GetInfo(Info) return plugin.Info{ Name: plugin.MakeTranslator(i18n.InfoName), SlugName: info.SlugName, Description: plugin.MakeTranslator(i18n.InfoDescription), Author: info.Author, Version: info.Version, Link: info.Link, } } func (r *Reviewer) Review(content *plugin.ReviewContent) (result *plugin.ReviewResult) { result = &plugin.ReviewResult{Approved: true, ReviewStatus: plugin.ReviewStatusApproved} // If the author is admin, no need to review if content.Author.Role > 1 { return result } if r.Config.PostReviewOption == OptionAll || (r.Config.PostReviewOption == "" && r.Config.PostAllNeedReview) { result = &plugin.ReviewResult{ Approved: false, ReviewStatus: plugin.ReviewStatusNeedReview, Reason: plugin.TranslateWithData(myI18n.Language(content.Language), i18n.CommentNeedReview, nil), } return result } if (r.Config.PostReviewOption == OptionFirst || (r.Config.PostReviewOption == "" && r.Config.PostNeedReview)) && content.Author.ApprovedQuestionAmount+content.Author.ApprovedAnswerAmount == 0 { result = &plugin.ReviewResult{ Approved: false, ReviewStatus: plugin.ReviewStatusNeedReview, Reason: plugin.TranslateWithData(myI18n.Language(content.Language), i18n.CommentNeedReview, nil), } return result } keywords := strings.Split(r.Config.PostReviewKeywords, "\n") disallowedKeywords := strings.Split(r.Config.PostDisallowedKeywords, "\n") // Check if the post contains the keywords that need review for _, keyword := range keywords { keyword = strings.TrimSpace(keyword) if len(keyword) == 0 { continue } keyword = strings.ToLower(keyword) if strings.Contains(strings.ToLower(content.Title), keyword) || strings.Contains(strings.ToLower(content.Content), keyword) || strings.Contains(content.IP, keyword) || strings.Contains(content.UserAgent, keyword) || r.checkTags(content.Tags, keyword) { return &plugin.ReviewResult{ Approved: false, ReviewStatus: plugin.ReviewStatusNeedReview, Reason: fmt.Sprintf(plugin.TranslateWithData(myI18n.Language(content.Language), i18n.CommentMatchWordReview, nil), keyword), } } } // If the post contains the disallowed keywords for _, disallowedKeyword := range disallowedKeywords { disallowedKeyword = strings.TrimSpace(disallowedKeyword) if len(disallowedKeyword) == 0 { continue } disallowedKeyword = strings.ToLower(disallowedKeyword) if strings.Contains(strings.ToLower(content.Title), disallowedKeyword) || strings.Contains(strings.ToLower(content.Content), disallowedKeyword) || strings.Contains(content.IP, disallowedKeyword) || strings.Contains(content.UserAgent, disallowedKeyword) || r.checkTags(content.Tags, disallowedKeyword) { return &plugin.ReviewResult{ Approved: false, ReviewStatus: plugin.ReviewStatusDeleteDirectly, Reason: fmt.Sprintf(plugin.TranslateWithData(myI18n.Language(content.Language), i18n.CommentMatchWordReview, nil), disallowedKeyword), } } } return result } func (r *Reviewer) ConfigFields() []plugin.ConfigField { defaultOption := OptionNone if r.Config.PostReviewOption == "" { if r.Config.PostAllNeedReview { defaultOption = OptionAll } else if r.Config.PostNeedReview { defaultOption = OptionFirst } } else { defaultOption = r.Config.PostReviewOption } return []plugin.ConfigField{ { Name: "review_post_option", Type: plugin.ConfigTypeSelect, Title: plugin.MakeTranslator(i18n.ConfigReviewPostTitle), Required: false, UIOptions: plugin.ConfigFieldUIOptions{}, Value: defaultOption, Options: []plugin.ConfigFieldOption{ { Value: OptionNone, Label: plugin.MakeTranslator(i18n.ConfigSelectOption), }, { Value: OptionAll, Label: plugin.MakeTranslator(i18n.ConfigReviewPostLabelAll), }, { Value: OptionFirst, Label: plugin.MakeTranslator(i18n.ConfigReviewPostLabelFirst), }, }, }, { Name: "review_post_keywords", Type: plugin.ConfigTypeTextarea, Title: plugin.MakeTranslator(i18n.ConfigReviewPostKeywordsTitle), Description: plugin.MakeTranslator(i18n.ConfigReviewPostKeywordsDescription), Value: r.Config.PostReviewKeywords, }, { Name: "disallowed_keywords", Type: plugin.ConfigTypeTextarea, Title: plugin.MakeTranslator(i18n.ConfigDisallowedKeywordsTitle), Description: plugin.MakeTranslator(i18n.ConfigDisallowedKeywordsDescription), Value: r.Config.PostDisallowedKeywords, }, } } func (r *Reviewer) ConfigReceiver(config []byte) error { c := &ReviewerConfig{} _ = json.Unmarshal(config, c) if c.PostReviewOption == OptionAll { c.PostAllNeedReview = true c.PostNeedReview = false } else if c.PostReviewOption == OptionFirst { c.PostAllNeedReview = false c.PostNeedReview = true } else if c.PostReviewOption == OptionNone { c.PostAllNeedReview = false c.PostNeedReview = false } r.Config = c return nil } func (r *Reviewer) checkTags(tags []string, keyword string) bool { for _, tag := range tags { if strings.Contains(strings.ToLower(tag), keyword) { return true } } return false }