root/trunk/Phergie/Plugin/Acronym.php @ 71

Revision 71, 4.7 KB (checked in by tobias382, 5 years ago)

* Added support to the Acronym plugin for filtering responses to certain acronyms
* Modified the Acronym plugin to restrict lookups to instances where the acronym takes up the entire post
* Modified the Acronym and Url plugins to add a lookup timeout
* Modified the Nickserv plugin to extend AdminCommand? instead of Command
* Fixed an issue in the tinyUrl method of the base plugin class where lack of URL encoding of the passed URL resulted in truncation of the original URL when computing its TinyURL equivalent
* Modified getIni and setIni methods in and added getPluginIni and setPluginIni to the base plugin case to allow for easier access to both core and plugin-specific settings and modified existing plugins to use the new methods where appropriate

Line 
1<?php
2
3/**
4* @see Phergie_Plugin_Abstract_Base
5*/
6require_once 'Phergie/Plugin/Abstract/Base.php';
7
8/**
9* Searches received messages for consecutive sequences of two or more capital
10* letters followed by a question mark, performs an acronym lookup for each
11* sequence, and either returns a limited number of possible meanings for the
12* acronym or performs a random action should no results be returned.
13*
14* The limit configuration setting should be set to the maximum number of
15* potential meanings to return for any single given acronym.
16*
17* @todo Add a cache to avoid exceeding the acronymfinder.com daily lookup
18*       limit. Cache should be flushed daily.
19*/
20class Phergie_Plugin_Acronym extends Phergie_Plugin_Abstract_Base
21{
22    /**
23    * Maximum number of meanings to return for a single acronym
24    *
25    * @var int
26    */
27    protected $limit;
28
29    /**
30    * List of acronyms for which responses should not be sent
31    *
32    * @var array
33    */
34    protected $filter;
35
36    /**
37    * Possible reactions to return when no result is returned
38    *
39    * @var array
40    */
41    protected $reactions = array(
42        'shrugs',
43        'blinks',
44        'giggles',
45        'sighs',
46        'yawns',
47        'hides behind %randomuser%'
48    );
49
50    /**
51    * Initializes the limit of meanings to return per acronym.
52    *
53    * @return void
54    */
55    public function init()
56    {
57        $limit = $this->getPluginIni('limit');
58        if ($limit < 0 || $limit === null) {
59            $this->limit = 5;
60        } else {
61            $this->limit = (int) $limit;
62        }
63
64        $this->filter = array_filter(preg_split('/[ ,]/', $this->getPluginIni('filter')), 'strlen');
65    }
66
67    /**
68    * Returns a random action, meant for cases where an acronym lookup
69    * returns no results.
70    *
71    * @param string $target Channel name or user nick to receive the action
72    * @return void
73    */
74    protected function randomAction($target)
75    {
76        do {
77            $reaction = $this->reactions[rand(0, count($this->reactions) - 1)];
78            $randomUser = strpos($reaction, '%randomuser%');
79        } while ($target[0] != '#' && $randomUser);
80        if ($randomUser) {
81            $nick = $this->getIni('nick');
82            do {
83                $user = Phergie_Plugin_Users::getRandomUser($target);
84            } while ($user == $nick);
85            $reaction = str_replace('%randomuser%', $user, $reaction);
86        }
87        $this->doAction($target, $reaction . '.');
88    }
89
90    /**
91    * Processes acronym lookups and returns results when available, or
92    * returns a random action when a lookup returns no results.
93    *
94    * @return void
95    */
96    public function onPrivmsg()
97    {
98        $target = $this->event->getSource();
99        $message = $this->event->getArgument(1);
100
101        if (!preg_match('/((?:[A-Z]\.?){2,})\?/AD', $message, $acronym)) {
102            return;
103        }
104
105        $acronym = str_replace('.', '', $acronym[1]);
106
107        if (in_array($acronym, $this->filter)) {
108            return;
109        }
110
111        if (in_array($acronym, array('WHO', 'WHAT', 'WHERE', 'WHEN', 'WHY', 'HOW'))) {
112            $this->doAction($target, 'shrugs.');
113            return;
114        }
115
116        $opts = array('http' =>
117            array(
118                'timeout' => 5,
119                'method' => 'GET',
120                'header' => 'Content-type: application/x-www-form-urlencoded',
121                'user_agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12',
122                'content' => http_build_query(array('terms' => $acronym, 'andor' => 'or', 'acronym' => 'on'))
123            )
124        );
125        $context = stream_context_create($opts);
126        $url = 'http://www.acronymfinder.com/af-query.asp?Acronym=' . urlencode($acronym) . '&Find=find';
127        $contents = @file_get_contents($url, false, $context);
128
129        if (empty ($contents)
130            || strpos($contents, 'no abbreviation matches') !== false
131            || strpos($contents, 'has exceeded the daily query limit') !== false) {
132            $this->randomAction($target);
133        } else {
134            $matches = array();
135            $offset = 0;
136
137            do {
138                $count = preg_match(
139                    '/<td width="65%"[^>]+>([^<]+)</i',
140                    $contents,
141                    $match,
142                    PREG_OFFSET_CAPTURE,
143                    $offset
144                );
145                if ($count == 1) {
146                    $matches[] = $match[1][0];
147                    $offset = $match[1][1];
148                }
149            } while (($this->limit == 0 || count($matches) < $this->limit) && $count == 1);
150
151            $text = 'Possible matches for ' . $acronym . ': ' . implode(', ', $matches);
152            $this->doPrivmsg($target, $text);
153        }
154    }
155}
Note: See TracBrowser for help on using the browser.