import tg from webob.exc import HTTPNotFound import re from bazbase import conversion, structure from bazki import util from bazki.translators import edit_url from bazki.edit import data_for_url from . import zampolit, restricted SQUARE_BRACKETS_RE = re.compile(r'\[(.*)\]$') PARENS_RE = re.compile(r' *\(..+\)') SPACE_RE = re.compile(r'[ ]+') SYMBOL_RE = re.compile(r'[^a-zA-Z0-9_]+') def propnameify(heading): match = SQUARE_BRACKETS_RE.search(heading) if match: key = match.group(1) else: key = PARENS_RE.sub('', heading) if '?' in key: key = key.rsplit('?', 1)[0] key = SPACE_RE.sub('_', key.lower()) key = SYMBOL_RE.sub('', key) return u'app_' + key def enameify(name): name = SYMBOL_RE.sub('', name) return u'App' + name DAY_RE = re.compile(r'([A-Za-z][a-z]+day)') TIME_RE = re.compile(r'([0-9]+ ?[AaPp][Mm])') def slot_enameify(slot, run): pref = u'Run%d' % run daym = DAY_RE.search(slot) assert daym is not None, slot day = daym.group(1) timem = TIME_RE.search(slot) assert timem is not None, slot return pref + day + timem.group(1) def castingbase_dict(): pcs = structure.get_element(u'PC').get_descendants() runs = structure.get_element(u'Run').get_descendants() app_parent = structure.get_element(u'App') if app_parent is not None: apps = app_parent.get_descendants() app_props = [pn for pn in app_parent.list_props() if pn.startswith(u'app_')] else: apps = [] app_props = [] return {'pcs': pcs, 'apps': apps, 'app_props': app_props, 'runs': runs} class Admin(tg.TGController): allow_only = restricted.PRED zampolit = zampolit.Zampolit() @tg.expose(template="mako:gameki.templates.email") def email(self, ename, send=False): elm = structure.get_element(ename) if elm is None: raise HTTPNotFound(ename) from . import macros from bazjunk.email import format emails = conversion.to_python(elm, u'product', 'email', 'email') msgs = [] for e in emails: atturl = e.get('attachment', None) if atturl is not None: res, res_type = data_for_url(atturl) attachment = (atturl.rsplit('/', 1)[-1], res, res_type) else: attachment = None kw = dict(msg=e['msg'], subject=e['subject'], from_addr=e['from'], to_addr=e['to'], cc=e.get('cc', None)) if send: if attachment: kw['attachment'] = attachment util.send_email(**kw) else: msgs.append((format(**kw), atturl, attachment)) if send: tg.flash('%s emails sent.' % len(emails)) tg.redirect(edit_url(ename)) else: return {'ename': ename, 'messages': msgs} @tg.expose(template="mako:gameki.templates.cast") def cast(self, apps=None): if apps is not None: import csv rows = csv.reader(apps.file) headings = rows.next() propnames = [propnameify(h) for h in headings] slots = [] for i in xrange(len(propnames)): if 'name' in propnames[i]: name_index = i break for i in xrange(len(propnames)): if 'when' in propnames[i]: when_index = i break # First pass, we're just checking for types could_be_integer = dict((pn, True) for pn in propnames) rows = list(rows) for r in rows: for i in xrange(len(r)): if not r[i].isdigit(): could_be_integer[propnames[i]] = False for i in xrange(len(propnames)): pn = propnames[i] if could_be_integer[pn]: flav = 'integer' else: flav = 'string' prop = structure.get_prop(pn) if prop is None: prop = structure.create_prop(pn, flav) else: prop.set_flavor(flav) prop.set_comment(headings[i]) parent = structure.get_element('App') if parent is None: parent = structure.get_root_element().create_child(u'App') for pn in propnames: parent.set_prop(pn, '') # Second pass, create some elements. for r in rows: if not r[name_index]: continue ename = enameify(r[name_index]) assert r[when_index], r whens = [w.strip() for w in r[when_index].split(',')] for wi in xrange(len(whens)): if whens[wi] not in slots: if wi > 0: slots.insert(slots.index(whens[wi - 1]) + 1, whens[wi]) else: slots.insert(0, whens[wi]) elm = structure.get_element(ename) if elm is None: elm = parent.create_child(ename) appending = False else: appending = True for i in xrange(len(r)): pn = propnames[i] val = r[i] if appending: old_val = elm.get_prop(pn) if old_val.strip(): val = old_val + '; ' + val elm.set_prop(pn, val) elm.set_prop('availability', ', '.join('[[%s]]' % slot_enameify(w, 1) for w in whens).encode('utf-8')) run_parent = structure.get_element(u'Run') for s in slots: slot_ename = slot_enameify(s, 1) run_parent.create_child(slot_ename).set_prop(u'name', s) return castingbase_dict() @tg.expose(template="mako:gameki.templates.casting") def casting(self): return castingbase_dict()