4a1b6f3a4db901072e3abc5be3681ddfdee1e6e6
[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://beta.veekun.com/dex/pokemon/{link_name}"""
120 self._reply(irc, reply_template.format(
121 id=obj.id,
122 name=obj.name,
123 type='/'.join(_.name for _ in obj.types),
124 abilities=' or '.join(_.name for _ in obj.abilities),
125 stats='/'.join(str(_.base_stat) for _ in obj.stats),
126 link_name=urllib.quote(obj.name.lower()),
127 )
128 )
129
130 elif isinstance(obj, tables.Move):
131 reply_template = \
132 u"""{name}, {type}-type {damage_class} move. """ \
133 """{power} power; {accuracy}% accuracy; {pp} PP. """ \
134 """{effect} """ \
135 """http://beta.veekun.com/dex/moves/{link_name}"""
136 self._reply(irc, reply_template.format(
137 name=obj.name,
138 type=obj.type.name,
139 damage_class=obj.damage_class.name,
140 power=obj.power,
141 accuracy=obj.accuracy,
142 pp=obj.pp,
143 effect=unicode(obj.short_effect.as_html),
144 link_name=urllib.quote(obj.name.lower()),
145 )
146 )
147
148 elif isinstance(obj, tables.Type):
149 self._reply(irc, u"""{name}, a type. http://beta.veekun.com/dex/types/{link_name}""".format(
150 name=obj.name,
151 link_name=urllib.quote(obj.name.lower()),
152 )
153 )
154
155 elif isinstance(obj, tables.Item):
156 self._reply(irc, u"""{name}, an item. http://beta.veekun.com/dex/items/{link_name}""".format(
157 name=obj.name,
158 link_name=urllib.quote(obj.name.lower()),
159 )
160 )
161
162 elif isinstance(obj, tables.Ability):
163 self._reply(irc, u"""{name}, an ability. {effect} http://beta.veekun.com/dex/abilities/{link_name}""".format(
164 name=obj.name,
165 effect=obj.effect,
166 link_name=urllib.quote(obj.name.lower()),
167 )
168 )
169
170 else:
171 # This can only happen if lookup.py is upgraded and we are not
172 self._reply(irc, "Uhh.. I found that, but I don't know what it is. :(")
173
174 pokedex = wrap(pokedex, [rest('something')])
175
176 def _reply(self, irc, response):
177 """Wraps irc.reply() to do some Unicode decoding."""
178 if isinstance(response, str):
179 irc.reply(response)
180 else:
181 irc.reply(response.encode('utf8'))
182
183
184 Class = Pokedex
185
186
187 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: