Beispiel #1
0
class Person(appier.Model):

    identifier = appier.field(type=int,
                              index=True,
                              increment=True,
                              default=True)

    identifier_safe = appier.field(type=int,
                                   index=True,
                                   increment=True,
                                   safe=True)

    name = appier.field()

    age = appier.field(type=int)

    info = appier.field(type=dict)

    father = appier.field(
        type=appier.reference("Person", name="identifier", dumpall=True))

    brother = appier.field(type=appier.reference("Person", name="identifier"))

    car = appier.field(type=appier.reference("Car", name="identifier"),
                       eager=True)

    cats = appier.field(type=appier.references("Cat", name="identifier"))

    @classmethod
    def validate(cls):
        return super(Person, cls).validate() + [
            appier.not_null("name"),
            appier.not_empty("name"),
            appier.not_duplicate("name", cls._name())
        ]
Beispiel #2
0
class Garage(appier.Model):

    identifier = appier.field(
        type = int,
        index = True,
        increment = True,
        default = True
    )

    identifier_safe = appier.field(
        type = int,
        index = True,
        increment = True,
        safe = True
    )

    name = appier.field()

    address = appier.field(
        type = appier.reference(
            "Address",
            name = "identifier"
        ),
        eager = True
    )
class EWishlistLine(base.EBase):

    quantity = appier.field(type=float)

    total = appier.field(type=float)

    product = appier.field(type=appier.reference("EProduct", name="id"))
Beispiel #4
0
class Car(appier.Model):

    identifier = appier.field(
        type = int,
        index = True,
        increment = True,
        default = True
    )

    identifier_safe = appier.field(
        type = int,
        index = True,
        increment = True,
        safe = True
    )

    name = appier.field()

    brand = appier.field()

    variant = appier.field()

    garage = appier.field(
        type = appier.reference(
            "Garage",
            name = "identifier"
        ),
        eager = True
    )
Beispiel #5
0
class EnterAction(action.Action):

    entity = appier.field(
        type = appier.reference(
            entity.Entity,
            name = "identifier"
        ),
        observations = """The entity that has just entered
        a certain area of coverage"""
    )

    @classmethod
    def list_names(cls):
        return ["timestamp", "entity", "app"]

    @classmethod
    def latest(cls, identifier):
        return cls.get(
            entity = identifier,
            sort = [("timestamp", -1), ("id", -1)],
            raise_e = False
        )

    @classmethod
    def last(cls, identifier, limit = 2):
        return cls.find(
            entity = identifier,
            sort = [("timestamp", -1), ("id", -1)],
            limit = limit
        )

    @classmethod
    def enter_s(
        cls,
        identifier,
        timestamp = None,
        info = None,
        key = None,
        verify = False
    ):
        info = info or dict()
        if verify: entity.Entity.verify_g(identifier, key)
        enter = cls(
            entity = identifier,
            timestamp = timestamp,
            info = info
        )
        enter.save()
        return enter
Beispiel #6
0
class Cat(appier.Model):

    identifier = appier.field(type=int,
                              index=True,
                              increment=True,
                              default=True)

    identifier_safe = appier.field(type=int,
                                   index=True,
                                   increment=True,
                                   safe=True)

    name = appier.field()

    friend = appier.field(type=appier.reference("Cat", name="identifier"))
Beispiel #7
0
class EOrderLine(base.EBase):

    quantity = appier.field(type=float)

    total = appier.field(type=float)

    size = appier.field(type=int)

    size_s = appier.field()

    scale = appier.field(type=int)

    meta = appier.field(type=dict)

    meta_j = appier.field()

    product = appier.field(type=appier.reference("EProduct", name="id"))

    @classmethod
    def _build(cls, model, map):
        super(EOrderLine, cls)._build(model, map)

        meta = model.get("meta", {}) or {}
        image_url = meta.get("image_url", None)
        if not image_url: return

        product = model["product"]
        for size in ("thumbnail", "large"):
            size_i = size + "_image"
            image = product[size_i] or {}
            image["url"] = image_url
            product[size_i] = image

    @property
    def size_v(self):
        return self.size_s if self.size_s else str(self.size)
Beispiel #8
0
class Base(appier_extras.admin.Base):

    id = dict(type=int, index=True, increment=True)

    unique_id = dict(index=True)

    enabled = dict(type=bool, index=True)

    create_date = dict(type=float, index=True)

    modify_date = dict(type=float, index=True)

    create_user = dict(type=appier.reference("Account", name="id"), index=True)

    modify_user = dict(type=appier.reference("Account", name="id"), index=True)

    description = dict(default=True)

    @classmethod
    def _build(cls, model, map):
        appier_extras.admin.Base._build(model, map)
        enabled = model.get("enabled", None)
        model["status"] = enabled and "enabled" or "disabled"

    @classmethod
    def lock_g(cls, name):
        model_name = cls.__name__
        model_name_l = model_name.lower()
        lock_name = "%s_%s" % (model_name_l, name)
        lock = LOCKS_MAP.get(lock_name, threading.RLock())
        lock.acquire()
        LOCKS_MAP[lock_name] = lock

    @classmethod
    def unlock_g(cls, name):
        model_name = cls.__name__
        model_name_l = model_name.lower()
        lock_name = "%s_%s" % (model_name_l, name)
        lock = LOCKS_MAP[lock_name]
        lock.release()

    @classmethod
    def _slugify(cls, text, delim=u"-"):
        result = []
        if not type(text) == unicode: text = text.decode("utf-8")
        _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
        for word in _punct_re.split(text.lower()):
            result.extend(unidecode.unidecode(word).split())
        return unicode(delim.join(result))

    @classmethod
    def _get_timestamp(cls, date=None):
        date = date or datetime.datetime.utcnow()
        date_utc = date.utctimetuple()
        timestamp = calendar.timegm(date_utc)
        return timestamp

    def pre_create(self):
        import account
        self.unique_id = str(uuid.uuid4())
        self.enabled = True
        self.create_date = self.modify_date = time.time()
        self.create_user = self.modify_user = account.Account.get_from_session(
            raise_e=False)

    def pre_update(self):
        import account
        self.modify_date = time.time()
        self.modify_user = account.Account.get_from_session(raise_e=False)

    def enable_s(self):
        if self.enabled: return
        self.enabled = True
        self.save()
        self.trigger("enabled")

    def disable_s(self):
        if not self.enabled: return
        self.enabled = False
        self.save()
        self.trigger("disabled")

    def increment_s(self, name, default=0):
        # acquires a lock for the attribute
        self.lock(name)

        # increments the value
        value = getattr(self, name) if hasattr(self, name) else default
        value += 1
        setattr(self, name, value)

        # saves the change and releases the lock
        collection = self._collection()
        try:
            collection.update({"id": self.id}, {"$set": {name: value}})
        finally:
            self.unlock(name)

    def decrement_s(self, name, default=0):
        # acquires a lock for the attribute
        self.lock(name)

        # decrements the value
        value = getattr(self, name) if hasattr(self, name) else default
        value -= 1
        setattr(self, name, value)

        # saves the change and releases the lock
        collection = self._collection()
        try:
            collection.update({"id": self.id}, {"$set": {name: value}})
        finally:
            self.unlock(name)

    def get_previous(self):
        import account
        account_s = account.Account.get_from_session(raise_e=False)
        _class = self.__class__
        entities = _class.find(
            id={"$lt": self.id}, enabled=True, sort=[
                ("id", -1)
            ], limit=1) if account_s else _class.find(
                id={"$lt": self.id}, sort=[("id", -1)], limit=1)
        if not entities: return
        entity = entities[0]
        return entity

    def get_next(self):
        import account
        account_s = account.Account.get_from_session(raise_e=False)
        _class = self.__class__
        entities = _class.find(
            id={"$gt": self.id}, enabled=True, sort=[
                ("id", 1)
            ], limit=1) if account_s else _class.find(
                id={"$gt": self.id}, sort=[("id", 1)], limit=1)
        if not entities: return
        entity = entities[0]
        return entity

    def get_previous_id(self):
        previous = self.get_previous()
        if not previous: return
        return previous.id

    def get_next_id(self):
        next = self.get_next()
        if not next: return
        return next.id

    def lock(self, name=None):
        _name = "%d_%s" % (self.id, name or "")
        self.lock_g(_name)

    def unlock(self, name=None):
        _name = "%d_%s" % (self.id, name or "")
        self.unlock_g(_name)

    def reload(self):
        cls = self.__class__
        return cls.get(id=self.id)

    def equals(self, entity):
        self_id = self.id if hasattr(self, "id") else None
        entity_id = entity.id if hasattr(entity, "id") else None
        return self_id == entity_id

    def is_persisted(self):
        return hasattr(self, "id") and not self.id == None

    def is_modified(self):
        return not self.create_date == self.modify_date

    def has_previous(self):
        previous = self.get_previous()
        return bool(previous)

    def has_next(self):
        next = self.get_next()
        return bool(next)

    def has(self, name):
        if not hasattr(self, name): return False
        if not self.name: return False
        return True
Beispiel #9
0
class EOrder(base.EBase):

    status = appier.field()

    paid = appier.field(type=bool)

    date = appier.field(type=int)

    reference = appier.field()

    currency = appier.field()

    sub_total = appier.field(type=float)

    discount = appier.field(type=float)

    shipping_cost = appier.field(type=float)

    total = appier.field(type=float)

    email = appier.field()

    shipping_address = appier.field(
        type=appier.reference("EAddress", name="id"))

    billing_address = appier.field(
        type=appier.reference("EAddress", name="id"))

    lines = appier.field(type=appier.references("EOrderLine", name="id"))

    vouchers = appier.field(type=appier.references("EVoucher", name="id"))

    @classmethod
    def _build(cls, model, map):
        super(EOrder, cls)._build(model, map)

        date = model["date"]
        if date: date = datetime.datetime.utcfromtimestamp(date)
        model["date_s"] = date.strftime("%Y-%m-%d") if date else None

        lines = model.get("lines", [])
        model["quantity"] = sum([line["quantity"] for line in lines])

    @property
    def voucher(self):
        if not hasattr(self, "vouchers"): return
        if not self.vouchers: return
        return self.vouchers[0]

    @property
    def quantity(self):
        return sum([line.quantity for line in self.lines])

    @property
    def date_s(self):
        return self.get_date_s()

    def get_date_s(self, format="%Y-%m-%d"):
        if not hasattr(self, "date"): return None
        if not self.date: return None
        date = datetime.datetime.utcfromtimestamp(self.date)
        return date.strftime(format)

    def is_finalized(self):
        return True
Beispiel #10
0
class EBagLine(base.EBase):

    quantity = appier.field(
        type = float
    )

    total = appier.field(
        type = float
    )

    size = appier.field(
        type = int
    )

    size_s = appier.field()

    scale = appier.field(
        type = int
    )

    meta = appier.field(
        type = dict
    )

    meta_j = appier.field()

    product = appier.field(
        type = appier.reference(
            "EProduct",
            name = "id"
        )
    )

    @classmethod
    def _build(cls, model, map):
        super(EBagLine, cls)._build(model, map)

        meta = model.get("meta", {}) or {}
        image_url = meta.get("image_url", None)
        embossing = meta.get("embossing", None)

        if image_url:
            product = model["product"]
            for size in ("thumbnail", "large"):
                size_i = size + "_image"
                image = product[size_i] or {}
                image["url"] = image_url
                product[size_i] = image

        if embossing:
            embossing_s = embossing.replace("_", " ")
            embossing_s = embossing_s.capitalize()
            meta["embossing_s"] = embossing_s

    def get_meta(self, normalize = True):
        if not self.meta: return self.meta
        meta = dict(self.meta)
        if not normalize: return meta
        for extra in ("embossing_s",):
            if not extra in meta: continue
            del meta[extra]
        return meta

    @property
    def size_v(self):
        return self.size_s if self.size_s else str(self.size)
Beispiel #11
0
class OAuthToken(base.Base, authenticable.Authenticable):
    """
    Model class that represent an OAuth 2.0 access token
    that as been in created for a specific user context
    and with a certain duration scope.
    """

    DEFAULT_DURATION = 3600
    """ The default duration of the OAuth token, this
    value should not be too long to avoid security issues """

    DEFAULT_LONG_DURATION = 315360000
    """ The default duration (in seconds) value to be used
    in a long lived OAUth token (eg: 10 years) """

    CODE_DURATION = 600
    """ The authorization code duration (in seconds), to be
    used for proper authorization code validation """

    name = appier.field(
        index = "hashed",
        default = True,
        safe = True,
        immutable = True
    )
    """ Simplified name value, created from the first few
    characters of the (original) access token value """

    access_token = appier.field(
        index = "hashed",
        safe = True
    )
    """ The actual string representing an authorization
    issued to the client, this is not an immutable value
    as the refresh token may be used to generate a new one """

    access_token_date = appier.field(
        type = float,
        safe = True,
        private = True,
        meta = "datetime"
    )
    """ The date when the access token was last generated, multiple
    access token may be generated using the refresh token"""

    authorization_code = appier.field(
        index = "hashed",
        safe = True,
        private = True
    )
    """ The authorization code generated by the authorization server
    to be sent to the client side for future obtain of access token """

    authorization_code_date = appier.field(
        type = float,
        safe = True,
        private = True,
        meta = "datetime"
    )
    """ The date when the authorization code was generated """

    username = appier.field(
        index = "hashed",
        safe = True,
        immutable = True
    )
    """ The name of the user that is authorized this
    access token, will be used for custom ACL creation """

    scope = appier.field(
        type = list,
        private = True,
        immutable = True
    )
    """ The OAuth based scope string that "created" this
    token with its values sorted alphabetically """

    expires_in = appier.field(
        type = int,
        index = "all",
        safe = True,
        immutable = True
    )
    """ The duration in seconds of the access token lifetime """

    redirect_uri = appier.field(
        index = "hashed",
        immutable = True,
        meta = "url",
        description = "Redirect URI"
    )
    """ An absolute URI to which the authorization server
    will redirect the user-agent to when the end-user
    authorization step is completed """

    refresh_token = appier.field(
        index = "hashed",
        safe = True,
        private = True,
        immutable = True
    )
    """ A token used by the client to obtain a new access token
    (in addition or as a replacement for an expired access
    token), without having to involve the resource owner. """

    tokens = appier.field(
        type = list,
        safe = True,
        private = True,
        immutable = True
    )
    """ The ACL tokens associated with this access token, should
    be created taking into account the token scope """

    client = appier.field(
        type = appier.reference(
            "OAuthClient",
            name = "id"
        ),
        immutable = True
    )
    """ The reference to the OAuth client that has been used
    for the generation of this token """

    @classmethod
    def validate(cls):
        return super(OAuthToken, cls).validate() + [
            appier.not_null("username"),
            appier.not_empty("username"),

            appier.not_null("scope"),
            appier.not_empty("scope"),
            appier.string_gt("scope", 0),

            appier.not_null("redirect_uri"),
            appier.not_empty("redirect_uri"),
            appier.is_url("redirect_uri"),

            appier.not_null("client")
        ]

    @classmethod
    def list_names(cls):
        return ["name", "created", "username"]

    @classmethod
    def order_name(cls):
        return ["id", -1]

    @classmethod
    def reuse_s(cls, redirect_uri, scope, oauth_client, account = None, owner = None):
        # defaults the provided owner value to the global registered
        # app to be used if required for account defaulting
        owner = owner or appier.get_app()

        # retrieves the current account from session and then
        # normalizes the provided scope list to convert it to
        # tokens (filters on account permissions) then tries to
        # retrieve an already existing compatible OAuth token
        account = account or owner.admin_part.account_c.from_session()
        tokens = cls._filter_scope_g(scope, account = account)
        oauth_token = cls.get_e(
            redirect_uri = redirect_uri,
            username = account.username,
            scope = scope,
            tokens = tokens,
            client = oauth_client.id,
            rules = False,
            raise_e = False
        )

        # in case there's no valid equivalent token, returns the
        # control flow immediately with an invalid value
        if not oauth_token: return False, tokens, None

        # in case the access token contained in the object is already
        # expired then refreshes the access token so that it can live
        # one more time for this request (refreshed re-usage scenario)
        if oauth_token.is_expired(): oauth_token.refresh_access_token_s()

        # in case there's an already existing OAuth token that
        # has the same requirements (scope, client, redirect URL)
        # of the one being requested, then a new authorization code
        # is generated and the user agent is redirected immediately
        # as there's no extra need for user interaction
        oauth_token.set_code_s()

        # returns a valid result indicating both the retrieved tokens
        # and the OAuth token that can be used for re-usage
        return True, tokens, oauth_token

    @classmethod
    def login(cls, access_token, rules = False):
        oauth_token = cls.get_e(
            access_token = access_token,
            rules = rules,
            raise_e = False
        )
        if not oauth_token: raise appier.SecurityError(
            message = "OAuth token not found",
            code = 403
        )
        oauth_token.touch_expired()
        return oauth_token

    @classmethod
    @appier.view(
        name = "Explorer",
        parameters = (
            ("Access Token", "access_token", str),
            ("Refresh Token", "refresh_token", str)
        )
    )
    def explorer_v(cls, access_token, refresh_token, *args, **kwargs):
        kwargs["sort"] = kwargs.get("sort", [("id", -1)])
        if access_token: kwargs.update(access_token = access_token)
        if refresh_token: kwargs.update(refresh_token = refresh_token)
        return appier.lazy_dict(
            model = cls,
            kwargs = kwargs,
            entities = appier.lazy(lambda: cls.find(*args, **kwargs)),
            page = appier.lazy(lambda: cls.paginate(*args, **kwargs))
        )

    @classmethod
    def _filter_scope_g(cls, scope, account = None, owner = None):
        """
        Filters the provided sequence of tokens for the scope, so
        that only the ones allowed for the requested account are used.

        This avoid security issues like someone requesting values
        for a token that is for which the user is not allowed.

        :type scope: List
        :param scope: The list of tokens to be filtered.
        :type account: Account
        :param account: The account that is going to be used for the
        filtering of the values, in case none is provided the current
        account in session is used.
        :rtype: List
        :return: The resulting filtering list containing only the
        tokens for which the provided account is capable.
        """

        # defaults the provided owner value to the global registered
        # app to be used if required for account defaulting
        owner = owner or appier.get_app()

        # builds the list that is going to be used to store the
        # result of the scope filtering (ACL verification)
        result = []

        # retrieves the complete set of tokens from the account
        # and then converts them into the map version of them
        account = account or owner.admin_part.account_c.from_session()
        tokens = account.tokens()
        tokens_m = appier.to_tokens_m(tokens)

        # iterates over each token of the scope to validate it
        # according to the ACL of the associated account
        for token in scope:
            valid = appier.check_token(None, token, tokens_m = tokens_m)
            if not valid: continue
            result.append(token)

        # returns the final result that contains only the scope
        # tokens for which the account is entitle to register
        return result

    @classmethod
    def _underscore(cls, plural = True):
        return "oauth_tokens" if plural else "oauth_token"

    @classmethod
    def _readable(cls, plural = False):
        return "OAuth Tokens" if plural else "OAuth Token"

    def pre_create(self):
        base.Base.pre_create(self)

        cls = self.__class__
        duration = appier.conf("OAUTH_DURATION", cls.DEFAULT_DURATION, cast = int)
        long_duration = appier.conf("OAUTH_LONG_DURATION", cls.DEFAULT_LONG_DURATION, cast = int)
        if hasattr(self, "long") and self.long: duration = long_duration
        self.access_token = appier.gen_token()
        self.access_token_date = time.time()
        self.client_secret = appier.gen_token()
        self.authorization_code = appier.gen_token()
        self.authorization_code_date = time.time()
        self.expires_in = duration
        self.refresh_token = appier.gen_token()
        self.tokens = self._filter_scope(self.scope)
        self.name = self.access_token[:8]

        self._verify()

    def set_code_s(self):
        self.authorization_code = appier.gen_token()
        self.authorization_code_date = time.time()
        self.save()

    def unset_code_s(self):
        self.authorization_code = None
        self.authorization_code_date = None
        self.save()

    def set_access_token_s(self):
        self.access_token = appier.gen_token()
        self.access_token_date = time.time()
        self.save()

    def unset_access_token_s(self):
        self.access_token = None
        self.access_token_date = None
        self.save()

    def refresh_access_token_s(self):
        self.set_access_token_s()

    def get_account(self):
        return self.owner.admin_part.account_c.get(
            username = self.username
        )

    def is_expired(self):
        access_token_date = self.access_token_date or self.created
        return time.time() > access_token_date + self.expires_in

    def touch_expired(self, delete = None):
        """
        Method to be called upon the token usage so that the
        expiration for the OAuth token may be checked.

        If the verification fails it's possible to have the
        current token removed from the data source if there's
        no refresh token defined.

        :type delete: bool
        :param delete: If the token should be automatically
        removed from the data source if it's expired (any of
        the verification fails).
        """

        try:
            self.verify_expired()
        except Exception:
            if delete == None: delete = False if self.refresh_token else True
            if delete: self.delete()
            raise

    def verify_code(self, code, grant_type = "authorization_code"):
        cls = self.__class__
        appier.verify(not self.authorization_code == None)
        appier.verify(not self.authorization_code_date == None)
        appier.verify(self.authorization_code == code)
        appier.verify(time.time() - self.authorization_code_date < cls.CODE_DURATION)
        appier.verify(grant_type, "authorization_code")

    def verify_refresh(self, refresh_token, grant_type = "refresh_token"):
        appier.verify(not self.refresh_token == None)
        appier.verify(not self.refresh_token == None)
        appier.verify(self.refresh_token == refresh_token)
        appier.verify(grant_type, "refresh_token")

    def verify_expired(self):
        appier.verify(
            not self.is_expired(),
            message = "OAuth access token is expired",
            code = 403,
            exception = appier.OperationalError
        )

    def _verify(self):
        self._verify_scope()

    def _verify_scope(self):
        scope_s = set(self.scope)
        appier.verify(len(self.scope) == len(scope_s))

    def _filter_scope(self, scope):
        """
        Filters the provided sequence of tokens for the scope, so
        that only the ones allowed for the requested user are used.

        This avoid security issues like someone requesting values
        for a token that is for which the user is not allowed.

        :type scope: List
        :param scope: The list of tokens to be filtered.
        :rtype: List
        :return: The resulting filtering list containing only the
        tokens for which the impersonated user is capable.
        """

        cls = self.__class__
        account = self.get_account()
        return cls._filter_scope_g(scope, account = account)

    def _set_session(self, unset = True, safes = [], method = "set"):
        cls = self.__class__
        account = self.get_account()
        account._set_session(unset = unset, safes = safes, method = method)
        if unset: return
        set("tokens", self.tokens)
