def remove_history(save):
    print('Telephone numbers:')
    for user in Es.users():
        remove_history_item(user, 'telephones', 'telephone', 'number', save=save)

    print('\nEmail addresses:')
    for user in Es.users():
        remove_history_item(user, 'emailAddresses', 'email', 'email', save=save)

    print('\nPost addresses:')
    for user in Es.users():
        remove_history_item(user, 'addresses', 'address', None, save=save)
Example #2
0
def api_users(request):
    if not request.REQUEST['key'] in settings.ALLOWED_API_KEYS:
        raise PermissionDenied
    ret = {}
    for m in Es.users():
        ret[str(m.name)] = m.full_name
    return HttpResponse(json.dumps(ret), mimetype="text/json")
Example #3
0
def api_users(request):
    if not request.REQUEST['key'] in settings.ALLOWED_API_KEYS:
        raise PermissionDenied
    ret = {}
    for m in Es.users():
        ret[str(m.name)] = m.full_name
    return HttpResponse(json.dumps(ret), mimetype="text/json")
def main():
    for e in Es.users():
        # Remove empty study entries
        if e._data['studies']:
            study = e._data['studies'][0]
            if (study['study'] is None and
                    study['number'] is None and
                    study['institute'] is None and
                    len(e._data['studies']) == 1):
                e._data['studies'] = []
                e.save()
        # Remove empty address entries
        if e._data['addresses']:
            address = e._data['addresses'][0]
            if (not address['street'] and
                    not address['city'] and 
                    not address['number'] and
                    len(e._data['addresses']) == 1):
                e._data['addresses'] = []
                e.save()
        # Remove empty telephone entries
        if e._data['telephones']:
            address = e._data['telephones'][0]
            if (not address['number'] and
                    len(e._data['telephones']) == 1):
                e._data['telephones'] = []
                e.save()
Example #5
0
def generate_openvpn_zips(giedo):
    for u in Es.users():
        if not u.is_active:
            continue
        if not os.path.isfile(os.path.join(settings.VPN_INSTALLER_STORAGE,
            'openvpn-config-%s.zip' % str(u.name))):
            _create_zip(u)
Example #6
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 #7
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 #8
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 #9
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 #10
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 #11
0
def find_name_for_user(first_name, last_name):
    """ Given the first and the last name of a user, find a free name """
    def clean(s, last_name=False, capitalize_tussenvoegsels=False):
        """ Cleans a first or last name.  We do some extra things for last
            names and optionally capitalize letters that came
            from tussenvoegsels. """
        if last_name and ',' in s:
            bits = s.split(',', 2)
            s = bits[1] + ' ' + bits[0]
        s = unidecode.unidecode(s).lower()
        s = ''.join((x for x in s if x in settings.USERNAME_CHARS))
        if last_name:
            s = s.replace('van ', 'V ')
            s = s.replace('der ', 'D ')
            s = s.replace('de ', 'D ')
            s = s.replace('den ', 'D ')
            if not capitalize_tussenvoegsels:
                s = s.lower()
        return s.replace(' ', '')

    names = Es.names()
    fn = clean(first_name)
    ln_ctv = clean(last_name, last_name=True, capitalize_tussenvoegsels=True)
    ln = clean(last_name, last_name=True)
    # Others users with this firstname
    users_with_same_fn = [
        u for u in Es.users() if u.first_name and clean(u.first_name) == fn
    ]
    # Try first_name or first_name with a few letters of the last_name appended
    for i in range(len(ln) + 1):
        n = fn + ln[:i]
        # Don't try giedov, but directly giedovdm if the name is derived
        # from `Giedo van der Meer'.
        if i and ln_ctv[:i][-1].isupper():
            continue
        if n in names:
            continue
        # Recall `Giedo Jansen' has the username `giedo'.  Suppose there is
        # a new member called `Giedo Joosten'. In this case we want to give
        # him the username `giedojo' instead of `giedoj'.
        ok = True
        for u in users_with_same_fn:
            un = clean(u.first_name) + clean(u.last_name, last_name=True)
            if un.startswith(n):
                ok = False
                break
        if ok:
            return n
    # Last resort: try <first_name><last_name><i> for i in {2,3,...}
    i = 1
    while True:
        i += 1
        n = fn + ln + str(i)
        if n not in names:
            return n
Example #12
0
def api_users(request):
    verified_key = False
    for key in settings.ALLOWED_API_KEYS:
        if constant_time_compare(request.REQUEST['key'], key):
            verified_key = True
    if not verified_key:
        raise PermissionDenied
    ret = {}
    for m in Es.users():
        ret[str(m.name)] = m.full_name
    return HttpResponse(json.dumps(ret), content_type="text/json")
Example #13
0
def find_name_for_user(first_name, last_name):
    """ Given the first and the last name of a user, find a free name """
    def clean(s, last_name=False, capitalize_tussenvoegsels=False):
        """ Cleans a first or last name.  We do some extra things for last
            names and optionally capitalize letters that came
            from tussenvoegsels. """
        if last_name and ',' in s:
            bits  = s.split(',', 2)
            s = bits[1] + ' ' + bits[0]
        s = unidecode.unidecode(s).lower()
        s = filter(lambda x: x in settings.USERNAME_CHARS + ' ', s)
        if last_name:
            s = s.replace('van ', 'V ')
            s = s.replace('der ', 'D ')
            s = s.replace('de ', 'D ')
            s = s.replace('den ', 'D ')
            if not capitalize_tussenvoegsels:
                s = s.lower()
        return s.replace(' ', '')

    names = Es.names()
    fn = clean(first_name)
    ln_ctv = clean(last_name, last_name=True, capitalize_tussenvoegsels=True)
    ln = clean(last_name, last_name=True)
    # Others users with this firstname
    users_with_same_fn = [u for u in Es.users() if u.first_name
                                and clean(u.first_name) == fn]
    # Try first_name or first_name with a few letters of the last_name appended
    for i in xrange(len(ln)+1):
        n = fn + ln[:i]
        # Don't try giedov, but directly giedovdm if the name is derived
        # from `Giedo van der Meer'.
        if i and ln_ctv[:i][-1].isupper():
            continue
        if n in names:
            continue
        # Recall `Giedo Jansen' has the username `giedo'.  Suppose there is
        # a new member called `Giedo Joosten'. In this case we want to give
        # him the username `giedojo' instead of `giedoj'.
        ok = True
        for u in users_with_same_fn:
            un = clean(u.first_name) + clean(u.last_name, last_name=True)
            if un.startswith(n):
                ok = False
                break
        if ok:
            return n
    # Last resort: try <first_name><last_name><i> for i in {2,3,...}
    i = 1
    while True:
        i += 1
        n = fn + ln + str(i)
        if n not in names:
            return n
