Add show_if and hide_if methods for routes and APIs, as well as proper comparison of feature values
This commit is contained in:
parent
0abbf042dd
commit
4f4112b18d
5 changed files with 71 additions and 5 deletions
|
@ -85,11 +85,32 @@ def handle_api_error(error):
|
||||||
|
|
||||||
def resource(*urls, **kwargs):
|
def resource(*urls, **kwargs):
|
||||||
def wrapper(api_resource):
|
def wrapper(api_resource):
|
||||||
|
if not api_resource:
|
||||||
|
return None
|
||||||
|
|
||||||
api.add_resource(api_resource, *urls, **kwargs)
|
api.add_resource(api_resource, *urls, **kwargs)
|
||||||
return api_resource
|
return api_resource
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def show_if(value):
|
||||||
|
def f(inner):
|
||||||
|
if not value:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return inner
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
def hide_if(value):
|
||||||
|
def f(inner):
|
||||||
|
if value:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return inner
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
def truthy_bool(param):
|
def truthy_bool(param):
|
||||||
return param not in {False, 'false', 'False', '0', 'FALSE', '', 'null'}
|
return param not in {False, 'false', 'False', '0', 'FALSE', '', 'null'}
|
||||||
|
|
||||||
|
@ -116,6 +137,7 @@ def method_metadata(func, name):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nickname = partial(add_method_metadata, 'nickname')
|
nickname = partial(add_method_metadata, 'nickname')
|
||||||
related_user_resource = partial(add_method_metadata, 'related_user_resource')
|
related_user_resource = partial(add_method_metadata, 'related_user_resource')
|
||||||
internal_only = add_method_metadata('internal', True)
|
internal_only = add_method_metadata('internal', True)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from flask.ext.principal import identity_changed, AnonymousIdentity
|
||||||
from app import app
|
from app import app
|
||||||
from endpoints.api import (ApiResource, nickname, resource, validate_json_request, request_error,
|
from endpoints.api import (ApiResource, nickname, resource, validate_json_request, request_error,
|
||||||
log_action, internal_only, NotFound, require_user_admin,
|
log_action, internal_only, NotFound, require_user_admin,
|
||||||
InvalidToken, require_scope, format_date)
|
InvalidToken, require_scope, format_date, hide_if, show_if)
|
||||||
from endpoints.api.subscribe import subscribe
|
from endpoints.api.subscribe import subscribe
|
||||||
from endpoints.common import common_login
|
from endpoints.common import common_login
|
||||||
from data import model
|
from data import model
|
||||||
|
@ -22,6 +22,7 @@ from util.gravatar import compute_hash
|
||||||
from util.email import (send_confirmation_email, send_recovery_email,
|
from util.email import (send_confirmation_email, send_recovery_email,
|
||||||
send_change_email)
|
send_change_email)
|
||||||
|
|
||||||
|
import features
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import urlparse
|
||||||
import json
|
import json
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from flask import make_response, render_template, request
|
from flask import make_response, render_template, request, abort
|
||||||
from flask.ext.login import login_user, UserMixin
|
from flask.ext.login import login_user, UserMixin
|
||||||
from flask.ext.principal import identity_changed
|
from flask.ext.principal import identity_changed
|
||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
|
@ -15,7 +15,7 @@ from auth.permissions import QuayDeferredPermissionUser
|
||||||
from auth import scopes
|
from auth import scopes
|
||||||
from endpoints.api.discovery import swagger_route_data
|
from endpoints.api.discovery import swagger_route_data
|
||||||
from werkzeug.routing import BaseConverter
|
from werkzeug.routing import BaseConverter
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -27,6 +27,29 @@ class RepoPathConverter(BaseConverter):
|
||||||
|
|
||||||
app.url_map.converters['repopath'] = RepoPathConverter
|
app.url_map.converters['repopath'] = RepoPathConverter
|
||||||
|
|
||||||
|
def route_show_if(value):
|
||||||
|
def decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if not value:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def route_hide_if(value):
|
||||||
|
def decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
if value:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def get_route_data():
|
def get_route_data():
|
||||||
global route_data
|
global route_data
|
||||||
|
|
|
@ -14,7 +14,7 @@ from auth.permissions import AdministerOrganizationPermission
|
||||||
from util.invoice import renderInvoiceToPdf
|
from util.invoice import renderInvoiceToPdf
|
||||||
from util.seo import render_snapshot
|
from util.seo import render_snapshot
|
||||||
from util.cache import no_cache
|
from util.cache import no_cache
|
||||||
from endpoints.common import common_login, render_page_template
|
from endpoints.common import common_login, render_page_template, route_show_if, route_hide_if
|
||||||
from endpoints.csrf import csrf_protect, generate_csrf_token
|
from endpoints.csrf import csrf_protect, generate_csrf_token
|
||||||
from util.names import parse_repository_name
|
from util.names import parse_repository_name
|
||||||
from util.gravatar import compute_hash
|
from util.gravatar import compute_hash
|
||||||
|
|
|
@ -2,4 +2,24 @@ def import_features(config_dict):
|
||||||
for feature, feature_val in config_dict.items():
|
for feature, feature_val in config_dict.items():
|
||||||
if feature.startswith('FEATURE_'):
|
if feature.startswith('FEATURE_'):
|
||||||
feature_name = feature[8:]
|
feature_name = feature[8:]
|
||||||
globals()[feature_name] = feature_val
|
globals()[feature_name] = FeatureNameValue(feature_name, feature_val)
|
||||||
|
|
||||||
|
|
||||||
|
class FeatureNameValue(object):
|
||||||
|
def __init__(self, name, value):
|
||||||
|
self.value = value
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '%s => %s' % (self.name, self.value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return self.value.__cmp__(other)
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return self.value.__nonzero__()
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue