예제 #1
0
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')]}
예제 #2
0
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")
예제 #3
0
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']
    }
예제 #4
0
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
    }
예제 #5
0
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()
예제 #6
0
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
    }
예제 #7
0
파일: models.py 프로젝트: youandvern/encomp
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'}
예제 #8
0
파일: models.py 프로젝트: youandvern/encomp
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'}
예제 #9
0
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']}
예제 #10
0
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
예제 #11
0
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')]}
예제 #12
0
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
예제 #13
0
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']}
예제 #14
0
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)
예제 #15
0
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
예제 #16
0
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]
예제 #17
0
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())
예제 #18
0
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()
예제 #19
0
class stock_price(db.Document):
    stock_id = db.StringField(max_length=20, required=True, unique=True)
    data = db.DictField()
    meta = {'indexes': ['stock_id']}
예제 #20
0
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')]}
예제 #21
0
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()
예제 #22
0
파일: game.py 프로젝트: hiperlogic/scsr-api
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}"
예제 #23
0
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()
예제 #24
0
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()
        ]
예제 #25
0
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']}