#!/usr/bin/python
# -*- coding: utf-8 -*-
+import argparse
import sqlite3
+import datetime
+import csv
import string
import jinja2
import os
import os.path
+import re
+import sys
-conn = sqlite3.connect('teilnehmer.sqlite')
-conn.text_factory = str
+import csv
-env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'))
+conn = None
-def create_mail():
+
+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() ])
+
+ with open(input) as f:
+ reader = csv.reader(f, delimiter=';', quotechar='"')
+ for row in reader:
+ if row[0] == '#':
+ continue
+ if not int(row[0]) in ids:
+ print "Importing %s" % (row, )
+ 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: "))
+
+ template = env.get_template('eingangsbestaetigung.eml')
+
+ while True:
+ uid = raw_input("User: ")
+ 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])
+
+
+ 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'),
+ betrag=betrag).encode('utf-8'))
+
+ conn.commit()
+
+def create_mail(outdir='output'):
def gen_rechnung(tshirt, zipper):
preis = 25
kosten = u""
kosten += ' '*2 + 29*'-' + '+' + 6*'-' + '\n'
kosten += u"%s | %s\n" % (u" Summe".ljust(30), "%2d.00" % preis)
- return kosten
+ 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())
- if not os.path.exists('output'):
- os.mkdir('output')
-
template = env.get_template('teilnehmerbeitrag.eml')
for id, vorname, nachname, email, tshirt, zipper in \
conn.execute("SELECT id, vorname, nachname, email, tshirt, zipper FROM teilnehmer WHERE emailsent = 0"):
- with open(os.path.join('output', email), 'w') as f:
+ 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_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=gen_rechnung(tshirt, zipper)).encode('utf-8'))
+ 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 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")
+
+ # Modus
+ group = parser.add_mutually_exclusive_group(required=True)
+ group.add_argument('--importcsv', action='store_true',
+ help='Importiere neue Teilnehmer aus CSV')
+ group.add_argument('--nametag', action='store_true',
+ help='Generiere Nametags')
+ group.add_argument('--email', action='store_true',
+ 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')
+ parser.add_argument('-i', '--input',
+ 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 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)
+ import_teilnehmer(args.input)
if __name__ == '__main__':
- create_mail()
-
+ main()
+
+# vim: set expandtab :