So if you've been on the irc, I've used a few languages for making my Comando bots.
I made Comando in SCAR, then Java, now Pymando. So I thought as with any Python program, I'd conform to the status quo naming scheme and start with a Py, hence the Pymando. (There were actually like 4 Comando's in java, including one that used python scripts as commands. Really nasty >.<)
I know a lot of the code isnt very 'python-ish,' so its a work-in-progress.
I've gotten it to the point where I think its ok to release or just show off
This is the core file
python Code:
import os.path
import os
import socket
# Its best not to touch this file. This is the core file, it loads the config,
# contains the variables, runs the bot loop, etc
#Information to be used to connect to the server and manage the bot
loaded_info = {'nick':'', 'pass':'', 'realname':'', 'server':'', 'port':6667, 'channels':[],
'keys':'', 'safe_mode': True, 'essentials_location':'', 'scripts_directory':'',
'core_location':'', 'home_directory':'', 'essentials_directory':'',
'config_location':'', 'scripts_locations':[], 'scripts':{}, 'admin_list':'',
'message_ping':False, 'quit':False}
coms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# This is actually what sends and recieves the data from the irc server.
bot = {'raw_input':'', 'sender_nick':'', 'sender_host':'', 'sender_type':'',
'sender_channel':'', 'sender_message':'', 'in_admin_list':False}
def get_directories():
#Get all the necessary directories.
loaded_info['core_location'] = os.path.abspath(__file__)
delimeter = '/' if os.name == 'posix' else '\\'
location = loaded_info['core_location'].split(delimeter)[:-2]#remove the file name and the top directory
loaded_info['home_directory']+delimeter
for x in location:
loaded_info['home_directory']+=x+delimeter
loaded_info['scripts_directory'] = loaded_info['home_directory'] +'scripts/'
loaded_info['essentials_directory'] = loaded_info['home_directory'] +'essentials/'
loaded_info['config_location'] = loaded_info['home_directory']+'config'
def get_script_locations():
#Obviously gets the scripts locatations that are in the essentials and in the scripts folder...
loaded_info['scripts_locations'] = [loaded_info['essentials_directory'] + x for x in os.listdir(loaded_info['essentials_directory'])]
loaded_info['scripts_locations'] += [loaded_info['scripts_directory'] + x for x in os.listdir(loaded_info['scripts_directory'])]
def store_scripts():
"""
This uses the info that was obtained from get_scripts_locations() and reads
the files and loads the scripts into a dictionary for quick and easy execution. Much faster to exec() than to execfile()?
"""
s = ''
for i in range(len(loaded_info['scripts_locations'])):
for lines in open(loaded_info['scripts_locations'][i]):
s += lines # remove the /..dir/ and .py from the script location so we can just keep the name
loaded_info['scripts'].update({loaded_info['scripts_locations'][i][loaded_info['scripts_locations'][i].rindex('/')+1:loaded_info['scripts_locations'][i].rindex('.')]:s})
s = ''
def execute_script(name):
#Run the script from the dictionary.
if loaded_info['safe_mode']:
try:
exec(loaded_info['scripts'][name.strip('\n\r')])
except Exception, e:
print 'Executing script, '+name.strip('\n\r')+', failed!'
print e
else:
exec(loaded_info['scripts'][name.strip('\n\r')])
def send(content):
coms.send(content + "\n")
def say(channel, content):
send('PRIVMSG '+channel+' :'+content)
def bot_loop():
get_directories()
get_script_locations()
store_scripts()
execute_script('parse_config')
execute_script('connect')
execute_script('identify')
for i in range(len(loaded_info['channels'])):
send('JOIN '+loaded_info['channels'][i])
while True:
bot['raw_input'] = coms.recv(1024).strip('\n\r')
print bot['raw_input']
execute_script('check_ping')
if not loaded_info['message_ping']:
execute_script('parse_message')
execute_script('check_others')
execute_script('analyze_message')
loaded_info['message_ping'] = False
if loaded_info['quit']: break
if __name__ == "__main__":
bot_loop()
There is a config file in there, obviously named config. It's kind of strict atm, so dont have blank lines. Just fill out whats there.
The naming for the variables is pretty simple. Whenever a message is parsed it goes into the dictionary bot. A ton of info is stored in the loaded_info dictionary.
if you want to see what somebody said, its located in bot['sender_message'], the nick of the sender is in bot['sender_nick'].
The bot scripts are in a dictionary. loaded_info['scripts'] is a dictionary as well. When a command is called in the chat, the core file will search in the dictionary. So like, loaded_info['scripts']['temperature'].
bot['in_admin_list'] is a boolean set when the message gets parsed. If the sender of the message is an 'admin' in the bot, it gets set to True.
bot['sender_type'] is for the type of message parsed. Is it a PRIVMSG, NOTICE, etc.
To add a script, put it in the pymando/scripts directory and have a .py at the end.
If you want to a change a script while the bot is connected to the server, call !reload. This works with everything except the core file, which in pymando/src/pymando.py
So far I've only setup ctcp version setup. If you want to expand that, its in pymando/essentials/check_others.py
Remember this is still pretty primitive, and this is my first attempt at python.
Everything is located in the Zip file attached below.
Feed back?