diff --git a/apimanager/apimanager/settings.py b/apimanager/apimanager/settings.py
index d21d1d6..b22314b 100644
--- a/apimanager/apimanager/settings.py
+++ b/apimanager/apimanager/settings.py
@@ -56,6 +56,7 @@ INSTALLED_APPS = [
'customers',
'metrics',
'config',
+ 'webui',
]
MIDDLEWARE = [
@@ -224,21 +225,7 @@ DIRECTLOGIN_PATH = '/my/logins/direct'
# Set to true if the API is connected to a core banking system
GATEWAYLOGIN_HAS_CBS = False
-# Local settings can override anything in here
-try:
- from apimanager.local_settings import * # noqa
-except ImportError:
- pass
-if not OAUTH_CONSUMER_KEY:
- raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY')
-if not OAUTH_CONSUMER_SECRET:
- raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_SECRET')
-
-# Settings here might use parts overwritten in local settings
-API_ROOT = API_HOST + API_BASE_PATH + API_VERSION
-# For some reason, swagger is not available at the latest API version
-API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + API_VERSION + '/swagger' # noqa
CACHES = {
'default': {
@@ -261,8 +248,21 @@ EXCLUDE_URL_PATTERN = []
# App Name to aggregate metrics
API_EXPLORER_APP_NAME = 'xxx'
+
+# Local settings can override anything in here
+try:
+ from apimanager.local_settings import * # noqa
+except ImportError:
+ pass
+
+# Settings here might use parts overwritten in local settings
+API_ROOT = API_HOST + API_BASE_PATH + API_VERSION
+# For some reason, swagger is not available at the latest API version
+API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + API_VERSION + '/swagger' # noqa
+
VERIFY = True if API_HOST.startswith("https") else False
-
-
-
+if not OAUTH_CONSUMER_KEY:
+ raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY')
+if not OAUTH_CONSUMER_SECRET:
+ raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_SECRET')
diff --git a/apimanager/apimanager/urls.py b/apimanager/apimanager/urls.py
index 1d0da46..86ca726 100644
--- a/apimanager/apimanager/urls.py
+++ b/apimanager/apimanager/urls.py
@@ -35,4 +35,5 @@ urlpatterns = [
url(r'^customers/', include('customers.urls')),
url(r'^metrics/', include('metrics.urls')),
url(r'^config/', include('config.urls')),
+ url(r'^webui/', include('webui.urls')),
]
diff --git a/apimanager/base/templates/base.html b/apimanager/base/templates/base.html
index aa46c6e..7389ea6 100644
--- a/apimanager/base/templates/base.html
+++ b/apimanager/base/templates/base.html
@@ -62,6 +62,8 @@
{% url "config-index" as config_index_url %}
Config
+ {% url "webui-index" as webui_props_index_url %}
+ Webui Props
{% if API_TESTER_URL %}
Go to API Tester
diff --git a/apimanager/metrics/templates/metrics/summary.html b/apimanager/metrics/templates/metrics/summary.html
index eb938a9..01d8378 100644
--- a/apimanager/metrics/templates/metrics/summary.html
+++ b/apimanager/metrics/templates/metrics/summary.html
@@ -55,7 +55,12 @@
{{ form.include_obp_apps }} Include System Calls
+ {{ excluded_functions }}
+ {{ excluded_url_pattern }}
+ {% if excluded_apps %}
+ {{ excluded_apps }}
+ {% endif %}
diff --git a/apimanager/metrics/views.py b/apimanager/metrics/views.py
index a4e85f3..0dc8225 100644
--- a/apimanager/metrics/views.py
+++ b/apimanager/metrics/views.py
@@ -818,6 +818,9 @@ class MetricsSummaryView(LoginRequiredMixin, TemplateView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@@ -868,6 +871,9 @@ class YearlySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@@ -922,6 +928,9 @@ class QuarterlySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@@ -973,6 +982,9 @@ class WeeklySummaryView(MetricsSummaryView):
# ##'calls_per_half_day': calls_per_half_day,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@@ -1026,6 +1038,9 @@ class DailySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@@ -1085,5 +1100,8 @@ class CustomSummaryView(MetricsSummaryView):
# ##'calls_per_day': calls_per_day,
# ##'calls_per_half_day': calls_per_half_day,
'form': form,
+ 'excluded_apps':EXCLUDE_APPS,
+ 'excluded_functions':EXCLUDE_FUNCTIONS,
+ 'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
\ No newline at end of file
diff --git a/apimanager/webui/__init__.py b/apimanager/webui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/apimanager/webui/apps.py b/apimanager/webui/apps.py
new file mode 100644
index 0000000..5196c49
--- /dev/null
+++ b/apimanager/webui/apps.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+"""
+App config for config app
+"""
+
+from django.apps import AppConfig
+
+
+class ConfigConfig(AppConfig):
+ """Config for config"""
+ name = 'config'
diff --git a/apimanager/webui/forms.py b/apimanager/webui/forms.py
new file mode 100644
index 0000000..916066c
--- /dev/null
+++ b/apimanager/webui/forms.py
@@ -0,0 +1,14 @@
+from django import forms
+
+
+class WebuiForm(forms.Form):
+
+ webui_props = forms.CharField(
+ label='WEBUI Props',
+ widget=forms.Textarea(
+ attrs={
+ 'class': 'form-control',
+ }
+ ),
+ required=False
+ )
\ No newline at end of file
diff --git a/apimanager/webui/static/webui/css/webui.css b/apimanager/webui/static/webui/css/webui.css
new file mode 100644
index 0000000..c2c54e3
--- /dev/null
+++ b/apimanager/webui/static/webui/css/webui.css
@@ -0,0 +1,10 @@
+#config pre {
+ overflow: auto;
+ word-wrap: normal;
+ white-space: pre;
+}
+#config .string { color: green; }
+#config .number { color: darkorange; }
+#config .boolean { color: blue; }
+#config .null { color: magenta; }
+#config .key { color: red; }
diff --git a/apimanager/webui/static/webui/js/webui.js b/apimanager/webui/static/webui/js/webui.js
new file mode 100644
index 0000000..fb0ea03
--- /dev/null
+++ b/apimanager/webui/static/webui/js/webui.js
@@ -0,0 +1,25 @@
+$(document).ready(function($) {
+ function syntaxHighlight(json) {
+ if (typeof json != 'string') {
+ json = JSON.stringify(json, undefined, 2);
+ }
+ json = json.replace(/&/g, '&').replace(//g, '>');
+ return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
+ var cls = 'number';
+ if (/^"/.test(match)) {
+ if (/:$/.test(match)) {
+ cls = 'key';
+ } else {
+ cls = 'string';
+ }
+ } else if (/true|false/.test(match)) {
+ cls = 'boolean';
+ } else if (/null/.test(match)) {
+ cls = 'null';
+ }
+ return '' + match + ' ';
+ });
+ }
+
+ $('#config-json').html((syntaxHighlight(ConfigJson)));
+});
diff --git a/apimanager/webui/templates/webui/index.html b/apimanager/webui/templates/webui/index.html
new file mode 100644
index 0000000..ac9fbe8
--- /dev/null
+++ b/apimanager/webui/templates/webui/index.html
@@ -0,0 +1,49 @@
+{% extends 'base.html' %}
+{% load static %}
+
+{% block page_title %}{{ block.super }} / Users{% endblock page_title %}
+
+{% block content %}
+
+{% endblock %}
+
+{% block extrajs %}
+
+
+{% endblock extrajs %}
+
+
+{% block extracss %}
+
+{% endblock extracss %}
diff --git a/apimanager/webui/urls.py b/apimanager/webui/urls.py
new file mode 100644
index 0000000..bb9b59e
--- /dev/null
+++ b/apimanager/webui/urls.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+"""
+URLs for config app
+"""
+
+from django.conf.urls import url
+
+from .views import IndexView
+
+urlpatterns = [
+ url(r'^$',
+ IndexView.as_view(),
+ name='webui-index'),
+]
diff --git a/apimanager/webui/views.py b/apimanager/webui/views.py
new file mode 100644
index 0000000..279289a
--- /dev/null
+++ b/apimanager/webui/views.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+"""
+Views of config app
+"""
+
+import json
+
+from django.contrib import messages
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.views.generic import FormView
+from obp.api import API, APIError
+from .forms import WebuiForm
+from django.urls import reverse_lazy
+
+def error_once_only(request, err):
+ """
+ Just add the error once
+ :param request:
+ :param err:
+ :return:
+ """
+ storage = messages.get_messages(request)
+ if str(err) not in [str(m.message) for m in storage]:
+ messages.error(request, err)
+
+class IndexView(LoginRequiredMixin, FormView):
+ """Index view for config"""
+ template_name = "webui/index.html"
+ form_class = WebuiForm
+ success_url = reverse_lazy('webui_list')
+
+ def dispatch(self, request, *args, **kwargs):
+ self.api = API(request.session.get('obp'))
+ return super(IndexView, self).dispatch(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ context = super(IndexView, self).get_context_data(**kwargs)
+
+ return context
+
+ def get_form(self, *args, **kwargs):
+ form = super(IndexView, self).get_form(*args, **kwargs)
+ # Cannot add api in constructor: super complains about unknown kwarg
+ fields = form.fields
+ form.api = self.api
+ try:
+ fields['webui_props'].initial = ""
+
+ except APIError as err:
+ messages.error(self.request, err)
+ except:
+ messages.error(self.request, "Unknown Error")
+
+ return form
+
+ def form_valid(self, form):
+ try:
+ data = form.cleaned_data
+ urlpath = '/management/webui_props'
+ payload = {
+ "name":"webui_api_explorer_url",
+ "value" : str(data["webui_props"]).replace("\n", "\\n").replace("\"", '\\"')
+ }
+ result = self.api.post(urlpath, payload=payload)
+ except APIError as err:
+ error_once_only(self.request, err)
+ return super(IndexView, self).form_invalid(form)
+ except Exception as err:
+ error_once_only(self.request, "Unknown Error")
+ return super(IndexView, self).form_invalid(form)
+ if 'code' in result and result['code']>=400:
+ error_once_only(self.request, result['message'])
+ return super(IndexView, self).form_valid(form)
+ msg = 'Submission successfully!'
+ messages.success(self.request, msg)
+ return super(IndexView, self).form_valid(form)
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 9123025..675ad08 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,4 +8,5 @@ gunicorn==19.6.0
matplotlib
django-bootstrap-datepicker-plus
django-mathfilters
-django-bootstrap3
\ No newline at end of file
+django-bootstrap3
+psycopg2
\ No newline at end of file