class Comic(db.Document): name = db.StringField(unique=True) description = db.StringField(unique=True) comicStrip = db.ListField() stories = db.ListField() events = db.ListField() series = db.ListField()
class BehaviorDiffDB(db.Document): elements_added = db.ListField(db.ReferenceField(ElementDB), db_field="elements_added", default=[]) # pylint: disable=no-member elements_removed = db.ListField(db.ReferenceField(ElementDB), db_field="elements_removed", default=[]) # pylint: disable=no-member created = db.DateTimeField(db_field="created", required=True, default=datetime.utcnow) # pylint: disable=no-member """ Returns the diff object for this data. Since the diff is only manipulated in the Application Level, all the data returned are AO """ def to_obj(self): return { "created": self.created, "diff": { "added": set(elt.to_obj() for elt in self.elements_added), "removed": set(elt.to_obj() for elt in self.elements_removed) } } def to_json(self): return { "created": self.created, "diff": { "added": set(elt.to_json() for elt in self.elements_added), "removed": set(elt.to_json() for elt in self.elements_removed) } } def __repr__(self): return f"Added: {self.elements_added} ||| Removed: {self.elements_removed}"
class HostRule(db.Document): """ Host Rule to add custom Parameters for importers or exporters """ name = db.StringField(required=True, unique=True) conditions = db.ListField(db.EmbeddedDocumentField(HostCondition)) params = db.ListField(db.EmbeddedDocumentField(HostParams)) enabled = db.BooleanField()
class LabelRule(db.Document): """ Rule to filter Labels """ name = db.StringField(required=True, unique=True) conditions = db.ListField(db.EmbeddedDocumentField(LabelCondition)) outcome = db.ListField(db.StringField(choices=label_outcome_types)) enabled = db.BooleanField()
class Post(db.Document): post_id = db.IntField(unique=True) title = db.StringField(max_length=50) teaser = db.StringField(max_length=500) body = db.ListField() date = db.DateTimeField() heading = db.ListField() image_description = db.StringField(max_length=50)
class Room(db.Document): name = db.StringField() created_at = db.DateTimeField() modified_at = db.DateTimeField() building = db.StringField() is_available = db.BooleanField() room_number = db.StringField() current_booking = db.ReferenceField( Booking, reverse_delete_rule=mongoengine.NULLIFY) last_active = db.DateTimeField() maintenance_history = db.ListField( db.ReferenceField(Maintenance, reverse_delete_rule=mongoengine.PULL)) booking_history = db.ListField( db.ReferenceField(Booking, reverse_delete_rule=db.PULL))
class ActionRule(db.Document): """ Rule to control Actions based on labels """ name = db.StringField(required=True, unique=True) condition_typ = db.StringField(choices=rule_types) conditions = db.ListField(db.EmbeddedDocumentField(ActionCondition)) outcome = db.ListField(db.EmbeddedDocumentField(ActionOutcome)) last_match = db.BooleanField(default=False) enabled = db.BooleanField() meta = { 'strict': False, }
class Articles(db.Document): url = db.StringField(max_length=100, unique=True, required=True) title = db.StringField(max_length=200) newspaper_title = db.StringField(max_length=200) topic_id = db.IntField() channel_id = db.IntField() published_date = db.DateTimeField(default=datetime.now) newspaper_published_date = db.DateTimeField(default=datetime.now) description = db.StringField() newspaper_topic = db.StringField(max_length=50) newspaper_summary = db.StringField() newspaper_text = db.StringField() newspaper_authors = db.ListField(db.StringField(max_length=20)) last_crawled = db.DateTimeField(default=datetime.now) newspaper_tags = db.ListField(db.StringField(max_length=20)) newspaper_keywords = db.ListField(db.StringField(max_length=20))
class User(UserMixin, db.Document): username = db.StringField(required=True, unique=True) password_hash = db.StringField(required=True) pairnames = db.ListField(db.StringField()) lastchannel = db.StringField(default=DEFAULTCHANNEL) @classmethod def getUsers(cls): """ returns a list of all the public channel names""" usernames = cls.objects.only('username') return [user.username for user in usernames] def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): """ check if the password is the correct one""" return check_password_hash(self.password_hash, password) def getotherperson(self, pairname): other = None both = pairname.split("-") if self.username in both: other = both[0] if both[0] != self.username else both[1] return other def addToPairNames(self, pairname): if pairname not in self.pairnames: self.pairnames.append(pairname) def __str__(self): return f"<{self.username}>"
class PageTextsDB(db.Document): """Stores the needed texts for the specified page """ page_id = db.StringField(db_field="page_id", required="True", primary_key=True) # pylint: disable=no-member page_texts = db.ListField(db.ReferenceField(TextsDB), db_field="page_texts", required=True, unique=True) # pylint: disable=no-member
class User(db.Document): user_id = db.IntField(unique=True) first_name = db.StringField(max_length=20) last_name = db.StringField(max_length=20) email = db.EmailField(max_length=30, unique=True) birthday = db.DateField() gender = db.StringField() address = db.StringField() suburb = db.StringField() postcode = db.IntField(length=4) description = db.StringField(max_length = 200) password = db.StringField(max_length=20) available = db.BooleanField(default=True) token = db.StringField() contacts = db.ListField(Contact) # profile_pic = def set_password(self, password): self.password = generate_password_hash(password) def get_password(self, password): return check_password_hash(self.password, password) def assign_token(self, id): secret = 'YUWA' token = str(jwt.encode({'id': id}, secret, algorithm='HS256')) self.token = token db.Users.update( {"_id": id}, {$set: {"token": token}} ) return token def invalidate_token(self, token): self.token = ""
class BesoinFinancier(db.Document): commande = db.StringField() fournisseur = db.StringField() montant = db.FloatField() avance = db.FloatField() paye = db.FloatField() date_echeance = db.DateTimeField() projet_id = db.ReferenceField(Projet) attente = db.BooleanField(default=True) rejet = db.BooleanField(default=False) parent = db.ReferenceField('self') last_child = db.BooleanField(default=False) updated = db.ListField(db.EmbeddedDocumentField(Update_Besoin)) def child(self): childs = BesoinFinancier.objects(parent=self.id) return childs def lasted_child(self): last = BesoinFinancier.objects(Q(parent=self.id) & Q(last_child=True)).first() return last def notified(self): data = [] for notifie in self.updated: if notifie.notified: data.append(notifie) return data
class Message(db.Document): from_user = db.ReferenceField(User, db_field="fu", reverse_delete_rule=CASCADE) to_user = db.ReferenceField(User, db_field="tu", default=None, reverse_delete_rule=CASCADE) text = db.StringField(db_field="t", max_length=1024) live = db.BooleanField(db_field="l", default=True) create_date = db.LongField(db_field="c", default=now()) parent = db.ObjectIdField(db_field="p", default=None) images = db.ListField(db_field="ii") message_type = db.IntField(db_field="mt", default=POST, choices=MESSAGE_TYPE) @property def text_linkified(self): return linkify(self.text) @property def human_timestamp(self): return ms_stamp_humanize(self.create_date) @property def comments(self): return Message.objects.filter(parent=self.id, message_type=COMMENT).order_by('create_date') @property def likes(self): return Message.objects.filter(parent=self.id, message_type=LIKE).order_by('-create_date') def post_imgsrc(self, image_ts, size): if AWS_BUCKET: return os.path.join(AWS_CONTENT_URL, AWS_BUCKET, 'posts', '%s.%s.%s.png' % (self.id, image_ts, size)) else: return url_for('static', filename=os.path.join(STATIC_IMAGE_URL, 'posts', '%s.%s.%s.png' % (self.id, image_ts, size))) meta = { 'indexes': [('from_user', 'to_user', '-create_date', 'message_type', 'live')] }
class User(db.Document, UserMixin): def __str__(self): return self.full_name meta = { 'allow_inheritance': True, 'indexes': [ 'id', 'slug', ], } email = db.StringField(max_length=128, required=True) password = db.StringField(max_length=128, required=True) full_name = db.StringField(max_length=128, required=True) slug = db.StringField(max_length=128, required=True) subjects = db.ListField(db.EmbeddedDocumentField(Subject)) def get_id(self): return str(self.id) @staticmethod def authenticate(email, password): user = User.objects(email=email, password=password).first() return user @classmethod def pre_save(cls, sender, document, **kwargs): document.slug = slugify(document.full_name) document.email = document.email.lower()
class Event(db.Document): name = db.StringField(required=True) place = db.StringField(required=True) location = db.PointField(required=True) start_datetime = db.DateTimeField(required=True) end_datetime = db.DateTimeField(required=True) event_photo = db.StringField() description = db.StringField(min_length=50, required=True) host = db.ObjectIdField(required=True) cancel = db.BooleanField(default=False) attendees = db.ListField(db.ReferenceField(User))
class SocialDB(db.Document): """ Class that maps to the database the friends list (users) of the user. Arguments: user -- The current user friends -- the list of users that accepted the requests made by the user friends_blocked -- the list of users the current user does not want to interact with friends_pending -- the list of transactions sent to users that the user requested to be in his list and is pending friends_request -- the list of transactions sent from users that requested the user to be in their contact list. friends_blocked_request -- the list of transactions sent to the system in order to block users (used to match the unblock transaction - it shall be removed then and moved to the general system transactions history). Reason: The system itself will be treated as a social networking app for games evaluation. The set operations provided by the scsr is a differential to the other game analysis tools """ user = db.ReferenceField(UserDB, db_field="user", primary_key=True) external_id = db.StringField(db_field="external_id", required=True, unique=True) #it is easier to maintain, a unique key other than the primary with the same name for all fields. (is it safe??) friends = db.ListField(db.ReferenceField(UserDB), db_field="friends") friends_blocked = db.ListField(db.ReferenceField(UserDB), db_field="friends_blocked") friends_pending = db.ListField(db.ReferenceField(FriendTransaction), db_field="friends_pending") friends_request = db.ListField(db.ReferenceField(FriendTransaction), db_field="friends_request") friends_blocked_request = db.ListField(db.ReferenceField(FriendTransaction), db_field="friends_blocked_request") def to_obj(self): retorno={ "user": self.user.to_obj(), "friends": UserDB.to_obj_list(self.friends), "friends_blocked": UserDB.to_obj_list(self.friends_blocked), "friends_pending": FriendTransaction.to_obj_list(self.friends_pending), "friends_request": FriendTransaction.to_obj_list(self.friends_request), "friends_blocked_request": FriendTransaction.to_obj_list(self.friends_blocked_request), "links": [ {"rel": "self", "href": "/social/" + self.user.external_id } ] }
class Following(db.Document): ''' hack for getting around the fact that there cannot be self referencing classes i.e. class user(): ... follower = db.referenceField(User) creates a new collection that references User instead stupid, yes neccessary, yes is there a better way, probably but im lazy ''' user = db.ReferenceField(User) following = db.ListField(db.ReferenceField(User))
class Booking(db.Document): customers = db.ListField( db.ReferenceField(Customer, reverse_delete_rule=mongoengine.PULL)) room_name = db.StringField() check_in = db.DateTimeField() check_out = db.DateTimeField() deposit = db.DecimalField() modified_at = db.DateTimeField() ppm = db.DecimalField() created_at = db.DateTimeField() created_by = db.ReferenceField(User) note = db.StringField() room_type = db.IntField() confirmed = db.BooleanField()
class Course(db.Document): created_at = db.DateTimeField( default=datetime.datetime.utcnow, required=True) projects = db.ListField(db.ReferenceField('Project')) name = db.StringField( max_length=256, min_length=4, unique=True, required=True) description = db.StringField(max_length=1024, min_length=10, required=True) supervisor = db.ReferenceField('User', reverse_delete_rule=db.PULL) teachers = db.ListField( db.ReferenceField('User', reverse_delete_rule=db.PULL)) students = db.ListField( db.ReferenceField('Student', reverse_delete_rule=db.PULL)) published = db.BooleanField(default=True, required=True) def is_user_associated(self, user): """Checks if user in course students or teachers.""" return user in self.students or user in self.teachers meta = { "indexes": [ { "fields": ['name'], "unique": True } ] } def to_dict(self, **kwargs): return { "id": self.id, "name": self.name, "description": self.description, "created_at": self.created_at, "published": self.published, "supervisor": self.supervisor.to_dict(), 'page': 1 }
class Review(db.DynamicDocument): meta = { 'collection': 'reviews', 'indexes': ['asin', 'reviewerID', 'pI', '-unixReviewTime', 'rI'], 'shard_key': ('asin', 'reviewerID'), } userid = db.StringField(db_field="reviewerID", required=True) reviewerIntId = db.IntField(db_field="rI") productIntId = db.IntField(db_field="pI") productid = db.StringField(db_field="asin", required=True) username = db.StringField(db_field="reviewerName") helpful = db.ListField(db_field="helpful") created = db.IntField(db_field="unixReviewTime", default=now()) review = db.StringField(db_field="reviewText") overall = db.FloatField(db_field="overall") title = db.StringField(db_fiedl="summary")
class TestResult(db.Document): """Results for a single test ran on a submission.""" created_at = db.DateTimeField( default=datetime.datetime.utcnow, required=True) name = db.StringField(min_length=1, required=True) cases = db.ListField( db.ReferenceField('TestCase', reverse_delete_rule=db.PULL)) success = db.BooleanField(default=False, required=True) def to_dict(self, **kwargs): return { "name": self.name, "created_at": self.created_at, "cases": [case.to_dict() for case in self.cases], "success": self.success }
class Submission(db.Document): """A student's submission.""" created_at = db.DateTimeField( default=datetime.datetime.utcnow, required=True) test_results = db.ListField( db.ReferenceField('TestResult', reverse_delete_rule=db.PULL)) processed = db.BooleanField(default=False, required=True) submitter = db.ReferenceField('Student', required=True, reverse_delete_rule=db.CASCADE) project = db.ReferenceField('Project', required=True) code = db.FileField(required=True) compile_status = db.BooleanField(default=False, required=True) compiler_out = db.StringField() started_processing_at = db.DateTimeField() finished_processing_at = db.DateTimeField() meta = { "indexes": [ { "fields": ['submitter'] }, { "fields": ['project'] } ] } def reset(self): """ Resets status as if never processed. Note: Saves document. """ self.processed = False self.compile_status = False self.compiler_out = None self.started_processing_at = None self.finished_processing_at = None for result in list(self.test_results): for case in list(result.cases): case.delete() result.delete() self.test_results = [] self.save()
class GamesGenresDB(db.Document): """ Collection that lists all games classified with the genre. Game that have 0 in the genre count must be removed from the list. Attributes: genre {GenreDB} -- The genre the games are assigned to. It is the primary key gamesList {ListField(GameDB)} -- A List of GameDB objects. Not just the references. Methods: s_append_game(the_genre, game): Adds a game to the genre list s_remove_game(the_genre, game): Removes a game to the genre list TODO: Code the methods to: Get the games that has at least one of the genres in a list assigned to them Get the games that has all genres specified assigned to them. """ genre = db.ReferenceField(GenreDB, db_field="genre", unique=True, primary_key=True) # pylint: disable=no-member gamesList = db.ListField(db.ReferenceField(GameDB), default=[]) # pylint: disable=no-member def __repr__(self): gameslist = [game.__repr__() for game in self.gamesList] return f"{self.genre.name}({self.genre.external_id}): {gameslist}" def to_obj(self): """ Provides the representation of the data. The genre and the list of objects Returns: Dict -- Dictionary type containing the genre as AO and the list of GameAO objects assigned to the genre """ return GamesGenresAO.from_db(self) @staticmethod def seek_genre(the_genre): """ Returns the object referring to the genre and the list of games assigned to it Arguments: the_genre {GenreDB} -- The genre object to be searched Raises: TypeError -- If the argument is not a valid GenreDB object Returns: Dict -- The dictionary representing the genre and the games list """ if (not isinstance(the_genre, GenreDB)): raise TypeError( "Error: the argument provided is not a valid GenreDB object. Object provided: " + type(the_genre)) GameGenresORM = GamesGenresDB.objects.filter(genre=the_genre).first() # pylint: disable=no-member return GameGenresORM @staticmethod def s_append_game(the_genre, game): """ Appends a game to the games list of the genre. Only if not already there. Arguments: the_genre {GenreDB} -- The GenreDB object for the game to be appended to game {GameDB} -- The GameDB object to be appended Raises: TypeError -- GenreDB object is not valid TypeError -- GameDB object is not valid RuntimeError -- No data found for the genre! """ if (not isinstance(the_genre, GenreDB)): raise TypeError( "Error: the argument provided is not a valid GenreDB object. Object provided: " + type(the_genre)) if (not isinstance(game, GameDB)): raise TypeError( "Error: the argument provided is not a valid GameDB object. Object provided: " + type(game)) GameGenresORM = GamesGenresDB.objects.filter(genre=the_genre).first() # pylint: disable=no-member if (not GameGenresORM): raise RuntimeError( "Error: Data Element not found for the GenreDB: %s in GamesGenresDB collection.", the_genre.external_id) if (not (game in GameGenresORM.gamesList)): GameGenresORM.gamesList.append(game) GameGenresORM.save() @staticmethod def s_remove_game(the_genre, game): """ Removes a game from the games list of the genre. Only if there. Arguments: the_genre {GenreDB} -- The GenreDB object for the game to be appended to game {GameDB} -- The GameDB object to be appended Raises: TypeError -- GenreDB object is not valid TypeError -- GameDB object is not valid RuntimeError -- No data found for the genre! """ if (not isinstance(the_genre, GenreDB)): raise TypeError( "Error: the argument provided is not a valid GenreDB object. Object provided: " + type(the_genre)) if (not isinstance(game, GenreDB)): raise TypeError( "Error: the argument provided is not a valid GameDB object. Object provided: " + type(game)) GameGenresORM = GamesGenresDB.objects.filter(genre=the_genre).first() # pylint: disable=no-member if (not GameGenresORM): raise RuntimeError( "Error: Data Element not found for the GenreDB: %s in GamesGenresDB collection.", the_genre.external_id) if (game in GameGenresORM.gamesList): GameGenresORM.gamesList.remove(game) GameGenresORM.save()
class UserGameGenreDB(db.Document): """Collection to store how each user set the genre for each game. A game may be multi-genre. Attributes: user {UserDB} game {GameDB} genre {list} Methods: to_obj Action Methods: Class/Static Methods: """ external_id = db.StringField(db_field="external_id", required=True) # pylint: disable=no-member user = db.ReferenceField(UserDB, db_field="user", required=True) # pylint: disable=no-member game = db.ReferenceField(GameDB, db_field="game", required=True) # pylint: disable=no-member #unique guarantees the code to occurr only once. genre = db.ListField(db.ReferenceField(GenreDB), db_field="genre_list", required=True, unigue=True) # pylint: disable=no-member meta = {"indexes": [("external_id", "user", "game")]} def to_obj(self): retorno = { "user": self.user.to_obj(), "game": self.game.to_obj(), "genre": [genre.to_obj() for genre in self.genre] } return retorno def remove_genre(self, genre): """ Removes one genre from the list The proper genre object must be provided by the caller. Arguments: genre {GenreDB} -- The genre """ if (not isinstance(genre, GenreDB)): raise TypeError( "ERROR: Argument provided is not an object of the type GenreDB. Object provided: " + type(genre)) if (genre in self.genre): if (not hasattr(self, "del_genres")): self.del_genres = set() self.del_genres.add(genre) def add_genre(self, genre): """Adds one genre to the user list of genres for the game. Ex: Baldurs Gate is either an RPG and a (sort of) strategy game. if the Genre does not exists in the Genre list, it is added, else, it is referenced. The proper genre object must be provided by the caller. Arguments: genre {GenreDB} -- the genre name. """ if (not isinstance(genre, GenreDB)): raise TypeError( "ERROR: Argument provided is not an object of the type GenreDB. Object provided: " + type(genre)) #The method only works with a user and a game if (not self.user): raise RuntimeError("ERROR: Invalid Object! No User assigned") if (not self.game): raise RuntimeError("ERROR: Invalid Object! No Game assigned") if (not hasattr(self, 'new_genres')): self.new_genres = set() self.new_genres.add(genre) pass def add_genres(self, genreObjList): """ Adds to the game the list of genre objs Arguments: genreObjList {list} -- List containing the genre objects to be added """ for genre in genreObjList: #garantees that all objects are genre if (not isinstance(genre, GenreDB)): raise TypeError( "ERROR: Argument provided is not an object of the type GenreDB. Object provided: " + type(genre)) if (not self.user): raise RuntimeError("ERROR: Invalid Object! No User assigned") if (not self.game): raise RuntimeError("ERROR: Invalid Object! No Game assigned") if (not hasattr(self, 'new_genres')): self.new_genres = set() for gn in genreObjList: if not gn in self.genre: self.new_genres.add(gn) @staticmethod def get_valid_game(game_data): if (not isinstance(game_data, GameDB)): raise TypeError( "ERROR: Argument provided is not an object of the type GameDB. Object provided: " + type(game_data)) return UserGameGenreDB.objects.filter(game=game_data, user__live=True) # pylint: disable=no-member @classmethod def preSave(cls, sender, document, **kwargs): """ Prior to saving to the database, the collection is queried to retrieve the pre-data in order to perform the post-save maintenance In this case, the data to do maintenance is the genre counting in the game. Genres added will be added to the game Genres removed will be removed from the game Some maintenance: Check if there is already an entry with the User and game prior to saving... if there is, check if the current document has id if not, then must append if does then if the ids match do the maintenance (we are in the usual flow) if not o-oh! MERGE!!! In doubt... MERGE! Arguments: sender {UserGameGenreDB} -- The sender of the signal document {UserGameGenreDB} -- The instance to be saved """ if (document.external_id): # There is a document already folks!!! # Get the data... #no need, we already are doing it via new_genres if (hasattr(document, "new_genres")): for genre in document.new_genres: # If the genre are not already in the genre list, append if (genre not in document.genre): document.genre.append(genre) else: # game already has it. Need to remove due to post save document.new_genres.remove(genre) if (hasattr(document, "del_genres")): for genre in document.del_genres: if (genre in document.genre): document.genre.remove(genre) else: #game does not have it! Need to remove due to post save document.del_genres.remove(genre) else: # It is (supposedly) a new document... let's check? doWeHave = cls.objects.filter(user=document.user, game=document.game) # pylint: disable=no-member if (doWeHave): raise RuntimeError( "ERROR: Invalid Object! Trying to create a new UserGameGenresDB data when one already exists. User=%s, Game=%s" ) # Check if game and user are assigned if (not document.user): raise RuntimeError("ERROR: Invalid Object! No User assigned") if (not document.game): raise RuntimeError("ERROR: Invalid Object! No Game assigned") #new document... Groovy document.external_id = str(uuid4()) if (hasattr(document, "new_genres")): for genre in document.new_genres: if (genre not in document.genre): document.genre.append(genre) #new document, nothing to remove! @classmethod def postSave(cls, sender, document, **kwargs): """ After saving the genre list the user set for the game, the data is compared to the previous genre list the user had The differences will be added/subtracted to the game genreCount Arguments: sender {UserGameGenreDB} -- The sender of the signal document {UserGameGenreDB} -- The instance of the document """ if (hasattr(document, "new_genres")): GameGenreQuantificationDB.s_add_genres(document.game, document.new_genres) """ --- PREVIOUS CODE --- while(len(document.new_genres)>0): the_genre=document.new_genres.pop() document.game.increase_genre(the_genre) """ if (hasattr(document, "del_genres")): GameGenreQuantificationDB.s_remove_genres(document.game, document.del_genres) """ --- PREVIOUS CODE --- while(len(document.del_genres)>0): the_genre=document.del_genres.pop() res=document.game.decrease_genre(the_genre) if(res==0): GamesGenresDB.s_remove_game(the_genre,document.game) """ document.game.save()
class GenreDB(db.Document): """ Genre will store the genres to be assigned to games. Represents the Genre object to be mapped to the database Attributes: external_id - unique representation data to send to clients genre - Attributes: external_id {String} -- to pass to the client (string) genre {dict} -- a key-value data set indicating the idiom and the value representing the genre in the idiom. Example: {'en':'adventure'} active {boolean} -- informs if the genre is active (valid) assigned_to {GenreDB} -- when reassigned, the current genre is no longer valid, this value is the one to be used assigned_from {list of GenreDB} -- One genre may be assigned from some others. Having this data does not validate the genre as active. It is possible to reassign it to other genre. Methods: to_obj: Returns a python dict representation of the data Action Methods: increase_genre: Increases a genre count (or initializes one with 1) in the game representation decrease_genre: Decreases a genre count (maintaining the lower limit as 0) in the game representation get_genres: Returns a list of the ORM objects of all the genres in game whose count>0 update_data: Disregards thecurrent genreCount and generates another one from the UserGameGenre collection Class/Static Methods: map_genre get_all_genres get_genres (in language) get_genre_obj get_or_create_genre """ external_id = db.StringField(db_field="external_id", unique=True) # pylint: disable=no-member genre = db.DictField(db_field = "genre") # pylint: disable=no-member reassigned_to=db.ReferenceField("self",db_field='reassiged_to') # pylint: disable=no-member reassigned_from=db.ListField(db.ReferenceField('self'),db_field='reassiged_from') # pylint: disable=no-member created = db.DateTimeField(db_field="created", default = datetime.utcnow) # pylint: disable=no-member updated = db.DateTimeField(db_field="updated", default = datetime.utcnow) # pylint: disable=no-member active = db.BooleanField(db_field="active", required=True, default=True) # pylint: disable=no-member meta = { "indexes": [("external_id", "genre", "active")] } def to_obj(self): return GenreAO.from_db(self) def get_reassigned_to_obj(self): retorno=None if(self.reassigned_to): retorno=self.reassigned_to.to_obj() return retorno @staticmethod def get_genre(eid): if not isinstance(eid,str): raise TypeError("ERROR: Invalid type for the identification data.") dbdata = GenreDB.objects.filter(external_id=eid).first() # pylint: disable=no-member if (not dbdata) or (not dbdata.external_id==eid): raise RuntimeError("ERROR: Persistent Data not Found or Mismatched.") return dbdata @staticmethod #TODO: def reassign(old,new): """ Maps the old genre, making it inactive to the new genre, calling the update in the games that were classified with both via UserGameGenre. The process is done via UserGameGenre due to the possibility of some users to have assigned both genres to a game. This invalidates one of the genres and maintains the sanity of the statistical data within the game. This reassignment has 2 purposes: 1 - replace one genre for the other or 2 - merge 2 genres representing the same, but with different languages. For the 1st, imagine someone set "graphic adventure" for a genre and other set just "adventure". Both represents the adventure genre, but one specifically states it has graphics It is of no concern of ours if the game has graphics or not, only the genre, so, the 1st genre will be disregarded. For the 2nd, imagine one started a genre for 'pt' saying: "aventura", and other set a genre for 'en' saying: "adventure". Both represent the same genre, but in different language This form, the assignment is a merge, producing 1 genre with the 2 idioms in the list. Arguments: old {GenreDB} -- The genre to become inactive new {GenreDB} -- The genre to become active TODO: This is a purely administrative task. The genres will be requested to be add by the users, the administrators will attend. So, if no user will tamper with this data, it can be coded later. """ #retrieve all users who assigned only the old genre to the game # onlyOld=UserGameGenre.objects(__raw__={"$and":{"$not":{"$in":new},"$in":old}}) # for ugg in onlyOld: # ugg.addGenre(new) # ugg.removeGenre(old) # ugg.save() ### remove the old genre, add the new #retrieve all users who assigned both genres to the game # both=UserGameGenre.objects(__raw__={"$and":{$in":new,"$in":old}) # for ugg in both: # ugg.remove(old) # ugg.save() ### remove just the old genre #assign the references # old.reassigned_to=new # old.active=false # if not new.reassigned_from: # new.reassigned_from=[] # new.reassigned_from.append(old) # old.save() # new.save() pass @classmethod def pre_save(cls, sender, document, **kwargs): """ prior to saving the genre set the external_id Arguments: sender {GenreDB} -- The sender of the signal document {GenreDB} -- The instance of the document """ if(not document.external_id): document.external_id=str(uuid4()) @classmethod def post_save(cls, sender, document, **kwargs): """ After saving the genre check if the GamesGenresDB data was created Arguments: sender {GenreDB} -- The sender of the signal document {GenreDB} -- The instance of the document """ from game.models.user_game_genre import GamesGenresDB genreGameList=GamesGenresDB.objects.filter(genre=document).first() # pylint: disable=no-member if(not genreGameList): #there is no genre for the games to be assigned to... create one genreGameList=GamesGenresDB() genreGameList.genre=document genreGameList.gamesList=[] genreGameList.save()
class Customer(db.Document): customer_id = db.StringField(db_field="customer_id", primary_key=True) password_hash = db.StringField() store_id = db.ReferenceField(Store, db_field="store_id") currency = db.StringField(db_field="currency") email = db.StringField(db_field="email") first_name = db.StringField(db_field="first_name") last_name = db.StringField(db_field="last_name") total_spent = db.DecimalField(db_field="total_spent", default=0) last_order_date = db.DateTimeField(db_field="last_order_date") last_cart_activity_at = db.DateTimeField(db_field="last_cart_activity_at") last_cart_created_at = db.DateTimeField(db_field="last_cart_created_at") log_out_expires_at = db.DateTimeField(default=datetime.now()) emails = db.ListField(db.EmbeddedDocumentField(Email)) confirmed_on = db.DateTimeField() confirmation_token = db.StringField() confirmation_token_expires_at = db.DateTimeField() last_seen_date = db.DateTimeField(default=datetime.now()) created_at = db.DateTimeField(default=datetime.now()) updated_at = db.DateTimeField(default=datetime.now()) deleted_at = db.DateTimeField() meta = {'indexes': [('customer_id', ), ('email', )]} @classmethod def get_customer(cls, customer_id, request): store = Store.objects.filter(app_id=request.headers.get('APP-ID'), deleted_at=None).first() return Customer.objects.filter(customer_id=customer_id, store_id=store, deleted_at=None).first() @classmethod def get_customer_by_email(cls, email, request): store = Store.objects.filter(app_id=request.headers.get('APP-ID'), deleted_at=None).first() return Customer.objects.filter(email=email, store_id=store, deleted_at=None).first() @classmethod def get_customer_by_token(cls, token): return Customer.objects.filter(confirmation_token=token, deleted_at=None).first() def add_address(self, request, is_primary=False): """ adds a new address based on request :param request: will pull data from flask request object :param is_primary: set new address to primary if true :return: address object """ new_address = Address(address_id=str(uuid.uuid4().int), customer_id=self, street=request.json.get("street"), city=request.json.get("city"), zip=request.json.get("zip"), state=request.json.get("state"), country=request.json.get("country")).save() if is_primary: new_address.make_primary() return new_address def get_primary_address(self): """ :return: current primary address if exists """ return Address.objects.filter(customer_id=self.customer_id, deleted_at=None, is_primary=True).first() def get_addresses(self): """ :return: all not deleted customer addresses """ return Address.objects.filter(customer_id=self.customer_id, deleted_at=None) def set_password(self, password): """ creates password for user :param password: new password :return: null """ self.password_hash = generate_password_hash(password) self.save() def check_password(self, password): """ checks if customer password is correct :param password: password to check :return: boolean """ return check_password_hash(self.password_hash, password) def login(self): """ logs customer in :return: null """ self.log_out_expires_at = datetime.now() + timedelta(hours=24) self.last_seen_date = datetime.now() self.save() def logout(self): """ logs customer out :return: null """ self.log_out_expires_at = datetime.now() self.save() def add_email(self, new_email, is_primary=False): """ adds a new email :param new_email: new email address :param is_primary: true if new email address should :return: null """ for email in self.emails: if is_primary: email.is_primary = False if email.email == new_email and email.deleted_at is None: raise DuplicateDataError new_email_document = Email(email_id=str(uuid.uuid4().int), email=new_email, is_primary=is_primary) if is_primary: self.email = new_email self.updated_at = datetime.now() self.emails.append(new_email_document) self.save() def get_emails(self): """ return list of active emails :return: list of email objects """ active_emails = [] for email in self.emails: if email.deleted_at is None: active_emails.append(email) return active_emails def delete_email(self, email_to_delete): """ deletes a customer email :param email_to_delete: email to be deleted :return: email object """ for email in self.emails: if email.email == email_to_delete and email.deleted_at is None: email.deleted_at = datetime.now() email.updated_at = datetime.now() self.updated_at = datetime.now() self.save() return email return None def make_email_primary(self, new_primay_email): if new_primay_email not in [email.email for email in self.emails]: return None new_primay_email_object = None for email in self.emails: if email.email == new_primay_email: email.is_primary = True new_primay_email_object = email else: email.is_primary = False self.save() return new_primay_email_object def send_email(self, subject, body): """ sends an email to the customers primary email :return: none """ msg = Message(subject, sender="*****@*****.**", recipients=[self.email]) msg.html = body mail.send(msg) def send_confirmation(self): """ sends confirmation email :return: none """ self.confirmation_token = str(uuid.uuid4().int) self.confirmation_token_expires_at = datetime.now() + timedelta( hours=24) self.save() subject = "Store Confirmation" link = "localhost/customer/confirm/" + self.confirmation_token html = "<html>Please click the link to confirm your registration: <a href={}>link</a></html>".format( link) self.send_email(subject=subject, body=html)
class Professorslot(db.Document): block_id = db.IntField( unique=True) prof_id = db.IntField( max_length=50 ) date = db.DateField(unique=True) slots = db.ListField()
class RecommendTable(db.DynamicDocument): meta = {'collection': 'recommendation_table', 'indexes': ['t']} userIntId = db.IntField(db_field="rI") recommendList = db.ListField(db_field="recommendations", required=True) created = db.IntField(db_field="dc", default=now())
class Product(db.Document, SearchableMixin): __searchable__ = ['description', 'product_type', 'title', 'vendor', 'tags'] __searchable_documents__ = ['tags'] product_id = db.StringField(db_field="id", primary_key=True) title = db.StringField(db_field="title") product_type = db.StringField(db_field="product_type") description = db.StringField() vendor = db.StringField(db_field="vendor") store = db.ReferenceField(Store, db_field="store_id") inventory = db.IntField(db_field="inventory", default=0) sale_price_in_cents = db.IntField() tags = db.ListField(db.EmbeddedDocumentField(ProductTag)) created_at = db.DateTimeField(default=datetime.now()) updated_at = db.DateTimeField(default=datetime.now()) deleted_at = db.DateTimeField() meta = { 'indexes': [('id', 'store', 'deleted_at'), ('vendor', 'product_type', 'store', 'deleted_at'), ('product_type', 'store', 'deleted_at'), ('vendor', 'store', 'deleted_at')] } def adjust_inventory(self, amount): new_amount = amount + self.inventory if new_amount < 0: raise ProductInventoryLessThanZeroException self.inventory = new_amount self.save() def set_inventory(self, amount): if amount < 0: raise ProductInventoryLessThanZeroException self.inventory = amount self.save() def add_tag(self, new_tag): """ adds a new tag to product :param new_tag: new tag :return: null """ if new_tag in [tag.tag for tag in self.tags]: raise DuplicateDataError new_tag_object = ProductTag(product_tag_id=str(uuid.uuid4().int), tag=new_tag) self.tags.append(new_tag_object) self.updated_at = datetime.now() self.save() def get_tags(self): """ return list of active tags :return: list of tag objects """ active_tags = [] for tag in self.tags: if tag.deleted_at is None: active_tags.append(tag) return active_tags def delete_tags(self, tag_to_delete): """ deletes one or all tags :param tag_to_delete: tag to be deleted :return: list of tag objects """ deleted_tags = [] for tag in self.tags: if tag.deleted_at is None and (tag.tag == tag_to_delete or tag_to_delete is None): tag.deleted_at = datetime.now() deleted_tags.append(tag) self.save() return deleted_tags def to_search_format(self, field_name): if field_name == 'tags': return " ".join([tag.tag for tag in self.tags])
class Project(db.Document): """A course's Project.""" LANGUAGES = [('J', 'Java Project')] created_at = db.DateTimeField( default=datetime.datetime.utcnow, required=True) due_date = db.DateTimeField(required=True) name = db.StringField(max_length=256, min_length=5, required=True) tests = db.ListField(db.FileField()) published = db.BooleanField(default=True, required=True) language = db.StringField( max_length=3, min_length=1, choices=LANGUAGES, required=True) test_timeout_seconds = db.LongField( default=600, max_value=1800, required=True) submissions = db.ListField( db.ReferenceField('Submission', reverse_delete_rule=db.PULL)) course = db.ReferenceField('Course') is_quiz = db.BooleanField(required=True) meta = { "indexes": [ { "fields": ['name'] }, { "fields": ['course'] } ] } @property def has_tests(self): return len(self.tests) >= 1 @property def has_class_files(self): return any([t.filename.endswith('.class') for t in self.tests]) @property def can_submit(self): return self.due_date >= datetime.datetime.utcnow() def student_results_for_csv(self): grades = TeamProjectGrade.objects(project=self) results = [] for grade in grades: for student in grade.get_students(): results.append({ "team_id": student.team_id, "guc_id": student.guc_id, "name": student.name, "email": student.email, "project": self.name, "passed cases": grade.best_submission.passed_cases_count, "total cases": grade.best_submission.cases_count, "grade in percentage": grade.grade, "submitter": grade.best_submission.submitter.name }) return results def get_teams_canadite_submissions(self): """ Gets teams candidate submissions for grading. Gets latest submission of each member of a team. returns a list of (team_id, submissions) """ from itertools import groupby from operator import attrgetter key_func = attrgetter('team_id') submitters = sorted([subm.submitter for subm in Submission.objects(project=self, submitter__exists=True)], key=key_func) submissions = [] for _, team in groupby(submitters, key_func): if _ is None: continue team = list(set(list(team))) canadite_submissions = [] for student in team: subms = (Submission.objects( submitter=student, project=self) .order_by('-created_at').limit(1)) if len(subms) > 0: canadite_submissions.append(subms[0]) submissions.append((_, canadite_submissions)) return submissions def get_team_best_submissions( self, rerurn_submissions=False, only_rerun_compile_error=False, get_latest=True): """ Cget team best submissions for grades, optionally reruns submissions. Please note that this function will block to submissions. returns a list of (team_id, submission) """ from application.tasks import junit_actual canadite_submissions = self.get_teams_canadite_submissions() best_team_submissions = [] if get_latest: for _, submissions in canadite_submissions: submissions = sorted(submissions, key=lambda subm: subm.created_at, reverse=True) submission = submissions[0] if rerurn_submissions: if only_rerun_compile_error and submission.compile_status: pass else: submission.reset() junit_actual(submission.id) best_team_submissions.append((_, submission)) else: for _, submissions in canadite_submissions: if rerurn_submissions: for submission in submissions: if only_rerun_compile_error\ and submission.compile_status: continue else: submission.reset() junit_actual(submission.id) passed_submissions = [s for s in canadite_submissions if s.compile_status] best_submissions = sorted(passed_submissions, key=lambda subm: len( subm.test_results)) best_team_submissions.append((_, best_submissions[0])) return best_team_submissions def grade_teams( self, rerurn_submissions=False, only_rerun_compile_error=False, get_latest=True): """ Computes team grades, optionally reruns submissions. Please note that this function will block to submissions. will attempt to find TeamGrade and update it if it already exists """ best_team_submissions = self.get_team_best_submissions( rerurn_submissions, only_rerun_compile_error, get_latest) for team_id, best_submission in best_team_submissions: try: grade = TeamProjectGrade.objects.get( team_id=team_id, project=self) if not rerurn_submissions: app.logger.info("found grade nothing to change") continue else: app.logger.info("found grade updateing submission") grade.best_submission = best_submission except TeamProjectGrade.DoesNotExist: grade = TeamProjectGrade( team_id=team_id, best_submission=best_submission, project=self) grade.save() app.logger.info("graded team {0} in project {1}" .format(team_id, self.name)) def get_student_submissions( self, rerurn_submissions=False, only_rerun_compile_error=False, only_rerun_test_cases_zero=False, get_latest=True): """ Computes latest grade for each student who submitted in this project, optionally reruns submissions. Please note that this function will block to submissions. will attempt to find TeamGrade and update it if it already exists """ from application.tasks import junit_actual students = self.course.students submissions = [] for student in students: subms = (Submission.objects( submitter=student, project=self) .order_by('-created_at').limit(1)) if len(subms) > 0: submissions.append(subms[0]) for submission in submissions: if rerurn_submissions: if only_rerun_compile_error and submission.compile_status: pass elif only_rerun_test_cases_zero and submission.cases_count > 0: pass else: submission.reset() junit_actual(submission.id) return submissions def student_submissions_for_csv(self): results = [] for submission in self.get_student_submissions(): student = submission.submitter results.append({ "guc_id": student.guc_id, "name": student.name, "email": student.email, "project": self.name, "passed cases": submission.passed_cases_count, "total cases": submission.cases_count, "grade in percentage": submission.passed_percentage, }) return results def to_dict(self, **kwargs): dic = { "id": self.id, "name": self.name, "language": self.language, "created_at": self.created_at, "course": self.course.to_dict(), "can_submit": self.can_submit, "due_date": self.due_date, 'published': self.published, "is_quiz": self.is_quiz, "rerurn_submissions": "no", 'page': 1 } dic['course_name'] = dic['course']['name'] def file_to_dic(project_id, file): dic = { "name": file.filename, "mimetype": file.content_type, "project_id": project_id } return dic dic['tests'] = [file_to_dic(self.id, f) for f in self.tests] dic['has_class_files'] = self.has_class_files return dic