diff --git a/.jupyter/api_authentication/models/database_dto.py b/.jupyter/api_authentication/models/database_dto.py index 9974642be9b7daba87c73e2e70f0af2d961ef7b9..baeaf0e46fa9a534e439e687533e6e6e86300d83 100644 --- a/.jupyter/api_authentication/models/database_dto.py +++ b/.jupyter/api_authentication/models/database_dto.py @@ -117,8 +117,7 @@ class DatabaseDto(object): if deleted is not None: self.deleted = deleted self.internal_name = internal_name - if publication_year is not None: - self.publication_year = publication_year + self.publication_year = publication_year if is_public is not None: self.is_public = is_public @@ -492,6 +491,8 @@ class DatabaseDto(object): :param publication_year: The publication_year of this DatabaseDto. # noqa: E501 :type: int """ + if publication_year is None: + raise ValueError("Invalid value for `publication_year`, must not be `None`") # noqa: E501 self._publication_year = publication_year diff --git a/.jupyter/api_container/models/database_dto.py b/.jupyter/api_container/models/database_dto.py index ef38b6a7d5a6a992f54b8e51d8f0455f45dd5ec4..0aa1b92b3db1bf2fd768ccff07f61361a4a56f21 100644 --- a/.jupyter/api_container/models/database_dto.py +++ b/.jupyter/api_container/models/database_dto.py @@ -117,8 +117,7 @@ class DatabaseDto(object): if deleted is not None: self.deleted = deleted self.internal_name = internal_name - if publication_year is not None: - self.publication_year = publication_year + self.publication_year = publication_year if is_public is not None: self.is_public = is_public @@ -492,6 +491,8 @@ class DatabaseDto(object): :param publication_year: The publication_year of this DatabaseDto. # noqa: E501 :type: int """ + if publication_year is None: + raise ValueError("Invalid value for `publication_year`, must not be `None`") # noqa: E501 self._publication_year = publication_year diff --git a/.jupyter/api_database/models/database_dto.py b/.jupyter/api_database/models/database_dto.py index 6e485faa9dc4f0dea3b7c3bae4063ab1be1135c7..52e21473a2256ae38d006e121c8080abecc2b7ad 100644 --- a/.jupyter/api_database/models/database_dto.py +++ b/.jupyter/api_database/models/database_dto.py @@ -117,8 +117,7 @@ class DatabaseDto(object): if deleted is not None: self.deleted = deleted self.internal_name = internal_name - if publication_year is not None: - self.publication_year = publication_year + self.publication_year = publication_year if is_public is not None: self.is_public = is_public @@ -492,6 +491,8 @@ class DatabaseDto(object): :param publication_year: The publication_year of this DatabaseDto. # noqa: E501 :type: int """ + if publication_year is None: + raise ValueError("Invalid value for `publication_year`, must not be `None`") # noqa: E501 self._publication_year = publication_year diff --git a/.jupyter/api_query/api/table_data_endpoint_api.py b/.jupyter/api_query/api/table_data_endpoint_api.py index 8f34b37dacac4db3543dd2def4951d0d24501b87..632bf0023c0c979119e43647dec551cf4bc744ad 100644 --- a/.jupyter/api_query/api/table_data_endpoint_api.py +++ b/.jupyter/api_query/api/table_data_endpoint_api.py @@ -259,7 +259,7 @@ class TableDataEndpointApi(object): auth_settings = ['bearerAuth'] # noqa: E501 return self.api_client.call_api( - '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'GET', + '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'HEAD', path_params, query_params, header_params, @@ -380,7 +380,7 @@ class TableDataEndpointApi(object): auth_settings = ['bearerAuth'] # noqa: E501 return self.api_client.call_api( - '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'HEAD', + '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'GET', path_params, query_params, header_params, diff --git a/.jupyter/api_query/models/database_dto.py b/.jupyter/api_query/models/database_dto.py index 008562a718b764a529bfdfbc6d14c04d0d3f9d7b..a6cbe93ef828694fc41e70f0dc370ee8fdd900f0 100644 --- a/.jupyter/api_query/models/database_dto.py +++ b/.jupyter/api_query/models/database_dto.py @@ -117,8 +117,7 @@ class DatabaseDto(object): if deleted is not None: self.deleted = deleted self.internal_name = internal_name - if publication_year is not None: - self.publication_year = publication_year + self.publication_year = publication_year if is_public is not None: self.is_public = is_public @@ -492,6 +491,8 @@ class DatabaseDto(object): :param publication_year: The publication_year of this DatabaseDto. # noqa: E501 :type: int """ + if publication_year is None: + raise ValueError("Invalid value for `publication_year`, must not be `None`") # noqa: E501 self._publication_year = publication_year diff --git a/.jupyter/api_units/__init__.py b/.jupyter/api_units/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4c957b741e1db37d91b16cf96b692225e94af901 --- /dev/null +++ b/.jupyter/api_units/__init__.py @@ -0,0 +1,25 @@ +# coding: utf-8 + +# flake8: noqa + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +from __future__ import absolute_import + +# import apis into sdk package +from api_units.api.default_api import DefaultApi +# import ApiClient +from api_units.api_client import ApiClient +from api_units.configuration import Configuration +# import models into sdk package +from api_units.models.units_savecolumnsconcept_body import UnitsSavecolumnsconceptBody +from api_units.models.units_saveconcept_body import UnitsSaveconceptBody +from api_units.models.units_suggest_body import UnitsSuggestBody diff --git a/.jupyter/api_units/api/__init__.py b/.jupyter/api_units/api/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e0a0fa250b70cb3f7dea9bcc5941dea5a85d763f --- /dev/null +++ b/.jupyter/api_units/api/__init__.py @@ -0,0 +1,6 @@ +from __future__ import absolute_import + +# flake8: noqa + +# import apis into api package +from api_units.api.default_api import DefaultApi diff --git a/.jupyter/api_units/api/default_api.py b/.jupyter/api_units/api/default_api.py new file mode 100644 index 0000000000000000000000000000000000000000..9de20b4fd5c4600ed24a84f4255b683d99b77536 --- /dev/null +++ b/.jupyter/api_units/api/default_api.py @@ -0,0 +1,500 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +from __future__ import absolute_import + +import re # noqa: F401 + +# python 2 and python 3 compatibility library +import six + +from api_units.api_client import ApiClient + + +class DefaultApi(object): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + Ref: https://github.com/swagger-api/swagger-codegen + """ + + def __init__(self, api_client=None): + if api_client is None: + api_client = ApiClient() + self.api_client = api_client + + def api_units_savecolumnsconcept_post(self, body, **kwargs): # noqa: E501 + """Save concepts to MDB # noqa: E501 + + This is a simple API for saving units and concepts. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_savecolumnsconcept_post(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSavecolumnsconceptBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.api_units_savecolumnsconcept_post_with_http_info(body, **kwargs) # noqa: E501 + else: + (data) = self.api_units_savecolumnsconcept_post_with_http_info(body, **kwargs) # noqa: E501 + return data + + def api_units_savecolumnsconcept_post_with_http_info(self, body, **kwargs): # noqa: E501 + """Save concepts to MDB # noqa: E501 + + This is a simple API for saving units and concepts. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_savecolumnsconcept_post_with_http_info(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSavecolumnsconceptBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + all_params = ['body'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + params = locals() + for key, val in six.iteritems(params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method api_units_savecolumnsconcept_post" % key + ) + params[key] = val + del params['kwargs'] + # verify the required parameter 'body' is set + if ('body' not in params or + params['body'] is None): + raise ValueError("Missing the required parameter `body` when calling `api_units_savecolumnsconcept_post`") # noqa: E501 + + collection_formats = {} + + path_params = {} + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + + body_params = None + if 'body' in params: + body_params = params['body'] + # HTTP header `Content-Type` + header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 + ['application/json']) # noqa: E501 + + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/api/units/savecolumnsconcept', 'POST', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=params.get('async_req'), + _return_http_data_only=params.get('_return_http_data_only'), + _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), + collection_formats=collection_formats) + + def api_units_saveconcept_post(self, body, **kwargs): # noqa: E501 + """Save concepts to MDB # noqa: E501 + + This is a simple API for saving units and concepts. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_saveconcept_post(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSaveconceptBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.api_units_saveconcept_post_with_http_info(body, **kwargs) # noqa: E501 + else: + (data) = self.api_units_saveconcept_post_with_http_info(body, **kwargs) # noqa: E501 + return data + + def api_units_saveconcept_post_with_http_info(self, body, **kwargs): # noqa: E501 + """Save concepts to MDB # noqa: E501 + + This is a simple API for saving units and concepts. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_saveconcept_post_with_http_info(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSaveconceptBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + all_params = ['body'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + params = locals() + for key, val in six.iteritems(params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method api_units_saveconcept_post" % key + ) + params[key] = val + del params['kwargs'] + # verify the required parameter 'body' is set + if ('body' not in params or + params['body'] is None): + raise ValueError("Missing the required parameter `body` when calling `api_units_saveconcept_post`") # noqa: E501 + + collection_formats = {} + + path_params = {} + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + + body_params = None + if 'body' in params: + body_params = params['body'] + # HTTP header `Content-Type` + header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 + ['application/json']) # noqa: E501 + + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/api/units/saveconcept', 'POST', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=params.get('async_req'), + _return_http_data_only=params.get('_return_http_data_only'), + _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), + collection_formats=collection_formats) + + def api_units_suggest_post(self, body, **kwargs): # noqa: E501 + """Autosuggest units # noqa: E501 + + This is a simple API which returns a list of suggested units. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_suggest_post(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSuggestBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.api_units_suggest_post_with_http_info(body, **kwargs) # noqa: E501 + else: + (data) = self.api_units_suggest_post_with_http_info(body, **kwargs) # noqa: E501 + return data + + def api_units_suggest_post_with_http_info(self, body, **kwargs): # noqa: E501 + """Autosuggest units # noqa: E501 + + This is a simple API which returns a list of suggested units. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_suggest_post_with_http_info(body, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param UnitsSuggestBody body: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + all_params = ['body'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + params = locals() + for key, val in six.iteritems(params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method api_units_suggest_post" % key + ) + params[key] = val + del params['kwargs'] + # verify the required parameter 'body' is set + if ('body' not in params or + params['body'] is None): + raise ValueError("Missing the required parameter `body` when calling `api_units_suggest_post`") # noqa: E501 + + collection_formats = {} + + path_params = {} + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + + body_params = None + if 'body' in params: + body_params = params['body'] + # HTTP header `Content-Type` + header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 + ['application/json']) # noqa: E501 + + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/api/units/suggest', 'POST', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=params.get('async_req'), + _return_http_data_only=params.get('_return_http_data_only'), + _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), + collection_formats=collection_formats) + + def api_units_uri_uname_get(self, uname, **kwargs): # noqa: E501 + """Get URI of units # noqa: E501 + + This is a simple API for getting the URI of a certain unit in OM. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_uri_uname_get(uname, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str uname: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.api_units_uri_uname_get_with_http_info(uname, **kwargs) # noqa: E501 + else: + (data) = self.api_units_uri_uname_get_with_http_info(uname, **kwargs) # noqa: E501 + return data + + def api_units_uri_uname_get_with_http_info(self, uname, **kwargs): # noqa: E501 + """Get URI of units # noqa: E501 + + This is a simple API for getting the URI of a certain unit in OM. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_uri_uname_get_with_http_info(uname, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str uname: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + all_params = ['uname'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + params = locals() + for key, val in six.iteritems(params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method api_units_uri_uname_get" % key + ) + params[key] = val + del params['kwargs'] + # verify the required parameter 'uname' is set + if ('uname' not in params or + params['uname'] is None): + raise ValueError("Missing the required parameter `uname` when calling `api_units_uri_uname_get`") # noqa: E501 + + collection_formats = {} + + path_params = {} + if 'uname' in params: + path_params['uname'] = params['uname'] # noqa: E501 + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + + body_params = None + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/api/units/uri/{uname}', 'GET', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=params.get('async_req'), + _return_http_data_only=params.get('_return_http_data_only'), + _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), + collection_formats=collection_formats) + + def api_units_validate_unit_get(self, unit, **kwargs): # noqa: E501 + """Validate units # noqa: E501 + + This is a simple API for validating units. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_validate_unit_get(unit, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str unit: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.api_units_validate_unit_get_with_http_info(unit, **kwargs) # noqa: E501 + else: + (data) = self.api_units_validate_unit_get_with_http_info(unit, **kwargs) # noqa: E501 + return data + + def api_units_validate_unit_get_with_http_info(self, unit, **kwargs): # noqa: E501 + """Validate units # noqa: E501 + + This is a simple API for validating units. # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.api_units_validate_unit_get_with_http_info(unit, async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str unit: to-do description (required) + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + all_params = ['unit'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + params = locals() + for key, val in six.iteritems(params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method api_units_validate_unit_get" % key + ) + params[key] = val + del params['kwargs'] + # verify the required parameter 'unit' is set + if ('unit' not in params or + params['unit'] is None): + raise ValueError("Missing the required parameter `unit` when calling `api_units_validate_unit_get`") # noqa: E501 + + collection_formats = {} + + path_params = {} + if 'unit' in params: + path_params['unit'] = params['unit'] # noqa: E501 + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + + body_params = None + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/api/units/validate/{unit}', 'GET', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=params.get('async_req'), + _return_http_data_only=params.get('_return_http_data_only'), + _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), + collection_formats=collection_formats) diff --git a/.jupyter/api_units/api_client.py b/.jupyter/api_units/api_client.py new file mode 100644 index 0000000000000000000000000000000000000000..36201d73283cdae2ea1e5cfb656c63a6de6f74d8 --- /dev/null +++ b/.jupyter/api_units/api_client.py @@ -0,0 +1,632 @@ +# coding: utf-8 +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" +from __future__ import absolute_import + +import datetime +import json +import mimetypes +from multiprocessing.pool import ThreadPool +import os +import re +import tempfile + +# python 2 and python 3 compatibility library +import six +from six.moves.urllib.parse import quote + +from api_units.configuration import Configuration +import api_units.models +from api_units import rest + + +class ApiClient(object): + """Generic API client for Swagger client library builds. + + Swagger generic API client. This client handles the client- + server communication, and is invariant across implementations. Specifics of + the methods and models for each application are generated from the Swagger + templates. + + NOTE: This class is auto generated by the swagger code generator program. + Ref: https://github.com/swagger-api/swagger-codegen + Do not edit the class manually. + + :param configuration: .Configuration object for this client + :param header_name: a header to pass when making calls to the API. + :param header_value: a header value to pass when making calls to + the API. + :param cookie: a cookie to include in the header when making calls + to the API + """ + + PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types + NATIVE_TYPES_MAPPING = { + 'int': int, + 'long': int if six.PY3 else long, # noqa: F821 + 'float': float, + 'str': str, + 'bool': bool, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'object': object, + } + + def __init__(self, configuration=None, header_name=None, header_value=None, + cookie=None): + if configuration is None: + configuration = Configuration() + self.configuration = configuration + + self.pool = ThreadPool() + self.rest_client = rest.RESTClientObject(configuration) + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value + self.cookie = cookie + # Set default User-Agent. + self.user_agent = 'Swagger-Codegen/1.0.0/python' + + def __del__(self): + self.pool.close() + self.pool.join() + + @property + def user_agent(self): + """User agent for this API client""" + return self.default_headers['User-Agent'] + + @user_agent.setter + def user_agent(self, value): + self.default_headers['User-Agent'] = value + + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value + + def __call_api( + self, resource_path, method, path_params=None, + query_params=None, header_params=None, body=None, post_params=None, + files=None, response_type=None, auth_settings=None, + _return_http_data_only=None, collection_formats=None, + _preload_content=True, _request_timeout=None): + + config = self.configuration + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict(self.parameters_to_tuples(header_params, + collection_formats)) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples(path_params, + collection_formats) + for k, v in path_params: + # specified safe chars, encode everything + resource_path = resource_path.replace( + '{%s}' % k, + quote(str(v), safe=config.safe_chars_for_path_param) + ) + + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + query_params = self.parameters_to_tuples(query_params, + collection_formats) + + # post parameters + if post_params or files: + post_params = self.prepare_post_parameters(post_params, files) + post_params = self.sanitize_for_serialization(post_params) + post_params = self.parameters_to_tuples(post_params, + collection_formats) + + # auth setting + self.update_params_for_auth(header_params, query_params, auth_settings) + + # body + if body: + body = self.sanitize_for_serialization(body) + + # request url + url = self.configuration.host + resource_path + + # perform request and return response + response_data = self.request( + method, url, query_params=query_params, headers=header_params, + post_params=post_params, body=body, + _preload_content=_preload_content, + _request_timeout=_request_timeout) + + self.last_response = response_data + + return_data = response_data + if _preload_content: + # deserialize response data + if response_type: + return_data = self.deserialize(response_data, response_type) + else: + return_data = None + + if _return_http_data_only: + return (return_data) + else: + return (return_data, response_data.status, + response_data.getheaders()) + + def sanitize_for_serialization(self, obj): + """Builds a JSON POST object. + + If obj is None, return None. + If obj is str, int, long, float, bool, return directly. + If obj is datetime.datetime, datetime.date + convert to string in iso8601 format. + If obj is list, sanitize each element in the list. + If obj is dict, return the dict. + If obj is swagger model, return the properties dict. + + :param obj: The data to serialize. + :return: The serialized form of data. + """ + if obj is None: + return None + elif isinstance(obj, self.PRIMITIVE_TYPES): + return obj + elif isinstance(obj, list): + return [self.sanitize_for_serialization(sub_obj) + for sub_obj in obj] + elif isinstance(obj, tuple): + return tuple(self.sanitize_for_serialization(sub_obj) + for sub_obj in obj) + elif isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + + if isinstance(obj, dict): + obj_dict = obj + else: + # Convert model obj to dict except + # attributes `swagger_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) + for attr, _ in six.iteritems(obj.swagger_types) + if getattr(obj, attr) is not None} + + return {key: self.sanitize_for_serialization(val) + for key, val in six.iteritems(obj_dict)} + + def deserialize(self, response, response_type): + """Deserializes response into an object. + + :param response: RESTResponse object to be deserialized. + :param response_type: class literal for + deserialized object, or string of class name. + + :return: deserialized object. + """ + # handle file downloading + # save response body into a tmp file and return the instance + if response_type == "file": + return self.__deserialize_file(response) + + # fetch data from response object + try: + data = json.loads(response.data) + except ValueError: + data = response.data + + return self.__deserialize(data, response_type) + + def __deserialize(self, data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if type(klass) == str: + if klass.startswith('list['): + sub_kls = re.match(r'list\[(.*)\]', klass).group(1) + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] + + if klass.startswith('dict('): + sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) + return {k: self.__deserialize(v, sub_kls) + for k, v in six.iteritems(data)} + + # convert str to class + if klass in self.NATIVE_TYPES_MAPPING: + klass = self.NATIVE_TYPES_MAPPING[klass] + else: + klass = getattr(api_units.models, klass) + + if klass in self.PRIMITIVE_TYPES: + return self.__deserialize_primitive(data, klass) + elif klass == object: + return self.__deserialize_object(data) + elif klass == datetime.date: + return self.__deserialize_date(data) + elif klass == datetime.datetime: + return self.__deserialize_datatime(data) + else: + return self.__deserialize_model(data, klass) + + def call_api(self, resource_path, method, + path_params=None, query_params=None, header_params=None, + body=None, post_params=None, files=None, + response_type=None, auth_settings=None, async_req=None, + _return_http_data_only=None, collection_formats=None, + _preload_content=True, _request_timeout=None): + """Makes the HTTP request (synchronous) and returns deserialized data. + + To make an async request, set the async_req parameter. + + :param resource_path: Path to method endpoint. + :param method: Method to call. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param response: Response data type. + :param files dict: key -> filename, value -> filepath, + for `multipart/form-data`. + :param async_req bool: execute request asynchronously + :param _return_http_data_only: response data without head status code + and headers + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: + If async_req parameter is True, + the request will be called asynchronously. + The method will return the request thread. + If parameter async_req is False or missing, + then the method will return the response directly. + """ + if not async_req: + return self.__call_api(resource_path, method, + path_params, query_params, header_params, + body, post_params, files, + response_type, auth_settings, + _return_http_data_only, collection_formats, + _preload_content, _request_timeout) + else: + thread = self.pool.apply_async(self.__call_api, (resource_path, + method, path_params, query_params, + header_params, body, + post_params, files, + response_type, auth_settings, + _return_http_data_only, + collection_formats, + _preload_content, _request_timeout)) + return thread + + def request(self, method, url, query_params=None, headers=None, + post_params=None, body=None, _preload_content=True, + _request_timeout=None): + """Makes the HTTP request using RESTClient.""" + if method == "GET": + return self.rest_client.GET(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "HEAD": + return self.rest_client.HEAD(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "OPTIONS": + return self.rest_client.OPTIONS(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "POST": + return self.rest_client.POST(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PUT": + return self.rest_client.PUT(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PATCH": + return self.rest_client.PATCH(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "DELETE": + return self.rest_client.DELETE(url, + query_params=query_params, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + else: + raise ValueError( + "http method must be `GET`, `HEAD`, `OPTIONS`," + " `POST`, `PATCH`, `PUT` or `DELETE`." + ) + + def parameters_to_tuples(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: Parameters as list of tuples, collections formatted + """ + new_params = [] + if collection_formats is None: + collection_formats = {} + for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501 + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, value) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(str(value) for value in v))) + else: + new_params.append((k, v)) + return new_params + + def prepare_post_parameters(self, post_params=None, files=None): + """Builds form parameters. + + :param post_params: Normal form parameters. + :param files: File parameters. + :return: Form parameters with files. + """ + params = [] + + if post_params: + params = post_params + + if files: + for k, v in six.iteritems(files): + if not v: + continue + file_names = v if type(v) is list else [v] + for n in file_names: + with open(n, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([k, tuple([filename, filedata, mimetype])])) + + return params + + def select_header_accept(self, accepts): + """Returns `Accept` based on an array of accepts provided. + + :param accepts: List of headers. + :return: Accept (e.g. application/json). + """ + if not accepts: + return + + accepts = [x.lower() for x in accepts] + + if 'application/json' in accepts: + return 'application/json' + else: + return ', '.join(accepts) + + def select_header_content_type(self, content_types): + """Returns `Content-Type` based on an array of content_types provided. + + :param content_types: List of content-types. + :return: Content-Type (e.g. application/json). + """ + if not content_types: + return 'application/json' + + content_types = [x.lower() for x in content_types] + + if 'application/json' in content_types or '*/*' in content_types: + return 'application/json' + else: + return content_types[0] + + def update_params_for_auth(self, headers, querys, auth_settings): + """Updates header and query params based on authentication setting. + + :param headers: Header parameters dict to be updated. + :param querys: Query parameters tuple list to be updated. + :param auth_settings: Authentication setting identifiers list. + """ + if not auth_settings: + return + + for auth in auth_settings: + auth_setting = self.configuration.auth_settings().get(auth) + if auth_setting: + if not auth_setting['value']: + continue + elif auth_setting['in'] == 'header': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + querys.append((auth_setting['key'], auth_setting['value'])) + else: + raise ValueError( + 'Authentication token must be in `query` or `header`' + ) + + def __deserialize_file(self, response): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + :param response: RESTResponse. + :return: file path. + """ + fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + content_disposition = response.getheader("Content-Disposition") + if content_disposition: + filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition).group(1) + path = os.path.join(os.path.dirname(path), filename) + response_data = response.data + with open(path, "wb") as f: + if isinstance(response_data, str): + # change str to bytes so we can write it + response_data = response_data.encode('utf-8') + f.write(response_data) + else: + f.write(response_data) + return path + + def __deserialize_primitive(self, data, klass): + """Deserializes string to primitive type. + + :param data: str. + :param klass: class literal. + + :return: int, long, float, str, bool. + """ + try: + return klass(data) + except UnicodeEncodeError: + return six.text_type(data) + except TypeError: + return data + + def __deserialize_object(self, value): + """Return a original value. + + :return: object. + """ + return value + + def __deserialize_date(self, string): + """Deserializes string to date. + + :param string: str. + :return: date. + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason="Failed to parse `{0}` as date object".format(string) + ) + + def __deserialize_datatime(self, string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :return: datetime. + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) + ) + + def __hasattr(self, object, name): + return name in object.__class__.__dict__ + + def __deserialize_model(self, data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :param klass: class literal. + :return: model object. + """ + + if not klass.swagger_types and not self.__hasattr(klass, 'get_real_child_model'): + return data + + kwargs = {} + if klass.swagger_types is not None: + for attr, attr_type in six.iteritems(klass.swagger_types): + if (data is not None and + klass.attribute_map[attr] in data and + isinstance(data, (list, dict))): + value = data[klass.attribute_map[attr]] + kwargs[attr] = self.__deserialize(value, attr_type) + + instance = klass(**kwargs) + + if (isinstance(instance, dict) and + klass.swagger_types is not None and + isinstance(data, dict)): + for key, value in data.items(): + if key not in klass.swagger_types: + instance[key] = value + if self.__hasattr(instance, 'get_real_child_model'): + klass_name = instance.get_real_child_model(data) + if klass_name: + instance = self.__deserialize(data, klass_name) + return instance diff --git a/.jupyter/api_units/configuration.py b/.jupyter/api_units/configuration.py new file mode 100644 index 0000000000000000000000000000000000000000..d9746a635357a967d7864586c7e7f480262dba9b --- /dev/null +++ b/.jupyter/api_units/configuration.py @@ -0,0 +1,244 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +from __future__ import absolute_import + +import copy +import logging +import multiprocessing +import sys +import urllib3 + +import six +from six.moves import http_client as httplib + + +class TypeWithDefault(type): + def __init__(cls, name, bases, dct): + super(TypeWithDefault, cls).__init__(name, bases, dct) + cls._default = None + + def __call__(cls): + if cls._default is None: + cls._default = type.__call__(cls) + return copy.copy(cls._default) + + def set_default(cls, default): + cls._default = copy.copy(default) + + +class Configuration(six.with_metaclass(TypeWithDefault, object)): + """NOTE: This class is auto generated by the swagger code generator program. + + Ref: https://github.com/swagger-api/swagger-codegen + Do not edit the class manually. + """ + + def __init__(self): + """Constructor""" + # Default Base url + self.host = "http://localhost:9095" + # Temp file folder for downloading files + self.temp_folder_path = None + + # Authentication Settings + # dict to store API key(s) + self.api_key = {} + # dict to store API prefix (e.g. Bearer) + self.api_key_prefix = {} + # function to refresh API key if expired + self.refresh_api_key_hook = None + # Username for HTTP basic authentication + self.username = "" + # Password for HTTP basic authentication + self.password = "" + # Logging Settings + self.logger = {} + self.logger["package_logger"] = logging.getLogger("api_units") + self.logger["urllib3_logger"] = logging.getLogger("urllib3") + # Log format + self.logger_format = '%(asctime)s %(levelname)s %(message)s' + # Log stream handler + self.logger_stream_handler = None + # Log file handler + self.logger_file_handler = None + # Debug file location + self.logger_file = None + # Debug switch + self.debug = False + + # SSL/TLS verification + # Set this to false to skip verifying SSL certificate when calling API + # from https server. + self.verify_ssl = True + # Set this to customize the certificate file to verify the peer. + self.ssl_ca_cert = None + # client certificate file + self.cert_file = None + # client key file + self.key_file = None + # Set this to True/False to enable/disable SSL hostname verification. + self.assert_hostname = None + + # urllib3 connection pool's maximum number of connections saved + # per pool. urllib3 uses 1 connection as default value, but this is + # not the best value when you are making a lot of possibly parallel + # requests to the same host, which is often the case here. + # cpu_count * 5 is used as default value to increase performance. + self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 + + # Proxy URL + self.proxy = None + # Safe chars for path_param + self.safe_chars_for_path_param = '' + + @property + def logger_file(self): + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + return self.__logger_file + + @logger_file.setter + def logger_file(self, value): + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + self.__logger_file = value + if self.__logger_file: + # If set logging file, + # then add file handler and remove stream handler. + self.logger_file_handler = logging.FileHandler(self.__logger_file) + self.logger_file_handler.setFormatter(self.logger_formatter) + for _, logger in six.iteritems(self.logger): + logger.addHandler(self.logger_file_handler) + if self.logger_stream_handler: + logger.removeHandler(self.logger_stream_handler) + else: + # If not set logging file, + # then add stream handler and remove file handler. + self.logger_stream_handler = logging.StreamHandler() + self.logger_stream_handler.setFormatter(self.logger_formatter) + for _, logger in six.iteritems(self.logger): + logger.addHandler(self.logger_stream_handler) + if self.logger_file_handler: + logger.removeHandler(self.logger_file_handler) + + @property + def debug(self): + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + return self.__debug + + @debug.setter + def debug(self, value): + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + self.__debug = value + if self.__debug: + # if debug status is True, turn on debug logging + for _, logger in six.iteritems(self.logger): + logger.setLevel(logging.DEBUG) + # turn on httplib debug + httplib.HTTPConnection.debuglevel = 1 + else: + # if debug status is False, turn off debug logging, + # setting log level to default `logging.WARNING` + for _, logger in six.iteritems(self.logger): + logger.setLevel(logging.WARNING) + # turn off httplib debug + httplib.HTTPConnection.debuglevel = 0 + + @property + def logger_format(self): + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + return self.__logger_format + + @logger_format.setter + def logger_format(self, value): + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + self.__logger_format = value + self.logger_formatter = logging.Formatter(self.__logger_format) + + def get_api_key_with_prefix(self, identifier): + """Gets API key (with prefix if set). + + :param identifier: The identifier of apiKey. + :return: The token for api key authentication. + """ + if self.refresh_api_key_hook: + self.refresh_api_key_hook(self) + + key = self.api_key.get(identifier) + if key: + prefix = self.api_key_prefix.get(identifier) + if prefix: + return "%s %s" % (prefix, key) + else: + return key + + def get_basic_auth_token(self): + """Gets HTTP basic authentication header (string). + + :return: The token for basic HTTP authentication. + """ + return urllib3.util.make_headers( + basic_auth=self.username + ':' + self.password + ).get('authorization') + + def auth_settings(self): + """Gets Auth Settings dict for api client. + + :return: The Auth Settings information dict. + """ + return { + } + + def to_debug_report(self): + """Gets the essential information for debugging. + + :return: The report for debugging. + """ + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 0.0.1\n"\ + "SDK Package Version: 1.0.0".\ + format(env=sys.platform, pyversion=sys.version) diff --git a/.jupyter/api_units/models/__init__.py b/.jupyter/api_units/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..08e7322d4595851ab810ec897cd98917b07fdeb2 --- /dev/null +++ b/.jupyter/api_units/models/__init__.py @@ -0,0 +1,19 @@ +# coding: utf-8 + +# flake8: noqa +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +from __future__ import absolute_import + +# import models into model package +from api_units.models.units_savecolumnsconcept_body import UnitsSavecolumnsconceptBody +from api_units.models.units_saveconcept_body import UnitsSaveconceptBody +from api_units.models.units_suggest_body import UnitsSuggestBody diff --git a/.jupyter/api_units/models/units_savecolumnsconcept_body.py b/.jupyter/api_units/models/units_savecolumnsconcept_body.py new file mode 100644 index 0000000000000000000000000000000000000000..1237b414feffa530b7b014493c40e6daf6ae40da --- /dev/null +++ b/.jupyter/api_units/models/units_savecolumnsconcept_body.py @@ -0,0 +1,188 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import pprint +import re # noqa: F401 + +import six + +class UnitsSavecolumnsconceptBody(object): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'cdbid': 'int', + 'cid': 'int', + 'tid': 'int', + 'uri': 'str' + } + + attribute_map = { + 'cdbid': 'cdbid', + 'cid': 'cid', + 'tid': 'tid', + 'uri': 'uri' + } + + def __init__(self, cdbid=None, cid=None, tid=None, uri=None): # noqa: E501 + """UnitsSavecolumnsconceptBody - a model defined in Swagger""" # noqa: E501 + self._cdbid = None + self._cid = None + self._tid = None + self._uri = None + self.discriminator = None + if cdbid is not None: + self.cdbid = cdbid + if cid is not None: + self.cid = cid + if tid is not None: + self.tid = tid + if uri is not None: + self.uri = uri + + @property + def cdbid(self): + """Gets the cdbid of this UnitsSavecolumnsconceptBody. # noqa: E501 + + + :return: The cdbid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :rtype: int + """ + return self._cdbid + + @cdbid.setter + def cdbid(self, cdbid): + """Sets the cdbid of this UnitsSavecolumnsconceptBody. + + + :param cdbid: The cdbid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :type: int + """ + + self._cdbid = cdbid + + @property + def cid(self): + """Gets the cid of this UnitsSavecolumnsconceptBody. # noqa: E501 + + + :return: The cid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :rtype: int + """ + return self._cid + + @cid.setter + def cid(self, cid): + """Sets the cid of this UnitsSavecolumnsconceptBody. + + + :param cid: The cid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :type: int + """ + + self._cid = cid + + @property + def tid(self): + """Gets the tid of this UnitsSavecolumnsconceptBody. # noqa: E501 + + + :return: The tid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :rtype: int + """ + return self._tid + + @tid.setter + def tid(self, tid): + """Sets the tid of this UnitsSavecolumnsconceptBody. + + + :param tid: The tid of this UnitsSavecolumnsconceptBody. # noqa: E501 + :type: int + """ + + self._tid = tid + + @property + def uri(self): + """Gets the uri of this UnitsSavecolumnsconceptBody. # noqa: E501 + + + :return: The uri of this UnitsSavecolumnsconceptBody. # noqa: E501 + :rtype: str + """ + return self._uri + + @uri.setter + def uri(self, uri): + """Sets the uri of this UnitsSavecolumnsconceptBody. + + + :param uri: The uri of this UnitsSavecolumnsconceptBody. # noqa: E501 + :type: str + """ + + self._uri = uri + + def to_dict(self): + """Returns the model properties as a dict""" + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + if issubclass(UnitsSavecolumnsconceptBody, dict): + for key, value in self.items(): + result[key] = value + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, UnitsSavecolumnsconceptBody): + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/.jupyter/api_units/models/units_saveconcept_body.py b/.jupyter/api_units/models/units_saveconcept_body.py new file mode 100644 index 0000000000000000000000000000000000000000..16fcdacc063f5f608a6e65034ada792420a0961e --- /dev/null +++ b/.jupyter/api_units/models/units_saveconcept_body.py @@ -0,0 +1,136 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import pprint +import re # noqa: F401 + +import six + +class UnitsSaveconceptBody(object): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'name': 'str', + 'uri': 'str' + } + + attribute_map = { + 'name': 'name', + 'uri': 'uri' + } + + def __init__(self, name=None, uri=None): # noqa: E501 + """UnitsSaveconceptBody - a model defined in Swagger""" # noqa: E501 + self._name = None + self._uri = None + self.discriminator = None + if name is not None: + self.name = name + if uri is not None: + self.uri = uri + + @property + def name(self): + """Gets the name of this UnitsSaveconceptBody. # noqa: E501 + + + :return: The name of this UnitsSaveconceptBody. # noqa: E501 + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """Sets the name of this UnitsSaveconceptBody. + + + :param name: The name of this UnitsSaveconceptBody. # noqa: E501 + :type: str + """ + + self._name = name + + @property + def uri(self): + """Gets the uri of this UnitsSaveconceptBody. # noqa: E501 + + + :return: The uri of this UnitsSaveconceptBody. # noqa: E501 + :rtype: str + """ + return self._uri + + @uri.setter + def uri(self, uri): + """Sets the uri of this UnitsSaveconceptBody. + + + :param uri: The uri of this UnitsSaveconceptBody. # noqa: E501 + :type: str + """ + + self._uri = uri + + def to_dict(self): + """Returns the model properties as a dict""" + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + if issubclass(UnitsSaveconceptBody, dict): + for key, value in self.items(): + result[key] = value + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, UnitsSaveconceptBody): + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/.jupyter/api_units/models/units_suggest_body.py b/.jupyter/api_units/models/units_suggest_body.py new file mode 100644 index 0000000000000000000000000000000000000000..7aaa2366f8bed8b81c00f6db2871d11670c663a5 --- /dev/null +++ b/.jupyter/api_units/models/units_suggest_body.py @@ -0,0 +1,136 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +import pprint +import re # noqa: F401 + +import six + +class UnitsSuggestBody(object): + """NOTE: This class is auto generated by the swagger code generator program. + + Do not edit the class manually. + """ + """ + Attributes: + swagger_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + swagger_types = { + 'offset': 'int', + 'ustring': 'str' + } + + attribute_map = { + 'offset': 'offset', + 'ustring': 'ustring' + } + + def __init__(self, offset=None, ustring=None): # noqa: E501 + """UnitsSuggestBody - a model defined in Swagger""" # noqa: E501 + self._offset = None + self._ustring = None + self.discriminator = None + if offset is not None: + self.offset = offset + if ustring is not None: + self.ustring = ustring + + @property + def offset(self): + """Gets the offset of this UnitsSuggestBody. # noqa: E501 + + + :return: The offset of this UnitsSuggestBody. # noqa: E501 + :rtype: int + """ + return self._offset + + @offset.setter + def offset(self, offset): + """Sets the offset of this UnitsSuggestBody. + + + :param offset: The offset of this UnitsSuggestBody. # noqa: E501 + :type: int + """ + + self._offset = offset + + @property + def ustring(self): + """Gets the ustring of this UnitsSuggestBody. # noqa: E501 + + + :return: The ustring of this UnitsSuggestBody. # noqa: E501 + :rtype: str + """ + return self._ustring + + @ustring.setter + def ustring(self, ustring): + """Sets the ustring of this UnitsSuggestBody. + + + :param ustring: The ustring of this UnitsSuggestBody. # noqa: E501 + :type: str + """ + + self._ustring = ustring + + def to_dict(self): + """Returns the model properties as a dict""" + result = {} + + for attr, _ in six.iteritems(self.swagger_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + if issubclass(UnitsSuggestBody, dict): + for key, value in self.items(): + result[key] = value + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, UnitsSuggestBody): + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/.jupyter/api_units/rest.py b/.jupyter/api_units/rest.py new file mode 100644 index 0000000000000000000000000000000000000000..a4b96071cbd53eb501a9fc5eac1909569705d449 --- /dev/null +++ b/.jupyter/api_units/rest.py @@ -0,0 +1,317 @@ +# coding: utf-8 + +""" + units + + powered by Flasgger # noqa: E501 + + OpenAPI spec version: 0.0.1 + + Generated by: https://github.com/swagger-api/swagger-codegen.git +""" + +from __future__ import absolute_import + +import io +import json +import logging +import re +import ssl + +import certifi +# python 2 and python 3 compatibility library +import six +from six.moves.urllib.parse import urlencode + +try: + import urllib3 +except ImportError: + raise ImportError('Swagger python client requires urllib3.') + + +logger = logging.getLogger(__name__) + + +class RESTResponse(io.IOBase): + + def __init__(self, resp): + self.urllib3_response = resp + self.status = resp.status + self.reason = resp.reason + self.data = resp.data + + def getheaders(self): + """Returns a dictionary of the response headers.""" + return self.urllib3_response.getheaders() + + def getheader(self, name, default=None): + """Returns a given response header.""" + return self.urllib3_response.getheader(name, default) + + +class RESTClientObject(object): + + def __init__(self, configuration, pools_size=4, maxsize=None): + # urllib3.PoolManager will pass all kw parameters to connectionpool + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 + # maxsize is the number of requests to host that are allowed in parallel # noqa: E501 + # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 + + # cert_reqs + if configuration.verify_ssl: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + + # ca_certs + if configuration.ssl_ca_cert: + ca_certs = configuration.ssl_ca_cert + else: + # if not set certificate file, use Mozilla's root certificates. + ca_certs = certifi.where() + + addition_pool_args = {} + if configuration.assert_hostname is not None: + addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 + + if maxsize is None: + if configuration.connection_pool_maxsize is not None: + maxsize = configuration.connection_pool_maxsize + else: + maxsize = 4 + + # https pool manager + if configuration.proxy: + self.pool_manager = urllib3.ProxyManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=ca_certs, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + proxy_url=configuration.proxy, + **addition_pool_args + ) + else: + self.pool_manager = urllib3.PoolManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=ca_certs, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + **addition_pool_args + ) + + def request(self, method, url, query_params=None, headers=None, + body=None, post_params=None, _preload_content=True, + _request_timeout=None): + """Perform requests. + + :param method: http request method + :param url: http request url + :param query_params: query parameters in the url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, + `application/x-www-form-urlencoded` + and `multipart/form-data` + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + """ + method = method.upper() + assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', + 'PATCH', 'OPTIONS'] + + if post_params and body: + raise ValueError( + "body parameter cannot be used with post_params parameter." + ) + + post_params = post_params or {} + headers = headers or {} + + timeout = None + if _request_timeout: + if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821 + timeout = urllib3.Timeout(total=_request_timeout) + elif (isinstance(_request_timeout, tuple) and + len(_request_timeout) == 2): + timeout = urllib3.Timeout( + connect=_request_timeout[0], read=_request_timeout[1]) + + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/json' + + try: + # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` + if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: + if query_params: + url += '?' + urlencode(query_params) + if re.search('json', headers['Content-Type'], re.IGNORECASE): + request_body = '{}' + if body is not None: + request_body = json.dumps(body) + r = self.pool_manager.request( + method, url, + body=request_body, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 + r = self.pool_manager.request( + method, url, + fields=post_params, + encode_multipart=False, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + elif headers['Content-Type'] == 'multipart/form-data': + # must del headers['Content-Type'], or the correct + # Content-Type which generated by urllib3 will be + # overwritten. + del headers['Content-Type'] + r = self.pool_manager.request( + method, url, + fields=post_params, + encode_multipart=True, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + # Pass a `string` parameter directly in the body to support + # other content types than Json when `body` argument is + # provided in serialized form + elif isinstance(body, str): + request_body = body + r = self.pool_manager.request( + method, url, + body=request_body, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + else: + # Cannot generate the request from given parameters + msg = """Cannot prepare a request message for provided + arguments. Please check that your arguments match + declared content type.""" + raise ApiException(status=0, reason=msg) + # For `GET`, `HEAD` + else: + r = self.pool_manager.request(method, url, + fields=query_params, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + except urllib3.exceptions.SSLError as e: + msg = "{0}\n{1}".format(type(e).__name__, str(e)) + raise ApiException(status=0, reason=msg) + + if _preload_content: + r = RESTResponse(r) + + # log response body + logger.debug("response body: %s", r.data) + + if not 200 <= r.status <= 299: + raise ApiException(http_resp=r) + + return r + + def GET(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("GET", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def HEAD(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("HEAD", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def OPTIONS(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("OPTIONS", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def DELETE(self, url, headers=None, query_params=None, body=None, + _preload_content=True, _request_timeout=None): + return self.request("DELETE", url, + headers=headers, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def POST(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("POST", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PUT(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PUT", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PATCH(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PATCH", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + +class ApiException(Exception): + + def __init__(self, status=None, reason=None, http_resp=None): + if http_resp: + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() + else: + self.status = status + self.reason = reason + self.body = None + self.headers = None + + def __str__(self): + """Custom error messages for exception""" + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}\n".format( + self.headers) + + if self.body: + error_message += "HTTP response body: {0}\n".format(self.body) + + return error_message diff --git a/.jupyter/load_test.py b/.jupyter/load_test.py index 55ce49c3b66b281463654f18bd34fd83d8963270..7a6ef465509a58a4ee2d018b9e33abe0390ad3cf 100644 --- a/.jupyter/load_test.py +++ b/.jupyter/load_test.py @@ -4,8 +4,8 @@ import time import os import shutil import uuid +import requests as rq from postgres import Postgres -from datetime import date import api_query.rest from api_authentication.api.authentication_endpoint_api import AuthenticationEndpointApi @@ -17,6 +17,7 @@ from api_query.api.table_data_endpoint_api import TableDataEndpointApi from api_query.api.query_endpoint_api import QueryEndpointApi from api_identifier.api.identifier_endpoint_api import IdentifierEndpointApi from api_identifier.api.persistence_endpoint_api import PersistenceEndpointApi +from api_units.api.default_api import DefaultApi authentication = AuthenticationEndpointApi() user = UserEndpointApi() @@ -27,6 +28,7 @@ query = QueryEndpointApi() data = TableDataEndpointApi() identifier = IdentifierEndpointApi() persistence = PersistenceEndpointApi() +unit = DefaultApi() token = "" @@ -99,7 +101,7 @@ def update_database(container_id, database_id, is_public=True): }, "language": "en", "is_public": is_public, - "publication_year": date.year + "publication_year": 2022 }, container_id, database_id) print("updated database with id %d" % response.id) return response @@ -204,9 +206,9 @@ def create_identifier(container_id, database_id, query_id, visibility="everyone" "affiliation": "TU Wien", "orcid": "0000-0002-9272-6225" }], - "publication_day": date.day, - "publication_month": date.month, - "publication_year": date.year, + "publication_day": 2, + "publication_month": 8, + "publication_year": 2022, "related_identifiers": [{ "value": "http://localhost:3000/container/" + str(container_id) + "/database/" + str(database_id), "type": "URL", @@ -240,10 +242,38 @@ def update_theme(user_id): }, user_id) print("updated theme user with id %d" % user_id) + def verify_user(user_id): db = Postgres("dbname=fda user=postgres password=postgres") token = db.one("SELECT ") + +def find_concept(concept): + response = rq.get("http://localhost:9095/api/units/uri/" + concept) + print("found concept for name %s" % concept) + return response.json() + + +def create_concept(name, uri): + response = rq.post("http://localhost:9095/api/units/saveconcept", { + "name": name, + "uri": uri + }) + print("created concept for name %s" % name) + return response.json() + + +def assign_concept(database_id, table_id, column_id, uri): + response = rq.post("http://localhost:9095/api/units/savecolumnsconcept", { + "cdbid": database_id, + "cid": column_id, + "tid": table_id, + "uri": uri + }) + print("assigned concept to column with id %d" % column_id) + return response.json() + + if __name__ == '__main__': # # create 1 user and 3 containers (public, private, public) @@ -256,6 +286,9 @@ if __name__ == '__main__': dbid = create_database(cid).id update_database(cid, dbid) tid = create_table(cid, dbid).id + curi = find_concept("time")["URI"] + create_concept("time", curi) + assign_concept(dbid, tid, 2, curi) tname = find_table(cid, dbid, tid).internal_name fill_table(cid, dbid, tid) create_query(cid, dbid, "select `id` from `" + tname + "`") diff --git a/fda-database-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java b/fda-database-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java index 4b6fc8d4c40a3b8d506099d15bb436afa9764eac..8a9136f0670dd6b56ff90031b51f8b86ccd9ee90 100644 --- a/fda-database-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java +++ b/fda-database-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java @@ -104,7 +104,7 @@ public abstract class BaseUnitTest { public final static String DATABASE_1_NAME = "Weather"; public final static String DATABASE_1_DESCRIPTION = "Weather somewhere in the world"; public final static String DATABASE_1_PUBLISHER = "TU Wien"; - public final static Short DATABASE_1_PUBLICATION_YEAR = 2022; + public final static Integer DATABASE_1_PUBLICATION_YEAR = 2022; public final static Boolean DATABASE_1_PUBLIC = false; public final static String DATABASE_1_INTERNALNAME = "weather"; public final static String DATABASE_1_EXCHANGE = "fda." + DATABASE_1_INTERNALNAME; diff --git a/fda-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java b/fda-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java index 62daeb5dd8c97282bc7951343e8704957cdd3c52..003e106dc80793a62b9358196d56b054e9858deb 100644 --- a/fda-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java +++ b/fda-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java @@ -28,11 +28,10 @@ import org.springframework.transaction.annotation.Transactional; import javax.persistence.PersistenceException; import java.security.Principal; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.sql.*; import java.time.Instant; +import java.time.temporal.ChronoField; +import java.util.Calendar; import java.util.List; import java.util.Optional; @@ -152,6 +151,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe database.setName(createDto.getName()); database.setInternalName(databaseMapper.nameToInternalName(database.getName())); database.setContainer(container); + database.setPublicationYear(Calendar.getInstance().get(Calendar.YEAR)); final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container); try { /* create database */ diff --git a/fda-identifier-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java b/fda-identifier-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java index 3d73541ada4d1faf1f64b0b2009dcced171a20da..c5937971671d0f445c02df17c3a5cfd99781f3f8 100644 --- a/fda-identifier-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java +++ b/fda-identifier-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java @@ -246,7 +246,7 @@ public abstract class BaseUnitTest { public final static Instant IDENTIFIER_1_CREATED = Instant.ofEpochSecond(1641588352); public final static Instant IDENTIFIER_1_MODIFIED = Instant.ofEpochSecond(1541588352); public final static Instant IDENTIFIER_1_EXECUTION = Instant.ofEpochSecond(1541588352); - public final static Short IDENTIFIER_1_PUBLICATION_YEAR = 2022; + public final static Integer IDENTIFIER_1_PUBLICATION_YEAR = 2022; public final static String IDENTIFIER_1_QUERY_HASH = "abc"; public final static String IDENTIFIER_1_RESULT_HASH = "def"; public final static String IDENTIFIER_1_QUERY = "SELECT `id` FROM `foobar`"; @@ -264,9 +264,9 @@ public abstract class BaseUnitTest { public final static Instant IDENTIFIER_2_CREATED = Instant.ofEpochSecond(1641588352); public final static Instant IDENTIFIER_2_MODIFIED = Instant.ofEpochSecond(1541588352); public final static Instant IDENTIFIER_2_EXECUTION = Instant.ofEpochSecond(1541588352); - public final static Short IDENTIFIER_2_PUBLICATION_DAY = 14; - public final static Short IDENTIFIER_2_PUBLICATION_MONTH = 7; - public final static Short IDENTIFIER_2_PUBLICATION_YEAR = 2022; + public final static Integer IDENTIFIER_2_PUBLICATION_DAY = 14; + public final static Integer IDENTIFIER_2_PUBLICATION_MONTH = 7; + public final static Integer IDENTIFIER_2_PUBLICATION_YEAR = 2022; public final static String IDENTIFIER_2_QUERY_HASH = "abc"; public final static String IDENTIFIER_2_RESULT_HASH = "def"; public final static String IDENTIFIER_2_QUERY = "SELECT `id` FROM `foobar`"; diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/mapper/DocumentMapper.java b/fda-identifier-service/services/src/main/java/at/tuwien/mapper/DocumentMapper.java index 152d2e4feb030da0c211947233ed4c4e9db4fc76..c7b97e3af0e7553a59ffc1138e5083b9851fc640 100644 --- a/fda-identifier-service/services/src/main/java/at/tuwien/mapper/DocumentMapper.java +++ b/fda-identifier-service/services/src/main/java/at/tuwien/mapper/DocumentMapper.java @@ -90,7 +90,7 @@ public interface DocumentMapper { } if (related.getRelation() != null) { builder.append(" relationType=\"") - .append(related.getRelation()) + .append(related.getRelation().name()) .append("\""); } builder.append(">") @@ -112,10 +112,7 @@ public interface DocumentMapper { .append(data.getDescription()) .append("</description></descriptions>"); } - builder.append("<version>1.0</version><descriptions>") - .append("<description xml:lang=\"en\" descriptionType=\"Abstract\">") - .append(data.getDescription()) - .append("</description></descriptions>") + builder.append("<version>1.0</version>") .append("</resource>"); log.trace("mapped identifier to xml {}", builder); return new InputStreamResource(IOUtils.toInputStream(builder.toString(), Charset.defaultCharset())); diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java index a9c1223a3f87133252c16f6d52e0e5af46033ef3..513b7e9458e604df91f96b144a7676c9453b79da 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java @@ -64,9 +64,10 @@ public class DatabaseDto { @Parameter(name = "database contact person") private UserDto contact; + @NotNull @JsonProperty("publication_year") @Parameter(name = "database publication year") - private Short publicationYear; + private Integer publicationYear; @Parameter(name = "tables") private List<TableBriefDto> tables; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseModifyDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseModifyDto.java index ba5804fa7213d955af9ccaa36150a5c919645f2c..ec8696bef5ede35b3b79909413529d971e839d7c 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseModifyDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseModifyDto.java @@ -31,10 +31,10 @@ public class DatabaseModifyDto { @Parameter(name = "database publisher", example = "TU Wien") private String publisher; - @NotBlank + @NotNull @JsonProperty("publication_year") @Parameter(name = "database publication year") - private Short publicationYear; + private Integer publicationYear; @Parameter(name = "database license") private LicenseDto license; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierCreateDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierCreateDto.java index 90b176d4db1c589c92e0dded17766f0de85c15dc..a35fc8b47abbe504c0806179541afacdacd18149 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierCreateDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierCreateDto.java @@ -41,16 +41,16 @@ public class IdentifierCreateDto { @JsonProperty("publication_day") @Parameter(name = "publication day") - private Short publicationDay; + private Integer publicationDay; @JsonProperty("publication_month") @Parameter(name = "publication month") - private Short publicationMonth; + private Integer publicationMonth; @NotNull @JsonProperty("publication_year") @Parameter(name = "publication year") - private Short publicationYear; + private Integer publicationYear; @NotNull @Parameter(name = "creators") diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java index e5e3d33c55fc270e9568efc5af11c516b6432c3f..42763f8c31387a81466b732792a3c1ef30a6f269 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierDto.java @@ -88,16 +88,16 @@ public class IdentifierDto { @JsonProperty("publication_day") @Parameter(name = "publication day") - private Short publicationDay; + private Integer publicationDay; @JsonProperty("publication_month") @Parameter(name = "publication month") - private Short publicationMonth; + private Integer publicationMonth; @NotNull @JsonProperty("publication_year") @Parameter(name = "publication year") - private Short publicationYear; + private Integer publicationYear; @NotNull @Parameter(name = "creators") diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java index 68e952263dedb4c5152013df3cd3b7e85cfd2d8c..60f95dcc6ce8b92c4a34620fbd241e9cc714a735 100644 --- a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java +++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java @@ -76,7 +76,7 @@ public class Database { private String publisher; @Column - private Short publicationYear; + private Integer publicationYear; @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) @JoinColumns({ diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java index a6ec125f5dece091fa881f3374b3e0c029f35588..375b9e4a5639b467e627fe6ce22dba30e400a53e 100644 --- a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java +++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java @@ -79,13 +79,13 @@ public class Identifier { private Long resultNumber; @Column(nullable = false) - private Short publicationYear; + private Integer publicationYear; @Column - private Short publicationMonth; + private Integer publicationMonth; @Column - private Short publicationDay; + private Integer publicationDay; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumns({ diff --git a/fda-metadata-db/setup-schema.sql b/fda-metadata-db/setup-schema.sql index d6f20c96bb009030800352b5c9d9cf2e1f8e87bf..f5dd40b1369e28b12f1d14a399f0a6d4c6eea14b 100644 --- a/fda-metadata-db/setup-schema.sql +++ b/fda-metadata-db/setup-schema.sql @@ -278,7 +278,7 @@ CREATE TABLE IF NOT EXISTS mdb_databases internal_name character varying(255) NOT NULL, exchange character varying(255) NOT NULL, subject character varying(255), - publication_year smallint, + publication_year INTEGER, ResourceType TEXT, Description TEXT, Engine VARCHAR(20) DEFAULT 'Postgres', @@ -458,9 +458,9 @@ CREATE TABLE IF NOT EXISTS mdb_identifiers title VARCHAR(255) NOT NULL, description TEXT NOT NULL, visibility VARCHAR(10) NOT NULL DEFAULT 'SELF', - publication_year smallint NOT NULL, - publication_month smallint, - publication_day smallint, + publication_year INTEGER NOT NULL, + publication_month INTEGER, + publication_day INTEGER, query TEXT NOT NULL, query_normalized TEXT NOT NULL, query_hash VARCHAR(255) NOT NULL, diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java index 56125529d8d94da58eb35125aebc18f8b0edd2c1..10cd45680a456d90aeedd3a6f47e5ccd0c6a871a 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java @@ -37,7 +37,7 @@ public abstract class AbstractEndpoint { return false; } /* view-only operations are allowed on public databases */ - if (database.getIsPublic() && List.of("TABLE_EXPORT", "DATA_VIEW", "DATA_HISTORY", "QUERY_VIEW_ALL").contains(permissionCode)) { + if (database.getIsPublic() && List.of("TABLE_EXPORT", "DATA_VIEW", "DATA_HISTORY", "QUERY_VIEW_ALL", "QUERY_EXECUTE").contains(permissionCode)) { log.debug("grant permission {} because database is public", permissionCode); return true; } diff --git a/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java b/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java index f1bc79f8191c512c2ba38a221853ea3292b03367..c39ade7008a6a118ac5403da1b8164df39023538 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java +++ b/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java @@ -652,17 +652,6 @@ public interface QueryMapper { } } - default Long resultSetToLong(ResultSet data) { - try { - if (data.next()) { - return data.getLong(1); - } - } catch (SQLException e) { - return null; - } - return null; - } - default PreparedStatement tableToRawFindAllQuery(Connection connection, Table table, Instant timestamp, Long size, Long page) throws ImageNotSupportedException, QueryMalformedException { /* param check */ diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java index 0ff0e3fc64e7123c1acb80cfb2aa9a2314b28339..b88f806e14590475d314e897004c4a56cc44fd34 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java @@ -23,8 +23,6 @@ import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.*; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.RandomStringUtils; -import org.hibernate.Session; -import org.hibernate.query.NativeQuery; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.stereotype.Service; diff --git a/fda-ui/components/DBToolbar.vue b/fda-ui/components/DBToolbar.vue index e20d3034dcea84c74c9edd2965604ea028acac44..229c09bfd25ed4f0a0c728864328e1aefb538a2b 100644 --- a/fda-ui/components/DBToolbar.vue +++ b/fda-ui/components/DBToolbar.vue @@ -20,7 +20,7 @@ </v-toolbar-title> <template v-slot:extension> <v-tabs v-model="tab" color="primary"> - <v-tab :to="`/container/${$route.params.container_id}/database/${databaseId}`"> + <v-tab :to="`/container/${$route.params.container_id}/database/${databaseId}/info`"> Info </v-tab> <v-tab :to="`/container/${$route.params.container_id}/database/${databaseId}/table`"> diff --git a/fda-ui/components/TableList.vue b/fda-ui/components/TableList.vue index a5149bccf7fe396516727933c1af88a46459c398..1ec27ab34debc7dcaf421b32abfa83e0f85454d7 100644 --- a/fda-ui/components/TableList.vue +++ b/fda-ui/components/TableList.vue @@ -1,6 +1,6 @@ <template> <div> - <v-progress-linear v-if="loading" :color="loadingColor" /> + <v-progress-linear v-if="loading" :color="loadingColor" indeterminate /> <v-card v-if="!loading && tables.length === 0" flat> <v-card-title> (no tables) @@ -80,12 +80,15 @@ </v-row> <v-row dense> <v-col> - <v-btn :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/${item.id}`"> + <v-btn color="secondary" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/${item.id}`"> View Data </v-btn> <v-btn color="secondary" class="ml-2" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/query/create?tid=${item.id}`"> Create Subset </v-btn> + <v-btn class="ml-2" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/${item.id}/import`"> + Import csv + </v-btn> </v-col> <v-col class="align-right"> <v-btn v-if="false" outlined color="error" @click="showDeleteTableDialog(item.id)"> diff --git a/fda-ui/pages/container/_container_id/database/_database_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/index.vue index d7b586ac145832845219a90836569c0fc7377282..e39d3d7b62049773de5edcbde3dabf7d92e6c7c6 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/index.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/index.vue @@ -1,210 +1,13 @@ <template> - <div> - <DBToolbar /> - <v-progress-linear v-if="loading" /> - <v-tabs-items v-model="tab"> - <v-tab-item> - <v-card flat> - <v-card-text> - <v-list dense> - <v-list-item> - <v-list-item-content> - <v-list-item-title> - Database Visibility - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ database.is_public ? 'Public' : 'Private' }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Database Publisher - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ publisher }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Database Internal Name - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ internal_name }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Database Description - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="paragraph" width="50%" /> - <span v-if="!loading">{{ description }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Database Creator - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading"> - {{ creator }} - <sup> - <v-icon v-if="database.creator.email_verified" small color="primary">mdi-check-decagram</v-icon> - </sup> - </span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Created - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ createdUTC }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Language - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ language }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - Publication Date - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <span v-if="!loading">{{ publication }}</span> - </v-list-item-content> - <v-list-item-title class="mt-2"> - License - </v-list-item-title> - <v-list-item-content> - <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> - <a v-if="database.license" target="_blank" :href="database.license.uri">{{ database.license.identifier }}</a> - <span v-if="!database.license">(none)</span> - </v-list-item-content> - </v-list-item-content> - </v-list-item> - </v-list> - <v-btn color="secondary" @click="editDbDialog = true">Edit</v-btn> - <v-dialog - v-model="editDbDialog" - persistent - max-width="640"> - <EditDB :database="database" @close-dialog="closeDialog" /> - </v-dialog> - </v-card-text> - </v-card> - </v-tab-item> - </v-tabs-items> - <v-breadcrumbs :items="items" class="pa-0 mt-2" /> - </div> + <div /> </template> <script> -import DBToolbar from '@/components/DBToolbar' -import EditDB from '@/components/dialogs/EditDB' -import { formatTimestampUTCLabel, formatUser } from '@/utils' - export default { - components: { - DBToolbar, - EditDB - }, - data () { - return { - loading: false, - editDbDialog: false, - database: { - id: null, - name: null, - description: null, - is_public: null, - publisher: null, - created: null, - subject: [], - language: null, - license: { - uri: null, - identifier: null - }, - creator: { - titles_before: null, - firstname: null, - lastname: null, - username: null, - titles_after: null - } - }, - items: [ - { text: 'Databases', to: '/container', activeClass: '' }, - { - text: `${this.$route.params.database_id}`, - to: `/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/info`, - activeClass: '' - } - ] - } - }, - computed: { - tab () { - return 0 - }, - description () { - return this.database.description === null ? '(no description)' : this.database.description - }, - publisher () { - return this.database.publisher === null ? '(none)' : this.database.publisher - }, - token () { - return this.$store.state.token - }, - config () { - if (this.token === null) { - return {} - } - return { - headers: { Authorization: `Bearer ${this.token}` } - } - }, - createdUTC () { - return formatTimestampUTCLabel(this.database.created) - }, - language () { - return this.database.language === null ? '(none)' : this.database.language - }, - internal_name () { - return this.database.internal_name - }, - publication () { - return this.database.publication === null ? '(none)' : this.database.publication - }, - creator () { - return formatUser(this.database.creator) - } - }, mounted () { - this.loadDatabase() - }, - methods: { - async loadDatabase () { - this.loading = true - try { - const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}`, this.config) - this.database = res.data - console.debug('database', res.data) - } catch (err) { - this.$toast.error('Could not load database.') - } - this.loading = false - }, - closeDialog () { - this.loadDatabase() - this.editDbDialog = false - } + this.$router.push(`/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/info`) } } </script> <style> -.v-card__text { - font-size: initial; -} -.skeleton-small .v-skeleton-loader__text { - width: 100px; -} </style> diff --git a/fda-ui/pages/container/_container_id/database/_database_id/info.vue b/fda-ui/pages/container/_container_id/database/_database_id/info.vue new file mode 100644 index 0000000000000000000000000000000000000000..d7b586ac145832845219a90836569c0fc7377282 --- /dev/null +++ b/fda-ui/pages/container/_container_id/database/_database_id/info.vue @@ -0,0 +1,210 @@ +<template> + <div> + <DBToolbar /> + <v-progress-linear v-if="loading" /> + <v-tabs-items v-model="tab"> + <v-tab-item> + <v-card flat> + <v-card-text> + <v-list dense> + <v-list-item> + <v-list-item-content> + <v-list-item-title> + Database Visibility + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ database.is_public ? 'Public' : 'Private' }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Database Publisher + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ publisher }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Database Internal Name + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ internal_name }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Database Description + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="paragraph" width="50%" /> + <span v-if="!loading">{{ description }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Database Creator + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading"> + {{ creator }} + <sup> + <v-icon v-if="database.creator.email_verified" small color="primary">mdi-check-decagram</v-icon> + </sup> + </span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Created + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ createdUTC }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Language + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ language }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + Publication Date + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <span v-if="!loading">{{ publication }}</span> + </v-list-item-content> + <v-list-item-title class="mt-2"> + License + </v-list-item-title> + <v-list-item-content> + <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" /> + <a v-if="database.license" target="_blank" :href="database.license.uri">{{ database.license.identifier }}</a> + <span v-if="!database.license">(none)</span> + </v-list-item-content> + </v-list-item-content> + </v-list-item> + </v-list> + <v-btn color="secondary" @click="editDbDialog = true">Edit</v-btn> + <v-dialog + v-model="editDbDialog" + persistent + max-width="640"> + <EditDB :database="database" @close-dialog="closeDialog" /> + </v-dialog> + </v-card-text> + </v-card> + </v-tab-item> + </v-tabs-items> + <v-breadcrumbs :items="items" class="pa-0 mt-2" /> + </div> +</template> + +<script> +import DBToolbar from '@/components/DBToolbar' +import EditDB from '@/components/dialogs/EditDB' +import { formatTimestampUTCLabel, formatUser } from '@/utils' + +export default { + components: { + DBToolbar, + EditDB + }, + data () { + return { + loading: false, + editDbDialog: false, + database: { + id: null, + name: null, + description: null, + is_public: null, + publisher: null, + created: null, + subject: [], + language: null, + license: { + uri: null, + identifier: null + }, + creator: { + titles_before: null, + firstname: null, + lastname: null, + username: null, + titles_after: null + } + }, + items: [ + { text: 'Databases', to: '/container', activeClass: '' }, + { + text: `${this.$route.params.database_id}`, + to: `/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/info`, + activeClass: '' + } + ] + } + }, + computed: { + tab () { + return 0 + }, + description () { + return this.database.description === null ? '(no description)' : this.database.description + }, + publisher () { + return this.database.publisher === null ? '(none)' : this.database.publisher + }, + token () { + return this.$store.state.token + }, + config () { + if (this.token === null) { + return {} + } + return { + headers: { Authorization: `Bearer ${this.token}` } + } + }, + createdUTC () { + return formatTimestampUTCLabel(this.database.created) + }, + language () { + return this.database.language === null ? '(none)' : this.database.language + }, + internal_name () { + return this.database.internal_name + }, + publication () { + return this.database.publication === null ? '(none)' : this.database.publication + }, + creator () { + return formatUser(this.database.creator) + } + }, + mounted () { + this.loadDatabase() + }, + methods: { + async loadDatabase () { + this.loading = true + try { + const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}`, this.config) + this.database = res.data + console.debug('database', res.data) + } catch (err) { + this.$toast.error('Could not load database.') + } + this.loading = false + }, + closeDialog () { + this.loadDatabase() + this.editDbDialog = false + } + } +} +</script> +<style> +.v-card__text { + font-size: initial; +} +.skeleton-small .v-skeleton-loader__text { + width: 100px; +} +</style> diff --git a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue index 7623073dbdca02119ad8e8f5a4cd310ed55fad23..e2c628149809449cdd710e260d424f282c4cc5ed 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue @@ -311,9 +311,6 @@ export default { } }, computed: { - token () { - return this.$store.state.token - }, result_icon () { return this.erroneous && !this.loadingQuery ? 'mdi-flash' : 'mdi-table' }, @@ -323,6 +320,9 @@ export default { loadingColor () { return this.error ? 'red' : 'primary' }, + token () { + return this.$store.state.token + }, config () { if (this.token === null) { return {} @@ -404,10 +404,7 @@ export default { async metadata () { this.metadataLoading = true try { - const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/identifier/${this.identifier.id}`, { - headers: { Authorization: `Bearer ${this.token}` }, - responseType: 'text' - }) + const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/identifier/${this.identifier.id}`, this.config) console.debug('identifier result', res) const url = window.URL.createObjectURL(new Blob([res.data])) const link = document.createElement('a') diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue index bb6c37509f8b82761c867b3b73a282b5d48ed324..ccc79ac9df1a6a08cd00065cb8987ec2ea73531b 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/import.vue @@ -1,97 +1,101 @@ <template> <div> <v-toolbar flat> - <v-toolbar-title>Import Data</v-toolbar-title> - <v-spacer /> <v-toolbar-title> - <v-btn :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/${$route.params.table_id}`"> - <v-icon left>mdi-table</v-icon> - View Table + <v-btn id="back-btn" class="mr-2" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table`"> + <v-icon left>mdi-arrow-left</v-icon> </v-btn> </v-toolbar-title> - </v-toolbar> - <v-card> - <v-card-title v-if="!loading"> + <v-toolbar-title> {{ table.name }} - </v-card-title> - <v-card-subtitle>{{ table.internal_name }}</v-card-subtitle> - <v-card-text> - <v-row dense> - <v-col cols="8"> - <v-select - v-model="tableImport.separator" - :items="separators" - item-text="key" - item-value="value" - required - hint="Character separating the values" - label="Separator *" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-text-field - v-model.number="tableImport.skip_lines" - :rules="[v => isNonNegativeInteger(v) || $t('Greater or equal to zero')]" - type="number" - required - hint="Skip n lines from the top. These may include comments or the header of column names." - label="Number of lines to skip *" - placeholder="e.g. 0" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-select - v-model="tableImport.quote" - :items="quotes" - item-text="key" - item-value="value" - hint="Character quoting the values" - label="Value quotes" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-text-field - v-model="tableImport.null_element" - hint="Representation of 'no value present'" - placeholder="e.g. NA" - label="NULL Element" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-text-field - v-model="tableImport.true_element" - label="True Element" - hint="Representation of boolean 'true'" - placeholder="e.g. 1, true, YES" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-text-field - v-model="tableImport.false_element" - label="False Element" - hint="Representation of boolean 'false'" - placeholder="e.g. 0, false, NO" /> - </v-col> - </v-row> - <v-row dense> - <v-col cols="8"> - <v-file-input - v-model="file" - accept=".csv,.tsv" - show-size - label="CSV/TSV File" /> - </v-col> - </v-row> - </v-card-text> - <v-card-actions> - <v-btn :disabled="!file" :loading="loading" color="primary" @click="upload">Upload</v-btn> - </v-card-actions> - </v-card> + </v-toolbar-title> + </v-toolbar> + <v-stepper v-model="step" vertical flat> + <v-stepper-step :complete="step > 1" step="1"> + Import Data + </v-stepper-step> + + <v-stepper-content step="1"> + <v-form ref="form" v-model="validStep1" @submit.prevent="submit"> + <v-row dense> + <v-col cols="8"> + <v-select + v-model="tableImport.separator" + :items="separators" + item-text="key" + item-value="value" + required + hint="Character separating the values" + label="Separator *" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-text-field + v-model.number="tableImport.skip_lines" + :rules="[v => isNonNegativeInteger(v) || $t('Greater or equal to zero')]" + type="number" + required + hint="Skip n lines from the top. These may include comments or the header of column names." + label="Number of lines to skip *" + placeholder="e.g. 0" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-select + v-model="tableImport.quote" + :items="quotes" + item-text="key" + item-value="value" + hint="Character quoting the values" + label="Value quotes" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-text-field + v-model="tableImport.null_element" + hint="Representation of 'no value present'" + placeholder="e.g. NA" + label="NULL Element" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-text-field + v-model="tableImport.true_element" + label="True Element" + hint="Representation of boolean 'true'" + placeholder="e.g. 1, true, YES" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-text-field + v-model="tableImport.false_element" + label="False Element" + hint="Representation of boolean 'false'" + placeholder="e.g. 0, false, NO" /> + </v-col> + </v-row> + <v-row dense> + <v-col cols="8"> + <v-file-input + v-model="file" + accept=".csv,.tsv" + show-size + label="CSV/TSV File" /> + </v-col> + </v-row> + <v-row> + <v-col cols="8"> + <v-btn :disabled="!file" :loading="loading" color="primary" @click="upload">Upload</v-btn> + </v-col> + </v-row> + </v-form> + </v-stepper-content> + </v-stepper> <v-breadcrumbs :items="items" class="pa-0 mt-2" /> </div> </template> @@ -104,6 +108,8 @@ export default { data () { return { loading: false, + step: 1, + validStep1: false, separators: [ { key: ',', value: ',' }, { key: ';', value: ';' }, @@ -155,6 +161,9 @@ export default { }, methods: { isNonNegativeInteger, + submit () { + this.$refs.form.validate() + }, async info () { this.loading = true const infoUrl = `/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table/${this.tableId}` @@ -210,6 +219,14 @@ export default { } } </script> - <style> +#back-btn { + min-width: auto; + padding: 0 0 0 12px; + background: none !important; + box-shadow: none; +} +#back-btn::before { + opacity: 0; +} </style> diff --git a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue index 269887ef5277bbf3b4ffd5ce062badc352e78420..b40ce18cb6c382b26d7dbf2c35d8af02347fff63 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/table/_table_id/index.vue @@ -83,7 +83,7 @@ <script> import EditTuple from '@/components/dialogs/EditTuple' import TimeTravel from '@/components/dialogs/TimeTravel' -import { formatTimestampUTCLabel, formatDateUTC } from '@/utils' +import { formatTimestampUTCLabel, formatDateUTC, formatTimestamp } from '@/utils' export default { components: { @@ -226,9 +226,11 @@ export default { this.pickVersionDialog = true }, pickVersion (event) { + const date = new Date(event.time) + date.setSeconds(date.getSeconds() + 1) console.debug('closed', event) if (event.time) { - this.version = event.time + this.version = formatTimestamp(date) } this.pickVersionDialog = false },