import sys import socket import string import os import irclib from constants import * # twisted imports from twisted.protocols import irc from twisted.internet import reactor, protocol from twisted.python import log #######log test #class FakeLog(object): #def flush(self): #return #def close(self): #return #def write(self, s): #return ##class ChannelLogger(callbacks.Plugin): #noIgnore = True #def __init__(self, irc): #self.__parent = super(ChannelLogger, self) #self.__parent.__init__(irc) #self.lastMsgs = {} #self.lastStates = {} #self.logs = {} #world.flushers.append(self.flush) #def die(self): #for log in self._logs(): #log.close() #world.flushers = [x for x in world.flushers #if hasattr(x, 'im_class') and #x.im_class is not self.__class__] #def __call__(self, irc, msg): #try: ## I don't know why I put this in, but it doesn't work, because it ## doesn't call doNick or doQuit. ## if msg.args and irc.isChannel(msg.args[0]): #self.__parent.__call__(irc, msg) #if irc in self.lastMsgs: #if irc not in self.lastStates: #self.lastStates[irc] = irc.state.copy() #self.lastStates[irc].addMsg(irc, self.lastMsgs[irc]) #finally: ## We must make sure this always gets updated. #self.lastMsgs[irc] = msg #def reset(self): #for log in self._logs(): #log.close() #self.logs.clear() #self.lastMsgs.clear() #self.lastStates.clear() #def _logs(self): #for logs in self.logs.itervalues(): #for log in logs.itervalues(): #yield log #def flush(self): #self.checkLogNames() #for log in self._logs(): #try: #log.flush() #except ValueError, e: #if e.args[0] != 'I/O operation on a closed file': #self.log.exception('Odd exception:') #def logNameTimestamp(self, channel): #format = self.registryValue('filenameTimestamp', channel) #return time.strftime(format) #def getLogName(self, channel): #if self.registryValue('rotateLogs', channel): #return '%s.%s.log' % (channel, self.logNameTimestamp(channel)) #else: #return '%s.log' % channel #def getLogDir(self, irc, channel): #logDir = conf.supybot.directories.log.dirize(self.name()) #if self.registryValue('directories'): #if self.registryValue('directories.network'): #logDir = os.path.join(logDir, irc.network) #if self.registryValue('directories.channel'): #logDir = os.path.join(logDir, channel) #if self.registryValue('directories.timestamp'): #format = self.registryValue('directories.timestamp.format') #timeDir =time.strftime(format) #logDir = os.path.join(logDir, timeDir) #if not os.path.exists(logDir): #os.makedirs(logDir) #return logDir #def checkLogNames(self): #for (irc, logs) in self.logs.items(): #for (channel, log) in logs.items(): #if self.registryValue('rotateLogs', channel): #name = self.getLogName(channel) #if name != log.name: #log.close() #del logs[channel] #def getLog(self, irc, channel): #self.checkLogNames() #try: #logs = self.logs[irc] #except KeyError: #logs = ircutils.IrcDict() #self.logs[irc] = logs #if channel in logs: #return logs[channel] #else: #try: #name = self.getLogName(channel) #logDir = self.getLogDir(irc, channel) #log = file(os.path.join(logDir, name), 'a') #logs[channel] = log #return log #except IOError: #self.log.exception('Error opening log:') #return FakeLog() #def timestamp(self, log): #format = conf.supybot.log.timestampFormat() #if format: #log.write(time.strftime(format)) #log.write(' ') #def normalizeChannel(self, irc, channel): #return ircutils.toLower(channel) #def doLog(self, irc, channel, s, *args): #s = format(s, *args) #channel = self.normalizeChannel(irc, channel) #log = self.getLog(irc, channel) #if self.registryValue('timestamp', channel): #self.timestamp(log) #if self.registryValue('stripFormatting', channel): #s = ircutils.stripFormatting(s) #log.write(s) #if self.registryValue('flushImmediately'): #log.flush() #def doPrivmsg(self, irc, msg): #(recipients, text) = msg.args #for channel in recipients.split(','): #if irc.isChannel(channel): #noLogPrefix = self.registryValue('noLogPrefix', channel) #if noLogPrefix and text.startswith(noLogPrefix): #text = '-= THIS MESSAGE NOT LOGGED =-' #nick = msg.nick or irc.nick #if ircmsgs.isAction(msg): #self.doLog(irc, channel, #'* %s %s\n', nick, ircmsgs.unAction(msg)) #else: #self.doLog(irc, channel, '<%s> %s\n', nick, text) #def doNotice(self, irc, msg): #(recipients, text) = msg.args #for channel in recipients.split(','): #if irc.isChannel(channel): #self.doLog(irc, channel, '-%s- %s\n', msg.nick, text) #def doNick(self, irc, msg): #oldNick = msg.nick #newNick = msg.args[0] #for (channel, c) in irc.state.channels.iteritems(): #if newNick in c.users: #self.doLog(irc, channel, #'*** %s is now known as %s\n', oldNick, newNick) #def doJoin(self, irc, msg): #for channel in msg.args[0].split(','): #self.doLog(irc, channel, #'*** %s has joined %s\n', #msg.nick or msg.prefix, channel) #def doKick(self, irc, msg): #if len(msg.args) == 3: #(channel, target, kickmsg) = msg.args #else: #(channel, target) = msg.args #kickmsg = '' #if kickmsg: #self.doLog(irc, channel, #'*** %s was kicked by %s (%s)\n', #target, msg.nick, kickmsg) #else: #self.doLog(irc, channel, #'*** %s was kicked by %s\n', target, msg.nick) #def doPart(self, irc, msg): #for channel in msg.args[0].split(','): #self.doLog(irc, channel, #'*** %s has left %s\n', msg.nick, channel) #def doMode(self, irc, msg): #channel = msg.args[0] #if irc.isChannel(channel) and msg.args[1:]: #self.doLog(irc, channel, #'*** %s sets mode: %s %s\n', #msg.nick or msg.prefix, msg.args[1], #' '.join(msg.args[2:])) #def doTopic(self, irc, msg): #if len(msg.args) == 1: #return # It's an empty TOPIC just to get the current topic. #channel = msg.args[0] #self.doLog(irc, channel, #'*** %s changes topic to "%s"\n', msg.nick, msg.args[1]) #def doQuit(self, irc, msg): #if not isinstance(irc, irclib.Irc): #irc = irc.getRealIrc() #for (channel, chan) in self.lastStates[irc].channels.iteritems(): #if msg.nick in chan.users: #self.doLog(irc, channel, '*** %s has quit IRC\n', msg.nick) #def outFilter(self, irc, msg): ## Gotta catch my own messages *somehow* :) ## Let's try this little trick... #if msg.command in ('PRIVMSG', 'NOTICE'): ## Other messages should be sent back to us. #m = ircmsgs.IrcMsg(msg=msg, prefix=irc.prefix) #self(irc, m) #return msg ##Class = ChannelLogger ## vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: ###########end log test #######################2nd log test :P def ctcp(s): return '\x01%s\x01' % s def me(s): return ctcp('ACTION %s' % s) global people people = {} global channels channels = [] # channels that this bot's on import os, os.path global directories directories = [] for entry in os.listdir(os.getcwd()): if os.path.isdir(entry): directories.append(entry) def log(channel, text): fn = time.strftime('%Y-%m-%d.log', time.gmtime(time.time())) if channel not in directories: os.mkdir(channel) # if it fails, the exception may as well be raised directories.append(channel) if TimeStamp: t = time.strftime('[%H:%M]', time.gmtime(time.time())) text = t + ' ' + text text += '\n' open(os.path.join(channel, fn), 'a').write(text) def main(hostName, port, chan): c = ircAsync.T() c.startChannels(chan) c.nick = NickName c.userid = 'logger' # Put any new functions here def hi(m, origin, args, text, c=c): c.tell(args[1], 'hi, %s' % origin.split('!')[0]) c.bind(hi, PRIVMSG, r"(?i)^(Hi|Hey|welcome)(,)? %s(\!)?$" % NickName) def logText(m, origin, args, text, c=c): channel = args[1] nick = origin if '!' in origin: nick = origin.split('!')[0] if not (text.startswith('\x01ACTION ') and text.endswith('\x01')): text = _text % (nick, text) else: text = _action % (nick, text[8:-1]) try: if not text[text.index(' ')+1:].startswith('[off]'): log(channel, text) except ValueError: log(channel, text) c.bind(logText, PRIVMSG, r"(.*)") def logTopic(m, origin, args, text, c=c): channel = args[1] nick = origin if '!' in origin: nick = origin.split('!')[0] topic = _topic % (nick, text) log(channel, topic) c.bind(logTopic, 'TOPIC', r"(.*)") def logMode(m, origin, args, text, c=c): channel = args[1] nick = origin if '!' in origin: nick = origin.split('!')[0] mode = _mode % (nick, ' '.join(args[2:])) log(channel, mode) c.bind(logMode, 'MODE', r"(.*)") def logJoin(m, origin, args, text, c=c): channel = text nick = origin if '!' in origin: nick = origin.split('!')[0] if nick == NickName: if channel not in channels: channels.append(channel) t = time.strftime('%a %b %d %H:%M:%S %Y', time.gmtime(time.time())) log(channel, "Session Start: %s" % t) log(channel, "Session Ident: %s" % channel) join = _join % (nick, channel) log(channel, join) if people.has_key(nick): if channel not in people[nick]: people[nick].append(channel) else: people[nick] = [channel] c.bind(logJoin, 'JOIN', r"(.*)") def logNames(m, origin, args, text, c=c): channel = args[3] raw_nicks = text.split(' ') for nick in raw_nicks: if nick.startswith('@') or nick.startswith('+'): nick = nick[1:] if people.has_key(nick): if channel not in people[nick]: people[nick].append(channel) else: people[nick] = [channel] c.bind(logNames, '353', r"(.*)") def logPart(m, origin, args, text, c=c): if nick == NickName: if channel in channels: channels.remove(channel) channel = args[1] nick = origin if '!' in origin: nick = origin.split('!')[0] part = _part % (nick, text) log(channel, part) try: people[nick].remove(channel) except: print >> sys.stderr, "Something messed up, but it doesn't matter" c.bind(logPart, 'PART', r"(.*)") def logQuit(m, origin, args, text, c=c): nick = origin if '!' in origin: nick = origin.split('!')[0] quit = _quit % (nick, text) if people.has_key(nick): for channel in people[nick]: log(channel, quit) del people[nick] c.bind(logQuit, 'QUIT', r"(.*)") def logKick(m, origin, args, text, c=c): if nick == NickName: if channel in channels: channels.remove(channel) channel = args[1] nick = origin if '!' in origin: nick = origin.split('!')[0] kickee = args[2] kick = _kick % (kickee, nick, text) log(channel, kick) try: people[nick].remove(channel) except: print >> sys.stderr, "Something messed up, but it doesn't matter" c.bind(logKick, 'KICK', r"(.*)") def logNick(m, origin, args, text, c=c): old = origin if '!' in origin: old = origin.split('!')[0] new = text nick = _nick % (old, new) if people.has_key(old): for channel in people[old]: log(channel, nick) people[new] = people[old] del people[old] c.bind(logNick, 'NICK', r"(.*)") c.makeConn(hostName, port) try: asyncore.loop() except: t = time.strftime('%a %b %d %H:%M:%S %Y', time.gmtime(time.time())) for channel in channels: log(channel, "Session Close: %s" % t) sys.exit(0) if __name__=='__main__': if len(sys.argv) > 2: server, chans = sys.argv[1], sys.argv[2:] chans = [('#%s' % c, c)[c.startswith('#')] for c in chans] if ':' in server: server, port = server.split(':') else: port = '6667' main(server, int(port), chans) else: print __doc__ ###################end 2nd log test # Generic echo handler ( space added ) # This is used to output some initial information from the server def handleEcho ( connection, event ): print print ' '.join ( event.arguments() ) irc = irclib.IRC() irc.add_global_handler ( 'welcome', handleEcho ) #def send(self, to, msg): # """Sends a message "msg" to "to" """ # s.send('PRIVMSG %s :%s\r\n' % (to, msg)) def make_log(s): ''' function to parse logs into HTML, post them, and modify the log index accordingly ''' title=time.strftime('%A, %B %d %Y', time.gmtime(time.time())) # make sure we're making a new file and not overwriting an old one fn = 'file' if os.path.exists(fn+'.html'): num = 1 while os.path.exists(fn+'.html'): num += 1 prev = fn fn = 'file'+str(num) # see if we have a log entry for this already description = '

