Example #1
0
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
Example #2
0
class Collection(BaseProposal):
    """ A collection object """

    meta = {'collection': 'app_collection'}
    # directly included proposals
    proposals = db.ListField(db.ReferenceField(Proposal))
    collections = db.ListField(db.ReferenceField('self'))

    # todo: url

    def __init__(self, *args, **kwargs):
        super(Collection, self).__init__(*args, **kwargs)
        if not self.id:
            self.interested.append(Interested(user=self.proposer))
            self.num_interested = 1

    def add_proposal(self, p):
        self.update(add_to_set__proposals=p)
        self.reload()

    def remove_proposal(self, p):
        self.update(pull__proposals=p)
        self.reload()

    def add_collection(self, c):
        self.update(add_to_set__collections=c)
        self.reload()

    def remove_collection(self, c):
        self.update(pull__collections=c)
        self.reload()

    def all_proposals(self):
        ''' Gets all events, including those from enclosed proposals and collections '''
        all_proposals = {}
        for c in self.collections:
            all_proposals.update(c.all_proposals())
        for p in self.proposals:
            all_proposals[p.id] = p
        return sorted(all_proposals.values(), key=operator.attrgetter('title'))

    def all_events(self, date_sorted=True):
        ''' Gets all events, including those from enclosed proposals and collections '''
        all_events = {}
        for c in self.collections:
            all_events.update(c.all_events())
        for p in self.proposals:
            for e in p.events:
                all_events[e.id] = e
        for e in self.events:
            all_events[e.id] = e
        if date_sorted:
            return sorted(all_events.values(),
                          key=operator.attrgetter('start'))
        else:
            return all_events
Example #3
0
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
Example #4
0
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)
Example #5
0
class Proposal(BaseProposal):
    """ A proposal object """
    meta = {'collection': 'proposal'}
    # Tags
    tags = db.ListField(db.StringField(max_length=30))
    # School the proposal was made to
    schools = db.ListField(
        db.ReferenceField(School, reverse_delete_rule=NULLIFY))
    # Context in which the proposal was made
    source = db.IntField(default=SOURCE_WEBSITE)
    # Which stage in the organizing process
    stage = db.ListField(db.EmbeddedDocumentField(Stage))

    def __init__(self, *args, **kwargs):
        super(Proposal, self).__init__(*args, **kwargs)
        if not self.id:
            self.interested.append(Interested(user=self.proposer))
            self.num_interested = 1
            self.stage.append(Stage(creator=self.proposer, date=self.created))

    @property
    def current_stage(self):
        current_stage = None
        for s in self.stage:
            if current_stage is None or s.date > current_stage.date:
                current_stage = s
        return current_stage
Example #6
0
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=256)
    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))

    available_weekday_morning = db.BooleanField(default=False)
    available_weekday_night = db.BooleanField(default=False)
    available_weekend_morning = db.BooleanField(default=False)
    available_weekend_night = db.BooleanField(default=False)

    # 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
Example #7
0
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
Example #8
0
class OrganizeProposal(db.Document):
    start = db.DateTimeField(required=True)
    end = db.DateTimeField(required=True)
    title = db.StringField(max_length=1000, required=True)
    #short_description = db.StringField(max_length=255, required=True)
    description = db.StringField(max_length=1000000, required=True)
    teacher = db.StringField(max_length=1000, required=True)
    class_difficulty = db.StringField(max_length=1000)
    places = db.ListField(db.ReferenceField(Place), required=True)
Example #9
0
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)
Example #10
0
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 Discussion(db.Document):
	"""
	Thread of comments.
	"""
	title = db.StringField(max_length=1000, 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)
	import datetime
	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,
	#		discussion = self,
	#		)
	#	c.created = datetime.datetime.now()
	#	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()

		
class Event(db.Document, InterestedMixin):
    """ 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."""
    start = db.DateTimeField(default=datetime.datetime.now(), required=True)
    end = db.DateTimeField(required=True)
    title = db.StringField(max_length=1000, required=True)
    creator = db.ReferenceField(User, reverse_delete_rule=NULLIFY)
    created = db.DateTimeField(default=datetime.datetime.now())
    updated = db.DateTimeField(default=datetime.datetime.now())
    #short_description = db.StringField(max_length=255, required=True)
    description = db.StringField(max_length=1000000, required=True)
    teacher = db.StringField(max_length=1000, required=True)
    class_difficulty = db.StringField(max_length=1000)
    places = db.ListField(db.ReferenceField(Place))

    #schools = db.ListField(db.ReferenceField(School, reverse_delete_rule = NULLIFY))

    def save(self, *args, **kwargs):
        """ Update the updated field before saving """
        self.updated = datetime.datetime.now()
        super(Event, self).save(*args, **kwargs)
class Comment(db.Document):
	"""
	Each individual comment
	"""
	creator = db.ReferenceField(User, reverse_delete_rule = NULLIFY)
	import datetime
	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(max_length=5000, required=True)
	is_deleted = db.BooleanField(default=False)
	
	def edit_comment(self, newText):
		self.text = newText
		self.save()
Example #14
0
class Proposal(db.Document, InterestedMixin):
	""" A proposal object """
	meta = {'collection': 'proposal'}
	## Tags
	#tags = db.ListField(db.StringField(max_length=30))
	# School the proposal was made to
	schools = db.ListField(db.ReferenceField(School, reverse_delete_rule = NULLIFY))
	# Context in which the proposal was made
	source = db.IntField(default=SOURCE_WEBSITE)
	# Which stage in the organizing process
	stage = db.ListField(db.EmbeddedDocumentField(Stage))

	title = db.StringField(max_length=1000, required=True)
	# A copy of the original description is kept
	description = db.StringField(max_length=1000000, required=True)
	#edited_description = db.StringField()
	# 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))
	teachers = db.ListField(db.ReferenceField(User, reverse_delete_rule = NULLIFY))

	def __init__(self, *args, **kwargs):
		super(Proposal, self).__init__(*args, **kwargs)
		if not self.id:
			self.interested.append(Interested(user=self.proposer))
			self.num_interested = 1
			self.stage.append(Stage(creator=self.proposer, date=self.created))

	@property
	def current_stage(self):
		current_stage = None
		for s in self.stage:
			if current_stage is None or s.date>current_stage.date:
				current_stage = s
		return current_stage

	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