Example #1
0
def check_email():
    comm_ids = [_id(x) for x in Es.by_name('comms').get_bearers()]
    list_ids = [_id(x) for x in Es.by_name('lists-opted').get_bearers()]
    with open('check-email.template') as f:
        template_text = cStringIO()
        for line in f:
            if line.endswith("\\\n"):
                template_text.write(line[:-2])
            else:
                template_text.write(line)
        templ = Template(template_text.getvalue())
    for m in args_to_users(sys.argv[1:]):
        rels = m.get_related()
        rels = sorted(rels, key=lambda x: Es.entity_humanName(x['with']))
        comms = []
        lists = []
        others = []
        for rel in rels:
            if Es.relation_is_virtual(rel):
                continue
            if _id(rel['with']) in comm_ids:
                comms.append(rel)
            elif _id(rel['with']) in list_ids:
                lists.append(rel)
            else:
                others.append(rel)
        print(m.name)
        em = templ.render(Context({
            'u': m,
            'comms': comms,
            'lists': lists,
            'others': others}))
        send_mail('Controle Karpe Noktem ledenadministratie',
                  em, '*****@*****.**',
                  [m.primary_email])
Example #2
0
def check_email():
    comm_ids = [_id(x) for x in Es.by_name('comms').get_bearers()]
    list_ids = [_id(x) for x in Es.by_name('lists-opted').get_bearers()]
    for m in args_to_users(sys.argv[1:]):
        rels = m.get_related()
        rels = sorted(rels, key=lambda x: Es.entity_humanName(x['with']))
        comms = []
        lists = []
        others = []
        for rel in rels:
            if Es.relation_is_virtual(rel):
                continue
            if _id(rel['with']) in comm_ids:
                comms.append(rel)
            elif _id(rel['with']) in list_ids:
                lists.append(rel)
            else:
                others.append(rel)
        print(m.name)
        render_then_email('leden/check-email.mail.html',
                          m.email, {
                              'u': m,
                              'comms': comms,
                              'lists': lists,
                              'others': others
                          },
                          from_email='*****@*****.**')
Example #3
0
def send_reminder(vacancy, update=True):
    to = vacancy.assignee.get_user()
    e = vacancy.event
    p = vacancy.pool
    edate = e.date.strftime('%A %d %B')
    msgfmt = p.reminder_format
    msg = msgfmt % {
        'firstName': to.first_name,
        'date': edate,
        'time': vacancy.begin_time,
        'vacancyName': vacancy.name,
        'eventName': e.name
    }
    ccs = map(lambda x: Es.by_name(x).canonical_full_email, p.reminder_cc)
    subj = '%s, %s' % (vacancy.name.capitalize(), edate)
    em = EmailMessage(subj,
                      msg,
                      to=[to.canonical_full_email],
                      headers={
                          'Reply-To':
                          Es.by_name(p.administrator).canonical_full_email,
                          'CC': ', '.join(ccs)
                      },
                      bcc=ccs)
    em.send()
    if update:
        vacancy.reminder_needed = False
        vacancy.save()
Example #4
0
def main():
    N = 0
    while True:
        N += 1
        g = Es.by_name('leden%s' % N)
        if g is None:
            break
    data = [[0 for i in range(1, N)] for j in range(1, N)]
    groups = list()
    for i in range(1, N):
        groups.append(Es.by_name('leden%s' % i).get_members())
    users = reduce(lambda x, y: x + y, groups, [])
    groups = [frozenset(x) for x in groups]
    for user in frozenset(users):
        first = None
        for i in range(1, N):
            if user in groups[i - 1]:
                if first is None:
                    first = i
                data[first - 1][i - 1] += 1
    for r in data:
        print('\t'.join(map(str, r)))
    print()
    for y in range(len(data)):
        m = data[y][y]
        row = []
        for sy in range(len(data) - y):
            row.append(data[y][y + sy] * 100 / m)
        print('\t'.join(map(str, row)))
Example #5
0
def overview(request):
    """ This view is used to show the overview of the lists to be moderated,
        but also to toggle moderation (via the toggle POST variable) and
        to renew moderation (via the renew POST variable). """
    toggle_with_name = None
    renew_with_name = None
    moderators = Es.by_name(settings.MODERATORS_GROUP)

    # Check for renew/toggle in POST
    if request.user.is_related_with(Es.by_name(settings.MODERATORS_GROUP)):
        is_moderator = True
        if request.method == 'POST':
            if 'toggle' in request.POST:
                toggle_with_name = request.POST['toggle']
            if 'renew' in request.POST:
                renew_with_name = request.POST['renew']
    else:
        is_moderator = False
    lists = []

    # Check current state of mailling lists
    ml_state = giedo.maillist_get_moderated_lists()

    if six.PY3:
        # hans is running Python 2, so we will get bytes() instead of str()s,
        # lets convert it to strings for Python 3.
        ml_state = {
            name.decode(): {
                key.decode(): val.decode() if isinstance(val, str) else val
                for key, val in entry.items()
            } for name, entry in ml_state.items()
        }

    for name in sorted(ml_state):
        r = mod_Es.by_name(name)
        if toggle_with_name == name:
            if ml_state[name]['modmode']:
                _deactivate_mm(name, request.user, r, moderators)
            else:
                r = _activate_mm(name, request.user, r, moderators)
            ml_state[name]['modmode'] = not ml_state[name]['modmode']
        if renew_with_name == name and ml_state[name]['modmode']:
            r = _renew_mm(name, request.user, r, moderators)
        by = None if r is None else r.by
        remaining = (
            None if r is None else
            r.at - datetime.datetime.now() + settings.MOD_RENEW_INTERVAL)
        lists.append({
            'name': name,
            'by': by,
            'remaining': remaining,
            'real_name': ml_state[name]['real_name'],
            'modmode': ml_state[name]['modmode'],
            'description': ml_state[name]['description'],
            'queue': ml_state[name]['queue']
        })
    return render_to_response('moderation/overview.html',
                              {'lists': lists,
                               'is_moderator': is_moderator},
                              context_instance=RequestContext(request))
Example #6
0
def check_email():
    comm_ids = [_id(x) for x in Es.by_name('comms').get_bearers()]
    list_ids = [_id(x) for x in Es.by_name('lists-opted').get_bearers()]
    for m in args_to_users(sys.argv[1:]):
        rels = m.get_related()
        rels = sorted(rels, key=lambda x: Es.entity_humanName(x['with']))
        comms = []
        lists = []
        others = []
        for rel in rels:
            if Es.relation_is_virtual(rel):
                continue
            if _id(rel['with']) in comm_ids:
                comms.append(rel)
            elif _id(rel['with']) in list_ids:
                lists.append(rel)
            else:
                others.append(rel)
        print(m.name)
        render_then_email('leden/check-email.mail.html',
                          m.email,
                          {'u': m,
                           'comms': comms,
                           'lists': lists,
                           'others': others},
                          from_email='*****@*****.**')
Example #7
0
def main():
    N = 0
    while True:
        N += 1
        g = Es.by_name("leden%s" % N)
        if g is None:
            break
    data = [[0 for i in xrange(1, N)] for j in xrange(1, N)]
    groups = list()
    for i in xrange(1, N):
        groups.append(Es.by_name("leden%s" % i).get_members())
    users = reduce(lambda x, y: x + y, groups, [])
    groups = map(frozenset, groups)
    for user in frozenset(users):
        first = None
        for i in xrange(1, N):
            if user in groups[i - 1]:
                if first is None:
                    first = i
                data[first - 1][i - 1] += 1
    for r in data:
        print "\t".join(map(str, r))
    print
    for y in xrange(len(data)):
        m = data[y][y]
        row = []
        for sy in xrange(len(data) - y):
            row.append(data[y][y + sy] * 100 / m)
        print "\t".join(map(str, row))
Example #8
0
def fin_check_names():
    users = Es.by_name('leden').as_group().get_members()
    comms = Es.by_name('comms').as_tag().get_bearers()
    req = moniek_pb2.FinNamesList()
    req.user.extend([six.text_type(user.humanName) for user in users])
    req.group.extend([six.text_type(com.humanName) for com in comms])
    return giedo.FinCheckNames(req)
