Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
TonioF committed Jul 10, 2020
2 parents 7e7c48e + df19e31 commit 3cce09f
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Version 2.1.0 (in development)
* Cate Web API is now handling user preferences
* Added normalization method in order to handle datasets with zonal means
which have no longitude information.
* Increased robustness when using netcdf library
Expand Down
6 changes: 4 additions & 2 deletions cate/conf/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from .defaults import GLOBAL_CONF_FILE, LOCAL_CONF_FILE, LOCATION_FILE, VERSION_CONF_FILE, \
VARIABLE_DISPLAY_SETTINGS, DEFAULT_DATA_PATH, DEFAULT_VERSION_DATA_PATH, DEFAULT_COLOR_MAP, DEFAULT_RES_PATTERN, \
WEBAPI_USE_WORKSPACE_IMAGERY_CACHE, DEFAULT_VARIABLES, DATASET_PERSISTENCE_FORMAT
WEBAPI_USE_WORKSPACE_IMAGERY_CACHE, DEFAULT_VARIABLES, DATASET_PERSISTENCE_FORMAT, USER_PREFERENCES_FILE

_CONFIG = None

Expand Down Expand Up @@ -147,9 +147,11 @@ def get_config() -> dict:
if _CONFIG is None:
_init_config([GLOBAL_CONF_FILE,
VERSION_CONF_FILE,
LOCAL_CONF_FILE],
LOCAL_CONF_FILE,
USER_PREFERENCES_FILE],
[DEFAULT_DATA_PATH,
DEFAULT_VERSION_DATA_PATH])

return _CONFIG


Expand Down
1 change: 1 addition & 0 deletions cate/conf/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
VERSION_CONF_FILE = os.path.join(DEFAULT_VERSION_DATA_PATH, 'conf.py')
LOCAL_CONF_FILE = 'cate-conf.py'
LOCATION_FILE = 'cate.location'
USER_PREFERENCES_FILE = 'user-preferences.json'

WORKSPACES_DIR_NAME = 'workspaces'
SCRATCH_WORKSPACES_DIR_NAME = 'scratch'
Expand Down
123 changes: 123 additions & 0 deletions cate/conf/userprefs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import json
import logging
import os

from cate.conf import USER_PREFERENCES_FILE, DEFAULT_DATA_PATH

_DEFAULT_USER_PREFS = {
"reopenLastWorkspace": True,
"lastWorkspacePath": "",
"autoUpdateSoftware": True,
"autoShowNewFigures": True,
"offlineMode": False,
"showSelectedVariableLayer": True,
"savedLayers": {},
"selectedDataStoreId": "",
"selectedDataSourceId": None,
"dataSourceFilterExpr": "",
"selectedOperationName": None,
"operationFilterTags": [],
"operationFilterExpr": "",
"dataSourceListHeight": 200,
"showDataSourceDetails": True,
"resourceListHeight": 100,
"showResourceDetails": True,
"workflowStepListHeight": 100,
"showWorkflowStepDetails": True,
"operationListHeight": 200,
"showOperationDetails": True,
"variableListHeight": 200,
"showVariableDetails": True,
"layerListHeight": 160,
"showLayerDetails": True,
"panelContainerUndockedMode": False,
"leftPanelContainerLayout": {
"horPos": 300,
"verPos": 400
},
"rightPanelContainerLayout": {
"horPos": 300,
"verPos": 400
},
"selectedLeftTopPanelId": "dataSources",
"selectedLeftBottomPanelId": "operations",
"selectedRightTopPanelId": "workspace",
"selectedRightBottomPanelId": "variables",
"placemarkCollection": {
"type": "FeatureCollection",
"features": []
},
"selectedPlacemarkId": None,
"placemarkListHeight": 160,
"showPlacemarkDetails": True,
"defaultPlacemarkStyle": {
"markerSize": "small",
"markerColor": "#ff0000",
"markerSymbol": "",
"fill": "#0000ff",
"fillOpacity": 0.5,
"stroke": "#ffff00",
"strokeOpacity": 0.5,
"strokeWidth": 1
},
"workspacePanelMode": "steps",
"showDataStoreDescription": False,
"showDataStoreNotices": True,
"showDataSourceIDs": True,
"showLayerTextOverlay": True,
"debugWorldView": False,
"styleContext": "entity",
"backendConfig": {
"dataStoresPath": "~/.cate/data_stores",
"useWorkspaceImageryCache": False,
"resourceNamePattern": "res_{index}",
"proxyUrl": None
}
}

_LOG = logging.getLogger('cate')


def _write_user_prefs_file(user_prefs_file: str, user_prefs: dict):
try:
with open(user_prefs_file, 'w') as fp:
json.dump(user_prefs, fp)
except Exception as error:
_LOG.warning('failed writing %s: %s' % (user_prefs_file, str(error)))


def _read_user_prefs(user_prefs_file: str) -> dict:
if user_prefs_file and os.path.isfile(user_prefs_file):
user_prefs = None
try:
with open(user_prefs_file, 'r') as pfile:
user_prefs = json.load(pfile)
except Exception as error:
_LOG.warning('failed reading %s: %s' % (user_prefs_file, str(error)))

if user_prefs is not None:
return user_prefs
else:
_LOG.error("Could not load user prefs")


def set_user_prefs(prefs: dict, user_prefs_file: str = None):
if not user_prefs_file:
user_prefs_file = os.path.join(DEFAULT_DATA_PATH, USER_PREFERENCES_FILE)

if not os.path.isfile(user_prefs_file):
_write_user_prefs_file(user_prefs_file, _DEFAULT_USER_PREFS)

_write_user_prefs_file(user_prefs_file, prefs)

return get_user_prefs()


def get_user_prefs(user_prefs_file: str = None) -> dict:
if not user_prefs_file:
user_prefs_file = os.path.join(DEFAULT_DATA_PATH, USER_PREFERENCES_FILE)

if not os.path.isfile(user_prefs_file):
_write_user_prefs_file(user_prefs_file, _DEFAULT_USER_PREFS)

return _read_user_prefs(user_prefs_file)
24 changes: 23 additions & 1 deletion cate/webapi/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"""
import os
import warnings
import re

warnings.filterwarnings("ignore") # never print any warnings to users
import sys
Expand Down Expand Up @@ -85,6 +84,28 @@ def get(self):
self.finish()


# noinspection PyAbstractClass
class WebAPICfgHandler(WebAPIRequestHandler):
def get(self):
user_root_mode = isinstance(self.application.workspace_manager, RelativeFSWorkspaceManager)

self.write_status_ok(content={'name': SERVICE_NAME,
'version': __version__,
'timestaffmp': date.today().isoformat(),
'user_root_mode': user_root_mode})

self.finish()

def post(self):
pass

def put(self):
pass

def delete(self):
pass


def service_factory(application):
return WebSocketService(application.workspace_manager)

Expand All @@ -111,6 +132,7 @@ def create_application(user_root_path: str = None):
(url_pattern(url_root + 'mpl/download/{{base_dir}}/{{figure_id}}/{{format_name}}'), MplDownloadHandler),
(url_pattern(url_root + 'mpl/figures/{{base_dir}}/{{figure_id}}'), MplWebSocketHandler),
(url_pattern(url_root), WebAPIInfoHandler),
(url_pattern(url_root + 'cfg'), WebAPICfgHandler),
(url_pattern(url_root + 'exit'), WebAPIExitHandler),
(url_pattern(url_root + 'api'), JsonRpcWebSocketHandler, dict(
service_factory=service_factory,
Expand Down
8 changes: 7 additions & 1 deletion cate/webapi/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from collections import OrderedDict
from typing import List, Sequence, Optional, Any, Union, Tuple, Dict

Expand All @@ -30,6 +29,7 @@
from cate.core.op import OP_REGISTRY
from cate.core.workspace import OpKwArgs
from cate.core.wsmanag import WorkspaceManager
from cate.conf.userprefs import set_user_prefs, get_user_prefs
from cate.util.misc import cwd, filter_fileset
from cate.util.monitor import Monitor
from cate.util.sround import sround_range
Expand Down Expand Up @@ -362,3 +362,9 @@ def get_workspace_variable_statistics(self, base_dir: str, res_name: str, var_na

actual_min, actual_max = sround_range((actual_min, actual_max), ndigits=2)
return dict(min=actual_min, max=actual_max)

def set_preferences(self, prefs: dict):
return set_user_prefs(prefs)

def get_preferences(self):
return get_user_prefs()
110 changes: 110 additions & 0 deletions tests/conf/test_userprefs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import os
import tempfile
import unittest

from cate.conf.userprefs import get_user_prefs, set_user_prefs

_TEST_USER_PREFS = {
"reopenLastWorkspace": True,
"lastWorkspacePath": "",
"autoUpdateSoftware": True,
"autoShowNewFigures": True,
"offlineMode": False,
"showSelectedVariableLayer": True,
"savedLayers": {},
"selectedDataStoreId": "",
"selectedDataSourceId": None,
"dataSourceFilterExpr": "",
"selectedOperationName": None,
"operationFilterTags": [],
"operationFilterExpr": "",
"dataSourceListHeight": 200,
"showDataSourceDetails": True,
"resourceListHeight": 100,
"showResourceDetails": True,
"workflowStepListHeight": 100,
"showWorkflowStepDetails": True,
"operationListHeight": 200,
"showOperationDetails": True,
"variableListHeight": 200,
"showVariableDetails": True,
"layerListHeight": 160,
"showLayerDetails": True,
"panelContainerUndockedMode": False,
"leftPanelContainerLayout": {
"horPos": 300,
"verPos": 400
},
"rightPanelContainerLayout": {
"horPos": 300,
"verPos": 400
},
"selectedLeftTopPanelId": "dataSources",
"selectedLeftBottomPanelId": "operations",
"selectedRightTopPanelId": "workspace",
"selectedRightBottomPanelId": "variables",
"placemarkCollection": {
"type": "FeatureCollection",
"features": []
},
"selectedPlacemarkId": None,
"placemarkListHeight": 160,
"showPlacemarkDetails": True,
"defaultPlacemarkStyle": {
"markerSize": "small",
"markerColor": "#ff0000",
"markerSymbol": "",
"fill": "#0000ff",
"fillOpacity": 0.5,
"stroke": "#ffff00",
"strokeOpacity": 0.5,
"strokeWidth": 1
},
"workspacePanelMode": "steps",
"showDataStoreDescription": False,
"showDataStoreNotices": True,
"showDataSourceIDs": True,
"showLayerTextOverlay": True,
"debugWorldView": False,
"styleContext": "entity",
"backendConfig": {
"dataStoresPath": "~/.cate/data_stores",
"useWorkspaceImageryCache": False,
"resourceNamePattern": "res_{index}",
"proxyUrl": None
}
}


class MyTestCase(unittest.TestCase):
def test_get_user_prefs(self):
tdir = tempfile.gettempdir()
tfile = os.path.join(tdir, 'test_get_prefs.txt')
prefs = get_user_prefs(tfile)

self.assertDictEqual(_TEST_USER_PREFS, prefs)

n_prefs = _TEST_USER_PREFS.copy()
n_prefs['autoUpdateSoftware'] = True

prefs = set_user_prefs(n_prefs, tfile)

self.assertDictEqual(n_prefs, prefs)

def test_set_user_prefs(self):
tdir = tempfile.gettempdir()
tfile = os.path.join(tdir, 'test_set_prefs.txt')
prefs = set_user_prefs(_TEST_USER_PREFS, tfile)

self.assertDictEqual(_TEST_USER_PREFS, prefs)

n_prefs = _TEST_USER_PREFS.copy()
n_prefs['autoUpdateSoftware'] = True

prefs = set_user_prefs(n_prefs)

self.assertDictEqual(n_prefs, prefs)


if __name__ == '__main__':
unittest.main()

0 comments on commit 3cce09f

Please sign in to comment.