3
\$\begingroup\$

I'm looking to see if there is anything in this I could have done better or see if could have structured the code better. Here is the project on GitHub.

import socket
import string
import sys
import os
path = "plugins/"
plugins = []
# Load plugins
sys.path.insert(0, path)
for f in os.listdir(path):
 fname, ext = os.path.splitext(f)
 if ext == '.py':
 mod = __import__(fname)
 plugins.append(getattr(mod, fname))
sys.path.pop(0)
class IRC_Client(object):
 """docstring for IRC_Client"""
 sock = ""
 def __init__(self, ircserver, ircnicklist, ircident, ircrealname,
 ircchanlist, nickpassword=None, ircport=6667):
 super(IRC_Client, self).__init__()
 if not isinstance(ircnicklist, list):
 raise TypeError("nicklist is not an instance of list")
 elif not isinstance(ircchanlist, list):
 raise TypeError("chanlist is not an instance of list")
 self.ircnicklist = ircnicklist
 self.ircident = ircident
 self.ircrealname = ircrealname
 self.ircchanlist = ircchanlist
 self.ircserver = ircserver
 self.ircport = ircport
 self.nickpassword = nickpassword
 def createconnection(self):
 self.sock = socket.socket()
 self.sock.connect((self.ircserver, self.ircport))
 def sendmessage(self, sender, message):
 sent = "PRIVMSG %s :%s\r\n" % (sender, message)
 self.sock.send(sent)
 def sendpong(self, sender):
 sent = "PONG %s\r\n" % sender
 self.sock.send(sent)
 def sendnotice(self, sender, message):
 sent = "NOTICE %s :%s\r\n" % (sender, message)
 self.sock.send(sent)
 def sendctcp(self):
 pass
 def setnick(self, nick):
 self.sock.send("NICK %s\r\n" % nick)
 def joinchannel(self, channel):
 self.sock.send("JOIN %s\r\n" % channel)
 def getusernick(self, serverbuffer):
 usernick = serverbuffer[0].split("!")
 usernick = usernick[0].replace(":", "")
 return usernick
 def getusermessage(self, serverbuffer):
 message = ""
 if len(serverbuffer) >= 4:
 serverbuffer[3] == serverbuffer[3][1:]
 for i in range(3, len(serverbuffer)):
 message += serverbuffer[i] + " "
 return message
 def getchannel(self, serverbuffer):
 if len(serverbuffer):
 return serverbuffer[2]
 def serverreplies(self, serverbuffer):
 serverbuffer = string.split(string.rstrip(serverbuffer))
 if serverbuffer[0].lower() == 'ping':
 self.sendpong(serverbuffer[0])
 if serverbuffer[1] == "431":
 print "No nick was given"
 exit()
 if serverbuffer[1] == "432":
 print "Erroneus nick"
 exit()
 if serverbuffer[1] == "433":
 if len(self.ircnicklist) != 0:
 self.setnick(self.ircnicklist.pop())
 else:
 raise IndexError("All nicks from nicklist are in use")
 for channel in self.ircchanlist:
 self.joinchannel(channel)
 def commandparser(self, line):
 line = string.split(string.rstrip(line.lower()))
 if (len(line) >= 4 and line[1] == 'privmsg'):
 map(lambda command: command(self, line), plugins)
 def connect(self):
 self.createconnection()
 self.setnick(self.ircnicklist[0])
 self.sock.send("USER %s %s bla :%s\r\n"
 % (self.ircident, self.ircserver, self.ircrealname))
 if not self.nickpassword:
 pass
 else:
 self.sock.send("PASS %s\r\n" % self.nickpassword)
 for channel in self.ircchanlist:
 self.joinchannel(channel)
 def loop(self):
 readbuffer = ""
 while 1:
 readbuffer = self.sock.recv(1024)
 temp = string.split(readbuffer, "\n")
 readbuffer = temp.pop()
 for line in temp:
 print line
 self.serverreplies(line)
 self.commandparser(line)
 logger(self, line)
 def runclient(self):
 self.connect()
 self.loop()