%s

' % (fn, title) index = open('IRCIntoLog.html').read() if index.count(title): fn = prev else: # add entry to log index (IRCIntoLog on the site) index = '\n'.join([index[:index.rfind('

')+4], description, index[index.rfind('

')+4:]]) open('IRCIntoLog.html', 'w').write(index) # add HTML header html = ''' %s
(home | about | stats)

%s

''' % (title, title, title) # add all lines of the log as HTML paragraphs (so that we have line breaks) html += '\n'.join(['

%s

' % string.replace(escape(line),'}', '}}') for line in s.split('\n')]) # add HTML footer html += '''
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-6s %(message)s', filename=NICK+'.log') log = logging.getLogger()
BlazeOfGlory.org. This is a pwyky site. Edit this document.
''' % fn[:-5] # write finished HTML to file open(fn+'.html', 'w').write(html) def command(cmd): ''' commands function for control via IRC ''' if cmd.startswith('BOT: '): cmd = cmd[len('BOT: '):].split() if cmd[0] == OWNER: if not cmd[1] in variables.admins: variables.admins.append(cmd[1]) elif cmd[0] == 'start': variables.logging = True elif cmd[0] == 'stop': variables.logging = False elif cmd[0] == 'ban': if cmd[1] in variables.admins and cmd[1] <> 'mcferrill': variables.admins.remove(cmd[1]) elif cmd[0] == 'post': make_log(variables.log) elif cmd[0] == 'reset': variables.log = '' def sendresponse(self, to, msg, nick): """Personalized version of send.""" msg = msg.replace('[nick]', nick) s.send('PRIVMSG %s :%s\r\n' % (to, msg)) def parsemsg(msg): complete=msg[1:].split(':',1) info=complete[0].split(' ') msgpart=complete[1] sender=info[0].split('!') if msgpart[0]=='`' and sender[0]==OWNER: cmd=msgpart[1:].split(' ') if cmd[0]=='op': s.send('MODE %s +o %s \n' % (info[2], cmd[1])) if cmd[0]=='deop': s.send('MODE %s -o %s \n' % (info[2], cmd[1])) if cmd[0]=='voice': s.send('MODE %s +v %s \n' % (info[2], cmd[1])) if cmd[0]=='devoice': s.send('MODE %s -o %s \n' % (info[2], cmd[1])) if cmd[0]=='sys': syscmd(msgpart[1:],info[2]) if msgpart[0]=='-' and sender[0]==OWNER : cmd=msgpart[1:] s.send(cmd, '\n') print 'cmd= %s' % (cmd) if msgpart[0]=='@': print msgpart cmd=msgpart[1:].strip( ) channel=info[2] factoids(cmd,channel,sender) def factoids(cmd,channel,sender): print cmd reply = "I have no idea what you're talking about" if cmd == 'ping': reply = 'pong' if cmd == 'info': reply = "I am the beginners-help channel bot. Beware the mighty power of the boot" if cmd == 'cbf': reply = 'TOO BAD! DO IT!!' if cmd == 'pacman': reply = 'OM NOM NOM NOM! I EAT YOU!' if cmd == 'help': reply = 'ajmorris, Joeb454, bodhi_zazen, attention please!' if cmd == 'help!': reply = 'ajmorris, Joeb454, bodhi_zazen, attention please!' if cmd == 'run': reply = '[nick], im coming to eat you!' if cmd == 'you suck': reply = 'no you do %s\r\n' % (NICKS) if cmd == 'ohmy': reply = 'Please watch your language and topic to help keep this channel family friendly.' if cmd == 'microsoft': reply = 'Microsoft is bad, VERY BAD. END OF DISCUSSION!' if cmd == 'pastebin': reply = 'pastebin is a service to post multiple-lined texts so you do not flood the channel. One of the many is located at http://www.pastebin.ca' if cmd == 'insult': reply = '[nick], You are nothing but a weedy ooze of penguin-molesting bladders.' if cmd.find('join')!=-1 and sender[0] == OWNER: chan = cmd.split(' ') chan = chan[1] s.send('JOIN %s\r\n' % (chan)) reply = 'done' if cmd.find('kick')!=-1 and sender[0] == OWNER: print cmd s.send('KICK %s\r\n' % (NEEDTODEFINE)) reply = 'with pleasure' if cmd.find('cs')!=-1 and sender[0] == OWNER: #cmd = cmd.split(' ') print cmd s.send('PRIVMSG ChanServ :OP %s\r\n' % (CHAN)) reply = 'I feel the power!' if cmd.find('op')!=-1 and sender[0] == OWNER: print cmd s.send('OP %s\r\r' % (NEEDTODEFINE)) reply = 'if i must' if cmd.find('identify')!=-1 and sender [0] == OWNER: cmd = cmd.split('_') print cmd s.send('PRIVMSG NickServ: IDENTIFY %s\r\n' % (PASS)) s.send('PRIVMSG %s :%s\n' % (channel, reply)) def syscmd(commandline,channel): cmd=commandline.replace('sys ',' ') cmd=cmd.rstrip() os.system(cmd+' >temp.txt') a=open('temp.txt') ot=a.read() ot.replace('n','|') a.close() s.send('PRIVMSG %s :%s\n' % (channel, ot)) return 0 #Connection s=socket.socket( ) s.connect((HOST, PORT)) s.send('NICK %s \n' % (NICK)) #Tells nick server nickname s.send('USER %s %s bla : %s \n' % (IDENT, HOST, REALNAME)) #Tells user Identity, current host, and actual name s.send('PRIVMSG NickServ :IDENTIFY %s\r\n' % (PASS)) s.send('PRIVMSG ChanServ :OP %s\r\n' % (CHAN)) while 1: #While True line=s.recv(500) print line # I believe this is for the bot owners information. It doesn't send anything to chatroom if line.find('Welcome to the freenode IRC Network')!=-1: #If any line says this it will join the channel(s) put in CHAN s.send('JOIN %s \n' % (CHAN)) if line.find('PRIVMSG')!=-1: # For private messaging, I do not know how this works parsemsg(line)