public $username = null;
public $password = null;
+ const REVIEWSPAM = 'ActivitySpamPlugin::REVIEWSPAM';
+ const TRAINSPAM = 'ActivitySpamPlugin::TRAINSPAM';
+
/**
* Initializer
*
switch ($cls)
{
+ case 'TrainAction':
+ include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
+ return false;
case 'Spam_score':
include_once $dir . '/'.$cls.'.php';
return false;
case 'SpamFilter':
+ case 'TrainSpamForm':
+ case 'TrainHamForm':
include_once $dir . '/'.strtolower($cls).'.php';
return false;
default:
return true;
}
+ function onUserRightsCheck($profile, $right, &$result) {
+ switch ($right) {
+ case self::REVIEWSPAM:
+ case self::TRAINSPAM:
+ $result = ($profile->hasRole(Profile_role::MODERATOR) || $profile->hasRole('modhelper'));
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ function onGetSpamFilter(&$filter) {
+ $filter = $this->filter;
+ return false;
+ }
+
+ function onEndShowNoticeOptions(&$nli)
+ {
+ $notice = $nli->notice;
+ $out = $nli->out;
+
+ if (!empty($notice)) {
+
+ $score = Spam_score::staticGet('notice_id', $notice->id);
+
+ if (empty($score)) {
+ // XXX: show a question-mark or something
+ } else if ($score->is_spam) {
+ $form = new TrainHamForm($out, $notice);
+ $form->show();
+ } else if (!$score->is_spam) {
+ $form = new TrainSpamForm($out, $notice);
+ $form->show();
+ }
+ }
+
+ return true;
+ }
+
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'ActivitySpam',
return $score;
}
+ function save($notice, $result) {
+
+ $score = Spam_score::staticGet('notice_id', $notice->id);
+
+ if (empty($score)) {
+ $orig = null;
+ $score = new Spam_score();
+ } else {
+ $orig = clone($score);
+ }
+
+ $score->notice_id = $notice->id;
+ $score->score = $result->probability;
+ $score->is_spam = $result->isSpam;
+ $score->scaled = Spam_score::scale($score->score);
+ $score->created = common_sql_now();
+ $score->notice_created = $notice->created;
+
+ if (empty($orig)) {
+ $score->insert();
+ } else {
+ $score->update($orig);
+ }
+
+ return $score;
+ }
+
/**
* The One True Thingy that must be defined and declared.
*/
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2012, StatusNet, Inc.
+ *
+ * Train a notice as spam
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2012 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Train a notice as spam
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2012 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class TrainAction extends Action
+{
+ protected $notice = null;
+ protected $filter = null;
+ protected $category = null;
+
+ /**
+ * For initializing members of the class.
+ *
+ * @param array $argarray misc. arguments
+ *
+ * @return boolean true
+ */
+
+ function prepare($argarray)
+ {
+ parent::prepare($argarray);
+
+ // User must be logged in.
+
+ $user = common_current_user();
+
+ if (empty($user)) {
+ throw new ClientException(_("You must be logged in to train spam."), 403);
+ }
+
+ // It must be a "real" login, not saved cookie login
+
+ if (!common_is_real_login()) {
+ common_set_returnto($this->selfUrl());
+ if (Event::handle('RedirectToLogin', array($this, $user))) {
+ common_redirect(common_local_url('login'), 303);
+ return false;
+ }
+ }
+
+ // User must have the right to review spam
+
+ if (!$user->hasRight(ActivitySpamPlugin::TRAINSPAM)) {
+ throw new ClientException(_('You cannot review spam on this site.'), 403);
+ }
+
+ $id = $this->trim('notice');
+
+ $this->notice = Notice::staticGet('id', $id);
+
+ if (empty($this->notice)) {
+ throw new ClientException(_("No such notice."));
+ }
+
+ $this->checkSessionToken();
+
+ $filter = null;
+
+ Event::handle('GetSpamFilter', &$filter);
+
+ if (empty($filter)) {
+ throw new ServerException(_("No spam filter configured."));
+ }
+
+ $this->filter = $filter;
+
+ $this->category = $this->trim('category');
+
+ if ($this->category !== SpamFilter::SPAM &&
+ $this->category !== SpamFilter::HAM)
+ {
+ throw new ClientException(_("No such category."));
+ }
+
+ return true;
+ }
+
+ /**
+ * Handler method
+ *
+ * @param array $argarray is ignored since it's now passed in in prepare()
+ *
+ * @return void
+ */
+
+ function handle($argarray=null)
+ {
+ // Train
+
+ $this->filter->trainOnError($this->notice, $this->category);
+
+ // Re-test
+
+ $result = $this->filter->test($this->notice);
+
+ // Update or insert
+
+ $score = Spam_score::save($notice, $result);
+
+ // Show new toggle form
+
+ if ($this->category === SpamFilter::SPAM) {
+ $form = new TrainHamForm($this, $this->notice);
+ } else {
+ $form = new TrainSpamForm($this, $this->notice);
+ }
+
+ if ($this->boolean('ajax')) {
+ $this->startHTML('text/xml;charset=utf-8');
+ $this->elementStart('head');
+ // TRANS: Page title for page on which favorite notices can be unfavourited.
+ $this->element('title', null, _('Disfavor favorite.'));
+ $this->elementEnd('head');
+ $this->elementStart('body');
+ $form->show();
+ $this->elementEnd('body');
+ $this->elementEnd('html');
+ } else {
+ common_redirect(common_local_url('spam'), 303);
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * Toggle indicating spam, click to train as ham
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Form
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class TrainHamForm extends Form {
+
+ var $notice = null;
+
+ function __construct($out, $notice) {
+ parent::__construct($out);
+ $this->notice = $notice;
+ }
+
+ /**
+ * Name of the form
+ *
+ * Sub-classes should overload this with the name of their form.
+ *
+ * @return void
+ */
+
+ function formLegend()
+ {
+ return _("Train ham");
+ }
+
+ /**
+ * Visible or invisible data elements
+ *
+ * Display the form fields that make up the data of the form.
+ * Sub-classes should overload this to show their data.
+ *
+ * @return void
+ */
+
+ function formData()
+ {
+ $this->hidden('category', SpamFilter::HAM);
+ $this->hidden('notice', $this->notice->id);
+ }
+
+ /**
+ * Buttons for form actions
+ *
+ * Submit and cancel buttons (or whatever)
+ * Sub-classes should overload this to show their own buttons.
+ *
+ * @return void
+ */
+
+ function formActions()
+ {
+ $this->submit('submit',
+ _('Train ham'),
+ 'submit',
+ null,
+ _("Mark as ham"));
+ }
+
+ /**
+ * ID of the form
+ *
+ * Should be unique on the page. Sub-classes should overload this
+ * to show their own IDs.
+ *
+ * @return int ID of the form
+ */
+
+ function id()
+ {
+ return 'train_ham_' . $this->notice->id;
+ }
+
+ /**
+ * Action of the form.
+ *
+ * URL to post to. Should be overloaded by subclasses to give
+ * somewhere to post to.
+ *
+ * @return string URL to post to
+ */
+
+ function action()
+ {
+ return common_local_url('train');
+ }
+
+ /**
+ * Class of the form. May include space-separated list of multiple classes.
+ *
+ * If 'ajax' is included, the form will automatically be submitted with
+ * an 'ajax=1' parameter added, and the resulting form or error message
+ * will replace the form after submission.
+ *
+ * It's up to you to make sure that the target action supports this!
+ *
+ * @return string the form's class
+ */
+
+ function formClass()
+ {
+ return 'form_train_ham ajax';
+ }
+}
--- /dev/null
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * Toggle indicating ham, click to train as spam
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+ // This check helps protect against security problems;
+ // your code file can't be executed directly from the web.
+ exit(1);
+}
+
+/**
+ * Form
+ *
+ * @category Spam
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class TrainSpamForm extends Form {
+
+ var $notice = null;
+
+ function __construct($out, $notice) {
+ parent::__construct($out);
+ $this->notice = $notice;
+ }
+
+ /**
+ * Name of the form
+ *
+ * Sub-classes should overload this with the name of their form.
+ *
+ * @return void
+ */
+
+ function formLegend()
+ {
+ return _("Train spam");
+ }
+
+ /**
+ * Visible or invisible data elements
+ *
+ * Display the form fields that make up the data of the form.
+ * Sub-classes should overload this to show their data.
+ *
+ * @return void
+ */
+
+ function formData()
+ {
+ $this->hidden('category', SpamFilter::SPAM);
+ $this->hidden('notice', $this->notice->id);
+ }
+
+ /**
+ * Buttons for form actions
+ *
+ * Submit and cancel buttons (or whatever)
+ * Sub-classes should overload this to show their own buttons.
+ *
+ * @return void
+ */
+
+ function formActions()
+ {
+ $this->submit('submit',
+ _('Train spam'),
+ 'submit',
+ null,
+ _("Mark as spam"));
+ }
+
+ /**
+ * ID of the form
+ *
+ * Should be unique on the page. Sub-classes should overload this
+ * to show their own IDs.
+ *
+ * @return int ID of the form
+ */
+
+ function id()
+ {
+ return 'train_spam_' . $this->notice->id;
+ }
+
+ /**
+ * Action of the form.
+ *
+ * URL to post to. Should be overloaded by subclasses to give
+ * somewhere to post to.
+ *
+ * @return string URL to post to
+ */
+
+ function action()
+ {
+ return common_local_url('train');
+ }
+
+ /**
+ * Class of the form. May include space-separated list of multiple classes.
+ *
+ * If 'ajax' is included, the form will automatically be submitted with
+ * an 'ajax=1' parameter added, and the resulting form or error message
+ * will replace the form after submission.
+ *
+ * It's up to you to make sure that the target action supports this!
+ *
+ * @return string the form's class
+ */
+
+ function formClass()
+ {
+ return 'form_train_spam ajax';
+ }
+}