Exemplo n.º 1
0
class Contact(BaseModel, IndexedModelMixin):
    """Contact model."""

    _index_class = IndexedContact

    user_id = columns.UUID(primary_key=True)
    contact_id = columns.UUID(primary_key=True)  # clustering key

    additional_name = columns.Text()
    addresses = columns.List(columns.UserDefinedType(PostalAddress))
    avatar = columns.Text()
    date_insert = columns.DateTime()
    date_update = columns.DateTime()
    deleted = columns.Boolean(default=False)
    emails = columns.List(columns.UserDefinedType(Email))
    family_name = columns.Text()
    given_name = columns.Text()
    groups = columns.List(columns.Text)
    identities = columns.List(columns.UserDefinedType(SocialIdentity))
    ims = columns.List(columns.UserDefinedType(IM))
    infos = columns.Map(columns.Text, columns.Text)
    name_prefix = columns.Text()
    name_suffix = columns.Text()
    organizations = columns.List(columns.UserDefinedType(Organization))
    phones = columns.List(columns.UserDefinedType(Phone))
    pi = columns.UserDefinedType(PIModel)
    privacy_features = columns.Map(columns.Text(), columns.Text())
    tags = columns.List(columns.UserDefinedType(ResourceTag))
    title = columns.Text()  # computed value, read only
Exemplo n.º 2
0
class TimeSeriesModel(Model):
    __table_name__ = "time_series2"
    name = columns.Text(primary_key=True, required=True)
    data_record = columns.Map(
        key_type=columns.Text(),
        value_type=columns.UserDefinedType(DataRecordModel),
        default={})
Exemplo n.º 3
0
class UserOrderModel(Model):
    __table_name__ = "user_order5"
    account_name = columns.Text(required=True, primary_key=True)
    place_time = columns.DateTime(required=True,
                                  primary_key=True,
                                  clustering_order='ASC')
    type = columns.Text(required=True)
    code = columns.Text(required=True)
    direction = columns.Text(required=True)
    quantity = columns.Float(required=True)
    status = columns.Text(required=True)
    reason = columns.Text(required=True)
    remark = columns.Text()
    real_order_id = columns.Text()
    failed_reason = columns.Text()
    cancel_reason = columns.Text()
    ideal_price = columns.Float()

    filled_start_time = columns.DateTime()
    filled_end_time = columns.DateTime()
    filled_quantity = columns.Float()
    filled_avg_price = columns.Float()
    fee = columns.Float()
    limit_price = columns.Float()
    stop_price = columns.Float()
    execution_map = columns.Map(
        key_type=columns.Text,
        value_type=UserDefinedType(UserOrderExecutionModel),
        default={})
    # price_change_history = columns.List(value_type=UserDefinedType(PriceChangeModel), default=[])
    bargainer = columns.UserDefinedType(BargainerModel)
Exemplo n.º 4
0
class Tag(Base):
    __table_name__ = 'tags'

    bucket = columns.Text(primary_key=True, partition_key=True, required=True)
    tag = columns.Text(primary_key=True, required=True)
    transactions = columns.List(columns.UserDefinedType(TransactionObject))

    @classmethod
    def get_transaction_hashes(cls, tag):
        tag_meta = Tag.get(tag)

        if not tag_meta:
            return list()

        return [
            transaction['hash'] for transaction in tag_meta['transactions']
        ]

    @classmethod
    def get(cls, tag):
        try:
            tag = Tag.objects.get(bucket=tag[:5], tag=tag)
            return tag.as_json()
        except DoesNotExist:
            return None

    def as_json(self):
        return {'tag': self.tag, 'transactions': self.transactions}
Exemplo n.º 5
0
class Transaction(UserType, JsonMixin):
    """
    Transaction
    """
    value = columns.UserDefinedType(Amount, required=True)
    type = columns.Text(required=True)
    event_id = columns.UUID(required=True)
Exemplo n.º 6
0
class User(AbstractUser):
    """
    Users within the Flask authentication system are represented by this model.
    """
    __table_name__ = 'user'

    id = columns.UUID(primary_key=True, default=uuid.uuid4)
    profile = columns.UserDefinedType(Profile)
    address = columns.UserDefinedType(Address)
    is_verified = columns.Boolean(default=False)

    @classmethod
    def create(cls, **kwargs):
        password = kwargs.get('password')
        kwargs['password'] = cls.hash_password(password)
        return super(User, cls).create(**kwargs)
