Add a check_repository_usage method which adds (or removes) a notification on the user/org when they go over their plan usage
This commit is contained in:
parent
525ef8d14f
commit
e5a461989f
6 changed files with 39 additions and 28 deletions
|
@ -28,7 +28,7 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
ViewTeamPermission,
|
ViewTeamPermission,
|
||||||
UserPermission)
|
UserPermission)
|
||||||
from endpoints.common import (common_login, get_route_data, truthy_param,
|
from endpoints.common import (common_login, get_route_data, truthy_param,
|
||||||
start_build, add_notification)
|
start_build, check_repository_usage)
|
||||||
from endpoints.trigger import (BuildTrigger, TriggerActivationException,
|
from endpoints.trigger import (BuildTrigger, TriggerActivationException,
|
||||||
TriggerDeactivationException,
|
TriggerDeactivationException,
|
||||||
EmptyRepositoryException)
|
EmptyRepositoryException)
|
||||||
|
@ -2197,6 +2197,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
cus = stripe.Customer.create(email=user.email, plan=plan, card=card)
|
cus = stripe.Customer.create(email=user.email, plan=plan, card=card)
|
||||||
user.stripe_id = cus.id
|
user.stripe_id = cus.id
|
||||||
user.save()
|
user.save()
|
||||||
|
check_repository_usage(user, plan_found)
|
||||||
log_action('account_change_plan', user.username, {'plan': plan})
|
log_action('account_change_plan', user.username, {'plan': plan})
|
||||||
except stripe.CardError as e:
|
except stripe.CardError as e:
|
||||||
return carderror_response(e)
|
return carderror_response(e)
|
||||||
|
@ -2213,6 +2214,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
# We only have to cancel the subscription if they actually have one
|
# We only have to cancel the subscription if they actually have one
|
||||||
cus.cancel_subscription()
|
cus.cancel_subscription()
|
||||||
cus.save()
|
cus.save()
|
||||||
|
check_repository_usage(user, plan_found)
|
||||||
log_action('account_change_plan', user.username, {'plan': plan})
|
log_action('account_change_plan', user.username, {'plan': plan})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -2228,6 +2230,7 @@ def subscribe(user, plan, token, require_business_plan):
|
||||||
return carderror_response(e)
|
return carderror_response(e)
|
||||||
|
|
||||||
response_json = subscription_view(cus.subscription, private_repos)
|
response_json = subscription_view(cus.subscription, private_repos)
|
||||||
|
check_repository_usage(user, plan_found)
|
||||||
log_action('account_change_plan', user.username, {'plan': plan})
|
log_action('account_change_plan', user.username, {'plan': plan})
|
||||||
|
|
||||||
resp = jsonify(response_json)
|
resp = jsonify(response_json)
|
||||||
|
|
|
@ -126,11 +126,14 @@ def render_page_template(name, **kwargs):
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
def add_notification(kind, metadata=None, user=None):
|
def check_repository_usage(user_or_org, plan_found):
|
||||||
if not user and current_user:
|
private_repos = model.get_private_repo_count(user_or_org.username)
|
||||||
user = current_user.db_user()
|
repos_allowed = plan_found['privateRepos']
|
||||||
|
|
||||||
return model.create_notification(kind, user, metadata or {})
|
if private_repos > repos_allowed:
|
||||||
|
model.create_notification('over_private_usage', user_or_org, {'namespace': user_or_org.username})
|
||||||
|
else:
|
||||||
|
model.delete_notifications_by_kind(user_or_org, 'over_private_usage')
|
||||||
|
|
||||||
|
|
||||||
def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
||||||
|
|
|
@ -43,8 +43,7 @@
|
||||||
ng-show="notificationService.notifications.length"
|
ng-show="notificationService.notifications.length"
|
||||||
ng-class="notificationService.notificationClasses"
|
ng-class="notificationService.notificationClasses"
|
||||||
bs-tooltip=""
|
bs-tooltip=""
|
||||||
title="{{ notificationService.notificationSummaries }}"
|
title="User Notifications"
|
||||||
data-html="true"
|
|
||||||
data-placement="left"
|
data-placement="left"
|
||||||
data-container="body">
|
data-container="body">
|
||||||
{{ notificationService.notifications.length }}
|
{{ notificationService.notifications.length }}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="notification-view-element">
|
<div class="notification-view-element">
|
||||||
<div class="container" ng-click="showNotification();">
|
<div class="container" ng-click="showNotification();">
|
||||||
<div class="circle" ng-class="getClass(notification)"></div>
|
<div class="circle" ng-class="getClass(notification)"></div>
|
||||||
<div class="message">{{ getMessage(notification) }}</div>
|
<div class="message" ng-bind-html="getMessage(notification)"></div>
|
||||||
<div class="orginfo" ng-if="notification.organization">
|
<div class="orginfo" ng-if="notification.organization">
|
||||||
<img src="//www.gravatar.com/avatar/{{ getGravatar(notification.organization) }}?s=24&d=identicon" />
|
<img src="//www.gravatar.com/avatar/{{ getGravatar(notification.organization) }}?s=24&d=identicon" />
|
||||||
<span class="orgname">{{ notification.organization }}</span>
|
<span class="orgname">{{ notification.organization }}</span>
|
||||||
|
|
|
@ -479,8 +479,8 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
return userService;
|
return userService;
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
$provide.factory('NotificationService', ['$rootScope', '$interval', 'UserService', 'ApiService', 'StringBuilderService',
|
$provide.factory('NotificationService', ['$rootScope', '$interval', 'UserService', 'ApiService', 'StringBuilderService', 'PlanService', 'UserService',
|
||||||
function($rootScope, $interval, UserService, ApiService, StringBuilderService) {
|
function($rootScope, $interval, UserService, ApiService, StringBuilderService, PlanService, UserService) {
|
||||||
var notificationService = {
|
var notificationService = {
|
||||||
'user': null,
|
'user': null,
|
||||||
'notifications': [],
|
'notifications': [],
|
||||||
|
@ -493,20 +493,35 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
var notificationKinds = {
|
var notificationKinds = {
|
||||||
'test_notification': {
|
'test_notification': {
|
||||||
'level': 'primary',
|
'level': 'primary',
|
||||||
'summary': 'This is a test notification',
|
|
||||||
'message': 'This notification is a long message for testing',
|
'message': 'This notification is a long message for testing',
|
||||||
'page': '/about/'
|
'page': '/about/'
|
||||||
},
|
},
|
||||||
'password_required': {
|
'password_required': {
|
||||||
'level': 'error',
|
'level': 'error',
|
||||||
'summary': 'A password is needed for your account',
|
|
||||||
'message': 'In order to begin pushing and pulling repositories to Quay.io, a password must be set for your account',
|
'message': 'In order to begin pushing and pulling repositories to Quay.io, a password must be set for your account',
|
||||||
'page': '/user?tab=password'
|
'page': '/user?tab=password'
|
||||||
|
},
|
||||||
|
'over_private_usage': {
|
||||||
|
'level': 'error',
|
||||||
|
'message': 'Namespace {namespace} is over its allowed private repository count. ' +
|
||||||
|
'<br><br>Please upgrade your plan to avoid disruptions in service.',
|
||||||
|
'page': function(metadata) {
|
||||||
|
var organization = UserService.getOrganization(metadata['namespace']);
|
||||||
|
if (organization) {
|
||||||
|
return '/organization/' + metadata['namespace'] + '/admin';
|
||||||
|
} else {
|
||||||
|
return '/user';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
notificationService.getPage = function(notification) {
|
notificationService.getPage = function(notification) {
|
||||||
return notificationKinds[notification['kind']]['page'];
|
var page = notificationKinds[notification['kind']]['page'];
|
||||||
|
if (typeof page != 'string') {
|
||||||
|
page = page(notification['metadata']);
|
||||||
|
}
|
||||||
|
return page;
|
||||||
};
|
};
|
||||||
|
|
||||||
notificationService.getMessage = function(notification) {
|
notificationService.getMessage = function(notification) {
|
||||||
|
@ -514,20 +529,6 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
return StringBuilderService.buildString(kindInfo['message'], notification['metadata']);
|
return StringBuilderService.buildString(kindInfo['message'], notification['metadata']);
|
||||||
};
|
};
|
||||||
|
|
||||||
notificationService.getSummary = function(notification) {
|
|
||||||
var kindInfo = notificationKinds[notification['kind']];
|
|
||||||
return StringBuilderService.buildString(kindInfo['summary'], notification['metadata']);
|
|
||||||
};
|
|
||||||
|
|
||||||
notificationService.getSummaries = function(notifications) {
|
|
||||||
var summaries = [];
|
|
||||||
for (var i = 0; i < notifications.length; ++i) {
|
|
||||||
var notification = notifications[i];
|
|
||||||
summaries.push(notificationService.getSummary(notification));
|
|
||||||
}
|
|
||||||
return summaries.join('<br>');
|
|
||||||
};
|
|
||||||
|
|
||||||
notificationService.getClass = function(notification) {
|
notificationService.getClass = function(notification) {
|
||||||
return 'notification-' + notificationKinds[notification['kind']]['level'];
|
return 'notification-' + notificationKinds[notification['kind']]['level'];
|
||||||
};
|
};
|
||||||
|
@ -550,7 +551,6 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
ApiService.listUserNotifications().then(function(resp) {
|
ApiService.listUserNotifications().then(function(resp) {
|
||||||
notificationService.notifications = resp['notifications'];
|
notificationService.notifications = resp['notifications'];
|
||||||
notificationService.notificationClasses = notificationService.getClasses(notificationService.notifications);
|
notificationService.notificationClasses = notificationService.getClasses(notificationService.notifications);
|
||||||
notificationService.notificationSummaries = notificationService.getSummaries(notificationService.notifications);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -559,6 +559,12 @@ quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angu
|
||||||
pollTimerHandle = $interval(notificationService.update, 5 * 60 * 1000 /* five minutes */);
|
pollTimerHandle = $interval(notificationService.update, 5 * 60 * 1000 /* five minutes */);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Watch for plan changes and update.
|
||||||
|
PlanService.registerListener(this, function(plan) {
|
||||||
|
notificationService.reset();
|
||||||
|
notificationService.update();
|
||||||
|
});
|
||||||
|
|
||||||
// Watch for user changes and update.
|
// Watch for user changes and update.
|
||||||
$rootScope.$watch(function() { return UserService.currentUser(); }, function(currentUser) {
|
$rootScope.$watch(function() { return UserService.currentUser(); }, function(currentUser) {
|
||||||
notificationService.reset();
|
notificationService.reset();
|
||||||
|
|
Binary file not shown.
Reference in a new issue