Example #9
0
def overview(request):
    """ This view is used to show the overview of the lists to be moderated,
        but also to toggle moderation (via the toggle POST variable) and
        to renew moderation (via the renew POST variable). """
    toggle_with_name = None
    renew_with_name = None
    moderators = Es.by_name(settings.MODERATORS_GROUP)

    # Check for renew/toggle in POST
    if request.user.is_related_with(Es.by_name(settings.MODERATORS_GROUP)):
        is_moderator = True
        if request.method == 'POST':
            if 'toggle' in request.POST:
                toggle_with_name = request.POST['toggle']
            if 'renew' in request.POST:
                renew_with_name = request.POST['renew']
    else:
        is_moderator = False
    lists = []

    # Check current state of mailling lists
    ml_state = giedo.maillist_get_moderated_lists()

    if six.PY3:
        # hans is running Python 2, so we will get bytes() instead of str()s,
        # lets convert it to strings for Python 3.
        ml_state = {
            name.decode(): {
                key.decode(): val.decode() if isinstance(val, str) else val
                for key, val in entry.items()
            }
            for name, entry in ml_state.items()
        }

    for name in sorted(ml_state):
        r = mod_Es.by_name(name)
        if toggle_with_name == name:
            if ml_state[name]['modmode']:
                _deactivate_mm(name, request.user, r, moderators)
            else:
                r = _activate_mm(name, request.user, r, moderators)
            ml_state[name]['modmode'] = not ml_state[name]['modmode']
        if renew_with_name == name and ml_state[name]['modmode']:
            r = _renew_mm(name, request.user, r, moderators)
        by = None if r is None else r.by
        remaining = (None if r is None else r.at - datetime.datetime.now() +
                     settings.MOD_RENEW_INTERVAL)
        lists.append({
            'name': name,
            'by': by,
            'remaining': remaining,
            'real_name': ml_state[name]['real_name'],
            'modmode': ml_state[name]['modmode'],
            'description': ml_state[name]['description'],
            'queue': ml_state[name]['queue']
        })
    return render(request, 'moderation/overview.html', {
        'lists': lists,
        'is_moderator': is_moderator
    })
Example #10
0
 def handle(self, d):
     with self.operation_lock:
         if d['type'] == 'sync':
             return self.sync()
         elif d['type'] == 'setpass':
             u = Es.by_name(d['user'])
             if u is None:
                 return {'error': 'no such user'}
             u = u.as_user()
             if not u.check_password(d['oldpass']):
                 return {'error': 'wrong old password'}
             u.set_password(d['newpass'])
             d2 = {'type': 'setpass',
                   'user': d['user'],
                   'pass': d['newpass']}
             self.daan.send(d2)
             self.cilia.send(d2)
             return {'success': True}
         elif d['type'] == 'set-villanet-password':
             u = Es.by_name(d['user'])
             if u is None:
                 return {'error': 'no such user'}
             u = u.as_user()
             if not u.check_password(d['oldpass']):
                 return {'error': 'wrong current password'}
             pc = Es.PushChange({'system': 'villanet',
                 'action': 'changeUser', 'data': {
                     'username': d['user'],
                     'password': self.villanet_encrypt_password(d['newpass'])
                         }})
             pc.save()
             self.push_changes_event.set()
             return {'success': True}
         elif d['type'] == 'fotoadmin-move-fotos':
             # TODO should this block Giedo?
             ret = self.daan.send(d)
             if 'success' not in ret:
                 return ret
             return self.cilia.send({
                 'type': 'fotoadmin-remove-moved-fotos',
                 'user': d['user'],
                 'dir': d['dir']})
         elif d['type'] == 'openvpn_create':
             # XXX hoeft niet onder de operation_lock
             u = Es.by_name(d['user'])
             if u is None:
                 return {'error': 'no such user'}
             u = u.as_user()
             if d['want'] == 'exe':
                 create_openvpn_installer(self, u)
             else:
                 create_openvpn_zip(self, u)
         elif d['type'] == 'update-site-agenda':
             return update_site_agenda(self)
         elif d['type'] in ['update-knsite', 'update-knfotos',
                 'fotoadmin-create-event']:
             return self.daan.send(d)
         else:
             logging.warn("Unknown command: %s" % d['type'])
Example #11
0
def fin_check_names():
    users = Es.by_name('leden').as_group().get_members()
    comms = Es.by_name('comms').as_tag().get_bearers()

    return get_giedo_connection().send({
        'type': 'fin-check-names',
        'names': {
            'user': [six.text_type(user.humanName) for user in users],
            'group': [six.text_type(com.humanName) for com in comms]
        }})
Example #12
0
def fin_check_names():
    users = Es.by_name('leden').as_group().get_members()
    comms = Es.by_name('comms').as_tag().get_bearers()

    return get_giedo_connection().send({
        'type': 'fin-check-names',
        'names': {
            'user': [six.text_type(user.humanName) for user in users],
            'group': [six.text_type(com.humanName) for com in comms]
        }
    })
Example #13
0
 def may_manage(self, user):
     '''
     Is this user allowed to manage this pool?
     '''
     if 'secretariaat' in user.cached_groups_names:
         return True
     if self.administrator in user.cached_groups_names:
         return True
     if user.is_related_with(Es.by_name(self.name),
                             how=Es.by_name('!brand-planner')):
         return True
     return False
Example #14
0
def main():
    oud = Es.by_name('oud')
    cur_leden, old_leden = Es.by_name('leden').get_current_and_old_members()
    cur_oud, old_oud = oud.get_current_and_old_members()
    for m in old_leden - old_oud - cur_oud:
        print(m.name)

        Es.rcol.insert({'who': Es._id(m),
                        'with': Es._id(oud),
                        'how': None,
                        'from': Es.now(),
                        'until': None})
Example #15
0
 def may_manage(self, user):
     '''
     Is this user allowed to manage this pool?
     '''
     if 'secretariaat' in user.cached_groups_names:
         return True
     if self.administrator in user.cached_groups_names:
         return True
     if user.is_related_with(Es.by_name(self.name),
                             how=Es.by_name('!brand-planner')):
         return True
     return False
Example #16
0
def main():
    oud = Es.by_name('oud')
    cur_leden, old_leden = Es.by_name('leden').get_current_and_old_members()
    cur_oud, old_oud = oud.get_current_and_old_members()
    for m in old_leden - old_oud - cur_oud:
        print(m.name)

        Es.rcol.insert({
            'who': Es._id(m),
            'with': Es._id(oud),
            'how': None,
            'from': Es.now(),
            'until': None
        })
Example #17
0
def overview(request):
    toggle_with_name = None
    renew_with_name = None
    moderators = Es.by_name(settings.MODERATORS_GROUP)
    if (request.user.is_related_with(Es.by_name(
            settings.MODERATORS_GROUP))):
        is_moderator = True
        if request.method == 'POST':
            if 'toggle' in request.POST:
                toggle_with_name = request.POST['toggle']
            if 'renew' in request.POST:
                renew_with_name = request.POST['renew']
    else:
        is_moderator = False
    lists = []
    for name in settings.MODED_MAILINGLISTS:
        r = mod_Es.by_name(name)
        ml = Mailman.MailList.MailList(name, True)
        try:
            if toggle_with_name == name:
                if  ml.emergency:
                    _deactivate_mm(ml, name, request.user,
                            r, moderators)
                else:
                    r = _activate_mm(ml, name, request.user,
                            r, moderators)
            if renew_with_name == name:
                r = _renew_mm(ml, name, request.user, r,
                        moderators)
            by = None if r is None else r.by
            remaining = (None if r is None else r.at +
                settings.MOD_RENEW_INTERVAL -
                datetime.datetime.now())
            until = (None if r is None else r.at +
                    settings.MOD_RENEW_INTERVAL)
            lists.append({'name': name,
                      'real_name': ml.real_name,
                      'modmode': ml.emergency,
                      'by': by,
                      'remaining': remaining,
                      'description': ml.description,
                      'queue': len(ml.GetHeldMessageIds())})
        finally:
            ml.Unlock()
    return render_to_response('moderation/overview.html',
            {'lists': lists,
             'is_moderator': is_moderator},
            context_instance=RequestContext(request))
Example #18
0
def generate_forum_changes(self):
        users = dict()
        creds = settings.FORUM_MYSQL_CREDS
        dc = MySQLdb.connect(creds[0], user=creds[1],
                        passwd=creds[2], db=creds[3])
        c = dc.cursor()
        c.execute("SELECT username, realname FROM users")
        todo = {'add': [], 'remove': [], 'update-realname': []}

        cur, old = Es.by_name('leden').get_current_and_old_members()
        for m in itertools.chain(cur, old):
                users[str(m.name)] = m
        for user, realname in c.fetchall():
                user = user.lower()
                if realname is not None:
                        realname = realname.decode('latin1')
                if user not in users:
                        if user == 'guest':
                                continue
                        todo['remove'].append(user)
                        logging.info("forum: removing user %s", user)
                else:
                        if users[user].humanName != realname:
                                todo['update-realname'].append((user,
                                        unicode(users[user].humanName)))
                        del users[user]
        for name, user in users.iteritems():
                todo['add'].append((name, unicode(user.humanName),
                                        user.canonical_email))
        c.close()
        dc.close()
        return todo
Example #19
0
def main():
    now = Es.now()
    member_age = {}
    for rel in Es.query_relations(-1,
                                  Es.by_name('leden'),
                                  None,
                                  None,
                                  deref_who=True):
        if not rel['from']:
            rel['from'] = Es.DT_MIN
        if rel['who'] not in member_age:
            member_age[rel['who']] = Es.DT_MAX
        member_age[rel['who']] = rel['from']
    l = []
    for m, age in member_age.iteritems():
        if not m.dateOfBirth:
            continue
        print(age - m.dateOfBirth).days / 365.242, unicode(m.name)
        l.append((age - m.dateOfBirth).days / 365.242)
    print 'avg', sum(l) / len(l)
    print 'med', sorted(l)[len(l) / 2]
    print '1st', sorted(l)[len(l) / 4 * 2]
    print '3rd', sorted(l)[len(l) / 4 * 3]
    print 'min', min(l)
    print 'max', max(l)
Example #20
0
def generate_quassel_changes(giedo):
    if not settings.QUASSEL_CONFIGDIR:
        logging.warning('quassel: no config dir available, skipping')
        return None
    db_path = os.path.join(
        settings.QUASSEL_CONFIGDIR,
        'quassel-storage.sqlite')
    if not os.path.exists(db_path):
        logging.warn('quassel: %s does not exist. Skipping.', db_path)
        return None

    # Check which users are currently on the core
    conn = sqlite3.connect(db_path)
    c = conn.cursor()
    have = set()
    try:
        for username, in c.execute("SELECT username FROM quasseluser"):
            have.add(username)
    except sqlite3.OperationalError:
        logging.exception("Operational error.")
        return {'add': [], 'remove': []}

    # Check which should be on the core
    want = set([str(e.name) for e in Es.by_name('leden').get_members()])

    # Done!
    return {'add': list(want - have),
            'remove': list(have - want)}
Example #21
0
def get_add_event_form(user, superuser=False):
    if superuser:
        choices = sorted(Es.groups(), lambda x, y: cmp(unicode(x.humanName), unicode(y.humanName))) + sorted(
            Es.by_name("leden").get_members(), lambda x, y: cmp(unicode(x.humanName), unicode(y.humanName))
        )
    else:
        choices = [user] + sorted(user.cached_groups, cmp=lambda x, y: cmp(unicode(x.humanName), unicode(y.humanName)))

    class AddEventForm(forms.Form):
        name = forms.RegexField(label="Korte naam", regex=r"^[a-z0-9-]+$")
        humanName = forms.CharField(label="Naam")
        description = forms.CharField(label="Beschrijving", widget=forms.Textarea)
        mailBody = forms.CharField(
            label="E-Mail",
            widget=forms.Textarea,
            initial="Hallo %(firstName)s,\n\n"
            + "Je hebt je aangemeld voor %(eventName)s.\n"
            + "\n"
            + "Je opmerkingen waren:\n"
            + "%(notes)s\n"
            + "\n"
            + "Met een vriendelijke groet,\n\n"
            + "%(owner)s",
        )
        cost = forms.DecimalField(label="Kosten")
        date = forms.DateField(label="Datum")
        owner = EntityChoiceField(label="Eigenaar", choices=choices)

    return AddEventForm
Example #22
0
def main():
    leden = Es.by_name('leden')
    lut = {}
    id2name = {}
    for m in Es.users():
        if not m.name:
            continue
        lut[str(m.name)] = set()
        id2name[m._id] = str(m.name)
    max_q = Es.date_to_year(Es.now()) * 4
    for q in range(1, max_q + 1):
        start, end = Es.quarter_to_range(q)
        for m in leden.get_rrelated(_from=start,
                                    until=end,
                                    how=None,
                                    deref_who=False,
                                    deref_with=False,
                                    deref_how=False):
            lut[id2name[m['who']]].add(q)
    for i, name in enumerate(sorted(six.itervalues(id2name))):
        if i % 20 == 0:
            print()
            print('%20s %s' % ('year', ' '.join([
                str(((q - 1) / 4) + 1).ljust(7)
                for q in range(1, max_q + 1, 4)
            ])))
            print('%20s %s' % ('quarter', ' '.join(
                [str(((q - 1) % 4) + 1) for q in range(1, max_q + 1)])))
        print('%-20s %s' % (name, ' '.join(
            ['*' if q in lut[name] else ' ' for q in range(1, max_q + 1)])))
Example #23
0
def main():
    writer = csv.writer(sys.stdout)
    writer.writerow(['gebruikersnaam',
                     'voornaam',
                     'achternaam',
                     'instituut',
                     'studierichting',
                     'studentnummer'])
    leden = Es.by_name('leden').get_members()
    leden.sort(cmp=lambda x,y: cmp(str(x.name), str(y.name)))
    now = datetime.datetime.now()
    for m in leden:
        if not m.is_user:
            continue
        ok = False
        if m.studies:
            for study in m.studies:
                if ((study['from'] and study['from'] > now)
                        or (study['until'] and study['until'] < now)):
                    continue
                writer.writerow(
                        [str(m.name),
                         m.first_name.encode('utf-8'),
                         m.last_name.encode('utf-8'),
                         unicode(study['institute'].humanName).encode('utf-8'),
                         unicode(study['study'].humanName).encode('utf-8'),
                         study['number']])
                ok = True
                break
        if not ok:
            writer.writerow([str(m.name),
                             m.first_name.encode('utf-8'),
                             m.last_name.encode('utf-8') ])
            continue
Example #24
0
def main2():
    rels = list(
        Es.query_relations(-1,
                           Es.by_name('comms').get_bearers(),
                           None,
                           now(),
                           deref_who=True,
                           deref_with=True))
    lut = {}
    for rel in rels:
        if rel['from'] is None:
            rel['from'] = Es.DT_MIN
        if not rel['with'] in lut:
            lut[rel['with']] = {}
        v = (now() - rel['from']).days / 365.0
        if rel['who'] not in lut[rel['with']] or \
                lut[rel['with']][rel['who']] > v:
            lut[rel['with']][rel['who']] = v

    pairs = lut.items()
    for comm, members in pairs:
        print(six.text_type(comm.humanName))
        mpairs = members.items()
        mpairs.sort(key=lambda x: x[1])
        for member, time in mpairs:
            print(' %-20s%.2f' % (member.name, time))
Example #25
0
def main():
    N = 0
    ages = set([None])
    data = []
    while True:
        current = {None: 0}
        N += 1
        g = Es.by_name('leden%s' % N)
        if g is None:
            break
        start_dt, end_dt = Es.year_to_range(N)
        for m in g.get_members():
            if m.dateOfBirth is None:
                continue
            age = int((start_dt - m.dateOfBirth).days / 365.242)
            if age not in current:
                current[age] = 0
            if age not in ages:
                ages.add(age)
            current[age] += 1
        data.append(current)
    if None in ages:
        ages.remove(None)
    with open('age-per-year.txt', 'w') as f:
        f.write('#  ?')
        for age in range(min(*ages), max(*ages)):
            f.write(' ' + str(age))
        f.write('\n')
        for _year, d in enumerate(data):
            year = _year + 1
            f.write('%s %s ' % (year, d.get(None, 0)))
            for age in range(min(*ages), max(*ages)):
                f.write('%2d ' % d.get(age, 0))
            f.write('\n')
    g = pyx.graph.graphxy(width=14, x=pyx.graph.axis.bar())
    colass = {}
    for i, age in enumerate(range(min(*ages) + 1, max(*ages))):
        colass['y%s' % age] = i + 2
    styles = [pyx.graph.style.bar([
        pyx.color.gradient.ReverseHue.select(
            0, max(*ages) - min(*ages))])]
    for i, age in enumerate(range(min(*ages) + 1, max(*ages))):
        styles.extend([pyx.graph.style.stackedbarpos('y%s' % age),
                       pyx.graph.style.bar([
                           pyx.color.gradient.ReverseHue.select(
                               i + 1, max(*ages) - min(*ages))])])
    cdata = []
    for d in data:
        cum = 0
        d2 = {}
        for age in range(min(*ages), max(*ages)):
            cum += d.get(age, 0)
            d2[age] = cum
        cdata.append(d2)
    g.plot(pyx.graph.data.points(
        [[_year + 1] + [d.get(age, 0)
                        for age in range(min(*ages), max(*ages))]
         for _year, d in enumerate(cdata)],
        xname=0, y=1, **colass), styles)
    g.writePDFfile('age-per-year')
Example #26
0
def main():
    writer = csv.writer(sys.stdout)
    writer.writerow(['gebruikersnaam',
                     'voornaam',
                     'achternaam',
                     'instituut',
                     'studierichting',
                     'studentnummer'])
    leden = Es.by_name('leden').get_members()
    leden.sort(key=lambda x: str(x.name))
    now = datetime.datetime.now()
    for m in leden:
        if not m.is_user:
            continue
        ok = False
        if m.studies:
            for study in m.studies:
                if ((study['from'] and study['from'] > now)
                        or (study['until'] and study['until'] < now)):
                    continue
                writer.writerow(
                    [str(m.name),
                     m.first_name.encode('utf-8'),
                     m.last_name.encode('utf-8'),
                     text_type(study['institute'].humanName).encode('utf-8'),
                     text_type(study['study'].humanName).encode('utf-8'),
                     study['number']])
                ok = True
                break
        if not ok:
            writer.writerow([str(m.name),
                             m.first_name.encode('utf-8'),
                             m.last_name.encode('utf-8')])
            continue
Example #27
0
def generate_wiki_changes():
    creds = settings.WIKI_MYSQL_SECRET
    if not creds:
        logging.warning('wiki: no credentials available, skipping')
        return None
    users = dict()
    id2name = dict()
    dc = pymysql.connect(host=creds[0],
                         user=creds[1],
                         password=creds[2],
                         db=creds[3],
                         charset='utf8')
    try:
        with dc.cursor() as c:
            c.execute("SELECT user_id, user_name FROM user")
            todo = daan_pb2.WikiChanges()

            cur, old = Es.by_name('leden').get_current_and_old_members()
            for m in itertools.chain(cur, old):
                if str(m.name) == 'admin':
                    logging.warning("wiki can't handle an admin user")
                    continue
                users[str(m.name)] = m
            ausers = set([u for u in users if users[u].is_active])

            for uid, user in c.fetchall():
                user = user.lower()
                if six.PY3:
                    user = user.decode()
                if user not in users:
                    if user == 'admin':
                        continue
                    todo.remove.append(user)
                    logging.info("wiki: removing user %s", user)
                else:
                    id2name[uid] = user
                    del users[user]
            for name, user in six.iteritems(users):
                todo.add.append(
                    daan_pb2.WikiUser(name=name,
                                      humanName=six.text_type(user.humanName),
                                      email=user.canonical_email))

            c.execute(
                """SELECT ug_user FROM user_groups
                         WHERE ug_group=%s""", 'leden')
            for uid, in c.fetchall():
                if uid not in id2name:
                    continue
                user = id2name[uid]
                if user not in ausers:
                    todo.deactivate.append(user)
                else:
                    ausers.remove(user)

            for name in ausers:
                todo.activate.append(name)
    finally:
        dc.close()
    return todo
Example #28
0
def generate_ldap_changes(giedo):
    if not settings.LDAP_PASS:
        logging.warning('ldap: no credentials available, skipping')
        return None
    todo = {'upsert': [], 'remove': []}
    ld = ldap.initialize(settings.LDAP_URL)
    ld.bind_s(settings.LDAP_USER, settings.LDAP_PASS)
    try:
        users = Es.by_name('leden').get_members()
        unaccounted_for = set()
        in_ldap = {}
        for dn, entry in ld.search_s(settings.LDAP_BASE, ldap.SCOPE_ONELEVEL):
            unaccounted_for.add(entry['uid'][0])
            in_ldap[(entry['uid'][0])] = (entry['uid'][0], entry['mail'][0],
                                          entry['sn'][0], entry['cn'][0])
        for u in users:
            uid = str(u.name).encode('utf-8')
            should_have = (uid, u.canonical_email.encode('utf-8'),
                           u.last_name.encode('utf-8'),
                           six.text_type(u.humanName).encode('utf-8'))
            if uid in unaccounted_for:
                unaccounted_for.remove(uid)
                if in_ldap[uid] == should_have:
                    continue
                logging.info('ldap: updating %s', uid)
            else:
                logging.info('ldap: adding %s', uid)
            todo['upsert'].append(should_have)

        for uid in unaccounted_for:
            todo['remove'].append(uid)
            logging.info('ldap: removing %s', uid)
    finally:
        ld.unbind_s()
    return todo
Example #29
0
def generate_forum_changes(self):
    creds = settings.FORUM_MYSQL_SECRET
    if not creds:
        logging.warning('forum: no credentials available, skipping')
        return None
    users = dict()
    dc = MySQLdb.connect(creds[0], user=creds[1], passwd=creds[2], db=creds[3])
    c = dc.cursor()
    c.execute("SELECT username, realname FROM users")
    todo = {'add': [], 'remove': [], 'update-realname': []}

    cur, old = Es.by_name('leden').get_current_and_old_members()
    for m in itertools.chain(cur, old):
        users[str(m.name)] = m
    for user, realname in c.fetchall():
        user = user.lower()
        if realname is not None:
            realname = realname.decode('latin1')
        if user not in users:
            if user == 'guest':
                continue
            todo['remove'].append(user)
            logging.info("forum: removing user %s", user)
        else:
            if users[user].humanName != realname:
                todo['update-realname'].append(
                    (user, unicode(users[user].humanName)))
            del users[user]
    for name, user in users.iteritems():
        todo['add'].append(
            (name, unicode(user.humanName), user.canonical_email))
    c.close()
    dc.close()
    return todo
Example #30
0
def main():
    writer = csv.writer(sys.stdout)
    writer.writerow(['gebruikersnaam',
                     'voornaam',
                     'achternaam',
                     'van',
                     'tot',
                     'instituut',
                     'studierichting',
                     'studentnummer'])
    leden = Es.by_name('leden').get_members()
    leden.sort(key=lambda x: str(x.name))
    for m in leden:
        if not m.is_user:
            continue
        if not m.studies:
            writer.writerow([m.name, m.humanName])
            continue
        for study in m.studies:
            writer.writerow(
                [str(m.name),
                 m.first_name.encode('utf-8'),
                 m.last_name.encode('utf-8'),
                 study['from'].date() if study['from'] else '',
                 study['until'].date() if study['until'] else '',
                 six.text_type(study['institute'].humanName),
                 six.text_type(study['study'].humanName),
                 study['number']])
Example #31
0
def main2():
    rels = list(Es.query_relations(-1,
                                   Es.by_name('comms').get_bearers(),
                                   None,
                                   now(),
                                   deref_who=True,
                                   deref_with=True))
    lut = {}
    for rel in rels:
        if rel['from'] is None:
            rel['from'] = Es.DT_MIN
        if not rel['with'] in lut:
            lut[rel['with']] = {}
        v = (now() - rel['from']).days / 365.0
        if rel['who'] not in lut[rel['with']] or \
                lut[rel['with']][rel['who']] > v:
            lut[rel['with']][rel['who']] = v

    pairs = lut.items()
    for comm, members in pairs:
        print(six.text_type(comm.humanName))
        mpairs = members.items()
        mpairs.sort(key=lambda x: x[1])
        for member, time in mpairs:
            print(' %-20s%.2f' % (member.name, time))
Example #32
0
def main():
    leden = Es.by_name('leden')
    lut = {}
    id2name = {}
    for m in Es.users():
        if not m.name:
            continue
        lut[str(m.name)] = set()
        id2name[m._id] = str(m.name)
    max_q = Es.date_to_year(Es.now()) * 4
    for q in range(1, max_q + 1):
        start, end = Es.quarter_to_range(q)
        for m in leden.get_rrelated(_from=start, until=end, how=None,
                                    deref_who=False, deref_with=False,
                                    deref_how=False):
            lut[id2name[m['who']]].add(q)
    for i, name in enumerate(sorted(six.itervalues(id2name))):
        if i % 20 == 0:
            print()
            print('%20s %s' % (
                'year',
                ' '.join([str(((q - 1) / 4) + 1).ljust(7)
                          for q in range(1, max_q + 1, 4)])
            ))
            print('%20s %s' % (
                'quarter',
                ' '.join([str(((q - 1) % 4) + 1)
                          for q in range(1, max_q + 1)])
            ))
        print('%-20s %s' % (
            name,
            ' '.join(['*' if q in lut[name] else ' '
                      for q in range(1, max_q + 1)])
        ))
Example #33
0
def generate_ldap_changes(giedo):
    todo = {'upsert': [], 'remove': []}
    l = ldap.open(settings.LDAP_HOST)
    l.bind_s(settings.LDAP_USER, settings.LDAP_PASS)
    try:
        users = Es.by_name('leden').get_members()
        unaccounted_for = set()
        in_ldap = {}
        for dn, entry in l.search_s(settings.LDAP_BASE, ldap.SCOPE_ONELEVEL):
            unaccounted_for.add(entry['uid'][0])
            in_ldap[(entry['uid'][0])] = (entry['uid'][0],
                                          entry['mail'][0],
                                          entry['sn'][0],
                                          entry['cn'][0])
        for u in users:
            uid = str(u.name)
            should_have = (uid,
                           u.canonical_email,
                           u.last_name.encode('utf-8'),
                           unicode(u.humanName).encode('utf-8'))
            if uid in unaccounted_for:
                unaccounted_for.remove(uid)
                if in_ldap[uid] == should_have:
                    continue
                logging.info('ldap: updating %s', uid)
            else:
                logging.info('ldap: adding %s', uid)
            todo['upsert'].append(should_have)

        for uid in unaccounted_for:
            todo['remove'].append(uid)
            logging.info('ldap: removing %s', uid)
    finally:
        l.unbind_s()
    return todo
Example #34
0
def generate_postfix_slm_map(giedo):
    # We generate the postfix "sender_login_maps".
    # This is used to decide by postfix whether a given user is allowed to
    # send e-mail as if it was coming from a particular e-mail address.
    # It is a dictionary { <email address> : [ <allowed user>, ... ] }
    tbl = dict()
    dt_now = now()
    # Get all users
    ulut = dict()
    # We only allow members to send e-mail
    for u in Es.by_name('leden').get_members():
        ulut[u._id] = u
        for name in u.names:
            if str(name) not in tbl:
                tbl[str(name)] = set()
            tbl[str(name)].add(str(u.name))
    # There are two kind of groups: groups whose members are allowed to
    # send e-mail as if coming from the group itself and those where this
    # is not allowed.  For convenience, lets call the first kind the
    # impersonatable groups.
    # Get all impersonatable groups and create a look-up-table for
    # group membership
    gs = list()
    for g in Es.groups():
        # TODO add a tag to force a group either impersonatable or not
        if not g.got_mailman_list:
            gs.append(g)
    mrels = Es.query_relations(how=None, _with=gs, _from=dt_now, until=dt_now)
    mlut = dict()
    for g in gs:
        mlut[g._id] = []
    for mrel in mrels:
        mlut[mrel['with']].append(mrel['who'])
    # Flatten out group membership.  For instance: if Giedo is in Kasco
    # and Kasco is in Boekenlezers, then Giedo is also in the Boekenlezers
    # unix group.
    # But first split the mlut graph into a impersonatable group
    # and a non-group subgraph.
    mlut_g = {}     # { <group> : <members that are impersonatable groups> }
    mlut_u = {}    # { <group> : <members that are users> }
    for g_id in mlut:
        mlut_g[g_id] = [c for c in mlut[g_id] if c in mlut]
        mlut_u[g_id] = [c for c in mlut[g_id] if c in ulut]
    mlut_g_tc = tc(mlut_g)  # transitive closure
    for g in gs:
        to_consider = tuple(mlut_g_tc[g._id]) + (g._id,)
        for sg_id in to_consider:
            for u_id in mlut_u[sg_id]:
                for name in g.names:
                    if str(name) not in tbl:
                        tbl[str(name)] = set()
                    tbl[str(name)].add(str(ulut[u_id].name))
    # Clean up tbl to return.
    ret = {}
    for name, users in six.iteritems(tbl):
        if not users:
            continue
        ret["%s@%s" % (name, settings.MAILDOMAIN)] = tuple(users)
    return ret
Example #35
0
def generate_wiki_changes(self):
    creds = settings.WIKI_MYSQL_SECRET
    if not creds:
        logging.warning('wiki: no credentials available, skipping')
        return None
    users = dict()
    id2name = dict()
    dc = pymysql.connect(
        host=creds[0],
        user=creds[1],
        password=creds[2],
        db=creds[3],
        charset='utf8'
    )
    try:
        with dc.cursor() as c:
            c.execute("SELECT user_id, user_name FROM user")
            todo = {'add': [], 'remove': [], 'activate': [], 'deactivate': []}

            cur, old = Es.by_name('leden').get_current_and_old_members()
            for m in itertools.chain(cur, old):
                if str(m.name) == 'admin':
                    logging.warning("wiki can't handle an admin user")
                    continue
                users[str(m.name)] = m
            ausers = set([u for u in users if users[u].is_active])

            for uid, user in c.fetchall():
                user = user.lower()
                if six.PY3:
                    user = user.decode()
                if user not in users:
                    if user == 'admin':
                        continue
                    todo['remove'].append(user)
                    logging.info("wiki: removing user %s", user)
                else:
                    id2name[uid] = user
                    del users[user]
            for name, user in six.iteritems(users):
                todo['add'].append((name, six.text_type(user.humanName),
                                    user.canonical_email))

            c.execute("""SELECT ug_user FROM user_groups
                         WHERE ug_group=%s""", 'leden')
            for uid, in c.fetchall():
                if uid not in id2name:
                    continue
                user = id2name[uid]
                if user not in ausers:
                    todo['deactivate'].append(user)
                else:
                    ausers.remove(user)

            for name in ausers:
                todo['activate'].append(name)
    finally:
        dc.close()
    return todo
Example #36
0
def send_informacie_digest():
    """ Sends the notifications for the informacie. """
    ntfs = Es.pop_all_informacie_notifications()
    if not ntfs:
        return
    render_then_email('leden/informacie-digest.mail.html',
                      Es.by_name('informacie').canonical_full_email, {
                          'ntfs': ntfs})
Example #37
0
def send_informacie_digest():
    """ Sends the notifications for the informacie. """
    ntfs = Es.pop_all_informacie_notifications()
    if not ntfs:
        return
    render_then_email('leden/informacie-digest.mail.html',
                      Es.by_name('informacie').canonical_full_email,
                      {'ntfs': ntfs})
Example #38
0
def main3():
    member_age = {}
    for rel in Es.query_relations(-1, Es.by_name('leden'), None,
                                  None, deref_who=True):
        if rel['who'] not in member_age:
            member_age[rel['who']] = 0
        member_age[rel['who']] = max(member_age[rel['who']],
                                     (now() - rel['from']).days / 365.0)

    # for comm in Es.by_name('comms').get_bearers():
    for comm in [Es.by_name('draai')]:
        print(six.text_type(comm.humanName))
        members = [(m, member_age.get(m)) for m in comm.get_members()]
        members.sort(key=lambda x: x[1])
        for member in members:
            print(" %-20s%.2f" % (six.text_type(member[0].name),
                                  member[1] if member[1] else -1))