Example #14
0
def _entity_detail(request, e):
    def _cmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['with'].humanName),
                unicode(y['with'].humanName))
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        return Es.relation_cmp_from(x,y)
    def _rcmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        r = cmp(unicode(x['who'].humanName),
                unicode(y['who'].humanName))
        if r: return r
        return Es.relation_cmp_from(x,y)
    related = sorted(e.get_related(), cmp=_cmp)
    rrelated = sorted(e.get_rrelated(), cmp=_rcmp)
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None else
                    Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]
    ctx = {'related': related,
           'rrelated': rrelated,
           'now': now(),
           'tags': sorted(tags, Es.entity_cmp_humanName),
           'object': e}
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(cmp=lambda x,y: cmp(unicode(x.humanName),
                        unicode(y.humanName)))
        users = sorted(Es.users(), cmp=Es.entity_cmp_humanName)
        brands = sorted(Es.brands(), cmp=Es.entity_cmp_humanName)
        ctx.update({'users': users,
                'brands': brands,
                'groups': groups,
                'may_add_related': True,
                'may_add_rrelated': True})
    if e.is_tag:
        ctx.update({'tag_bearers': sorted(e.as_tag().get_bearers(),
                        cmp=Es.entity_cmp_humanName)})
    return ctx
Example #15
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 #16
0
 def _sync_villanet(self):
     if not settings.VILLANET_SECRET_API_KEY:
         logging.warn("VILLANET_SECRET_API_KEY not set")
         return
     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 #17
0
def find_name_for_user(first_name, last_name):
    """ Given the first and the last name of a user, find a free name """
    names = Es.names()

    def clean(s):
        return filter(lambda x: x in settings.USERNAME_CHARS, s.lower())

    def clean_ln(s):
        if ',' in s:
            bits = s.split(',', 2)
            s = bits[1] + ' ' + bits[0]
        s = s.lower()
        s = s.replace('van ', 'v ')
        s = s.replace('de ', 'd ')
        s = s.replace('der ', 'd ')
        s = s.replace('den ', 'd ')
        return clean(s)

    fn = clean(first_name)
    ln = clean_ln(last_name)
    users = [
        u for u in Es.users() if u.first_name and clean(u.first_name) == fn
    ]
    # First, simply try the first_name.  This is OK if the name is not taken
    # and there is noone else with that first_name.
    if fn not in names and len(users) == 0:
        return fn
    # Try first_name with a few letters of last_name.
    for i in xrange(len(ln)):
        n = fn + ln[:i + 1]
        if n in names:
            continue
        ok = True
        for u in users:
            un = clean(u.first_name) + clean_ln(u.last_name)
            if un.startswith(n):
                ok = False
                break
        if ok:
            return n
    # Try <first_name><last_name><i> for i in {2,3,...}
    i = 1
    while True:
        i += 1
        n = fn + ln + str(i)
        if n not in names:
            return n
Example #18
0
def find_name_for_user(first_name, last_name):
    """ Given the first and the last name of a user, find a free name """
    names = Es.names()
    def clean(s):
        return filter(lambda x: x in settings.USERNAME_CHARS, s.lower())
    def clean_ln(s):
        if ',' in s:
            bits  = s.split(',',2)
            s = bits[1] + ' ' + bits[0]
        s = s.lower()
        s = s.replace('van ', 'v ')
        s = s.replace('de ', 'd ')
        s = s.replace('der ', 'd ')
        s = s.replace('den ', 'd ')
        return clean(s)
    fn = clean(first_name)
    ln = clean_ln(last_name)
    users = [u for u in Es.users() if u.first_name
                        and clean(u.first_name) == fn]
    # First, simply try the first_name.  This is OK if the name is not taken
    # and there is noone else with that first_name.
    if fn not in names and len(users) == 0:
        return fn
    # Try first_name with a few letters of last_name.
    for i in xrange(len(ln)):
        n = fn + ln[:i+1]
        if n in names:
            continue
        ok = True
        for u in users:
            un = clean(u.first_name) + clean_ln(u.last_name)
            if un.startswith(n):
                ok = False
                break
        if ok:
            return n
    # Try <first_name><last_name><i> for i in {2,3,...}
    i = 1
    while True:
        i += 1
        n = fn + ln + str(i)
        if n not in names:
            return n
Example #19
0
def main():
    for e in Es.users():
        # Remove empty study entries
        if e._data['studies']:
            study = e._data['studies'][0]
            if (study['study'] is None and study['number'] is None
                    and study['institute'] is None
                    and len(e._data['studies']) == 1):
                e._data['studies'] = []
                e.save()
        # Remove empty address entries
        if e._data['addresses']:
            address = e._data['addresses'][0]
            if (not address['street'] and not address['city']
                    and not address['number']
                    and len(e._data['addresses']) == 1):
                e._data['addresses'] = []
                e.save()
        # Remove empty telephone entries
        if e._data['telephones']:
            address = e._data['telephones'][0]
            if (not address['number'] and len(e._data['telephones']) == 1):
                e._data['telephones'] = []
                e.save()
Example #20
0
def users_underage(request):
    users = Es.users()
    users = filter(lambda u: u.is_active, users)
    users = filter(lambda u: u.is_underage, users)
    users = sorted(users, key=lambda x: x.dateOfBirth)
    return render(request, 'leden/entities_underage.html', {'users': users})
Example #21
0
def _entity_detail(request, e):
    related = sorted(
        e.get_related(),
        key=lambda x: (Es.DT_MIN - Es.relation_until(
            x), Es.entity_humanName(x['with']), Es.entity_humanName(x['how'])))
    rrelated = sorted(
        e.get_rrelated(),
        key=lambda x: (Es.DT_MIN - Es.relation_until(
            x), Es.entity_humanName(x['how']), Es.entity_humanName(x['who'])))
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None or r['until'] >= now()
                           else Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r['until_year']
        if year is None:
            year = 'this'

        if year not in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r['who'])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {
        'related': related,
        'rrelated': rrelated,
        'year_counts': year_counts,
        'now': now(),
        'tags': sorted(tags, key=Es.entity_humanName),
        'object': e,
        'chiefs': [],
        'pipos': [],
        'reps': []
    }
    for r in rrelated:
        if r['how'] and Es.relation_is_active(r):
            if str(r['how'].name) == '!brand-hoofd':
                r['hidden'] = True
                ctx['chiefs'].append(r)
            if str(r['how'].name) == '!brand-bestuurspipo':
                r['hidden'] = True
                ctx['pipos'].append(r)
            if str(r['how'].name) == '!brand-vertegenwoordiger':
                r['hidden'] = True
                ctx['reps'].append(r)
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(key=Es.entity_humanName)
        users = sorted(Es.users(), key=Es.entity_humanName)
        brands = sorted(Es.brands(), key=Es.entity_humanName)
        ctx.update({
            'users': users,
            'brands': brands,
            'groups': groups,
            'may_add_related': True,
            'may_add_rrelated': True,
            'may_tag': True,
            'may_untag': True
        })
    ctx['may_upload_smoel'] = e.name and request.user.may_upload_smoel_for(e)
    if e.is_tag:
        ctx.update({
            'tag_bearers':
            sorted(e.as_tag().get_bearers(), key=Es.entity_humanName)
        })

    # Check whether entity has a photo
    photo_size = e.photo_size
    if e.photo_size is not None:
        ctx.update({
            'hasPhoto': True,
            'photoWidth': photo_size[0],
            'photoHeight': photo_size[1]
        })
    return ctx
Example #22
0
# vim: et:sta:bs=2:sw=4:
from __future__ import print_function

import _import  # noqa: F401
import sys

from common import args_to_users

from django.utils import six
from django.utils.six.moves import range

import kn.leden.entities as Es

users = dict()
if len(sys.argv) == 1:
    _users = Es.users()
else:
    _users = args_to_users(sys.argv[1:])

for m in _users:
    users[str(m.name)] = set()

i = 0
while True:
    i += 1
    g = Es.by_name('leden%s' % i)
    if g is None:
        break
    for m in g.get_members():
        if str(m.name) in users:
            users[str(m.name)].add(i)
Example #23
0
def users_underage(request):
    users = Es.users()
    users = filter(lambda u: u.is_active, users)
    users = filter(lambda u: u.is_underage, users)
    users = sorted(users, key=lambda x: x.dateOfBirth)
    return render(request, 'leden/entities_underage.html', {'users': users})
Example #24
0
def _entity_detail(request, e):
    def _cmp(x, y):
        r = Es.relation_cmp_until(y, x)
        if r:
            return r
        r = cmp(unicode(x["with"].humanName), unicode(y["with"].humanName))
        if r:
            return r
        r = cmp(unicode(x["how"].humanName) if x["how"] else None, unicode(y["how"].humanName) if y["how"] else None)
        if r:
            return r
        return Es.relation_cmp_from(x, y)

    def _rcmp(x, y):
        r = Es.relation_cmp_until(y, x)
        if r:
            return r
        r = cmp(unicode(x["how"].humanName) if x["how"] else None, unicode(y["how"].humanName) if y["how"] else None)
        if r:
            return r
        r = cmp(unicode(x["who"].humanName), unicode(y["who"].humanName))
        if r:
            return r
        return Es.relation_cmp_from(x, y)

    related = sorted(e.get_related(), cmp=_cmp)
    rrelated = sorted(e.get_rrelated(), cmp=_rcmp)
    for r in chain(related, rrelated):
        r["may_end"] = Es.user_may_end_relation(request.user, r)
        r["id"] = r["_id"]
        r["until_year"] = None if r["until"] is None or r["until"] >= now() else Es.date_to_year(r["until"])
        r["virtual"] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r["until_year"]
        if year is None:
            year = "this"

        if not year in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r["who"])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {
        "related": related,
        "rrelated": rrelated,
        "year_counts": year_counts,
        "now": now(),
        "tags": sorted(tags, Es.entity_cmp_humanName),
        "object": e,
        "chiefs": [],
        "pipos": [],
        "reps": [],
    }
    for r in rrelated:
        if r["how"] and Es.relation_is_active(r):
            if str(r["how"].name) == "!brand-hoofd":
                r["hidden"] = True
                ctx["chiefs"].append(r)
            if str(r["how"].name) == "!brand-bestuurspipo":
                r["hidden"] = True
                ctx["pipos"].append(r)
            if str(r["how"].name) == "!brand-vertegenwoordiger":
                r["hidden"] = True
                ctx["reps"].append(r)
    # Is request.user allowed to add (r)relations?
    if "secretariaat" in request.user.cached_groups_names and (e.is_group or e.is_user):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(cmp=lambda x, y: cmp(unicode(x.humanName), unicode(y.humanName)))
        users = sorted(Es.users(), cmp=Es.entity_cmp_humanName)
        brands = sorted(Es.brands(), cmp=Es.entity_cmp_humanName)
        ctx.update(
            {
                "users": users,
                "brands": brands,
                "groups": groups,
                "may_add_related": True,
                "may_add_rrelated": True,
                "may_tag": True,
                "may_untag": True,
            }
        )
    ctx["may_upload_smoel"] = e.name and request.user.may_upload_smoel_for(e)
    if e.is_tag:
        ctx.update({"tag_bearers": sorted(e.as_tag().get_bearers(), cmp=Es.entity_cmp_humanName)})

    # Check whether entity has a photo
    photos_path = path.join(settings.SMOELEN_PHOTOS_PATH, str(e.name)) if e.name else None
    if photos_path and default_storage.exists(photos_path + ".jpg"):
        img = Image.open(default_storage.open(photos_path + ".jpg"))
        width, height = img.size
        if default_storage.exists(photos_path + ".orig"):
            # smoel was created using newer strategy. Shrink until it fits the
            # requirements.
            width, height = resize_proportional(
                img.size[0], img.size[1], settings.SMOELEN_WIDTH, settings.SMOELEN_HEIGHT
            )
        elif width > settings.SMOELEN_WIDTH:
            # smoel was created as high-resolution image, probably 600px wide
            width /= 2
            height /= 2
        else:
            # smoel was created as normal image, probably 300px wide
            pass
        ctx.update({"hasPhoto": True, "photoWidth": width, "photoHeight": height})
    return ctx
