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])
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='*****@*****.**')
def event_create(request): if not may_manage_planning(request.user): raise PermissionDenied if request.method == 'POST': form = EventCreateForm(request.POST) if form.is_valid(): fd = form.cleaned_data day = date_to_dt(fd['date']) e = Event({ 'name': fd['name'], 'date': day, 'kind': fd['template'] }) e.save() for poolname, periods in templates[fd['template']].items(): pool = Pool.by_name(poolname) for period in periods: begin_date = day + datetime.timedelta(seconds=period[0][0]) end_date = day + datetime.timedelta(seconds=period[1][0]) v = Vacancy({ 'name': period[2], 'event': _id(e), 'begin': (begin_date, period[0][1]), 'end': (end_date, period[1][1]), 'pool': _id(pool), 'assignee': None, 'reminder_needed': True, }) v.save() return HttpResponseRedirect( reverse('planning-event-edit', args=(e._id, ))) else: form = EventCreateForm() return render(request, 'planning/event_create.html', {'form': form})
def event_create(request): if request.method == 'POST': form = EventCreateForm(request.POST) if form.is_valid(): fd = form.cleaned_data day = date_to_dt(fd['date']) e = Event({ 'name': fd['name'], 'date': day, 'kind': fd['template']}) e.save() for poolname, periods in templates[fd['template']].items(): pool = Pool.by_name(poolname) for period in periods: begin_date = day + datetime.timedelta(seconds=period[0][0]) end_date = day + datetime.timedelta(seconds=period[1][0]) v = Vacancy({ 'name': period[2], 'event': _id(e), 'begin': (begin_date, period[0][1]), 'end': (end_date, period[1][1]) , 'pool': _id(pool), 'assignee': None, 'reminder_needed': True, }) v.save() return HttpResponseRedirect(reverse('planning-event-edit', args=(e._id,))) else: form = EventCreateForm() return render_to_response('planning/event_create.html', {'form': form}, context_instance=RequestContext(request))
def planning_view(request): period = 'now' if request.GET.get('year') in {'past1', 'past2'}: period = request.GET['year'] pools = list(Pool.all()) poolid2index = dict() poolids = set() for pool in pools: poolids.add(_id(pool)) # TODO reduce number of queries current = date_to_midnight(now() - datetime.timedelta(days=1)) past1year = date_to_midnight(now() - datetime.timedelta(days=356)) past2year = date_to_midnight(now() - datetime.timedelta(days=356*2)) if period == 'now': start = current end = None elif period == 'past1': start = past1year end = current elif period == 'past2': start = past2year end = past1year event_entities = list(Event.all_in_period(start, end)) used_pools = set() for e in event_entities: for v in e.vacancies(): used_pools.add(v.pool_id) pools_tpl = [] i = 0 for pool in pools: if _id(pool) not in used_pools: continue poolid2index[pool._id] = i pools_tpl.append(pool) i += 1 events = list() for e in event_entities: ei = {'id': _id(e), 'name': e.name, 'datetime': e.date, 'kind': e.kind, 'vacancies': dict()} for index in poolid2index.values(): ei['vacancies'][index] = list() for v in e.vacancies(): ei['vacancies'][poolid2index[v.pool_id]].append({ 'begin': v.begin, 'begin_time': v.begin_time, 'end_time': v.end_time, 'assignee': v.assignee.humanName if v.assignee else "?"}) for index in poolid2index.values(): ei['vacancies'][index].sort(key=lambda x: x['begin']) events.append(ei) events.sort(key=lambda x: x['datetime']) return render_to_response('planning/overview.html', {'events': events, 'pools': pools_tpl, 'period': period}, context_instance=RequestContext(request))
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='*****@*****.**')
def last_shift(self, worker): for v in vcol.find({ 'assignee': _id(worker), 'pool': _id(self) }, sort=[('begin', DESCENDING)], limit=1): return Vacancy(v).begin.date()
def remove_relation(who, _with, how, _from, until): if _from is None: _from = DT_MIN if until is None: until = DT_MAX rcol.remove({'who': _id(who), 'with': _id(_with), 'how': None if how is None else _id(how), 'from': _from, 'until': until})
def event_edit(request, eventid): if not may_manage_planning(request.user): raise PermissionDenied avform = None e = Event.by_id(eventid) if e is None: raise Http404 if request.method == 'POST': if request.POST['action'] == 'remove_event': for vacancy in e.vacancies(): vacancy.delete() e.delete() return HttpResponseRedirect(reverse('planning-poollist')) elif request.POST['action'] == 'remove_vacancy': Vacancy.by_id(_id(request.POST['vacancy_id'])).delete() return HttpResponseRedirect(reverse('planning-event-edit', args=(eventid,))) elif request.POST['action'] == 'add_vacancy': avform = AddVacancyForm(request.POST) if avform.is_valid(): fd = avform.cleaned_data (begin_hour, begin_minute) = map(int, fd['begin'].split(':')) (end_hour, end_minute) = map(int, fd['end'].split(':')) begin_offset = hm2s(begin_hour, begin_minute) end_offset = hm2s(end_hour, end_minute) begin_date = e.date + datetime.timedelta(seconds=begin_offset) end_date = e.date + datetime.timedelta(seconds=end_offset) v = Vacancy({ 'name': fd['name'], 'event': _id(e), 'begin': (begin_date, fd['begin_is_approximate'] == "True"), 'end': (end_date, fd['end_is_approximate'] == "True"), 'pool': _id(fd['pool']), 'assignee': None, 'reminder_needed': True, }) v.save() return HttpResponseRedirect(reverse('planning-event-edit', args=(eventid,))) if avform is None: avform = AddVacancyForm() pools = dict() for p in Pool.all(): pools[_id(p)] = p vacancies = list() for v in e.vacancies(): v.poolname = pools[v.pool_id].name v.assignee_text = str(v.assignee.name) if v.assignee else "-" v.vid = str(v._id) vacancies.append(v) vacancies.sort(key=lambda x: str(x.pool_id) + str(x.begin)) return render( request, 'planning/event_edit.html', {'name': e.name, 'kind': e.kind, 'date': e.date.date(), 'avform': avform, 'vacancies': vacancies}, )
def is_related_with(self, whom, how=None): dt = now() how = None if how is None else _id(how) return rcol.find_one( {'who': _id(self), 'how': how, 'from': {'$lte': dt}, 'until': {'$gte': dt}, 'with': _id(whom)}, {'_id': True}) is not None
def notify_informacie(event, entity=None, relation=None): data = {'when': now(), 'event': event} if relation is not None: data['rel'] = _id(relation) elif entity is not None: data['entity'] = _id(entity) else: raise ValueError, 'supply either entity or relation' incol.insert(data)
def last_shift_in(self, pool): self.last_shift = None for v in vcol.find({ 'assignee': _id(self), 'pool': _id(pool) }, sort=[('begin', DESCENDING)], limit=1): return Vacancy(v).begin.date()
def event_new_or_edit(request, edit=None): superuser = '******' in request.user.cached_groups_names if edit is not None: e = subscr_Es.event_by_name(edit) if e is None: raise Http404 if not superuser and not request.user.is_related_with(e.owner) and \ not _id(e.owner) == request.user.id: raise PermissionDenied AddEventForm = get_add_event_form(request.user, superuser) if request.method == 'POST': form = AddEventForm(request.POST) if form.is_valid(): fd = form.cleaned_data if not superuser and not request.user.is_related_with( fd['owner']) and not fd['owner'] == request.user.id: raise PermissionDenied name = fd['name'] # If not secretariaat, then prefix name with the username prefix = str(request.user.name) + '-' if not superuser and not name.startswith(prefix): name = prefix + name d = { 'date': date_to_dt(fd['date']), 'owner': _id(fd['owner']), 'description': fd['description'], 'mailBody': fd['mailBody'], 'humanName': fd['humanName'], 'createdBy': request.user._id, 'name': name, 'cost': str(fd['cost']), 'is_open': True} if edit is None: e = subscr_Es.Event(d) else: e._data.update(d) e.save() act = 'bewerkt' if edit else 'aangemaakt' EmailMessage( "Activiteit %s %s door %s" % (fd['humanName'], act, unicode(request.user.humanName)), "%s heeft een activiteit %s:\n\n"\ " http://karpenoktem.nl%s" % (unicode(request.user.humanName), act, reverse('event-detail', args=(e.name,))), 'Karpe Noktem Activiteiten <*****@*****.**>', ['*****@*****.**']).send() return HttpResponseRedirect(reverse('event-detail', args=(e.name,))) elif edit is None: form = AddEventForm() else: d = e._data form = AddEventForm(d) ctx = {'form': form} return render_to_response('subscriptions/event_new_or_edit.html', ctx, context_instance=RequestContext(request))
def remove_relation(who, _with, how, _from, until): if _from is None: _from = DT_MIN if until is None: until = DT_MAX rcol.remove({ 'who': _id(who), 'with': _id(_with), 'how': None if how is None else _id(how), 'from': _from, 'until': until })
def add_relation(who, _with, how=None, _from=None, until=None): if _from is None: _from = DT_MIN if until is None: until = DT_MAX rcol.insert({'who': _id(who), 'with': _id(_with), 'how': None if how is None else _id(how), 'from': _from, 'until': until})
def add_relation(who, _with, how=None, _from=None, until=None): if _from is None: _from = DT_MIN if until is None: until = DT_MAX return rcol.insert({ 'who': _id(who), 'with': _id(_with), 'how': None if how is None else _id(how), 'from': _from, 'until': until })
def user_may_end_relation(user, rel): """ Returns whether @user may end @rel """ if relation_is_virtual(rel): return False if not relation_is_active(rel): return False if 'secretariaat' in user.cached_groups_names: return True if _id(rel['who']) == _id(user) and \ rel['how'] is None and \ by_id(rel['with']).has_tag(id_by_name('!free-to-join', True)): return True return False
def user_may_begin_relation(user, who, _with, how): """ Returns whether @user may begin a @how-relation between @who and @_with """ _with_e = by_id(_with) user_e = by_id(user) if _with_e.is_group and _with_e.as_group().is_virtual: return False if 'secretariaat' in user_e.cached_groups_names: return True if _with_e.has_tag(id_by_name('!free-to-join', True)): if _id(user) == _id(who) and how is None: return True return False
def get_subscription(self, user, create=False): ''' Return Subscription for user, creating it if it doesn't already exist. ''' subscription = self._subscriptions.get(str(_id(user))) if subscription or not create: return subscription if 'subscriptions' not in self._data: self._data['subscriptions'] = [] d = {'user': _id(user)} self._data['subscriptions'].append(d) subscription = Subscription(d, self) self._subscriptions[str(_id(user))] = subscription return subscription
def planning_view(request): if 'lookbehind' in request.GET: lookbehind = int(request.GET['lookbehind']) else: lookbehind = 1 pools = list(Pool.all()) poolid2index = dict() poolids = set() for pool in pools: poolids.add(_id(pool)) # TODO reduce number of queries event_entities = list(Event.all_since_datetime(date_to_midnight(now()) - datetime.timedelta(days=lookbehind))) used_pools = set() for e in event_entities: for v in e.vacancies(): used_pools.add(v.pool_id) pools_tpl = [] i = 0 for pool in pools: if _id(pool) not in used_pools: continue poolid2index[pool._id] = i pools_tpl.append(pool) i += 1 events = list() for e in event_entities: ei = { 'id': _id(e), 'name': e.name, 'datetime': e.date, 'kind': e.kind, 'vacancies': dict()} for index in poolid2index.values(): ei['vacancies'][index] = list() for v in e.vacancies(): ei['vacancies'][poolid2index[v.pool_id]].append({ 'begin': v.begin, 'begin_time': v.begin_time, 'end_time': v.end_time, 'assignee': v.assignee.humanName if v.assignee else "?"}) for index in poolid2index.values(): ei['vacancies'][index].sort(key=lambda x: x['begin']) events.append(ei) events.sort(key=lambda x: x['datetime']) return render_to_response('planning/overview.html', {'events': events, 'pools': pools_tpl}, context_instance=RequestContext(request))
def is_related_with(self, whom, how=None): dt = now() how = None if how is None else _id(how) return rcol.find_one( { 'who': _id(self), 'how': how, 'from': { '$lte': dt }, 'until': { '$gte': dt }, 'with': _id(whom) }, {'_id': True}) is not None
def update_study(self, study, institute, number, save=True): """ Adds (study, institute, number) as new and primary. """ if 'studies' not in self._data: self._data['studies'] = [] studies = self._data['studies'] dt = now() if studies: studies[0]['until'] = dt studies.insert(0, {'study': _id(study), 'institute': _id(institute), 'number': number, 'from': dt, 'until': DT_MAX}) if save: self.save()
def secr_add_group(request): if "secretariaat" not in request.user.cached_groups_names: raise PermissionDenied if request.method == "POST": form = AddGroupForm(request.POST) if form.is_valid(): fd = form.cleaned_data nm = fd["name"] g = Es.Group( { "types": ["group", "tag"], "names": [nm], "use_mailman_list": fd["true_group"], "has_unix_group": fd["true_group"], "humanNames": [{"name": nm, "human": fd["humanName"], "genitive_prefix": fd["genitive_prefix"]}], "description": fd["description"], "tags": [_id(fd["parent"])], } ) logging.info("Added group %s" % nm) g.save() Es.notify_informacie("addgroup", request.user, entity=g._id) giedo.sync_async(request) messages.info(request, "Groep toegevoegd.") return HttpResponseRedirect(reverse("group-by-name", args=(nm,))) else: form = AddGroupForm() return render_to_response("leden/secr_add_group.html", {"form": form}, context_instance=RequestContext(request))
def relation_begin(request): # TODO We should use Django forms, or better: use sweet Ajax d = {} for t in ('who', 'with', 'how'): if t not in request.POST: raise ValueError, "Missing attr %s" % t if t == 'how' and request.POST[t] == 'null': d[t] = None else: d[t] = _id(request.POST[t]) if not Es.user_may_begin_relation(request.user, d['who'], d['with'], d['how']): raise PermissionDenied # Check whether such a relation already exists dt = now() ok = False try: next(Es.query_relations(who=d['who'], _with=d['with'], how=d['how'], _from=dt, until=DT_MAX)) except StopIteration: ok = True if not ok: raise ValueError, "This relation already exists" # Add the relation! Es.add_relation(d['who'], d['with'], d['how'], dt, DT_MAX) giedo.sync() return redirect_to_referer(request)
def relation_begin(request): # TODO We should use Django forms, or better: use sweet Ajax d = {} for t in ("who", "with", "how"): if t not in request.POST: raise ValueError, "Missing attr %s" % t if t == "how" and (not request.POST[t] or request.POST[t] == "null"): d[t] = None else: d[t] = _id(request.POST[t]) if not Es.user_may_begin_relation(request.user, d["who"], d["with"], d["how"]): raise PermissionDenied # Check whether such a relation already exists dt = now() ok = False try: next(Es.query_relations(who=d["who"], _with=d["with"], how=d["how"], _from=dt, until=DT_MAX)) except StopIteration: ok = True if not ok: raise ValueError, _("Deze relatie bestaat al") # Add the relation! relation_id = Es.add_relation(d["who"], d["with"], d["how"], dt, DT_MAX) # Notify informacie # TODO (rik) leave out 'als lid' Es.notify_informacie("relation_begin", request.user, relation=relation_id) giedo.sync_async(request) return redirect_to_referer(request)
def version_by_names(reglement_name, version_name): regl = reglement_by_name(reglement_name) if not regl: return None tmp = vcol.find_one({'name': version_name, 'reglement': _id(regl.id)}) return None if tmp is None else ReglementVersion(tmp)
def event_new(request): AddEventForm = get_add_event_form(request.user) if request.method == 'POST': form = AddEventForm(request.POST) if form.is_valid(): fd = form.cleaned_data if not request.user.is_related_with(fd['owner']): raise PermissionDenied e = subscr_Es.Event({ 'date': date_to_dt(fd['date']), 'owner': _id(fd['owner']), 'description': fd['description'], 'mailBody': fd['mailBody'], 'humanName': fd['humanName'], 'createdBy': request.user._id, 'name': fd['name'], 'cost': str(fd['cost']), 'is_open': True}) e.save() return HttpResponseRedirect(reverse('event-detail', args=(e.name,))) else: form = AddEventForm() ctx = {'form': form} return render_to_response('subscriptions/event_new.html', ctx, context_instance=RequestContext(request))
def invite(self, inviter, notes): assert not self.invited and not self.has_mutations self._data['inviter'] = _id(inviter) self._data['inviteDate'] = datetime.datetime.now() self._data['inviterNotes'] = notes self.save() self.send_notification({'state': 'invited'})
def get_subscription_of(self, user): d = scol.find_one({ 'event': self._data['_id'], 'user': _id(user)}) if d is None: return None return Subscription(d)
def secr_add_group(request): if 'secretariaat' not in request.user.cached_groups_names: raise PermissionDenied if request.method == 'POST': form = AddGroupForm(request.POST) if form.is_valid(): fd = form.cleaned_data nm = fd['name'] g = Es.Group({ 'types': ['group', 'tag'], 'names': [nm], 'use_mailman_list': fd['true_group'], 'has_unix_group': fd['true_group'], 'humanNames': [{ 'name': nm, 'human': fd['humanName'], 'genitive_prefix': fd['genitive_prefix'] }], 'description': fd['description'], 'tags': [_id(fd['parent'])] }) logging.info("Added group %s" % nm) g.save() Es.notify_informacie('addgroup', request.user, entity=g._id) giedo.sync_async(request) messages.info(request, 'Groep toegevoegd.') return HttpResponseRedirect(reverse('group-by-name', args=(nm, ))) else: form = AddGroupForm() return render(request, 'leden/secr_add_group.html', {'form': form})
def secr_add_group(request): if 'secretariaat' not in request.user.cached_groups_names: raise PermissionDenied if request.method == 'POST': form = AddGroupForm(request.POST) if form.is_valid(): fd = form.cleaned_data nm = fd['name'] g = Es.Group({ 'types': ['group', 'tag'], 'names': [nm], 'use_mailman_list': fd['true_group'], 'has_unix_group': fd['true_group'], 'humanNames': [{'name': nm, 'human': fd['humanName'], 'genitive_prefix': fd['genitive_prefix']}], 'description': fd['description'], 'tags': [_id(fd['parent'])]}) logging.info("Added group %s" % nm) g.save() Es.notify_informacie("De groep %s is opgericht." % ( unicode(g.humanName))) giedo.sync_async(request) request.user.push_message("Groep toegevoegd.") return HttpResponseRedirect(reverse('group-by-name', args=(nm,))) else: form = AddGroupForm() return render_to_response('leden/secr_add_group.html', {'form': form}, context_instance=RequestContext(request))
def disj_query_relations(queries, deref_who=False, deref_with=False, deref_how=False): """ Find relations matching any one of @queries. See @query_relations. """ if not queries: return [] bits = [] for query in queries: for attr in ('with', 'how', 'who'): if attr not in query: continue elif isinstance(query[attr], (list, tuple)): query[attr] = {'$in': map(_id, query[attr])} elif query[attr] is not None: query[attr] = _id(query[attr]) else: query[attr] = None if query.get('from') is None: query['from'] = DT_MIN if query.get('until') is None: query['until'] = DT_MAX # When DT_MIN < from < until < DT_MAX we need the most complicated # query. However, in the following four cases we can simplify the # required query bits. if query['from'] == DT_MIN and query['until'] == DT_MAX: del query['from'] del query['until'] bits.append(query) elif query['from'] == query['until']: query['from'] = {'$lte': query['from']} query['until'] = {'$gte': query['until']} bits.append(query) elif query['from'] == DT_MIN: query['from'] = {'$lte': query['until']} query['until'] = {'$gte': DT_MIN} bits.append(query) elif query['until'] == DT_MAX: query['until'] = {'$gte': query['from']} query['from'] = {'$lte': DT_MAX} bits.append(query) else: qa, qb, qc = dict(query), dict(query), dict(query) qa['until'] = {'$gte': query['from'], '$lte': query['until']} # NOTE we have to set these void conditions, otherwise # mongo will not use its indices. qa['from'] = {'$gte': DT_MIN} bits.append(qa) qb['until'] = {'$gte': DT_MIN} qb['from'] = {'$gte': query['from'], '$lte': query['until']} bits.append(qb) qc['until'] = {'$gte': query['until']} qc['from'] = {'$lte': query['from']} bits.append(qc) # NOTE If bits is a one-element-array the `$or' query does not return # anything, even if it should. Bug in MongoDB? cursor = rcol.find({'$or': bits} if len(bits) != 1 else bits[0]) if not deref_how and not deref_who and not deref_with: return cursor return __derefence_relations(cursor, deref_who, deref_with, deref_how)
def tag(self, tag, save=True): if self.has_tag(tag): raise ValueError(_("Entiteit heeft al deze stempel")) if 'tags' not in self._data: self._data['tags'] = [] self._data['tags'].append(_id(tag)) if save: self.save()
def update(self, data, user, save=True): self._data.update(data) self.pushHistory({ 'action': 'edited', 'date': datetime.datetime.now(), 'by': _id(user)}) if save: self.save()
def add_note(self, what, by=None): dt = now() note = Note({'note': what, 'on': self._id, 'by': None if by is None else _id(by), 'at': dt}) note.save() return note
def study_start(self, study, institute, number, start_date, save=True): start_date = datetime.datetime(start_date.year, start_date.month, start_date.day) if not 'studies' in self._data: self._data['studies'] = [] if start_date <= self.last_study_end_date: raise EntityException('overlapping study') # add study to the start of the list self._data['studies'].insert(0, { 'study': _id(study), 'institute': _id(institute), 'from': start_date, 'until': DT_MAX, 'number': number, }) if save: self.save()
def update(self, data, user, save=True): self._data.update(data) self.pushHistory({ 'action': 'edited', 'date': datetime.datetime.now(), 'by': _id(user) }) if save: self.save()
def disj_query_relations(queries, deref_who=False, deref_with=False, deref_how=False): """ Find relations matching any one of @queries. See @query_relations. """ bits = [] for query in queries: for attr in ('with', 'how', 'who'): if attr not in query: continue elif isinstance(query[attr], (list, tuple)): query[attr] = {'$in': map(_id, query[attr])} elif query[attr] is not None: query[attr] = _id(query[attr]) else: query[attr] = None if query.get('from') is None: query['from'] = DT_MIN if query.get('until') is None: query['until'] = DT_MAX # When DT_MIN < from < until < DT_MAX we need the most complicated # query. However, in the following four cases we can simplify the # required query bits. if query['from'] == DT_MIN and query['until'] == DT_MAX: del query['from'] del query['until'] bits.append(query) elif query['from'] == query['until']: query['from'] = {'$lte': query['from']} query['until'] = {'$gte': query['until']} bits.append(query) elif query['from'] == DT_MIN: query['from'] = {'$lte': query['until']} query['until'] = {'$gte': DT_MIN} bits.append(query) elif query['until'] == DT_MAX: query['until'] = {'$gte': query['from']} query['from'] = {'$lte': DT_MAX} bits.append(query) else: qa, qb, qc = dict(query), dict(query), dict(query) qa['until'] = {'$gte': query['from'], '$lte': query['until']} # NOTE we have to set these void conditions, otherwise # mongo will not use its indices. qa['from'] = {'$gte': DT_MIN} bits.append(qa) qb['until'] = {'$gte': DT_MIN} qb['from'] = {'$gte': query['from'], '$lte': query['until']} bits.append(qb) qc['until'] = {'$gte': query['until']} qc['from'] = {'$lte': query['from']} bits.append(qc) # NOTE If bits is a one-element-array the `$or' query does not return # anything, even if it should. Bug in MongoDB? cursor = rcol.find({'$or': bits} if len(bits) != 1 else bits[0]) if not deref_how and not deref_who and not deref_with: return cursor return __derefence_relations(cursor, deref_who, deref_with, deref_how)
def relation_by_id(__id, deref_who=True, deref_with=True, deref_how=True): cursor = rcol.find({'_id': _id(__id)}) try: if not deref_how and not deref_who and not deref_with: return next(cursor) return next( __derefence_relations(cursor, deref_who, deref_with, deref_how)) except StopIteration: return None
def close_note(data, request): """ Wraps Note.close() >> {action:"close_note", id: "5038b134d4080073f410fafd"} << {ok: true} ( << {ok: false, error: "Note already closed"} ) """ if not 'secretariaat' in request.user.cached_groups_names: return {'ok': False, 'error': 'Permission denied'} note = Es.note_by_id(_id(data.get('id'))) if note is None: return {'ok': False, 'error': 'Note not found'} if not note.open: return {'ok': False, 'error': 'Note already closed'} note.close(_id(request.user)) render_then_email('leden/note-closed.mail.txt', Es.by_name('secretariaat').canonical_full_email, { 'note': note}) return {'ok': True}
def update_study(self, study, institute, number, save=True): """ Adds (study, institute, number) as new and primary. """ if 'studies' not in self._data: self._data['studies'] = [] studies = self._data['studies'] dt = now() if studies: studies[0]['until'] = dt studies.insert( 0, { 'study': _id(study), 'institute': _id(institute), 'number': number, 'from': dt, 'until': DT_MAX }) if save: self.save()
def study_start(self, study, institute, number, start_date, save=True): start_date = datetime.datetime(start_date.year, start_date.month, start_date.day) if 'studies' not in self._data: self._data['studies'] = [] if start_date <= self.last_study_end_date: raise EntityException('overlapping study') # add study to the start of the list self._data['studies'].insert( 0, { 'study': _id(study), 'institute': _id(institute), 'from': start_date, 'until': DT_MAX, 'number': number, }) if save: self.save()
def close_note(data, request): """ Wraps Note.close() >> {action:"close_note", id: "5038b134d4080073f410fafd"} << {ok: true} ( << {ok: false, error: "Note already closed"} ) """ if not 'secretariaat' in request.user.cached_groups_names: return {'ok': False, 'error': 'Permission denied'} note = Es.note_by_id(_id(data.get('id'))) if note is None: return {'ok': False, 'error': 'Note not found'} if not note.open: return {'ok': False, 'error': 'Note already closed'} note.close(_id(request.user)) render_then_email('leden/note-closed.mail.txt', Es.by_name('secretariaat').canonical_full_email, {'note': note}) return {'ok': True}
def relation_by_id(__id, deref_who=True, deref_with=True, deref_how=True): cursor = rcol.find({'_id': _id(__id)}) try: if not deref_how and not deref_who and not deref_with: return next(cursor) return next(__derefence_relations(cursor, deref_who, deref_with, deref_how)) except StopIteration: return None
def add_note(self, what, by=None): dt = now() note = Note({ 'note': what, 'on': self._id, 'by': None if by is None else _id(by), 'at': dt }) note.save() return note
def vote(request, name): poll = poll_Es.poll_by_name(name) if not poll: raise Http404 filling = poll.filling_for(request.user) initial = False if not filling: initial = True filling = poll_Es.Filling({ 'user': _id(request.user), 'poll': _id(poll), 'answers': [None] * len(poll.questions) }) allValid = True forms = [] # question forms for q_id, question in enumerate(poll.questions): form_kwargs = {'prefix': str(q_id)} answer = filling.answers[q_id] if answer is None: answer = -1 form_kwargs['initial'] = {'answer': answer} if request.method == 'POST': form = create_questionForm(question)(request.POST, **form_kwargs) if not form.is_valid(): allValid = False else: form = create_questionForm(question)(**form_kwargs) forms.append(form) if request.method == 'POST' and not poll.is_open: request.user.push_message("De enquete is gesloten") elif allValid and request.method == 'POST': request.user.push_message('Veranderingen opgeslagen!') for q_id, form in enumerate(forms): filling.answers[q_id] = int(form.cleaned_data['answer']) filling.date = datetime.datetime.now() filling.save() return render_to_response('poll/vote.html', { 'forms': forms, 'poll': poll, 'initial': initial }, context_instance=RequestContext(request))
def add_note(self, what, by=None): dt = now() Note({ 'note': what, 'on': self._id, 'open': True, 'by': None if by is None else _id(by), 'at': dt, 'closed_by': None, 'closed_at': None }).save()
def open(self, user, save=True): if self.is_open: return self.is_open = True self.pushHistory({ 'action': 'opened', 'date': datetime.datetime.now(), 'by': _id(user) }) if save: self.save()
def close(self, user, save=True): if not self.is_open: return self.is_open = False self.pushHistory({ 'action': 'closed', 'date': datetime.datetime.now(), 'by': _id(user) }) if save: self.save()
def main(): count = 0 for vacancy in Vacancy.all(): if vacancy.assignee_id is None: continue worker_data = wcol.find_one({'_id': vacancy.assignee_id}) if worker_data is None: continue user = Es.by_id(worker_data['user']) vacancy._data['assignee'] = _id(user) vacancy.save() count += 1 print('Converted %d vacancies.' % count)
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])
def note_add(request): if not 'secretariaat' in request.user.cached_groups_names: raise PermissionDenied if 'on' not in request.POST or 'note' not in request.POST: raise ValueError, "missing `on' or `note'" on = Es.by_id(_id(request.POST['on'])) if on is None: raise Http404 on.add_note(request.POST['note'], request.user) render_then_email("leden/new-note.mail.txt", Es.by_name('secretariaat').canonical_full_email, { 'user': request.user, 'note': request.POST['note'], 'on': on}) return redirect_to_referer(request)
class AddEventForm(forms.Form): humanName = forms.CharField( label='Naam', widget=forms.TextInput(attrs={'required': ''})) if not editing: name = forms.RegexField( label=_('Naam voor computers'), regex=r'^[a-z0-9-]+$', widget=forms.TextInput(attrs={ 'required': '', 'pattern': '[a-z0-9-]+' }), validators=[validate_event_name]) description = forms.CharField( label=_('Beschrijving'), widget=forms.Textarea(attrs={'required': ''})) cost = forms.DecimalField(label=_('Kosten'), initial='0', widget=forms.NumberInput(attrs={ 'required': '', 'min': '0' })) date = forms.DateField( label=_('Datum'), widget=forms.DateInput(attrs={ 'required': '', 'placeholder': 'jjjj-mm-dd' })) max_subscriptions = forms.IntegerField( required=False, label=_('Maximum aantal deelnemers (optioneel)'), widget=forms.NumberInput(attrs={'placeholder': _('geen maximum')})) if superuser: owner = EntityChoiceField(label=_("Eigenaar")) else: owner = forms.ChoiceField(label=_('Eigenaar'), choices=[ (_id(e), six.text_type(e.humanName)) for e in get_allowed_owners(user) ]) has_public_subscriptions = forms.BooleanField( required=False, label=_('Inschrijvingen openbaar')) may_unsubscribe = forms.BooleanField( required=False, initial=False, label=_('Leden mogen zichzelf afmelden'))