Example #39
0
def fiscus_debtmail(request):

    if 'fiscus' not in request.user.cached_groups_names:
        raise PermissionDenied

    data = dict([(n, {'debt': Decimal(debt)}) for (n, debt) in
                 giedo.fin_get_debitors()])

    for user in Es.users():
        name = user.full_name
        if name in data:
            data[name]['user'] = user

    ctx = {
        'BASE_URL': settings.BASE_URL,
        'quaestor': fin.quaestor(),
        'account_number': settings.BANK_ACCOUNT_NUMBER,
        'account_holder': settings.BANK_ACCOUNT_HOLDER,
    }

    if request.method == 'POST' and 'debitor' in request.POST:
        users_to_email = request.POST.getlist('debitor')
        for user_name in users_to_email:
            user = Es.by_name(user_name)

            ctx['first_name'] = user.first_name,
            ctx['debt'] = data[user.full_name]['debt']

            try:
                render_then_email("leden/debitor.mail.txt",
                                  to=user, ctx=ctx,
                                  cc=[],  # ADD penningmeester
                                  from_email=ctx['quaestor']['email'],
                                  reply_to=ctx['quaestor']['email'])
                messages.info(
                    request,
                    _("Email gestuurd naar %s.") %
                    user_name)
            except Exception as e:
                messages.error(request,
                               _("Email naar %(user)s faalde: %(e)s.") %
                               {'user': user_name, 'e': repr(e)})

    # get a sample of the email that will be sent for the quaestor's review.
    email = ""
    email_template = get_template('leden/debitor.mail.txt')

    ctx['first_name'] = '< Naam >'
    ctx['debt'] = '< Debet >'
    context = Context(ctx)
    for node in email_template:
        if isinstance(node, BlockNode) and node.name == "plain":
            email = node.render(context)
            break

    return render_to_response('leden/fiscus_debtmail.html',
                              {'data': data, 'email': email},
                              context_instance=RequestContext(request))
Example #40
0
def rauth(request):
    """
        An implementation of Jille Timmermans' rauth scheme
        The token that is given to the authenticated user is only valid until
        the end of the day.
    """
    if request.REQUEST.get('url') is None:
        raise Http404
    if (request.REQUEST.get('validate') is not None and
            request.REQUEST.get('user') is not None):
        token = sha256('%s|%s|%s|%s' % (
            request.REQUEST['user'],
            date.today(),
            request.REQUEST['url'],
            settings.SECRET_KEY)).hexdigest()
        if constant_time_compare(request.REQUEST['validate'], token):
            return HttpResponse("OK")
        return HttpResponse("INVALID")

    '''
    The next check will allow you to request information about the user that
    is currently logged in using the 'fetch'-get attribute with the property
    names seperated by commas.
    A JSON string will be returned containing the information.
    '''
    if (request.REQUEST.get('fetch') is not None and
            request.REQUEST.get('user') is not None):
        token = sha256('%s|%s|%s|%s' % (
            request.REQUEST['user'],
            date.today(),
            request.REQUEST['url'],
            settings.SECRET_KEY)).hexdigest()
        if constant_time_compare(request.REQUEST['token'], token):
            user = Es.by_name(request.REQUEST['user'])
            properties = {
                'firstname': user.first_name,
                'lastname': user.last_name,
                'fullname': user.full_name,
                'groups': list(user.cached_groups_names)
            }
            return HttpResponse(json.dumps(dict([
                (k, properties[k]) for k in
                set(s.strip() for s in request.REQUEST.get('fetch').split(','))
                if k in properties
            ])))
        return HttpResponse("INVALID TOKEN")
    if not request.user.is_authenticated():
        return redirect_to_login('%s?url=%s' % (
            reverse('rauth'),
            urlquote(request.REQUEST['url'])))
    token = sha256('%s|%s|%s|%s' % (str(request.user.name),
                                    date.today(),
                                    request.REQUEST['url'],
                                    settings.SECRET_KEY)).hexdigest()
    return HttpResponseRedirect('%s%suser=%s&token=%s' % (
        request.REQUEST['url'],
        '?' if request.REQUEST['url'].find('?') == -1 else '&',
        str(request.user.name), token))
Example #41
0
def overview(request):
    toggle_with_name = None
    renew_with_name = None
    moderators = Es.by_name(settings.MODERATORS_GROUP)
    if (request.user.is_related_with(Es.by_name(settings.MODERATORS_GROUP))):
        is_moderator = True
        if request.method == 'POST':
            if 'toggle' in request.POST:
                toggle_with_name = request.POST['toggle']
            if 'renew' in request.POST:
                renew_with_name = request.POST['renew']
    else:
        is_moderator = False
    lists = []
    for name in settings.MODED_MAILINGLISTS:
        r = mod_Es.by_name(name)
        ml = Mailman.MailList.MailList(name, True)
        try:
            if toggle_with_name == name:
                if ml.emergency:
                    _deactivate_mm(ml, name, request.user, r, moderators)
                else:
                    r = _activate_mm(ml, name, request.user, r, moderators)
            if renew_with_name == name:
                r = _renew_mm(ml, name, request.user, r, moderators)
            by = None if r is None else r.by
            remaining = (None if r is None else r.at +
                         settings.MOD_RENEW_INTERVAL - datetime.datetime.now())
            until = (None if r is None else r.at + settings.MOD_RENEW_INTERVAL)
            lists.append({
                'name': name,
                'real_name': ml.real_name,
                'modmode': ml.emergency,
                'by': by,
                'remaining': remaining,
                'description': ml.description,
                'queue': len(ml.GetHeldMessageIds())
            })
        finally:
            ml.Unlock()
    return render_to_response('moderation/overview.html', {
        'lists': lists,
        'is_moderator': is_moderator
    },
                              context_instance=RequestContext(request))
Example #42
0
def get_add_event_form(user, superuser=False):
    if superuser:
        choices = (sorted(Es.groups(),
                lambda x,y: cmp(unicode(x.humanName),
                    unicode(y.humanName))) +
            sorted(Es.by_name('leden').get_members(),
                lambda x,y: cmp(unicode(x.humanName),
                    unicode(y.humanName))))
    else:
        choices = [user]+sorted(user.cached_groups,
            cmp=lambda x,y: cmp(unicode(x.humanName),
                    unicode(y.humanName)))
    class AddEventForm(forms.Form):
        name = forms.RegexField(label='Korte naam', regex=r'^[a-z0-9-]+$')
        humanName = forms.CharField(label='Naam')
        description = forms.CharField(label='Beschrijving',
                widget=forms.Textarea)
        mailBody = forms.CharField(label='E-Mail wanneer aangemeld',
            widget=forms.Textarea,
            initial="Hallo %(firstName)s,\n\n"+
                "Je hebt je aangemeld voor %(eventName)s.\n"+
                "\n"+
                "Je opmerkingen waren:\n"+
                "%(notes)s\n"+
                "\n"+
                "Met een vriendelijke groet,\n\n"+
                "%(owner)s")
        subscribedByOtherMailBody = forms.CharField(
            label='E-Mail wanneer aangemeld door een ander',
            widget=forms.Textarea,
            initial="Hallo %(firstName)s,\n\n"+
                "Je bent door %(by_firstName)s aangemeld "+
                    "voor %(eventName)s.\n"+
                "\n"+
                "%(by_firstName)s opmerkingen waren:\n"+
                "%(by_notes)s\n"+
                "\n"+
                "Om deze aanmelding te bevestigen, bezoek:\n"
                "  %(confirmationLink)s\n"+
                "\n"+
                "Met een vriendelijke groet,\n\n"+
                "%(owner)s")
        confirmationMailBody = forms.CharField(
            label='E-Mail wanneer aanmelding is bevestigd',
            widget=forms.Textarea,
            initial="Hallo %(firstName)s,\n\n"+
                "Je hebt je aanmelding voor %(eventName)s bevestigd.\n\n"+
                "Met een vriendelijke groet,\n\n"+
                "%(owner)s")
        cost = forms.DecimalField(label='Kosten')
        date = forms.DateField(label='Datum')
        owner = EntityChoiceField(label="Eigenaar", choices=choices)
        has_public_subscriptions = forms.BooleanField(required=False,
                label='Inschrijvingen openbaar')
        everyone_can_subscribe_others = forms.BooleanField(required=False,
                label='Iedereen kan iedereen inschrijven')
    return AddEventForm
Example #43
0
class AddGroupForm(forms.Form):
    name = forms.RegexField(label="Naam", regex=r'^[a-z0-9-]{2,64}$')
    humanName = forms.CharField(label="Naam voor mensen")
    genitive_prefix = forms.CharField(label="Genitivus", initial="van de")
    description = forms.CharField(label="Korte beschrijving")
    parent = EntityChoiceField(label="Parent",
                               _type='group',
                               initial=Es.by_name('secretariaat')._id)
    true_group = forms.BooleanField(label="Volwaardige groep", initial=True)