def logger(ircclientinstance, serverbuffer):
 serverbuffer = string.split(string.rstrip(serverbuffer))
 if serverbuffer[1].lower() == "privmsg":
 if serverbuffer[2] in ircclientinstance.ircchanlist:
 filename = ("%s.log" % serverbuffer[2])
 f = open(filename, 'a+')
 f.write("<%s>%s\n" % (ircclientinstance.getusernick(
 serverbuffer), ircclientinstance.getusermessage(serverbuffer)))
 f.close()
 else:
 filename = ("%s.log" % ircclientinstance.getusernick(serverbuffer))
 f = open(filename, 'a+')
 f.write("<%s>%s\n" % (ircclientinstance.getusernick(
 serverbuffer), ircclientinstance.getusermessage(serverbuffer)))
 f.close()
if __name__ == "__main__":
 # TODO: config file? maybe
 mybot = IRC_Client('irc.freenode.net', ['swaglorde', 'swaglordeh'], 'swaglorde', 
 'swaglorde', ['#dtest'])
 mybot.runclient()

Example of a plugin:

I am thinking about converting my plugin system to a class based system. I am also not sure if it would better, but I do have a bit of code I am reusing with every plugin.

import requests
def showInfo(tvname):
 tvname = tvname.replace(' ', '+')
 tvinfo = requests.get(
 "http://services.tvrage.com/tools/quickinfo.php?show=" + tvname).text
 try:
 tvdata = tvinfo.split('\n')
 tvinfo = []
 for data in tvdata:
 data = data.split('@')
 tvinfo.append(data)
 return tvinfo
 except:
 return None
def next(ircclientinstance, serverbuffer):
 commandname = 'next'
 commands = {':!': True, ':.': False, ':@': True}
 # This needs to be included in all plugins that take arguements
 commandarguements = ""
 parseargs = serverbuffer[3:][1:]
 for x in parseargs:
 commandarguements += x.strip() + " "
 if commandarguements == '':
 output = "No info found :3"
 else:
 try:
 tvinfo = showInfo(commandarguements)
 output = "[%s] :: [Next: %s] [Airs: %s]" % (
 tvinfo[1][1], tvinfo[7][1].replace('^', ' '), tvinfo[15][1])
 except:
 output = "No info found :3"
 # this needs to be included with all plugins
 if serverbuffer[3][2:] == commandname:
 if serverbuffer[3][:2] in commands:
 notice = commands.get(serverbuffer[3][:2])
 if not notice:
 if serverbuffer[1] == "privmsg":
 if serverbuffer[2] in ircclientinstance.ircchanlist:
 ircclientinstance.sendmessage(serverbuffer[2], output)
 else:
 ircclientinstance.sendmessage(
 ircclientinstance.getusernick(serverbuffer), output)
 else:
 ircclientinstance.sendnotice(
 ircclientinstance.getusernick(serverbuffer), output)
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 5, 2014 at 16:30
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

A few comments regarding the main code:

  • Try to order imports alphabetically
  • Use underscores to separate words in method names (createconnection -> create_connection, sendmessage, send_message, etc.)
  • Use class attributes instead of hardcded constants ("431" -> self.ERR_NONICKNAMEGIVEN, "432" -> self.ERR_ERRONEUSNICKNAME, etc.)
  • Use if/elif/elif instead of if/if/if to avoid unnecessary checks
  • Use the logging module instead of print statements.
  • To check if a list is not empty use just the list name self.ircnicklist instead of len(self.ircnicklist) != 0
  • Review exception types. Is IndexError really appropriate when there are no more elements in the list?l
  • Prefer to use list comprehensions instead of map
  • Remove pass if isn't really useful. Instead of:

    if not self.nickpassword:
     pass
    else:
     self.sock.send("PASS %s\r\n" % self.nickpassword)
    

    write:

    if self.nickpassword:
     self.sock.send("PASS %s\r\n" % self.nickpassword)
    
  • Instead of while 1 use while True

  • Use context managers to open and close files. Instead of:

    f = open(filename, 'a+')
    f.write("<%s>%s\n" % (ircclientinstance.getusernick(
     serverbuffer), ircclientinstance.getusermessage(serverbuffer)))
    f.close()
    

    write:

    with open(filename, 'a+') as f:
     f.write("<%s>%s\n"
     % (ircclientinstance.getusernick(serverbuffer),
     ircclientinstance.getusermessage(serverbuffer)))
    

I hope this helps.

answered Aug 5, 2014 at 22:48
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.