コード例 #1
0
    def delete(self, request, rss):

        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Get rss entry
        try:
            rss_model = RSS.objects.get(name=rss)
        except:
            return build_response(request, 404, 'Not found')

        # Delete provider limits
        rss_factory = RSSManagerFactory(rss_model)

        exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)
        call_result = _make_rss_request(exp_manager, exp_manager.delete_provider_limit, request.user)

        if call_result[0]:
            return build_response(request, call_result[1], call_result[2])

        # Delete rs models
        model_manager = rss_factory.get_model_manager(request.user.userprofile.access_token)
        call_result = _make_rss_request(model_manager, model_manager.delete_provider_models, request.user)

        if call_result[0]:
            return build_response(request, call_result[1], call_result[2])

        # Delete rss model
        rss_model.delete()
        return build_response(request, 204, 'No content')
コード例 #2
0
def build_rs_model(offering):

    # Get RSS object
    if not len(RSS.objects.all()):
        return

    rss = RSS.objects.all()[0]

    if rss.api_version == 1:
        return

    rss_factory = RSSManagerFactory(rss)
    model_manager = rss_factory.get_model_manager(rss.access_token)

    # Build basic RS model
    # Get applied class
    revenue_class = None
    for plan in (offering.offering_description['pricing']['price_plans']):
        if 'price_components' in plan:

            for comp in plan['price_components']:
                if 'price_function' in comp:
                    revenue_class = 'use'
                    break

                try:
                    unit = Unit.objects.get(name=comp['unit'])
                except:
                    raise Exception('Unsupported unit in price plan model')

                if unit.defined_model == 'pay per use':
                    revenue_class = 'use'
                    break
                elif unit.defined_model == 'subscription':
                    revenue_class = 'subscription'
                elif unit.defined_model == 'single payment' and revenue_class is None:
                    revenue_class = 'single-payment'

        if revenue_class == 'use':
            break

    if revenue_class is not None:
        # Create new provider in the RSS
        prov_manager = rss_factory.get_provider_manager(rss.access_token)
        provider_info = {
            'provider_id': offering.owner_organization.actor_id,
            'provider_name': offering.owner_organization.name
        }
        try:
            prov_manager.register_provider(provider_info)
        except HTTPError as e:
            if e.code == 401:
                rss.refresh_token()
                prov_manager.set_credentials(rss.access_token)
                try:
                    prov_manager.register_provider(provider_info)
                except:
                    pass

        model_info = {}
        for model in rss.revenue_models:
            if model.revenue_class == revenue_class:
                model_info['aggregatorValue'] = model.percentage
                break

        model_info['ownerValue'] = 100 - model_info['aggregatorValue']
        model_info['productClass'] = offering.owner_organization.name + '/' + offering.name + '/' + offering.version

        try:
            model_manager.create_revenue_model(model_info, offering.owner_organization.actor_id)
        except HTTPError as e:
            if e.code == 401:
                rss.refresh_token()
                model_manager.set_credentials(rss.access_token)
                model_manager.create_revenue_model(model_info, offering.owner_organization.actor_id)
            else:
                raise Exception('Revenue Sharing model for offering ' + offering.owner_organization.name + ' ' + offering.name + ' ' + offering.version)
コード例 #3
0
    def update(self, request, rss):
        """
        Makes a partial update, only name, limits and default selection
        """
        # Check if the user is staff
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Check rss
        try:
            rss_model = RSS.objects.get(name=rss)
        except:
            return build_response(request, 404, 'Not found')

        # Get data
        try:
            data = json.loads(request.raw_post_data)
        except:
            return build_response(request, 400, 'Invalid JSON data')

        # Check the name
        if 'name' in data and data['name'].lower() != rss.lower():
            # Check that the name does not exist
            exist = True
            try:
                RSS.objects.get(name=data['name'])
            except:
                exist = False

            if exist:
                return build_response(request, 400, 'The selected name is in use')

            rss_model.name = data['name']
            rss_model.save()

        limits = {}
        # Check if limits has been provided
        if 'limits' in data:
            limits = _check_limits(data['limits'])

        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        # Update expenditure limits
        rss_factory = RSSManagerFactory(rss_model)
        if limits:
            old_limits = rss_model.expenditure_limits
            rss_model.expenditure_limits = limits
            rss_model.save()
            # Make the update request
            exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)
            call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

            if call_result[0]:
                # Reset expenditure limits
                rss_model.expenditure_limits = old_limits
                return build_response(request, call_result[1], call_result[2])

        # Update revenue sharing models
        if len(sharing_models):
            rss_model.revenue_models = []

            if rss_model.api_version == 1:
                model_manager = rss_factory.get_model_manager(request.user.userprofile.access_token)

            # Update the models
            for model in sharing_models:
                revenue_model = RevenueModel(
                    revenue_class=model['class'],
                    percentage=Decimal(model['percentage'])
                )

                if rss_model.api_version == 1:
                    def call_model_creation():
                        model_manager.update_revenue_model(model)

                    call_result = _make_rss_request(model_manager, call_model_creation, request.user)

                    if call_result[0]:
                        return build_response(request, call_result[1], call_result[2])

                rss_model.revenue_models.append(revenue_model)

        # Update credentials
        rss_model.access_token = request.user.userprofile.access_token
        rss_model.refresh_token = request.user.userprofile.refresh_token

        # Save the model
        rss_model.save()

        return build_response(request, 200, 'OK')