Example #44
0
def generate_unix_map(giedo):
    ret = {'groups': {},
           'users': {}}
    dt_now = now()
    # Get all users
    ulut = dict()
    for u in Es.users():
        if not u.got_unix_user:
            continue
        ulut[u._id] = u
        ret['users'][str(u.name)] = {
                'full_name': u.full_name,
                'expire_date': DT_MIN.strftime('%Y-%m-%d')}
    member_relations_grouped = dict()
    for rel in Es.query_relations(_with=Es.by_name('leden'), until=dt_now):
        if rel['who'] not in member_relations_grouped:
            member_relations_grouped[rel['who']] = []
        member_relations_grouped[rel['who']].append(rel)
    for user_id, relations in member_relations_grouped.items():
        latest = max(relations, key=lambda x: x['until'])
        ret['users'][str(ulut[user_id].name)]['expire_date'] \
                = latest['until'].strftime('%Y-%m-%d')

    # Get all groups and create a look-up-table for group membership
    gs = tuple(Es.groups())
    mrels = Es.query_relations(how=None, _with=gs, _from=dt_now,
                until=dt_now)
    mlut = dict()
    for g in gs:
        mlut[g._id] = []
    for mrel in mrels:
        mlut[mrel['with']].append(mrel['who'])
    # Flatten out group membership.  For instance: if Giedo is in Kasco
    # and Kasco is in Boekenlezers, then Giedo is also in the Boekenlezers
    # unix group.
    # But first split the mlut graph into a group and a non-group subgraph.
    mlut_g = {}     # { <group> : <members that are groups> }
    mlut_ng = {}    # { <group> : <members that are not groups> }
    for g_id in mlut:
        mlut_g[g_id] = [c for c in mlut[g_id] if c in mlut]
        mlut_ng[g_id] = [c for c in mlut[g_id] if c not in mlut]
    mlut_g_tc = tc(mlut_g)  # transitive closure
    # Generate the { <group> : <indirect non-group members> } graph
    memb_graph = {}
    for g in gs:
        if not g.got_unix_group:
            continue
        memb_graph[g._id] = set(mlut_ng[g._id])
        for h_id in mlut_g_tc[g._id]:
            memb_graph[g._id].update(mlut_ng[h_id])
    # Fill the return map
    for g in gs:
        if not g.got_unix_group:
            continue
        ret['groups'][str(g.name)] = [str(ulut[c].name)
                for c in memb_graph[g._id] if c in ulut]
    return ret
Example #45
0
def user_smoel(request, name):
    user = Es.by_name(name)
    if not user:
        raise Http404
    try:
        img = default_storage.open(path.join(settings.SMOELEN_PHOTOS_PATH, str(user.name)) + ".jpg")
    except IOError:
        raise Http404
    return HttpResponse(FileWrapper(img), content_type="image/jpeg")
Example #46
0
def generate_unix_map(giedo):
    ret = {'groups': {},
           'users': {}}
    dt_now = now()
    # Get all users
    ulut = dict()
    for u in Es.users():
        if not u.got_unix_user:
            continue
        ulut[u._id] = u
        ret['users'][str(u.name)] = {
            'full_name': u.full_name,
            'expire_date': DT_MIN.strftime('%Y-%m-%d')}
    member_relations_grouped = dict()
    for rel in Es.query_relations(_with=Es.by_name('leden'), until=dt_now):
        if rel['who'] not in member_relations_grouped:
            member_relations_grouped[rel['who']] = []
        member_relations_grouped[rel['who']].append(rel)
    for user_id, relations in member_relations_grouped.items():
        latest = max(relations, key=lambda x: x['until'])
        ret['users'][str(ulut[user_id].name)]['expire_date'] = (
            latest['until'].strftime('%Y-%m-%d'))

    # Get all groups and create a look-up-table for group membership
    gs = tuple(Es.groups())
    mrels = Es.query_relations(how=None, _with=gs, _from=dt_now,
                               until=dt_now)
    mlut = dict()
    for g in gs:
        mlut[g._id] = []
    for mrel in mrels:
        mlut[mrel['with']].append(mrel['who'])
    # Flatten out group membership.  For instance: if Giedo is in Kasco
    # and Kasco is in Boekenlezers, then Giedo is also in the Boekenlezers
    # unix group.
    # But first split the mlut graph into a group and a non-group subgraph.
    mlut_g = {}     # { <group> : <members that are groups> }
    mlut_ng = {}    # { <group> : <members that are not groups> }
    for g_id in mlut:
        mlut_g[g_id] = [c for c in mlut[g_id] if c in mlut]
        mlut_ng[g_id] = [c for c in mlut[g_id] if c not in mlut]
    mlut_g_tc = tc(mlut_g)  # transitive closure
    # Generate the { <group> : <indirect non-group members> } graph
    memb_graph = {}
    for g in gs:
        if not g.got_unix_group:
            continue
        memb_graph[g._id] = set(mlut_ng[g._id])
        for h_id in mlut_g_tc[g._id]:
            memb_graph[g._id].update(mlut_ng[h_id])
    # Fill the return map
    for g in gs:
        if not g.got_unix_group:
            continue
        ret['groups'][str(g.name)] = [str(ulut[c].name)
                                      for c in memb_graph[g._id] if c in ulut]
    return ret
Example #47
0
def fiscus_debtmail(request):

    if 'fiscus' not in request.user.cached_groups_names:
        raise PermissionDenied

    data = dict([(n, {
        'debt': Decimal(debt)
    }) for (n, debt) in giedo.fin_get_debitors()])

    for user in Es.users():
        name = user.full_name
        if name in data:
            data[name]['user'] = user

    ctx = {
        'BASE_URL': settings.BASE_URL,
        'quaestor': fin.quaestor(),
        'account_number': settings.BANK_ACCOUNT_NUMBER,
        'account_holder': settings.BANK_ACCOUNT_HOLDER,
    }

    if request.method == 'POST' and 'debitor' in request.POST:
        users_to_email = request.POST.getlist('debitor')
        for user_name in users_to_email:
            user = Es.by_name(user_name)

            ctx['first_name'] = user.first_name
            ctx['debt'] = data[user.full_name]['debt']

            try:
                render_then_email(
                    'leden/debitor.mail.html',
                    to=user,
                    ctx=ctx,
                    cc=[],  # ADD penningmeester
                    from_email=ctx['quaestor']['email'],
                    reply_to=ctx['quaestor']['email'])
                messages.info(request,
                              _("Email gestuurd naar %s.") % user_name)
            except Exception as e:
                messages.error(
                    request,
                    _("Email naar %(user)s faalde: %(e)s.") % {
                        'user': user_name,
                        'e': repr(e)
                    })

    # get a sample of the email that will be sent for the quaestor's review.
    ctx['first_name'] = '< Naam >'
    ctx['debt'] = '< Debet >'
    email = render_message('leden/debitor.mail.html', ctx)['html']

    return render(request, 'leden/fiscus_debtmail.html', {
        'data': data,
        'email': email
    })
Example #48
0
def event_detail(request, name):
    # First, find the event.
    event = subscr_Es.event_by_name(name)
    if event is None:
        raise Http404
    # Has the user already subscribed?
    subscription = event.get_subscription(request.user)
    # What are our permissions?
    has_read_access = event.has_read_access(request.user)
    has_write_access = event.has_write_access(request.user)
    if request.method == 'POST' and 'subscribe' in request.POST:
        if not event.is_open:
            raise PermissionDenied
        if subscription is not None and subscription.subscribed:
            messages.error(request, "Je bent al aangemeld")
        else:
            notes = request.POST['notes']
            subscription = event.subscribe(request.user, notes)
        return HttpResponseRedirect(reverse('event-detail',
                                            args=(event.name,)))
    elif request.method == 'POST' and 'invite' in request.POST:
        if not event.is_open:
            raise PermissionDenied
        # Find the other user
        user = Es.by_id(request.POST['who'])
        if not user or not user.is_user:
            raise Http404
        # Is the other already subscribed?
        if event.get_subscription(user) is not None:
            messages.error(request, "%s is al aangemeld" % user.full_name)
        else:
            notes = request.POST['notes']
            other_subscription = event.invite(user, notes, request.user)
        return HttpResponseRedirect(reverse('event-detail',
                                            args=(event.name,)))

    users = filter(lambda u: event.get_subscription(u) is None and \
                             u != request.user,
                   Es.by_name('leden').get_members())
    users.sort(key=lambda u: unicode(u.humanName))
    subscriptions = event.subscriptions
    subscriptions.sort(key=lambda s: s.date)
    invitations = event.invitations
    invitations.sort(key=lambda i: i.date)

    ctx = {'object': event,
           'user': request.user,
           'users': users,
           'subscription': subscription,
           'subscriptions': subscriptions,
           'invitations': invitations,
           'has_read_access': has_read_access,
           'has_write_access': has_write_access}
    return render_to_response('subscriptions/event_detail.html', ctx,
            context_instance=RequestContext(request))