Exemplo n.º 7
0
class Approvee(Base):
    __table_name__ = 'approvees'

    bucket = columns.Text(primary_key=True, partition_key=True, required=True)
    hash = columns.Text(primary_key=True, required=True)
    approvees = columns.List(columns.UserDefinedType(TransactionObject))

    @classmethod
    def get(cls, hash):
        try:
            approvee = Approvee.objects.get(bucket=hash[:5], hash=hash)
            return approvee.as_json()
        except DoesNotExist:
            return None

    def as_json(self):
        return {'hash': self.hash, 'transactions': self.transactions}

    @classmethod
    def get_approvees_hashes(cls, hash):
        approvee_meta = Approvee.get(hash)

        if not approvee_meta:
            return list()

        return [
            transaction['hash'] for transaction in approvee_meta['approvees']
        ]
Exemplo n.º 8
0
class LogHttpRequest(Log):
    """
    Log requests
    """
    __discriminator_value__ = 'http_request'

    request = columns.UserDefinedType(Request)
    response = columns.UserDefinedType(Response)

    def __init__(self, **values):
        super(LogHttpRequest, self).__init__(**values)
        self.type = self.__discriminator_value__

    @classmethod
    def create(cls, **kwargs):
        from flask import request
        if request:
            kwargs['request'] = Request.validate_request(request)
        return super(LogHttpRequest, cls).create(**kwargs)
Exemplo n.º 9
0
class Cancellation(UserType, JsonMixin):
    """
    Cancellation
    """
    __type_name__ = 'cancellation'

    reason = columns.Text()
    user = columns.UserDefinedType(CancellationByUser)
    task = columns.UserDefinedType(CancellationByTask)
    cancelled_on = columns.DateTime()

    def __init__(self, *args, **kwargs):
        super(Cancellation, self).__init__(*args, **kwargs)
        if self.cancelled_on is None:
            self.cancelled_on = datetime.utcnow()

    @property
    def type(self):
        cancelled_by = 'user' if isinstance(self.user, CancellationByUser) else 'task'
        return '{}_by_{}'.format(self.__type_name__, cancelled_by)
Exemplo n.º 10
0
class Device(BaseModel):
    """User device."""

    user_id = columns.UUID(primary_key=True)
    device_id = columns.UUID(primary_key=True, default=uuid.uuid4)

    name = columns.Text()
    date_insert = columns.DateTime(required=True, default=datetime.utcnow)
    date_revoked = columns.DateTime()
    type = columns.Text(required=True)  # laptop, desktop, smartphone, etc
    status = columns.Text(default='unverified')
    user_agent = columns.Text()
    ip_creation = columns.Text()
    privacy_features = columns.Map(columns.Text, columns.Text)
    pi = columns.UserDefinedType(PIModel)
Exemplo n.º 11
0
class Device(BaseModel):
    """User device."""

    user_id = columns.UUID(primary_key=True)
    device_id = columns.UUID(primary_key=True, default=uuid.uuid4)

    name = columns.Text()
    signature_key = columns.Text()  # secret key for device validation
    date_insert = columns.DateTime(required=True,
                                   default=datetime.datetime.now(tz=pytz.utc))
    type = columns.Text(required=True)  # laptop, desktop, smartphone, etc
    status = columns.Text(default='unknown')
    fingerprint = columns.Text()
    last_seen = columns.DateTime(default=datetime.datetime.now(tz=pytz.utc))
    privacy_features = columns.Map(columns.Text, columns.Text)
    locations = columns.List(columns.UserDefinedType(DeviceLocation))
Exemplo n.º 12
0
class User(BaseModel):
    """User main model."""

    user_id = columns.UUID(primary_key=True, default=uuid.uuid4)
    name = columns.Text(required=True)
    password = columns.Text(required=True)
    date_insert = columns.DateTime()
    given_name = columns.Text()
    family_name = columns.Text()
    params = columns.Map(columns.Text, columns.Text)
    contact_id = columns.UUID()
    main_user_id = columns.UUID()
    recovery_email = columns.Text(required=True)
    local_identities = columns.List(columns.Text())

    privacy_features = columns.Map(columns.Text(), columns.Text())
    pi = columns.UserDefinedType(PIModel)
Exemplo n.º 13
0
class Address(Base):
    __table_name__ = 'addresses'

    bucket = columns.Text(primary_key=True, partition_key=True, required=True)
    address = columns.Text(primary_key=True, required=True)
    transactions = columns.List(columns.UserDefinedType(TransactionObject))

    @classmethod
    def get(cls, address):
        try:
            address = Address.objects.get(bucket=address[:5], address=address)
            return address.as_json()
        except DoesNotExist:
            return None

    def as_json(self):
        return {'address': self.address, 'transactions': self.transactions}
