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