chiark / gitweb /
FishPond: Use in all other bots
[irc.git] / Servus-artichoke.py
1 # This file is part of Acrobat.
2 #
3 # Acrobat is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published
5 # by the Free Software Foundation; either version 2 of the License,
6 # or (at your option) any later version.
7 #
8 # Acrobat is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with Acrobat; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
16 # USA.
17
18 # Andrew Walkingshaw <andrew@lexical.org.uk>
19 # Peter Corbett <ptc24@cam.ac.uk>
20 # Matthew Vernon <matthew@debian.org>
21 # Stephen Early <steve@greenend.org.uk>
22 # Richard Kettlewell <rjk@greenend.org.uk
23
24 # Acrobat configuration file
25
26 # The following definitions are required to be present in this module:
27 server = "irc.nsict.org"
28 port = 6667
29 nickname = "Servus"
30 channel = "#artichoke"
31 owner = "Emperor"
32 # Also a function called "command"; see later.
33
34 # Everything else in this file is configuration-specific.
35
36 import os, time
37
38 # Most command implementations are stored in a separate module.
39 import commands as c
40
41 # This fishpond is shared between trouts and flirts.  It doesn't have to be;
42 # you can define as many ponds as you like.
43 class fish (c.FishPond):
44         cur_fish=5
45         max_fish=5
46         nofish_time=60
47         fish_time_inc=60
48         fish_inc=2
49         Boring_Git='Nobody'
50
51 # load a file full of flirts or trouts
52 def __load(filename):
53     try:
54         f = open(filename, "r")
55         r = [l.strip() for l in f.readlines() if l.find("%s") != -1]
56         f.close()
57     except IOError:
58         r = [ "doesn't know what to do about %s." ]
59     return r
60
61 # (troutlist,selftroutmsg,DoSmsg,notargetmsg,nofishmsg,fishpond,selftroutprob)
62 troutcfg = (
63         __load("trouts"),
64         ' (at the instigation of %s)',
65         "Sorry, but %s is being a spoilsport.",
66         "Who do you wish me to trout?",
67         "Fish stocks exhausted.",
68         fish,
69         0.1)
70
71 flirtcfg = (
72         __load("flirts"),
73         ' (but %s is their secret admirer)',
74         "Sorry, but %s made me take Holy Orders.",
75         "Who do you wish me to flirt with?",
76         "My libido is over-used!",
77         fish,
78         0.1)
79
80 slashcfg= ( 
81         __load("slashes"),
82         ' (while %s watches)',
83         "Sorry, but %s stole my pen.",
84         "Who do you want to slash?",
85         "I have writer's block!",
86         fish,
87         0.1)
88
89 # Hacky command to output the current fishpond state
90 def fishq(bot, cmd, nick, conn, public,f):
91         from irclib import irc_lower
92         if not public and irc_lower(nick) == irc_lower(bot.owner):
93                 state=("Fishpond state: cur_fish=%d, max_fish=%d, nofish_time=%d, "
94                        +"fish_time_inc=%d, fish_inc=%d, DoS=%d, Boring_Git=%s, "
95                        +"quotatime=%d")%(f.cur_fish,f.max_fish,f.nofish_time,
96                                          f.fish_time_inc,f.fish_inc,f.DoS,f.Boring_Git,
97                                          f.quotatime)
98                 bot.automsg(public,nick,state)
99                     
100 # Karma implementation
101 import cPickle
102 karmafilename = "artichoke-karma"
103 # load the karma db
104 try:
105     f = open(karmafilename, "r")
106     karmadb = cPickle.load(f)
107     f.close()
108 except IOError:
109     karmadb = {}
110 # Modify karma
111 def karma(cmd, amount):
112     thing=cmd.split()[0][:-2].lower()
113     if karmadb.has_key(thing):
114         karmadb[thing] += amount
115     else:
116         karmadb[thing] = amount
117     savekarma()
118 def savekarma():
119     tmp = "%s.tmp" % karmafilename
120     try:
121         f = open(tmp, "w")
122         cPickle.dump(karmadb, f)
123         f.close()
124         os.rename(tmp, karmafilename)
125     except IOError, e:
126         sys.stderr.write("error writing karma: %s" % e)
127
128 def quit(bot,cmd,nick,conn,public):
129     c.quitq(bot,cmd,nick,conn,public)
130 def reload(bot,cmd,nick,conn,public):
131     c.reloadq(bot,cmd,nick,conn,public)
132
133 #The game...
134 class game:
135         trigger="Servus"
136         grace=time.time()
137         minlose=24*60*60 #1 day
138         maxlose=14*minlose #2 weeks
139         losetime=time.time()+300000
140
141 # Command processing: whenever something is said that the bot can hear,
142 # "command" is invoked and must decide what to do.  This configuration
143 # defines a couple of special cases (for karma) but is otherwise driven
144 # by a dictionary of commands.
145
146 commands = {"karma": (c.karmaq,karmadb),
147             "karmalist": (c.listkeysq,karmadb),
148             "karmadel": (c.karmadelq,karmadb),
149             "info": (c.infoq,karmadb),
150             "trout": (c.troutq,troutcfg),
151             "slash": (c.slashq, slashcfg),
152             "rot13": c.rot13q,
153             "fish": (fishq,fish),
154             "flirt": (c.troutq,flirtcfg),
155             "quiet": (c.nofishq,fish),
156             "reload": reload,
157             "quit": quit,
158             "die": quit,
159             "google": c.googleq,
160 #           "define": c.defineq,
161 #           "game": (c.gameq,game),
162             "say": c.sayq,
163             "do": c.doq }
164 # disconnect and hop annoy people
165 #            "disconnect": c.disconnq,
166 #            "hop": c.disconnq }
167 commands["list"]=(c.listkeysq,commands)
168
169 triggers = ("!", "~") # what character should the bot be invoked by:
170                       # eg !trout, ~trout etc.
171
172 def command(bot, cmd, nick, conn, public):
173     ours=0
174     try:
175             if public and cmd[0] in triggers:
176                     ours=1
177                     cmd=cmd[1:]
178             if not public:
179                     ours=1
180             command = cmd.split()[0]
181     except IndexError:
182             command=""
183     # karma: up
184     if command.endswith("++"):
185         karma(cmd,1)
186     # karma: down
187     if command.endswith("--"):
188         karma(cmd,-1)
189
190     if ours and command.lower() in commands.keys():
191         e=commands[command.lower()]
192         if callable(e):
193             e(bot,cmd,nick,conn,public)
194         else:
195             e[0](bot,cmd,nick,conn,public,*e[1:])
196 #    elif public:
197 #        if cmd.find("GAME")!=-1: #someone else lost
198 #           grace.grace=time.time()+60*20
199 #       elif cmd.find(game.trigger)!=-1 and len(game.trigger)>2: #we lost!
200 #           c.gameq(bot,"pad "+game.trigger,bot.owner,conn,False,game)
201 #       elif time.time()>game.losetime: #we randomly lost, take new trigger
202 #           c.gameq(bot,cmd,bot.owner,conn,False,game)
203 #