summaryrefslogtreecommitdiffstats
path: root/Reaktor
diff options
context:
space:
mode:
Diffstat (limited to 'Reaktor')
-rw-r--r--Reaktor/IRC/getconf.py7
-rw-r--r--Reaktor/IRC/ircasy.py5
-rwxr-xr-xReaktor/IRC/reaktor.py8
-rwxr-xr-xReaktor/commands/caps2
-rw-r--r--Reaktor/config.py61
-rwxr-xr-xReaktor/titlebot/commands/highest30
-rwxr-xr-xReaktor/titlebot/commands/list4
-rwxr-xr-xReaktor/titlebot/commands/undo10
-rwxr-xr-xReaktor/titlebot/commands/up18
-rw-r--r--Reaktor/titlebot/titlebot.py31
10 files changed, 125 insertions, 51 deletions
diff --git a/Reaktor/IRC/getconf.py b/Reaktor/IRC/getconf.py
index f9cd4404..168c908c 100644
--- a/Reaktor/IRC/getconf.py
+++ b/Reaktor/IRC/getconf.py
@@ -9,14 +9,17 @@ import os
def make_getconf(filename):
- def getconf(prop):
+ def getconf(prop, default_value=None):
prop_split = prop.split('.')
string = ''
config = load_config(filename)
#imp.reload(config)
tmp = config.__dict__
for pr in prop_split:
- tmp = tmp[pr]
+ if pr in tmp:
+ tmp = tmp[pr]
+ else:
+ return default_value
return tmp
return getconf
diff --git a/Reaktor/IRC/ircasy.py b/Reaktor/IRC/ircasy.py
index 259ea98c..9a7f44f3 100644
--- a/Reaktor/IRC/ircasy.py
+++ b/Reaktor/IRC/ircasy.py
@@ -114,10 +114,7 @@ class asybot(asychat):
self.on_kick(prefix, command, params, rest)
elif command == 'JOIN':
- try:
- self.on_join(prefix, command, params, rest)
- except:
- pass
+ self.on_join(prefix, command, params, rest)
elif command == '433':
# ERR_NICKNAMEINUSE, retry with another name
diff --git a/Reaktor/IRC/reaktor.py b/Reaktor/IRC/reaktor.py
index b53ef651..ec306e7c 100755
--- a/Reaktor/IRC/reaktor.py
+++ b/Reaktor/IRC/reaktor.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import os
from ircasy import asybot
from asyncore import loop
@@ -36,7 +36,7 @@ class Reaktor(asybot):
return False
def on_join(self, prefix, command, params, rest):
- for command in getconf('on_join'):
+ for command in getconf('on_join', []):
self.execute_command(command, None, prefix, params)
def on_privmsg(self, prefix, command, params, rest):
@@ -69,6 +69,9 @@ class Reaktor(asybot):
log.info("cannot parse args!")
cwd = getconf('workdir')
+ if not os.access(cwd,os.W_OK):
+ log.error("Workdir '%s' is not Writable! Falling back to root dir"%cwd)
+ cwd = "/"
env = command.get('env', {})
env['_prefix'] = prefix
@@ -81,7 +84,6 @@ class Reaktor(asybot):
target.append(env['_from'])
log.debug('target:' +str(target))
- env['config_filename'] = os.path.abspath(self.config)
start = time()
try:
p = popen(myargv, bufsize=1, stdout=PIPE, stderr=PIPE, env=env, cwd=cwd)
diff --git a/Reaktor/commands/caps b/Reaktor/commands/caps
index d0245575..b5d6642d 100755
--- a/Reaktor/commands/caps
+++ b/Reaktor/commands/caps
@@ -10,4 +10,4 @@ def load_config(filename):
config = load_config(os.environ['config_filename'])
print('Private: '+' '.join(filter(None,[ x.get('capname',None) for x in config.commands])))
-print('Public: '+' '.join(filter(None,[ x.get('capname',None) for x in config.public_commands])))
+print('Public: '+' '.join(filter(None,[ x.get('capname',None) for x in config.public_commands])))
diff --git a/Reaktor/config.py b/Reaktor/config.py
index 0a01c5cb..424019a7 100644
--- a/Reaktor/config.py
+++ b/Reaktor/config.py
@@ -1,11 +1,11 @@
-from os import environ
+from os.path import abspath, expanduser
+import re
debug = True
-# CAVEAT name should not contains regex magic
name = 'crabmanner'
-workdir = environ['HOME'] + '/state'
+workdir = expanduser('~') + '/state'
irc_alarm_timeout = 300
irc_hammer_interval = 10
@@ -17,37 +17,56 @@ irc_restart_timeout = 5
irc_channels = [
'#krebs'
]
-admin_file='admin.lst'
-auth_file='auth.lst'
-def default_command(cmd):
+admin_file=workdir+'/admin.lst'
+auth_file=workdir+'/auth.lst'
+
+config_filename = abspath(__file__)
+
+# me is used, so name cannot kill our patterns below
+me = '\\b' + re.escape(name) + '\\b'
+me_or_us = '(?:' + me + '|\\*)'
+
+def default_command(cap, cmd=None, env=None):
+ if not env: env = {}
+ if cmd == None: cmd=cap
+ return {
+ 'capname': cap,
+ 'pattern': '^' + me_or_us + ':\\s*' + cap + '\\s*(?:\\s+(?P<args>.*))?$',
+ 'argv': [ 'commands/' + cmd ],
+ 'env': env
+ }
+
+def simple_command(cap, cmd=None, env={}):
+ if cmd == None: cmd=cap
return {
- 'capname': cmd,
- 'pattern': '^(?:' + name + '|\\*):\\s*' + cmd + '\\s*(?:\\s+(?P<args>.*))?$',
- 'argv': [ 'commands/' + cmd ] }
+ 'capname': cap,
+ 'pattern': '^' + cap + '\\s*(?:\\s+(?P<args>.*))?$',
+ 'argv' : [ 'commands/' + cmd ],
+ 'env': env
+ }
public_commands = [
- default_command('caps'),
+ default_command('caps', env={
+ 'config_filename': config_filename
+ }),
default_command('hello'),
default_command('badcommand'),
default_command('rev'),
default_command('uptime'),
default_command('nocommand'),
- {
- 'capname': 'tell',
- 'pattern': '^' + name + ':\\s*' + 'tell' + '\\s*(?:\\s+(?P<args>.*))?$',
- 'argv': [ 'commands/tell-on_privmsg' ],
- 'env': { 'state_file': workdir + '/tell.txt' }
- },
+ default_command('tell', cmd='tell-on_privmsg', env={
+ 'state_file': workdir + '/tell.txt'
+ }),
# command not found
- { 'pattern': '^(?:' + name + '|\\*):.*',
+ { 'pattern': '^' + me_or_us + ':.*',
'argv': [ 'commands/respond','You are made of stupid!'] },
# "highlight"
- { 'pattern': '.*\\b' + name + '\\b.*',
+ { 'pattern': '.*' + me + '.*',
'argv': [ 'commands/say', 'I\'m famous' ] },
# identify via direct connect
- { 'capname': 'identify',
- 'pattern': '^identify' + '\\s*(?:\\s+(?P<args>.*))?$',
- 'argv' : [ 'commands/identify' ]}
+ simple_command('identify', env={
+ 'config_filename': config_filename
+ })
]
commands = [
default_command('reload')
diff --git a/Reaktor/titlebot/commands/highest b/Reaktor/titlebot/commands/highest
new file mode 100755
index 00000000..d0408ac0
--- /dev/null
+++ b/Reaktor/titlebot/commands/highest
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+import json
+from os import environ
+import sys
+import os
+import poll
+
+f = 'suggestions.json'
+title=" ".join(sys.argv[1:])
+db = poll.load_db(f)
+# only print the last N values (default 1)
+limit = int(sys.argv[1]) if len(sys.argv) > 1 else 1
+num = 0
+last_vote = 9001
+# stolen from http://stackoverflow.com/questions/9647202/ordinal-numbers-replacement
+suffixes = ["th", "st", "nd", "rd", ] + ["th"] * 16
+
+for entry in poll.sort_by_votes(db):
+ # if two entries have the same number of upvotes, do not increment the rank
+ current_vote = sum(entry['votes'].values())
+ if current_vote < last_vote:
+ num = num + 1
+ last_vote = current_vote
+ # exit if we are above the limit
+ if num > limit:
+ sys.exit(0)
+
+ suffixed_num = str(num) + suffixes[num % 100]
+ print("%s: '%s' (%d votes)" %
+ (suffixed_num,entry['title'],sum(entry['votes'].values())))
diff --git a/Reaktor/titlebot/commands/list b/Reaktor/titlebot/commands/list
index 3a29919a..cee4b8a8 100755
--- a/Reaktor/titlebot/commands/list
+++ b/Reaktor/titlebot/commands/list
@@ -17,11 +17,11 @@ if len(sys.argv) > 1 and ("-h" in sys.argv[1] or "usage" == sys.argv[1]):
if len(sys.argv) > 1 and ("votes" in sys.argv[1]):
use = poll.sort_by_votes(db)
elif len(sys.argv) > 1 and ("age" in sys.argv[1]) or len(sys.argv) == 1:
- pass
+ use = db
else:
print("unknown sorting method")
sys.exit(1)
-for entry in poll.sort_by_votes(db):
+for entry in use:
print("#%d %s (votes: %d)" %
(db.index(entry),entry['title'],sum(entry['votes'].values())))
diff --git a/Reaktor/titlebot/commands/undo b/Reaktor/titlebot/commands/undo
index bebd57a3..a66de67f 100755
--- a/Reaktor/titlebot/commands/undo
+++ b/Reaktor/titlebot/commands/undo
@@ -16,12 +16,16 @@ except:
undos vote of one or more entries based on .list""")
sys.exit(1)
voter = environ['_prefix']
+voter_name = environ['_from']
for vote in votes:
try:
vote = int(vote)
- del(db[vote]['votes'][voter] )
- print("undid vote by %s for #%d" %(environ['_from'],vote))
+ if not voter in db[vote]['votes']:
+ print("%s, you never voted for '%s'!"%(voter_name,db[vote]['title']))
+ else:
+ del(db[vote]['votes'][voter] )
+ print("%s undid vote for '%s'" %(voter_name,db[vote]['title'] ))
except:
- print("undo voting for #%s failed" %vote)
+ print("%s undo voting for #%d failed" %(voter_name,vote))
poll.save_db(f,db)
diff --git a/Reaktor/titlebot/commands/up b/Reaktor/titlebot/commands/up
index c9de1223..0a48bdb0 100755
--- a/Reaktor/titlebot/commands/up
+++ b/Reaktor/titlebot/commands/up
@@ -9,19 +9,25 @@ import poll
f = 'suggestions.json'
db = poll.load_db(f)
votes = []
-try:
- votes = sys.argv[1:]
-except:
+votes = sys.argv[1:]
+if not votes:
print("""usage: up number (...)
upvotes one or more entries based on .list""")
sys.exit(1)
voter = environ['_prefix']
+voter_name =environ['_from']
for vote in votes:
try:
vote = int(vote)
- db[vote]['votes'][voter] = 1
+ if vote < 0:
+ raise Exception()
+ if voter in db[vote]['votes']:
+ print("%s, you already have voted for '%s'"%(voter_name,db[vote]['title']) )
+ else:
+ db[vote]['votes'][voter] = 1
+ print("%s voted for '%s'"%(voter_name,db[vote]['title']))
except:
- print("voting for #%s failed" %vote)
-print("Thanks for your votes %s"%environ['_from'])
+ print("%s, voting for #%s failed" %(voter_name,vote))
+
poll.save_db(f,db)
diff --git a/Reaktor/titlebot/titlebot.py b/Reaktor/titlebot/titlebot.py
index dc4e28ae..c1eac3b0 100644
--- a/Reaktor/titlebot/titlebot.py
+++ b/Reaktor/titlebot/titlebot.py
@@ -1,5 +1,6 @@
from os import environ,mkdir
-
+from os.path import abspath, expanduser
+import re
debug = False
# CAVEAT name should not contains regex magic
@@ -21,26 +22,37 @@ irc_restart_timeout = 5
irc_channels = [
'#binaergewitter'
]
+admin_file=workdir+'/admin.lst'
+auth_file=workdir+'/auth.lst'
+
+config_filename = abspath(__file__)
-admin_file=workdir+'/'+'admin.lst'
try:
with open(admin_file,"x"): pass
except: pass
-auth_file=workdir+'/'+'auth.lst'
-def default_command(cmd):
+# me is used, so name cannot kill our patterns below
+me = '\\b' + re.escape(name) + '\\b'
+me_or_us = '(?:' + me + '|\\*)'
+
+def default_command(cmd, env=None):
+ if not env: env = {}
return {
'capname': cmd,
- 'pattern': '^(?:' + name + '|\\*):\\s*' + cmd + '\\s*(?:\\s+(?P<args>.*))?$',
- 'argv': [ 'commands/' + cmd ] }
+ 'pattern': '^' + me_or_us + ':\\s*' + cmd + '\\s*(?:\\s+(?P<args>.*))?$',
+ 'argv': [ 'commands/' + cmd ],
+ 'env': env
+ }
def titlebot_cmd(cmd):
return {
'capname': cmd,
- 'pattern': '\\.' + cmd + '\\s*(?:\\s+(?P<args>.*))?$',
+ 'pattern': '^\\.' + cmd + '\\s*(?:\\s+(?P<args>.*))?$',
'argv': [ 'titlebot/commands/' + cmd ] }
public_commands = [
- default_command('caps'),
+ default_command('caps', env={
+ 'config_filename': config_filename
+ }),
default_command('hello'),
default_command('badcommand'),
default_command('rev'),
@@ -48,13 +60,14 @@ public_commands = [
default_command('nocommand'),
titlebot_cmd('list'),
titlebot_cmd('help'),
+ titlebot_cmd('highest'),
titlebot_cmd('up'),
titlebot_cmd('new'),
titlebot_cmd('undo'),
titlebot_cmd('down'),
# identify via direct connect
{ 'capname': 'identify',
- 'pattern': '^identify' + '\\s*(?:\\s+(?P<args>.*))?$',
+ 'pattern': '^identify' + '\\s*(?:\\s+(?P<args>.*))?$',
'argv' : [ 'commands/identify' ]}
]
commands = [