626814424071906ee95582489bd6a94161e810d8
[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 class Pokedex(callbacks.Plugin):
44 """Add the help for "@plugin help Pokedex" here
45 This should describe *how* to use this plugin."""
46 def __init__(self, irc):
47 self.__parent = super(Pokedex, self)
48 self.__parent.__init__(irc)
49 self.db = pokedex.db.connect(self.registryValue('databaseURL'))
50 self.indices = pokedex.lookup.open_index(
51 directory=conf.supybot.directories.data.dirize('pokedex-index'),
52 session=self.db,
53 )
54
55 def pokedex(self, irc, msg, args, thing):
56 """<thing...>
57
58 Looks up <thing> in the veekun Pokédex."""
59
60 # Fix encoding. Sigh.
61 if not isinstance(thing, unicode):
62 ascii_thing = thing
63 try:
64 thing = ascii_thing.decode('utf8')
65 except UnicodeDecodeError:
66 thing = ascii_thing.decode('latin1')
67
68 # Similar logic to the site, here.
69 results = pokedex.lookup.lookup(thing, session=self.db,
70 indices=self.indices)
71
72 # Nothing found
73 if len(results) == 0:
74 self._reply(irc, "I don't know what that is.")
75 return
76
77 # Multiple matches; propose them all
78 if len(results) > 1:
79 if results[0].exact:
80 reply = "Are you looking for"
81 else:
82 reply = "Did you mean"
83
84 # For exact name matches with multiple results, use type prefixes
85 # (item:Metronome). For anything else, omit them
86 use_prefixes = (results[0].exact
87 and '*' not in thing
88 and '?' not in thing)
89
90 result_strings = []
91 for result in results:
92 result_string = result.object.name
93
94 # Prepend, e.g., pokemon: if necessary
95 if use_prefixes:
96 # Table classes know their singular names
97 prefix = result.object.__singlename__
98 result_string = prefix + ':' + result_string
99
100 # Identify foreign language names
101 if result.language:
102 result_string += u""" ({0}: {1})""".format(
103 result.iso3166, result.name)
104
105 result_strings.append(result_string)
106
107 self._reply(irc, u"{0}: {1}?".format(reply, '; '.join(result_strings)))
108 return
109
110 # If we got here, there's an exact match; hurrah!
111 result = results[0]
112 obj = result.object
113 if isinstance(obj, tables.Pokemon):
114 reply_template = \
115 u"""#{id} {name}, {type}-type Pokémon. Has {abilities}. """ \
116 """Is {stats}."""
117 self._reply(irc, reply_template.format(
118 id=obj.id,
119 name=obj.name,
120 type='/'.join(_.name for _ in obj.types),
121 abilities=' or '.join(_.name for _ in obj.abilities),
122 stats='/'.join(str(_.base_stat) for _ in obj.stats),
123 )
124 )
125
126 elif isinstance(obj, tables.Move):
127 reply_template = \
128 u"""{name}, {type}-type {damage_class} move. """ \
129 """{power} power; {accuracy}% accuracy; {pp} PP. """ \
130 """{effect}"""
131 self._reply(irc, reply_template.format(
132 name=obj.name,
133 type=obj.type.name,
134 damage_class=obj.damage_class.name,
135 power=obj.power,
136 accuracy=obj.accuracy,
137 pp=obj.pp,
138 effect=unicode(obj.short_effect.as_html),
139 )
140 )
141
142 elif isinstance(obj, tables.Type):
143 self._reply(irc, u"""{name}, a type.""".format(
144 name=obj.name,
145 )
146 )
147
148 elif isinstance(obj, tables.Item):
149 self._reply(irc, u"""{name}, an item.""".format(
150 name=obj.name,
151 )
152 )
153
154 elif isinstance(obj, tables.Ability):
155 self._reply(irc, u"""{name}, an ability. {effect}""".format(
156 name=obj.name,
157 effect=obj.effect,
158 )
159 )
160
161 else:
162 # This can only happen if lookup.py is upgraded and we are not
163 self._reply(irc, "Uhh.. I found that, but I don't know what it is. :(")
164
165 pokedex = wrap(pokedex, [rest('something')])
166
167 def _reply(self, irc, response):
168 """Wraps irc.reply() to do some Unicode decoding."""
169 if isinstance(response, str):
170 irc.reply(response)
171 else:
172 irc.reply(response.encode('utf8'))
173
174
175 Class = Pokedex
176
177
178 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: