]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/ActivitySpam/spamfilter.php
Merge ActivitySpam plugin
[quix0rs-gnu-social.git] / plugins / ActivitySpam / spamfilter.php
1 <?php
2   /**
3    * StatusNet - the distributed open-source microblogging tool
4    * Copyright (C) 2012, StatusNet, Inc.
5    *
6    * Spam filter class
7    * 
8    * PHP version 5
9    *
10    * This program is free software: you can redistribute it and/or modify
11    * it under the terms of the GNU Affero General Public License as published by
12    * the Free Software Foundation, either version 3 of the License, or
13    * (at your option) any later version.
14    *
15    * This program is distributed in the hope that it will be useful,
16    * but WITHOUT ANY WARRANTY; without even the implied warranty of
17    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    * GNU Affero General Public License for more details.
19    *
20    * You should have received a copy of the GNU Affero General Public License
21    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22    *
23    * @category  Spam
24    * @package   StatusNet
25    * @author    Evan Prodromou <evan@status.net>
26    * @copyright 2012 StatusNet, Inc.
27    * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28    * @link      http://status.net/
29    */
30
31 if (!defined('STATUSNET')) {
32     // This check helps protect against security problems;
33     // your code file can't be executed directly from the web.
34     exit(1);
35 }
36
37 /**
38  * Spam filter class
39  *
40  * Local proxy for remote filter
41  *
42  * @category  Spam
43  * @package   StatusNet
44  * @author    Evan Prodromou <evan@status.net>
45  * @copyright 2012 StatusNet, Inc.
46  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
47  * @link      http://status.net/
48  */
49
50 class SpamFilter extends OAuthClient {
51
52     const HAM  = 'ham';
53     const SPAM = 'spam';
54
55     public $server;
56
57     function __construct($server, $consumerKey, $secret) {
58         parent::__construct($consumerKey, $secret);
59         $this->server = $server;
60     }
61
62     protected function toActivity($notice) {
63         // FIXME: need this to autoload ActivityStreamsMediaLink
64         $doc = new ActivityStreamJSONDocument();
65
66         $activity = $notice->asActivity(null);
67
68         return $activity;
69     }
70
71     public function test($notice) {
72
73         $activity = $this->toActivity($notice);
74         return $this->testActivity($activity);
75     }
76     
77     public function testActivity($activity) {
78
79         $response = $this->postJSON($this->server . "/is-this-spam", $activity->asArray());
80
81         $result = json_decode($response->getBody());
82
83         return $result;
84     }
85
86     public function train($notice, $category) {
87
88         $activity = $this->toActivity($notice);
89         return $this->trainActivity($activity, $category);
90
91     }
92
93     public function trainActivity($activity, $category) {
94
95         switch ($category) {
96         case self::HAM:
97             $endpoint = '/this-is-ham';
98             break;
99         case self::SPAM:
100             $endpoint = '/this-is-spam';
101             break;
102         default:
103             throw new Exception("Unknown category: " + $category);
104         }
105
106         $response = $this->postJSON($this->server . $endpoint, $activity->asArray());
107
108         // We don't do much with the results
109         return true;
110     }
111
112     public function trainOnError($notice, $category) {
113
114         $activity = $this->toActivity($notice);
115
116         return $this->trainActivityOnError($activity, $category);
117     }
118     
119     public function trainActivityOnError($activity, $category) {
120
121         $result = $this->testActivity($activity);
122
123         if (($category === self::SPAM && $result->isSpam) ||
124             ($category === self::HAM && !$result->isSpam)) {
125             return true;
126         } else {
127             return $this->trainActivity($activity, $category);
128         }
129     }
130
131     function postJSON($url, $body)
132     {
133         $request = OAuthRequest::from_consumer_and_token($this->consumer,
134                                                          $this->token,
135                                                          'POST',
136                                                          $url);
137
138         $request->sign_request($this->sha1_method,
139                                $this->consumer,
140                                $this->token);
141
142         $hclient = new HTTPClient($url);
143
144         $hclient->setConfig(array('connect_timeout' => 120,
145                                   'timeout' => 120,
146                                   'follow_redirects' => true,
147                                   'ssl_verify_peer' => false,
148                                   'ssl_verify_host' => false));
149
150         $hclient->setMethod(HTTP_Request2::METHOD_POST);
151         $hclient->setBody(json_encode($body));
152         $hclient->setHeader('Content-Type', 'application/json');
153         $hclient->setHeader($request->to_header());
154
155         // Twitter is strict about accepting invalid "Expect" headers
156         // No reason not to clear it still here -ESP
157
158         $hclient->setHeader('Expect', '');
159
160         try {
161             $response = $hclient->send();
162             $code = $response->getStatus();
163             if (!$response->isOK()) {
164                 throw new OAuthClientException($response->getBody(), $code);
165             }
166             return $response;
167         } catch (Exception $e) {
168             throw new OAuthClientException($e->getMessage(), $e->getCode());
169         }
170     }
171 }