Beispiel #12
0
class Label(base.ToolisBase):

    name = appier.field(
        default = True,
        index = "hashed",
        meta = "text",
        observations = """Name of the label to be created, this should
        be as descriptive and simple as possible"""
    )

    attributes = appier.field(
        meta = "text",
        observations = """The multiple attributes that describe the label
        should describe a set of key to value associations"""
    )

    code = appier.field(
        index = "hashed",
        meta = "text",
        observations = """Internal code to be used in the barcode
        generation process"""
    )

    image = appier.field(
        type = appier.image(
            width = 500,
            height = 500,
            format = "jpeg"
        ),
        private = True,
        observations = """The image that is going to be used to visually
        describe the item associated with the label"""
    )

    image_url = appier.field(
        index = "hashed",
        meta = "image_url",
        description = "Image URL",
        observations = """The URL of the image that is currently associated,
        it should be a valid absolute value"""
    )

    category = appier.field(
        type = appier.reference(
            "Category",
            name = "name"
        ),
        observations = """The logical category to which this label belongs"""
    )

    @classmethod
    def validate(cls):
        return super(Label, cls).validate() + [
            appier.not_null("name"),
            appier.not_empty("name"),

            appier.not_duplicate("code", cls._name())
        ]

    @classmethod
    def list_names(cls):
        return ["name", "description", "code", "category"]

    @classmethod
    def order_name(cls):
        return ("id", -1)

    @classmethod
    @appier.operation(
        name = "Create",
        parameters = (
            ("Name", "name", str),
            ("Description", "description", str),
            ("Attributes", "attributes", "longtext"),
            ("Image", "file", "file"),
        )
    )
    def create_s(cls, name, description, attributes, image):
        label = cls(
            name = name,
            description = description,
            attributes = attributes,
            image = cls.image.type(image)
        )
        label.save()
        return label

    @classmethod
    @appier.link(name = "Left 30x12", context = True)
    def list_30x12_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_30x12",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Left 98x40", context = True)
    def list_98x40_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_98x40",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 40x25", context = True)
    def list_40x25_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_40x25",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 70x25", context = True)
    def list_70x25_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_70x25",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 55x45", context = True)
    def list_55x45_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_55x45",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 90x57", context = True)
    def list_90x57_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_90x57",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 100x50", context = True)
    def list_100x50_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_100x50",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Right 145x85", context = True)
    def list_145x85_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_145x85",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Vertical 25x40", context = True)
    def list_25x40_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_25x40",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Vertical 25x70", context = True)
    def list_25x70_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_25x70",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Vertical 50x100", context = True)
    def list_50x100_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_50x100",
            view = view,
            context = context,
            absolute = absolute
        )

    @classmethod
    @appier.link(name = "Vertical 85x145", context = True)
    def list_85x145_url(cls, view = None, context = None, absolute = False):
        return appier.get_app().url_for(
            "label.list_85x145",
            view = view,
            context = context,
            absolute = absolute
        )

    def post_create(self):
        base.ToolisBase.post_create(self)
        self.set_code_s()
        self.set_image_url_s()

    def post_update(self):
        base.ToolisBase.post_update(self)
        self.set_image_url_s()

    @appier.operation(name = "Set Code")
    def set_code_s(self, force = False):
        if self.code and not force: return
        prefix = appier.conf("TOOLIS_LABEL_CODE", "%09d")
        self.code = prefix % self.id
        self.save()

    @appier.operation(name = "Set Image URL")
    def set_image_url_s(self, force = False):
        if self.image_url and not force: return
        self.image_url = self.view_image_url(absolute = True)
        self.save()

    @appier.operation(
        name = "Set Name",
        parameters = (("Name", "name", appier.legacy.UNICODE),)
    )
    def set_name_s(self, name):
        if not name: return
        self.name = name
        self.save()

    @appier.operation(
        name = "Set Category",
        parameters = (
            (
                "Category",
                "category",
                appier.reference("Category", name = "name")
            ),
        )
    )
    def set_category_s(self, category):
        if not category: return
        self.category = category
        self.save()

    @appier.operation(name = "Duplicate", factory = True)
    def duplicate_s(self):
        cls = self.__class__
        instance = self.reload(rules = False)
        label = cls(
            name = instance.name,
            attributes = instance.attributes,
            image = instance.image,
            category = instance.category
        )
        label.save()
        return label

    @appier.link(name = "View Image", devel = True)
    def view_image_url(self, absolute = False):
        cls = self.__class__
        return self.owner.url_for(
            "label.image",
            id = self.id,
            absolute = absolute
        )
Beispiel #13
0
class EAccount(base.EBase):

    username = appier.field()

    password = appier.field()

    email = appier.field()

    first_name = appier.field()

    last_name = appier.field()

    gender = appier.field()

    birth_date = appier.field(type=int)

    country = appier.field()

    phone_number = appier.field()

    receive_newsletters = appier.field(type=bool, initial=False)

    avatar = appier.field(type=appier.File)

    facebook_id = appier.field()

    facebook_token = appier.field(private=True)

    google_id = appier.field()

    google_token = appier.field(private=True)

    bag = appier.field(type=appier.reference("EBag", name="id"))

    wishlist = appier.field(type=appier.reference("EWishlist", name="id"))

    def tokens(self):
        return ["user"]

    @classmethod
    def validate(cls):
        return super(EAccount, cls).validate() + [
            appier.not_null("username"),
            appier.not_empty("username"),
            appier.string_gt("username", 3),
            appier.not_duplicate("username", cls._name()),
            appier.not_null("email"),
            appier.not_empty("email"),
            appier.is_email("email"),
            appier.not_duplicate("email", cls._name()),
            appier.not_null("first_name"),
            appier.not_empty("first_name"),
            appier.is_regex("phone_number", "^\+?[0-9\s]{2,}$"),
            appier.equals("password_confirm", "password"),
            appier.equals("new_password_confirm", "new_password")
        ]

    @classmethod
    def validate_new(cls):
        return super(EAccount, cls).validate_new() + [
            appier.not_null("password"),
            appier.not_empty("password"),
            appier.not_null("password_confirm"),
            appier.not_empty("password_confirm")
        ]

    @property
    def full_name(self):
        name = self.first_name
        name += " " + self.last_name if self.last_name else ""
        return name

    @property
    def birth_date_s(self):
        if not self.birth_date: return None
        return self.string_from_timestamp(self.birth_date)