def delay_task(task,
               kwargs=None,
               args=None,
               force_simulate=False,
               queue='high-priority'):
    if current_app.config['ENABLE_SIMULATOR_MODE'] or force_simulate:
        return worker_simulator.simulate(task, kwargs, args, queue)
    signature = celery_app.signature(task, kwargs=kwargs, args=args)
    async_result = signature.apply_async(queue=queue)
    return async_result
Exemple #2
0
def save_photo_and_check_for_duplicate(url, new_filename, image_id):
    save_to_s3_from_url(url, new_filename)

    try:
        rekognition_task = celery_app.signature('worker.celery_tasks.check_for_duplicate_person',
                                                args=(new_filename, image_id))
        # TODO: Standardize this task (pipe through execute_synchronous_celery)
        rekognition_task.delay()
    except Exception as e:
        print(e)
        sentry_sdk.capture_exception(e)
        pass
Exemple #3
0
def save_photo_and_check_for_duplicate(url, new_filename, image_id):

    save_to_s3_from_url(url, new_filename)

    try:
        rekognition_task = celery_app.signature(
            'worker.celery_tasks.check_for_duplicate_person',
            args=(new_filename, image_id))

        rekognition_task.delay()
    except Exception as e:
        print(e)
        sentry.captureException()
        pass
Exemple #4
0
    def location(self, location):

        self._location = location

        if location is not None and location is not '':

            try:
                task = {'user_id': self.id, 'address': location}
                geolocate_task = celery_app.signature(
                    'worker.celery_tasks.geolocate_address', args=(task, ))

                geolocate_task.delay()
            except Exception as e:
                print(e)
                sentry.captureException()
                pass
Exemple #5
0
    def ip(self, ip):

        self._ip = ip

        if ip is not None:

            try:
                task = {'ip_address_id': self.id, 'ip': ip}
                ip_location_task = celery_app.signature(
                    'worker.celery_tasks.ip_location', args=(task, ))

                ip_location_task.delay()
            except Exception as e:
                print(e)
                sentry.captureException()
                pass
def get_usd_to_satoshi_rate():

    blockchain_task = celery_app.signature(
        'worker.celery_tasks.get_usd_to_satoshi_rate')
    # TODO: Convert to task_runner
    result = blockchain_task.apply_async()

    try:
        conversion_rate = result.wait(timeout=3, propagate=True, interval=0.5)

    except Exception as e:
        print(e)
        sentry_sdk.capture_exception(e)
        raise BlockchainError("Blockchain Error")

    finally:
        result.forget()

    return conversion_rate
