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

Revision 72, 4.8 KB (checked in by Seldaek, 5 years ago)

* Acronym : allowed <Nick>: ACRO?
* Daddy : added "I am your daddy, bitch!" 10% chance response (if curses is on)
* Logging : fixed "heard foo bar" triggering false positive heard answers, same for seen
* Url : caches 5 URLs now to avoid cross-bot flood
* phergie.ini : added global curses switch

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        // Matches an optional "Nick: " followed by an acronym formatted as A.B.C. or ABC
102        if (!preg_match('/^(?:[A-Za-z0-9\[\]`|{}_-]+: )?((?:[A-Z]\.?){2,})\?$/', $message, $acronym)) {
103            return;
104        }
105
106        $acronym = str_replace('.', '', $acronym[1]);
107
108        if (in_array($acronym, $this->filter)) {
109            return;
110        }
111
112        if (in_array($acronym, array('WHO', 'WHAT', 'WHERE', 'WHEN', 'WHY', 'HOW'))) {
113            $this->doAction($target, 'shrugs.');
114            return;
115        }
116
117        $opts = array('http' =>
118            array(
119                'timeout' => 5,
120                'method' => 'GET',
121                'header' => 'Content-type: application/x-www-form-urlencoded',
122                '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',
123                'content' => http_build_query(array('terms' => $acronym, 'andor' => 'or', 'acronym' => 'on'))
124            )
125        );
126        $context = stream_context_create($opts);
127        $url = 'http://www.acronymfinder.com/af-query.asp?Acronym=' . urlencode($acronym) . '&Find=find';
128        $contents = @file_get_contents($url, false, $context);
129
130        if (empty ($contents)
131            || strpos($contents, 'no abbreviation matches') !== false
132            || strpos($contents, 'has exceeded the daily query limit') !== false) {
133            $this->randomAction($target);
134        } else {
135            $matches = array();
136            $offset = 0;
137
138            do {
139                $count = preg_match(
140                    '/<td width="65%"[^>]+>([^<]+)</i',
141                    $contents,
142                    $match,
143                    PREG_OFFSET_CAPTURE,
144                    $offset
145                );
146                if ($count == 1) {
147                    $matches[] = $match[1][0];
148                    $offset = $match[1][1];
149                }
150            } while (($this->limit == 0 || count($matches) < $this->limit) && $count == 1);
151
152            $text = 'Possible matches for ' . $acronym . ': ' . implode(', ', $matches);
153            $this->doPrivmsg($target, $text);
154        }
155    }
156}
Note: See TracBrowser for help on using the browser.