Пример #1
0
def report_user_usage(email):
    user = User.get_by_email(email)
    if not user:
        raise exceptions.UserNotFoundException(email)
    for application in user.application_set.all():
        changes = AllocationChange.objects.filter(
            application=application).filter(billed=False)
        if changes.count() < 1:
            continue
        log_info_message("for application %s, reporting %s changes" %
                         (application, changes.count()))
        for chargable in Chargable.objects.all():
            total_seconds = 0.0
            total_cents = 0.0
            # only look at allocs from before one minute ago
            now = datetime.datetime.now() - datetime.timedelta(seconds=60)
            allocs = list(
                changes.filter(chargable=chargable).filter(
                    timestamp__lt=now).order_by('-timestamp'))
            if len(allocs) < 1:
                continue
            latest = allocs[-1]
            latest_copy = AllocationChange(application=application,
                                           chargable=chargable,
                                           quantity=latest.quantity,
                                           timestamp=now)
            latest_copy.save()
            allocs.insert(0, latest_copy)
            for alloc in allocs:
                if alloc == latest_copy:
                    continue
                diff = (now - alloc.timestamp).seconds
                if chargable.component == Chargable.components[
                        'application_processes']:
                    # the (alloc.quantity - 1) is to ensure the first process is free
                    price = (diff * (alloc.quantity - 1) *
                             (chargable.price / 3600.0))
                else:
                    price = (diff * (alloc.quantity) *
                             (chargable.price / 3600.0))
                total_cents += price
                total_seconds += diff
                now = alloc.timestamp
                alloc.billed = True
            total_hours = (total_seconds / 3600) + 1
            result = report_usage(user,
                                  total_cents,
                                  memo="%s hours for %s" %
                                  (total_hours, chargable))
            if result:
                [alloc.save() for alloc in allocs]
                be = BillingEvent(email=email,
                                  customer_id=user.customer_id,
                                  application_name=application.name,
                                  chargable_name=str(chargable),
                                  cents=total_cents,
                                  success=True,
                                  memo="devpayments dump: %s" % str(result))
                be.save()
                log_info_message(
                    "Reported %s cents for %s for application %s" %
                    (total_cents, chargable, application.name))
            else:
                be = BillingEvent(email=email,
                                  customer_id=user.customer_id,
                                  application_name=application.name,
                                  chargable_name=str(chargable),
                                  cents=total_cents,
                                  success=False,
                                  memo="devpayments dump: %s" % str(result))
                be.save()
                log_error_message(
                    "Reporting failed for %s cents for %s for application %s: %s"
                    % (total_cents, chargable, application.name, result))
Пример #2
0
def update_billing_info(email, info):
    def _unpack_customer_info():
        return {
            'first_name': info.get('first_name', ''),
            'last_name': info.get('last_name', ''),
            'email': email
        }

    def _unpack_billing_info():
        return {
            'number': info['cc_number'],
            'exp_month': info['expiration_month'],
            'exp_year': info['expiration_year'],
            'cvc': info['cvv']
        }

    def _create_new_customer():
        devpay = devpayments.Client(DEVPAYMENTS_API_KEY)
        try:
            result = devpay.createCustomer(
                mnemonic=_unpack_customer_info()['email'],
                card=_unpack_billing_info())
            user.customer_id = result.id
            user.save()
        except DevPayException as e:
            return e.message
        return True

    def _update_customer():
        devpay = devpayments.Client(DEVPAYMENTS_API_KEY)
        try:
            result = devpay.updateCustomer(
                id=user.customer_id,
                mnemonic=_unpack_customer_info()['email'],
                card=_unpack_billing_info())
            user.customer_id = result.id
            user.save()
        except DevPayException as e:
            return e.message
        return True

    user = User.get_by_email(email)
    if not user:
        raise exceptions.UserNotFoundException(email)
    message = True
    if user.customer_id == '-1' or user.customer_id == '':
        try:
            result = _create_new_customer()
            if True != result:
                message = result
        except Exception as e:
            log_error_message(e)
            return "Our system encountered an error.  Please contact [email protected]."
    else:
        try:
            result = _update_customer()
            if True != result:
                message = result
        except Exception as e:
            log_error_message(e)
            return "Our system encountered an error.  Please contact [email protected]."

    try:
        cust_info = _unpack_customer_info()
        user.first_name = cust_info.get('first_name', '')
        user.last_name = cust_info.get('last_name', '')
        user.save()
    except Exception as e:
        log_error_message(e)
        return "Our system encountered an error.  Please contact [email protected]."
    return message
Пример #3
0
def add_application(application_name, email, pubkey):
    """ Add the application specified by application_name and a corresponding database, owned by the user with the email address specified. """

    # Claim the application name
    ActiveApplicationName(name=application_name).save()

    user = User.get_by_email(email)

    # generate a secure password
    db_password = gen_password()

    # create the application row
    app = Application()
    app.name = application_name
    app.account = user
    app.db_name = application_name
    app.db_username = application_name
    app.db_password = db_password
    app.db_host = DEFAULT_DATABASE_HOST
    app.num_procs = 1
    app.save()

    # generate user and group ids to run as
    uids_gid = gen_uids_gid(app.id)
    app.setup_uid = uids_gid['setup_uid']
    app.web_uid   = uids_gid['web_uid']
    app.cron_uid  = uids_gid['cron_uid']
    app.app_gid   = uids_gid['app_gid']
    app.save()

    # enable git push
    create_git_repository(application_name)
    add_ssh_public_key(user, pubkey)

    # allocate a proxycache host for the application -- improve on this later
    ProxyCache(application = app, host = DEFAULT_PROXYCACHE_HOST).save()

    # assign virtualhost on which to listen for application
    VirtualHost(application = app, virtualhost = application_name + '.djangy.com').save()

    # allocate the application to a worker host
    # Note: this must happen after ProxyCache and VirtualHost are filled in. 
    allocate_workers(app)

    # create the database
    db = _mysql.connect(
        host = DEFAULT_DATABASE_HOST,
        user = DATABASE_ROOT_USER, 
        passwd = DATABASE_ROOT_PASSWORD)

    try: # try to remove the user if it already exists
        db.query(""" DROP USER '%s'@'%%';""" % application_name)
    except:
        pass

    db.query("""
        CREATE USER '%s'@'%%' IDENTIFIED BY '%s';""" % (application_name, db_password))

    try: # try to drop the database in case it exists
        db.query(""" DROP DATABASE %s;""" % application_name)
    except:
        pass

    db.query("""
        CREATE DATABASE %s;""" % application_name)

    db.query("""
        USE %s""" % application_name)

    db.query("""
        GRANT ALL ON %s.* TO '%s'@'%%';""" % (application_name, application_name))

    return True
Пример #4
0
def report_user_usage(email):
    user = User.get_by_email(email)
    if not user:
        raise exceptions.UserNotFoundException(email)
    for application in user.application_set.all():
        changes = AllocationChange.objects.filter(application=application).filter(billed=False)
        if changes.count() < 1:
            continue
        log_info_message("for application %s, reporting %s changes" % (application, changes.count()))
        for chargable in Chargable.objects.all():
            total_seconds = 0.0
            total_cents = 0.0
            # only look at allocs from before one minute ago
            now = datetime.datetime.now() - datetime.timedelta(seconds=60)
            allocs = list(changes.filter(chargable=chargable).filter(timestamp__lt=now).order_by('-timestamp'))
            if len(allocs) < 1:
                continue
            latest = allocs[-1]
            latest_copy = AllocationChange(application = application, chargable = chargable, quantity = latest.quantity, timestamp = now)
            latest_copy.save()
            allocs.insert(0, latest_copy)
            for alloc in allocs:
                if alloc == latest_copy:
                    continue
                diff = (now - alloc.timestamp).seconds
                if chargable.component == Chargable.components['application_processes']:
                    # the (alloc.quantity - 1) is to ensure the first process is free
                    price = (diff * (alloc.quantity - 1) * (chargable.price / 3600.0))
                else:
                    price = (diff * (alloc.quantity) * (chargable.price / 3600.0))
                total_cents += price
                total_seconds += diff
                now = alloc.timestamp
                alloc.billed = True
            total_hours = (total_seconds / 3600) + 1
            result = report_usage(user, total_cents, memo="%s hours for %s" % (total_hours, chargable))
            if result:
                [alloc.save() for alloc in allocs]
                be = BillingEvent(
                    email = email,
                    customer_id = user.customer_id,
                    application_name = application.name,
                    chargable_name = str(chargable),
                    cents = total_cents,
                    success = True,
                    memo = "devpayments dump: %s" % str(result)
                )
                be.save()
                log_info_message("Reported %s cents for %s for application %s" % (total_cents, chargable, application.name))
            else:
                be = BillingEvent(
                    email = email,
                    customer_id = user.customer_id,
                    application_name = application.name,
                    chargable_name = str(chargable),
                    cents = total_cents,
                    success = False,
                    memo = "devpayments dump: %s" % str(result)
                )
                be.save()
                log_error_message("Reporting failed for %s cents for %s for application %s: %s" % (total_cents, chargable, application.name, result))