Exemple #7
0
    def send_blockchain_payload_to_worker(self, is_retry=False):
        if self.transfer_type == TransferTypeEnum.DISBURSEMENT:

            if self.recipient_user and self.recipient_user.transfer_card:

                self.recipient_user.transfer_card.update_transfer_card()

            master_wallet_approval_status = self.recipient_transfer_account.master_wallet_approval_status

            elapsed_time('4.3.2: Approval Status calculated')

            if master_wallet_approval_status in ['NO_REQUEST', 'FAILED']:
                account_to_approve_pk = self.recipient_transfer_account.blockchain_address.encoded_private_key
            else:
                account_to_approve_pk = None

            blockchain_payload = {
                'type': 'DISBURSEMENT',
                'credit_transfer_id': self.id,
                'transfer_amount': self.transfer_amount,
                'recipient':
                self.recipient_transfer_account.blockchain_address.address,
                'account_to_approve_pk': account_to_approve_pk,
                'master_wallet_approval_status': master_wallet_approval_status,
                'uncompleted_tasks': list(self.uncompleted_blockchain_tasks),
                'is_retry': is_retry
            }

            elapsed_time('4.3.3: Payload made')

        elif self.transfer_type == TransferTypeEnum.PAYMENT:

            if self.recipient_transfer_account:
                recipient = self.recipient_transfer_account.blockchain_address.address
            else:
                recipient = self.recipient_blockchain_address.address

            try:
                master_wallet_approval_status = self.recipient_transfer_account.master_wallet_approval_status

            except AttributeError:
                master_wallet_approval_status = 'NOT_REQUIRED'

            if master_wallet_approval_status in ['NO_REQUEST', 'FAILED']:
                account_to_approve_pk = self.recipient_transfer_account.blockchain_address.encoded_private_key
            else:
                account_to_approve_pk = None

            blockchain_payload = {
                'type': 'PAYMENT',
                'credit_transfer_id': self.id,
                'transfer_amount': self.transfer_amount,
                'sender':
                self.sender_transfer_account.blockchain_address.address,
                'recipient': recipient,
                'account_to_approve_pk': account_to_approve_pk,
                'master_wallet_approval_status': master_wallet_approval_status,
                'uncompleted_tasks': list(self.uncompleted_blockchain_tasks),
                'is_retry': is_retry
            }

        elif self.transfer_type == TransferTypeEnum.WITHDRAWAL:

            master_wallet_approval_status = self.sender_transfer_account.master_wallet_approval_status

            if master_wallet_approval_status == 'NO_REQUEST':
                account_to_approve_pk = self.sender_transfer_account.blockchain_address.encoded_private_key
            else:
                account_to_approve_pk = None

            blockchain_payload = {
                'type': 'WITHDRAWAL',
                'credit_transfer_id': self.id,
                'transfer_amount': self.transfer_amount,
                'sender':
                self.sender_transfer_account.blockchain_address.address,
                'recipient': current_app.config['ETH_OWNER_ADDRESS'],
                'account_to_approve_pk': account_to_approve_pk,
                'master_wallet_approval_status': master_wallet_approval_status,
                'uncompleted_tasks': list(self.uncompleted_blockchain_tasks),
                'is_retry': is_retry
            }

        else:
            raise InvalidTransferTypeException("Invalid Transfer Type")

        if not is_retry or len(blockchain_payload['uncompleted_tasks']) > 0:
            try:
                blockchain_task = celery_app.signature(
                    'worker.celery_tasks.make_blockchain_transaction',
                    kwargs={'blockchain_payload': blockchain_payload})
                blockchain_task.delay()

            except Exception as e:
                print(e)
                sentry.captureException()
                pass
Exemple #8
0
def master_wallet_funds_available(allowed_cache_age_seconds=60):
    """
    IF refreshing cash THEN:
        return: [current blockchain balance] - [all transfers with blockchain state pending or unknown]
        save to cache: [funds available at last cache], [ID of highest transfer used in cache], [cache creation datetime]
    ELSE
        return: [funds available at last cache] - [all non-failed transfers since cache created]
    :param allowed_cache_age_seconds: how long between checking the blockchain for external funds added or removed
    :return: amount of funds available
    """

    refresh_cache = False
    funds_available_cache = red.get('funds_available_cache')

    try:
        parsed_cache = json.loads(funds_available_cache)

        last_updated_datetime = datetime.datetime.fromtimestamp(
            float(parsed_cache['last_updated']))

        earliest_allowed = datetime.datetime.utcnow() - datetime.timedelta(
            seconds=allowed_cache_age_seconds)
        if last_updated_datetime < earliest_allowed:
            refresh_cache = True

    except Exception as e:
        refresh_cache = True

    if refresh_cache:

        blockchain_task = celery_app.signature(
            'worker.celery_tasks.get_master_balance')

        result = blockchain_task.apply_async()

        try:
            master_wallet_balance = result.wait(timeout=6,
                                                propagate=True,
                                                interval=0.5)

        except Exception as e:
            print(e)
            sentry.captureException()
            raise BlockchainError("Blockchain Error")

        finally:
            result.forget()

        highest_transfer_id_checked = 0
        required_blockchain_statuses = ['PENDING', 'UNKNOWN']

    else:
        cached_funds_available = parsed_cache['cached_funds_available']
        highest_transfer_id_checked = parsed_cache[
            'highest_transfer_id_checked']
        required_blockchain_statuses = ['PENDING', 'UNKNOWN', 'COMPLETE']

    new_dibursements = (models.CreditTransfer.query.filter(
        models.CreditTransfer.transfer_type ==
        models.TransferTypeEnum.DISBURSEMENT).filter(
            models.CreditTransfer.transfer_status ==
            models.TransferStatusEnum.COMPLETE).filter(
                models.CreditTransfer.id > highest_transfer_id_checked
            ).filter(
                models.CreditTransfer.created > datetime.datetime.utcnow() -
                datetime.timedelta(hours=36)).all())

    local_disbursement_value = 0
    for disbursement in new_dibursements:

        status = disbursement.blockchain_status

        if status in required_blockchain_statuses:
            local_disbursement_value += disbursement.transfer_amount

    if refresh_cache:

        balance = master_wallet_balance - local_disbursement_value

        if len(new_dibursements) > 0:
            highest_transfer_id_checked = new_dibursements[-1].id
        else:
            all_transfers = models.CreditTransfer.query.all()
            if len(all_transfers) > 0:
                highest_transfer_id_checked = all_transfers[-1].id
            else:
                highest_transfer_id_checked = 0

        cache_data = {
            'cached_funds_available': balance,
            'highest_transfer_id_checked': highest_transfer_id_checked,
            'last_updated': datetime.datetime.utcnow().timestamp()
        }

        red.set('funds_available_cache', json.dumps(cache_data))

        balance = master_wallet_balance - local_disbursement_value

        return balance

    else:

        balance = cached_funds_available - local_disbursement_value

        return balance
