def __init__(self, id, trashed, app, authors, title, time, location, description): super().__init__(id=id, trashed=trashed, app=app) Editable.__init__(self, authors=authors) self.title = title self.time = time self.location = location self.description = description self._items_key = self.id + '.items' self._trashed_items_key = self.id + '.trashed_items' self.items = JSONRedisMapping(self.app.r, self._items_key) self.trashed_items = JSONRedisMapping(self.app.r, self._trashed_items_key)
def __init__(self, id, trashed, app, authors, title, time, location, description): super().__init__(id=id, trashed=trashed, app=app) Editable.__init__(self, authors=authors) self.title = title self.time = parse_isotime(time) if time else None self.location = location self.description = description self._items_key = self.id + '.items' self._trashed_items_key = self.id + '.trashed_items' self.items = JSONRedisMapping(self.app.r, self._items_key) self.trashed_items = JSONRedisMapping(self.app.r, self._trashed_items_key)
def setUp(self): super().setUp() self.objects = OrderedDict([('cat:0', Cat('cat:0', 'Happy')), ('cat:1', Cat('cat:1', 'Grumpy')), ('cat:2', Cat('cat:2', 'Long')), ('cat:3', Cat('cat:3', 'Monorail')), ('cat:4', Cat('cat:4', 'Ceiling'))]) self.r.omset(self.objects) self.r.rpush('cats', *self.objects.keys()) self.cats = JSONRedisMapping(self.r, 'cats')
def __init__(self, redis_url='', email='bot@localhost', smtp_url='', render_email_auth_message=None): super().__init__(redis_url=redis_url, email=email, smtp_url=smtp_url, render_email_auth_message=render_email_auth_message) self.types.update({'Meeting': Meeting, 'AgendaItem': AgendaItem}) self.meetings = JSONRedisMapping(self.r, 'meetings')
class Meeting(Object, Editable): """See :ref:`Meeting`. .. attribute:: items Ordered map of :class:`AgendaItem` s on the meeting's agenda. .. attribute:: trashed_items Ordered map of trashed (deleted) :class:`AgendaItem` s. """ def __init__(self, id, trashed, app, authors, title, time, location, description): super().__init__(id=id, trashed=trashed, app=app) Editable.__init__(self, authors=authors) self.title = title self.time = parse_isotime(time) if time else None self.location = location self.description = description self._items_key = self.id + '.items' self._trashed_items_key = self.id + '.trashed_items' self.items = JSONRedisMapping(self.app.r, self._items_key) self.trashed_items = JSONRedisMapping(self.app.r, self._trashed_items_key) def do_edit(self, **attrs): e = InputError() if 'title' in attrs and not str_or_none(attrs['title']): e.errors['title'] = 'empty' e.trigger() if 'title' in attrs: self.title = attrs['title'] if 'time' in attrs: self.time = attrs['time'] if 'location' in attrs: self.location = str_or_none(attrs['location']) if 'description' in attrs: self.description = str_or_none(attrs['description']) def create_agenda_item(self, title, duration=None, description=None): """See :http:post:`/api/meetings/(id)/items`.""" if not self.app.user: raise PermissionError() e = InputError() if str_or_none(title) is None: e.errors['title'] = 'empty' if duration is not None and duration <= 0: e.errors['duration'] = 'not_positive' description = str_or_none(description) e.trigger() item = AgendaItem(id='AgendaItem:' + randstr(), trashed=False, app=self.app, authors=[self.app.user.id], title=title, duration=duration, description=description) self.app.r.oset(item.id, item) self.app.r.rpush(self._items_key, item.id) return item def trash_agenda_item(self, item): """See :http:post:`/api/meetings/(id)/trash-agenda-item`.""" if not self.app.r.lrem(self._items_key, 1, item.id): raise ValueError('item_not_found') self.app.r.rpush(self._trashed_items_key, item.id) item.trashed = True self.app.r.oset(item.id, item) def restore_agenda_item(self, item): """See :http:post:`/api/meetings/(id)/restore-agenda-item`.""" if not self.app.r.lrem(self._trashed_items_key, 1, item.id): raise ValueError('item_not_found') self.app.r.rpush(self._items_key, item.id) item.trashed = False self.app.r.oset(item.id, item) def move_agenda_item(self, item, to): """See :http:post:`/api/meetings/(id)/move-agenda-item`.""" if to: if to.id not in self.items: raise ValueError('to_not_found') if to == item: # No op return if not self.app.r.lrem(self._items_key, 1, item.id): raise ValueError('item_not_found') if to: self.app.r.linsert(self._items_key, 'after', to.id, item.id) else: self.app.r.lpush(self._items_key, item.id) def json(self, restricted=False, include=False): """See :meth:`Object.json`. If *include_items* is ``True``, *items* and *trashed_items* are included. """ json = super().json(restricted=restricted, include=include) json.update(Editable.json(self, restricted=restricted, include=include)) json.update({ 'title': self.title, 'time': self.time.isoformat() + 'Z' if self.time else None, 'location': self.location, 'description': self.description }) if include: json['items'] = [ i.json(restricted=restricted, include=include) for i in self.items.values() ] json['trashed_items'] = [ i.json(restricted=restricted, include=include) for i in self.trashed_items.values() ] return json
class Meeting(Object, Editable): """See :ref:`Meeting`. .. attribute:: items Ordered map of :class:`AgendaItem` s on the meeting's agenda. .. attribute:: trashed_items Ordered map of trashed (deleted) :class:`AgendaItem` s. """ def __init__(self, id, trashed, app, authors, title, time, location, description): super().__init__(id=id, trashed=trashed, app=app) Editable.__init__(self, authors=authors) self.title = title self.time = time self.location = location self.description = description self._items_key = self.id + '.items' self._trashed_items_key = self.id + '.trashed_items' self.items = JSONRedisMapping(self.app.r, self._items_key) self.trashed_items = JSONRedisMapping(self.app.r, self._trashed_items_key) def do_edit(self, **attrs): e = InputError() if 'title' in attrs and not str_or_none(attrs['title']): e.errors['title'] = 'empty' e.trigger() if 'title' in attrs: self.title = attrs['title'] if 'time' in attrs: self.time = attrs['time'] if 'location' in attrs: self.location = str_or_none(attrs['location']) if 'description' in attrs: self.description = str_or_none(attrs['description']) def create_agenda_item(self, title, duration=None, description=None): """See :http:post:`/api/meetings/(id)/items`.""" if not self.app.user: raise PermissionError() e = InputError() if str_or_none(title) is None: e.errors['title'] = 'empty' if duration is not None and duration <= 0: e.errors['duration'] = 'not_positive' description = str_or_none(description) e.trigger() item = AgendaItem( id='AgendaItem:' + randstr(), trashed=False, app=self.app, authors=[self.app.user.id], title=title, duration=duration, description=description) self.app.r.oset(item.id, item) self.app.r.rpush(self._items_key, item.id) return item def trash_agenda_item(self, item): """See :http:post:`/api/meetings/(id)/trash-agenda-item`.""" if not self.app.r.lrem(self._items_key, 1, item.id): raise ValueError('item_not_found') self.app.r.rpush(self._trashed_items_key, item.id) item.trashed = True self.app.r.oset(item.id, item) def restore_agenda_item(self, item): """See :http:post:`/api/meetings/(id)/restore-agenda-item`.""" if not self.app.r.lrem(self._trashed_items_key, 1, item.id): raise ValueError('item_not_found') self.app.r.rpush(self._items_key, item.id) item.trashed = False self.app.r.oset(item.id, item) def move_agenda_item(self, item, to): """See :http:post:`/api/meetings/(id)/move-agenda-item`.""" if to: if to.id not in self.items: raise ValueError('to_not_found') if to == item: # No op return if not self.app.r.lrem(self._items_key, 1, item.id): raise ValueError('item_not_found') if to: self.app.r.linsert(self._items_key, 'after', to.id, item.id) else: self.app.r.lpush(self._items_key, item.id) def json(self, restricted=False, include_users=False, include_items=False): """See :meth:`Object.json`. If *include_items* is ``True``, *items* and *trashed_items* are included. """ # pylint: disable=arguments-differ; extended signature json = super().json(attrs={ 'title': self.title, 'time': self.time.isoformat() + 'Z' if self.time else None, 'location': self.location, 'description': self.description }) json.update(Editable.json(self, restricted=restricted, include_users=include_users)) if include_items: json['items'] = [i.json(restricted=restricted, include_users=include_users) for i in self.items.values()] json['trashed_items'] = [i.json(restricted=restricted, include_users=include_users) for i in self.trashed_items.values()] return json