Example #25
0
# vim: et:sta:bs=2:sw=4:
import _import

import sys
from common import *
import kn.leden.entities as Es

users = dict()
if len(sys.argv) == 1:
    _users = Es.users()
else:
    _users = args_to_users(sys.argv[1:])

for m in _users:
    users[str(m.name)] = set()

i = 0
while True:
    i += 1
    g = Es.by_name('leden%s' % i)
    if g is None:
        break
    for m in g.get_members():
        if str(m.name) in users:
            users[str(m.name)].add(i)
nyears = i - 1
N = 0

for m, ys in users.iteritems():
    N += 1
    if N % 20 == 0:
Example #26
0
def _entity_detail(request, e):
    def _cmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['with'].humanName),
                unicode(y['with'].humanName))
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        return Es.relation_cmp_from(x,y)
    def _rcmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        r = cmp(unicode(x['who'].humanName),
                unicode(y['who'].humanName))
        if r: return r
        return Es.relation_cmp_from(x,y)
    related = sorted(e.get_related(), cmp=_cmp)
    rrelated = sorted(e.get_rrelated(), cmp=_rcmp)
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None else
                    Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r['until_year']
        if year is None:
            year = 'this'

        if not year in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r['who'])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {'related': related,
           'rrelated': rrelated,
           'year_counts': year_counts,
           'now': now(),
           'tags': sorted(tags, Es.entity_cmp_humanName),
           'object': e,
           'chiefs': [],
           'pipos': [] }
    for r in rrelated:
        if r['how'] and Es.relation_is_active(r):
            if str(r['how'].name) == '!brand-hoofd':
                r['hidden'] = True
                ctx['chiefs'].append(r)
            if str(r['how'].name) == '!brand-bestuurspipo':
                r['hidden'] = True
                ctx['pipos'].append(r)
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(cmp=lambda x,y: cmp(unicode(x.humanName),
                        unicode(y.humanName)))
        users = sorted(Es.users(), cmp=Es.entity_cmp_humanName)
        brands = sorted(Es.brands(), cmp=Es.entity_cmp_humanName)
        ctx.update({'users': users,
                'brands': brands,
                'groups': groups,
                'may_add_related': True,
                'may_add_rrelated': True})
    if e.is_tag:
        ctx.update({'tag_bearers': sorted(e.as_tag().get_bearers(),
                        cmp=Es.entity_cmp_humanName)})
    return ctx
Example #27
0
def _entity_detail(request, e):
    def _cmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['with'].humanName),
                unicode(y['with'].humanName))
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        return Es.relation_cmp_from(x,y)
    def _rcmp(x,y):
        r = Es.relation_cmp_until(y,x)
        if r: return r
        r = cmp(unicode(x['how'].humanName) if x['how'] else None,
            unicode(y['how'].humanName) if y['how'] else None)
        if r: return r
        r = cmp(unicode(x['who'].humanName),
                unicode(y['who'].humanName))
        if r: return r
        return Es.relation_cmp_from(x,y)
    related = sorted(e.get_related(), cmp=_cmp)
    rrelated = sorted(e.get_rrelated(), cmp=_rcmp)
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None else
                    Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r['until_year']
        if year is None:
            year = 'this'

        if not year in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r['who'])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {'related': related,
           'rrelated': rrelated,
           'year_counts': year_counts,
           'now': now(),
           'tags': sorted(tags, Es.entity_cmp_humanName),
           'object': e,
           'chiefs': [],
           'pipos': [] }
    for r in rrelated:
        if r['how'] and Es.relation_is_active(r):
            if str(r['how'].name) == '!brand-hoofd':
                r['hidden'] = True
                ctx['chiefs'].append(r)
            if str(r['how'].name) == '!brand-bestuurspipo':
                r['hidden'] = True
                ctx['pipos'].append(r)
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(cmp=lambda x,y: cmp(unicode(x.humanName),
                        unicode(y.humanName)))
        users = sorted(Es.users(), cmp=Es.entity_cmp_humanName)
        brands = sorted(Es.brands(), cmp=Es.entity_cmp_humanName)
        ctx.update({'users': users,
                'brands': brands,
                'groups': groups,
                'may_add_related': True,
                'may_add_rrelated': True})
    if e.is_tag:
        ctx.update({'tag_bearers': sorted(e.as_tag().get_bearers(),
                        cmp=Es.entity_cmp_humanName)})
    return ctx
Example #28
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path': path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path': path}) \
                    + '#' + filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path': album.path}) \
            + '#' + filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render_to_response(
            'fotos/fotos.html',
            {'fotos': {'parents': album_parents_json(album)},
             'error': 'permission-denied'},
            context_instance=RequestContext(request)
        )
        response.status_code = 403
        return response

    if 'download' in request.GET:
        if album.is_root:
            # Downloading ALL photos would be way too much
            raise PermissionDenied
        download = ZipSeeker()
        add_download_files(download, album, album.full_path, user)
        response = StreamingHttpResponse(download.blocks(),
                                         content_type='application/zip')
        response['Content-Length'] = download.size()
        response['Last-Modified'] = http_date(download.lastModified())
        # TODO: human-readable download name?
        response['Content-Disposition'] = 'attachment; filename=' + \
            album.name + '.zip'
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first
        # by whether they are active (active members first) and
        # then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = six.text_type(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active + inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render_to_response('fotos/fotos.html',
                              {'fotos': fotos,
                               'fotos_admin': fEs.is_admin(user),
                               'people': people},
                              context_instance=RequestContext(request))
Example #29
0
File: db.py Project: aykevl/kninfra
def update_db(giedo):
    dt_now = now()
    # Load tags
    # TODO cache this
    tags = Es.ids_by_names(('!year-group', '!year-overrides',
                            '!virtual-group', '!sofa-brand'))
    year_overrides = {}
    for t in Es.bearers_by_tag_id(tags['!year-overrides'], _as=Es.Tag):
        year_overrides[t._id] = (t._data['year-override']['type'],
                                 t._data['year-override']['year'])

    # Load _id -> name lut.
    id2name = Es.names_by_ids()
    # Load groups and brands
    groups = Es.of_type_by_name('group')
    groups_set = frozenset(six.itervalues(groups))
    # Find groups that have a virtual group for each year
    year_groups = [g for g in groups_set
                   if tags['!year-group'] in g.tag_ids]
    # Find relations on those groups and add the years for which those
    # relations hold.

    def add_years_to_relations(rels):
        years_of_year_overrides = [yo[1] for yo
                                   in six.itervalues(year_overrides)]
        until_years = [Es.date_to_year(r['until']) for r in rels
                       if r['until'] != DT_MAX]
        max_until = max(
            max(until_years) if until_years else 0,
            max(years_of_year_overrides) if years_of_year_overrides else 0,
            Es.date_to_year(dt_now)
        )
        from_years = [Es.date_to_year(r['from']) for r in rels
                      if r['from'] != DT_MIN]
        min_from = min(min(from_years) if from_years else
                       Es.date_to_year(dt_now),
                       Es.date_to_year(dt_now))
        for rel in rels:
            s = (min_from if rel['from'] == DT_MIN
                 else Es.date_to_year(rel['from']))
            t = (max_until if rel['until'] == DT_MAX
                 else Es.date_to_year(rel['until']))
            years = set(range(s, t + 1))
            for tid in rel.get('tags', ()):
                if tid not in year_overrides:
                    continue
                tp, yr = year_overrides[tid]
                if tp:
                    years.add(yr)
                else:
                    if yr not in years:
                        logging.warning('bogus year-override -{} on {}'.format(
                            yr, rel['_id']))
                        continue
                    years.remove(yr)
            rel['years'] = years
    year_group_mrels = tuple(Es.query_relations(_with=year_groups))
    # Check whether all year groups are created
    for g in year_groups:
        mrels = [rel for rel in year_group_mrels if rel['with'] == g._id]
        add_years_to_relations(mrels)
        years = set()
        for rel in mrels:
            years.update(rel['years'])
        for year in years:
            n = str(g.name) + str(year)
            if n not in groups:
                logging.info("Creating yeargroup %s" % n)
                _create_yeargroup(g, year, n, tags, groups, id2name)
    # Find all virtual groups
    virtual_groups = [g for g in groups_set
                      if tags['!virtual-group'] in g.tag_ids]
    sofa_vgroups = []
    yeargroup_vgroups = []
    for vg in virtual_groups:
        if vg._data['virtual']['type'] == 'sofa':
            sofa_vgroups.append(vg)
        elif vg._data['virtual']['type'] == 'year-group':
            yeargroup_vgroups.append(vg)
        else:
            logging.warn("Unknown vgroup type: %s"
                         % vg._data['virtua']['type'])
    # Find all relations with the sofa virtual groups

    def relkey(rel):
        return (rel['who'], rel['how'], rel['with'],
                rel['from'], rel['until'])
    vgroup_rlut = dict()
    for rel in Es.query_relations(_with=virtual_groups):
        vgroup_rlut[relkey(rel)] = rel['_id']
    # create look up table of existing sofas
    sofa_queries = []
    sofa_lut = dict()
    for svg in sofa_vgroups:
        w = dict(svg._data['virtual'])
        sofa_queries.append({'how': w['how'],
                             'with': w['with']})
        k = (w['how'], w['with'])
        if k not in sofa_lut:
            sofa_lut[k] = []
        sofa_lut[k].append(svg)
    # Check whether all year-group relations are in place
    # If there are two relations between an entity and a group in the
    # same year, we do not want this relation to be handled twice.
    # Thus we keep a seperate look-up-table to prevent this.
    year_vgroup_rel_ok = set()
    for mrel in year_group_mrels:
        g = groups[id2name[mrel['with']]]
        for year in mrel['years']:
            yg = groups[str(g.name) + str(year)]
            rrel = {'who': mrel['who'],
                    'with': yg._id,
                    'how': mrel['how'],
                    'from': DT_MIN,
                    'until': DT_MAX}
            if (not relkey(rrel) in vgroup_rlut and relkey(rrel)
                    not in year_vgroup_rel_ok):
                logging.info("vgroup: adding %s -> %s (%s)" % (
                    id2name[mrel['who']], yg.name,
                    id2name.get(mrel['how'])))
                Es.rcol.insert(rrel)
            elif relkey(rrel) in vgroup_rlut:
                del vgroup_rlut[relkey(rrel)]
            year_vgroup_rel_ok.add(relkey(rrel))
    # Check whether all sofas are created
    sofa_brands = {}
    for b in Es.brands():
        if tags['!sofa-brand'] not in b._data['tags']:
            continue
        sofa_brands[b._id] = b
    for rel in Es.query_relations(how=tuple(sofa_brands.values())):
        if (rel['how'], rel['with']) in sofa_lut:
            continue
        if not id2name[rel['with']]:
            continue
        g = groups[id2name[rel['with']]]
        nm = str(g.name) + '-' + sofa_brands[rel['how']].sofa_suffix
        logging.info("creating sofa %s" % nm)
        n = {'types': ['group', 'tag'],
             'names': [nm],
             'tags': [tags['!virtual-group']],
             'virtual': {
                 'type': 'sofa',
                 'with': rel['with'],
                 'how': rel['how']},
             'humanNames': [{
                 'name': nm,
                 'human': six.text_type(g.humanName) + ' ' +
                 six.text_type(sofa_brands[rel['how']].humanName)}]}
        n['_id'] = Es.ecol.insert(n)
        groups[nm] = Es.Group(n)
        id2name[n['_id']] = nm
        sofa_vgroups.append(g)
        sofa_lut[rel['how'], rel['with']] = [groups[nm]]
        sofa_queries.append({'how': rel['how'],
                             'with': rel['with']})
    # Find all relations for the sofa virtual groups and check whether
    # the appropriate relations to the sofas are generated
    for rel in Es.disj_query_relations(sofa_queries):
        for svg in sofa_lut[(rel['how'], rel['with'])]:
            rrel = {'how': None,
                    'from': rel['from'],
                    'until': rel['until'],
                    'who': rel['who'],
                    'with': svg._id}
            if not relkey(rrel) in vgroup_rlut:
                logging.info("sofa: adding %s to %s" % (
                    id2name[rrel['who']], str(svg.name)))
                Es.rcol.insert(rrel)
            else:
                del vgroup_rlut[relkey(rrel)]
    # Check which relations to vgroups are unaccounted for and thus are to
    # be removed.
    for relkey in vgroup_rlut:
        logging.info("removing superfluous %s -> %s (%s)" % (
            id2name[relkey[0]], id2name.get(relkey[2]),
            id2name.get(relkey[1])))
        Es.remove_relation(relkey[0], relkey[2], relkey[1], relkey[3],
                           relkey[4])
    # Set is_active on Users if and only if they are not in the `leden' group.
    # TODO We might optimize this by including it in a more generic process
    active_users = [rel['who'] for rel in Es.by_name('leden').get_rrelated(
        None, dt_now, dt_now, False, False, False)]
    for u in Es.users():
        is_active = u._id in active_users
        if u.is_active == is_active:
            continue
        u._data['is_active'] = is_active
        u.save()
        logging.info(
            "%s user %s",
            ("activated" if is_active else "deactivated"),
            str(u.name)
        )