Example #49
0
def user_smoel(request, name):
    user = Es.by_name(name)
    if not user:
        raise Http404
    try:
        img = default_storage.open(
            os.path.join(settings.SMOELEN_PHOTOS_PATH, str(user.name)) +
            ".jpg", 'rb')
    except IOError:
        raise Http404
    return HttpResponse(FileWrapper(img), content_type="image/jpeg")
Example #50
0
def main3():
    member_age = {}
    for rel in Es.query_relations(-1,
                                  Es.by_name('leden'),
                                  None,
                                  None,
                                  deref_who=True):
        if rel['who'] not in member_age:
            member_age[rel['who']] = 0
        member_age[rel['who']] = max(member_age[rel['who']],
                                     (now() - rel['from']).days / 365.0)

    # for comm in Es.by_name('comms').get_bearers():
    for comm in [Es.by_name('draai')]:
        print(six.text_type(comm.humanName))
        members = [(m, member_age.get(m)) for m in comm.get_members()]
        members.sort(key=lambda x: x[1])
        for member in members:
            print(" %-20s%.2f" % (six.text_type(
                member[0].name), member[1] if member[1] else -1))
Example #51
0
def send_reminder(vacancy, update=True):
    to = vacancy.assignee.get_user()
    e = vacancy.event
    p = vacancy.pool
    edate = e.date.strftime('%A %d %B')
    msgfmt = p.reminder_format
    msg = msgfmt % {
        'firstName': to.first_name,
        'date': edate,
        'time': vacancy.begin_time,
        'vacancyName': vacancy.name,
        'eventName': e.name}
    ccs = map(lambda x: Es.by_name(x).canonical_email, p.reminder_cc)
    subj = '%s, %s' % (vacancy.name.capitalize(), edate)
    em = EmailMessage(subj, msg, to=[to.canonical_email], headers={'Reply-To':
        Es.by_name(p.administrator).canonical_email, 'CC': ', '.join(ccs)}, bcc=ccs)
    em.send()
    if update:
        vacancy.reminder_needed = False
        vacancy.save()
Example #52
0
def main():
    for n in []:
        e = Es.by_name(n)
        print n
        for rel in e.get_related(_from=Es.now(), until=Es.now()):
            grp = rel['with']
            if grp.is_virtual: continue
            if str(grp.name) == 'nibbana': continue
            if str(grp.name) == 'uilfest': continue
            print ' '+str(grp.name)
            assert rel['until'] is None
Example #53
0
def check_email():
    dt_now = now()
    comm_ids = map(_id, Es.by_name('comms').get_bearers())
    list_ids = map(_id, Es.by_name('lists-opted').get_bearers())
    with open('check-email.template') as f:
        template_text = StringIO()
        for line in f:
            if line.endswith("\\\n"):
                template_text.write(line[:-2])
            else:
                template_text.write(line)
        templ = Template(template_text.getvalue())
    for m in args_to_users(sys.argv[1:]):
        rels = m.get_related()
        rels = sorted(rels,
                      cmp=lambda x, y: cmp(str(x['with'].humanName),
                                           str(y['with'].humanName)))
        comms = []
        lists = []
        others = []
        for rel in rels:
            if Es.relation_is_virtual(rel):
                continue
            if _id(rel['with']) in comm_ids:
                comms.append(rel)
            elif _id(rel['with']) in list_ids:
                lists.append(rel)
            else:
                others.append(rel)
        print m.name
        em = templ.render(
            Context({
                'u': m,
                'comms': comms,
                'lists': lists,
                'others': others
            }))
        send_mail('Controle Karpe Noktem ledenadministratie', em,
                  '*****@*****.**', [m.primary_email])
Example #54
0
def redirect(request, name):
    # if not request.build_absolute_uri().startswith(
    #         settings.MOD_DESIRED_URI_PREFIX):
    #     return HttpResponseRedirect(settings.MOD_DESIRED_URI_PREFIX +
    #                                 request.get_full_path())
    if not request.user.is_related_with(Es.by_name(settings.MODERATORS_GROUP)):
        return HttpResponse(_("Toegang geweigerd"))
    if name not in settings.MODED_MAILINGLISTS:
        raise Http404
    cookie_name, cookie_value = giedo.maillist_get_moderator_cookie(name)
    r = HttpResponseRedirect(settings.MOD_UI_URI % name)
    r[cookie_name] = cookie_value
    return r
def main():
    for n in []:
        e = Es.by_name(n)
        print(n)
        for rel in e.get_related(_from=Es.now(), until=Es.now()):
            grp = rel['with']
            if grp.is_virtual:
                continue
            if str(grp.name) == 'nibbana':
                continue
            if str(grp.name) == 'uilfest':
                continue
            print(' ' + str(grp.name))
            assert rel['until'] is None
Example #56
0
def main():
    leden = frozenset(Es.by_name('leden').get_members())
    han = Es.by_id('4e6fcc85e60edf3dc0000015')
    for m in sorted(Es.by_institute(han), key=lambda x: str(x.name)):
        if not m in leden:
            continue
        ok = False
        for study in m.studies:
            if study['institute'] != han:
                continue
            if study['until'] is None or study['until'] >= Es.now():
                ok = True
        print "%-30s %-10s %s" % (m.full_name, study['number'],
                                  unicode(study['study'].humanName))
Example #57
0
 def _sync_villanet(self):
     ret = self.villanet_request({'action': 'listUsers'})
     if not ret[0]:
         return
     ret = json.loads(ret[1])
     users = dict()
     ulut = dict()
     for u in Es.users():
         ulut[u._id] = str(u.name)
     member_relations_grouped = dict()
     for rel in Es.query_relations(_with=Es.by_name('leden'), until=now()):
         if rel['who'] not in member_relations_grouped:
             member_relations_grouped[rel['who']] = []
         member_relations_grouped[rel['who']].append(rel)
     for user_id, relations in member_relations_grouped.items():
         latest = max(relations, key=lambda x: x['until'])
         users[ulut[user_id]] = latest['until'].strftime('%Y-%m-%d')
     vn = set(ret.keys())
     kn = set(users.keys())
     dt_max = settings.DT_MAX.strftime('%Y-%m-%d')
     for name in kn - vn:
         data = {
             'username': name,
             'password': self.villanet_encrypt_password(pseudo_randstr(16)),
         }
         if users[name] != dt_max:
             data['till'] = users[name]
         pc = Es.PushChange({
             'system': 'villanet',
             'action': 'addUser',
             'data': data
         })
         pc.save()
     for name in vn - kn:
         logging.info("Stray user %s" % name)
     for name in vn & kn:
         remote = (ret[name]['till'][:10]
                   if ret[name]['till'] is not None else '')
         local = users[name] if users[name] != dt_max else ''
         if remote != local:
             pc = Es.PushChange({
                 'system': 'villanet',
                 'action': 'changeUser',
                 'data': {
                     'username': name,
                     'till': local
                 }
             })
             pc.save()
     self.push_changes_event.set()
Example #58
0
def entity_detail(request, name=None, _id=None, type=None):
    if name is not None:
        e = Es.by_name(name)
    else:
        e = Es.by_id(_id)
    if e is None:
        raise Http404
    if type and not type in e.types:
        raise ValueError, "Entity is not a %s" % type
    if not type:
        type = e.type
    if not type in Es.TYPE_MAP:
        raise ValueError, "Unknown entity type"
    return globals()['_'+type+'_detail'](request, getattr(e, 'as_'+type)())