Exemple #9
0
    def post(self):

        post_data = request.get_json()

        call = post_data.get('call')

        if call == 'CREATE_RESPONSE':

            transaction_hash = post_data.get('transaction_hash')

            if transaction_hash is None:
                response_object = {
                    'message': 'No transaction hash supplied',
                }

                return make_response(jsonify(response_object)), 400

            transaction = BlockchainTransaction.query.filter_by(
                hash=transaction_hash).first()
            if transaction is None:
                response_object = {
                    'message':
                    'Transaction not found for hash {}'.format(
                        transaction_hash),
                }

                return make_response(jsonify(response_object)), 405

            credit_transfer_id = transaction.credit_transfer_id

            if credit_transfer_id is None:
                response_object = {
                    'message':
                    'No credit transfer id for hash {}'.format(
                        transaction_hash),
                }

                return make_response(jsonify(response_object)), 404

            blockchain_task = celery_app.signature(
                'worker.celery_tasks.create_transaction_response',
                kwargs={
                    'previous_result': {
                        'transaction_hash': transaction_hash
                    },
                    'credit_transfer_id': credit_transfer_id
                })
            blockchain_task.delay()

            response_object = {
                'message': 'Starting Create Response',
            }

            return make_response(jsonify(response_object)), 200

        elif call == 'COMPLETE_TASKS':

            credit_transfer_id = post_data.get('credit_transfer_id')

            if credit_transfer_id is None:
                response_object = {
                    'message': 'No credit transfer id supplied',
                }

                return make_response(jsonify(response_object)), 400

            credit_transfer = CreditTransfer.query.get(credit_transfer_id)

            if credit_transfer is None:
                response_object = {
                    'message': 'No credit transfer not found',
                }

                return make_response(jsonify(response_object)), 404

            credit_transfer.send_blockchain_payload_to_worker(is_retry=True)

            response_object = {
                'message': 'Starting Complete Tasks',
            }

            return make_response(jsonify(response_object)), 200

        response_object = {
            'message': 'Call not recognised',
        }

        return make_response(jsonify(response_object)), 400
Exemple #10
0
def delay_task(task, kwargs=None, args=None, force_simulate=False):
    if current_app.config['ENABLE_SIMULATOR_MODE'] or force_simulate:
        return worker_simulator.simulate(task, kwargs, args)
    signature = celery_app.signature(task, kwargs=kwargs, args=args)
    async_result = signature.delay()
    return async_result
 def set_ip_location(ip_address_id, ip):
     # TODO: Standardize this task (pipe through execute_synchronous_celery)
     task = {'ip_address_id': ip_address_id, 'ip': ip}
     ip_location_task = celery_app.signature(
         'worker.celery_tasks.ip_location', args=(task, ))
     ip_location_task.delay()