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