mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-30 14:49:28 +01:00
It's almost June! Updates:
- Move config handling into separate module - Implement identify and status commands, currently only supporting the admin account defined in the config. Closes #1. - Move proto.add_cmd to utils.py, rename _msg() to msg() - Allow sending the command name as an optional argument in add_cmd - Add catch-all exception handling in plugins to prevent them from crashing the program!
This commit is contained in:
parent
0e53a0fee4
commit
d9db7e1b9e
5
conf.py
Normal file
5
conf.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import yaml
|
||||||
|
|
||||||
|
with open("config.yml", 'r') as f:
|
||||||
|
global conf
|
||||||
|
conf = yaml.load(f)
|
14
main.py
14
main.py
@ -1,20 +1,17 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import yaml
|
|
||||||
import imp
|
import imp
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from conf import conf
|
||||||
import proto
|
import proto
|
||||||
print('PyLink starting...')
|
|
||||||
|
|
||||||
with open("config.yml", 'r') as f:
|
if conf['login']['password'] == 'changeme':
|
||||||
conf = yaml.load(f)
|
print("You have not set the login details correctly! Exiting...")
|
||||||
|
sys.exit(2)
|
||||||
# if conf['login']['password'] == 'changeme':
|
|
||||||
# print("You have not set the login details correctly! Exiting...")
|
|
||||||
|
|
||||||
class Irc():
|
class Irc():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -74,5 +71,6 @@ class Irc():
|
|||||||
self.loaded.append(imp.load_source(plugin, moduleinfo[1]))
|
self.loaded.append(imp.load_source(plugin, moduleinfo[1]))
|
||||||
print("loaded plugins: %s" % self.loaded)
|
print("loaded plugins: %s" % self.loaded)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print('PyLink starting...')
|
||||||
irc_obj = Irc()
|
irc_obj = Irc()
|
||||||
|
@ -3,22 +3,54 @@ import sys, os
|
|||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
import proto
|
import proto
|
||||||
import utils
|
import utils
|
||||||
|
from conf import conf
|
||||||
|
|
||||||
@proto.add_cmd
|
@utils.add_cmd
|
||||||
def tell(irc, source, args):
|
def tell(irc, source, args):
|
||||||
try:
|
try:
|
||||||
target, text = args[0], ' '.join(args[1:])
|
target, text = args[0], ' '.join(args[1:])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
utils._msg(irc, source, 'Error: not enough arguments.', notice=False)
|
utils.msg(irc, source, 'Error: not enough arguments.')
|
||||||
return
|
return
|
||||||
targetuid = proto._nicktoUid(irc, target)
|
targetuid = proto._nicktoUid(irc, target)
|
||||||
if targetuid is None:
|
if targetuid is None:
|
||||||
utils._msg(irc, source, 'Error: unknown user %r' % target, notice=False)
|
utils.msg(irc, source, 'Error: unknown user %r' % target)
|
||||||
return
|
return
|
||||||
utils._msg(irc, target, text)
|
if not text:
|
||||||
|
utils.msg(irc, source, "Error: can't send an empty message!")
|
||||||
|
return
|
||||||
|
utils.msg(irc, target, text, notice=True)
|
||||||
|
|
||||||
@proto.add_cmd
|
@utils.add_cmd
|
||||||
def debug(irc, source, args):
|
def debug(irc, source, args):
|
||||||
utils._msg(irc, source, 'Debug info printed to console.')
|
utils.msg(irc, source, 'Debug info printed to console.')
|
||||||
print(irc.users)
|
print(irc.users)
|
||||||
print(irc.servers)
|
print(irc.servers)
|
||||||
|
|
||||||
|
@utils.add_cmd
|
||||||
|
def status(irc, source, args):
|
||||||
|
identified = irc.users[source].identified
|
||||||
|
if identified:
|
||||||
|
utils.msg(irc, source, 'You are identified as %s.' % identified)
|
||||||
|
else:
|
||||||
|
utils.msg(irc, source, 'You are not identified as anyone.')
|
||||||
|
|
||||||
|
@utils.add_cmd
|
||||||
|
def identify(irc, source, args):
|
||||||
|
try:
|
||||||
|
username, password = args[0], args[1]
|
||||||
|
except IndexError:
|
||||||
|
utils.msg(irc, source, 'Error: not enough arguments.')
|
||||||
|
return
|
||||||
|
if username.lower() == conf['login']['user'].lower() and password == conf['login']['password']:
|
||||||
|
realuser = conf['login']['user']
|
||||||
|
irc.users[source].identified = realuser
|
||||||
|
utils.msg(irc, source, 'Successfully logged in as %s.' % realuser)
|
||||||
|
else:
|
||||||
|
utils.msg(irc, source, 'Incorrect credentials.')
|
||||||
|
|
||||||
|
def listcommands(irc, source, args):
|
||||||
|
cmds = list(utils.bot_commands.keys())
|
||||||
|
cmds.sort()
|
||||||
|
utils.msg(irc, source, 'Available commands include: %s' % ', '.join(cmds))
|
||||||
|
utils.add_cmd(listcommands, 'list')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import sys, os
|
import sys, os
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
import proto
|
import utils
|
||||||
|
|
||||||
@proto.add_cmd
|
@utils.add_cmd
|
||||||
def hello(irc, source, args):
|
def hello(irc, source, args):
|
||||||
proto._sendFromUser(irc, 'PRIVMSG %s :hello!' % source)
|
utils.msg(irc, source, 'hello!')
|
||||||
|
27
proto.py
27
proto.py
@ -3,10 +3,7 @@ import time
|
|||||||
import sys
|
import sys
|
||||||
from utils import *
|
from utils import *
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
import traceback
|
||||||
global bot_commands
|
|
||||||
# This should be a mapping of command names to functions
|
|
||||||
bot_commands = {}
|
|
||||||
|
|
||||||
class IrcUser():
|
class IrcUser():
|
||||||
def __init__(self, nick, ts, uid, ident='null', host='null',
|
def __init__(self, nick, ts, uid, ident='null', host='null',
|
||||||
@ -21,6 +18,8 @@ class IrcUser():
|
|||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.realname = realname
|
self.realname = realname
|
||||||
|
|
||||||
|
self.identified = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__dict__)
|
return repr(self.__dict__)
|
||||||
|
|
||||||
@ -48,12 +47,12 @@ def _nicktoUid(irc, nick):
|
|||||||
if v.nick == nick:
|
if v.nick == nick:
|
||||||
return k
|
return k
|
||||||
|
|
||||||
def introduceUser(irc, nick, user, host):
|
def spawnClient(irc, nick, user, host, *args):
|
||||||
uid = next_uid(irc.sid)
|
uid = next_uid(irc.sid)
|
||||||
_sendFromServer(irc, "UID {uid} {ts} {nick} {host} {host} {user} 0.0.0.0 {ts} +o +"
|
_sendFromServer(irc, "UID {uid} {ts} {nick} {host} {host} {user} 0.0.0.0 {ts} +o +"
|
||||||
" :PyLink Client".format(ts=int(time.time()), host=host,
|
" :PyLink Client".format(ts=int(time.time()), host=host,
|
||||||
nick=nick, user=user, uid=uid))
|
nick=nick, user=user, uid=uid))
|
||||||
irc.users[uid] = IrcUser(nick, ts, uid, ident, host, realname, realhost, ip)
|
irc.users[uid] = IrcUser(nick, ts, uid, ident, host, *args)
|
||||||
irc.servers[irc.sid].users.append(uid)
|
irc.servers[irc.sid].users.append(uid)
|
||||||
|
|
||||||
def connect(irc):
|
def connect(irc):
|
||||||
@ -96,15 +95,22 @@ def handle_privmsg(irc, source, command, args):
|
|||||||
prefix = irc.conf['bot']['prefix']
|
prefix = irc.conf['bot']['prefix']
|
||||||
if args[0] == irc.pseudoclient.uid:
|
if args[0] == irc.pseudoclient.uid:
|
||||||
cmd_args = args[1].split(' ')
|
cmd_args = args[1].split(' ')
|
||||||
cmd = cmd_args[0]
|
cmd = cmd_args[0].lower()
|
||||||
try:
|
try:
|
||||||
cmd_args = cmd_args[1:]
|
cmd_args = cmd_args[1:]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
cmd_args = []
|
cmd_args = []
|
||||||
try:
|
try:
|
||||||
bot_commands[cmd](irc, source, cmd_args)
|
func = bot_commands[cmd]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
_sendFromUser(irc, 'PRIVMSG %s :unknown command %r' % (source, cmd))
|
msg(irc, source, 'Unknown command %r.' % cmd)
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
func(irc, source, cmd_args)
|
||||||
|
except Exception as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
msg(irc, source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e)))
|
||||||
|
return
|
||||||
|
|
||||||
def handle_error(irc, numeric, command, args):
|
def handle_error(irc, numeric, command, args):
|
||||||
print('Received an ERROR, killing!')
|
print('Received an ERROR, killing!')
|
||||||
@ -214,6 +220,3 @@ def handle_events(irc, data):
|
|||||||
func(irc, numeric, command, args)
|
func(irc, numeric, command, args)
|
||||||
except KeyError: # unhandled event
|
except KeyError: # unhandled event
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def add_cmd(func):
|
|
||||||
bot_commands[func.__name__.lower()] = func
|
|
||||||
|
12
utils.py
12
utils.py
@ -1,6 +1,10 @@
|
|||||||
import string
|
import string
|
||||||
import proto
|
import proto
|
||||||
|
|
||||||
|
global bot_commands
|
||||||
|
# This should be a mapping of command names to functions
|
||||||
|
bot_commands = {}
|
||||||
|
|
||||||
# From http://www.inspircd.org/wiki/Modules/spanningtree/UUIDs.html
|
# From http://www.inspircd.org/wiki/Modules/spanningtree/UUIDs.html
|
||||||
chars = string.digits + string.ascii_uppercase
|
chars = string.digits + string.ascii_uppercase
|
||||||
iters = [iter(chars) for _ in range(6)]
|
iters = [iter(chars) for _ in range(6)]
|
||||||
@ -13,6 +17,12 @@ def next_uid(sid, level=-1):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
return UID(level-1)
|
return UID(level-1)
|
||||||
|
|
||||||
def _msg(irc, target, text, notice=True):
|
def msg(irc, target, text, notice=False):
|
||||||
command = 'NOTICE' if notice else 'PRIVMSG'
|
command = 'NOTICE' if notice else 'PRIVMSG'
|
||||||
proto._sendFromUser(irc, '%s %s :%s' % (command, target, text))
|
proto._sendFromUser(irc, '%s %s :%s' % (command, target, text))
|
||||||
|
|
||||||
|
def add_cmd(func, name=None):
|
||||||
|
if name is None:
|
||||||
|
name = func.__name__
|
||||||
|
name = name.lower()
|
||||||
|
bot_commands[name] = func
|
||||||
|
Loading…
Reference in New Issue
Block a user