From ce347a95c91a89eaff084ce75ede4459c7a79edd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 Apr 2014 03:03:14 +0200 Subject: [PATCH] order processing and other scripts --- process/compress.py | 72 +++++++++++++ process/orders-accept | 2 + process/orders-process | 218 ++++++++++++++++++++++++++++++++++++++++ process/orders.cron | 16 +++ process/send-bz2-report | 35 +++++++ process/send-zip-report | 46 +++++++++ 6 files changed, 389 insertions(+) create mode 100755 process/compress.py create mode 100755 process/orders-accept create mode 100755 process/orders-process create mode 100755 process/orders.cron create mode 100755 process/send-bz2-report create mode 100755 process/send-zip-report diff --git a/process/compress.py b/process/compress.py new file mode 100755 index 000000000..539f1a032 --- /dev/null +++ b/process/compress.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +from sys import argv, exit +from string import join +from os import access, R_OK +from os import system + +gamename='Eressea' + +if(len(argv) >= 3): + gamename=argv[2] + +template="""#!/bin/bash +#PATH=$PATH:$HOME/bin + +addr=%(email)s +[ $# -ge 1 ] && addr=$1 +[ -z $addr ] || send-%(compression)s-report $addr '%(gamename)s Report #%(turn)s' %(files)s +""" + +turn = argv[1] +try: + infile = file("reports.txt", "r") +except: + print "%s: reports.txt file does not exist" % (argv[0], ) + exit(0) + +for line in infile.readlines(): + settings = line[:-1].split(":") + options = { "turn" : turn} + options["gamename"] = gamename + for setting in settings: + try: + key, value = setting.split("=") + options[key] = value + except: + print "Invalid input line", line + if not options.has_key("reports"): + continue + reports = options["reports"].split(",") +# reports = reports + [ "iso.cr" ] + prefix = "%(turn)s-%(faction)s." % options + files=[] + if options["compression"]=="zip": + output = prefix+"zip" + files = [output] + if (access(output, R_OK)): + pass + else: + parameters = [] + for extension in reports: + filename = "%s%s" % (prefix, extension) + if (access(filename, R_OK)): + parameters = parameters + [ filename ] + system("zip %s -q -m -j -1 %s" % (output, join(parameters," "))) + else: + for extension in reports: + if extension!='': + filename = "%s%s" % (prefix, extension) + output = "%s%s.bz2" % (prefix, extension) + files = files+[output] + if access(filename, R_OK): + if (access(output, R_OK)): + #print output, "exists, skipping" + continue + system("bzip2 %s" % filename) + #print files + options["files"] = join(files, " ") + batch = file("%s.sh" % options["faction"], "w") + batch.write(template % options) + batch.close() +infile.close() diff --git a/process/orders-accept b/process/orders-accept new file mode 100755 index 000000000..552a3e9a1 --- /dev/null +++ b/process/orders-accept @@ -0,0 +1,2 @@ +#/bin/.sh +grep -v '>From' | $HOME/src/scripts/bin/orders-accept $* diff --git a/process/orders-process b/process/orders-process new file mode 100755 index 000000000..d15d188cf --- /dev/null +++ b/process/orders-process @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- + +from os import unlink, symlink, rename, popen, tmpfile +from os.path import exists +from re import compile, IGNORECASE +from string import split, join, upper, strip +from sys import argv, exit +from time import sleep, time, ctime +from syslog import openlog, closelog, syslog + +from epasswd import EPasswd + +def pwd_get_email(faction, pwd, pwdfile=None): + return None + +def splitfilename(filename): + from os.path import split + return split(filename) + +def unlock_file(filename): + try: + unlink(filename+".lock") + except: + print "could not unlock %s.lock, file not found" % filename + raise + +def lock_file(filename): + i = 0 + wait = 1 + if not exists(filename): + file=open(filename, "w") + file.close() + while True: + try: + symlink(filename, filename+".lock") + return + except: + i = i+1 + if i == 5: + raise + sleep(wait) + wait = wait*2 + +messages = { +"subject-de": "Befehle angekommen", +"subject-en": "orders received", + +"validate-en": "Validating", +"validate-de": "Verarbeite", + +"faction-en": "Faction", +"faction-de": "Partei", + +"unknown-de": "WARNUNG: Die Partei ist nicht bekannt, oder das Passwort falsch!", +"unknown-en": "WARNING: This faction is unknown, or the password is incorrect!", + +"warning-de": "Warnung", +"warning-en": "Warning", + +"error-de": "Fehler", +"error-en": "Error", +} + + +# base directory for all your games: +rootdir = "/home/eressea/eressea" +frommail = "Eressea Server " +orderbase = "orders.dir" +sendmail = True +maxlines = 25 +echeck_cmd = "/home/eressea/echeck/echeck.sh" + +# regular expression that finds the start of a faction +fact_re = compile("^\s*(eressea|vinyambar|partei|faction)\s+([a-zA-Z0-9]+)\s+\"?([^\"]*)\"?", IGNORECASE) + +def check_pwd(filename, email, pw_data): + results = [] + try: + file = open(filename, "r") + except: + print "could not open file", filename + return results + for line in file.readlines(): + mo = fact_re.search(strip(line)) + if mo != None: + fact_nr = str(mo.group(2)) + fact_pw = str(mo.group(3)) + if pw_data.fac_exists(fact_nr): + if pw_data.check(fact_nr, fact_pw) == 0: + game_email = pw_data.get_email(fact_nr) + results = results + [ (fact_nr, game_email, False, fact_pw) ] + else: + game_email = pw_data.get_email(fact_nr) + results = results + [ (fact_nr, game_email, True, fact_pw) ] + else: + results = results + [ (fact_nr, None, False, fact_pw) ] + return results + +def echeck(filename, locale, rules): + dirname, filename = splitfilename(filename) + stream = popen("%s %s %s %s %s" % (echeck_cmd, locale, filename, dirname, rules), 'r') + lines = stream.readlines() + if len(lines)==0: + stream.close() + return None + if len(lines)>maxlines: + mail = join(lines[:maxlines-3] + ["...", "\n"] + lines[-3:], '') + else: + mail = join(lines[:maxlines], '') + stream.close() + return mail + +## the main body of the script +game = int(argv[1]) + +basedir = rootdir + "/game-%d" % (game, ) +queuename = basedir + "/orders.queue" +if not exists(queuename): + exit(0) + +# parse the queue file - +#print "connecting to SMTP..." +from smtplib import SMTP +try: + server = SMTP("localhost") +except: + print "could not connect to SMTP server" + exit(0) +#print "reading password file..." +pw_data = EPasswd(basedir + "/passwd") + +#print "reading orders.queue..." +# move the queue file to a save space while locking it: +try: + lock_file(queuename) +except: + exit(0) +queuefile = open(queuename, "r") +lines = queuefile.readlines() +queuefile.close() + +# copy to a temp file + +tname="/tmp/orders.queue.%s" % str(time()) +try: + lock_file(tname) +except: + exit(0) +tmpfile=open(tname, "w") +for line in lines: + tmpfile.write(line) +tmpfile.close() + +openlog("orders") + +unlink(queuename) +try: + unlock_file(queuename) +except: + pass + +for line in lines: + tokens = split(line[:-1], ' ') + dict = {} + for token in tokens: + name, value = split(token, '=') + dict[name] = value + + email = dict["email"] + locale = dict["locale"] + game = int(dict["game"]) + file = dict["file"] + gamename='[E%d]' % game + rules='e%d' % game + warning = "" + failed = True + results = check_pwd(file, email, pw_data) + logfile = open(basedir+"/zug.log", "a") + dirname, filename = splitfilename(file) + msg = messages["validate-"+locale] + " " + filename + "\n\n" + for faction, game_email, success, pwd in results: + msg = msg + messages["faction-"+locale] + " " + faction + "\n" + if success: failed = False + else: msg = msg + messages["unknown-"+locale] + "\n" + msg = msg + "\n" + logfile.write("%s:%s:%s:%s:%s:%s\n" % (ctime(time()), email, game_email, faction, pwd, success)) + logfile.close() + + if failed: + warning = " (" + messages["warning-" + locale] + ")" + syslog("failed - no valid password in " + file) + else: + result = echeck(file, locale, rules) + if email=='eressea': + print result + continue + elif result is None: + # echeck did not finish + msg = msg + "Echeck was killed. Your turn was accepted, but could not be verified.\n" + warning = " (" + messages["warning-" + locale] + ")" + syslog("process - echeck got killed, " + file) + else: + msg = msg + result + syslog("process - checked orders in " + file) + + subject = gamename + " " + messages["subject-" + locale] + warning + msg = "Subject: %s\nFrom: %s\nTo: %s\nContent-Type: text/plain; charset=utf-8\n\n" % (subject, frommail, email) + msg + try: + server.sendmail(frommail, email, msg) + except: + syslog("failed - cannot send to " + email) + +server.close() + +closelog() +unlink(tname) +unlock_file(tname) diff --git a/process/orders.cron b/process/orders.cron new file mode 100755 index 000000000..be573fe86 --- /dev/null +++ b/process/orders.cron @@ -0,0 +1,16 @@ +#!/bin/bash + +## this script processes incoming order files. +# files are delivered into an incoming queue by procmail, then cron runs +# this here script to make a non-blocking syntax check and reject or +# accept the order file. + +for GAME in $* +do + if [ "$GAME" == "eressea" ]; then GAME=2 ; fi + if [ "$GAME" == "e3a" ]; then GAME=3 ; fi + if [ -e $HOME/eressea/game-$GAME/orders.queue ] + then + $HOME/bin/orders-process $GAME + fi +done diff --git a/process/send-bz2-report b/process/send-bz2-report new file mode 100755 index 000000000..733b5c6be --- /dev/null +++ b/process/send-bz2-report @@ -0,0 +1,35 @@ +#!/bin/bash +if [ -z $ERESSEA ]; then + echo "You have to define the \$ERESSEA environment variable to run $0" + exit -2 +fi +source $HOME/bin/functions.sh +source $ERESSEA/etc/eressea.conf + +TEMPLATE=report-mail.txt +if [ "$1" == "-Lde" ] +then + TEMPLATE=report-mail.de.txt + shift +fi + +if [ "$1" == "-Lde" ] +then + TEMPLATE=report-mail.en.txt + shift +fi + +EMAIL=$1 +SUBJECT=$2 +shift 2 + +ATTACHMENTS="" +while [ $# -gt 0 ] +do + if [ -e "$1" ]; then + ATTACHMENTS="-a $1 $ATTACHMENTS" + fi + shift +done + +cat $ERESSEA/etc/$TEMPLATE | mutt -F $ERESSEA/etc/muttrc -s "$SUBJECT" $ATTACHMENTS -- $EMAIL diff --git a/process/send-zip-report b/process/send-zip-report new file mode 100755 index 000000000..fb068c33f --- /dev/null +++ b/process/send-zip-report @@ -0,0 +1,46 @@ +#!/bin/bash +if [ -z $ERESSEA ]; then + ERESSEA=`echo $PWD |sed -e 's/\/game.*//'` + echo "Assuming that ERESSEA=$ERESSEA" +fi +if [ ! -f reports.txt ]; then + echo "need to run $0 from the report direcory" + exit -2 +fi + +PWD=$(pwd) +GAME=$(dirname $PWD) + +TEMPLATE=report-mail.txt +if [ "$1" == "-Lde" ] +then + TEMPLATE=report-mail.de.txt + shift +fi + +if [ "$1" == "-Len" ] +then + TEMPLATE=report-mail.en.txt + shift +fi + +if [ -e $GAME/$TEMPLATE ]; then +TEMPLATE=$GAME/$TEMPLATE +else +TEMPLATE=$ERESSEA/etc/$TEMPLATE +fi + +if [ ! -e $TEMPLATE ]; then + echo "no such email template: $TEMPLATE" + exit -3 +fi + +while [ -e /tmp/.stopped ] ; do + echo "waiting 2 minutes for lockfile in /tmp/.stopped to clear" + sleep 120 +done +mutt -F $ERESSEA/etc/muttrc -s "$2" -a "$3" -- $1 < $TEMPLATE + +if [ $? -ne 0 ] ; then + echo "Sending failed for email/report: $2/$3" +fi