| /* | |
| * 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 | |
| } |