Exemplo n.º 14
0
class Bundle(Base):
    __table_name__ = 'bundles'

    bucket = columns.Text(primary_key=True, partition_key=True, required=True)
    bundle = columns.Text(primary_key=True, required=True)
    transactions = columns.List(columns.UserDefinedType(TransactionObject))

    @classmethod
    def get(cls, bundle):
        try:
            bundle = Bundle.objects.get(bucket=bundle[:5], bundle=bundle)
            return bundle.as_json()
        except DoesNotExist:
            return None

    def as_json(self):
        return {'bundle': self.bundle, 'transactions': self.transactions}
Exemplo n.º 15
0
 class UserModelText(Model):
     id = columns.Text(primary_key=True)
     info = columns.UserDefinedType(User)
Exemplo n.º 16
0
class CurrentAccount(Account):
    """
    CurrentAccount
    """
    __discriminator_value__ = 'current'
    available = columns.UserDefinedType(Amount)
    pending = columns.Map(columns.UUID, columns.UserDefinedType(Operation))

    # --------------
    # Super Methods
    # --------------
    def save(self):
        """
        Note: convert key UUID to <type 'str'> in self.pending
        """
        for o in self.pending:
            if isinstance(o, uuid.UUID):
                self.pending[o.__str__()] = self.pending.pop(o)
        return super(CurrentAccount, self).save()

    @classmethod
    def create(cls, **kwargs):
        kwargs['available'] = Amount(amount=0, currency=DEFAULT_CURRENCY[0])
        return super(CurrentAccount, cls).create(**kwargs)

    # --------------
    # Super Methods END
    # --------------

    # --------------
    # Properties
    # --------------
    @property
    def pending_debits(self):
        return sum([
            operation.value.amount for operation in self.pending.values()
            if operation.type == 'debit'
        ])

    @property
    def pending_credits(self):
        return sum([
            operation.value.amount for operation in self.pending.values()
            if operation.type == 'credit'
        ])

    @property
    def net(self):
        total = self.available.amount - self.pending_debits
        return Amount(amount=total, currency=self.available.currency)

    @property
    def balance(self):
        total = self.available.amount - self.pending_debits + self.pending_credits
        return Amount(amount=total, currency=self.available.currency)

    @property
    def has_funds(self):
        return self.net.amount >= 0

    # --------------
    # Properties END
    # --------------

    # --------------
    # Methods
    # --------------
    def _pop_pending(self, id=None):
        try:
            return self.pending.pop(id)
        except KeyError as e:
            logger.error('No pending operation found with key {}'.format(e))
            return Response(error=FAILURE_TRANSACTION_OPERATION_ERROR)

    def execute_pending(self, id=None):
        o = self._pop_pending(id)
        if isinstance(o, Response):
            return o
        # make transaction amount available
        self.available.update(o)
        return Response()

    def cancel_pending(self, id=None):
        o = self._pop_pending(id)
        if isinstance(o, Response):
            return o
        return Response()
Exemplo n.º 17
0
 class Container(Model):
     id = columns.UUID(primary_key=True, default=uuid4)
     names = columns.List(columns.UserDefinedType(Name))