Пример #5
0
def update_billing_info(email, info):
    def _unpack_customer_info():
        return {
            'first_name':info.get('first_name', ''),
            'last_name':info.get('last_name', ''),
            'email':email
        }

    def _unpack_billing_info():
        return {
            'number':info['cc_number'],
            'exp_month':info['expiration_month'],
            'exp_year':info['expiration_year'],
            'cvc':info['cvv']
        }

    def _create_new_customer():
        devpay = devpayments.Client(DEVPAYMENTS_API_KEY)
        try:
            result = devpay.createCustomer(
                mnemonic = _unpack_customer_info()['email'],
                card = _unpack_billing_info()
            )
            user.customer_id = result.id
            user.save()
        except DevPayException as e:
            return e.message
        return True

    def _update_customer():
        devpay = devpayments.Client(DEVPAYMENTS_API_KEY)
        try:
            result = devpay.updateCustomer(
                id = user.customer_id,
                mnemonic = _unpack_customer_info()['email'],
                card = _unpack_billing_info()
            )
            user.customer_id = result.id
            user.save()
        except DevPayException as e:
            return e.message
        return True

    user = User.get_by_email(email)
    if not user:
        raise exceptions.UserNotFoundException(email)
    message = True
    if user.customer_id == '-1' or user.customer_id == '':
        try:
            result = _create_new_customer()
            if True != result:
                message = result
        except Exception as e:
            log_error_message(e)
            return "Our system encountered an error.  Please contact [email protected]."
    else:
        try:
            result = _update_customer()
            if True != result:
                message = result
        except Exception as e:
            log_error_message(e)
            return "Our system encountered an error.  Please contact [email protected]."

    try:
        cust_info = _unpack_customer_info()
        user.first_name = cust_info.get('first_name', '')
        user.last_name = cust_info.get('last_name', '')
        user.save()
    except Exception as e:
        log_error_message(e)
        return "Our system encountered an error.  Please contact [email protected]."
    return message
Пример #6
0
def add_application(application_name, email, pubkey):
    """ Add the application specified by application_name and a corresponding database, owned by the user with the email address specified. """

    # Claim the application name
    ActiveApplicationName(name=application_name).save()

    user = User.get_by_email(email)

    # generate a secure password
    db_password = gen_password()

    # create the application row
    app = Application()
    app.name = application_name
    app.account = user
    app.db_name = application_name
    app.db_username = application_name
    app.db_password = db_password
    app.db_host = DEFAULT_DATABASE_HOST
    app.num_procs = 1
    app.save()

    # generate user and group ids to run as
    uids_gid = gen_uids_gid(app.id)
    app.setup_uid = uids_gid['setup_uid']
    app.web_uid = uids_gid['web_uid']
    app.cron_uid = uids_gid['cron_uid']
    app.app_gid = uids_gid['app_gid']
    app.save()

    # enable git push
    create_git_repository(application_name)
    add_ssh_public_key(user, pubkey)

    # allocate a proxycache host for the application -- improve on this later
    ProxyCache(application=app, host=DEFAULT_PROXYCACHE_HOST).save()

    # assign virtualhost on which to listen for application
    VirtualHost(application=app,
                virtualhost=application_name + '.djangy.com').save()

    # allocate the application to a worker host
    # Note: this must happen after ProxyCache and VirtualHost are filled in.
    allocate_workers(app)

    # create the database
    db = _mysql.connect(host=DEFAULT_DATABASE_HOST,
                        user=DATABASE_ROOT_USER,
                        passwd=DATABASE_ROOT_PASSWORD)

    try:  # try to remove the user if it already exists
        db.query(""" DROP USER '%s'@'%%';""" % application_name)
    except:
        pass

    db.query("""
        CREATE USER '%s'@'%%' IDENTIFIED BY '%s';""" %
             (application_name, db_password))

    try:  # try to drop the database in case it exists
        db.query(""" DROP DATABASE %s;""" % application_name)
    except:
        pass

    db.query("""
        CREATE DATABASE %s;""" % application_name)

    db.query("""
        USE %s""" % application_name)

    db.query("""
        GRANT ALL ON %s.* TO '%s'@'%%';""" %
             (application_name, application_name))

    return True