Example #30
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path': path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path': path}) \
                    + '#' + filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path': album.path}) \
            + '#' + filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render(
            request,
            'fotos/fotos.html',
            {'fotos': {'parents': album_parents_json(album)},
             'error': 'permission-denied'},
        )
        response.status_code = 403
        return response

    if 'download' in request.GET:
        if album.is_root:
            # Downloading ALL photos would be way too much
            raise PermissionDenied
        download = ZipSeeker()
        add_download_files(download, album, album.full_path, user)
        response = StreamingHttpResponse(download.blocks(),
                                         content_type='application/zip')
        response['Content-Length'] = download.size()
        response['Last-Modified'] = http_date(download.lastModified())
        # TODO: human-readable download name?
        response['Content-Disposition'] = 'attachment; filename=' + \
            album.name + '.zip'
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first
        # by whether they are active (active members first) and
        # then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = six.text_type(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active + inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render(request, 'fotos/fotos.html',
                  {'fotos': fotos,
                   'fotos_admin': fEs.is_admin(user),
                   'people': people})
Example #31
0
def _entity_detail(request, e):
    related = sorted(e.get_related(),
                     key=lambda x: (Es.DT_MIN - Es.relation_until(x),
                                    Es.entity_humanName(x['with']),
                                    Es.entity_humanName(x['how'])))
    rrelated = sorted(e.get_rrelated(),
                      key=lambda x: (Es.DT_MIN - Es.relation_until(x),
                                     Es.entity_humanName(x['how']),
                                     Es.entity_humanName(x['who'])))
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None
                           or r['until'] >= now()
                           else Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r['until_year']
        if year is None:
            year = 'this'

        if year not in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r['who'])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {'related': related,
           'rrelated': rrelated,
           'year_counts': year_counts,
           'now': now(),
           'tags': sorted(tags, key=Es.entity_humanName),
           'object': e,
           'chiefs': [],
           'pipos': [],
           'reps': []}
    for r in rrelated:
        if r['how'] and Es.relation_is_active(r):
            if str(r['how'].name) == '!brand-hoofd':
                r['hidden'] = True
                ctx['chiefs'].append(r)
            if str(r['how'].name) == '!brand-bestuurspipo':
                r['hidden'] = True
                ctx['pipos'].append(r)
            if str(r['how'].name) == '!brand-vertegenwoordiger':
                r['hidden'] = True
                ctx['reps'].append(r)
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(key=Es.entity_humanName)
        users = sorted(Es.users(), key=Es.entity_humanName)
        brands = sorted(Es.brands(), key=Es.entity_humanName)
        ctx.update({'users': users,
                    'brands': brands,
                    'groups': groups,
                    'may_add_related': True,
                    'may_add_rrelated': True,
                    'may_tag': True,
                    'may_untag': True})
    ctx['may_upload_smoel'] = e.name and request.user.may_upload_smoel_for(e)
    if e.is_tag:
        ctx.update({'tag_bearers': sorted(e.as_tag().get_bearers(),
                                          key=Es.entity_humanName)})

    # Check whether entity has a photo
    photos_path = (path.join(settings.SMOELEN_PHOTOS_PATH, str(e.name))
                   if e.name else None)
    if photos_path and default_storage.exists(photos_path + '.jpg'):
        img = PIL.Image.open(default_storage.open(photos_path + '.jpg'))
        width, height = img.size
        if default_storage.exists(photos_path + '.orig'):
            # smoel was created using newer strategy. Shrink until it fits the
            # requirements.
            width, height = resize_proportional(img.size[0], img.size[1],
                                                settings.SMOELEN_WIDTH,
                                                settings.SMOELEN_HEIGHT)
        elif width > settings.SMOELEN_WIDTH:
            # smoel was created as high-resolution image, probably 600px wide
            width /= 2
            height /= 2
        else:
            # smoel was created as normal image, probably 300px wide
            pass
        ctx.update({
            'hasPhoto': True,
            'photoWidth': width,
            'photoHeight': height})
    return ctx
Example #32
0
def update_db(giedo):
    dt_now = now()
    # Load tags
    # TODO cache this
    tags = Es.ids_by_names(
        ('!year-group', '!year-overrides', '!virtual-group', '!sofa-brand'))
    year_overrides = {}
    for t in Es.bearers_by_tag_id(tags['!year-overrides'], _as=Es.Tag):
        year_overrides[t._id] = (t._data['year-override']['type'],
                                 t._data['year-override']['year'])

    # Load _id -> name lut.
    id2name = Es.names_by_ids()
    # Load groups and brands
    groups = Es.of_type_by_name('group')
    groups_set = frozenset(six.itervalues(groups))
    # Find groups that have a virtual group for each year
    year_groups = [g for g in groups_set if tags['!year-group'] in g.tag_ids]

    # Find relations on those groups and add the years for which those
    # relations hold.

    def add_years_to_relations(rels):
        years_of_year_overrides = [
            yo[1] for yo in six.itervalues(year_overrides)
        ]
        until_years = [
            Es.date_to_year(r['until']) for r in rels if r['until'] != DT_MAX
        ]
        max_until = max(
            max(until_years) if until_years else 0,
            max(years_of_year_overrides) if years_of_year_overrides else 0,
            Es.date_to_year(dt_now))
        from_years = [
            Es.date_to_year(r['from']) for r in rels if r['from'] != DT_MIN
        ]
        min_from = min(
            min(from_years) if from_years else Es.date_to_year(dt_now),
            Es.date_to_year(dt_now))
        for rel in rels:
            s = (min_from
                 if rel['from'] == DT_MIN else Es.date_to_year(rel['from']))
            t = (max_until
                 if rel['until'] == DT_MAX else Es.date_to_year(rel['until']))
            years = set(range(s, t + 1))
            for tid in rel.get('tags', ()):
                if tid not in year_overrides:
                    continue
                tp, yr = year_overrides[tid]
                if tp:
                    years.add(yr)
                else:
                    if yr not in years:
                        logging.warning('bogus year-override -{} on {}'.format(
                            yr, rel['_id']))
                        continue
                    years.remove(yr)
            rel['years'] = years

    year_group_mrels = tuple(Es.query_relations(_with=year_groups))
    # Check whether all year groups are created
    for g in year_groups:
        mrels = [rel for rel in year_group_mrels if rel['with'] == g._id]
        add_years_to_relations(mrels)
        years = set()
        for rel in mrels:
            years.update(rel['years'])
        for year in years:
            n = str(g.name) + str(year)
            if n not in groups:
                logging.info("Creating yeargroup %s" % n)
                _create_yeargroup(g, year, n, tags, groups, id2name)
    # Find all virtual groups
    virtual_groups = [
        g for g in groups_set if tags['!virtual-group'] in g.tag_ids
    ]
    sofa_vgroups = []
    yeargroup_vgroups = []
    for vg in virtual_groups:
        if vg._data['virtual']['type'] == 'sofa':
            sofa_vgroups.append(vg)
        elif vg._data['virtual']['type'] == 'year-group':
            yeargroup_vgroups.append(vg)
        else:
            logging.warn("Unknown vgroup type: %s" %
                         vg._data['virtua']['type'])
    # Find all relations with the sofa virtual groups

    def relkey(rel):
        return (rel['who'], rel['how'], rel['with'], rel['from'], rel['until'])

    vgroup_rlut = dict()
    for rel in Es.query_relations(_with=virtual_groups):
        vgroup_rlut[relkey(rel)] = rel['_id']
    # create look up table of existing sofas
    sofa_queries = []
    sofa_lut = dict()
    for svg in sofa_vgroups:
        w = dict(svg._data['virtual'])
        sofa_queries.append({'how': w['how'], 'with': w['with']})
        k = (w['how'], w['with'])
        if k not in sofa_lut:
            sofa_lut[k] = []
        sofa_lut[k].append(svg)
    # Check whether all year-group relations are in place
    # If there are two relations between an entity and a group in the
    # same year, we do not want this relation to be handled twice.
    # Thus we keep a seperate look-up-table to prevent this.
    year_vgroup_rel_ok = set()
    for mrel in year_group_mrels:
        g = groups[id2name[mrel['with']]]
        for year in mrel['years']:
            yg = groups[str(g.name) + str(year)]
            rrel = {
                'who': mrel['who'],
                'with': yg._id,
                'how': mrel['how'],
                'from': DT_MIN,
                'until': DT_MAX
            }
            if (not relkey(rrel) in vgroup_rlut
                    and relkey(rrel) not in year_vgroup_rel_ok):
                logging.info(
                    "vgroup: adding %s -> %s (%s)" %
                    (id2name[mrel['who']], yg.name, id2name.get(mrel['how'])))
                Es.rcol.insert(rrel)
            elif relkey(rrel) in vgroup_rlut:
                del vgroup_rlut[relkey(rrel)]
            year_vgroup_rel_ok.add(relkey(rrel))
    # Check whether all sofas are created
    sofa_brands = {}
    for b in Es.brands():
        if tags['!sofa-brand'] not in b._data['tags']:
            continue
        sofa_brands[b._id] = b
    for rel in Es.query_relations(how=tuple(sofa_brands.values())):
        if (rel['how'], rel['with']) in sofa_lut:
            continue
        if not id2name[rel['with']]:
            continue
        g = groups[id2name[rel['with']]]
        nm = str(g.name) + '-' + sofa_brands[rel['how']].sofa_suffix
        logging.info("creating sofa %s" % nm)
        n = {
            'types': ['group', 'tag'],
            'names': [nm],
            'tags': [tags['!virtual-group']],
            'virtual': {
                'type': 'sofa',
                'with': rel['with'],
                'how': rel['how']
            },
            'humanNames': [{
                'name':
                nm,
                'human':
                six.text_type(g.humanName) + ' ' +
                six.text_type(sofa_brands[rel['how']].humanName)
            }]
        }
        n['_id'] = Es.ecol.insert(n)
        groups[nm] = Es.Group(n)
        id2name[n['_id']] = nm
        sofa_vgroups.append(g)
        sofa_lut[rel['how'], rel['with']] = [groups[nm]]
        sofa_queries.append({'how': rel['how'], 'with': rel['with']})
    # Find all relations for the sofa virtual groups and check whether
    # the appropriate relations to the sofas are generated
    for rel in Es.disj_query_relations(sofa_queries):
        for svg in sofa_lut[(rel['how'], rel['with'])]:
            rrel = {
                'how': None,
                'from': rel['from'],
                'until': rel['until'],
                'who': rel['who'],
                'with': svg._id
            }
            if not relkey(rrel) in vgroup_rlut:
                logging.info("sofa: adding %s to %s" %
                             (id2name[rrel['who']], str(svg.name)))
                Es.rcol.insert(rrel)
            else:
                del vgroup_rlut[relkey(rrel)]
    # Check which relations to vgroups are unaccounted for and thus are to
    # be removed.
    for relkey in vgroup_rlut:
        logging.info("removing superfluous %s -> %s (%s)" %
                     (id2name[relkey[0]], id2name.get(
                         relkey[2]), id2name.get(relkey[1])))
        Es.remove_relation(relkey[0], relkey[2], relkey[1], relkey[3],
                           relkey[4])
    # Set is_active on Users if and only if they are not in the `leden' group.
    # TODO We might optimize this by including it in a more generic process
    active_users = [
        rel['who'] for rel in Es.by_name('leden').get_rrelated(
            None, dt_now, dt_now, False, False, False)
    ]
    for u in Es.users():
        is_active = u._id in active_users
        if u.is_active == is_active:
            continue
        u._data['is_active'] = is_active
        u.save()
        logging.info("%s user %s",
                     ("activated" if is_active else "deactivated"),
                     str(u.name))
Example #33
0
def fotos(request, path=''):
    path = unquote(path)

    if any(k in request.GET for k in ['album', 'search_album', 'search_tag']):
        # redirect old URL
        path = request.GET.get('album', '')
        q = None
        if request.GET.get('search_album'):
            q = 'album:' + request.GET.get('search_album')
        if request.GET.get('search_tag'):
            q = 'tag:' + request.GET.get('search_tag')
        url = reverse('fotos', kwargs={'path':path})
        if q is not None:
            qs = QueryDict('', mutable=True)
            qs['q'] = q
            url += '?' + qs.urlencode()
        return redirect(url, permanent=True)

    album = fEs.by_path(path)
    if album is None:
        bits = path.rsplit('/', 1)
        if len(bits) == 2:
            path = bits[0]
            name = bits[1].replace('+', ' ')
            entity = fEs.by_path_and_name(path, name)
            if entity is not None:
                # Zen Photo used + signs in the filename part of the URL.
                url = reverse('fotos', kwargs={'path':path}) \
                        + '#'+filepath_to_uri(name)
                return redirect(url, permanent=True)
        raise Http404

    if album._type != 'album':
        # This is a photo, not an album.
        # Backwards compatibility, probably to Zen Photo.
        url = reverse('fotos', kwargs={'path':album.path}) \
                + '#'+filepath_to_uri(album.name)
        return redirect(url, permanent=True)

    user = request.user if request.user.is_authenticated() else None

    if not album.may_view(user) and user is None:
        # user is not logged in
        return redirect_to_login(request.get_full_path())

    if not album.may_view(user):
        # user is logged in, but may not view the album
        title = album.title
        if not title:
            title = album.name
        # respond with a nice error message
        response = render_to_response('fotos/fotos.html',
                  {'fotos': {'parents': album_parents_json(album)},
                   'error': 'permission-denied'},
                  context_instance=RequestContext(request))
        response.status_code = 403
        return response

    people = None
    if fEs.is_admin(user):
        # Get all members (now or in the past), and sort them first by whether they
        # are active (active members first) and then by their name.
        humanNames = {}
        active = []
        inactive = []
        for u in Es.users():
            humanNames[str(u.name)] = unicode(u.humanName)
            if u.is_active:
                active.append(str(u.name))
            else:
                inactive.append(str(u.name))
        active.sort()
        inactive.sort()
        people = []
        for name in active+inactive:
            people.append((name, humanNames[name]))

    fotos = album_json(album, user)
    return render_to_response('fotos/fotos.html',
             {'fotos': fotos,
              'fotos_admin': fEs.is_admin(user),
              'people': people},
             context_instance=RequestContext(request))
Example #34
0
def _entity_detail(request, e):
    related = sorted(e.get_related(),
                     key=lambda x: (Es.DT_MIN - Es.relation_until(x),
                                    Es.entity_humanName(x['with']),
                                    Es.entity_humanName(x['how'])))
    rrelated = sorted(e.get_rrelated(),
                      key=lambda x: (Es.DT_MIN - Es.relation_until(x),
                                     Es.entity_humanName(x['how']),
                                     Es.entity_humanName(x['who'])))
    for r in chain(related, rrelated):
        r['may_end'] = Es.user_may_end_relation(request.user, r)
        r['id'] = r['_id']
        r['until_year'] = (None if r['until'] is None
                           or r['until'] >= now()
                           else Es.date_to_year(r['until']))
        r['virtual'] = Es.relation_is_virtual(r)
    tags = [t.as_primary_type() for t in e.get_tags()]

    # mapping of year => set of members
    year_sets = {}
    for r in rrelated:
        year = r['until_year']
        if year is None:
            year = 'this'

        if year not in year_sets:
            year_sets[year] = set()
        year_sets[year].add(r['who'])

    year_counts = {}
    for year in year_sets:
        year_counts[year] = len(year_sets[year])

    ctx = {'related': related,
           'rrelated': rrelated,
           'year_counts': year_counts,
           'now': now(),
           'tags': sorted(tags, key=Es.entity_humanName),
           'object': e,
           'chiefs': [],
           'pipos': [],
           'reps': []}
    for r in rrelated:
        if r['how'] and Es.relation_is_active(r):
            if str(r['how'].name) == '!brand-hoofd':
                r['hidden'] = True
                ctx['chiefs'].append(r)
            if str(r['how'].name) == '!brand-bestuurspipo':
                r['hidden'] = True
                ctx['pipos'].append(r)
            if str(r['how'].name) == '!brand-vertegenwoordiger':
                r['hidden'] = True
                ctx['reps'].append(r)
    # Is request.user allowed to add (r)relations?
    if ('secretariaat' in request.user.cached_groups_names
            and (e.is_group or e.is_user)):
        groups = [g for g in Es.groups() if not g.is_virtual]
        groups.sort(key=Es.entity_humanName)
        users = sorted(Es.users(), key=Es.entity_humanName)
        brands = sorted(Es.brands(), key=Es.entity_humanName)
        ctx.update({'users': users,
                    'brands': brands,
                    'groups': groups,
                    'may_add_related': True,
                    'may_add_rrelated': True,
                    'may_tag': True,
                    'may_untag': True})
    ctx['may_upload_smoel'] = e.name and request.user.may_upload_smoel_for(e)
    if e.is_tag:
        ctx.update({'tag_bearers': sorted(e.as_tag().get_bearers(),
                                          key=Es.entity_humanName)})

    # Check whether entity has a photo
    photo_size = e.photo_size
    if e.photo_size is not None:
        ctx.update({
            'hasPhoto': True,
            'photoWidth': photo_size[0],
            'photoHeight': photo_size[1]})
    return ctx