Exemplo n.º 18
0
class Transfer(AbstractBaseModel, TaskQueueMixin, MachineMixin):
    """
    Transfer
    """
    __table_name__ = 'transfer'

    id = columns.UUID(primary_key=True, default=uuid.uuid4)
    description = columns.Text()
    value = columns.UserDefinedType(Amount, required=True)
    account_id = columns.UUID(required=True)
    destination_id = columns.UUID(required=True)
    # signatures
    signatures = columns.Map(columns.Text, columns.Text)
    #
    type = columns.Text(discriminator_column=True)
    status = columns.TinyInt(default=TRANSFER_CREATED[0])
    # reverse
    reversed = columns.Boolean(default=False)
    value_reversed = columns.UserDefinedType(Amount)
    # failure
    failure_code = columns.SmallInt()
    # cancellation data
    cancellation_data = columns.UserDefinedType(Cancellation)
    # tasks
    tasks = columns.Map(columns.Text, columns.Text)

    def __init__(self, *args, **kwargs):
        super(Transfer, self).__init__(*args, **kwargs)
        self._init_machine()

    # ---------------
    # Machine Methods
    # ---------------
    def _init_machine(self):
        """
        Method to hook a state machine to the instance
        """
        states = list(TRANSFER_STATUS_STRING_CHOICES)
        transitions = TRANSFER_STATE_TRANSITIONS
        self.machine = Machine(model=self, states=states, transitions=transitions,
                               auto_transitions=False, send_event=True,
                               initial=TRANSFER_STATUS_MAP[self.status],
                               after_state_change='_state_changed')

    def _state_changed(self, event):
        """
        callback from state machine to change status on instance and persist
        :param event: EventData
        :return:
        """
        self.status = TRANSFER_STATUS_STRING_MAP[event.state.name]
        persist = event.kwargs.get('persist', False)
        if persist:
            self.save()

    def _is_txn_valid(self, txn=None):
        return txn is not None and self.id == txn.source_id

    def _get_act_txn(self, event):
        act_txn = event.kwargs.get('act_txn')
        if self._is_txn_valid(act_txn):
            return act_txn

        act_txn = DebitAccountTransaction.objects.filter(account_id=self.account_id).get()
        if self._is_txn_valid(act_txn):
            return act_txn

        if act_txn is None:
            raise AccountTransactionNotAvailable

    def _get_dst_txn(self, event):
        dst_txn = event.kwargs.get('dst_txn')
        if self._is_txn_valid(dst_txn):
            return dst_txn

        dst_txn = CreditAccountTransaction.objects.filter(account_id=self.destination_id).get()
        if self._is_txn_valid(dst_txn):
            return dst_txn

        if dst_txn is None:
            raise DestinationTransactionNotAvailable

    def set_account_signature(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        act_signature = event.kwargs.get('act_signature')
        # TODO is signature valid
        if act_signature:
            self.signatures['act_signature'] = act_signature

    def set_destination_signature(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        dst_signature = event.kwargs.get('dst_signature')
        # TODO is signature valid
        if dst_signature:
            self.signatures['dst_signature'] = dst_signature

    def has_valid_account_signature(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        signature = self.signatures.get('act_signature')
        # TODO is signature valid
        if signature is not 'signature':
            self.failure_code = FAILURE_INVALID_ACCOUNT_SIGNATURE[0]
            return False
        return True

    def has_valid_destination_signature(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        signature = self.signatures.get('dst_signature')
        # TODO is signature valid
        if signature is not 'signature':
            self.failure_code = FAILURE_INVALID_DESTINATION_SIGNATURE[0]
            return False
        return True

    def has_transaction_account_succeed(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        act_txn = self._get_act_txn(event)
        if act_txn.is_succeed():
            return True
        if act_txn.is_failed():
            self.failure_code = FAILURE_INVALID_ACCOUNT_OPERATION_ERROR[0]
        return False

    def has_transaction_destination_succeed(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        dst_txn = self._get_dst_txn(event)
        if dst_txn.is_succeed():
            return True
        if dst_txn.is_failed():
            self.failure_code = FAILURE_INVALID_ACCOUNT_OPERATION_ERROR[0]
        return False

    def has_failure_code(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        return self.failure_code is not None

    def set_cancellation_data(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        reason = event.kwargs.get('reason')
        if reason is None:
            raise ReasonNotAvailable

        user = event.kwargs.get('user')
        if user is not None:
            self.cancellation_data = Cancellation(reason=reason, user=CancellationByUser(id=user.id))
            return

        queue_name = event.kwargs.get('queue_name')
        task_name = event.kwargs.get('task_name')
        if queue_name is not None and task_name is not None:
            task = CancellationByTask(name=task_name, queue_name=queue_name)
            cancellation = Cancellation(reason=reason, task=task)
            self.cancellation_data = cancellation

    def has_cancellation_data(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        return self.cancellation_data.type is not None

    def execute_cancel(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        if self.has_cancellation_data(event):
            persist = event.kwargs.get('persist', False)
            #
            act_txn = self._get_act_txn(event)
            act_txn = self._cancel_txn(act_txn, persist)
            event.kwargs.update({'act_txn': act_txn})
            #
            dst_txn = self._get_dst_txn(event)
            dst_txn = self._cancel_txn(dst_txn, persist)
            event.kwargs.update({'dst_txn': dst_txn})

    def remove_expired_task(self, event, **kwargs):
        """

        :param args:
        :param kwargs:
        :return:
        """
        task_name = self.tasks.get('cancel')
        if task_name:
            queue_name = self.__table_name__
            self.remove_task(queue_name=queue_name, name=task_name)
            del self.tasks['cancel']

    # ---------------
    # Task Methods
    # ---------------
    def create_expired_task(self):
        kwargs = dict()
        action = 'cancel'
        url_params = {'id': self.id, 'action': action}
        url = url_for('tasks.transfer_actions', **url_params)
        kwargs['queue_name'] = self.__table_name__
        kwargs['method'] = 'PUT'
        kwargs['url'] = url
        kwargs['eta'] = datetime.utcnow() + timedelta(hours=24)
        kwargs['payload'] = urllib.urlencode({'action': action,
                                              'metadata': json.dumps({'reason': 'expired'})})
        # context['target'] = modules.get_current_module_name()
        task = self.add_task(**kwargs)
        if isinstance(task, taskqueue.Task):
            self.tasks['cancel'] = task.name