e3a925ec1212076fb7a8ce47064b2c3f3f3e05e6
[zzz-dywypi.git] / plugins / Pokedex / plugin.py
1 # encoding: utf8
2 ###
3 # Copyright (c) 2010, Alex Munroe
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 #
9 # * Redistributions of source code must retain the above copyright notice,
10 # this list of conditions, and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above copyright notice,
12 # this list of conditions, and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # * Neither the name of the author of this software nor the name of
15 # contributors to this software may be used to endorse or promote products
16 # derived from this software without specific prior written consent.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 # POSSIBILITY OF SUCH DAMAGE.
29
30 ###
31
32 import supybot.conf as conf
33 import supybot.utils as utils
34 from supybot.commands import *
35 import supybot.plugins as plugins
36 import supybot.ircutils as ircutils
37 import supybot.callbacks as callbacks
38
39 import pokedex.db
40 import pokedex.db.tables as tables
41 import pokedex.lookup
42
43 import urllib
44
45 class Pokedex(callbacks.Plugin):
46 """Add the help for "@plugin help Pokedex" here
47 This should describe *how* to use this plugin."""
48 def __init__(self, irc):
49 self.__parent = super(Pokedex, self)
50 self.__parent.__init__(irc)
51 self.db = pokedex.db.connect(self.registryValue('databaseURL'))
52 self.indices = pokedex.lookup.open_index(
53 directory=conf.supybot.directories.data.dirize('pokedex-index'),
54 session=self.db,
55 )
56
57 def pokedex(self, irc, msg, args, thing):
58 """<thing...>
59
60 Looks up <thing> in the veekun Pokédex."""
61
62 # Fix encoding. Sigh.
63 if not isinstance(thing, unicode):
64 ascii_thing = thing
65 try:
66 thing = ascii_thing.decode('utf8')
67 except UnicodeDecodeError:
68 thing = ascii_thing.decode('latin1')
69
70 # Similar logic to the site, here.
71 results = pokedex.lookup.lookup(thing, session=self.db,
72 indices=self.indices)
73
74 # Nothing found
75 if len(results) == 0:
76 self._reply(irc, "I don't know what that is.")
77 return
78
79 # Multiple matches; propose them all
80 if len(results) > 1:
81 if results[0].exact:
82 reply = "Are you looking for"
83 else:
84 reply = "Did you mean"
85
86 # For exact name matches with multiple results, use type prefixes
87 # (item:Metronome). For anything else, omit them
88 use_prefixes = (results[0].exact
89 and '*' not in thing
90 and '?' not in thing)
91
92 result_strings = []
93 for result in results:
94 result_string = result.object.name
95
96 # Prepend, e.g., pokemon: if necessary
97 if use_prefixes:
98 # Table classes know their singular names
99 prefix = result.object.__singlename__
100 result_string = prefix + ':' + result_string
101
102 # Identify foreign language names
103 if result.language:
104 result_string += u""" ({0}: {1})""".format(
105 result.iso3166, result.name)
106
107 result_strings.append(result_string)
108
109 self._reply(irc, u"{0}: {1}?".format(reply, '; '.join(result_strings)))
110 return
111
112 # If we got here, there's an exact match; hurrah!
113 result = results[0]
114 obj = result.object
115 if isinstance(obj, tables.Pokemon):
116 reply_template = \
117 u"""#{id} {name}, {type}-type Pokémon. Has {abilities}. """ \
118 """Is {stats}. """ \
119 """http://veekun.com/dex/pokemon/{link_name}"""
120
121 if obj.forme_name:
122 name = '{form} {name}'.format(
123 form=obj.forme_name.title(),
124 name=obj.name
125 )
126 else:
127 name = obj.name
128
129 if obj.forme_base_pokemon:
130 # Can't use urllib.quote() on the whole thing or it'll
131 # catch "?" and "=" where it shouldn't.
132 # XXX Also we need to pass urllib.quote() things explicitly
133 # encoded as utf8 or else we get a UnicodeEncodeError.
134 link_name = '{name}?form={form}'.format(
135 name=urllib.quote(obj.name.lower().encode('utf8')),
136 form=urllib.quote(obj.forme_name.lower().encode('utf8')),
137 )
138 else:
139 link_name = urllib.quote(obj.name.lower().encode('utf8'))
140
141 self._reply(irc, reply_template.format(
142 id=obj.national_id,
143 name=name,
144 type='/'.join(_.name for _ in obj.types),
145 abilities=' or '.join(_.name for _ in obj.abilities),
146 stats='/'.join(str(_.base_stat) for _ in obj.stats),
147 link_name=link_name,
148 )
149 )
150
151 elif isinstance(obj, tables.Move):
152 reply_template = \
153 u"""{name}, {type}-type {damage_class} move. """ \
154 """{power} power; {accuracy}% accuracy; {pp} PP. """ \
155 """{effect} """ \
156 """http://beta.veekun.com/dex/moves/{link_name}"""
157 self._reply(irc, reply_template.format(
158 name=obj.name,
159 type=obj.type.name,
160 damage_class=obj.damage_class.name,
161 power=obj.power,
162 accuracy=obj.accuracy,
163 pp=obj.pp,
164 effect=unicode(obj.short_effect.as_html),
165 link_name=urllib.quote(obj.name.lower()),
166 )
167 )
168
169 elif isinstance(obj, tables.Type):
170 self._reply(irc, u"""{name}, a type. http://beta.veekun.com/dex/types/{link_name}""".format(
171 name=obj.name,
172 link_name=urllib.quote(obj.name.lower()),
173 )
174 )
175
176 elif isinstance(obj, tables.Item):
177 self._reply(irc, u"""{name}, an item. http://beta.veekun.com/dex/items/{link_name}""".format(
178 name=obj.name,
179 link_name=urllib.quote(obj.name.lower()),
180 )
181 )
182
183 elif isinstance(obj, tables.Ability):
184 self._reply(irc, u"""{name}, an ability. {effect} http://beta.veekun.com/dex/abilities/{link_name}""".format(
185 name=obj.name,
186 effect=obj.effect,
187 link_name=urllib.quote(obj.name.lower()),
188 )
189 )
190
191 else:
192 # This can only happen if lookup.py is upgraded and we are not
193 self._reply(irc, "Uhh.. I found that, but I don't know what it is. :(")
194
195 pokedex = wrap(pokedex, [rest('something')])
196
197 def _reply(self, irc, response):
198 """Wraps irc.reply() to do some Unicode decoding."""
199 if isinstance(response, str):
200 irc.reply(response)
201 else:
202 irc.reply(response.encode('utf8'))
203
204
205 Class = Pokedex
206
207
208 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: