Merge the plans and mark many as deprecated. Fix a bunch of pylint errors.

This commit is contained in:
yackob03 2013-12-19 17:06:04 -05:00
parent 2d0a61b6c2
commit 5633c1fc79
3 changed files with 119 additions and 81 deletions

View file

@ -1,20 +1,13 @@
import json
import itertools
USER_PLANS = [
{
'title': 'Open Source',
'price': 0,
'privateRepos': 0,
'stripeId': 'free',
'audience': 'Share with the world',
},
PLANS = [
# Deprecated Plans
{
'title': 'Micro',
'price': 700,
'privateRepos': 5,
'stripeId': 'micro',
'audience': 'For smaller teams',
'bus_features': False,
'deprecated': True,
},
{
'title': 'Basic',
@ -22,6 +15,8 @@ USER_PLANS = [
'privateRepos': 10,
'stripeId': 'small',
'audience': 'For your basic team',
'bus_features': False,
'deprecated': True,
},
{
'title': 'Medium',
@ -29,6 +24,8 @@ USER_PLANS = [
'privateRepos': 20,
'stripeId': 'medium',
'audience': 'For medium teams',
'bus_features': False,
'deprecated': True,
},
{
'title': 'Large',
@ -36,16 +33,28 @@ USER_PLANS = [
'privateRepos': 50,
'stripeId': 'large',
'audience': 'For larger teams',
'bus_features': False,
'deprecated': True,
},
]
BUSINESS_PLANS = [
# Active plans
{
'title': 'Open Source',
'price': 0,
'privateRepos': 0,
'stripeId': 'bus-free',
'stripeId': 'free',
'audience': 'Committment to FOSS',
'bus_features': False,
'deprecated': False,
},
{
'title': 'Personal',
'price': 1200,
'privateRepos': 5,
'stripeId': 'personal',
'audience': 'Individuals',
'bus_features': False,
'deprecated': False,
},
{
'title': 'Skiff',
@ -53,6 +62,8 @@ BUSINESS_PLANS = [
'privateRepos': 10,
'stripeId': 'bus-micro',
'audience': 'For startups',
'bus_features': True,
'deprecated': False,
},
{
'title': 'Yacht',
@ -60,6 +71,8 @@ BUSINESS_PLANS = [
'privateRepos': 20,
'stripeId': 'bus-small',
'audience': 'For small businesses',
'bus_features': True,
'deprecated': False,
},
{
'title': 'Freighter',
@ -67,6 +80,8 @@ BUSINESS_PLANS = [
'privateRepos': 50,
'stripeId': 'bus-medium',
'audience': 'For normal businesses',
'bus_features': True,
'deprecated': False,
},
{
'title': 'Tanker',
@ -74,14 +89,16 @@ BUSINESS_PLANS = [
'privateRepos': 125,
'stripeId': 'bus-large',
'audience': 'For large businesses',
'bus_features': True,
'deprecated': False,
},
]
def get_plan(id):
def get_plan(plan_id):
""" Returns the plan with the given ID or None if none. """
for plan in itertools.chain(USER_PLANS, BUSINESS_PLANS):
if plan['stripeId'] == id:
for plan in PLANS:
if plan['stripeId'] == plan_id:
return plan
return None

View file

@ -12,7 +12,7 @@ from collections import defaultdict
from data import model
from data.queue import dockerfile_build_queue
from data.plans import USER_PLANS, BUSINESS_PLANS, get_plan
from data.plans import PLANS, get_plan
from app import app
from util.email import send_confirmation_email, send_recovery_email
from util.names import parse_repository_name, format_robot_username
@ -30,6 +30,7 @@ from endpoints.web import common_login
from util.cache import cache_control
from datetime import datetime, timedelta
store = app.config['STORAGE']
user_files = app.config['USERFILES']
logger = logging.getLogger(__name__)
@ -37,8 +38,9 @@ logger = logging.getLogger(__name__)
def log_action(kind, user_or_orgname, metadata={}, repo=None):
performer = current_user.db_user()
model.log_action(kind, user_or_orgname, performer=performer, ip=request.remote_addr,
metadata=metadata, repository=repo)
model.log_action(kind, user_or_orgname, performer=performer,
ip=request.remote_addr, metadata=metadata, repository=repo)
def api_login_required(f):
@wraps(f)
@ -64,7 +66,7 @@ def handle_dme(ex):
@app.errorhandler(KeyError)
def handle_dme(ex):
def handle_dme_key_error(ex):
return make_response(ex.message, 400)
@ -76,8 +78,7 @@ def welcome():
@app.route('/api/plans/')
def plans_list():
return jsonify({
'user': USER_PLANS,
'business': BUSINESS_PLANS,
'plans': PLANS,
})
@ -164,7 +165,7 @@ def convert_user_to_organization():
# Subscribe the organization to the new plan.
plan = convert_data['plan']
subscribe(user, plan, None, BUSINESS_PLANS)
subscribe(user, plan, None, PLANS)
# Convert the user to an organization.
model.convert_user_to_organization(user, model.get_user(admin_username))
@ -172,7 +173,6 @@ def convert_user_to_organization():
# And finally login with the admin credentials.
return conduct_signin(admin_username, admin_password)
@app.route('/api/user/', methods=['PUT'])
@ -427,7 +427,7 @@ def change_organization_details(orgname):
except model.InvalidOrganizationException:
abort(404)
org_data = request.get_json();
org_data = request.get_json()
if 'invoice_email' in org_data:
logger.debug('Changing invoice_email for organization: %s', org.username)
model.change_invoice_email(org, org_data['invoice_email'])
@ -477,7 +477,7 @@ def get_organization_member(orgname, membername):
abort(404)
member_dict = None
member_teams = model.get_organization_members_with_teams(org, membername = membername)
member_teams = model.get_organization_members_with_teams(org, membername=membername)
for member in member_teams:
if not member_dict:
member_dict = {'username': member.user.username,
@ -551,17 +551,20 @@ def update_organization_team(orgname, teamname):
log_action('org_create_team', orgname, {'team': teamname})
if is_existing:
if 'description' in details and team.description != details['description']:
if ('description' in details and
team.description != details['description']):
team.description = details['description']
team.save()
log_action('org_set_team_description', orgname, {'team': teamname, 'description': team.description})
log_action('org_set_team_description', orgname,
{'team': teamname, 'description': team.description})
if 'role' in details:
role = model.get_team_org_role(team).name
if role != details['role']:
team = model.set_team_org_permission(team, details['role'],
current_user.db_user().username)
log_action('org_set_team_role', orgname, {'team': teamname, 'role': details['role']})
log_action('org_set_team_role', orgname,
{'team': teamname, 'role': details['role']})
resp = jsonify(team_view(orgname, team))
if not is_existing:
@ -629,7 +632,8 @@ def update_organization_team_member(orgname, teamname, membername):
# Add the user to the team.
model.add_user_to_team(user, team)
log_action('org_add_team_member', orgname, {'member': membername, 'team': teamname})
log_action('org_add_team_member', orgname,
{'member': membername, 'team': teamname})
return jsonify(member_view(user))
abort(403)
@ -644,7 +648,8 @@ def delete_organization_team_member(orgname, teamname, membername):
# Remote the user from the team.
invoking_user = current_user.db_user().username
model.remove_user_from_team(orgname, teamname, membername, invoking_user)
log_action('org_remove_team_member', orgname, {'member': membername, 'team': teamname})
log_action('org_remove_team_member', orgname,
{'member': membername, 'team': teamname})
return make_response('Deleted', 204)
abort(403)
@ -673,7 +678,9 @@ def create_repo_api():
repo.description = req['description']
repo.save()
log_action('create_repo', namespace_name, {'repo': repository_name, 'namespace': namespace_name}, repo=repo)
log_action('create_repo', namespace_name,
{'repo': repository_name, 'namespace': namespace_name},
repo=repo)
return jsonify({
'namespace': namespace_name,
'name': repository_name
@ -758,7 +765,8 @@ def update_repo_api(namespace, repository):
repo.description = values['description']
repo.save()
log_action('set_repo_description', namespace, {'repo': repository, 'description': values['description']},
log_action('set_repo_description', namespace,
{'repo': repository, 'description': values['description']},
repo=repo)
return jsonify({
'success': True
@ -778,7 +786,8 @@ def change_repo_visibility_api(namespace, repository):
if repo:
values = request.get_json()
model.set_repository_visibility(repo, values['visibility'])
log_action('change_repo_visibility', namespace, {'repo': repository, 'visibility': values['visibility']},
log_action('change_repo_visibility', namespace,
{'repo': repository, 'visibility': values['visibility']},
repo=repo)
return jsonify({
'success': True
@ -795,7 +804,8 @@ def delete_repository(namespace, repository):
if permission.can():
model.purge_repository(namespace, repository)
registry.delete_repository_storage(namespace, repository)
log_action('delete_repo', namespace, {'repo': repository, 'namespace': namespace})
log_action('delete_repo', namespace,
{'repo': repository, 'namespace': namespace})
return make_response('Deleted', 204)
abort(403)
@ -912,7 +922,8 @@ def request_repo_build(namespace, repository):
dockerfile_build_queue.put(json.dumps({'build_id': build_request.id}))
log_action('build_dockerfile', namespace,
{'repo': repository, 'namespace': namespace, 'fileid': dockerfile_id}, repo=repo)
{'repo': repository, 'namespace': namespace,
'fileid': dockerfile_id}, repo=repo)
resp = jsonify({
'started': True
@ -943,7 +954,8 @@ def create_webhook(namespace, repository):
resp.headers['Location'] = url_for('get_webhook', repository=repo_string,
public_id=webhook.public_id)
log_action('add_repo_webhook', namespace,
{'repo': repository, 'webhook_id': webhook.public_id}, repo=repo)
{'repo': repository, 'webhook_id': webhook.public_id},
repo=repo)
return resp
abort(403) # Permissions denied
@ -1143,7 +1155,8 @@ def list_repo_user_permissions(namespace, repository):
current_func = role_view_func
def wrapped_role_org_view(repo_perm):
return wrap_role_view_org(current_func(repo_perm), repo_perm.user, org_members)
return wrap_role_view_org(current_func(repo_perm), repo_perm.user,
org_members)
role_view_func = wrapped_role_org_view
@ -1228,7 +1241,8 @@ def change_user_permissions(namespace, repository, username):
return error_resp
log_action('change_repo_permission', namespace,
{'username': username, 'repo': repository, 'role': new_permission['role']},
{'username': username, 'repo': repository,
'role': new_permission['role']},
repo=model.get_repository(namespace, repository))
resp = jsonify(perm_view)
@ -1255,7 +1269,8 @@ def change_team_permissions(namespace, repository, teamname):
new_permission['role'])
log_action('change_repo_permission', namespace,
{'team': teamname, 'repo': repository, 'role': new_permission['role']},
{'team': teamname, 'repo': repository,
'role': new_permission['role']},
repo=model.get_repository(namespace, repository))
resp = jsonify(role_view(perm))
@ -1282,7 +1297,8 @@ def delete_user_permissions(namespace, repository, username):
error_resp.status_code = 400
return error_resp
log_action('delete_repo_permission', namespace, {'username': username, 'repo': repository},
log_action('delete_repo_permission', namespace,
{'username': username, 'repo': repository},
repo=model.get_repository(namespace, repository))
return make_response('Deleted', 204)
@ -1299,7 +1315,8 @@ def delete_team_permissions(namespace, repository, teamname):
if permission.can():
model.delete_team_permission(teamname, namespace, repository)
log_action('delete_repo_permission', namespace, {'team': teamname, 'repo': repository},
log_action('delete_repo_permission', namespace,
{'team': teamname, 'repo': repository},
repo=model.get_repository(namespace, repository))
return make_response('Deleted', 204)
@ -1353,7 +1370,8 @@ def create_token(namespace, repository):
token = model.create_delegate_token(namespace, repository,
token_params['friendlyName'])
log_action('add_repo_accesstoken', namespace, {'repo': repository, 'token': token_params['friendlyName']},
log_action('add_repo_accesstoken', namespace,
{'repo': repository, 'token': token_params['friendlyName']},
repo = model.get_repository(namespace, repository))
resp = jsonify(token_view(token))
@ -1378,7 +1396,8 @@ def change_token(namespace, repository, code):
new_permission['role'])
log_action('change_repo_permission', namespace,
{'repo': repository, 'token': token.friendly_name, 'code': code, 'role': new_permission['role']},
{'repo': repository, 'token': token.friendly_name, 'code': code,
'role': new_permission['role']},
repo = model.get_repository(namespace, repository))
resp = jsonify(token_view(token))
@ -1397,7 +1416,8 @@ def delete_token(namespace, repository, code):
token = model.delete_delegate_token(namespace, repository, code)
log_action('delete_repo_accesstoken', namespace,
{'repo': repository, 'token': token.friendly_name, 'code': code},
{'repo': repository, 'token': token.friendly_name,
'code': code},
repo = model.get_repository(namespace, repository))
return make_response('Deleted', 204)
@ -1486,9 +1506,9 @@ def get_card(user):
if default_card:
card_info = {
'owner': card.name,
'type': card.type,
'last4': card.last4
'owner': default_card.name,
'type': default_card.type,
'last4': default_card.last4
}
return jsonify({'card': card_info})
@ -1500,7 +1520,7 @@ def subscribe_api():
plan = request_data['plan']
token = request_data['token'] if 'token' in request_data else None
user = current_user.db_user()
return subscribe(user, plan, token, USER_PLANS)
return subscribe(user, plan, token, PLANS)
def carderror_response(e):
@ -1511,15 +1531,18 @@ def carderror_response(e):
return resp
def subscribe(user, plan, token, accepted_plans):
def subscribe(user, plan, token, require_business_plan):
plan_found = None
for plan_obj in accepted_plans:
for plan_obj in PLANS:
if plan_obj['stripeId'] == plan:
plan_found = plan_obj
if not plan_found:
abort(404)
if require_business_plan and not plan_found['bus_features']:
abort(404)
private_repos = model.get_private_repo_count(user.username)
# This is the default response
@ -1619,7 +1642,7 @@ def subscribe_org_api(orgname):
plan = request_data['plan']
token = request_data['token'] if 'token' in request_data else None
organization = model.get_organization(orgname)
return subscribe(organization, plan, token, BUSINESS_PLANS)
return subscribe(organization, plan, token, PLANS)
abort(403)
@ -1743,20 +1766,20 @@ def delete_org_robot(orgname, robot_shortname):
def log_view(log):
view = {
'kind': log.kind.name,
'metadata': json.loads(log.metadata_json),
'ip': log.ip,
'datetime': log.datetime,
view = {
'kind': log.kind.name,
'metadata': json.loads(log.metadata_json),
'ip': log.ip,
'datetime': log.datetime,
}
if log.performer:
view['performer'] = {
'username': log.performer.username,
'is_robot': log.performer.robot,
}
if log.performer:
view['performer'] = {
'username': log.performer.username,
'is_robot': log.performer.robot,
}
return view
return view
@ -1786,12 +1809,14 @@ def org_logs_api(orgname):
start_time = request.args.get('starttime', None)
end_time = request.args.get('endtime', None)
return get_logs(orgname, start_time, end_time, performer_name=performer_name)
return get_logs(orgname, start_time, end_time,
performer_name=performer_name)
abort(403)
def get_logs(namespace, start_time, end_time, performer_name=None, repository=None):
def get_logs(namespace, start_time, end_time, performer_name=None,
repository=None):
performer = None
if performer_name:
performer = model.get_user(performer_name)
@ -1815,7 +1840,8 @@ def get_logs(namespace, start_time, end_time, performer_name=None, repository=No
if not end_time:
end_time = datetime.today()
logs = model.list_logs(namespace, start_time, end_time, performer = performer, repository=repository)
logs = model.list_logs(namespace, start_time, end_time, performer=performer,
repository=repository)
return jsonify({
'start_time': start_time,
'end_time': end_time,

View file

@ -1,19 +1,14 @@
import logging
import requests
import stripe
from flask import (abort, redirect, request, url_for, render_template,
make_response)
from flask.ext.login import login_user, UserMixin, login_required
from flask.ext.principal import identity_changed, Identity, AnonymousIdentity
from flask import request, make_response
from data import model
from app import app, login_manager, mixpanel
from auth.permissions import QuayDeferredPermissionUser
from data.plans import USER_PLANS, BUSINESS_PLANS, get_plan
from app import app
from util.invoice import renderInvoiceToHtml
from util.email import send_invoice_email
logger = logging.getLogger(__name__)
@ -33,10 +28,10 @@ def stripe_webhook():
# Find the user associated with the customer ID.
user = model.get_user_or_org_by_customer_id(customer_id)
if user and user.invoice_email:
# Lookup the invoice.
invoice = stripe.Invoice.retrieve(invoice_id)
if invoice:
invoice_html = renderInvoiceToHtml(invoice, user)
send_invoice_email(user.email, invoice_html)
# Lookup the invoice.
invoice = stripe.Invoice.retrieve(invoice_id)
if invoice:
invoice_html = renderInvoiceToHtml(invoice, user)
send_invoice_email(user.email, invoice_html)
return make_response('Okay')