]> git.siccegge.de Git - teilnehmertool.git/blob - teilnehmertool.py
extra packliste := verkleinerte teilnehmerliste
[teilnehmertool.git] / teilnehmertool.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 import argparse
5 import sqlite3
6 import datetime
7 import csv
8 import string
9 import jinja2
10 import os
11 import os.path
12 import re
13 import sys
14
15 import csv
16
17 conn = None
18
19
20 env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates', encoding='utf-8'))
21
22
23 ## jinja2 TeX espaping from http://flask.pocoo.org/snippets/55/
24 LATEX_SUBS = [
25 (re.compile(r'\\'), r'\\textbackslash{}'),
26 (re.compile(r'([{}_#%&$])'), r'\\\1'),
27 (re.compile(r'~'), r'\~{}'),
28 (re.compile(r'\^'), r'\^{}'),
29 (re.compile(r'"'), r"''"),
30 (re.compile(r'\.\.\.+'), r'\\ldots'),
31 ]
32
33 def escape_tex(value):
34 newval = value
35 for pattern, replacement in LATEX_SUBS:
36 newval = pattern.sub(replacement, newval)
37 return newval
38
39 env.filters['escape_tex'] = escape_tex
40
41
42 ## dont judge me. i don't see any good way sadly
43 VERANSTALTUNGSLEITER = {
44 }
45
46 def is_veranstaltungsleiter(row):
47 if VERANSTALTUNGSLEITER.has_key(row['username']):
48 return True
49 return False
50
51
52 def create_helfer_nametags(csvpath, outdir='helfer_nametags'):
53 template = env.get_template('nametag.svg')
54
55 with open(csvpath, 'r') as csvfile:
56 csvreader = csv.DictReader(csvfile, delimiter=',', quotechar='"')
57 uni = "FAU Erlangen"
58
59 for row in csvreader:
60 if is_veranstaltungsleiter(row):
61 nick = "%s %s" % (VERANSTALTUNGSLEITER[row['username']][0], VERANSTALTUNGSLEITER[row['username']][1])
62 with open(os.path.join(outdir, "%s.svg" % nick), 'w') as f:
63 f.write(template.render(nick=nick.decode('utf-8'), uni1=uni.decode('utf-8')).encode('utf-8'))
64 nick = "%s" % (row['username'])
65
66 with open(os.path.join(outdir, "%s.svg" % nick), 'w') as f:
67 f.write(template.render(nick=nick.decode('utf-8'), uni1=uni.decode('utf-8')).encode('utf-8'))
68
69
70 def import_teilnehmer(input):
71 ids = set([ i[0] for i in conn.execute('SELECT id FROM teilnehmer').fetchall() ])
72
73 with open(input) as f:
74 reader = csv.reader(f, delimiter=';', quotechar='"')
75 for row in reader:
76 if row[0] == '#':
77 continue
78 if not int(row[0]) in ids:
79 print "Importing %s" % (row, )
80 conn.execute("INSERT INTO teilnehmer VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
81 row[:-2] + ['Kein T-Shirt', 'Kein Pulli'] + row[-2:] + [0, 0, 0, "", "false"])
82
83 conn.commit()
84
85 def mark_pay(outdir):
86 betrag = int(raw_input("Betrag: "))
87
88 template = env.get_template('eingangsbestaetigung.eml')
89
90 while True:
91 uid = raw_input("User: ")
92 if uid == "":
93 break
94 uid = int(uid)
95 vorname, nachname, email, bezahlt = \
96 conn.execute("SELECT vorname, nachname, email, bezahlt FROM teilnehmer WHERE id = ?", [uid]).fetchone()
97
98 if bezahlt == betrag:
99 continue
100
101 conn.execute("UPDATE teilnehmer SET bezahlt = ? WHERE id = ?", [betrag, uid])
102
103
104 with open(os.path.join(outdir, email), 'w') as f:
105 f.write(template.render(vorname=vorname.decode('utf-8'),
106 nachname=nachname.decode('utf-8'),
107 email=email.decode('utf-8'),
108 betrag=betrag).encode('utf-8'))
109
110 conn.commit()
111
112 def create_mail(outdir='output'):
113 def gen_rechnung(tshirt, zipper):
114 preis = 25
115 kosten = u""
116 kosten += u"%s | %s\n" % (u" Konferenzbeitrag".ljust(30), "25.00")
117 kosten += u"%s | %s\n" % ((u" T-Shirt (Größe %s)" % tshirt).ljust(30), " 0.00")
118 if zipper != 'Kein Pulli':
119 kosten += u"%s | %s\n" % ((u" Kapuzenzipper (Größe %s)" % zipper).ljust(30), "25.00")
120 preis += 25
121 kosten += ' '*2 + 29*'-' + '+' + 6*'-' + '\n'
122 kosten += u"%s | %s\n" % (u" Summe".ljust(30), "%2d.00" % preis)
123
124 return kosten, preis
125
126 def gen_token(id, vorname, nachname):
127 return u"%s-%s-%s" % (id, nachname.decode('utf-8').upper(), vorname.decode('utf-8').upper())
128
129 template = env.get_template('teilnehmerbeitrag.eml')
130
131 for id, vorname, nachname, email, tshirt, zipper in \
132 conn.execute("SELECT id, vorname, nachname, email, tshirt, zipper FROM teilnehmer WHERE emailsent = 0"):
133
134 rechnung, preis = gen_rechnung(tshirt, zipper)
135
136 with open(os.path.join(outdir, email), 'w') as f:
137 f.write(template.render(vorname=vorname.decode('utf-8'),
138 nachname=nachname.decode('utf-8'),
139 email=email.decode('utf-8'),
140 token=gen_token(id, vorname, nachname),
141 rechnung=rechnung).encode('utf-8'))
142
143 conn.execute("UPDATE teilnehmer set emailsent = ?, betrag = ? WHERE id = ?", [datetime.datetime.now().isoformat(),
144 preis, id])
145 conn.commit()
146
147 def create_remind(outdir='output'):
148 def gen_rechnung(tshirt, zipper):
149 preis = 25
150 kosten = u""
151 kosten += u"%s | %s\n" % (u" Konferenzbeitrag".ljust(30), "25.00")
152 kosten += u"%s | %s\n" % ((u" T-Shirt (Größe %s)" % tshirt).ljust(30), " 0.00")
153 if zipper != 'Kein Pulli':
154 kosten += u"%s | %s\n" % ((u" Kapuzenzipper (Größe %s)" % zipper).ljust(30), "25.00")
155 preis += 25
156 kosten += ' '*2 + 29*'-' + '+' + 6*'-' + '\n'
157 kosten += u"%s | %s\n" % (u" Summe".ljust(30), "%2d.00" % preis)
158
159 return kosten, preis
160
161 def gen_token(id, vorname, nachname):
162 return u"%s-%s-%s" % (id, nachname.decode('utf-8').upper(), vorname.decode('utf-8').upper())
163
164 template = env.get_template('erinnerung.eml')
165
166 for id, vorname, nachname, email, tshirt, zipper in \
167 conn.execute("SELECT id, vorname, nachname, email, tshirt, zipper FROM teilnehmer " +
168 "WHERE bezahlt < 25 AND datetime(emailsent) < datetime(?)",
169 [(datetime.datetime.now() - datetime.timedelta(14)).isoformat()]):
170
171 rechnung, preis = gen_rechnung(tshirt, zipper)
172
173 with open(os.path.join(outdir, email), 'w') as f:
174 f.write(template.render(vorname=vorname.decode('utf-8'),
175 nachname=nachname.decode('utf-8'),
176 email=email.decode('utf-8'),
177 token=gen_token(id, vorname, nachname),
178 rechnung=rechnung).encode('utf-8'))
179
180 conn.execute("UPDATE teilnehmer set emailsent = ?, betrag = ? WHERE id = ?", [datetime.datetime.now().isoformat(),
181 preis, id])
182 conn.commit()
183
184
185 def create_nametag(outdir='output'):
186 template = env.get_template('nametag.svg')
187
188 for teiln_id, vorname, nachname, namensschild, hochschule, dochned in \
189 conn.execute("SELECT id, vorname, nachname, namensschild, hochschule, dochned FROM teilnehmer"):
190
191 if dochned != "false":
192 print >> sys.stderr, "not generating %s %s (id %s), because abgemeldet" % (vorname, nachname, teiln_id)
193 continue
194
195 with open(os.path.join(outdir, "%s.svg" % teiln_id), 'w') as f:
196 f.write(template.render(name=u"%s %s" % (vorname.decode('utf-8'),
197 nachname.decode('utf-8')),
198 nick=namensschild.decode('utf-8'),
199 uni1=hochschule.decode('utf-8')).encode('utf-8'))
200
201
202 def create_teilnehmer_list(outdir = 'output'):
203 template_full = env.get_template('teilnehmerliste.tex')
204 template_pack = env.get_template('packliste.tex')
205
206 teilnehmer = []
207 for vor, nach, nick, hochschule, betrag, bezahlt, shirtsize, zippersize, dochned, comment in \
208 conn.execute("SELECT vorname, nachname, namensschild, hochschule, betrag, bezahlt, tshirt, zipper, dochned, orga_comment FROM teilnehmer ORDER BY UPPER(hochschule) ASC, UPPER(nachname) ASC"):
209
210 vor = vor.decode('utf8')
211 nach = nach.decode('utf8')
212 nick = nick.decode('utf8')
213 hochschule = hochschule.decode('utf8')
214 ## betrag ist schon int
215 ## bezahlt ist schon int
216 shirtsize = shirtsize.decode('utf8')
217 if re.match("kein", shirtsize, flags=re.IGNORECASE):
218 shirtsize = ""
219
220 zippersize = zippersize.decode('utf8')
221 if re.match("kein", zippersize, flags=re.IGNORECASE):
222 zippersize = ""
223
224 ## string to bool..
225 if dochned == "false":
226 will_attend = True
227 else:
228 will_attend = False
229
230 comment = comment.decode('utf8')
231
232 teilnehmer.append({'vorname': vor, 'nachname': nach,
233 'hochschule': hochschule, 'nick': nick, 'betrag': betrag, 'bezahlt':
234 bezahlt, 'shirtsize': shirtsize, 'zippersize': zippersize,
235 'will_attend': will_attend, 'comment': comment})
236
237
238 with open(os.path.join(outdir, "teilnehmerliste.tex"), 'w') as out:
239 out.write(template_full.render(teilnehmer=teilnehmer).encode('utf-8'))
240
241 with open(os.path.join(outdir, "packliste.tex"), 'w') as out:
242 out.write(template_pack.render(teilnehmer=teilnehmer).encode('utf-8'))
243
244
245
246 def create_bmbf_list(outdir = 'output'):
247 template = env.get_template('bmbf-unterschriftenliste.tex')
248
249
250 teilnehmer = []
251 i = 1
252 for vor, nach, hochschule in \
253 conn.execute("SELECT vorname, nachname, hochschule FROM teilnehmer ORDER BY UPPER(nachname) ASC"):
254
255 vor = vor.decode('utf8')
256 nach = nach.decode('utf8')
257 hochschule = hochschule.decode('utf8')
258
259 teilnehmer.append({'vorname': vor, 'nachname': nach, 'num': i, 'hochschule': hochschule})
260 i = i+1
261
262
263 with open(os.path.join(outdir, "bmbf-unterschriftenliste.tex"), 'w') as out:
264 out.write(template.render(teilnehmer=teilnehmer).encode('utf-8'))
265
266
267 def main():
268 parser = argparse.ArgumentParser(description="Ultimate Teilnehmertool")
269
270 # Modus
271 group = parser.add_mutually_exclusive_group(required=True)
272 group.add_argument('--importcsv', action='store_true',
273 help='Importiere neue Teilnehmer aus CSV')
274 group.add_argument('--nametag', action='store_true',
275 help='Generiere Nametags')
276 group.add_argument('--email', action='store_true',
277 help='Generiere E-Mails mit Überweisungsinformationen')
278 group.add_argument('--pay', action='store_true',
279 help='Speichere Zahlungseingang')
280 group.add_argument('--remind', action='store_true',
281 help='Generiere Zahlungsaufforderungserinnerung')
282 group.add_argument('--bmbf', action='store_true',
283 help='Generiere BMBF-Unterschriftenliste')
284 group.add_argument('--liste', action='store_true',
285 help='Generiere Teilnehmerübersichtsliste')
286 group.add_argument('--helfer', action='store_true',
287 help='Generiere Helfer-Nametags aus helfer.csv')
288
289 # Argumente
290 parser.add_argument('--db', default='teilnehmer.sqlite',
291 help='Teilnehmerdatenbank')
292 parser.add_argument('-i', '--input',
293 help='Eingabedatei')
294 parser.add_argument('-o', '--output', default='output',
295 help='Ausgabeverzeichnis')
296
297 args = parser.parse_args()
298
299 global conn
300 conn = sqlite3.connect(args.db)
301 conn.text_factory = str
302 conn.row_factory = sqlite3.Row
303 conn.execute('pragma encoding = "UTF-8";')
304
305 if args.nametag or args.email or args.pay or args.remind or args.bmbf or \
306 args.liste or args.helfer:
307 assert(args.output)
308 if not os.path.exists(args.output):
309 os.mkdir(args.output)
310
311 if args.nametag:
312 create_nametag(args.output)
313 elif args.email:
314 create_mail(args.output)
315 elif args.pay:
316 mark_pay(args.output)
317 elif args.remind:
318 create_remind(args.output)
319 elif args.bmbf:
320 create_bmbf_list(args.output)
321 elif args.liste:
322 create_teilnehmer_list(args.output)
323 elif args.helfer:
324 assert(args.input)
325 create_helfer_nametags(args.input, args.output)
326
327 elif args.importcsv:
328 assert(args.input)
329 import_teilnehmer(args.input)
330
331 if __name__ == '__main__':
332 main()
333
334 # vim: set expandtab :