コード例 #4
0
    def create(self, request):

        # Only the admin can register new RSS instances
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        if 'name' not in data or 'host' not in data or 'api_version' not in data:
            msg = 'RSS creation error: Missing a required field'

            if 'name' not in data:
                msg += ', name'

            if 'host' not in data:
                msg += ', host'

            if 'api_version' not in data:
                msg += ', api_version'

            return build_response(request, 400, msg)

        # Check name regex
        if not is_valid_id(data['name']):
            return build_response(request, 400, 'RSS creation error: Invalid name format')

        # Check url regex
        if not is_valid_url(data['host']):
            return build_response(request, 400, 'RSS creation error: Invalid URL format')

        # Check api_version format
        try:
            api_version = int(data['api_version'])
        except:
            return build_response(request, 400, 'RSS creation error: Invalid api_version format, must be an integer (1 or 2)')

        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'RSS creation error: Invalid api_version, must be 1 or 2')

        # Check if the information provided is not already registered
        if len(RSS.objects.all()) > 0:
            return build_response(request, 409, 'RSS creation error: There is a RSS instance already registered')

        limits = {}
        cont = Context.objects.all()[0]

        # Check request limits
        if 'limits' in data:
            try:
                limits = _check_limits(data['limits'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        if not len(limits):
            # Set default limits
            limits = {
                'currency': cont.allowed_currencies['default'],
                'perTransaction': 10000,
                'weekly': 100000,
                'daily': 10000,
                'monthly': 100000
            }

        # Check revenue sharing models
        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))
        else:
            # Set default revenue models
            sharing_models = [{
                'class': 'single-payment',
                'percentage': 10.0
            }, {
                'class': 'subscription',
                'percentage': 20.0
            }, {
                'class': 'use',
                'percentage': 30.0
            }]

        # Build revenue models
        db_revenue_models = []
        for model in sharing_models:
            db_revenue_models.append(RevenueModel(
                revenue_class=model['class'],
                percentage=Decimal(model['percentage'])
            ))

        if not data['host'].endswith('/'):
            data['host'] += '/'

        # Create the new entry
        rss = RSS.objects.create(
            name=data['name'],
            host=data['host'],
            api_version=api_version,
            expenditure_limits=limits,
            revenue_models=db_revenue_models,
            aggregator_id=request.user.email
        )

        rss_factory = RSSManagerFactory(rss)

        # Create a new provider if needed
        if api_version == 2:
            prov_manager = rss_factory.get_provider_manager(request.user.userprofile.access_token)
            provider_info = {
                'provider_id': settings.STORE_NAME.lower() + '-provider',
                'provider_name': settings.STORE_NAME + '-Provider'
            }
            call_result = _make_rss_request(prov_manager, prov_manager.register_provider, request.user, provider_info)

            if call_result[0]:
                rss.delete()
                # Return error response
                return build_response(request, call_result[1], call_result[2])

        exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)

        # Create default expenditure limits
        call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

        if call_result[0]:
            rss.delete()
            # Return error response
            return build_response(request, call_result[1], call_result[2])

        # Create default revenue sharing models
        if api_version == 1:
            model_manager = rss_factory.get_model_manager(rss, request.user)

            model_created = False
            for model in sharing_models:
                def call_model_creation():
                    model_manager.create_revenue_model(model)

                call_result = _make_rss_request(model_manager, call_model_creation, request.user)

                if call_result[0] and not model_created:
                    rss.delete()
                    return build_response(request, call_result[1], call_result[2])
                elif not call_result[0]:
                    model_created = True

        # The request has been success so the used credentials are valid
        # Store the credentials for future access
        rss.access_token = request.user.userprofile.access_token
        rss.refresh_token = request.user.userprofile.refresh_token
        rss.save()

        return build_response(request, 201, 'Created')