pax_global_header00006660000000000000000000000064143047661230014520gustar00rootroot0000000000000052 comment=5d5f4cb39205ec19f3b99249b8044878171e4e44 golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/000077500000000000000000000000001430476612300220015ustar00rootroot00000000000000golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/.editorconfig000066400000000000000000000000521430476612300244530ustar00rootroot00000000000000[*.go] indent_style = tab indent_size = 2 golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/LICENSE000066400000000000000000000020451430476612300230070ustar00rootroot00000000000000Copyright 2018 Adhityaa Chandrasekar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/README.md000066400000000000000000000056701430476612300232700ustar00rootroot00000000000000# go-akismet [![GoDoc](https://godoc.org/github.com/adtac/go-akismet/github?status.svg)](https://godoc.org/github.com/adtac/go-akismet) go-akismet is a Go client library for accessing the [Akismet API](https://akismet.com/development/api/) (v1.1). ### Usage ```go import "github.com/adtac/go-akismet/akismet" ``` Here's an example if you want to check whether a particular comment is spam or not using the `akismet.Check` method: ```go akismetKey := "abcdef012345" isSpam, err := akismet.Check(akismet.Comment{ Blog: "https://example.com", // required UserIP: "8.8.8.8", // required UserAgent: "...", // required CommentType: "comment", CommentAuthor: "Billie Joe", CommentAuthorEmail: "billie@example.com", CommentContent: "Something's on my mind", }, akismetKey) if err != nil { // There was some issue with the API request. Most probable cause is // missing required fields. } ``` You can also submit false positives (comments that were wrongly marked as spam) with the `akismet.SubmitHam` method. Or you can submit false negatives (comments that should be marked as spam, but weren't) with the `akismet.SubmitSpam` method. Both methods have the same method signature as the `akismet.Check` function: an `akismet.Comment` structure as the first argument followed by your API key. ### Development #### Contributing Patches welcome! This library was primarily developed for use in [Commento](https://github.com/adtac/commento), so priority of features and bug fixes from me will probably follow requirements there. #### Testing To run tests, you first need to set up your Akismet API key in the `AKISMET_KEY` environment variable. Following this, run `go test` to automatically execute all tests. Note that this will make real HTTP requests to the Akismet API server. ```bash $ export AKISMET_KEY=abcdef012345 $ go test ``` ### License ``` Copyright 2018 Adhityaa Chandrasekar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/000077500000000000000000000000001430476612300234365ustar00rootroot00000000000000golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/akismet.go000066400000000000000000000021751430476612300254270ustar00rootroot00000000000000package akismet import ( "fmt" "io/ioutil" "net/http" "net/url" "reflect" "strings" ) // All Akismet endpoints have the exact same request body format, with only // the endpoint changing between comment checks and submitting ham/spam. // Therefore, it makes sense to abstract the HTTP request in an unexported // function and re-use everywhere. func postRequest(c *Comment, key string, endpoint string) (string, error) { form := url.Values{} v := reflect.ValueOf(*c) t := v.Type() for i := 0; i < v.Type().NumField(); i++ { if v.Field(i).String() != "" { form.Add(t.Field(i).Tag.Get("form"), v.Field(i).String()) } } client := &http.Client{} reqBody := strings.NewReader(form.Encode()) api := fmt.Sprintf("https://%s.rest.akismet.com/1.1/%s", key, endpoint) req, err := http.NewRequest("POST", api, reqBody) if err != nil { return "", err } req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(respBody), nil } golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/comment.go000066400000000000000000000013461430476612300254330ustar00rootroot00000000000000package akismet type Comment struct { Blog string `form:"blog"` UserIP string `form:"user_ip"` UserAgent string `form:"user_agent"` Referrer string `form:"referrer"` Permalink string `form:"permalink"` CommentType string `form:"comment_type"` CommentAuthor string `form:"comment_author"` CommentAuthorEmail string `form:"comment_author_email"` CommentAuthorURL string `form:"comment_author_url"` CommentContent string `form:"comment_content"` BlogLang string `form:"blog_lang"` BlogCharset string `form:"blog_charset"` UserRole string `form:"user_role"` // TODO: Add support for comment_date_gmt and comment_post_modified_gmt } golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/comment_check.go000066400000000000000000000011211430476612300265570ustar00rootroot00000000000000package akismet import ( "errors" ) // This function checks whether a particular Comment is spam or not by querying // the Akismet API. The returned boolean is true if the comment was classified // as spam, false otherwise. If the request failed for whatever reason, the // error returned will be non-nil. func Check(c *Comment, key string) (bool, error) { respBody, err := postRequest(c, key, "comment-check") if err != nil { return true, err } if respBody == "true" { return true, nil } else if respBody == "false" { return false, nil } return true, errors.New(respBody) } golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/comment_check_test.go000066400000000000000000000045561430476612300276350ustar00rootroot00000000000000package akismet import ( "os" "testing" ) var chromeUA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36" var notSpam = "But the good of the scorpion is not the good of the frog, yes?" type testCaseCheck struct { name string c Comment isSpam bool hasError bool } func TestCheck(t *testing.T) { tests := []func(*testing.T, string){ testInvalids, testSpam, } if os.Getenv("AKISMET_KEY") == "" { t.Errorf("AKISMET_KEY not set") return } key := os.Getenv("AKISMET_KEY") for _, test := range tests { test(t, key) } } func runTests(t *testing.T, testCases []testCaseCheck, key string) { for _, tc := range testCases { isSpam, err := Check(&tc.c, key) if isSpam != tc.isSpam { t.Errorf("%s: expected isSpam=%v, got isSpam=%v", tc.name, tc.isSpam, isSpam) } if tc.hasError != (err != nil) { t.Errorf("%s: hasError=%v, got err=%v", tc.name, tc.hasError, err) } } } func testInvalids(t *testing.T, key string) { testCases := []testCaseCheck{ testCaseCheck{ "Comment{} missing everything", Comment{}, true, true, }, testCaseCheck{ "Comment{} missing blog", Comment{UserIP: "8.8.8.8", UserAgent: chromeUA, CommentContent: "Hello!"}, true, true, }, } runTests(t, testCases, key) } func testSpam(t *testing.T, key string) { testCases := []testCaseCheck{ testCaseCheck{ "Typical 419 scam", Comment{Blog: "https://example.com", UserIP: "8.8.8.8", UserAgent: chromeUA, CommentContent: "Send $6,321 to my western union account and receive $1,000,000 today http://419.com http://419.com"}, true, false, }, testCaseCheck{ "Outed by user agent", Comment{Blog: "https://example.com", UserIP: "8.8.8.8", UserAgent: "Python-urllib/2.1", CommentContent: notSpam}, true, false, }, testCaseCheck{ "Known to be a spammer by email", Comment{Blog: "https://example.com", UserIP: "8.8.8.8", UserAgent: chromeUA, CommentContent: notSpam, CommentAuthorEmail: "akismet-guaranteed-spam@example.com"}, true, false, }, } runTests(t, testCases, key) } func testHam(t *testing.T, key string) { testCases := []testCaseCheck{ testCaseCheck{ "Comment{} missing blog", Comment{Blog: "https://example.com", UserIP: "8.8.8.8", UserAgent: chromeUA, CommentContent: notSpam}, false, false, }, } runTests(t, testCases, key) } golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/comment_submit.go000066400000000000000000000015671430476612300270230ustar00rootroot00000000000000package akismet // This function submits a false positive to Akismet using the API. False // positives are those comments that should *not* be marked as spam, but were // accidentally. This method is mandatorily required in all implementations. // If the request went fine, a nil error is returned. Otherwise the returned // error is non-nil. func SubmitHam(c *Comment, key string) error { _, err := postRequest(c, key, "submit-ham") return err } // This function submits a false negatives to Akismet using the API. False // negatives are those comments that should be marked as spam, but were *not* // accidentally. This method is mandatorily required in all implementations. // If the request went fine, a nil error is returned. Otherwise the returned // error is non-nil. func SubmitSpam(c *Comment, key string) error { _, err := postRequest(c, key, "submit-spam") return err } golang-github-adtac-go-akismet-0.0~git20181220.0ca9e10/akismet/doc.go000066400000000000000000000022441430476612300245340ustar00rootroot00000000000000/* The akismet package provides a client for using the Akismet API. Usage: import "github.com/adtac/go-akismet/akismet" Here's an example if you want to check whether a particular comment is spam or not using the akismet.Check method: akismetKey := "abcdef012345" isSpam, err := akismet.Check(akismet.Comment{ Blog: "https://example.com", // required UserIP: "8.8.8.8", // required UserAgent: "...", // required CommentType: "comment", CommentAuthor: "Billie Joe", CommentAuthorEmail: "billie@example.com", CommentContent: "Something's on my mind", }, akismetKey) if err != nil { // There was some issue with the API request. Most probable cause is // missing required fields. } You can also submit false positives (comments that were wrongly marked as spam) with the akismet.SubmitHam method. Or you can submit false negatives (comments that should be marked as spam, but weren't) with the akismet.SubmitSpam method. Both methods have the same method signature as the akismet.Check function: an akismet.Comment structure as the first argument followed by your API key. */ package akismet