class DAN(db.Document): school = db.ReferenceField(School, reverse_delete_rule=CASCADE) users = db.ListField(db.ReferenceField(User, reverse_delete_rule=NULLIFY)) is_current = db.BooleanField(default=False) start = db.DateTimeField(default=datetime.datetime.now()) end = db.DateTimeField() def age(self): """ Age (in days). """ if self.end: diff = self.end - self.start return diff.days else: diff = datetime.datetime.now() - self.start return diff.days def clone(self, finalize=True): if finalize: self.end = datetime.datetime.now() self.is_current = False self.save() if '_id' in self.__dict__: del self.__dict__['_id'] if '_created' in self.__dict__: del self.__dict__['_created'] if '_changed_fields' in self.__dict__: del self.__dict__['_changed_fields'] self.id = ObjectId() self.start = datetime.datetime.now() self.end = None self.is_current = True
class Comment(db.Document): """ Each individual comment """ creator = db.ReferenceField(User, reverse_delete_rule=NULLIFY) created = db.DateTimeField(default=datetime.datetime.now()) updated = db.DateTimeField(default=datetime.datetime.now()) published = db.BooleanField(default=True) discussion = db.GenericReferenceField() # The actual content of the comment text = db.StringField()
class Interested(db.EmbeddedDocument): """ Structure for holding information about someone being interested in a proposal """ date = db.DateTimeField(default=datetime.datetime.now()) user = db.ReferenceField(User) can_teach = db.BooleanField(default=False) can_organize = db.BooleanField(default=False) can_host = db.BooleanField(default=False)
class BaseProposal(db.Document, InterestedMixin): meta = { 'allow_inheritance': True, 'abstract': True, } title = db.StringField(max_length=255) # A copy of the original description is kept description = db.StringField() edited_description = db.StringField() # School the proposal was made to schools = db.ListField( db.ReferenceField(School, reverse_delete_rule=NULLIFY)) # Person who made the proposal proposer = db.ReferenceField(User, reverse_delete_rule=NULLIFY) created = db.DateTimeField(default=datetime.datetime.now()) updated = db.DateTimeField(default=datetime.datetime.now()) published = db.BooleanField(default=True) # The proposal that this proposal "copies" copy_of = db.ReferenceField("self", reverse_delete_rule=NULLIFY) # Events events = db.ListField(db.ReferenceField(Event, reverse_delete_rule=NULLIFY)) # Discussions discussions = db.ListField( db.ReferenceField(Discussion, reverse_delete_rule=NULLIFY)) def add_event(self, event): self.update(add_to_set__events=event) self.reload() def remove_event(self, event): self.update(pull__events=event) self.reload() def add_discussion(self, discussion): self.update(add_to_set__discussions=discussion) self.reload() def remove_discussion(self, discussion): self.update(pull__discussions=discussion) self.reload() def __str__(self): return self.title
class Stage(db.EmbeddedDocument): """ Structure for holding the stage of a proposal """ date = db.DateTimeField(default=datetime.datetime.now()) value = db.IntField(default=LIFE_ORIGIN) creator = db.ReferenceField(User) @property def pretty_date(self): return pretty_date(self.date)
class User(db.Document, UserMixin): """ A user object that integrates with Flask-Login (via UserMixin and the authenticate method) """ email = db.EmailField(unique=True) username = db.StringField(unique=True, max_length=64) display_name = db.StringField(max_length=64) password = db.StringField(max_length=255) active = db.BooleanField(default=True) role = db.IntField(default=ROLE_USER) created = db.DateTimeField(default=datetime.datetime.now()) # School/s the user is following schools = db.ListField( db.ReferenceField(School, reverse_delete_rule=NULLIFY)) # following which schools? (list of schools) # committee memberships (list) def __init__(self, is_admin=False, *args, **kwargs): super(User, self).__init__(*args, **kwargs) password = kwargs.get('password', None) if not self.id and password is not None: self.set_password(password) if not self.id and self.display_name is None: self.display_name = self.username if not self.id and is_admin: self.role = ROLE_ADMIN def is_admin(self): return self.role == ROLE_ADMIN def set_password(self, password): self.password = generate_password_hash(password) def check_password(self, password): if self.password is None: return False return check_password_hash(self.password, password) @classmethod def authenticate(self, login, password): """ Used by my implementation of Flask-Login """ try: user = self.objects.get(Q(username=login) | Q(email=login)) if user: authenticated = user.check_password(password) else: authenticated = False return user, authenticated except: import traceback print(traceback.format_exc()) return None, False def __str__(self): return self.display_name
class Place(db.Document): """ A place where an event might happen """ name = db.StringField(max_length=255, required=True) address = db.StringField() geo = db.PointField() information = db.StringField() schools = db.ListField( db.ReferenceField(School, reverse_delete_rule=NULLIFY)) creator = db.ReferenceField(User, reverse_delete_rule=NULLIFY) created = db.DateTimeField(default=datetime.datetime.now()) def __str__(self): return self.name
class Event(db.Document): """ Every event has a single start and end time. This class does not handle repeating - it is very simple. Instead, it will provide a clone method and the logic of repeating or continuing events will be handled by the application.""" #Required fields start = db.DateTimeField(default=datetime.datetime.now(), required=True) end = db.DateTimeField() title = db.StringField(max_length=255) schools = db.ListField( db.ReferenceField(School, reverse_delete_rule=NULLIFY)) creator = db.ReferenceField(User, reverse_delete_rule=NULLIFY) created = db.DateTimeField(default=datetime.datetime.now()) updated = db.DateTimeField(default=datetime.datetime.now()) # Optional fields short_description = db.StringField(max_length=255) description = db.StringField() places = db.ListField(db.ReferenceField(Place)) def save(self, *args, **kwargs): """ Update the updated field before saving """ self.updated = datetime.datetime.now() super(Event, self).save(*args, **kwargs)
class Discussion(db.Document): """ Thread of comments. """ title = db.StringField(max_length=255, required=True) # The comments and pointers to certain important comments #comments = db.SortedListField(db.ReferenceField(Comment), ordering="created", reverse=True) num_comments = db.IntField(default=0) first_comment = db.ReferenceField(Comment) last_comment = db.ReferenceField(Comment) last_comment_time = db.DateTimeField(default=datetime.datetime.now()) # Setting priority might allow for control over the ordering of discussion threads priority = db.IntField(default=0) created = db.DateTimeField(default=datetime.datetime.now()) creator = db.ReferenceField(User, reverse_delete_rule=NULLIFY) published = db.BooleanField(default=True) schools = db.ListField( db.ReferenceField(School, reverse_delete_rule=NULLIFY)) def add_comment(self, text, user, time=None): """ Creates a new comment and adds it to discussion thread """ c = Comment( creator=user, text=text, created=time or datetime.datetime.now(), discussion=self, ) c.save() #self.update(add_to_set__comments=c) #self.reload() #self.update(set__num_comments=len(self.comments)) if not self.first_comment: self.first_comment = c self.last_comment = c self.last_comment_time = c.created self.save()