]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Added forms to train notices as spam/ham
authorEvan Prodromou <evan@status.net>
Wed, 7 Mar 2012 13:24:28 +0000 (07:24 -0600)
committerEvan Prodromou <evan@status.net>
Wed, 7 Mar 2012 13:24:28 +0000 (07:24 -0600)
ActivitySpamPlugin.php
Spam_score.php
train.php [new file with mode: 0644]
trainhamform.php [new file with mode: 0644]
trainspamform.php [new file with mode: 0644]

index fcc6673ce2e7ec98ab7285b465ed3780d7d85561..8a6ee89b3faa3686f30d67bda7b220de860e7939 100644 (file)
@@ -50,6 +50,9 @@ class ActivitySpamPlugin extends Plugin
     public $username = null;
     public $password = null;
 
+    const REVIEWSPAM = 'ActivitySpamPlugin::REVIEWSPAM';
+    const TRAINSPAM = 'ActivitySpamPlugin::TRAINSPAM';
+
     /**
      * Initializer
      *
@@ -101,10 +104,15 @@ class ActivitySpamPlugin extends Plugin
 
         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:
@@ -146,6 +154,45 @@ class ActivitySpamPlugin extends Plugin
         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',
index 08887d06b38a4206db193356043ab50eb84fa0e5..d6a05e2261fab8710e5d105f7aa10c47c4283b0f 100644 (file)
@@ -83,6 +83,33 @@ class Spam_score extends Managed_DataObject
         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.
      */
diff --git a/train.php b/train.php
new file mode 100644 (file)
index 0000000..4657993
--- /dev/null
+++ b/train.php
@@ -0,0 +1,165 @@
+<?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);
+        }
+    }
+}
diff --git a/trainhamform.php b/trainhamform.php
new file mode 100644 (file)
index 0000000..71bd650
--- /dev/null
@@ -0,0 +1,147 @@
+<?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';
+    }
+}
diff --git a/trainspamform.php b/trainspamform.php
new file mode 100644 (file)
index 0000000..07942f4
--- /dev/null
@@ -0,0 +1,147 @@
+<?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';
+    }
+}