class Save_valuation(db.Document): stock_id = db.StringField(max_length=10, required=True) form_data = db.DictField() from_user = db.ReferenceField(User, reverse_delete_rule=CASCADE) created = db.IntField(default=now()) meta = {'indexes': ['stock_id', ('stock_id', 'from_user')]}
class Product(db.DynamicDocument): meta = { 'collection': 'products', 'shard_key': 'asin', 'indexes': [ 'title', "asin", "pI", '-created', { "fields": ['$title', '$description'], "default_language": 'english', 'weights': { 'title': 7, 'description': 3 } } ] } asin = db.StringField(db_field="asin", required=True, unique=True) productIntId = db.IntField(db_field="pI") title = db.StringField(db_field="title", required=True) description = db.StringField(db_field="description", required=True) imageUrl = db.StringField(db_field="imUrl") created = db.IntField(db_field="c", default=now()) related = db.DictField(db_field="related") price = db.FloatField(db_field="price")
class User(db.Document): username = db.StringField(db_field="u", required=True, unique=True) password = db.StringField(db_field="p", required=True) email = db.EmailField(db_field="e", required=True, unique=True) first_name = db.StringField(db_field="fn", max_length=50) last_name = db.StringField(db_field="ln", max_length=50) created = db.IntField(db_field="c", default=now()) bio = db.StringField(db_field="b", max_length=160) email_confirmed = db.BooleanField(db_field="ecf", default=False) change_configuration = db.DictField(db_field="cc") profile_image = db.StringField(db_field="i", default=None) @classmethod def pre_save(cls, sender, document, **kwargs): document.username = document.username.lower() document.email = document.email.lower() def profile_imgsrc(self, size): if self.profile_image: if AWS_BUCKET: return os.path.join(AWS_CONTENT_URL, AWS_BUCKET, 'user', '%s.%s.%s.png' % (self.id, self.profile_image, size)) else: return url_for('static', filename=os.path.join(STATIC_IMAGE_URL, 'user', '%s.%s.%s.png' % (self.id, self.profile_image, size))) else: return url_for('static', filename=os.path.join(STATIC_IMAGE_URL, 'user', 'no-profile.%s.png' % (size))) meta = { 'indexes': ['username', 'email', '-created'] }
class User(db.Document): username = db.StringField(db_field="u", required=True, unique=True) password = db.StringField(db_field="p", required=True) email = db.EmailField(db_field="e", required=True, unique=True) first_name = db.StringField(db_field="fn", max_length=50) last_name = db.StringField(db_field="ln", max_length=50) created = db.IntField(db_field="c", default=now()) bio = db.StringField(db_field="b", max_length=160) email_confirmed = db.BooleanField(db_field="ecf", default=False) change_configuration = db.DictField(db_field="cc") profile_image = db.StringField(db_field="i", default=None) # Make username and email all lowercase # This method is called before object is written to the database @classmethod # Do any manipulations you need to do within pre_save def pre_save(cls, sender, document, **kwargs): document.username = document.username.lower() document.email = document.email.lower() def profile_imgsrc(self, size): # return os.path.join(IMAGE_URL, "user", "%s.%s.%s.png" % (self.id, # self.profile_image, size)) return os.path.join( IMAGE_URL, "user", "{0}.{1}.{2}.png".format(self.id, self.profile_image, size)) # Add indexes meta = { "indexes": ["username", "email", "-created"] # -created means sort order reversed to get most recent members }
class User(db.Document): # db_field='u' the first character of the field name => saves space in large # databases username = db.StringField(db_field='u', required=True, unique=True) password = db.StringField(db_field='p', required=True) email = db.StringField(db_field='e', required=True, unique=True) first_name = db.StringField(db_field='fn', max_length=50) last_name = db.StringField(db_field='ln', max_length=50) # create a time stamp(NB NOT a date because a time stampe cn give more # information). Use a helper function created = db.IntField(db_field='c', default=now()) bio = db.StringField(db_field='b', max_length=160) # Confirm email. Usually after registration the email of the account is verified email_confirmed = db.BooleanField(db_field='ecf', default=False) # A dictionary object in json format that will store the old and new email # when the email is changing. In a transition phase change_configuration = db.DictField(db_field='cc') # Add the indexes by using the meta properties of the class. Give a string # of the indexes. The minus created means that the sort order is reversed meta = { 'indexes':['username', 'email', '-created'] } # The @classmethod will be called prior to the save to the database # so can make any adjustments here ie change fields to lower case # pre_save is a mongo method @classmethod def pre_save(cls, sender, document, **kwargs): document.username = document.username.lower() document.email = document.email.lower()
class User(db.Document): #create object for Mongo username=db.StringField(db_field="u", required = True, unique = True) #dbfield name in Mongo: single letter to save space password=db.StringField(db_field="p", required = True) email=db.EmailField(db_field="e", required = True, unique = True) first_name=db.StringField(db_field="fn", max_length=50) last_name=db.StringField(db_field="ln", max_length=50) created=db.IntField(db_field="c", default=now()) bio=db.StringField(db_field="b", max_length=200) email_confirmed=db.BooleanField(db_field="ec", default=False) change_configuration=db.DictField(db_field="cc") profile_image = db.StringField(db_field="i", default=None) @classmethod #for pre_save def pre_save(cls, sender, document, **kwargs): #always called before database save document.username = document.username.lower() document.email = document.email.lower() def profile_imgsrc(self, size): if self.profile_image: if AWS_BUCKET: return os.path.join(AWS_CONTENT_URL, AWS_BUCKET, 'user', '%s.%s.%s.png' % (self.id, self.profile_image, size)) else: return url_for('static', filename=os.path.join(STATIC_IMAGE_URL, 'user', '%s.%s.%s.png' % (self.id, self.profile_image, size))) else: return url_for('static', filename=os.path.join(STATIC_IMAGE_URL, 'user', 'no-profile.%s.png' % (size))) meta = { 'indexes': ['username', 'email', '-created'] #create indices to sort the data }
class DeletedCalc(db.Document): _id = db.ObjectIdField() calc_name = db.StringField( max_length=100 ) description = db.StringField( max_length=250 ) calc_type_id = db.ObjectIdField() project_id = db.ObjectIdField( ) calc_input_dict = db.DictField() meta = {'db_alias': 'default'}
class CalcInput(db.Document): _id = db.ObjectIdField() calc_name = db.StringField( max_length=100 ) description = db.StringField( max_length=250 ) calc_type_id = db.ObjectIdField() project_id = db.ObjectIdField( ) calc_input_dict = db.DictField() left_header = db.StringField( max_length=250 ) center_header = db.StringField( max_length=250 ) right_header = db.StringField( max_length=250 ) meta = {'db_alias': 'default'}
class User(db.Document): username = db.StringField(db_field='u', unique=True) password = db.StringField(db_field='pwd') email = db.EmailField(db_field='em', required=True, unique=True) first_name = db.StringField(db_field="fn", max_length=50, default=None) last_name = db.StringField(db_field="ln", max_length=50, default=None) created = db.IntField(db_field='c', default=now()) email_confirmed = db.BooleanField(db_field="ecf", default=False) change_configuration = db.DictField(db_field="cc") profile_image = db.StringField(db_field="i", default=None) facebook_link = db.StringField(db_field="fb") tel = db.StringField(db_field="tl") provider = db.StringField(db_field="pv", default='local') @classmethod def pre_save(cls, sender, document, **kwargs): #don't understand if document.username: document.username = document.username.lower() document.email = document.email.lower() def user_imgsrc(self, size): if self.profile_image: if AWS_BUCKET: return os.path.join( AWS_CONTENT_URL, AWS_BUCKET, 'user', '%s.%s.%s.png' % (self.id, self.profile_image, size)) else: return url_for( 'static', filename=os.path.join( STATIC_IMAGE_URL, 'user', '%s.%s.%s.jpg' % (self.id, self.profile_image, size))).replace( "%5C", "/") else: return url_for('static', filename=os.path.join( 'assets', 'default_image', 'default-profile.png')).replace('%5C', '/') #Class method to add Notification delete old one def add_notification(self, name, data): Notification.objects.filter(name=name, user_id=self.id).delete() n = Notification(name=name, payload_json=json.dumps(data), user_id=self.id) n.save() return n meta = {'indexes': ['username', 'email', '-created']}
class AdminGroupDB(db.Document): """ ORM to reference the groups to be assigned to the admins. In system start there are only two basic groups: - GOD: Can do whatever he wants - common: basically can only list who are users and check scsr freely. Future possible groups: - gamemanagers: Can approve suggested games - genremaintainers: Maps or merges genres - systemadmins: Maintains the transactions - usersmanagers: Guarantees the sanity of the (social) system by verifying and managing user activities - This level allows the manager to invalidate the user classifications. - scsrpolice: Guarantees the sanity of the SCSR Methods: to_obj: Return a dict object representing the class Action Methods: pre_save: Assigns an external_id if one is missing """ external_id=db.StringField(db_field="external_id", required=True) group=db.DictField(db_field="group", required=True) def to_obj(self): """Returns the Object as a Python Dict object Returns: dict -- the instantiated object """ jsonStr=self.to_json() retorno=json.loads(jsonStr) retorno.pop("_id","") return retorno @classmethod def preSave(cls, sender, document, **kwargs): """ After saving the genre set the external_id Arguments: sender {UserGameGenre} -- The sender of the signal document {UserGameGenre} -- The instance of the document """ if(not document.external_id): document.external_id=str(uuid4()) pass
class report_yearly(db.Document): stock_id = db.StringField(db_field="sid", max_length=10, required=True) data = db.DictField() report_name = db.StringField(db_field="rn", max_length=4, required=True) companyName = db.StringField(db_field="cn", max_length=160, required=True) companyNameEng = db.StringField(db_field="cne", max_length=160, required=True) industryName = db.StringField(db_field="indn", max_length=100, required=True) floor = db.StringField(db_field="floor", max_length=5, required=True) shares = db.LongField(db_field="share", max_value=10000000000, required=True) meta = {'indexes': ['stock_id', ('stock_id', 'report_name')]}
class country_codeDB(db.Document): """ Represents the language codes and names to be used in the system. - The code is the ISO 3166-2 code - The name is a dictfield in the form: {lang_code: ['country_name_in_lang']} Ex: {'pt':["Português"], 'en':["Portuguese"]} """ code = db.StringField(db_field="db_country_code", required=True, primary_key=True) country = db.DictField(db_field="db_country_name", required=True) def to_obj(self): retorno={ 'code': self.code, 'country':self.country } return retorno
class User(db.Document): username = db.StringField(db_field="u", required=True, unique=True) password = db.StringField(db_field="p", required=True) email = db.EmailField(db_field="e", required=True, unique=True) first_name = db.StringField(db_field="fn", max_length=50) last_name = db.StringField(db_field="ln", max_length=50) created = db.IntField(db_field="c", default=now()) bio = db.StringField(db_field="b", max_length=160) email_confirmed = db.BooleanField(db_field="ecf", default=False) change_configuration = db.DictField(db_field="cc") @classmethod def pre_save(cls, sender, document, **kwargs): document.username = document.username.lower() document.email = document.email.lower() meta = {'indexes': ['username', 'email', '-created']}
class ElementReferenceDB(db.Document): """ Class to perform ORM of the reference related to the element Attributes: element {ElementDB} -- The element the reference is related ref {Dict} -- The reference data. This is a dict provided with the following structure: {"type":[TYPE], "source":[SOURCE], "ref":[REFERENCE] (,"ambiguity":[BOOLEAN])} Where: TYPE assumes the values: 'single': for a single source, or 'multi': for multiple sources SOURCE refers to what is contained in the ref field and assumes the values: 'text': for a single text in the reference field 'link': for links to webpages 'paper': for academic reference 'book': for literary reference or 'multi': for multiple types of references (only available if TYPE is multi) REFERENCE is the reference data and it is dependant on the SOURCE in the following form: if the SOURCE is 'text': The Reference is a string 'link': The Reference is a string beginning with http:// (refers to a website) 'paper': The reference is a dict with the PAPER structure 'book': The reference is a dict with the BOOK structure 'multi': Each reference is a list with the reference structure ambiguity is a field that can occurs in type multi. The references may provide ambiguous meaning The structures: PAPER: {"author":[AUTHOR],"title":[TITLE],"published":[YEAR],"source":[EVENT/JOURNAL] (,"doi":[DOI], "coauthors":[[AUTHORS]])} Excluding YEAR that must be a valid int, all other fields are strings and coauthors, a list of string BOOK: {"author":[AUTHOR],"title":[TITLE],"published":[YEAR],"publisher":[PUBLISHER], "isbn":[ISBN] (,"coauthors":[[AUTHORS]], "page":[PAGE])} Excluding YEAR and PAGE that must be a valid int, all other fields are strings and coauthors, a list of string REF: {"type":[TYPE], "ref":[REFERENCE]} The REF type is a subset of REFERENCE type that excludes the multi type. Methods: to_obj {ElementReferenceAO} -- """ element = db.ReferenceField(ElementDB, db_field="element", primary_key=True, required=True) # pylint: disable=no-member reference = db.DictField(db_field="reference", required=True) # pylint: disable=no-member def to_obj(self): return ElementReferenceAO.from_db(self)
class TextsDB(db.Document): """Just to store in the DB the localization data. Attributes: external_id {String} -- [string-code to retrieve the text] site_text {Dict field} -- [Dictionary containing {text_identificator :{language:text}}] Ex: external_id = 'title' text= { 'pt':'Representação Estrutural Contextual Estatística em Jogos', 'en':'Statistical Contextual Structural Representation in Games' } """ external_id=db.StringField(db_field="external_id", required=True, primary_key=True) # pylint: disable=no-member text=db.DictField(db_field="site_text", required=True) # pylint: disable=no-member
class ElementGameMappingDB(db.Document): """ Class to map the games that were assigned to the elements. Data in this collection are just provided when SCSR is saved. If SCSR is modified and the element removed, this association maintains. This association means that there are (or were) interpretation that the element was associated with the game. This collection helps to get the game and assess how it was interpreted. """ element = db.ReferenceField(ElementDB, db_field="element", required=True, primary_key=True) # pylint: disable=no-member #After the system starts, each new element added will have a game associated. Only prior there will be the pre-recorded elements. games = db.DictField(db_field="games") # pylint: disable=no-member @staticmethod def get_games(element): """ get the games associated with the provided element Arguments: element {ElementAO} -- The Application Object representing the element. Raises: TypeError -- If the argument is not a valid ApplicationObject RuntimeError -- If the argument is valid, but represents no valid data in the collection Returns: List -- List of GameAO objects associated with this element. """ if not isinstance(element, ElementAO): raise TypeError("ERROR: Argument is not a valid ElementAO object.") elementdb = ElementDB.objects.filter( external_id=element.external_id).first() # pylint: disable=no-member if not elementdb: raise RuntimeError( "ERROR: Could not retrieve data for the element: " + element.external_id) return [game.to_obj() for game in elementdb.games]
class ScsrDiffDB(db.Document): """ The scsr mods class represents a modification made to a scsr. The dictionary referencing the element contains the functions and behaviors as the normal SCSR, but with the added and removed list of elements. This provides a method to track the scsr evolution within time. The coded_scsr is a dict representing the difference The external_id in the return refers to the diff external id. The coded scsr is of the form: { persuasive: persuasive_diff aesthetic: aesthetic_diff orchestration: orchestration_diff reification: reification_diff } With each diff representing a persisted object of the respective function. """ external_id = db.StringField(db_field="external_id", required=True) # pylint: disable=no-member date_modified = db.DateTimeField(db_field="date_modified", required=True, default=datetime.utcnow) # pylint: disable=no-member coded_scsr = db.DictField(db_field="coded_scsr", required=True, default={}) # pylint: disable=no-member def to_obj(self): return ScsrDiffAO.from_db(self) def to_json(self): return ScsrDiffAO.from_db(self).to_json() @classmethod def pre_save(cls, sender, document, **kwargs): """ Prior to saving the scsrdiff, guarantees its consistencies and check the external_id Arguments: sender {scsrDiffDB} -- The sender of the signal document {scsrDiffDB} -- The instance of the document """ if (not document.external_id): document.external_id = str(uuid4())
class lang_codeDB(db.Document): """ Represents the language codes and names to be used in the system. - The code is the ISO 639-1 code - The name is a dictfield in the form: {code: ['lang_name_in_code']} Ex: {'pt':["Português"], 'en':["Portuguese"]} """ code = db.StringField(db_field="db_lang_code", required=True, primary_key=True) # pylint: disable=no-member lang = db.DictField(db_field="db_lang_name", required=True) # pylint: disable=no-member in_system = db.BooleanField(db_field="in_system", required=True, default=False) # pylint: disable=no-member def to_obj(self): retorno = {'code': self.code, 'lang': self.lang} return retorno def set_system(self): self.in_system = True self.save()
class stock_price(db.Document): stock_id = db.StringField(max_length=20, required=True, unique=True) data = db.DictField() meta = {'indexes': ['stock_id']}
class report_quaterly(db.Document): stock_id = db.StringField(max_length=10, required=True) data = db.DictField() report_name = db.StringField(max_length=4, required=True) meta = {'indexes': ['stock_id', ('stock_id', 'report_name')]}
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 GameDB(db.Document): """Game Class represents the basic object analyzed. Each scsr must relate to a game object. Attributes: external_id {String} -- to pass to the client (string) year {datetime} -- the year the game was released (datetime component) name {String} -- the name of the game (a dictionary element of type lang: name) This data is a dictField containing in the key the idiom code and in the data the name of the element in the specified idiom Used for Localization studio {String} -- The studio name that created the game (string) publisher {String} -- The company that published the game (string) ##### REMOVED - DECOUPLED TO ITS OWN CLASS # genreCount {DictField} -- the statistical user attributed genre for the game. # This is a dictionary of the form {'genreId':count} ##### 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: seek_exact_name seek_partial_name seek_studio """ external_id = db.StringField(db_field="external_id") # pylint: disable=no-member year = db.DateTimeField(db_field="year") # pylint: disable=no-member # {'lang':'name_in_lang'} name = db.DictField(db_field="name", required=True) # pylint: disable=no-member studio = db.StringField(db_field="studio") # pylint: disable=no-member publisher = db.StringField(db_field="publisher") # pylint: disable=no-member date_proposed = db.DateTimeField(db_field="proposed", required=True, default=datetime.utcnow) # pylint: disable=no-member date_accepted = db.DateTimeField(db_field="accepted", required=True, default=datetime.utcnow) # pylint: disable=no-member active = db.BooleanField(db_field="active", required=True, default=True) # pylint: disable=no-member updated = db.DateTimeField(db_field="updated", required=True, default=datetime.utcnow) # pylint: disable=no-member meta = { "indexes": [("external_id", "name", "studio", "publisher", "active")] } def to_obj(self): """Returns the Object as a AO object Returns: GameAO -- the instantiated object as Application Object """ return GameAO.from_GameDB(self) def increase_genre(self,genre): """ When an user sets the genre for a game, it must be increased (or added) Arguments: genre {GenreDB instance} -- The genre to be added """ from game.models.user_game_genre import GameGenreQuantificationDB GameGenreQuantificationDB.s_add_genre(self,genre) def decrease_genre(self,genre): """Decrease the number of times a genre was cited to be assigned to the game Arguments: genre {The genre} -- The genre object assigned to the game Returns: int -- If there is no citations of the genre, 0 is return for maintenance in the GamesGenre data field, 1 otherwise. """ from game.models.user_game_genre import GameGenreQuantificationDB GameGenreQuantificationDB.s_remove_genre(self,genre) def get_genres(self): """Returns the genres assigned to the game with their respective quantification """ from game.models.user_game_genre import GameGenreQuantificationDB GameGenreQuantificationDB.s_get_genres(self) def __update_data__(self): """ Updates the genre counts. Disregards all of the current data and compute from zero! A maintenance method for the game """ from game.models.user_game_genre import GameGenreQuantificationDB return GameGenreQuantificationDB.__s_update_quantification__(self) @staticmethod def seek_exact_name(lang,name): """Return the object referent to the game with the name as extacly provided or None Arguments: lang {String} -- Language code for the game name 'pt','en','es','fr',... name {String} -- The name to be searched Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"name."+lang.lower():name}).first() # pylint: disable=no-member @staticmethod def seek_partial_name(lang,name): """Return the object referent to the game with the name containing the text provided Arguments: lang {String} -- Language code for the game name 'pt','en','es','fr',... name {String} -- The text to be searched in the game name Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"name."+lang.lower():{'$regex':name,'$options':'i'}}) # pylint: disable=no-member @staticmethod def seek_studio(name): """Return the object referent to the game with the studio as extacly provided or None Arguments: name {String} -- The name of the studio to be searched Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"studio":name}) # pylint: disable=no-member @staticmethod def seek_partial_studio(name): """Return the object referent to the game with the studio that contains the text provided or None Arguments: name {String} -- The text part of the studio to be searched Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"studio":{'$regex':name,'$options':'i'}}) # pylint: disable=no-member @staticmethod def seek_publisher(name): """Return the object referent to the game with the publisher as extacly provided or None Arguments: name {String} -- The name of the publisher to be searched Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"publisher":name}) # pylint: disable=no-member @staticmethod def seek_partial_publisher(name): """Return the object referent to the game with the publisher containing the text provided or None Arguments: name {String} -- The text part of the publisher name to be searched Returns: GameDB instance -- a GameDB instance with the proper data from the database or None """ return GameDB.objects(__raw__={"publisher":{'$regex':name,'$options':'i'}}) # pylint: disable=no-member @staticmethod def seek_year(the_year): """ Seeks the games reported to be published in the specified year Arguments: the_year {int} -- An integer object containing the year to be searched Returns: List -- A List of GameDB objects with the games published in the specified year """ dtobj=datetime(year=the_year, month=1, day=1) return GameDB.objects(__raw__ = {"year":dtobj}) # pylint: disable=no-member @staticmethod def seek_post_year(the_year): """ Seeks the games reported to be published after the specified year Arguments: the_year {int} -- An integer object containing the year to be searched Returns: List -- A List of GameDB objects with the games published after the specified year """ dtobj=datetime(year=the_year, month=1, day=1) return GameDB.objects(__raw__ = {"year":{ "$gt": dtobj}}) # pylint: disable=no-member @staticmethod def seek_pre_year(the_year): """ Seeks the games reported to be published prior to the specified year Arguments: the_year {int} -- An integer object containing the year to be searched Returns: List -- A List of GameDB objects with the games published prior to the specified year """ dtobj=datetime(year=the_year, month=1, day=1) return GameDB.objects(__raw__ = {"year":{"$lt":dtobj}}) # pylint: disable=no-member @staticmethod def seek_until_year(the_year): """ Seeks the games reported to be published until the specified year Arguments: the_year {int} -- An integer object containing the year to be searched Returns: List -- A List of GameDB objects with the games published until the specified year """ dtobj=datetime(year=the_year, month=1, day=1) return GameDB.objects(__raw__ = {"year":{"$lte":dtobj}}) # pylint: disable=no-member @staticmethod def seek_from_year(the_year): """ Seeks the games reported to be published from the specified year Arguments: the_year {int} -- An integer object containing the year to be searched Returns: List -- A List of GameDB objects with the games published from the specified year """ dtobj=datetime(year=the_year, month=1, day=1) return GameDB.objects(__raw__ = {"year":{"$lte":dtobj}}) # pylint: disable=no-member @staticmethod def seek_by_genre(lang,genre): """ Seeks the games reported to be classified as the provided genre Arguments: lang {String} -- The language code for the genre specified (ex: 'pt') genre {String} -- The genre to be searched Returns: List -- A List of GameDB objects reported to be classified in the specified genre TODO: GamesGenres will provide it """ the_gamesAO=GameAO.seek_by_genre(lang,genre) the_gamesDB=[el.__get_persisted__() for el in the_gamesAO] # pylint: disable=no-member return the_gamesDB @staticmethod def seek_by_genres_or(lang,genre): """ Seeks the games reported to be classified as the provided genre Arguments: lang {String} -- The language code for the genre specified (ex: 'pt') genre {String} -- The list genres to be searched Returns: List -- A List of GameDB objects reported to be classified in the specified genres TODO: The GamesGenres will provide it! """ pass @staticmethod def seek_by_genres_and(lang,genre): """ Seeks the games reported to be classified as the provided genre Arguments: lang {String} -- The language code for the genre specified (ex: 'pt') genre {String} -- The list genres to be searched Returns: List -- A List of GameDB objects reported to be classified in the specified genres TODO: The GamesGenres will provide it! """ pass @classmethod def pre_save(cls, sender, document, **kwargs): """ After saving the genre set the external_id Arguments: sender {UserGameGenre} -- The sender of the signal document {UserGameGenre} -- The instance of the document """ if(not document.external_id): document.external_id=str(uuid4()) #it is a new game. calls for a new quantification object document.is_new=True @classmethod def post_save(cls, sender, document, **kwargs): """ After saving the genre set the external_id Arguments: sender {UserGameGenre} -- The sender of the signal document {UserGameGenre} -- The instance of the document """ if hasattr(document,"is_new"): #it is a new game. calls for a new quantification object from game.models.user_game_genre import GameGenreQuantificationDB newQuant=GameGenreQuantificationDB() newQuant.game=document #a new game, no genre assigned yet newQuant.genreCount={} newQuant.save() def __repr__(self): the_game=f" External_id: {self.external_id}\n Name: {self.name}\n Studio: {self.studio}\n Publisher: {self.publisher}\n Year: {self.year}\n" the_game+=f" Active: {self.active}\n Proposed: {self.date_proposed}\n Accepted: {self.date_accepted}\n Updated: {self.updated}"
class ElementDB(db.Document): """Class mapping the element object in the system with the element data in the database Arguments: db {Document} -- Derive from the Document class in MongoEngine Attributes: external_id {StringField} -- A string containing a uuid data representing a single element. A primary key to be provided to external applications active {BooleanField} -- A boolean value indicating whether the element is active (in use/is part of computations) or not in the system. This field represents data that had identified duplicate (due to the distributiveness and concurrency of the system) A False value excludes the data to be provided to queries (such as suggestions) element {DictField} -- The proper element is represented with a dictionary to provide multilang feature. The format of the data consists in the pair lang : element, like: {'pt':'personagem', 'en': 'character'} reassigned_to {ReferenceField(ElementDB)} -- a reference field indicating the current element is deprecated and to which one the context was reassigned reassigned_from {ReferenceField(ElementDB)} -- a reference field indicating that it now holds responsibility to contextualize the meaning of the former element """ external_id = db.StringField(db_field="external_id", required=True) # pylint: disable=no-member # Element field is a dictfield to provide multilang data. # Data form: {'lang1':'element', 'lang2':'element'} element = db.DictField(db_field="element", required=True) # pylint: disable=no-member active = db.BooleanField(db_field="active", default=True) # 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 updated = db.DateTimeField(db_field="updated", required=True, default=datetime.utcnow) # pylint: disable=no-member created = db.DateTimeField(db_field="created", required=True, default=datetime.utcnow) # pylint: disable=no-member meta = {"indexes": [("external_id", "active", "element")]} def __repr__(self): return f"{self.external_id}: {self.element} - active: {self.active} \n {self.reassigned_to if self.reassigned_to else ''} \n {self.reassigned_from if self.reassigned_from else ''}" def __eq__(self, other): return self.__hash__() == other.__hash__() def __semi_hash__(self): the_str = "" langs = list(self.element.keys()) if langs: langs.sort() for key in langs: the_str += f"{key}:{self.element[key]} - " the_str += str(self.active) + " " elts = [elem.external_id for elem in self.reassigned_from] if elts: elts.sort() for elt in elts: the_str += f"{elt} - " if self.reassigned_to: the_str += self.reassigned_to.external_id + " - " return the_str def __hash__(self): """ Returns the hash value of the object. The hash value is created considering the following form: Starts with a DB indicating it is from database Get the element keys as list. It is the list of languages. Sort it The sorted list is used to form the string combo for each element (yes, ends with a dash space): lang+element - To this string appends the active value Creates the string for reassigned from, using only the external_id of the elements The reassigned_to must be the same. This is valid only with the external_id (or else we have a recursion) Finally, the updated data. """ the_str = "DB " + self.__semi_hash__() return hash(the_str) def compare_application(self, ao_obj): if not isinstance(ao_obj, ElementAO): return False self_hash = hash(self.__semi_hash__()) ao_hash = hash(ao_obj.__semi_hash__()) return self_hash == ao_hash def to_obj(self): return ElementAO.from_db(self) def update_element(self, lang, elem): """Updates the element sign for the language without performing a full scale mapping Arguments: lang {string(2)} -- The string representing the system language to indicate the element elem {string} -- The proper sign of the element """ self.element[lang] = elem self.save() @staticmethod def reassign(current, deprecated): """Reassign the deprecated element to the current one. Used to maintain the semantics sanity of the system Arguments: current {ElementDB} -- The element that will assume the meaning deprecated {ElementDB} -- The element whose meaning will be transfered Some ground rules: If the element has a reassigned_to, the active field must be false. If the element has a reassigned_from, each element in the reassigned from list must have this element as reassigned to. This does not update the stored SCSR user data, but must perform recalculations on SCSR consolidated data. This does, however, updates the SCSR user data sent to the Frontend. The change must be highlighted and explained. If the user updates, the deprecated is removed and the current is added. """ if ((not isinstance(current, ElementDB)) or (not isinstance(deprecated, ElementDB))): return False #Set the reassigned_to deprecated.reassiged_to = current deprecated.active = False deprecated.save() # #Set the reassigned_from if (not current.reassigned_from): current.reassigned_from = [] current.reassigned_from.append(deprecated) current.save() # This is what must return return True @staticmethod def seek_or_create(lang, element): elemento = ElementDB.seek_element(lang, element) if (not elemento): elemento = ElementDB() elemento.element = {} elemento.element[lang] = element elemento.save() return elemento @staticmethod def seek_element(lang, elem): return ElementDB.objects(__raw__={ "element." + lang.lower(): elem, "active": True }).first() # pylint: disable=no-member @staticmethod def seek(ext_id): return ElementDB.objects.filter(external_id=ext_id).first() # pylint: disable=no-member @staticmethod def suggests(lang, elem): """Returns the list of elements that contains or starts with the partial text provided in the language of the typer Arguments: lang {String} -- The language of the element elem {String} -- The partial string that the element contains """ return ElementDB.objects( __raw__={ "element." + lang.lower(): { '$regex': elem, '$options': 'i' }, "active": True }) # pylint: disable=no-member @classmethod def pre_save(cls, sender, document, **kwargs): """ Prior to saving the element check if all lang are supported, set the external_id Arguments: sender {ElementDB} -- The sender of the signal document {ElementDB} -- The instance of the document """ if (not document.external_id): document.external_id = str(uuid4()) @classmethod def post_save(cls, sender, document, **kwargs): """ With a successful save check if there is a reference element. If not, create one. Arguments: sender {ElementDB} -- The sender of the signal document {ElementDB} -- The instance of the document """ refel = ElementReferenceDB.objects.filter(element=document).first() # pylint: disable=no-member if not refel: #Element just created. Create the reference for it ElementReferenceAO(element=document.to_obj()).save()
class GameGenreQuantificationDB(db.Document): """ Class that quantifies the genres in games. Replaces the field in the GamesDB obj, maintaining decoupling of responsibilities. This Element Data is created when the referenced game is available in the system. Meaning, a game suggestion is accepted. Attributes: game {GameDB}: The primary key, refers to the game in process genreCount {DictField}: The quantification field. Constructed in the form {string:value} representing the GenreDB external ID and the number of assignments made. Methods: to_obj(self): Returns the full representation of the quantification in the form: [{"genre":GenreObj, "cited":number_of_citations}] __maintenance(self): performs the maintenance of the persisted data, counting the genres assigned to the game add_genre(self,genre): Increments the genre in the object or adds it setting to 1. Does not persist the data. add_genres(self,genres): Increments the genre in the object or adds it setting to 1. Does not persist the data. s_add_genre(game,genre): Increments the genre in the game provided. Persists the data. s_add_genres(game,genres): Increments the genres of the list in the game provided. Persists the data. remove_genre(self,genre): Decrements the genre in the object. Does not persist the data. remove_genres(self,genres): Decrements the genre in the object list. Does not persist the data. s_remove_genre(game,genre): Decrements the genre in the game provided. Persists the data. s_remove_genres(game,genres): Decrements the genres of the list in the game provided. Persists the data. Note: The remove method does not remove the key from the dict if the count reaches 0. This indicates that the genre was once considered for the game and this is a valid information. Note: All the data are considered to be DB data. The Controller must provide the proper data! """ game = db.ReferenceField(GameDB, db_field="game", required=True, primary_key=True) # pylint: disable=no-member genreCount = db.DictField(db_field="genreCount", default={}) # pylint: disable=no-member def to_obj(self): """ Returns the genres with their respective quantification in a list of dictionaris Returns: List(dict) -- The list of dictionaries with the respective genre and quantification in the form (keys) {'genre','cited'} """ retorno = [{ 'genre': GenreDB.objects.filter(external_id=key).first(), 'cited': self.genreCount[key] } for key in self.genreCount.keys()] # pylint: disable=no-member return retorno def add_genre(self, genre): """ method to add a genre to the game referred in the object. The quantification is updated. Data not persisted. Arguments: genre {GenreDB} -- The GenreDB object to be added Raises: TypeError -- Error if arguments are not of the provided type """ if (not isinstance(genre, GenreDB)): raise TypeError( "Argument provided is not of the class GenreDB. Class provided: " + type(genre)) if (genre.external_id in self.genreCount): self.genreCount[ genre.external_id] = self.genreCount[genre.external_id] + 1 else: self.genreCount[genre.external_id] = 1 GamesGenresDB.s_append_game(genre, self.game) def remove_genre(self, genre): """ method to remove a genre to the game referred in the object. The quantification is updated. Data not persisted. Arguments: genre {GenreDB} -- The GenreDB object to be removed Raises: TypeError -- Error if arguments are not of the provided type """ if (not isinstance(genre, GenreDB)): raise TypeError( "Argument provided is not of the class GenreDB. Class provided: " + type(genre)) if (genre.external_id in self.genreCount): self.genreCount[ genre.external_id] = self.genreCount[genre.external_id] - 1 if (self.genreCount[genre.external_id] < 1): self.genreCount[genre.external_id] = 0 GamesGenresDB.s_remove_game(genre, self.game) def add_genres(self, genres): """ method to add the genres in the list to the game referred in the object. The quantification is updated. Data not persisted. Arguments: genre {List(GenreDB)} -- The list of GenreDB objects to be added Raises: TypeError -- Error if arguments are not of the provided type """ #validate all for genre in genres: # Although there is a validation for each genre in the add_genre method, the method do perform changes... # This guarantees that no change is made if there is at least one invalid data. if (not isinstance(genre, GenreDB)): raise TypeError( "Argument provided in list is not of the class GenreDB. Class provided: " + type(genre)) for genre in genres: self.add_genre(genre) def remove_genres(self, genres): """ method to remove the genres in the list to the game referred in the object. The quantification is updated. Data not persisted. Arguments: genre {List(GenreDB)} -- The list of GenreDB objects to be removed Raises: TypeError -- Error if arguments are not of the provided type """ #validate all for genre in genres: # Although there is a validation for each genre in the add_genre method, the method do perform changes... # This guarantees that no change is made if there is at least one invalid data. if (not isinstance(genre, GenreDB)): raise TypeError( "Argument provided in list is not of the class GenreDB. Class provided: " + type(genre)) for genre in genres: self.remove_genre(genre) def __update_quantification__(self): """ Updates the quantification data for the object. TODO: Check if a less constly method is provided by python. This shall cost O(N^2)... luckily there are few genres! Raises: RuntimeError -- No quantification data found! """ #retrieve all user data for this game user_datas = UserGameGenreDB.objects.filter(game=self.game) # pylint: disable=no-member if (not user_datas): raise RuntimeError( "ERROR: Quantification data for the game object not found.") new_quant = {} current_gen_list = set(self.genreCount.keys()) # DAMN... it is f*****g O(n^2)... tenho que rever isso! for classification in user_datas: for genre in classification.genre: if (genre.external_id not in new_quant.keys()): new_quant[genre.external_id] = 0 new_quant[genre.external_id] = new_quant[genre.external_id] + 1 new_gen_list = set(new_quant.keys()) removed = current_gen_list.difference(new_gen_list) added = new_gen_list.difference(current_gen_list) #updates the games in genre list. for to_del in removed: GamesGenresDB.s_remove_game( GenreDB.objects.filter(external_id=to_del).first(), self.game) # pylint: disable=no-member for to_add in added: GamesGenresDB.s_append_game( GenreDB.objects.filter(external_id=to_add).first(), self.game) # pylint: disable=no-member self.genreCount = new_quant self.save() @staticmethod def __s_update_quantification__(the_game): """ Updates the quantification data for the desired game Arguments: the_game {GameDB} -- The game to have its quantification updated Raises: TypeError -- The game data is not a valid GameDB object Returns: True if executed. """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #retrieve the quantification object for the game. Its data will be disregarded. to_update = GameGenreQuantificationDB.objects.filter(game=the_game) # pylint: disable=no-member to_update.__update_quantification__() # No exception raised... returns true! return True @staticmethod def s_add_genre(the_game, genre): """ Static method to add a genre assigned to a game. The quantification is updated. Data persisted. Arguments: the_game {GameDB} -- A GameDB Object referring to the game genre {GenreDB} -- The GenreDB object to be added Raises: TypeError -- Error if arguments are not of the provided type RuntimeError -- Error if no valid quantification exists """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_save = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_save): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) to_save.add_genre(genre) to_save.save() @staticmethod def s_add_genres(the_game, genres): """ Static method to add a list of genres assigned to a game. The quantification is updated. Data persisted. Arguments: the_game {GameDB} -- A GameDB Object referring to the game genres {List (GenreDB)} -- A List of GenreDB Objects to be added Raises: TypeError -- Error if arguments are not of the provided type RuntimeError -- Error if no valid quantification exists """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_save = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_save): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) to_save.add_genres(genres) to_save.save() @staticmethod def s_remove_genre(the_game, genre): """ Static method to remove a genre assigned to a game. The quantification is updated. Data persisted. Arguments: the_game {GameDB} -- A GameDB Object referring to the game genre {GenreDB} -- The GenreDB object to be removed Raises: TypeError -- Error if arguments are not of the provided type RuntimeError -- Error if no valid quantification exists """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_save = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_save): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) to_save.remove_genre(genre) to_save.save() @staticmethod def s_remove_genres(the_game, genres): """ Static method to remove a list of genres assigned to a game. The quantification is updated. Data persisted. Arguments: the_game {GameDB} -- A GameDB Object referring to the game genres {List (GenreDB)} -- A List of GenreDB Objects to be removed Raises: TypeError -- Error if arguments are not of the provided type RuntimeError -- Error if no valid quantification exists """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_save = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_save): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) to_save.remove_genres(genres) to_save.save() @staticmethod def s_get_genres(the_game): """ Return the genre quantification data for the game. Arguments: the_game {GameDB} -- The game data to be assessed Raises: TypeError -- If the argument is not a GameDB object RuntimeError -- If a valid GameDB object is provided but no quantification is found Returns: List -- List of dictionaries containing the Genre object and the number of citations of the genre for the object in the form {genre,cited} """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_retrieve = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_retrieve): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) return to_retrieve.to_obj() @staticmethod def s_get_genres_ao(the_game): """ Return the genre quantification data for the game. Arguments: the_game {GameDB} -- The game data to be assessed Raises: TypeError -- If the argument is not a GameDB object RuntimeError -- If a valid GameDB object is provided but no quantification is found Returns: List -- List of dictionaries containing the Genre object and the number of citations of the genre for the object in the form {genre,cited} """ if (not isinstance(the_game, GameDB)): raise TypeError( "Argument provided is not a valid GameDB object. Object provided: " + type(the_game)) #seek the game_genre object to_retrieve = GameGenreQuantificationDB.objects.filter( game=the_game).first() # pylint: disable=no-member if (not to_retrieve): raise RuntimeError( "There is no data for the Game provided. There should be. Game: " + the_game.external_id) return [ { "genre": GenreDB.objects.filter(external_id=key).first().to_obj(), # pylint: disable=no-member "cited": to_retrieve.genreCount[key] } for key in to_retrieve.genreCount.keys() ]
class Store(db.Document): OPEN = 1 AWAY = 0 CLOSED = 2 STATUS_TYPE = ((OPEN, 'Opening'), (CLOSED, 'Closed'), (AWAY, 'Away')) storename = db.StringField(db_field="sn", default=None, unique=True) username = db.StringField(db_field="u", required=True, unique=True) password = db.StringField(db_field="pwd", required=True) store_image = db.StringField(db_field="si", default=None) qr_image = db.StringField(db_field="qr", default=None) status = db.IntField(db_field="st", choices=STATUS_TYPE, default=CLOSED) created = db.IntField(db_field="c", default=now()) storecode = db.StringField(db_field="sc", unique=True, required=True) email = db.StringField(db_field="em") pageprize = db.DictField(db_field='pp') pages = db.ListField(db_field='p') #store user ,name, and message for use to notify store #store message as str def add_notification(self, name, data): Notification.objects.filter(name=name, user_id=self.id).delete() n = Notification(name=name, payload_json=json.dumps(data), user_id=self.id) n.save() return n def store_imgsrc(self, size): #This models function take size as parameter #then return a path base on storename and size #file name is base on Thumbnail_process() if self.store_image: if AWS_BUCKET: return os.path.join( AWS_CONTENT_URL, AWS_BUCKET, 'store', '%s.%s.%s.jpg' % (self.storecode, self.store_image, size) ).replace( "%5C", "/" ) #Locate img location and have size as parameter for using in different templates else: return url_for( 'static', filename=os.path.join( STATIC_IMAGE_URL, 'store', '%s.%s.%s.jpg' % (self.storecode, self.store_image, size))).replace( "%5C", "/") else: return url_for('static', filename=os.path.join( 'assets', 'default_image', 'logo-store-png.png')).replace('%5C', '/') def owner_imgsrc(self, size): #This models function take size as parameter #then return a path base on owner and size #file name is base on Thumbnail_process() if self.qr_image: if AWS_BUCKET: return os.path.join( AWS_CONTENT_URL, AWS_BUCKET, 'owner', '%s.%s.jpg' % (self.storecode, self.qr_image) ).replace( '%5C', '/' ) #Locate img location and have size as parameter for using in different templates else: return url_for( 'static', filename=os.path.join( STATIC_IMAGE_URL, 'owner', '%s.%s.%s.jpg' % (self.storecode, self.qr_image, size))).replace( '%5C', '/') else: return url_for('static', filename=os.path.join('assets', 'default_image', 'non-qr.png')).replace( '%5C', '/') meta = {'indexes': ['storecode', 'username', '-created', 'status']}