X-Git-Url: https://git.siccegge.de//index.cgi?p=teilnehmertool.git;a=blobdiff_plain;f=teilnehmertool.py;h=32967b7dcfed078e47ae3fea9026731e906d9b8c;hp=b11b6882567448aaf48b38ff0105803337e084b5;hb=HEAD;hpb=87c918514af5f31d6a5d29d0870a0278926af2f3 diff --git a/teilnehmertool.py b/teilnehmertool.py index b11b688..32967b7 100755 --- a/teilnehmertool.py +++ b/teilnehmertool.py @@ -9,11 +9,63 @@ import string import jinja2 import os import os.path +import re +import sys + +import csv conn = None -env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates')) +env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates', encoding='utf-8')) + + +## jinja2 TeX espaping from http://flask.pocoo.org/snippets/55/ +LATEX_SUBS = [ + (re.compile(r'\\'), r'\\textbackslash{}'), + (re.compile(r'([{}_#%&$])'), r'\\\1'), + (re.compile(r'~'), r'\~{}'), + (re.compile(r'\^'), r'\^{}'), + (re.compile(r'"'), r"''"), + (re.compile(r'\.\.\.+'), r'\\ldots'), +] + +def escape_tex(value): + newval = value + for pattern, replacement in LATEX_SUBS: + newval = pattern.sub(replacement, newval) + return newval + +env.filters['escape_tex'] = escape_tex + + +## dont judge me. i don't see any good way sadly +VERANSTALTUNGSLEITER = { + } + +def is_veranstaltungsleiter(row): + if VERANSTALTUNGSLEITER.has_key(row['username']): + return True + return False + + +def create_helfer_nametags(csvpath, outdir='helfer_nametags'): + template = env.get_template('nametag.svg') + + with open(csvpath, 'r') as csvfile: + csvreader = csv.DictReader(csvfile, delimiter=',', quotechar='"') + uni = "FAU Erlangen" + + for row in csvreader: + if is_veranstaltungsleiter(row): + nick = "%s %s" % (VERANSTALTUNGSLEITER[row['username']][0], VERANSTALTUNGSLEITER[row['username']][1]) + with open(os.path.join(outdir, "%s.svg" % nick), 'w') as f: + f.write(template.render(nick=nick.decode('utf-8'), uni1=uni.decode('utf-8')).encode('utf-8')) + nick = "%s" % (row['username']) + + with open(os.path.join(outdir, "%s.svg" % nick), 'w') as f: + f.write(template.render(nick=nick.decode('utf-8'), uni1=uni.decode('utf-8')).encode('utf-8')) + def import_teilnehmer(input): ids = set([ i[0] for i in conn.execute('SELECT id FROM teilnehmer').fetchall() ]) @@ -25,11 +77,11 @@ def import_teilnehmer(input): continue if not int(row[0]) in ids: print "Importing %s" % (row, ) - conn.execute("INSERT INTO teilnehmer VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - row + [0, 0, 0]) + conn.execute("INSERT INTO teilnehmer VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + row[:-2] + ['Kein T-Shirt', 'Kein Pulli'] + row[-2:] + [0, 0, 0, "", "false"]) conn.commit() - + def mark_pay(outdir): betrag = int(raw_input("Betrag: ")) @@ -40,8 +92,14 @@ def mark_pay(outdir): if uid == "": break uid = int(uid) + vorname, nachname, email, bezahlt = \ + conn.execute("SELECT vorname, nachname, email, bezahlt FROM teilnehmer WHERE id = ?", [uid]).fetchone() + + if bezahlt == betrag: + continue + conn.execute("UPDATE teilnehmer SET bezahlt = ? WHERE id = ?", [betrag, uid]) - vorname, nachname, email = conn.execute("SELECT vorname, nachname, email FROM teilnehmer WHERE id = ?", [uid]).fetchone() + with open(os.path.join(outdir, email), 'w') as f: f.write(template.render(vorname=vorname.decode('utf-8'), @@ -86,18 +144,167 @@ def create_mail(outdir='output'): preis, id]) conn.commit() +def create_remind(outdir='output'): + def gen_rechnung(tshirt, zipper): + preis = 25 + kosten = u"" + kosten += u"%s | %s\n" % (u" Konferenzbeitrag".ljust(30), "25.00") + kosten += u"%s | %s\n" % ((u" T-Shirt (Größe %s)" % tshirt).ljust(30), " 0.00") + if zipper != 'Kein Pulli': + kosten += u"%s | %s\n" % ((u" Kapuzenzipper (Größe %s)" % zipper).ljust(30), "25.00") + preis += 25 + kosten += ' '*2 + 29*'-' + '+' + 6*'-' + '\n' + kosten += u"%s | %s\n" % (u" Summe".ljust(30), "%2d.00" % preis) + + return kosten, preis + + def gen_token(id, vorname, nachname): + return u"%s-%s-%s" % (id, nachname.decode('utf-8').upper(), vorname.decode('utf-8').upper()) + + template = env.get_template('erinnerung.eml') + + for id, vorname, nachname, email, tshirt, zipper in \ + conn.execute("SELECT id, vorname, nachname, email, tshirt, zipper FROM teilnehmer " + + "WHERE bezahlt < 25 AND datetime(emailsent) < datetime(?)", + [(datetime.datetime.now() - datetime.timedelta(14)).isoformat()]): + + rechnung, preis = gen_rechnung(tshirt, zipper) + + with open(os.path.join(outdir, email), 'w') as f: + f.write(template.render(vorname=vorname.decode('utf-8'), + nachname=nachname.decode('utf-8'), + email=email.decode('utf-8'), + token=gen_token(id, vorname, nachname), + rechnung=rechnung).encode('utf-8')) + + conn.execute("UPDATE teilnehmer set emailsent = ?, betrag = ? WHERE id = ?", [datetime.datetime.now().isoformat(), + preis, id]) + conn.commit() + + def create_nametag(outdir='output'): template = env.get_template('nametag.svg') - - for vorname, nachname, namensschild, hochschule in \ - conn.execute("SELECT vorname, nachname, namensschild, hochschule FROM teilnehmer"): - with open(os.path.join(outdir, "%s.svg" % namensschild), 'w') as f: + for teiln_id, vorname, nachname, namensschild, hochschule, dochned in \ + conn.execute("SELECT id, vorname, nachname, namensschild, hochschule, dochned FROM teilnehmer"): + + if dochned != "false": + print >> sys.stderr, "not generating %s %s (id %s), because abgemeldet" % (vorname, nachname, teiln_id) + continue + + with open(os.path.join(outdir, "%s.svg" % teiln_id), 'w') as f: f.write(template.render(name=u"%s %s" % (vorname.decode('utf-8'), nachname.decode('utf-8')), nick=namensschild.decode('utf-8'), uni1=hochschule.decode('utf-8')).encode('utf-8')) + +def create_teilnehmer_list(outdir = 'output', only_quittung=False): + template_full = env.get_template('teilnehmerliste.tex') + template_pack = env.get_template('packliste.tex') + template_quittung = env.get_template('quittung.tex') + template_strichliste = env.get_template('strichliste.tex') + + if os.path.exists('helfer.csv'): + with open('helfer.csv', 'r') as csvfile: + csvreader = csv.DictReader(cvspath, delimiter=',', quotechar='"') + uni = "FAU Erlangen" + + helfer = [ row['username'] for row in cvsreader ] + else: + print "Kein helfer.csv gefunden" + helfer = [] + + + i = 0 + teilnehmer = [] + for vor, nach, nick, hochschule, betrag, bezahlt, shirtsize, zippersize, dochned, comment in \ + conn.execute("SELECT vorname, nachname, namensschild, hochschule, betrag, bezahlt, tshirt, zipper, dochned, orga_comment FROM teilnehmer ORDER BY UPPER(hochschule) ASC, UPPER(namensschild) ASC"): + + vor = vor.decode('utf8') + nach = nach.decode('utf8') + nick = nick.decode('utf8') + hochschule = hochschule.decode('utf8') + ## betrag ist schon int + ## bezahlt ist schon int + shirtsize = shirtsize.decode('utf8') + if re.match("kein", shirtsize, flags=re.IGNORECASE): + shirtsize = "" + + zippersize = zippersize.decode('utf8') + if re.match("kein", zippersize, flags=re.IGNORECASE): + zippersize = "" + + ## string to bool.. + if dochned == "false": + will_attend = True + else: + will_attend = False + + comment = comment.decode('utf8') + + teilnehmer.append({'vorname': vor, 'nachname': nach, + 'hochschule': hochschule, 'nick': nick, 'betrag': betrag, 'bezahlt': + bezahlt, 'shirtsize': shirtsize, 'zippersize': zippersize, + 'will_attend': will_attend, 'comment': comment}) + + if will_attend: + with open(os.path.join(outdir, ("%03d_quittung_%s_%s.tex" % (i, vor.replace(" ", "_"), nach.replace(" ", "_")))), 'w') as out: + out.write(template_quittung.render(vorname=vor, nachname=nach, uni=hochschule).encode('utf-8')) + + i = i+1 + + ## gibt schlimmere hacks.. + if only_quittung: + return + + with open(os.path.join(outdir, "teilnehmerliste.tex"), 'w') as out: + out.write(template_full.render(teilnehmer=teilnehmer).encode('utf-8')) + + with open(os.path.join(outdir, "packliste.tex"), 'w') as out: + out.write(template_pack.render(teilnehmer=teilnehmer).encode('utf-8')) + + with open(os.path.join(outdir, "teilnehmer-strichliste.tex"), 'w') as out: + out.write(template_strichliste.render(teilnehmer=teilnehmer, helfer=helfer).encode('utf-8')) + + +def create_teilnehmer_quittungen(output='quittungen'): + create_teilnehmer_list(output, only_quittung=True) + + +def create_bmbf_list(outdir = 'output'): + template = env.get_template('bmbf-unterschriftenliste.tex') + + + teilnehmer = [] + i = 1 + for vor, nach, hochschule, dochned in \ + conn.execute("SELECT vorname, nachname, hochschule, dochned FROM teilnehmer ORDER BY UPPER(nachname) ASC, UPPER (vorname) ASC"): + + vor = vor.decode('utf8') + nach = nach.decode('utf8') + hochschule = hochschule.decode('utf8') + + if dochned != "false": + continue + + if hochschule == "Privat" : + continue + + teilnehmer.append({'vorname': vor, 'nachname': nach, 'num': i, 'hochschule': hochschule}) + i = i+1 + + + with open(os.path.join(outdir, "bmbf-unterschriftenliste.tex"), 'w') as out: + out.write(template.render(teilnehmer=teilnehmer).encode('utf-8')) + + +def list_teilnehmer_ids(): + for tid, dochned in conn.execute("SELECT id, dochned FROM teilnehmer ORDER BY id ASC"): + if dochned == "false": + print tid + + def main(): parser = argparse.ArgumentParser(description="Ultimate Teilnehmertool") @@ -111,7 +318,19 @@ def main(): help='Generiere E-Mails mit Überweisungsinformationen') group.add_argument('--pay', action='store_true', help='Speichere Zahlungseingang') - + group.add_argument('--remind', action='store_true', + help='Generiere Zahlungsaufforderungserinnerung') + group.add_argument('--bmbf', action='store_true', + help='Generiere BMBF-Unterschriftenliste') + group.add_argument('--liste', action='store_true', + help='Generiere Teilnehmerübersichtsliste') + group.add_argument('--helfer', action='store_true', + help='Generiere Helfer-Nametags aus helfer.csv') + group.add_argument('--quittungen', action='store_true', + help='Generiere Quittungen für Teilnehmer') + group.add_argument('--ids', action='store_true', + help='Liste alle Teilnehmerids auf, die sich nicht abgemeldet haben') + # Argumente parser.add_argument('--db', default='teilnehmer.sqlite', help='Teilnehmerdatenbank') @@ -119,24 +338,40 @@ def main(): help='Eingabedatei') parser.add_argument('-o', '--output', default='output', help='Ausgabeverzeichnis') - + args = parser.parse_args() global conn conn = sqlite3.connect(args.db) conn.text_factory = str + conn.row_factory = sqlite3.Row + conn.execute('pragma encoding = "UTF-8";') - if args.nametag or args.email or args.pay: + if args.nametag or args.email or args.pay or args.remind or args.bmbf or \ + args.liste or args.helfer or args.quittungen or args.ids: assert(args.output) if not os.path.exists(args.output): os.mkdir(args.output) - + if args.nametag: create_nametag(args.output) elif args.email: create_mail(args.output) elif args.pay: mark_pay(args.output) + elif args.remind: + create_remind(args.output) + elif args.bmbf: + create_bmbf_list(args.output) + elif args.liste: + create_teilnehmer_list(args.output) + elif args.helfer: + assert(args.input) + create_helfer_nametags(args.input, args.output) + elif args.quittungen: + create_teilnehmer_quittungen(args.output) + elif args.ids: + list_teilnehmer_ids() elif args.importcsv: assert(args.input) @@ -144,4 +379,5 @@ def main(): if __name__ == '__main__': main() - + +# vim: set expandtab :