Merge remote-tracking branch 'origin/develop' into 100.1.0

This commit is contained in:
tawoe 2023-03-01 13:39:40 +01:00
commit 6b7e6a8435
79 changed files with 1403 additions and 981 deletions

View File

@ -89,7 +89,7 @@ or maybe upgrade dependency version, If still facing issue to run **pip install
├── static-collected
└── venv
```
6. Then, update information in local_setting.py file, the example is below for updating information. For this file, required **OAUTH_CONSUMER_KEY** and **OAUTH_CONSUMER_SECRET** to run this app. For this purpose, must be OBP-API running locally. Follow these steps to run [OBP-API Local](https://github.com/OpenBankProject/OBP-API).
6. Then, update information in local_setting.py file, the example is below for updating information. For this file, required **OAUTH_CONSUMER_KEY** and **OAUTH_CONSUMER_SECRET** to run this app. For this purpose, must be OBP-API running locally. Follow these steps to run [OBP-API Local](https://github.com/OpenBankProject/OBP-API).
```python
@ -137,6 +137,13 @@ DATABASE = {
"PORT": "5432",
}
}
# This is an optional setting.
# CALLBACK_BASE_URL can be used to explicitly set the redirect base url that API Manager uses during OAuth authentication.
# If CALLBACK_BASE_URL is not set, API Manager (this applicaiton) in the function "get_redirect_url" will use the Django HTTP_HOST environ field (see here: https://docs.djangoproject.com/en/4.1/ref/request-response/). Note, this might be modified by NGINX via the directive: proxy_set_header Host $http_host;
# In order to be explicit you can set it here e.g.
# CALLBACK_BASE_URL="https://apimanager.example.com"
```
@ -220,9 +227,9 @@ EXCLUDE_URL_PATTERN = []
API_EXPLORER_APP_NAME = 'xxx'
#Map Java: yyyy-MM-dd'T'HH:mm'Z'
API_DATETIMEFORMAT = '%Y-%m-%dT%H:%M:%SZ'
API_DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
#Map Java: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
API_DATEFORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
API_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
```

View File

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class AccountConfig(AppConfig):
name = 'account-list'

View File

View File

@ -0,0 +1,4 @@
from django.db import models
# Create your models here.
# -*- coding: utf-8 -*-

View File

@ -0,0 +1,18 @@
#accounts_list div {
margin: 5px 0;
}
/* The actual popup (appears on top) */
.popuptext {
width: 250px;
background-color: #555;
color: #fff;
text-align: left;
border-radius: 6px;
padding: 8px 0;
z-index: 1;
/*bottom: 125%;*/
top:100%
left: 50%;
margin-left: -80px;
}

View File

@ -0,0 +1,43 @@
{% extends 'base.html' %} {% load static %} {% load i18n %}
{% block page_title %} {{ block.super }} / {% trans "Account List" %}{% endblock page_title %} {% block content %}
<div id="accounts_list">
<h1>{% trans "Account List" %}</h1>
<form class="form-inline" method="get">
<input type="submit" class="btn btn-default" value ='{% trans "Export CSV" %}' onclick="javascript: form.action='{% url 'export-csv-account' %}';">
</form>
<div class="table-responsive">
<table class="table table-hover tablesorter" id="accounts-list" aria-describedby="accounts list">
<thead>
<th scope="col">{% trans "Account Id" %}</th>
<th scope="col">{% trans "Bank Id" %}</th>
<th scope="col">{% trans "Label" %}</th>
<th scope="col">{% trans "More info" %}</th>
</thead>
<tbody>
{% for account in accounts_list %}
{% url 'account_update' account.id account.bank_id as url_account_update %}
<tr data-account-id="{{ account.id }}">
<td>{{ account.id }}</td>
<td>{{ account.bank_id }}</td>
<td>{{ account.label }}</td>
<td>
<div class="popuptext">
<ul>
<li>{% trans "Other Info" %}:
<ul>
<li>{{account.account_type}}</li>
</ul>
</li>
</ul>
</div>
</td>
<td><a href="{{ url_atm_update }}" class="btn btn-primary">{% trans "View" %}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %} {% block extrajs %} {% endblock extrajs %} {% block extracss %}
<link href="{% static 'accountlist/css/accountlist.css' %}" rel="stylesheet"> {% endblock extracss %}

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
"""
URLs for Account list app
"""
from django.conf.urls import url
from .views import AccountListView, ExportCsvView
urlpatterns = [
url(r'^$',
AccountListView.as_view(),
name='account-list'),
url(r'^export_csv$',
ExportCsvView.as_view(),
name='export-csv-account')
]

View File

@ -0,0 +1,75 @@
from django.shortcuts import render
# Create your views here.
# -*- coding: utf-8 -*-
"""
Views of Account List app
"""
import datetime
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
import json
from django.urls import reverse_lazy
from django.http import HttpResponse
from django.views.generic import FormView,TemplateView, View
from accounts.views import IndexAccountsView
from obp.api import API, APIError
from base.views import get_banks
import csv
class AccountListView(IndexAccountsView, LoginRequiredMixin, FormView ):
template_name = "accountlist/accountlist.html"
success_url = '/accounts/list'
def get_accountlist(self, context):
api = API(self.request.session.get('obp'))
try:
#self.bankids = self.get_banks()
accounts_list = []
#for bank_id in self.bankids:
urlpath = '/my/accounts'
result = api.get(urlpath)
if 'accounts' in result:
accounts_list.extend(result['accounts'])
except APIError as err:
messages.error(self.request, err)
return []
except Exception as inst:
messages.error(self.request, "Unknown Error {}".format(type(inst).__name__))
return []
return accounts_list
def get_context_data(self, **kwargs):
context = super(IndexAccountsView, self).get_context_data(**kwargs)
accounts_list = self.get_accountlist(context)
context.update({
'accounts_list': accounts_list,
#'bankids': bankids
})
return context
class ExportCsvView(LoginRequiredMixin, View):
"""View to export the user to csv"""
def get(self, request, *args, **kwargs):
api = API(self.request.session.get('obp'))
try:
self.bankids = get_banks(self.request)
accounts_list = []
for bank_id in self.bankids:
urlpath = 'banks/{}/accounts'.format(bank_id)
result = api.get(urlpath)
if 'accounts' in result:
accounts_list.extend(result['accounts'])
except APIError as err:
messages.error(self.request, err)
except Exception as inst:
messages.error(self.request, "Unknown Error {}".format(type(inst).__name__))
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment;filename= Account'+ str(datetime.datetime.now())+'.csv'
writer = csv.writer(response)
writer.writerow(["id","label","bank_id","account_type","scheme","address","id", "short_name", "description", "is_public"])
for user in accounts_list:
writer.writerow([user['id'],user['label'], user['bank_id'], user["account_type"], user["scheme"], user["address"], user["views"]['id'],
user["views"]['short_name'], user["views"]['description'], user["views"]['is_public']])
return response

View File

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class CustomersConfig(AppConfig):
name = 'customers_list'

View File

View File

@ -0,0 +1,18 @@
#apicollectionlist div {
margin: 5px 0;
}
/* The actual popup (appears on top) */
.popuptext {
width: 250px;
background-color: #555;
color: #fff;
text-align: left;
border-radius: 6px;
padding: 8px 0;
z-index: 1;
/*bottom: 125%;*/
top:100%
left: 50%;
margin-left: -80px;
}

View File

@ -0,0 +1,49 @@
{% extends 'base.html' %} {% load static %} {% load i18n %}
{% block page_title %} {{ block.super }} / {% trans "Customer List" %}{% endblock page_title %} {% block content %}
<div id="apicollectionlist">
<h1>{% trans " All API Collections" %}</h1>
<form class="form-inline" method="get">
<input type="submit" class="btn btn-default" value ='{% trans "Export CSV" %}' onclick="javascript: form.action='{% url 'export-csv-apicollection' %}';">
</form>
<div class="table-responsive">
<table class="table table-hover tablesorter" id="apicollectionlist" aria-describedby="apicollectionlist list">
<thead>
<th scope="col">{% trans "API Collection" %}</th>
<th scope="col">{% trans "User Name" %}</th>
<th scope="col">{% trans "API Collection Name" %}</th>
<th scope="col">{% trans "More info" %}</th>
</thead>
<tbody>
{% for apicollection in apicollections_list %}
{% url 'my-api-collection-detail' apicollection.api_collection_id as url_collection_detail %}
<tr id="{{ apicollection.api_collection_id }}">
<!--Add Try It button using API-Collection ID after success response for redirecting API-Explorer-->
<td>{% if apicollection.api_collection_id %}
<a class="api_collection_id btn btn-primary" onclick="redirect_api_explorer_url('{{apicollection.collection_on_api_explorer_url}}')" value="{{apicollection.api_collection_id}}">Try It</a>
{% endif %}</td>
<td>{{ apicollection.username }}</td>
<td>{{ apicollection.api_collection_name }}</td>
<td>
<div class="popuptext">
<ul>
<li>{% trans "Is Sharable" %}:
<ul>
<li>{{apicollection.is_sharable}}</li>
</ul>
</li>
</ul>
</div>
</td>
<td><a type= "button" class="btn btn-primary" href= "{{ url_collection_detail }}">{% trans "View" %}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'base/js/base.js' %}"></script>
{% endblock extrajs %} {% block extracss %}
<link href="{% static 'customerlist/css/customerlist.css' %}" rel="stylesheet"> {% endblock extracss %}

View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
"""
URLs for Api Collection list app
"""
from django.conf.urls import url
from .views import ApiCollectionListView, ExportCsvView
urlpatterns = [
url(r'^$',
ApiCollectionListView.as_view(),
name='apicollection-list'),
url(r'^export_csv$',
ExportCsvView.as_view(),
name='export-csv-apicollection')
]

View File

@ -0,0 +1,93 @@
from django.shortcuts import render
# Create your views here.
# -*- coding: utf-8 -*-
"""
Views of Api Collection list app
"""
import datetime
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
import json
from django.urls import reverse_lazy
from django.http import HttpResponse
from django.views.generic import FormView,TemplateView, View
from apicollections.views import IndexView
from obp.api import API, APIError
from django.conf import settings
import csv
class ApiCollectionListView(IndexView, LoginRequiredMixin, FormView ):
template_name = "apicollectionlist/apicollectionlist.html"
success_url = '/apicollections/list'
def get_apicollections(self, context):
"""Get All user """
api = API(self.request.session.get('obp'))
try:
apicollections_list = []
#TODO: NOTE- THIS RETURNS ALL USER. THIS IS A POTENTIAL PERFORMANCE ISSUE. WE NEED ENDPOINT FOR COLLECTION.
#Endpoint will return users.
get_all_users_url_path = '/users'
user = api.get(get_all_users_url_path)
for i in user["users"]:
# Returns the APIs collections for a user.
api_collections_for_user_url_path = '/users/{}/api-collections'.format(i["user_id"])
api_collections_for_user = api.get(api_collections_for_user_url_path)
if 'api_collections' in api_collections_for_user:
apicollections_list.extend(api_collections_for_user['api_collections'])
for ac in apicollections_list:
ac["collection_on_api_explorer_url"] = f"{settings.API_EXPLORER_HOST}/?api-collection-id={ac['api_collection_id']}"
except APIError as err:
messages.error(self.request, err)
return []
except Exception as err:
messages.error(self.request, err)
return []
return apicollections_list
def get_context_data(self, **kwargs):
api = API(self.request.session.get('obp'))
context = super(IndexView, self).get_context_data(**kwargs)
apicollections_list = self.get_apicollections(context)
try:
for final_collection_list in apicollections_list:
url_path = "/users/user_id/{}".format(final_collection_list["user_id"])
result = api.get(url_path)
final_collection_list["username"] = result["username"]
except Exception as err:
messages.error(self.request, err)
context.update({
'apicollections_list': apicollections_list,
})
return context
class ExportCsvView(LoginRequiredMixin, View):
"""View to export the user to csv"""
def get(self, request, *args, **kwargs):
api = API(self.request.session.get('obp'))
try:
apicollections_list = []
urlpath = '/my/api-collections'
result = api.get(urlpath)
if 'api_collections' in result:
apicollections_list.extend(result['api_collections'])
except APIError as err:
messages.error(self.request, err)
except Exception as inst:
messages.error(self.request, "Unknown Error {}".format(type(inst).__name__))
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment;filename= ApiCollections'+ str(datetime.datetime.now())+'.csv'
writer = csv.writer(response)
writer.writerow(["api_collection_id","user_id","api_collection_name","is_sharable","description"])
for user in apicollections_list:
writer.writerow([user['api_collection_id'],user['user_id'], user['api_collection_name'], user["is_sharable"],
user["description"]])
return response

View File

@ -1,12 +1,11 @@
$(document).ready(function($) {
$('.runner button.forSave').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var api_collection_name = $(runner).find('.api_collection_name').val();
var api_collection_is_sharable = $(runner).find('.api_collection_is_sharable').val();
var api_collection_description = $(runner).find('.api_collection_description').val();
let runner = $(this).parent().parent().parent();
let api_collection_name = $(runner).find('.api_collection_name').val();
let api_collection_is_sharable = $(runner).find('.api_collection_is_sharable').val();
let api_collection_description = $(runner).find('.api_collection_description').val();
$('.runner button.forUpdate').attr("disabled","disabled");
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
$.post('save/apicollection', {
@ -17,12 +16,31 @@ $(document).ready(function($) {
location.reload();
});
});
$('.runner button.forUpdate').click(function(e) {
e.preventDefault();
let runner = $(this).parent().parent().parent();
let api_collection_id = $(runner).find('.api_collection_id').attr("value");
let api_collection_name = $(runner).find('.api_collection_name').val();
let api_collection_is_sharable = $(runner).find('.api_collection_is_sharable').val();
let api_collection_description = $(runner).find('.api_collection_description').val();
$('.runner button.forUpdate').attr("disabled","disabled");
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
$.post('update/apicollection', {
'api_collection_id': api_collection_id,
'api_collection_name': api_collection_name,
'api_collection_is_sharable': api_collection_is_sharable,
'api_collection_description': api_collection_description,
}, function (response) {
location.reload();
});
});
$('.runner button.forDelete').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var api_collection_id = $(runner).find('.api_collection_id').html();
let runner = $(this).parent().parent().parent();
let api_collection_id = $(runner).find('.api_collection_id').attr("value");
$('.runner button.forUpdate').attr("disabled","disabled");
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
$.post('delete/apicollection', {

View File

@ -3,7 +3,7 @@
{% block page_title %}{{ block.super }} / API Collections{% endblock page_title %}
{% block content %}
<h1>{% trans "API Collections" %}</h1>
<h1>{% trans "My API Collections" %}</h1>
<div class="row">
<div class="col-xs-12 col-sm-2">
<label class="form-group">{% trans "API Collection Id" %}:</label> <br>
@ -26,20 +26,32 @@
<div class="row">
<div class="col-xs-12 col-sm-2">
<div class="form-group" cols="1" rows="1">
<a class="api_collection_id" href="{{ url_collection_detail }}">{{ api_collection.api_collection_id }}</a></div>
<!--Add Try It button using API-Collection ID after success response for redirecting API-Explorer-->
{% if api_collection.api_collection_id %}
<a class="api_collection_id btn btn-primary" onclick="redirect_api_explorer_url('{{api_collection.collection_on_api_explorer_url}}')" value="{{api_collection.api_collection_id}}">Try It</a>
{% endif %}
</div>
</div>
{% if api_collection.api_collection_id %}
<div class="col-xs-12 col-sm-2">
<div class="form-group" cols="1" rows="1">
<div>{{ api_collection.api_collection_name }}</div></div>
<div>
<input class="api_collection_name form-control" value="{{ api_collection.api_collection_name }}">
</div>
</div>
</div>
<div class="col-xs-12 col-sm-2">
<div class="form-group" cols="1" rows="1">
<div>{{ api_collection.is_sharable }}</div>
<div>
<select class="api_collection_is_sharable form-control">
<option value="{{ api_collection.is_sharable }}" selected="selected" hidden>{{ api_collection.is_sharable }}</option>
<option value="True">True</option>
<option value="False">False</option>
</select></div>
</div>
</div>
<div class="col-xs-12 col-sm-4">
<div cols="40" rows="1" class="form-control">{{api_collection.description}}</div>
<div class="col-xs-6 col-sm-3">
<textarea cols="40" rows="1" class="form-control api_collection_description" style="margin: 5px -2px 5px 0px; height: 138px; width: 100%;">{{api_collection.description}}</textarea>
</div>
{% else %}
<div class="col-xs-12 col-sm-2">
@ -55,19 +67,29 @@
</select>
</div>
</div>
<div class="col-xs-12 col-sm-4">
<textarea cols="40" rows="1" class="form-control api_collection_description">{% trans "Describe the purpose of the collection" %}</textarea>
<div class="col-xs-6 col-sm-3">
<textarea cols="40" rows="1" class="form-control api_collection_description">{% trans "Enter the Description" %}</textarea>
</div>
{% endif %}
{% if forloop.counter0 == 0 %}
<div class="col-sm-12 col-sm-2">
<div class="col-sm-6 col-sm-2">
<div class="form-group">
<button class="btn btn-primary btn-green forSave">{% trans "Create" %}</button>
</div>
</div>
{% endif %}
{% if forloop.counter0 > 0 %}
<div class="col-sm-12 col-sm-2">
<div class="col-sm-3 col-sm-1">
<div class="form-group">
<a type= "button" class="btn btn-primary" href="{{ url_collection_detail }}">{% trans "Edit" %}</a>
</div>
</div>
<div class="col-sm-3 col-sm-1">
<div class="form-group">
<button class="btn btn-primary forUpdate">{% trans "Update" %}</button>
</div>
</div>
<div class="col-sm-3 col-sm-1">
<div class="form-group">
<button class="btn btn-primary btn-red forDelete">{% trans "Delete" %}</button>
</div>
@ -82,4 +104,5 @@
{% block extrajs %}
<script type="text/javascript" src="{% static 'apicollections/js/apicollections.js' %}"></script>
<script type="text/javascript" src="{% static 'base/js/base.js' %}"></script>
{% endblock extrajs %}

View File

@ -6,7 +6,7 @@ URLs for config app
from django.conf.urls import url
from apicollections.views import IndexView, apicollections_save, \
apicollections_delete, DetailView, DeleteCollectionEndpointView
apicollections_delete, DetailView, DeleteCollectionEndpointView, apicollections_update
urlpatterns = [
url(r'^$',
@ -14,6 +14,8 @@ urlpatterns = [
name='apicollections-index'),
url(r'save/apicollection', apicollections_save,
name='apicollection-save'),
url(r'update/apicollection', apicollections_update,
name='apicollection-update'),
url(r'delete/apicollection', apicollections_delete,
name='apicollection-delete'),
url(r'^my-api-collection-ids/(?P<api_collection_id>[\w\@\.\+-]+)$',

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
Views of config app
Views of API Collection app
"""
import json
@ -13,10 +13,10 @@ from django.urls import reverse, reverse_lazy
from base.utils import exception_handle, error_once_only
from .forms import ApiCollectionsForm, ApiCollectionEndpointsForm
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
class IndexView(LoginRequiredMixin, FormView):
"""Index view for config"""
"""Index view for API Collection"""
template_name = "apicollections/index.html"
form_class = ApiCollectionsForm
success_url = reverse_lazy('apicollections-index')
@ -32,10 +32,12 @@ class IndexView(LoginRequiredMixin, FormView):
error_once_only(self.request, response['message'])
else:
api_collections=response['api_collections']
for ac in api_collections:
ac["collection_on_api_explorer_url"] = f"{settings.API_EXPLORER_HOST}/?api-collection-id={ac['api_collection_id']}"
except APIError as err:
messages.error(self.request, err)
except BaseException as err:
error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err))))
except Exception as err:
error_once_only(self.request, err)
else:
# set the default endpoint there, the first item will be the new endpoint.
default_api_endpoint = {
@ -71,8 +73,8 @@ class DetailView(LoginRequiredMixin, FormView):
except APIError as err:
messages.error(self.request, err)
return super(DetailView, self).form_invalid(form)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
error_once_only(self.request, err)
return super(DetailView, self).form_invalid(form)
if 'code' in api_collection_endpoint and api_collection_endpoint['code']>=400:
messages.error(self.request, api_collection_endpoint['message'])
@ -97,11 +99,9 @@ class DetailView(LoginRequiredMixin, FormView):
else:
api_collection_endpoints=response['api_collection_endpoints']
except APIError as err:
error_once_only(self.request, Exception("OBP-API server is not running or do not response properly. "
"Please check OBP-API server. "
"Details: " + str(err)))
except BaseException as err:
error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err))))
messages.error(self.request, result['message'])
except Exception as err:
error_once_only(self.request, err)
else:
context.update({
'api_collection_endpoints': api_collection_endpoints,
@ -115,8 +115,9 @@ class DeleteCollectionEndpointView(LoginRequiredMixin, FormView):
"""Deletes api collection endpoint from API"""
api = API(self.request.session.get('obp'))
try:
urlpath = '/my/api-collections-ids/{}/api-collection-endpoints/{}'\
.format(kwargs['api_collection_id'],kwargs['operation_id'])
get_api_collection_by_id_url = "/my/api-collections/{}".format(kwargs["api_collection_id"])
result = api.get(get_api_collection_by_id_url)
urlpath = '/my/api-collections/{}/api-collection-endpoints/{}'.format(kwargs['api_collection_name'],kwargs['operation_id'])
result = api.delete(urlpath)
if result is not None and 'code' in result and result['code']>=400:
messages.error(request, result['message'])
@ -125,9 +126,8 @@ class DeleteCollectionEndpointView(LoginRequiredMixin, FormView):
messages.success(request, msg)
except APIError as err:
messages.error(request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, 'Unknown Error', err)
redirect_url = reverse('my-api-collection-detail',kwargs={"api_collection_id":kwargs['api_collection_id']})
return HttpResponseRedirect(redirect_url)
@ -144,6 +144,21 @@ def apicollections_save(request):
result = api.post(urlpath, payload = payload)
return result
@exception_handle
@csrf_exempt
def apicollections_update(request):
connector_method_id = request.POST.get('api_collection_id').strip()
urlpath = '/my/api-collections/{}'.format(connector_method_id)
api = API(request.session.get('obp'))
payload = {
'api_collection_name': request.POST.get('api_collection_name').strip(),
'is_sharable': True if request.POST.get('api_collection_is_sharable').strip().lower() == "true" else False,
'description': request.POST.get('api_collection_description').strip()
}
result = api.put(urlpath, payload=payload)
return result
@exception_handle
@csrf_exempt

View File

@ -27,7 +27,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = None
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = False
@ -52,6 +52,7 @@ INSTALLED_APPS = [
'obp',
'consumers',
'accounts',
'accountlist',
'systemviews',
'users',
'branches',
@ -68,7 +69,8 @@ INSTALLED_APPS = [
'methodrouting',
'connectormethod',
'dynamicendpoints',
'apicollections'
'apicollections',
'apicollectionlist'
]
MIDDLEWARE = [
@ -242,15 +244,16 @@ LOGGING = {
LOGIN_URL = reverse_lazy('home')
#Map Java: yyyy-MM-dd'T'HH:mm'Z'
API_DATETIMEFORMAT = '%Y-%m-%dT%H:%M:%SZ'
API_DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
#Map Java: yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
API_DATEFORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
API_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
# the API_Manager the web form date format, eg: 2020-10-11
API_MANAGER_DATE_FORMAT= '%Y-%m-%d'
API_HOST = 'http://127.0.0.1:8080'
API_EXPLORER_HOST = 'http://127.0.0.1:8082'
# Only override this if you have a separate portal instance
API_PORTAL = API_HOST
API_BASE_PATH = '/obp/v'
@ -299,13 +302,17 @@ LOGO_URL = 'https://static.openbankproject.com/images/OBP/favicon.png'
OVERRIDE_CSS_URL = None
VERIFY = True
CALLBACK_BASE_URL = ""
# Local settings can override anything in here
# Global
UNDEFINED = "<undefined>"
# Local settings can replace any value ABOVE
try:
from apimanager.local_settings import * # noqa
except ImportError:
pass
# EVERYTHING BELOW HERE WILL NOT BE OVERWRITTEN BY LOCALSETTINGS!
# EVERYTHING BELOW HERE WILL *NOT* BE OVERWRITTEN BY LOCALSETTINGS!
# DO NOT TRY TO DO SO YOU WILL BE IGNORED!
# Settings here might use parts overwritten in local settings

View File

@ -36,6 +36,7 @@ urlpatterns += i18n_patterns(
LogoutView.as_view(), name='oauth-logout'),
url(r'^systemviews/', include('systemviews.urls')),
url(r'^accounts/', include('accounts.urls')),
url(r'^account/list', include('accountlist.urls')),
url(r'^consumers/', include('consumers.urls')),
url(r'^entitlementrequests/', include('entitlementrequests.urls')),
url(r'^users/', include('users.urls')),
@ -53,6 +54,7 @@ urlpatterns += i18n_patterns(
url(r'^connectormethod/', include('connectormethod.urls')),
url(r'^dynamicendpoints/', include('dynamicendpoints.urls')),
url(r'^apicollections/', include('apicollections.urls')),
url(r'^apicollections-list', include('apicollectionlist.urls')),
)
#prefix_default_language=False,
#)+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -15,6 +15,8 @@ from obp.api import API, APIError
from .forms import CreateAtmForm
from django.utils.translation import ugettext_lazy as _
CHOOSE = "Choose..."
class IndexAtmsView(LoginRequiredMixin, FormView):
"""Index view for ATMs"""
@ -33,12 +35,12 @@ class IndexAtmsView(LoginRequiredMixin, FormView):
fields = form.fields
try:
fields['bank_id'].choices = self.api.get_bank_id_choices()
fields['is_accessible'].choices = [('',_('Choose...')),(True, True), (False, False)]
fields['has_deposit_capability'].choices = [('',_('Choose...')),(True, True), (False, False)]
fields['supported_languages'].choices = [('',_('Choose...')),("en", "en"), ("fr", "fr"), ("de", "de")]
fields['notes'].choices = [('',_('Choose...')),("String1", "String1"), ("String2", "String2")]
fields['supported_currencies'].choices = [('',_('Choose...')),("EUR", "EUR"), ("MXN", "MXN"), ("USD", "USD")]
fields['location_categories'].choices = [('',_('Choose...')),("ATBI", "ATBI"), ("ATBE", "ATBE")]
fields['is_accessible'].choices = [('',_(CHOOSE)),(True, True), (False, False)]
fields['has_deposit_capability'].choices = [('',_(CHOOSE)),(True, True), (False, False)]
fields['supported_languages'].choices = [('',_(CHOOSE)),("en", "en"), ("fr", "fr"), ("de", "de")]
fields['notes'].choices = [('',_(CHOOSE)),("String1", "String1"), ("String2", "String2")]
fields['supported_currencies'].choices = [('',_(CHOOSE)),("EUR", "EUR"), ("MXN", "MXN"), ("USD", "USD")]
fields['location_categories'].choices = [('',_(CHOOSE)),("ATBI", "ATBI"), ("ATBE", "ATBE")]
fields['lobby'].initial = json.dumps({
"monday": [
{
@ -111,16 +113,8 @@ class IndexAtmsView(LoginRequiredMixin, FormView):
"bank_id": data["bank_id"],
"name": data["name"],
"address": json.loads(data['address']),
"location": {
"latitude": float(data["location_latitude"]) if data["location_latitude"] is not None else "",
"longitude": float(data["location_longitude"]) if data["location_longitude"] is not None else ""
},
"meta": {
"license": {
"id": "ODbL-1.0",
"name": data["meta_license_name"] if data["meta_license_name"]!="" else "license name"
}
},
"location": self._location(data),
"meta": self._meta(data),
"monday": {
"opening_time": "",
"closing_time": ""
@ -149,30 +143,22 @@ class IndexAtmsView(LoginRequiredMixin, FormView):
"opening_time": "",
"closing_time": ""
},
"is_accessible": data["is_accessible"] if data["is_accessible"]!="" else "false",
"located_at": data["located_at"] if data["located_at"]!="no-example-provided" else " ",
"more_info": data["more_info"] if data["more_info"]!="" else "false",
"has_deposit_capability": data["has_deposit_capability"] if data["has_deposit_capability"]!="" else "false",
"supported_languages":[data["supported_languages"]],
"services":[data["services"]],
"accessibility_features":[data["accessibility_features"]],
"supported_currencies":[data["supported_currencies"]],
"notes":[data["notes"]],
"location_categories":[data["location_categories"]],
"minimum_withdrawal": data["minimum_withdrawal"] if data["minimum_withdrawal"]!="" else "false",
"branch_identification": data["branch_identification"] if data["branch_identification"]!="" else "false",
"site_identification": data["site_identification"] if data["site_identification"]!="" else "false",
"site_name": data["site_name"] if data["site_name"]!="" else "false",
"cash_withdrawal_national_fee": data["cash_withdrawal_national_fee"] if data["cash_withdrawal_national_fee"]!="" else "false",
"cash_withdrawal_international_fee": data["cash_withdrawal_international_fee"] if data["cash_withdrawal_international_fee"]!="" else "false",
"balance_inquiry_fee": data["balance_inquiry_fee"] if data["balance_inquiry_fee"]!="" else "false",
**self._boolean_payload1(data),
**self._boolean_payload2(data),
}
result = self.api.post(urlpath, payload=payload)
except APIError as err:
messages.error(self.request, "Unknown Error")
messages.error(self.request, err)
return super(IndexAtmsView, self).form_invalid(form)
except Exception as err:
messages.error(self.request, "Unknown Error")
messages.error(self.request, err)
return super(IndexAtmsView, self).form_invalid(form)
if 'code' in result and result['code']>=400:
messages.error(self.request, result['message'])
@ -181,6 +167,39 @@ class IndexAtmsView(LoginRequiredMixin, FormView):
messages.success(self.request, msg)
return super(IndexAtmsView, self).form_valid(form)
def _location(self, data):
return {
"latitude": float(data["location_latitude"]) if data["location_latitude"] is not None else "",
"longitude": float(data["location_longitude"]) if data["location_longitude"] is not None else ""
}
def _meta(self, data):
return {
"license": {
"id": "ODbL-1.0",
"name": data["meta_license_name"] if data["meta_license_name"]!="" else "license name"
}
}
def _boolean_payload1(self, data):
return {
"is_accessible": data["is_accessible"] if data["is_accessible"]!="" else "false",
"located_at": data["located_at"] if data["located_at"]!="no-example-provided" else " ",
"more_info": data["more_info"] if data["more_info"]!="" else "false",
"has_deposit_capability": data["has_deposit_capability"] if data["has_deposit_capability"]!="" else "false",
"minimum_withdrawal": data["minimum_withdrawal"] if data["minimum_withdrawal"]!="" else "false"
}
def _boolean_payload2(self, data):
return {
"branch_identification": data["branch_identification"] if data["branch_identification"]!="" else "false",
"site_identification": data["site_identification"] if data["site_identification"]!="" else "false",
"site_name": data["site_name"] if data["site_name"]!="" else "false",
"cash_withdrawal_national_fee": data["cash_withdrawal_national_fee"] if data["cash_withdrawal_national_fee"]!="" else "false",
"cash_withdrawal_international_fee": data["cash_withdrawal_international_fee"] if data["cash_withdrawal_international_fee"]!="" else "false",
"balance_inquiry_fee": data["balance_inquiry_fee"] if data["balance_inquiry_fee"]!="" else "false"
}
class UpdateAtmsView(LoginRequiredMixin, FormView):
template_name = "atms/update.html"
success_url = '/atms/list'
@ -200,8 +219,8 @@ class UpdateAtmsView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
try:
result = self.api.get(urlpath)
fields['bank_id'].initial = self.kwargs['bank_id']
@ -214,14 +233,6 @@ class UpdateAtmsView(LoginRequiredMixin, FormView):
fields['meta_license_name'].initial = result['meta']['license']['name']
fields['minimum_withdrawal'].initial = result['minimum_withdrawal']
fields['branch_identification'].initial = result['branch_identification']
if result['is_accessible'].lower()=='true':
fields['is_accessible'].choices = [(True, True), (False, False)]
else:
fields['is_accessible'].choices = [(False, False), (True, True)]
if result['has_deposit_capability'].lower()=='true':
fields['has_deposit_capability'].choices = [(True, True), (False, False)]
else:
fields['has_deposit_capability'].choices = [(False, False), (True, True)]
fields['has_deposit_capability'].initial = result['accessibility_features']
fields['site_identification'].initial = result['site_identification']
fields['site_name'].initial = result['site_name']
@ -232,35 +243,53 @@ class UpdateAtmsView(LoginRequiredMixin, FormView):
fields['located_at'].initial = result['located_at']
fields['more_info'].initial = result['more_info']
fields['located_at'].initial = result['located_at']
if result['supported_languages'][0].lower()=='en':
fields['supported_languages'].choices = [("en", "en"), ("fr", "fr"), ("de", "de")]
elif result['supported_languages'][0].lower()=='fr':
fields['supported_languages'].choices = [("fr", "fr"), ("en", "en"), ("de", "de")]
else:
fields['supported_languages'].choices = [("de", "de"),("fr", "fr"), ("en", "en")]
fields['supported_languages'].initial = result['supported_languages']
if result['supported_currencies'][0].lower()=='EUR':
fields['supported_currencies'].choices = [("EUR", "EUR"), ("MXN", "MXN"), ("USD", "USD")]
elif result['supported_currencies'][0].lower()=='MXN':
fields['supported_currencies'].choices = [("MXN", "MXN"), ("EUR", "EUR"), ("USD", "USD")]
else:
fields['supported_currencies'].choices = [("USD", "USD"),("MXN", "MXN"), ("EUR", "EUR")]
fields['supported_currencies'].initial = result['supported_currencies']
if result['notes'][0].lower()=='string1':
fields['notes'].choices = [("String1", "String1"),("String2", "String2")]
else:
fields['notes'].choices = [("String2", "String2"),("String1", "String1")]
fields['notes'].initial = result['notes']
if result['location_categories'][0].lower()=='atbi':
fields['location_categories'].choices = [("ATBI", "ATBI"),("ATBE", "ATBE")]
else:
fields['location_categories'].choices = [("ATBE", "ATBE"),("ATBI", "ATBI")]
fields['location_categories'].initial = result['location_categories']
self._paylod_choices(result, fields)
self._paylod_languages_and_currencies(result, fields)
self._paylod_notes_and_categories(result, fields)
except APIError as err:
messages.error(self.request, err)
except Exception as err:
messages.error(self.request, "Unknown Error {}".format(err))
return form
def _paylod_choices(self, result, fields):
if result['is_accessible'].lower()=='true':
fields['is_accessible'].choices = [(True, True), (False, False)]
else:
fields['is_accessible'].choices = [(False, False), (True, True)]
if result['has_deposit_capability'].lower()=='true':
fields['has_deposit_capability'].choices = [(True, True), (False, False)]
else:
fields['has_deposit_capability'].choices = [(False, False), (True, True)]
def _paylod_languages_and_currencies(self, result, fields):
if result['supported_languages'][0].lower()=='en':
fields['supported_languages'].choices = [("en", "en"), ("fr", "fr"), ("de", "de")]
elif result['supported_languages'][0].lower()=='fr':
fields['supported_languages'].choices = [("fr", "fr"), ("en", "en"), ("de", "de")]
else:
fields['supported_languages'].choices = [("de", "de"),("fr", "fr"), ("en", "en")]
fields['supported_languages'].initial = result['supported_languages']
if result['supported_currencies'][0].lower()=='EUR':
fields['supported_currencies'].choices = [("EUR", "EUR"), ("MXN", "MXN"), ("USD", "USD")]
elif result['supported_currencies'][0].lower()=='MXN':
fields['supported_currencies'].choices = [("MXN", "MXN"), ("EUR", "EUR"), ("USD", "USD")]
else:
fields['supported_currencies'].choices = [("USD", "USD"),("MXN", "MXN"), ("EUR", "EUR")]
fields['supported_currencies'].initial = result['supported_currencies']
def _paylod_notes_and_categories(self, result, fields):
if result['notes'][0].lower()=='string1':
fields['notes'].choices = [("String1", "String1"),("String2", "String2")]
else:
fields['notes'].choices = [("String2", "String2"),("String1", "String1")]
fields['notes'].initial = result['notes']
if result['location_categories'][0].lower()=='atbi':
fields['location_categories'].choices = [("ATBI", "ATBI"),("ATBE", "ATBE")]
else:
fields['location_categories'].choices = [("ATBE", "ATBE"),("ATBI", "ATBI")]
fields['location_categories'].initial = result['location_categories']
def form_valid(self, form):
data = form.cleaned_data
urlpath = '/banks/{}/atms/{}'.format(data["bank_id"],data["atm_id"])
@ -307,23 +336,14 @@ class UpdateAtmsView(LoginRequiredMixin, FormView):
"opening_time": " ",
"closing_time": " "
},
"is_accessible": data["is_accessible"] if data["is_accessible"]!="" else "false",
"located_at": data["located_at"] if data["located_at"]!="no-example-provided" else " ",
"more_info": data["more_info"] if data["more_info"]!="" else "false",
"has_deposit_capability": data["has_deposit_capability"] if data["has_deposit_capability"]!="" else "false",
"supported_languages":[data["supported_languages"]],
"services":[data["services"]],
"accessibility_features":[data["accessibility_features"]],
"supported_currencies":[data["supported_currencies"]],
"notes":[data["notes"]],
"location_categories":[data["location_categories"]],
"minimum_withdrawal": data["minimum_withdrawal"] if data["minimum_withdrawal"]!="" else "false",
"branch_identification": data["branch_identification"] if data["branch_identification"]!="" else "false",
"site_identification": data["site_identification"] if data["site_identification"]!="" else "false",
"site_name": data["site_name"] if data["site_name"]!="" else "false",
"cash_withdrawal_national_fee": data["cash_withdrawal_national_fee"] if data["cash_withdrawal_national_fee"]!="" else "false",
"cash_withdrawal_international_fee": data["cash_withdrawal_international_fee"] if data["cash_withdrawal_international_fee"]!="" else "false",
"balance_inquiry_fee": data["balance_inquiry_fee"] if data["balance_inquiry_fee"]!="" else "false",
**self._update_boolean_payload1(data),
**self._update_boolean_payload2(data)
}
try:
result = self.api.put(urlpath, payload=payload)
@ -341,6 +361,25 @@ class UpdateAtmsView(LoginRequiredMixin, FormView):
messages.success(self.request, msg)
return super(UpdateAtmsView, self).form_valid(form)
def _update_boolean_payload1(self, data):
return {
"is_accessible": data["is_accessible"] if data["is_accessible"]!="" else "false",
"located_at": data["located_at"] if data["located_at"]!="no-example-provided" else " ",
"more_info": data["more_info"] if data["more_info"]!="" else "false",
"has_deposit_capability": data["has_deposit_capability"] if data["has_deposit_capability"]!="" else "false",
"minimum_withdrawal": data["minimum_withdrawal"] if data["minimum_withdrawal"]!="" else "false"
}
def _update_boolean_payload2(self, data):
return {
"branch_identification": data["branch_identification"] if data["branch_identification"]!="" else "false",
"site_identification": data["site_identification"] if data["site_identification"]!="" else "false",
"site_name": data["site_name"] if data["site_name"]!="" else "false",
"cash_withdrawal_national_fee": data["cash_withdrawal_national_fee"] if data["cash_withdrawal_national_fee"]!="" else "false",
"cash_withdrawal_international_fee": data["cash_withdrawal_international_fee"] if data["cash_withdrawal_international_fee"]!="" else "false",
"balance_inquiry_fee": data["balance_inquiry_fee"] if data["balance_inquiry_fee"]!="" else "false"
}
def get_context_data(self, **kwargs):
context = super(UpdateAtmsView, self).get_context_data(**kwargs)
self.bank_id = self.kwargs['bank_id']

View File

@ -9,6 +9,7 @@ from django.contrib import messages
from obp.api import API, APIError, LOGGER
from django.core.cache import cache
USER_CURRENT = "/users/current"
def api_root(request):
"""Returns the configured API_ROOT"""
@ -36,7 +37,7 @@ def override_css_url(request):
def api_username(request):
"""Returns the API username/email of the logged-in user"""
nametodisplay = 'not authenticated'
get_current_user_api_url = '/users/current'
get_current_user_api_url = USER_CURRENT
#Here we can not get the user from obp-api side, so we use the django auth user id here.
cache_key_django_user_id = request.session._session.get('_auth_user_id')
cache_key = '{},{},{}'.format('api_username',get_current_user_api_url, cache_key_django_user_id)
@ -45,38 +46,42 @@ def api_username(request):
apicaches=cache.get(cache_key)
except Exception as err:
apicaches=None
messages.error(request, err)
if not apicaches is None:
return apicaches
else:
if request.user.is_authenticated:
try:
api = API(request.session.get('obp'))
data = api.get(get_current_user_api_url)
username = data['username']
email = data['email']
provider = data['provider']
if "google" in provider:
nametodisplay = email
elif "yahoo" in provider:
nametodisplay = email
elif "microsoft" in provider:
nametodisplay = email
else:
nametodisplay = username
apicaches=cache.set(cache_key, {'API_USERNAME': nametodisplay})
LOGGER.warning('The cache is setting try to api_user_name:')
LOGGER.warning('The cache is setting key is: {}'.format(cache_key))
except APIError as err:
messages.error(request, err)
except Exception as err:
messages.error(request, err)
nametodisplay = authenticated_name(request, get_current_user_api_url)
apicaches=cache.set(cache_key, {'API_USERNAME': nametodisplay})
LOGGER.warning('The cache setting api_user_name is: {}'.format(nametodisplay))
LOGGER.warning('The cache setting key is: {}'.format(cache_key))
return {'API_USERNAME': nametodisplay}
def authenticated_name(request, get_current_user_api_url):
try:
api = API(request.session.get('obp'))
data = api.get(get_current_user_api_url)
username = data['username']
email = data['email']
provider = data['provider']
if "google" in provider:
nametodisplay = email
elif "yahoo" in provider:
nametodisplay = email
elif "microsoft" in provider:
nametodisplay = email
else:
nametodisplay = username
return nametodisplay
except APIError as err:
messages.error(request, err)
except Exception as err:
messages.error(request, err)
def api_user_id(request):
"""Returns the API user id of the logged-in user"""
user_id = 'not authenticated'
get_current_user_api_url = '/users/current'
get_current_user_api_url = USER_CURRENT
#Here we can not get the user from obp-api side, so we use the django auth user id here.
cache_key_django_user_id = request.session._session.get('_auth_user_id')
cache_key = '{},{},{}'.format('api_user_id',get_current_user_api_url, cache_key_django_user_id)
@ -91,7 +96,7 @@ def api_user_id(request):
if request.user.is_authenticated:
try:
api = API(request.session.get('obp'))
data = api.get('/users/current')
data = api.get(USER_CURRENT)
user_id = data['user_id']
apicaches=cache.set(cache_key, {'API_USER_ID': user_id})
LOGGER.warning('The cache is setting try to api_user_id:')

View File

@ -77,7 +77,7 @@ class FilterTime(BaseFilter):
print(filtered)
for item in data:
item_date = datetime.strptime(
item[self.time_fieldname], settings.API_DATETIMEFORMAT)
item[self.time_fieldname], settings.API_DATE_TIME_FORMAT)
if now - item_date <= delta:
filtered.append(item)
return filtered

View File

@ -208,13 +208,17 @@ table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSo
}
.language-select {
text-decoration: none;
color:#fff;
margin-left:5rem;
text-decoration: none !important;
}
#uk {
cursor:pointer;
}
#es {
cursor:pointer;
}1
}
.language_underline_format > a > span:hover
{
text-decoration: underline;
font-weight: bold !important;
}

View File

@ -1,8 +1,33 @@
$(document).ready(function($) {
// Select a language from navbar which want to change.
var currentURL = window.location.href;
const element = document.getElementById('gb')
element.addEventListener("click", () => {
if (currentURL.includes("/es/")) {
location.href = currentURL.split("/es/")[0] + "/en/" + currentURL.split("/es/")[1]
}
});
const element1 = document.getElementById('es')
element1.addEventListener("click", () => {
if (currentURL.includes("/en/")) {
location.href = currentURL.split("/en/")[0] + "/es/" + currentURL.split("/en/")[1]
}
});
$('table.tablesorter').tablesorter();
$('#authentication-select').change(function() {
$('.authentication-method').hide();
var method = $(this).val();
let method = $(this).val();
$(`#authenticate-${method}`).show();
});
});
// Redirect to API-Explorer, just click on Try Ii button in API-Collection and Dynamic Endpoint after success response.
function redirect_api_explorer_url(api_explorer_url) {
var currentURL = window.location.href.split("/");
if (currentURL[3] == "en") {
location.href = api_explorer_url + "&locale=en_GB";
}
else {
location.href = api_explorer_url + "&locale=es_ES";
}
}

View File

@ -14,7 +14,6 @@
<link href="{% static 'css/base.css' %}" rel="stylesheet">
<link href="{% static 'css/jsoneditor.min.css' %}" rel="stylesheet">
<link href="{% static 'css/obpjsoneditor.css' %}" rel="stylesheet">
<!--<link href="{{ override_css_url }}" rel="stylesheet">-->
{% block extracss %}{% endblock extracss %}
</head>
@ -59,23 +58,24 @@
<li {% if metrics_summary_url in request.path %} class="active" {% endif %}><a href="{{ metrics_summary_url }}">{% trans "KPI Dashboard" %}</a></li>
</ul>
</li>
{% url "system_view" as system_view_url %} {% url "accounts-create" as accounts_create_url %} {% url "branches_list" as branches_list_url %} {% url "customers-create" as customers_create_url %} {% url "customer-list" as customer_list_url %} {% url "atms_create" as atms_create_url %} {% url "atm-list" as atm_list_url %} {% url "product-list" as product_list_url %} {% url "products-create" as product_create_url %}
{% url "system_view" as system_view_url %} {% url "accounts-create" as accounts_create_url %} {% url "account-list" as accounts_list_url %} {% url "branches_list" as branches_list_url %} {% url "customers-create" as customers_create_url %} {% url "customer-list" as customer_list_url %} {% url "atms_create" as atms_create_url %} {% url "atm-list" as atm_list_url %} {% url "product-list" as product_list_url %} {% url "products-create" as product_create_url %}
<li class="dropdown{% if customers_create_url in request.path %} active{% endif %}">
<a href="#" data-toggle="dropdown" class="dropdown-toggle">{% trans "Resources" %}</a>
<ul class="dropdown-menu">
<li {% if system_view_url in request.path %} class="active" {% endif %}><a href="{{ system_view_url }}">{% trans "System View" %}</a></li>
<li {% if system_view_url in request.path %} class="active" {% endif %}><a href="{{ system_view_url }}">{% trans "System Views" %}</a></li>
<hr class="dropdown-hr">
<li {% if accounts_create_url in request.path %} class="active" {% endif %}><a href="{{ accounts_create_url }}">{% trans "Account Create" %}</a></li>
<li {% if customers_create_url in request.path %} class="active" {% endif %}><a href="{{ customers_create_url }}">{% trans "Customers" %}</a></li>
<li {% if accounts_list_url in request.path %} class="active" {% endif %}><a href="{{ accounts_list_url }}">{% trans "Account List" %}</a></li>
<li {% if customers_create_url in request.path %} class="active" {% endif %}><a href="{{ customers_create_url }}">{% trans "Customer Create" %}</a></li>
<li {% if customer_list_url in request.path %} class="active" {% endif %}><a href="{{ customer_list_url }}">{% trans "Customer List" %}</a></li>
<li {% if branches_list_url in request.path %} class="active" {% endif %}><a href="{{ branches_list_url }}">{% trans "Branches" %}</a></li>
<li {% if branches_list_url in request.path %} class="active" {% endif %}><a href="{{ branches_list_url }}">{% trans "Branch Create" %}</a></li>
<li {% if atms_create_url in request.path %} class="active" {% endif %}><a href="{{ atms_create_url }}">{% trans "ATM Create" %}</a></li>
<li {% if atm_list_url in request.path %} class="active" {% endif %}><a href="{{ atm_list_url }}">{% trans "ATM List" %}</a></li>
<li {% if product_create_url in request.path %} class="active" {% endif %}><a href="{{ product_create_url }}">{% trans "Product Create" %}</a></li>
<li {% if product_list_url in request.path %} class="active" {% endif %}><a href="{{ product_list_url }}">{% trans "Product List" %}</a></li>
</ul>
</li>
{% url "config-index" as config_index_url %} {% url "webui-index" as webui_props_index_url %} {% url "methodrouting-index" as methodrouting_index_url %} {% url "connectormethod" as connectormethod_url %} {% url "dynamicendpoints-index" as dynamic_endpoints_index_url %} {% url "apicollections-index" as api_collections_index_url %}
{% url "config-index" as config_index_url %} {% url "webui-index" as webui_props_index_url %} {% url "methodrouting-index" as methodrouting_index_url %} {% url "connectormethod" as connectormethod_url %} {% url "dynamicendpoints-index" as dynamic_endpoints_index_url %} {% url "apicollections-index" as api_collections_index_url %} {% url "apicollection-list" as api_collections_list_url %}
<li class="dropdown{% if config_index_url in request.path %} active{% endif %}">
<a href="#" data-toggle="dropdown" class="dropdown-toggle">{% trans "Configurations" %}</a>
<ul class="dropdown-menu">
@ -91,6 +91,8 @@
</li>
<hr class="dropdown-hr">
<li {% if api_collections_index_url in request.path %} class="active" {% endif %}><a href="{{ api_collections_index_url }}">{% trans "My API Collections" %}</a></li>
<hr class="dropdown-hr">
<li {% if api_collections_list_url in request.path %} class="active" {% endif %}><a href="{{ api_collections_list_url }}">{% trans "All API Collections" %}</a></li>
</ul>
</li>
{% if SHOW_API_TESTER %}
@ -98,19 +100,16 @@
<a href="{{ API_TESTER_URL }}">{% trans "API Tester" %}</a>
</li>
{% endif %}
<!--<ul class="nav navbar-nav navbar-right" style="padding-top:13px; margin-left:12rem">-->
<li>
{% if user.is_authenticated %}
<p class="navbar-right button-select"><span id="navbar-login-username">{{API_USERNAME}}</span>&nbsp;&nbsp;<a href="/logout" class="btn btn-default">{% trans "Logout" %} </a></p>
{% endif %}
</li>
<!--</ul>-->
<li class="language-select"><a style="color:#fff;">Language
<span id="uk">EN</span>
<li class="language-select language_underline_format"><a style="color:#fff; text-decoration: none !important;">Language
<span id="gb">EN</span>
|
<span id="es">ES</span></a></li>
</ul>
<!--/.nav-collapse -->
</div>
</div>
</nav>
@ -130,27 +129,12 @@
<div class="footer-content-wrapper" data-lift="WebUI.homePage" style="cursor:pointer">
</div>
</div>
<script>
var currentURL = window.location.href;
const element = document.getElementById('uk')
element.addEventListener("click", () => {
if (currentURL.includes("/es/")) {
location.href = currentURL.split("/es/")[0] + "/en/" + currentURL.split("/es/")[1]
}
});
const element1 = document.getElementById('es')
element1.addEventListener("click", () => {
if (currentURL.includes("/en/")) {
location.href = currentURL.split("/en/")[0] + "/es/" + currentURL.split("/en/")[1]
}
});
</script>
<footer>
<div class="container">
<p class="text-muted">
<a title="API ROOT" href="{{ API_ROOT }}">API ROOT: {{ API_ROOT }}</a> |
<a title="Open Bank Project" href="https://openbankproject.com?locale=en_GB">Open Bank Project</a> | Powered by <a title="TESOBE" href="http://tesobe.com">TESOBE</a> |
<small>Copyright &copy; 2016 - 2020</small>
<small>Copyright &copy; 2016 - 2023</small>
</p>
</div>
</footer>

View File

@ -46,10 +46,6 @@
<label for="password">Password:</label>
{{ directlogin_form.password }}
</div>
<!--<div class="form-group"style="visibility:hidden">
<label for="consumer-key">Consumer Key:</label>
{{ directlogin_form.consumer_key }}
</div>-->
<button class="btn btn-primary">Login</button>
</form>
</div>

View File

@ -4,7 +4,7 @@ Base utilities
"""
from django.contrib.humanize.templatetags.humanize import naturaltime
from datetime import datetime, timedelta
from apimanager.settings import API_DATEFORMAT, API_MANAGER_DATE_FORMAT
from apimanager.settings import API_DATE_FORMAT, API_MANAGER_DATE_FORMAT
from base import context_processors
from django.contrib import messages
import functools
@ -24,7 +24,6 @@ def get_cache_key_for_current_call(request, urlpath):
"""we will generate the cache key by login username+urlpath
url path may contain lots of special characters, here we use the hash method first.
"""
#TODO, we need the obp user.provide there.
return context_processors.api_username(request).get('API_USERNAME') + str(hash(urlpath))
@ -62,7 +61,7 @@ def convert_form_date_to_obpapi_datetime_format(form_to_date_string):
"""
convert the String 2020-10-22 to 2020-10-22T00:00:00.000000Z
"""
return datetime.strptime(form_to_date_string, API_MANAGER_DATE_FORMAT).strftime(API_DATEFORMAT)
return datetime.strptime(form_to_date_string, API_MANAGER_DATE_FORMAT).strftime(API_DATE_FORMAT)
def return_to_days_ago(date, days):
"""
@ -71,4 +70,4 @@ def return_to_days_ago(date, days):
days =1
return 2020-10-21T00:00:00.000000Z
"""
return (datetime.strptime(date, API_DATEFORMAT) - timedelta(days)).strftime(API_DATEFORMAT)
return (datetime.strptime(date, API_DATE_FORMAT) - timedelta(days)).strftime(API_DATE_FORMAT)

View File

@ -15,6 +15,8 @@ from obp.api import API, APIError
from .forms import CreateBranchForm
from base.views import get_banks
LICENSE_NAME = "license name"
class IndexBranchesView(LoginRequiredMixin, FormView):
"""Index view for branches"""
template_name = "branches/index.html"
@ -122,8 +124,8 @@ class IndexBranchesView(LoginRequiredMixin, FormView):
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return form
@ -143,14 +145,14 @@ class IndexBranchesView(LoginRequiredMixin, FormView):
"meta": {
"license": {
"id": "PDDL",
"name": data["meta_license_name"] if data["meta_license_name"]!="" else "license name"
"name": data["meta_license_name"] if data["meta_license_name"]!="" else LICENSE_NAME
}
},
"lobby": json.loads(data['lobby']),
"drive_up": json.loads(data["drive_up"]),
"branch_routing": {
"scheme": data["branch_routing_scheme"] if data["branch_routing_scheme"]!="" else "license name",
"address": data["branch_routing_address"] if data["branch_routing_address"]!="" else "license name"
"scheme": data["branch_routing_scheme"] if data["branch_routing_scheme"]!="" else LICENSE_NAME,
"address": data["branch_routing_address"] if data["branch_routing_address"]!="" else LICENSE_NAME
},
"is_accessible": data["is_accessible"] if data["is_accessible"]!="" else "false",
"accessibleFeatures": data["accessibleFeatures"] if data["accessibleFeatures"]!="" else "accessible features name",
@ -163,7 +165,7 @@ class IndexBranchesView(LoginRequiredMixin, FormView):
error_once_only(self.request, err)
return super(IndexBranchesView, self).form_invalid(form)
except Exception as err:
error_once_only(self.request, "Unknown Error")
error_once_only(self.request, err)
return super(IndexBranchesView, self).form_invalid(form)
if 'code' in result and result['code']>=400:
error_once_only(self.request, result['message'])
@ -222,8 +224,8 @@ class UpdateBranchesView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
try:
result = self.api.get(urlpath)
fields['bank_id'].initial = self.kwargs['bank_id']
@ -272,8 +274,8 @@ class UpdateBranchesView(LoginRequiredMixin, FormView):
"lobby": json.loads(data["lobby"]),
"drive_up": json.loads(data["drive_up"]),
"branch_routing": {
"scheme": data["branch_routing_scheme"] if data["branch_routing_scheme"] != "" else "license name",
"address": data["branch_routing_address"] if data["branch_routing_address"] != "" else "license name"
"scheme": data["branch_routing_scheme"] if data["branch_routing_scheme"] != "" else LICENSE_NAME,
"address": data["branch_routing_address"] if data["branch_routing_address"] != "" else LICENSE_NAME
},
"is_accessible": data["is_accessible"],
"accessibleFeatures": data["accessibleFeatures"],
@ -289,8 +291,8 @@ class UpdateBranchesView(LoginRequiredMixin, FormView):
except APIError as err:
messages.error(self.request, err)
return super(UpdateBranchesView, self).form_invalid(form)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return super(UpdateBranchesView, self).form_invalid(form)
msg = 'Branch {} for Bank {} has been created successfully!'.format( # noqa
data["branch_id"], data["bank_id"])

View File

@ -5,7 +5,7 @@ $(document).ready(function($) {
}
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
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';
let cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';

View File

@ -25,8 +25,8 @@ class IndexView(LoginRequiredMixin, TemplateView):
except APIError as err:
messages.error(self.request, err)
config = {}
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
config = {}
context.update({

View File

@ -1,11 +1,10 @@
$(document).ready(function($) {
$('.runner button.forSave').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var connector_method_name = $(runner).find('.connector_method_name').val();
var connector_method_programming_lang = $(runner).find('.connector_method_programming_lang').val();
var connector_method_body = $(runner).find('.connector_method_body').val();
let runner = $(this).parent().parent().parent();
let connector_method_name = $(runner).find('.connector_method_name').val();
let connector_method_programming_lang = $(runner).find('.connector_method_programming_lang').val();
let connector_method_body = $(runner).find('.connector_method_body').val();
$('.runner button.forSave').attr("disabled", "disabled");
$('.runner button.forDelete').attr("disabled", "disabled");
@ -20,11 +19,10 @@ $(document).ready(function($) {
$('.runner button.forUpdate').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var connector_method_id = $(runner).find('.connector_method_id').html();
var connector_method_programming_lang_update = $(runner).find('.connector_method_programming_lang_update').val();
var connector_method_body_update = $(runner).find('.connector_method_body_update').val();
let runner = $(this).parent().parent().parent();
let connector_method_id = $(runner).find('.connector_method_id').html();
let connector_method_programming_lang_update = $(runner).find('.connector_method_programming_lang_update').val();
let connector_method_body_update = $(runner).find('.connector_method_body_update').val();
$('.runner button.forSave').attr("disabled", "disabled");
$('.runner button.forUpdate').attr("disabled", "disabled");

View File

@ -34,8 +34,8 @@ class IndexView(LoginRequiredMixin, FormView):
connectormethod=response['connector_methods']
except APIError as err:
messages.error(self.request, err)
except BaseException as err:
error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err))))
except Exception as err:
error_once_only(self.request, err)
else:
default_connector_method_endpoint = {
"connector_method_name": "Method Name",
@ -73,6 +73,5 @@ def connectormethod_update(request):
'programming_lang': request.POST.get('connector_method_programming_lang_update'),
'method_body': request.POST.get('connector_method_body_update').strip()
}
result = HttpResponse(content_type = 'application/json')
result = api.put(urlpath, payload=payload)
return result

View File

@ -16,9 +16,6 @@ from base.filters import BaseFilter, FilterTime
from .forms import ApiConsumersForm
# import logging
# logger = logging.getLogger(__name__)
class FilterAppType(BaseFilter):
"""Filter consumers by application type"""
@ -47,7 +44,7 @@ class IndexView(LoginRequiredMixin, TemplateView):
"""Scrubs data in the given consumers to adher to certain formats"""
for consumer in consumers:
consumer['created'] = datetime.strptime(
consumer['created'], settings.API_DATETIMEFORMAT)
consumer['created'], settings.API_DATE_TIME_FORMAT)
return consumers
def compile_statistics(self, consumers):
@ -129,7 +126,6 @@ class DetailView(LoginRequiredMixin, FormView):
'per_week_call_limit': data['per_week_call_limit'],
'per_month_call_limit': data['per_month_call_limit']
}
user = self.api.put(urlpath, payload=payload)
except APIError as err:
messages.error(self.request, err)
return super(DetailView, self).form_invalid(api_consumers_form)
@ -150,7 +146,7 @@ class DetailView(LoginRequiredMixin, FormView):
urlpath = '/management/consumers/{}'.format(self.kwargs['consumer_id'])
consumer = api.get(urlpath)
consumer['created'] = datetime.strptime(
consumer['created'], settings.API_DATETIMEFORMAT)
consumer['created'], settings.API_DATE_TIME_FORMAT)
call_limits_urlpath = '/management/consumers/{}/consumer/call-limits'.format(self.kwargs['consumer_id'])
consumer_call_limtis = api.get(call_limits_urlpath)
@ -191,8 +187,8 @@ class EnableDisableView(LoginRequiredMixin, RedirectView):
messages.success(self.request, self.success)
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown")
except APIError as err:
messages.error(self.request, err)
urlpath = self.request.POST.get('next', reverse('consumers-index'))
query = self.request.GET.urlencode()

View File

@ -17,8 +17,6 @@ from obp.api import API, APIError
from base.views import get_banks
import csv
class CustomerListView(CreateView, LoginRequiredMixin, FormView ):
template_name = "customerlist/customerlist.html"
success_url = '/customers/list'
@ -28,9 +26,7 @@ class CustomerListView(CreateView, LoginRequiredMixin, FormView ):
try:
self.bankids = get_banks(self.request)
customers_list = []
#for bank_id in self.bankids:
urlpath = '/customers'
#urlpath = 'http://127.0.0.1:8080/obp/v4.0.0/my/customers'
result = api.get(urlpath)
if 'customers' in result:
customers_list.extend(result['customers'])

View File

@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _
from obp.api import APIError
PLACEHOLDER = "2013-01-22T00:08:00Z"
class CreateCustomerForm(forms.Form):
bank_id = forms.ChoiceField(
@ -80,10 +81,10 @@ class CreateCustomerForm(forms.Form):
)
face_image_date = forms.DateTimeField(
label=_('Face Image Date'),
input_formats=[settings.API_DATETIMEFORMAT],
input_formats=[settings.API_DATE_TIME_FORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': '2013-01-22T00:08:00Z',
'placeholder': PLACEHOLDER,
'class': 'form-control',
}
),
@ -91,10 +92,10 @@ class CreateCustomerForm(forms.Form):
)
date_of_birth = forms.DateTimeField(
label=_('Date of Birth'),
input_formats=[settings.API_DATETIMEFORMAT],
input_formats=[settings.API_DATE_TIME_FORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': '2013-01-22T00:08:00Z',
'placeholder': PLACEHOLDER,
'class': 'form-control',
}
),
@ -125,7 +126,7 @@ class CreateCustomerForm(forms.Form):
label=_('Date of Birth of Dependants'),
widget=forms.TextInput(
attrs={
'placeholder': '2013-01-22T00:08:00Z, 2010-01-22T00:08:00Z',
'placeholder': f'{PLACEHOLDER}, 2010-01-22T00:08:00Z',
'class': 'form-control',
}
),
@ -203,10 +204,10 @@ class CreateCustomerForm(forms.Form):
)
last_ok_date = forms.DateTimeField(
label=_('Last OK Date'),
input_formats=[settings.API_DATETIMEFORMAT],
input_formats=[settings.API_DATE_TIME_FORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': '2013-01-22T00:08:00Z',
'placeholder': PLACEHOLDER,
'class': 'form-control',
}
),
@ -220,14 +221,14 @@ class CreateCustomerForm(forms.Form):
def clean_face_image_date(self):
data = self.cleaned_data['face_image_date']
if data:
return data.strftime(settings.API_DATETIMEFORMAT)
return data.strftime(settings.API_DATE_TIME_FORMAT)
else:
return None
def clean_date_of_birth(self):
data = self.cleaned_data['date_of_birth']
if data:
return data.strftime(settings.API_DATETIMEFORMAT)
return data.strftime(settings.API_DATE_TIME_FORMAT)
else:
return None

View File

@ -35,10 +35,10 @@ class CreateView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
fields['last_ok_date'].initial =\
datetime.datetime.now().strftime(settings.API_DATETIMEFORMAT)
datetime.datetime.now().strftime(settings.API_DATE_TIME_FORMAT)
return form
def form_valid(self, form):
@ -71,15 +71,15 @@ class CreateView(LoginRequiredMixin, FormView):
'employment_status': data['employment_status'],
'kyc_status': data['kyc_status'],
'last_ok_date':
data['last_ok_date'].strftime(settings.API_DATETIMEFORMAT),
data['last_ok_date'].strftime(settings.API_DATE_TIME_FORMAT),
}
try:
result = self.api.post(urlpath, payload=payload)
except APIError as err:
messages.error(self.request, err)
return super(CreateView, self).form_invalid(form)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return super(CreateView, self).form_invalid(form)
msg = 'Customer number {} for user {} has been created successfully!'.format( # noqa
result['customer_number'], data['username'])

View File

@ -7,14 +7,14 @@ $(document).ready(function($) {
//each dynamic_endpoint will have each own json_editor, and will put data into it when click `parameter` box
//and will use the data from click `save` button.
var json_editors = []
let json_editors = []
$('.parameters').click(function() {
var runner = $(this).parent().parent().parent();
var json_editor_id= $(runner).find('.jsoneditor_div')[0].id;
var json_editor_number = json_editor_id.replace("jsoneditor","");
var container = $("#"+json_editor_id);
parameters = JSON.parse($(runner).find('textarea[name="parameters"]').text());
var jsoneditor_div = $(runner).find('.jsoneditor_div');
let runner = $(this).parent().parent().parent();
let json_editor_id= $(runner).find('.jsoneditor_div')[0].id;
let json_editor_number = json_editor_id.replace("jsoneditor","");
let container = $("#"+json_editor_id);
let parameters = JSON.parse($(runner).find('textarea[name="parameters"]').text());
let jsoneditor_div = $(runner).find('.jsoneditor_div');
//make sure only create one jsoneditor_div block
if(!(jsoneditor_div.css("display") ==="block")){
json_editors[json_editor_number] = new JSONEditor(container[0], options, parameters);
@ -27,11 +27,10 @@ $(document).ready(function($) {
});
$('.runner button.forSave').click(function() {
var t = $(this);
var runner = $(this).parent().parent().parent();
var jsoneditor_id= $(runner).find('.jsoneditor_div')[0].id
var json_editor_number = jsoneditor_id.replace("jsoneditor","")
parameters_Json_editor = JSON.stringify(json_editors[json_editor_number].get());
let runner = $(this).parent().parent().parent();
let jsoneditor_id= $(runner).find('.jsoneditor_div')[0].id
let json_editor_number = jsoneditor_id.replace("jsoneditor","")
let parameters_Json_editor = JSON.stringify(json_editors[json_editor_number].get());
console.log("parameters_Json_editor:"+parameters_Json_editor)
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
@ -45,9 +44,8 @@ $(document).ready(function($) {
});
$('.runner button.forDelete').click(function() {
var t = $(this);
var runner = $(this).parent().parent().parent();
dynamic_endpoint_id = $(runner).find('.dynamic_endpoint_id').text();
let runner = $(this).parent().parent().parent();
let dynamic_endpoint_id = $(runner).find('.dynamic_endpoint_id').text();
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
$.post('dynamicendpoints/delete/dynamicendpoint', {

View File

@ -4,53 +4,60 @@
{% block page_title %}{{ block.super }} / Dynamic Endpoints{% endblock page_title %}
{% block content %}
<h1>{% trans "Dynamic Endpoints" %}</h1>
<div class="row">
<div class="col-xs-12 col-sm-2">
<label class="form-group">{% trans "ENDPOINT ID" %}:</label> <br>
</div>
<div class="col-xs-12 col-sm-10">
<label class="form-group">{% trans "SWAGGER STRING" %}:</label> <br>
</div>
<h1>{% trans "Dynamic Endpoints" %}</h1>
<div class="row">
<div class="col-xs-12 col-sm-2">
<label class="form-group">{% trans "ENDPOINT ID" %}:</label> <br>
</div>
<form method="post">
{% csrf_token %}
{% for dynamic_endpoint in dynamic_endpoints %}
<div class="runner">
<div class="row">
<div class="col-xs-12 col-sm-2">
<div class="form-group" cols="1" rows="1">
<div class="dynamic_endpoint_id">{{ dynamic_endpoint.dynamic_endpoint_id }}</div></div>
</div>
<div class="col-xs-12 col-sm-8">
<textarea cols="40" rows="1" class="form-control parameters"
name="parameters">{{ dynamic_endpoint.swagger_string }}</textarea>
</div>
{% if forloop.counter0 == 0 %}
<div class="col-sm-12 col-sm-2">
<div class="form-group">
<button class="btn btn-primary btn-green forSave">{% trans "Create" %} </button><span style="display: none;margin-left: 5px;background-color:#00cc00">{% trans "saved." %}</span>
</div>
</div>
{% endif %}
{% if forloop.counter0 > 0 %}
<div class="col-sm-12 col-sm-2">
<div class="form-group">
<button class="btn btn-primary btn-red forDelete">{% trans "Delete" %}</button>
</div>
</div>
{% endif %}
<div class="col-sm-12 col-sm-12">
<div id="jsoneditor{{forloop.counter0}}" style="display: none" class ="jsoneditor_div"></div>
<div class="col-xs-12 col-sm-10">
<label class="form-group">{% trans "SWAGGER STRING" %}:</label> <br>
</div>
</div>
<form method="post">
{% csrf_token %}
{% for dynamic_endpoint in dynamic_endpoints %}
<div class="runner">
<div class="row">
<div class="col-xs-12 col-sm-2">
<div class="form-group" cols="1" rows="1">
<!--Add Try It button using Dynamic Endpoint ID after success response for redirecting API-Explorer-->
{% if dynamic_endpoint.dynamicendpoint_on_api_explorer_url %}
<a class="dynamic_endpoint_id btn btn-primary" onclick="redirect_api_explorer_url('{{dynamic_endpoint.dynamicendpoint_on_api_explorer_url}}')" value="{{dynamic_endpoint.dynamic_endpoint_id}}">Try It</a>
{% else %}
<span>{{dynamic_endpoint.dynamic_endpoint_id}}</span>
{% endif %}
</div>
</div>
<div class="col-xs-12 col-sm-8">
<textarea cols="40" rows="1" class="form-control parameters"
name="parameters">{{ dynamic_endpoint.swagger_string }}</textarea>
</div>
{% if forloop.counter0 == 0 %}
<div class="col-sm-12 col-sm-2">
<div class="form-group">
<button class="btn btn-primary btn-green forSave">{% trans "Create" %} </button><span style="display: none;margin-left: 5px;background-color:#00cc00">{% trans "saved." %}</span>
</div>
</div>
{% endif %}
{% if forloop.counter0 > 0 %}
<div class="col-sm-12 col-sm-2">
<div class="form-group">
<button class="btn btn-primary btn-red forDelete">{% trans "Delete" %}</button>
</div>
</div>
{% endif %}
<div class="col-sm-12 col-sm-12">
<div id="jsoneditor{{forloop.counter0}}" style="display: none" class ="jsoneditor_div"></div>
</div>
</div>
</div>
{% endfor %}
</form>
</form>
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'dynamicendpoints/js/dynamicendpoints.js' %}"></script>
{% endblock extrajs %}
<script type="text/javascript" src="{% static 'dynamicendpoints/js/dynamicendpoints.js' %}"></script>
<script type="text/javascript" src="{% static 'base/js/base.js' %}"></script>
{% endblock extrajs %}

View File

@ -4,6 +4,7 @@ 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
@ -11,7 +12,12 @@ from base.utils import exception_handle, error_once_only
from .forms import DynamicEndpointsForm
from django.urls import reverse_lazy
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
DEFINITIONS_USER = "#/definitions/user"
UNEXPECTED_ERROR = "unexpected error"
RESPONSES_UNEXPECTED_ERROR = "#/responses/unexpectedError"
DEFINITIONS_API_ERROR = "#/definitions/APIError"
class IndexView(LoginRequiredMixin, FormView):
"""Index view for config"""
@ -30,10 +36,13 @@ class IndexView(LoginRequiredMixin, FormView):
error_once_only(self.request, response['message'])
else:
dynamic_endpoints=response['dynamic_endpoints']
#Accessing API-Explorer URL, parameters API-Collection Id and selected Language eg. locale=en_GB (for English)
for de in dynamic_endpoints:
de["dynamicendpoint_on_api_explorer_url"] = f"{settings.API_EXPLORER_HOST}/?api-dynamic_endpoint-id={de['dynamic_endpoint_id']}"
except APIError as err:
messages.error(self.request, err)
except BaseException as err:
error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err))))
except Exception as err:
error_once_only(self.request, err)
else:
# set the default endpoint there, the first item will be the new endpoint.
default_dynamic_endpoint = {
@ -63,20 +72,20 @@ class IndexView(LoginRequiredMixin, FormView):
"in":"body",
"required":True,
"schema":{
"$ref":"#/definitions/user"
"$ref":DEFINITIONS_USER
}
}],
"responses":{
"201":{
"description":"create user successful and return created user object",
"schema":{
"$ref":"#/definitions/user"
"$ref": DEFINITIONS_USER
}
},
"500":{
"description":"unexpected error",
"description":UNEXPECTED_ERROR,
"schema":{
"$ref":"#/responses/unexpectedError"
"$ref":RESPONSES_UNEXPECTED_ERROR
}
}
}
@ -93,7 +102,7 @@ class IndexView(LoginRequiredMixin, FormView):
"200":{
"description":"the successful get requested user by user ID",
"schema":{
"$ref":"#/definitions/user"
"$ref":DEFINITIONS_USER
}
},
"400":{
@ -105,13 +114,13 @@ class IndexView(LoginRequiredMixin, FormView):
"404":{
"description":"user not found",
"schema":{
"$ref":"#/definitions/APIError"
"$ref":DEFINITIONS_API_ERROR
}
},
"500":{
"description":"unexpected error",
"description":UNEXPECTED_ERROR,
"schema":{
"$ref":"#/responses/unexpectedError"
"$ref":RESPONSES_UNEXPECTED_ERROR
}
}
}
@ -125,13 +134,13 @@ class IndexView(LoginRequiredMixin, FormView):
"200":{
"description":"get all users",
"schema":{
"$ref":"#/definitions/users"
"$ref":DEFINITIONS_USER
}
},
"404":{
"description":"user not found",
"schema":{
"$ref":"#/definitions/APIError"
"$ref":DEFINITIONS_API_ERROR
}
}
}
@ -144,20 +153,20 @@ class IndexView(LoginRequiredMixin, FormView):
"in":"body",
"required":True,
"schema":{
"$ref":"#/definitions/user"
"$ref":DEFINITIONS_USER
}
}],
"responses":{
"200":{
"description":"create user successful and return created user object",
"schema":{
"$ref":"#/definitions/user"
"$ref":DEFINITIONS_USER
}
},
"500":{
"description":"unexpected error",
"description":UNEXPECTED_ERROR,
"schema":{
"$ref":"#/responses/unexpectedError"
"$ref":RESPONSES_UNEXPECTED_ERROR
}
}
}
@ -181,9 +190,9 @@ class IndexView(LoginRequiredMixin, FormView):
}
},
"500":{
"description":"unexpected error",
"description":UNEXPECTED_ERROR,
"schema":{
"$ref":"#/responses/unexpectedError"
"$ref":RESPONSES_UNEXPECTED_ERROR
}
}
}
@ -217,7 +226,7 @@ class IndexView(LoginRequiredMixin, FormView):
"description":"array of users",
"type":"array",
"items":{
"$ref":"#/definitions/user"
"$ref":DEFINITIONS_USER
}
},
"APIError":{
@ -237,15 +246,15 @@ class IndexView(LoginRequiredMixin, FormView):
},
"responses":{
"unexpectedError":{
"description":"unexpected error",
"description":UNEXPECTED_ERROR,
"schema":{
"$ref":"#/definitions/APIError"
"$ref":DEFINITIONS_API_ERROR
}
},
"invalidRequest":{
"description":"invalid request",
"schema":{
"$ref":"#/definitions/APIError"
"$ref":DEFINITIONS_API_ERROR
}
}
},
@ -273,10 +282,10 @@ class IndexView(LoginRequiredMixin, FormView):
@exception_handle
@csrf_exempt
def dynamicendpoints_save(request):
parameters_Json_editor = request.POST.get('parameters_Json_editor')
parameters_Json_editor_dynamic = request.POST.get('parameters_Json_editor')
api = API(request.session.get('obp'))
urlpath = '/management/dynamic-endpoints'
result = api.post(urlpath, payload=json.loads(parameters_Json_editor) )
result = api.post(urlpath, payload=json.loads(parameters_Json_editor_dynamic) )
return result

View File

@ -12,6 +12,7 @@ from datetime import datetime
from django.conf import settings
from django.urls import reverse
from django.http import HttpResponseRedirect
from apimanager.settings import UNDEFINED
@ -23,7 +24,7 @@ class IndexView(LoginRequiredMixin, TemplateView):
"""Scrubs data in the given entitlement requests to adher to certain formats"""
for entitlement_request in entitlement_requests:
entitlement_request['created'] = datetime.strptime(
entitlement_request['created'], settings.API_DATETIMEFORMAT)
entitlement_request['created'], settings.API_DATE_TIME_FORMAT)
return entitlement_requests
def get_context_data(self, **kwargs):
@ -44,8 +45,8 @@ class IndexView(LoginRequiredMixin, TemplateView):
entitlement_requests = sorted(entitlement_requests, key=lambda k: k['created'], reverse=True)
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
context.update({
'entitlementrequests': entitlement_requests,
@ -66,12 +67,12 @@ class RejectEntitlementRequest(LoginRequiredMixin, View):
messages.error(self.request, response['message'])
else:
msg = 'Entitlement Request with role {} has been deleted.'.format(
request.POST.get('role_name', '<undefined>'))
request.POST.get('role_name', UNDEFINED))
messages.success(request, msg)
except APIError as err:
messages.error(request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return HttpResponseRedirect(reverse('entitlementrequests-index'))
@ -86,32 +87,32 @@ class AcceptEntitlementRequest(LoginRequiredMixin, View):
try:
urlpath = '/users/{}/entitlements'.format(kwargs['user_id'])
payload = {
'bank_id': request.POST.get('bank_id', '<undefined>'),
'role_name': request.POST.get('role_name', '<undefined>'),
'bank_id': request.POST.get('bank_id', UNDEFINED),
'role_name': request.POST.get('role_name', UNDEFINED),
}
response = api.post(urlpath, payload=payload)
if 'code' in response and response['code'] >= 400:
messages.error(self.request, response['message'])
else:
msg = 'Entitlement with role {} has been added.'.format(request.POST.get('role_name', '<undefined>'))
msg = 'Entitlement with role {} has been added.'.format(request.POST.get('role_name', UNDEFINED))
messages.success(request, msg)
except APIError as err:
messages.error(request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
try:
urlpath = '/entitlement-requests/{}'.format(request.POST.get('entitlement_request_id', '<undefined>'))
urlpath = '/entitlement-requests/{}'.format(request.POST.get('entitlement_request_id', UNDEFINED))
response = api.delete(urlpath)
if 'code' in response and response['code'] >= 400:
messages.error(self.request, response['message'])
else:
msg = 'Entitlement Request with role {} has been deleted.'.format(
request.POST.get('role_name', '<undefined>'))
request.POST.get('role_name', UNDEFINED))
messages.success(request, msg)
except APIError as err:
messages.error(request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return HttpResponseRedirect(reverse('entitlementrequests-index'))
return HttpResponseRedirect(reverse('entitlementrequests-index'))

View File

@ -1,7 +1,6 @@
import requests
import os
import dotenv
#from deepl_translation_fun import trasnlator
BASE_DIR = os.getcwd() #method tells us the location of current working directory

View File

@ -7,29 +7,27 @@ languages=['de','es','fr','hi'] # Defining languages
# This class is used for converting languages
class clsTranslate():
def translateText(self, strString, strTolang):
class languageConverting():
def parametersTextConverte(self, stString, prevlangToNewlang):
"""
This function translates one language into another language. It takes two
parameters
1. strString :=> String that you want to convert
2. strTolang :=> Languages(fr,hi,es etc)
1. prevStrToNewString :=> String that you want to convert
2. prevlangToNewlang :=> Languages(fr,hi,es etc)
"""
self.strString = strString
self.strTolang = strTolang
translator = translator(text=self.strString, language=self.strTolang)
self.prevStrToNewString = prevStrToNewString
self.prevlangToNewlang = prevlangToNewlang
translator = translator(text=self.prevStrToNewString, language=self.prevlangToNewlang)
return (str(translator))
# This is method for writing file
def writeFile(language):
print(language,"Started")
def localeWriteFile(language):
fileName=f'locale/{language}/LC_MESSAGES/django.po' # Openning a file
try:
with open(fileName,encoding='utf-8') as f: # Reading from the file
a=[i.replace("\n","") for i in f.readlines()] # Reading everyline from a file and store it into a
except Exception as e: # same like try block.
print(fileName, e)
b=0
for i in range(len(a)):
if 'msgid' in a[i] and a[i]!='msgid ""':
@ -37,29 +35,25 @@ def writeFile(language):
break
if b!=0:
trans=clsTranslate() # Creating object for translation class
trans=languageConverting() # Creating object for translation class
for i in range(b-1,len(a)):
try:
if "msgid" in a[i]:
msgid,msgstr=a[i],a[i+1]
if msgstr == 'msgstr ""':
ms=msgid[7:len(msgid)-1]
val=trans.translateText(ms,language)
val=trans.parametersTextConverte(ms,language)
a[i+1]=f'msgstr "{val}"'
# print(a[i])
except: pass
try:
lock.acquire()
with open(fileName,'w',encoding='utf-8') as f:
for i in a:
f.write(f"{i}\n")
print(language,"is completed")
lock.release()
except Exception as e:
print(e)
lock.release()
else:
print(language,"is completed")
with tpe() as e:
e.map(writeFile,languages)
e.map(localeWriteFile,languages)

View File

@ -7,14 +7,14 @@ $(document).ready(function($) {
//each method_routing will have each own json_editor, and will put data into it when click `parameter` box
//and will use the data from click `save` button.
var json_editors = []
let json_editors = []
$('.parameters').click(function() {
var runner = $(this).parent().parent().parent();
var json_editor_id= $(runner).find('.jsoneditor_div')[0].id;
var json_editor_number = json_editor_id.replace("jsoneditor","");
var container = $("#"+json_editor_id);
parameters = JSON.parse($(runner).find('textarea[name="parameters"]').text());
var jsoneditor_div = $(runner).find('.jsoneditor_div');
let runner = $(this).parent().parent().parent();
let json_editor_id= $(runner).find('.jsoneditor_div')[0].id;
let json_editor_number = json_editor_id.replace("jsoneditor","");
let container = $("#"+json_editor_id);
let parameters = JSON.parse($(runner).find('textarea[name="parameters"]').text());
let jsoneditor_div = $(runner).find('.jsoneditor_div');
//make sure only create one jsoneditor_div block, click once to open and then close the block.
if (typeof json_editors[json_editor_number] === 'undefined') {
json_editors[json_editor_number] = new JSONEditor(container[0], options, parameters);
@ -30,21 +30,20 @@ $(document).ready(function($) {
});
$('.runner button.forSave').click(function() {
var t = $(this);
var runner = $(this).parent().parent().parent();
method_routing_id = $(runner).find('.method_routing_id').text();
method_name = $(runner).find('.method_name').text();
connector_name = $(runner).find('.connector_name').val();
bank_id_pattern = $(runner).find('textarea[name="bank_id_pattern"]').val();
is_bank_id_exact_match = $(runner).find('.is_bank_id_exact_match').val();
parameters = $(runner).find('textarea[name="parameters"]').val();
var jsoneditor_id= $(runner).find('.jsoneditor_div')[0].id;
var json_editor_number = jsoneditor_id.replace("jsoneditor","");
let runner = $(this).parent().parent().parent();
let method_routing_id = $(runner).find('.method_routing_id').text();
let method_name = $(runner).find('.method_name').text();
let connector_name = $(runner).find('.connector_name').val();
let bank_id_pattern = $(runner).find('textarea[name="bank_id_pattern"]').val();
let is_bank_id_exact_match = $(runner).find('.is_bank_id_exact_match').val();
let parameters = $(runner).find('textarea[name="parameters"]').val();
let jsoneditor_id= $(runner).find('.jsoneditor_div')[0].id;
let json_editor_number = jsoneditor_id.replace("jsoneditor","");
//if the user do not click the `parameters` box, then there is no json_editors here,so we use the parameters directly.
if (typeof json_editors[json_editor_number] === 'undefined') {
parameters_Json_editor = parameters;
let parameters_Json_editor = parameters;
} else {
parameters_Json_editor = JSON.stringify(json_editors[json_editor_number].get());
let parameters_Json_editor = JSON.stringify(json_editors[json_editor_number].get());
}
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
@ -63,9 +62,8 @@ $(document).ready(function($) {
});
$('.runner button.forDelete').click(function() {
var t = $(this);
var runner = $(this).parent().parent().parent();
method_routing_id = $(runner).find('.method_routing_id').text();
let runner = $(this).parent().parent().parent();
let method_routing_id = $(runner).find('.method_routing_id').text();
$('.runner button.forSave').attr("disabled","disabled");
$('.runner button.forDelete').attr("disabled","disabled");
$.post('methodrouting/delete/method', {

View File

@ -71,11 +71,11 @@
<option value="stored_procedure_vDec2019">{% trans "stored_procedure_vDec2019" %}</option>
{% elif method_routing.connector_name == "rest_vMar2019" %}
<option value="rest_vMar2019">{% trans "rest_vMar2019" %}</option> # This will be selected
<option value="kafka_vSept2018">{% trans "kafka_vSept2018</option>
<option value="mapped">{% trans "mapped</option>
<option value="akka_vDec2018">{% trans "akka_vDec2018</option>
<option value="kafka_vMay2019">{% trans "kafka_vMay2019</option>
<option value="stored_procedure_vDec2019">{% trans "stored_procedure_vDec2019</option>
<option value="kafka_vSept2018">{% trans "kafka_vSept2018" %}</option>
<option value="mapped">{% trans "mapped" %}</option>
<option value="akka_vDec2018">{% trans "akka_vDec2018" %}</option>
<option value="kafka_vMay2019">{% trans "kafka_vMay2019" %}</option>
<option value="stored_procedure_vDec2019">{% trans "stored_procedure_vDec2019" %}</option>
{% elif method_routing.connector_name == "kafka_vMay2019" %}
<option value="kafka_vMay2019">{% trans "kafka_vMay2019" %}</option> # This will be selected
<option value="rest_vMar2019">{% trans "rest_vMar2019" %}</option>
@ -99,7 +99,7 @@
<textarea class="form-control" rows="1"
name="bank_id_pattern">{{ method_routing.bank_id_pattern }}</textarea>
</div>
<div class="col-xs-12 col-sm-1" align="center">
<div class="col-xs-12 col-sm-1" style="align-self:center;">
<select class="is_bank_id_exact_match form-control">
{% if method_routing.is_bank_id_exact_match == False %}
<option value="False">{% trans "False" %}</option>

View File

@ -5,7 +5,6 @@ URLs for config app
from django.conf.urls import url
#from .views import IndexView, methodrouting_save, methodrouting_delete
from methodrouting.views import IndexView, methodrouting_save, methodrouting_delete
urlpatterns = [

View File

@ -37,8 +37,8 @@ class IndexView(LoginRequiredMixin, FormView):
method_routings=response['method_routings']
except APIError as err:
messages.error(self.request, err)
except BaseException as err:
error_once_only(self.request, (Exception("Unknown Error. Details:" + str(err))))
except Exception as err:
error_once_only(self.request, err)
else:
for i in range(len(method_routings)):
#if the parameters are empty, we provide the example value.
@ -51,13 +51,13 @@ class IndexView(LoginRequiredMixin, FormView):
method_routings[i]['parameters'] = json.dumps(method_routings[i]['parameters'], sort_keys=False)
if(str(settings.API_ROOT).find("127.0.0.1") == -1):
methodSwaggerUrl = '{}/message-docs?connector=stored_procedure_vDec2019#'.format(settings.API_HOST.replace(".openbankproject.", "-explorer.openbankproject."))
method_Swagger_Url = '{}/message-docs?connector=stored_procedure_vDec2019#'.format(settings.API_HOST.replace(".openbankproject.", "-explorer.openbankproject."))
else:
methodSwaggerUrl = "http://127.0.0.1:8082/message-docs?connector=stored_procedure_vDec2019#"
method_Swagger_Url = "http://127.0.0.1:8082/message-docs?connector=stored_procedure_vDec2019#"
context.update({
'method_routings': method_routings,
"methodSwaggerUrl": methodSwaggerUrl
"method_Swagger_Url": method_Swagger_Url
})
return context
@ -68,7 +68,6 @@ def methodrouting_save(request):
connector_name = request.POST.get('connector_name')
bank_id_pattern = request.POST.get('bank_id_pattern')
is_bank_id_exact_match = request.POST.get('is_bank_id_exact_match')
parameters = request.POST.get('parameters')
method_routing_id = request.POST.get('method_routing_id')
parameters_Json_editor = request.POST.get('parameters_Json_editor')
#from sonarcloud: Dynamic code execution should not be vulnerable to injection attacks
@ -101,4 +100,4 @@ def methodrouting_delete(request):
urlpath = '/management/method_routings/{}'.format(method_routing_id)
result = api.delete(urlpath)
return result
return result

View File

@ -11,37 +11,31 @@ from datetime import datetime, timedelta
from django.utils.translation import ugettext_lazy as _
from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput
from apimanager.settings import API_MANAGER_DATE_FORMAT
API_DATE_FORMAT_PLACEHOLDER = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
FORM_CONTROL = 'form-control'
FROM_DATE = 'From Date'
TO_DATE = 'To Date'
class MetricsForm(forms.Form):
from_date = forms.DateTimeField(
label=_('From Date'),
input_formats=[settings.API_DATEFORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
'class': 'form-control',
}
),
initial='2020-01-01T00:00:00.000Z',
label=_(FROM_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=False,
initial=(datetime.now() - timedelta(30)).strftime(API_MANAGER_DATE_FORMAT),
)
to_date = forms.DateTimeField(
label=_('To Date'),
input_formats=[settings.API_DATEFORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
'class': 'form-control',
}
),
label=_(TO_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=False,
initial=str(datetime.now().strftime(API_MANAGER_DATE_FORMAT)),
)
limit = forms.IntegerField(
label=_('Limit'),
widget=forms.NumberInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
initial=100,
@ -51,7 +45,7 @@ class MetricsForm(forms.Form):
label=_('Offset'),
widget=forms.NumberInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
initial=0,
@ -91,7 +85,7 @@ class APIMetricsForm(MetricsForm):
label=_('Consumer ID'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -100,7 +94,7 @@ class APIMetricsForm(MetricsForm):
label=_('User ID'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -110,7 +104,7 @@ class APIMetricsForm(MetricsForm):
choices=ANONYMOUS,
widget=forms.Select(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
initial='',
@ -120,7 +114,7 @@ class APIMetricsForm(MetricsForm):
label=_('App Name'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -130,7 +124,7 @@ class APIMetricsForm(MetricsForm):
choices=VERB,
widget=forms.Select(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
initial='',
@ -140,7 +134,7 @@ class APIMetricsForm(MetricsForm):
label=_('URL'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -149,7 +143,7 @@ class APIMetricsForm(MetricsForm):
label=_('Implemented By Partial Function'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -159,7 +153,7 @@ class APIMetricsForm(MetricsForm):
choices=VERSION,
widget=forms.Select(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
initial='',
@ -170,22 +164,16 @@ class APIMetricsForm(MetricsForm):
class ConnectorMetricsForm(MetricsForm):
# override from_date until API returns values without given date
from_date = forms.DateTimeField(
label=_('From Date'),
input_formats=[settings.API_DATEFORMAT],
widget=forms.DateTimeInput(
attrs={
'placeholder': "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
'class': 'form-control',
}
),
initial='2020-01-01T00:00:00.000Z',
label=_(FROM_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=True,
initial=(datetime.now() - timedelta(6)).strftime(API_MANAGER_DATE_FORMAT),
)
connector_name = forms.CharField(
label=_('Connector Name'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -194,7 +182,7 @@ class ConnectorMetricsForm(MetricsForm):
label=_('Function Name'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -203,7 +191,7 @@ class ConnectorMetricsForm(MetricsForm):
label=_('Correlation ID'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
@ -212,45 +200,28 @@ class ConnectorMetricsForm(MetricsForm):
class CustomSummaryForm(forms.Form):
to_date = forms.DateField(
label=_('To Date'),
# input_formats=[settings.API_DATEFORMAT],
# widget=forms.DateTimeInput(
# attrs={
# 'placeholder': 'yyyy-mm-ddThh:mm:ss',
# 'class': 'form-control',
# }
# ),
widget=DatePickerInput(format='%Y-%m-%d'),
label=_(TO_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=True,
# initial=str(datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%fZ')),
initial=str(datetime.now().strftime('%Y-%m-%d')),
initial=str(datetime.now().strftime(API_MANAGER_DATE_FORMAT)),
)
from_date_custom = forms.DateField(
label=_('From Date'),
#input_formats=[settings.API_DATEFORMAT],
# widget=forms.DateTimeInput(
# attrs={
# 'placeholder': 'yyyy-mm-ddThh:mm:ss',
# 'class': 'form-control',
# }
# )
widget=DatePickerInput(format='%Y-%m-%d'),
label=_(FROM_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=True,
#initial=str(datetime.now().strftime('%Y-%m-%d')),
initial=(datetime.now() - timedelta(6)).strftime('%Y-%m-%d'),
initial=(datetime.now() - timedelta(6)).strftime(API_MANAGER_DATE_FORMAT),
)
exclude_app_names = forms.CharField(
label=_('Exclude App Names'),
include_app_names = forms.CharField(
label=_('Include App Names'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
initial='API-Manager',
)
include_obp_apps = forms.BooleanField(required=False, label=_('Include System Date'))
def __init__(self, *args, **kwargs):
kwargs.setdefault('label_suffix', '')
@ -258,31 +229,22 @@ class CustomSummaryForm(forms.Form):
class MonthlyMetricsSummaryForm(forms.Form):
to_date = forms.DateField(
label=_('To Date'),
# input_formats=[settings.API_DATEFORMAT],
# widget=forms.DateTimeInput(
# attrs={
# 'placeholder': 'yyyy-mm-ddThh:mm:ss',
# 'class': 'form-control',
# }
# ),
widget=DatePickerInput(format='%Y-%m-%d'),
label=_(TO_DATE),
widget=DatePickerInput(format=API_MANAGER_DATE_FORMAT),
required=True,
# initial=str(datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%fZ')),
initial=str(datetime.now().strftime('%Y-%m-%d')),
#initial=str(datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%fZ')),
initial=str(datetime.now().strftime(API_MANAGER_DATE_FORMAT)),
)
exclude_app_names = forms.CharField(
label=_('Exclude App Names'),
include_app_names = forms.CharField(
label=_('Include App Names'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'class': FORM_CONTROL,
}
),
required=False,
initial='API-Manager',
)
include_obp_apps = forms.BooleanField(required=False, label=_('Include System Date'))
def __init__(self, *args, **kwargs):
kwargs.setdefault('label_suffix', '')
super(MonthlyMetricsSummaryForm, self).__init__(*args, **kwargs)
super(MonthlyMetricsSummaryForm, self).__init__(*args, **kwargs)

View File

@ -1,14 +0,0 @@
document.getElementsByClassName("include_system_calls")[0].innerHTML=`<div>
<input type="checkbox" id="include_system_calls_id" name="Include System Calls"
>
<label for="systemCalls">Include System Calls</label>
</div>`
function systemCalls(){
var checkbox = document.getElementById('include_system_calls_id');
if (checkbox.checked == false) {
document.getElementById("obp_app_table").style.display = "none";
}else{
document.getElementById("obp_app_table").style.display = "";
}
}

View File

@ -1,5 +1,5 @@
$(document).ready(function($) {
var barChart = new Chart($("#barchart"), {
let barChart = new Chart($("#barchart"), {
type: 'horizontalBar',
data: {
labels: BarchartData['labels'],

View File

@ -0,0 +1,10 @@
$(document).ready(function () {
$('.spinner').on('click', function() {
var e=this;
setTimeout(function() {
e.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...';
e.disabled=true;
},0);
return true;
});
});

View File

@ -120,7 +120,7 @@
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
@ -140,7 +140,7 @@
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">{% trans "Verb" %}</th>
<th scope="col">{% trans "Verb Select" %}</th>
<th scope="col">{% trans "URL" %}</th>
<th scope="col">{% trans "Date" %}</th>
<th scope="col">{% trans "Duration(ms)" %}</th>
@ -151,7 +151,7 @@
{% for metric in metrics %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ metric.verb }}</td>
<td>{{ metric.verb_selection }}</td>
<td>
{{ metric.url }}
</td>

View File

@ -4,7 +4,7 @@
{% block nav_tabs %}
<li><a href="{% url 'api-metrics' %}?{{ request.GET.urlencode }}">{% trans "List" %}</a></li>
<li class="active"><a href="{% url 'api-metrics-summary-partial-function' %}?{{ request.GET.urlencode }}">{% trans "Summary by Partial Function" %}</a></li>
<li><a href="{% url 'api-metrics-summary-partial-function' %}?{{ request.GET.urlencode }}">{% trans "Summary by Partial Function" %}</a></li>
{% endblock nav_tabs %}
{% block tab_content %}

View File

@ -21,28 +21,28 @@
<div class="col-xs-6 col-sm-3">
{% if form.from_date.errors %}<div class="alert alert-danger">{{ form.from_date.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "from_date" %} </strong>
<strong>{% trans "From Date" %} </strong>
{{ form.from_date }}
</div>
</div>
<div class="col-xs-6 col-sm-3">
{% if form.to_date.errors %}<div class="alert alert-danger">{{ form.to_date.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "to_date" %} </strong>
<strong>{% trans "To Date" %} </strong>
{{ form.to_date }}
</div>
</div>
<div class="col-xs-6 col-sm-3">
{% if form.limit.errors %}<div class="alert alert-danger">{{ form.limit.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "limit" %} </strong>
<strong>{% trans "Limit" %} </strong>
{{ form.limit }}
</div>
</div>
<div class="col-xs-6 col-sm-3">
{% if form.offset.errors %}<div class="alert alert-danger">{{ form.offset.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "offset" %} </strong>
<strong>{% trans "Offset" %} </strong>
{{ form.offset }}
</div>
</div>
@ -52,27 +52,27 @@
<div class="col-xs-12 col-sm-4">
{% if form.connector_name.errors %}<div class="alert alert-danger">{{ form.connector_name.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "connector_name" %} </strong>
<strong>{% trans "Connector Name" %} </strong>
{{ form.connector_name }}
</div>
</div>
<div class="col-xs-12 col-sm-4">
{% if form.function_name.errors %}<div class="alert alert-danger">{{ form.function_name.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "function_name" %} </strong>
<strong>{% trans "Function Name" %} </strong>
{{ form.function_name }}
</div>
</div>
<div class="col-xs-12 col-sm-4">
{% if form.correlation_id.errors %}<div class="alert alert-danger">{{ form.correlation_id.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "correlation_id" %} </strong>
<strong>{% trans "Correlation Id" %} </strong>
{{ form.correlation_id }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>

View File

@ -2,6 +2,7 @@
{% load static %}
{% load i18n %}
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
<h1>{% trans "API Usage Report" %}</h1>
@ -14,15 +15,12 @@
<li><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li class="active"><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -40,39 +38,32 @@
<div class="col-xs-6 col-sm-3">
{% if form.from_date_custom.errors %}<div class="alert alert-danger">{{ form.from_date_custom.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "from_date_custom" %} </strong>
<strong>{% trans "From Date Custom" %} </strong>
{{ form.from_date_custom }}
</div>
</div>
<div class="col-xs-6 col-sm-3">
{% if form.to_date.errors %}<div class="alert alert-danger">{{ form.to_date.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "to_date" %} </strong>
<strong>{% trans "To Date Custom" %} </strong>
{{ form.to_date }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %}: {% trans "From" %}{{ from_date }} {% trans "to" %}{{ to_date }} </h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1">
<tr>
@ -83,10 +74,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per day (last 30 days)" %}:</td>
@ -126,7 +117,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -142,14 +133,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>{% trans "N/A" %}</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>
@ -157,6 +145,9 @@
{% endblock %}
{% block extrajs %}
<link href="{% static 'metrics/js/spinner.js' %}" rel="stylesheet">
{% endblock extrajs %}
{% block extracss %}
<link href="{% static 'metrics/css/metrics.css' %}" rel="stylesheet">
{% endblock extracss %}

View File

@ -5,6 +5,7 @@
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
@ -19,15 +20,12 @@
<li><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li class="active"><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -47,36 +45,29 @@
<div class="col-xs-6 col-sm-3">
{% if form.to_date.errors %}<div class="alert alert-danger">{{ form.to_date.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "to_date" %} </strong>
<strong>{% trans "To Date" %} </strong>
{{ form.to_date }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<table border="1">
<tr>
<th></th>
<th></th>
@ -85,10 +76,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per hour" %}:</td>
@ -129,7 +120,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -145,14 +136,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>

View File

@ -3,6 +3,7 @@
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
@ -24,8 +25,6 @@
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -50,31 +49,24 @@
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %}: {% trans "From" %}{{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<table border="1" summary="Table about call APIs in every hours">
<tr>
<th></th>
<th></th>
@ -83,17 +75,17 @@
<td>{% trans "API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>-->
<tr>
<td>{% trans "Calls per minute" %}:</td>
<td style="background-color:#FF0000">{%for item in calls_per_hour_list%}<li><ol>{{item}}</ol></li>{% endfor %}</td>
</tr>
<tr>
<td>{% trans "Calls per minute" %}:</td>
<td bgcolor="#FF0000">{%for item in calls_per_hour_list%}<li>{{item}}</li>{% endfor %}</td>
</tr>
<tr>
<td>{% trans "Calls per minute" %}:</td>
<td bgcolor="#FF0000"><img src="data:image/png;base64, {{ per_hour_chart }}" alt="somealt" /></td>
<td style="background-color:#FF0000"><img src="data:image/png;base64, {{ per_hour_chart }}" alt="somealt" /></td>
</tr>
<tr>
<td>{% trans "Average number of calls hour" %}: </td>
@ -126,7 +118,7 @@
<td>{% trans "Top APIs" %}:</td>
<td><img src="data:image/png;base64, {{ top_apis_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}</td>
</tr>
@ -143,14 +135,11 @@
<tr>
<td>{% trans "CanSearchWarehouse users" %}:</td>
<td>{{number_of_users_with_cansearchwarehouse}}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>

View File

@ -2,6 +2,7 @@
{% load static %}
{% load i18n %}
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
<h1>{% trans "API Usage Report" %}</h1>
@ -14,15 +15,12 @@
<li class="active"><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -42,36 +40,29 @@
<div class="col-xs-6 col-sm-3">
{% if form.to_date.errors %}<div class="alert alert-danger">{{ form.to_date.errors }}</div>{% endif %}
<div class="form-group">
<strong>{% trans "to_date" %} </strong>
<strong>{% trans "To Date" %} </strong>
{{ form.to_date }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %}: {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<table border="1">
<tr>
<th></th>
<th></th>
@ -80,10 +71,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per day" %}:</td>
@ -123,7 +114,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -139,14 +130,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>

View File

@ -4,6 +4,7 @@
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
@ -18,15 +19,12 @@
<li><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -51,31 +49,24 @@
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %}:{% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<table border="1">
<tr>
<th></th>
<th></th>
@ -84,10 +75,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per month" %}:</td>
@ -132,7 +123,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -148,14 +139,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>

View File

@ -4,6 +4,7 @@
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
@ -20,15 +21,12 @@
<li><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li class="active"><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -53,29 +51,22 @@
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<table border="1">
<tr>
<th></th>
<th></th>
@ -84,10 +75,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per day" %}:</td>
@ -128,7 +119,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -144,14 +135,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>

View File

@ -4,6 +4,7 @@
{% block page_title %}{{ block.super }} / API Usage Report{% endblock page_title %}
{% load bootstrap3 %}
{% block content %}
<div id="metrics">
@ -20,15 +21,12 @@
<li><a href="{% url 'metrics-summary' %}?{{ request.GET.urlencode }}">{% trans "Month" %}</a></li>
<li><a href="{% url 'weekly-summary' %}?{{ request.GET.urlencode }}">{% trans "Week" %}</a></li>
<li><a href="{% url 'daily-summary' %}?{{ request.GET.urlencode }}">{% trans "Day" %}</a></li>
<!--<li><a href="{% url 'hourly-summary' %}?{{ request.GET.urlencode }}">Hour</a></li>-->
<li><a href="{% url 'custom-summary' %}?{{ request.GET.urlencode }}">{% trans "Custom" %}</a></li>
{% endblock nav_tabs %}
</ul>
<div id="metrics-filter">
<!--{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}-->
<!--{% bootstrap_css %} {# Embed Bootstrap CSS #}-->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extrahead %} {# Extra Resources Start #}
@ -53,30 +51,21 @@
</div>
</div>
<div class="col-xs-4 col-sm-3">
{% if form.exclude_app_names.errors %}<div class="alert alert-danger">{{ form.exclude_app_names.errors }}</div>{% endif %}
{% if form.include_app_names.errors %}<div class="alert alert-danger">{{ form.include_app_names.errors }}</div>{% endif %}
<div class="form-group">
{{ form.exclude_app_names.label_tag }}
{{ form.exclude_app_names }}
</div>
</div>
<div class="col-xs-4 col-sm-3">
<div class="form-group include_system_calls">
{{ form.include_obp_apps }}
{{ form.include_obp_apps.label_tag }}
{{ form.include_app_names.label_tag }}
{{ form.include_app_names }}
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" onclick="systemCalls()">{% trans "Update filter" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Search" %}</button>
</form>
</div>
<div class="tab-content">
{% if form.include_obp_apps.value %}
{% block tab_content %}
<div class="tab-pane active">
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
<table border="1" id="obp_app_table">
<h2>{% if include_app_names != "" %} {{ include_app_names }} : {% endif %}{{ from_date }} - {{ to_date }}</h2>
<table border="1">
<tr>
<th></th>
<th></th>
@ -86,10 +75,10 @@
<td>{% trans "Total API calls" %}:</td>
<td>{{ api_calls }}</td>
</tr>
<tr>
<!--<tr>
<td>{% trans "API calls made using API Explorer" %}:</td>
<td>{{ calls_by_api_explorer }} ({% widthratio calls_by_api_explorer api_calls 100 %} %)</td>
</tr>
</tr>-->
<tr>
<td>{% trans "Calls per month" %}:</td>
@ -114,7 +103,7 @@
<td>{{ number_of_apps_with_unique_app_name }}</td>
</tr>
<tr>
<td>{% trans "Apps with distinct developer email addresses:</td>
<td>{% trans "Apps with distinct developer email addresses:" %}</td>
<td>{{ number_of_apps_with_unique_developer_email }}</td>
</tr>
@ -130,7 +119,7 @@
<td>{% trans "Top 10 Consumers" %}:</td>
<td><img src="data:image/png;base64, {{ top_consumers_bar_chart }}" alt="somealt" /></td>
</tr>
<tr>
<!--<tr>
<td>{% trans "Top Warehouse APIs" %}:</td>
<td>{% if top_warehouse_apis %}{%for element in top_warehouse_apis%} <p>{{ element.Implemented_by_partial_function }} : {{ element.count }}</p> {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
@ -146,14 +135,11 @@
<tr>
<td>{% trans "Users with role CanSearchWarehouse" %}:</td>
<td>{% if user_email_cansearchwarehouse %}{% for key, value in user_email_cansearchwarehouse.items %} {{key}}, {% endfor %}{% else %} <p>N/A</p>{% endif %}</td>
</tr>
</tr>-->
</table>
</div>
{% endblock tab_content %}
{% else %}
<h2>{% trans "Period" %} : {% trans "From" %} {{ from_date }} {% trans "to" %} {{ to_date }}</h2>
{% endif %}
</div>
</div>
</div>

View File

@ -11,7 +11,7 @@ from enum import Enum
from django.conf import settings
from apimanager import local_settings
from apimanager.settings import API_HOST, EXCLUDE_APPS, EXCLUDE_FUNCTIONS, EXCLUDE_URL_PATTERN, API_EXPLORER_APP_NAME, API_DATEFORMAT
from apimanager.settings import API_HOST, EXCLUDE_APPS, EXCLUDE_FUNCTIONS, EXCLUDE_URL_PATTERN, API_EXPLORER_APP_NAME, API_DATE_FORMAT, API_DATE_TIME_FORMAT, DEBUG
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView
@ -33,6 +33,11 @@ import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import statistics
import urllib.parse
CACHE_SETTING_URL_MSG = "The cache setting url is"
CACHE_SETTING_KEY_MSG = "The cache setting key is"
def get_random_color(to_hash):
hashed = str(int(hashlib.md5(to_hash.encode('utf-8')).hexdigest(), 16))
@ -109,7 +114,7 @@ class MetricsView(LoginRequiredMixin, TemplateView):
"""
for metric in metrics:
metric['date'] = datetime.datetime.strptime(
metric['date'], settings.API_DATETIMEFORMAT)
metric['date'], settings.API_DATE_TIME_FORMAT)
return metrics
def to_api(self, cleaned_data):
@ -124,7 +129,7 @@ class MetricsView(LoginRequiredMixin, TemplateView):
# Maybe we should define the API format as Django format to not
# have to convert in places like this?
if value.__class__.__name__ == 'datetime':
value = value.strftime(settings.API_DATEFORMAT)
value = value.strftime(settings.API_DATE_FORMAT)
if value:
# API does not like quoted data
params.append('{}={}'.format(name, value))
@ -143,11 +148,17 @@ class MetricsView(LoginRequiredMixin, TemplateView):
metrics = api.get(urlpath)
metrics = self.to_django(metrics['metrics'])
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except KeyError as err:
if DEBUG:
raise(err)
error_once_only(self.request, metrics['message'])
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
return metrics
def get_context_data(self, **kwargs):
@ -197,13 +208,13 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
template_name = 'metrics/monthly_summary.html'
api_urlpath = None
def get_form(self, web_page_type = ""):
def get_form(self):
"""
Get bound form either from request.GET or initials
We need a bound form because we already send a request to the API
without user intervention on initial request
"""
if (self.request.GET) and (web_page_type != SummaryType.CUSTOM):
if self.request.GET:
data = self.request.GET
else:
fields = self.form_class.declared_fields
@ -221,7 +232,7 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
"""
for metric in metrics:
metric['date'] = datetime.datetime.strptime(
metric['date'], API_DATEFORMAT)
metric['date'], API_DATE_FORMAT)
return metrics
def to_api(self, cleaned_data):
@ -236,113 +247,151 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
# Maybe we should define the API format as Django format to not
# have to convert in places like this?
if value.__class__.__name__ == 'datetime':
value = value.strftime(settings.API_DATEFORMAT)
value = value.strftime(settings.API_DATE_FORMAT)
if value:
# API does not like quoted data
params.append('{}={}'.format(name, value))
params = '&'.join(params)
return params
def get_aggregate_metrics(self, from_date, to_date, is_included_obp_apps, only_show_api_explorer_metrics = False):
def get_app_name_parameters(self, include_app_names):
#if len(app_names) == 1:
# return
#1. Parse include_app_names create a list using a commo (,) separator
#2. Trim each word (remove space),
#3. Then is one word, &app_name = thing
#4. IF IT IS MORE than one word then return number of app without space
#5. return either &app_name=thing
#6. Or
#7. return &include_app_names=thing1,thing2,
#8. url encode
#app_names = []
#input_string = "simon says, foo, bar , App 2 "
input_string = include_app_names.strip()
result = ""
if input_string != "":
input_list = input_string.strip().split(",")
#print("input_list is:", input_list)
cleaned_list = [item.strip() for item in input_list]
#print("cleaned_list is: ", cleaned_list)
cleaned_string=', '.join([str(item) for item in cleaned_list])
#print("cleaned_string is:", cleaned_string)
url_encoded_string = urllib.parse.quote(cleaned_string)
#print("url_encoded_string is:", url_encoded_string)
if len(cleaned_list) == 0:
result = ""
elif len(cleaned_list) == 1:
result = "&app_name={}".format(url_encoded_string)
else:
result = "&include_app_names={}".format(url_encoded_string)
return result
def get_aggregate_metrics(self, from_date, to_date, include_app_names):
"""
Gets the metrics from the API, using given parameters,
There are different use cases, so we accept different parameters.
only_show_api_explorer_metrics has the default value False, because it is just used for app = API_Explorer.
"""
try:
print("get_app_name_parameters is: ", self.get_app_name_parameters(include_app_names))
api_calls_total = 0
average_response_time = 0
urlpath = '/management/aggregate-metrics'
if only_show_api_explorer_metrics:
urlpath = urlpath + '?from_date={}&to_date={}&app_name={}'.format(from_date, to_date, API_EXPLORER_APP_NAME)
elif ((not only_show_api_explorer_metrics) and (not is_included_obp_apps)):
urlpath = urlpath + '?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(local_settings.EXCLUDE_APPS),",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
else:
urlpath = urlpath + '?from_date={}&to_date={}'.format(from_date, to_date)
cache_key = get_cache_key_for_current_call(self.request, urlpath)
apicaches = None
url_path = '/management/aggregate-metrics'
#if only_show_api_explorer_metrics:
# urlpath = urlpath + '?from_date={}&to_date={}&app_name={}'.format(from_date, to_date)
#elif (not only_show_api_explorer_metrics):
# urlpath = urlpath + '?from_date={}&to_date={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
# from_date, to_date, ",".join(local_settings.EXCLUDE_FUNCTIONS), ",".join(local_settings.EXCLUDE_URL_PATTERN))
#
#else:
url_path = url_path + '?from_date={}&to_date={}{}'.format(from_date, to_date, self.get_app_name_parameters(include_app_names))
#print("get_app_name_parameters(include_app_names) is:", self.get_app_name_parameters(include_app_names))
#print("url_path is: ", url_path)
cache_key = get_cache_key_for_current_call(self.request, url_path)
api_cache = None
try:
apicaches = cache.get(cache_key)
api_cache = cache.get(cache_key)
except Exception as err:
apicaches = None
if not apicaches is None:
metrics = apicaches
api_cache = None
if not api_cache is None:
metrics = api_cache
else:
api = API(self.request.session.get('obp'))
metrics = api.get(urlpath)
apicaches = cache.set(cache_key, metrics)
LOGGER.warning('The cache is setting, url is: {}'.format(urlpath))
LOGGER.warning('The cache is setting key is: {}'.format(cache_key))
metrics = api.get(url_path)
api_cache = cache.set(cache_key, metrics)
LOGGER.warning('{0}: {1}'.format(CACHE_SETTING_URL_MSG, url_path))
LOGGER.warning('{0}: {1}'.format(CACHE_SETTING_KEY_MSG, cache_key))
api_calls_total, average_calls_per_day, average_response_time = self.get_internal_api_call_metrics(
api_calls_total, average_response_time, cache_key, from_date, metrics, to_date, urlpath)
api_calls_total, average_response_time, cache_key, from_date, metrics, to_date, url_path)
return api_calls_total, average_response_time, int(average_calls_per_day)
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
def get_internal_api_call_metrics(self, api_calls_total, average_response_time, cache_key, from_date, metrics,
to_date, urlpath):
api_calls_total = metrics[0]["count"]
average_response_time = metrics[0]["average_response_time"]
to_date = datetime.datetime.strptime(to_date, API_DATEFORMAT)
from_date = datetime.datetime.strptime(from_date, API_DATEFORMAT)
to_date = datetime.datetime.strptime(to_date, API_DATE_FORMAT)
from_date = datetime.datetime.strptime(from_date, API_DATE_FORMAT)
number_of_days = abs((to_date - from_date).days)
# if number_of_days= 0, then it means calls_per_hour
average_calls_per_day = api_calls_total if (number_of_days == 0) else api_calls_total / number_of_days
return api_calls_total, average_calls_per_day, average_response_time
def get_aggregate_metrics_api_explorer(self, from_date, to_date):
return self.get_aggregate_metrics(from_date, to_date, True, True)
def get_active_apps(self, is_included_obp_apps, from_date, to_date, exclude_app_names):
def get_active_apps(self, from_date, to_date):
"""
Gets the metrics from the API, using given parameters,
There are different use cases, so we accept different parameters.
only_show_api_explorer_metrics has the default value False, because it is just used for app = API_Explorer.
"""
apps = []
form = self.get_form()
active_apps_list = []
if is_included_obp_apps:
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}'.format(from_date, to_date, exclude_app_names)
api = API(self.request.session.get('obp'))
try:
apps = api.get(urlpath)
if apps is not None and 'code' in apps and apps['code']==403:
error_once_only(self.request, apps['message'])
else:
active_apps_list = list(apps)
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}'.format(from_date, to_date)
api = API(self.request.session.get('obp'))
try:
apps = api.get(urlpath)
if apps is not None and 'code' in apps and apps['code']==403:
error_once_only(self.request, apps['message'])
else:
active_apps_list = list(apps)
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
else:
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(local_settings.EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
api = API(self.request.session.get('obp'))
try:
apps = api.get(urlpath)
active_apps_list = list(apps['top_consumers'])
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
return active_apps_list
def get_total_number_of_apps(self, cleaned_data, from_date, to_date):
apps = []
from_date = datetime.datetime.strptime(from_date, API_DATEFORMAT)
to_date = datetime.datetime.strptime(to_date, API_DATEFORMAT)
from_date = datetime.datetime.strptime(from_date, API_DATE_FORMAT)
to_date = datetime.datetime.strptime(to_date, API_DATE_FORMAT)
apps_list = self.get_all_consumers()
for app in apps_list:
app_created_date = datetime.datetime.strptime(app["created"], '%Y-%m-%dT%H:%M:%SZ')
app_created_date = datetime.datetime.strptime(app["created"], API_DATE_TIME_FORMAT)
if app_created_date < from_date and app_created_date > to_date:
apps_list.remove(app)
@ -353,12 +402,10 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
app_names.append(apps["app_name"])
# If include OBP Apps is selected
if cleaned_data.get('include_obp_apps'):
app_names = app_names
else:
for app in app_names:
if app in local_settings.EXCLUDE_APPS:
app_names.remove(app)
#if not cleaned_data.get('include_obp_apps'):
# for app in app_names:
# if app in local_settings.EXCLUDE_APPS:
# app_names.remove(app)
app_names = list(filter(None, app_names))
@ -380,35 +427,39 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
urlpath = '/management/consumers'
api = API(self.request.session.get('obp'))
cache_key = get_cache_key_for_current_call(self.request, urlpath)
apicaches = None
api_cache = None
try:
apicaches = cache.get(cache_key)
api_cache = cache.get(cache_key)
except Exception as err:
apicaches = None
if not apicaches is None:
apps_list = apicaches
api_cache = None
if api_cache is not None:
apps_list = api_cache
else:
try:
apps = api.get(urlpath)
apps_list = apps["consumers"]
cache.set(cache_key, apps_list, 60 * 60) # for the consumers we cache for 1 hour, consumers may be increased
LOGGER.warning('The cache is setting, url is: {}'.format(urlpath))
LOGGER.warning('The cache is setting key is: {}'.format(cache_key))
LOGGER.warning('{0}: {1}'.format(CACHE_SETTING_URL_MSG, urlpath))
LOGGER.warning('{0}: {1}'.format(CACHE_SETTING_KEY_MSG, cache_key))
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
return apps_list
def calls_per_delta(self, is_included_obp_apps, from_date_string, to_date_string, exclude_app_names, **delta ):
def calls_per_delta(self, from_date_string, to_date_string, include_app_names, **delta ):
"""
return how many calls were made in total per given delta.
Here we need to convert date_string to datetime object, and calculate the dates.
"""
# we need to convert string to datetime object, then we can calculate the date
from_datetime_object = datetime.datetime.strptime(from_date_string, API_DATEFORMAT)
to_datetime_object = datetime.datetime.strptime(to_date_string , API_DATEFORMAT)
from_datetime_object = datetime.datetime.strptime(from_date_string, API_DATE_FORMAT)
to_datetime_object = datetime.datetime.strptime(to_date_string , API_DATE_FORMAT)
time_delta_in_loop = from_datetime_object + timedelta(**delta)
result_list = []
@ -417,16 +468,18 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
while time_delta_in_loop <= to_datetime_object:
try:
# here we need to first convert datetime object to String
form_date= from_datetime_object.strftime(API_DATEFORMAT)
to_date= time_delta_in_loop.strftime(API_DATEFORMAT)
aggregate_metrics = self.get_aggregate_metrics(form_date, to_date, is_included_obp_apps)
form_date= from_datetime_object.strftime(API_DATE_FORMAT)
to_date= time_delta_in_loop.strftime(API_DATE_FORMAT)
aggregate_metrics = self.get_aggregate_metrics(form_date, to_date, include_app_names)
result = aggregate_metrics[0]
result_list_pure.append(result)
result_list.append('{} - {} # {}'.format(from_datetime_object, time_delta_in_loop, result))
date_list.append(from_datetime_object)
except Exception as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
break
error_once_only(self.request, 'Unknown Error. {}'.format(err))
from_datetime_object = time_delta_in_loop
time_delta_in_loop = time_delta_in_loop + timedelta(**delta)
@ -434,21 +487,20 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
return (result_list, result_list_pure, date_list)
def calls_per_month(self, is_included_obp_apps, from_date, to_date, exclude_app_names):
def calls_per_month(self,from_date, to_date, include_app_names):
"""
Convenience function to print number of calls per month
It is actually 30 days, not a month
"""
calls_per_month_list, calls_per_month, month_list = self.calls_per_delta(is_included_obp_apps, from_date, to_date, exclude_app_names, days=30)
calls_per_month_list, calls_per_month, month_list = self.calls_per_delta(from_date, to_date, include_app_names, days=30)
return calls_per_month_list, calls_per_month, month_list
def calls_per_day(self, is_included_obp_apps, from_date, to_date, exclude_app_names):
def calls_per_day(self,from_date, to_date, include_app_names):
"""
Convenience function to print number of calls per day
"""
index = []
calls_per_day, calls_per_day_pure, date_list = self.calls_per_delta(is_included_obp_apps, from_date, to_date,exclude_app_names, days=1)
calls_per_day, calls_per_day_pure, date_list = self.calls_per_delta(from_date, to_date, include_app_names, days=1)
if len(calls_per_day) >= 90:
calls_per_day = calls_per_day[-90:]
@ -462,18 +514,18 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
return calls_per_day, calls_per_day_pure, date_list
def calls_per_half_day(self, is_included_obp_apps, from_date):
def calls_per_half_day(self,from_date, include_app_names):
"""
Convenience function to print number of calls per half day
"""
return self.calls_per_delta(is_included_obp_apps, from_date, exclude_app_names, hours=12)
return self.calls_per_delta(from_date, hours=12)
def calls_per_hour(self, is_included_obp_apps, from_date, to_date, exclude_app_names):
def calls_per_hour(self,from_date, to_date, include_app_names):
"""
Convenience function to print number of calls per hour
"""
calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_delta(is_included_obp_apps, from_date, to_date, exclude_app_names, hours=1)
calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_delta(from_date, to_date, include_app_names, hours=1)
return calls_per_hour_list, calls_per_hour, hour_list
def plot_line_chart(self, plot_data, date_month_list, period):
@ -482,40 +534,13 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
hour_list = []
if period == 'day':
if len(plot_data) == 0:
plt.xlabel("Dates", fontsize=8)
plt.plot()
else:
plt.title("API calls per day", fontsize=14)
plt.xlabel("Dates", fontsize=8)
for date in date_month_list:
date = date.strftime('%B %d')
date_list.append(str(date))
plt.plot(date_list, plot_data, linewidth=1, marker='o')
self._day(plot_data, date_month_list, date_list)
elif period == 'month':
if len(plot_data) == 0:
plt.xlabel("Months", fontsize=8)
plt.plot()
else:
plt.title("API calls per month", fontsize=14)
plt.xlabel("Months", fontsize=8)
for date in date_month_list:
month = date.strftime('%B %Y')
month_list.append(str(month))
plt.plot(month_list, plot_data, linewidth=1, marker='o')
self._month(plot_data, date_month_list, month_list)
elif period == 'hour':
if len(plot_data) == 0:
plt.xlabel("Hours", fontsize=8)
plt.plot()
else:
plt.title("API calls per hour", fontsize=14)
plt.xlabel("Hours", fontsize=8)
for date in date_month_list:
hour = date.strftime('%B %d -- %H : %m')
hour_list.append(str(hour))
plt.plot(hour_list, plot_data, linewidth=1, marker='o')
self._hour(plot_data, date_month_list, hour_list)
plt.xticks(rotation=90, fontsize=6)
@ -532,7 +557,41 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
plt.gcf().clear()
return image_base64
def _day(self, plot_data, date_month_list, date_list):
if len(plot_data) == 0:
plt.xlabel("Dates", fontsize=8)
plt.plot()
else:
plt.title("API calls per day", fontsize=14)
plt.xlabel("Dates", fontsize=8)
for date in date_month_list:
date = date.strftime('%B %d')
date_list.append(str(date))
plt.plot(date_list, plot_data, linewidth=1, marker='o')
def _month(self, plot_data, date_month_list, month_list):
if len(plot_data) == 0:
plt.xlabel("Months", fontsize=8)
plt.plot()
else:
plt.title("API calls per month", fontsize=14)
plt.xlabel("Months", fontsize=8)
for date in date_month_list:
month = date.strftime('%B %Y')
month_list.append(str(month))
plt.plot(month_list, plot_data, linewidth=1, marker='o')
def _hour(self, plot_data, date_month_list, hour_list):
if len(plot_data) == 0:
plt.xlabel("Hours", fontsize=8)
plt.plot()
else:
plt.title("API calls per hour", fontsize=14)
plt.xlabel("Hours", fontsize=8)
for date in date_month_list:
hour = date.strftime('%B %d -- %H : %m')
hour_list.append(str(hour))
plt.plot(hour_list, plot_data, linewidth=1, marker='o')
def plot_bar_chart(self, data):
x = []
@ -592,60 +651,59 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
error_once_only(self.request, users['message'])
if 'users' not in users:
users['users']=[]
else:
self._update_user_with_cansearchwarehouse(users, users_with_cansearchwarehouse, email_with_cansearchwarehouse)
# fail gracefully in case API provides new structure
except APIError as err:
error_once_only(self.request, err)
except KeyError as err:
messages.error(self.request, 'KeyError: {}'.format(err))
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
else:
try:
for user in users['users']:
for entitlement in user['entitlements']['list']:
if 'CanSearchWarehouse' in entitlement['role_name']:
users_with_cansearchwarehouse.append(user["username"])
email_with_cansearchwarehouse.append(user["email"])
# fail gracefully in case API provides new structure
except KeyError as err:
messages.error(self.request, 'KeyError: {}'.format(err))
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
user_email_cansearchwarehouse = dict(zip(users_with_cansearchwarehouse, email_with_cansearchwarehouse))
number_of_users_with_cansearchwarehouse = len(user_email_cansearchwarehouse)
return user_email_cansearchwarehouse, number_of_users_with_cansearchwarehouse
def _update_user_with_cansearchwarehouse(self, users, users_with_cansearchwarehouse, email_with_cansearchwarehouse):
for user in users['users']:
for entitlement in user['entitlements']['list']:
if 'CanSearchWarehouse' in entitlement['role_name']:
users_with_cansearchwarehouse.append(user["username"])
email_with_cansearchwarehouse.append(user["email"])
def _api_data(self, urlpath, data_key):
api = API(self.request.session.get('obp'))
data = []
try:
data = api.get(urlpath)
if data is not None and 'code' in data and data['code']==403:
error_once_only(self.request, data['message'])
data=[]
else:
data = data[data_key]
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
return data
def get_top_apis(self, cleaned_data, from_date, to_date):
top_apis = []
form = self.get_form()
if cleaned_data.get('include_obp_apps'):
urlpath = '/management/metrics/top-apis?from_date={}&to_date={}'.format(from_date, to_date)
api = API(self.request.session.get('obp'))
try:
top_apis = api.get(urlpath)
if top_apis is not None and 'code' in top_apis and top_apis['code']==403:
error_once_only(self.request, top_apis['message'])
top_apis=[]
else:
top_apis = top_apis['top_apis']
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
else:
urlpath = '/management/metrics/top-apis?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(local_settings.EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
api = API(self.request.session.get('obp'))
try:
top_apis = api.get(urlpath)
if top_apis is not None and 'code' in top_apis and top_apis['code']==403:
error_once_only(self.request, top_apis['message'])
top_apis=[]
else:
top_apis = top_apis['top_apis']
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
#if cleaned_data.get('include_obp_apps'):
# urlpath = '/management/metrics/top-apis?from_date={}&to_date={}'.format(from_date, to_date)
#else:
# urlpath = '/management/metrics/top-apis?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
# from_date, to_date, ",".join(local_settings.EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
urlpath = '/management/metrics/top-apis?from_date={}&to_date={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
top_apis = self._api_data(urlpath, 'top_apis')
for api in top_apis:
if api['Implemented_by_partial_function'] == "":
@ -654,44 +712,20 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
for api in top_apis:
api['Implemented_by_partial_function'] = api['Implemented_by_partial_function'] + '(' + api['implemented_in_version'] + ')'
top_apis = top_apis[:10]
# for api in top_apis:
# #print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TOP APIS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
# print(str(top_apis.index(api) + 1) + "," + api['Implemented_by_partial_function'] + "," + str(api['count']))
top_apis = reversed(top_apis)
return top_apis
def get_top_consumers(self, cleaned_data, from_date, to_date):
top_consumers = []
form = self.get_form()
if cleaned_data.get('include_obp_apps'):
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}'.format(from_date, to_date)
api = API(self.request.session.get('obp'))
try:
top_consumers = api.get(urlpath)
if top_consumers is not None and 'code' in top_consumers and top_consumers['code']==403:
error_once_only(self.request, top_consumers['message'])
top_consumers=[]
else:
top_consumers = top_consumers['top_consumers']
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
else:
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(local_settings.EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
api = API(self.request.session.get('obp'))
try:
top_consumers = api.get(urlpath)
if top_consumers is not None and 'code' in top_consumers and top_consumers['code']==403:
error_once_only(self.request, top_consumers['message'])
top_consumers=[]
else:
top_consumers = top_consumers['top_consumers']
except APIError as err:
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
#if cleaned_data.get('include_obp_apps'):
# urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}'.format(from_date, to_date)
#else:
# urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
# from_date, to_date, ",".join(local_settings.EXCLUDE_APPS), ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_implemented_by_partial_functions={}&exclude_url_pattern={}'.format(
from_date, to_date, ",".join(EXCLUDE_FUNCTIONS), ",".join(EXCLUDE_URL_PATTERN))
top_consumers = self._api_data(urlpath, 'top_consumers')
for consumer in top_consumers:
if consumer['app_name'] == "":
top_consumers.remove(consumer)
@ -709,17 +743,20 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
if "elasticSearchWarehouse" in api['Implemented_by_partial_function']:
top_warehouse_calls.append(api)
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
return top_warehouse_calls
def get_top_apps_using_warehouse(self, from_date, to_date, exclude_app_names):
form = self.get_form()
def get_top_apps_using_warehouse(self, from_date, to_date):
top_apps_using_warehouse = []
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&exclude_app_names={}&implemented_by_partial_function={}'.format(
from_date, to_date, exclude_app_names, "elasticSearchWarehouse")
urlpath = '/management/metrics/top-consumers?from_date={}&to_date={}&implemented_by_partial_function={}'.format(
from_date, to_date, "elasticSearchWarehouse")
api = API(self.request.session.get('obp'))
try:
top_apps_using_warehouse = api.get(urlpath)
@ -729,45 +766,49 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
else:
top_apps_using_warehouse = top_apps_using_warehouse["top_consumers"][:2]
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
return top_apps_using_warehouse
def median_time_to_first_api_call(self, from_date, to_date):
return 0 #TODO this cost too much time, do not use this at the moment.
form = self.get_form()
form = self.get_form()
new_apps_list = []
apps = []
apps_list = self.get_all_consumers()
for app in apps_list:
created_date = datetime.datetime.strptime(app['created'], '%Y-%m-%dT%H:%M:%SZ')
created_date = created_date.strftime(API_DATEFORMAT)
created_date = datetime.datetime.strptime(created_date, API_DATEFORMAT)
if created_date >= datetime.datetime.strptime(from_date, API_DATEFORMAT):
created_date = created_date.strftime(API_DATE_FORMAT)
created_date = datetime.datetime.strptime(created_date, API_DATE_FORMAT)
if created_date >= datetime.datetime.strptime(from_date, API_DATE_FORMAT):
new_apps_list.append(app)
times_to_first_call = []
strfrom_date=datetime.datetime.strptime(from_date, API_DATEFORMAT)
strto_date=datetime.datetime.strptime(to_date, API_DATEFORMAT)
strfrom_date=datetime.datetime.strptime(from_date, API_DATE_FORMAT)
strto_date=datetime.datetime.strptime(to_date, API_DATE_FORMAT)
for app in new_apps_list:
urlpath_metrics = '/management/metrics?from_date={}&to_date={}&consumer_id={}&sort_by={}&direction={}&limit={}'.format(
from_date, to_date, app['consumer_id'], 'date', 'asc', '1')
cache_key = get_cache_key_for_current_call(self.request, urlpath_metrics)
api = API(self.request.session.get('obp'))
try:
apicaches=None
api_cache=None
try:
apicaches=cache.get(cache_key)
api_cache=cache.get(cache_key)
except Exception as err:
apicaches=None
api_cache=None
metrics=[]
if not apicaches is None:
metrics=apicaches
if not api_cache is None:
metrics=api_cache
else:
metrics = api.get(urlpath_metrics)
@ -787,8 +828,12 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
except APIError as err:
if DEBUG:
raise(err)
error_once_only(self.request, err)
except Exception as err:
if DEBUG:
raise(err)
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if times_to_first_call:
@ -803,15 +848,15 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
def prepare_general_context(self, web_page_type, **kwargs):
try:
form = self.get_form(web_page_type)
form = self.get_form()
per_day_chart=[]
calls_per_month_list=[]
per_month_chart=[]
calls_per_hour_list=[]
per_hour_chart=[]
if form.is_valid():
is_included_obp_apps = form.cleaned_data.get('include_obp_apps')
exclude_app_names = form.cleaned_data.get("exclude_app_names")
# = form.cleaned_data.get('include_obp_apps')
include_app_names = form.cleaned_data.get("include_app_names")
#if exclude_app_names not in local_settings.EXCLUDE_APPS:
# error_once_only(self.request, "Invalid Exclude App Name, Please select" + str(local_settings.EXCLUDE_APPS) + "Anyone of these")
form_to_date_string = form.data['to_date']
@ -820,41 +865,46 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
if (web_page_type == SummaryType.DAILY):
# for one day, the from_date is 1 day ago.
from_date = return_to_days_ago(to_date, 1)
calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_hour(is_included_obp_apps, from_date, to_date, exclude_app_names)
calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_hour(from_date, to_date, include_app_names)
per_hour_chart = self.plot_line_chart(calls_per_hour, hour_list, 'hour')
if (web_page_type == SummaryType.WEEKLY):
# for one month, the from_date is 7 days ago.
from_date = return_to_days_ago(to_date, 7)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(is_included_obp_apps, from_date, to_date, exclude_app_names)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date, include_app_names)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
if (web_page_type == SummaryType.MONTHLY):
# for one month, the from_date is 30 days ago.
from_date = return_to_days_ago(to_date, 30)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(is_included_obp_apps, from_date, to_date, exclude_app_names)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date, include_app_names)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
if (web_page_type == SummaryType.QUARTERLY):
# for one quarter, the from_date is 90 days ago.
from_date = (datetime.datetime.strptime(to_date, API_DATEFORMAT) - timedelta(90)).strftime(API_DATEFORMAT)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(is_included_obp_apps, from_date, to_date, exclude_app_names)
from_date = (datetime.datetime.strptime(to_date, API_DATE_FORMAT) - timedelta(90)).strftime(API_DATE_FORMAT)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(from_date, to_date, include_app_names)
per_month_chart = self.plot_line_chart(calls_per_month, month_list, 'month')
if (web_page_type == SummaryType.YEARLY):
from_date = return_to_days_ago(to_date, 365)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(is_included_obp_apps, from_date, to_date, exclude_app_names)
#calls_per_month_list, calls_per_month, month_list = self.calls_per_month(, from_date, to_date)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(from_date, to_date, include_app_names)
per_month_chart = self.plot_line_chart(calls_per_month, month_list, "month")
if (web_page_type == SummaryType.CUSTOM):
# for one month, the from_date is x day ago.
form_from_date_string = form.data['from_date_custom']
from_date = convert_form_date_to_obpapi_datetime_format(form_from_date_string)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(is_included_obp_apps, from_date, to_date, exclude_app_names)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
#calls_per_day_list, calls_per_day, date_list = self.calls_per_day(, from_date, to_date)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date,include_app_names)
if (len(calls_per_day) <= 31):
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
else:
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "month")
api_host_name = API_HOST
top_apps_using_warehouse = self.get_top_apps_using_warehouse(from_date, to_date, exclude_app_names)
top_apps_using_warehouse = self.get_top_apps_using_warehouse(from_date, to_date)
user_email_cansearchwarehouse, number_of_users_with_cansearchwarehouse = self.get_users_cansearchwarehouse()
median_time_to_first_api_call = self.median_time_to_first_api_call(from_date, to_date)
@ -863,19 +913,16 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
top_consumers = self.get_top_consumers(form.cleaned_data, from_date, to_date)
top_consumers_bar_chart = self.plot_topconsumer_bar_chart(top_consumers)
top_warehouse_calls = self.get_top_warehouse_calls(form.cleaned_data, from_date, to_date)
api_calls, average_response_time, average_calls_per_day = self.get_aggregate_metrics(from_date, to_date,is_included_obp_apps)
calls_by_api_explorer, average_response_time_api_explorer, average_calls_per_day_api_explorer = self.get_aggregate_metrics_api_explorer(
from_date, to_date)
api_calls, average_response_time, average_calls_per_day = self.get_aggregate_metrics(from_date, to_date, include_app_names)
unique_app_names, number_of_apps_with_unique_app_name, number_of_apps_with_unique_developer_email = self.get_total_number_of_apps(
form.cleaned_data, from_date, to_date)
active_apps_list = self.get_active_apps(is_included_obp_apps, from_date, to_date, exclude_app_names)
active_apps_list = self.get_active_apps(from_date, to_date)
context = super(MonthlyMetricsSummaryView, self).get_context_data(**kwargs)
context.update({
'form': form,
'api_calls': api_calls,
'calls_by_api_explorer': calls_by_api_explorer,
'include_app_names': include_app_names,
'calls_per_month_list': calls_per_month_list,
'per_month_chart': per_month_chart,
'per_day_chart': per_day_chart,
@ -891,19 +938,65 @@ class MonthlyMetricsSummaryView(LoginRequiredMixin, TemplateView):
'user_email_cansearchwarehouse': user_email_cansearchwarehouse,
'number_of_users_with_cansearchwarehouse': number_of_users_with_cansearchwarehouse,
'api_host_name': api_host_name,
'from_date': (datetime.datetime.strptime(from_date, API_DATEFORMAT)).strftime('%Y-%m-%d'),
'to_date': (datetime.datetime.strptime(to_date, API_DATEFORMAT)).strftime('%Y-%m-%d'),
'from_date': (datetime.datetime.strptime(from_date, API_DATE_FORMAT)).strftime('%d %B %Y'),
'to_date': (datetime.datetime.strptime(to_date, API_DATE_FORMAT)).strftime('%d %B %Y'),
'top_apis': top_apis,
'top_apis_bar_chart': top_apis_bar_chart,
'top_consumers_bar_chart': top_consumers_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'excluded_apps':[exclude_app_names if exclude_app_names in local_settings.EXCLUDE_APPS else "null"],
#'excluded_apps':[exclude_app_names if exclude_app_names in local_settings.EXCLUDE_APPS else "null"],
})
return context
else:
error_once_only(self.request, str(form.errors))
except Exception as err:
error_once_only(self.request, 'Unknown Error. {}'.format(err))
if DEBUG:
raise(err)
error_once_only(self.request, err)
def _daily_and_weekly(self, web_page_type,to_date, per_hour_chart, per_day_chart, from_date):
if (web_page_type == SummaryType.DAILY):
# for one day, the from_date is 1 day ago.
from_date = return_to_days_ago(to_date, 1)
calls_per_hour_list, calls_per_hour, hour_list = self.calls_per_hour(from_date, to_date)
per_hour_chart = self.plot_line_chart(calls_per_hour, hour_list, 'hour')
if (web_page_type == SummaryType.WEEKLY):
# for one month, the from_date is 7 days ago.
from_date = return_to_days_ago(to_date, 7)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
return (from_date, per_hour_chart, per_day_chart)
def _monthly_and_quarterly(self, web_page_type,to_date, per_day_chart, per_month_chart, from_date):
if (web_page_type == SummaryType.MONTHLY):
# for one month, the from_date is 30 days ago.
from_date = return_to_days_ago(to_date, 30)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
if (web_page_type == SummaryType.QUARTERLY):
# for one quarter, the from_date is 90 days ago.
from_date = (datetime.datetime.strptime(to_date, API_DATE_FORMAT) - timedelta(90)).strftime(API_DATE_FORMAT)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(from_date, to_date, include_app_names)
per_month_chart = self.plot_line_chart(calls_per_month, month_list, 'month')
return (from_date, per_day_chart, per_month_chart)
def _yearly_and_custom(self, web_page_type,to_date, per_month_chart, per_day_chart, from_date):
if (web_page_type == SummaryType.YEARLY):
from_date = return_to_days_ago(to_date, 365)
calls_per_month_list, calls_per_month, month_list = self.calls_per_month(from_date, to_date, include_app_names)
per_month_chart = self.plot_line_chart(calls_per_month, month_list, "month")
if (web_page_type == SummaryType.CUSTOM):
# for one month, the from_date is x day ago.
form_from_date_string = form.data['from_date_custom']
from_date = convert_form_date_to_obpapi_datetime_format(form_from_date_string)
calls_per_day_list, calls_per_day, date_list = self.calls_per_day(from_date, to_date)
per_day_chart = self.plot_line_chart(calls_per_day, date_list, "day")
return (from_date, per_month_chart, per_day_chart)
class YearlySummaryView(MonthlyMetricsSummaryView):
template_name = 'metrics/yearly_summary.html'
@ -928,4 +1021,4 @@ class HourlySummaryView(MonthlyMetricsSummaryView):
class CustomSummaryView(MonthlyMetricsSummaryView):
form_class = CustomSummaryForm
template_name = 'metrics/custom_summary.html'
def get_context_data(self, **kwargs): return self.prepare_general_context(SummaryType.CUSTOM, **kwargs)
def get_context_data(self, **kwargs): return self.prepare_general_context(SummaryType.CUSTOM, **kwargs)

View File

@ -107,18 +107,6 @@ class API(object):
response = self.call('PUT', url, payload)
return self.handle_response(response)
# def handle_response_404(self, response, prefix):
# msg = '{} {}: {}'.format(
# prefix, response.status_code, response.text)
# log(logging.ERROR, msg)
# raise APIError(msg)
#
# def handle_response_500(self, response, prefix):
# msg = '{} {}: {}'.format(
# prefix, response.status_code, response.text)
# log(logging.ERROR, msg)
# raise APIError(msg)
def handle_response_error(self, prefix, error):
if 'Invalid or expired access token' in error:
raise APIError(error)

View File

@ -49,7 +49,7 @@ class DirectLoginAuthenticator(Authenticator):
raise AuthenticatorError(Exception("The OBP-API server is not running or does not respond properly."
"Please check OBP-API server. "
"Details: "+str(err)))
except BaseException as err:
except Exception as err:
raise AuthenticatorError(Exception("Unknown Error. Details:"+ str(err)))
# This is the direct-Login Token:

View File

@ -56,7 +56,7 @@ class GatewayLoginAuthenticator(Authenticator):
raise AuthenticatorError(Exception("The OBP-API server is not running or does not respond properly."
"Please check OBP-API server. "
"Details: " + str(err)))
except BaseException as err:
except Exception as err:
raise AuthenticatorError(Exception("Unknown Error. Details:" + str(err)))
# this will show the obp errors
if response.status_code != 200:

View File

@ -16,6 +16,7 @@ from .api import API, APIError
from .authenticator import AuthenticatorError
from .forms import DirectLoginForm, GatewayLoginForm
from .oauth import OAuthAuthenticator
from django.conf import settings
class LoginToDjangoMixin(object):
@ -31,8 +32,8 @@ class LoginToDjangoMixin(object):
data = api.get('/users/current')
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
return False
else:
userid = data['user_id'] or data['email']
@ -53,8 +54,11 @@ class OAuthInitiateView(RedirectView):
Gets the callback URI to where the user shall be returned after
initiation at OAuth server
"""
base_url = '{}://{}'.format(
request.scheme, request.environ['HTTP_HOST'])
if settings.CALLBACK_BASE_URL:
base_url = settings.CALLBACK_BASE_URL
else:
base_url = '{}://{}'.format(
request.scheme, request.environ['HTTP_HOST'])
uri = base_url + reverse('oauth-authorize')
if 'next' in request.GET:
uri = '{}?next={}'.format(uri, request.GET['next'])
@ -69,8 +73,8 @@ class OAuthInitiateView(RedirectView):
except AuthenticatorError as err:
messages.error(self.request, err)
return reverse('home')
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
return reverse('home')
else:
self.request.session['obp'] = {
@ -95,8 +99,8 @@ class OAuthAuthorizeView(RedirectView, LoginToDjangoMixin):
authenticator.set_access_token(authorization_url)
except AuthenticatorError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
else:
session_data['authenticator_kwargs'] = {
'token': authenticator.token,

View File

@ -5,7 +5,7 @@ URLs for metrics app
from django.conf.urls import url
from .views import IndexProductView, UpdateProductView, createList
from .views import IndexProductView, UpdateProductView, create_list
urlpatterns = [
url(r'^create',
@ -15,6 +15,6 @@ urlpatterns = [
UpdateProductView.as_view(),
name='products_update'),
url(r'^createProductList',
createList,
create_list,
name = 'create-product-list'),
]

View File

@ -36,8 +36,8 @@ class IndexProductView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return form
def form_valid(self, form):
@ -91,8 +91,8 @@ class UpdateProductView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
try:
result = self.api.get(urlpath)
fields['parent_product_code'].initial = self.kwargs['parent_product_code']
@ -155,7 +155,7 @@ class UpdateProductView(LoginRequiredMixin, FormView):
@exception_handle
@csrf_exempt
def createList(request):
def create_list(request):
print(request.POST, "createProductList listt")
return HttpResponse("<h1>View 1</h1>")

View File

@ -1,7 +1,7 @@
{% extends 'base.html' %} {% load static %} {% load i18n %}
{% block page_title %} {{ block.super }} / {% trans "System View" %}{% endblock page_title %} {% block content %}
<div id="systemview">
<h1>{% trans "System View" %}</h1>
<h1>{% trans "System Views" %}</h1>
<div class="table-responsive">
<table class="table table-hover tablesorter" id="system_view" aria-describedby="system view">
<thead>

View File

@ -100,14 +100,15 @@ class IndexView(LoginRequiredMixin, TemplateView):
users = response
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
role_names = self.get_users_rolenames(context)
try:
users = FilterRoleName(context, self.request.GET) \
.apply([users] if username else users['users'])
except:
except Exception as err:
messages.error(self.request, err)
users = []
context.update({
'role_names': role_names,
@ -137,8 +138,8 @@ class DetailView(LoginRequiredMixin, FormView):
form.fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
return form
def form_valid(self, form):
@ -154,8 +155,8 @@ class DetailView(LoginRequiredMixin, FormView):
except APIError as err:
messages.error(self.request, err)
return super(DetailView, self).form_invalid(form)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
return super(DetailView, self).form_invalid(form)
if 'code' in entitlement and entitlement['code']>=400:
messages.error(self.request, entitlement['message'])
@ -181,8 +182,8 @@ class DetailView(LoginRequiredMixin, FormView):
context['form'].fields['user_id'].initial = user['user_id']
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
context.update({
'apiuser': user, # 'user' is logged-in user in template context
@ -205,8 +206,8 @@ class MyDetailView(LoginRequiredMixin, FormView):
form.fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
return form
def form_valid(self, form):
@ -229,7 +230,7 @@ class MyDetailView(LoginRequiredMixin, FormView):
messages.error(self.request, err)
return super(MyDetailView, self).form_invalid(form)
except Exception as err:
messages.error(self.request, 'Unknown Error. {}'.format(err))
messages.error(self.request, err)
return super(MyDetailView, self).form_invalid(form)
else:
return super(MyDetailView, self).form_valid(form)
@ -246,10 +247,7 @@ class MyDetailView(LoginRequiredMixin, FormView):
except APIError as err:
messages.error(self.request, err)
except Exception as err:
messages.error(self.request, 'Unknown Error')
#print(user,"This is ")
#entitlements=user["entitlements"]["list"]
user["entitlements"]["list"] = sorted(user["entitlements"]["list"], key=lambda d: d['role_name'])
messages.error(self.request, err)
context.update({
'apiuser': user, # 'user' is logged-in user in template context
})
@ -274,8 +272,8 @@ class InvitationView(LoginRequiredMixin, FormView):
fields['bank_id'].choices = self.api.get_bank_id_choices()
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
except Exception as err:
messages.error(self.request, err)
return form
def form_valid(self, form, **kwargs):
@ -306,7 +304,7 @@ class InvitationView(LoginRequiredMixin, FormView):
messages.error(self.request, err)
return super(InvitationView, self).form_invalid(form)
except Exception as err:
messages.error(self.request, "Unknown Error:{}".format(str(err)))
messages.error(self.request, err)
return super(InvitationView, self).form_invalid(form)
def get_invitations(self, context, get_url_path, invitations):
@ -338,10 +336,10 @@ class DeleteEntitlementView(LoginRequiredMixin, View):
messages.success(request, msg)
except APIError as err:
messages.error(request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
# from sonarcloud: Change this code to not perform redirects based on user-controlled data.
# from sonarcloud: Change this code to not perform redirects based on user-controlled data.
redirect_url_from_gui = request.POST.get('next', reverse('users-index'))
if "/users/all/user_id/" in str(redirect_url_from_gui):
redirect_url = reverse('users-detail',kwargs={"user_id":kwargs['user_id']})
@ -349,7 +347,6 @@ class DeleteEntitlementView(LoginRequiredMixin, View):
redirect_url = reverse('my-user-detail',kwargs={"user_id":kwargs['user_id']})
else:
redirect_url = reverse('users-index')
return HttpResponseRedirect(redirect_url)
@ -379,7 +376,6 @@ class UserStatusUpdateView(LoginRequiredMixin, View):
else:
urlpath = '/users/{}/lock-status'.format(kwargs['username'])
result = api.put(urlpath, None)
print("result", result)
#if result is not None and 'code' in result and result['code'] >= 400:
if 'code' in result and result['code'] == 404:
msg = 'User {} has been unlocked.'.format(kwargs['username'])
@ -392,8 +388,8 @@ class UserStatusUpdateView(LoginRequiredMixin, View):
except APIError as err:
messages.error(request, err)
except Exception as e:
messages.error(self.request, 'Unknown Error' + str(e))
except Exception as err:
messages.error(self.request, err)
# from sonarcloud: Change this code to not perform redirects based on user-controlled data.
redirect_url_from_gui = request.POST.get('next', reverse('users-index'))
@ -433,8 +429,8 @@ class ExportCsvView(LoginRequiredMixin, View):
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, 'Unknown Error')
except Exception as err:
messages.error(self.request, err)
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment;filename= Users'+ str(datetime.datetime.now())+'.csv'
writer = csv.writer(response)
@ -443,4 +439,3 @@ class ExportCsvView(LoginRequiredMixin, View):
writer.writerow([user['username'], user['user_id'], user['email'], user['provider_id'], user['provider'],
user['last_marketing_agreement_signed_date']])
return response

View File

@ -1,10 +1,10 @@
$(document).ready(function($) {
$('.runner button.forSave').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var web_ui_props_name = $(runner).find('.web_ui_props_name').text();
var web_ui_props_value = $(runner).find('.web_ui_props_value').val();
const t = $(this);
const runner = t.parent().parent().parent();
const web_ui_props_name = $(runner).find('.web_ui_props_name').text();
const web_ui_props_value = $(runner).find('.web_ui_props_value').val();
$('.runner button.forSave').attr("disabled", "disabled");
$('.runner button.forDelete').attr("disabled", "disabled");
$.post('save/method', {
@ -17,13 +17,10 @@ $(document).ready(function($) {
$('.runner button.forDelete').click(function(e) {
e.preventDefault();
var t = $(this);
var runner = t.parent().parent().parent();
var web_ui_props_name = $(runner).find('.web_ui_props_name').text();
var textArea = runner.find('.web_ui_props_value');
var props_id = $(runner).find('.web_ui_props_id');
var web_ui_props_id = props_id.val();
var webui = $('#webui');
const t = $(this);
const runner = t.parent().parent().parent();
const props_id = $(runner).find('.web_ui_props_id');
const web_ui_props_id = props_id.val();
$('.runner button.forSave').attr("disabled", "disabled");
$('.runner button.forDelete').attr("disabled", "disabled");
$.post('delete/method', {
@ -32,4 +29,4 @@ $(document).ready(function($) {
location.reload();
});
});
});
});

View File

@ -38,8 +38,8 @@ class IndexView(LoginRequiredMixin, FormView):
context.update(response)
except APIError as err:
messages.error(self.request, err)
except BaseException as err:
messages.error(self.request, (Exception("Unknown Error. Details:" + str(err))))
except Exception as err:
messages.error(self.request, err)
return context
def get_form(self, *args, **kwargs):
@ -65,7 +65,6 @@ def webui_save(request):
@csrf_exempt
def webui_delete(request):
web_ui_props_id = request.POST.get('web_ui_props_id')
web_ui_props_name = request.POST.get('web_ui_props_name')
if web_ui_props_id == 'default' or web_ui_props_id == '' or web_ui_props_id is None:
return {'code':403,'message':'Cann\'t delete web_ui_props_id default'}
else:

View File

@ -1,8 +1,8 @@
#Django==1.11.7
Django==2.0.7
oauthlib==2.0.0
requests==2.11.1
requests-oauthlib==0.6.2
Django==2.2.13
oauthlib==3.2.0
requests==2.27.1
requests-oauthlib==1.3.1
PyJWT==1.5.3
gunicorn==19.6.0
matplotlib