From 32b372346426a870ac7320e8b7840240268dc58f Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Fri, 24 May 2024 08:08:03 +0200 Subject: [PATCH 01/11] separating msmws installation --- mslib/msui/flighttrack.py | 3 +- mslib/msui/mpl_pathinteractor.py | 3 +- mslib/mswms/mswms.py | 13 +------- mslib/utils/coordinate.py | 22 +------------ mslib/utils/locations.py | 48 ++++++++++++++++++++++++++++ requirements.d/mswms.txt | 45 ++++++++++++++++++++++++++ tests/_test_utils/test_coordinate.py | 5 +-- 7 files changed, 102 insertions(+), 37 deletions(-) create mode 100644 mslib/utils/locations.py create mode 100644 requirements.d/mswms.txt diff --git a/mslib/msui/flighttrack.py b/mslib/msui/flighttrack.py index 1d3ad2b15..1753fe782 100644 --- a/mslib/msui/flighttrack.py +++ b/mslib/msui/flighttrack.py @@ -46,7 +46,8 @@ from mslib import __version__ from mslib.utils.units import units -from mslib.utils.coordinate import find_location, path_points, get_distance +from mslib.utils.coordinate import path_points, get_distance +from mslib.utils.locations import find_location from mslib.utils import thermolib from mslib.utils.config import config_loader, save_settings_qsettings, load_settings_qsettings from mslib.utils.config import MSUIDefaultConfig as mss_default diff --git a/mslib/msui/mpl_pathinteractor.py b/mslib/msui/mpl_pathinteractor.py index 59fb8702a..54d35cce6 100644 --- a/mslib/msui/mpl_pathinteractor.py +++ b/mslib/msui/mpl_pathinteractor.py @@ -51,7 +51,8 @@ import matplotlib.patches as mpatches from PyQt5 import QtCore, QtWidgets -from mslib.utils.coordinate import get_distance, find_location, latlon_points, path_points +from mslib.utils.coordinate import get_distance, latlon_points, path_points +from mslib.utils.locations import find_location from mslib.utils.units import units from mslib.utils.thermolib import pressure2flightlevel from mslib.msui import flighttrack as ft diff --git a/mslib/mswms/mswms.py b/mslib/mswms/mswms.py index 987d6a7a2..df71823a3 100644 --- a/mslib/mswms/mswms.py +++ b/mslib/mswms/mswms.py @@ -31,9 +31,8 @@ from mslib import __version__ from mslib.utils import setup_logging -from mslib.utils.qt import Updater, Worker from mslib.mswms.wms import app as application - +q def main(): parser = argparse.ArgumentParser() @@ -87,16 +86,6 @@ def main(): print("Version:", __version__) sys.exit() - updater = Updater() - if args.update: - updater.on_update_available.connect(lambda old, new: updater.update_mss()) - updater.on_log_update.connect(lambda s: print(s.replace("\n", ""))) - updater.on_status_update.connect(lambda s: print(s.replace("\n", ""))) - updater.run() - while Worker.workers: - list(Worker.workers)[0].wait() - sys.exit() - setup_logging(args) # keep the import after the version check. This creates all layers. diff --git a/mslib/utils/coordinate.py b/mslib/utils/coordinate.py index 63138d74a..37762eca9 100644 --- a/mslib/utils/coordinate.py +++ b/mslib/utils/coordinate.py @@ -4,7 +4,7 @@ mslib.utils.coordinate ~~~~~~~~~~~~~~~~ - Collection of functions all around coordinates, locations and positions. + Collection of functions all around coordinates and positions. This file is part of MSS. @@ -33,9 +33,6 @@ from scipy.interpolate import interp1d from scipy.ndimage import map_coordinates -from mslib.utils.config import config_loader - - __PR = Geod(ellps='WGS84') @@ -54,23 +51,6 @@ def get_distance(lat0, lon0, lat1, lon1): return __PR.inv(lon0, lat0, lon1, lat1)[-1] / 1000. -def find_location(lat, lon, tolerance=5): - """ - Checks if a location is present at given coordinates - :param lat: latitude - :param lon: longitude - :param tolerance: maximum distance between location and coordinates in km - :return: None or lat/lon, name - """ - locations = config_loader(dataset='locations') - distances = sorted([(get_distance(lat, lon, loc_lat, loc_lon), loc) - for loc, (loc_lat, loc_lon) in locations.items()]) - if len(distances) > 0 and distances[0][0] <= tolerance: - return locations[distances[0][1]], distances[0][1] - else: - return None - - def fix_angle(ang): """ Normalizes an angle between -180 and 180 degree. diff --git a/mslib/utils/locations.py b/mslib/utils/locations.py new file mode 100644 index 000000000..3f0af9801 --- /dev/null +++ b/mslib/utils/locations.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +""" + + mslib.utils.locations + ~~~~~~~~~~~~~~~~~~~~~ + + Collection of functions all around locations. + + This file is part of MSS. + + :copyright: Copyright 2008-2014 Deutsches Zentrum fuer Luft- und Raumfahrt e.V. + :copyright: Copyright 2011-2014 Marc Rautenhaus (mr) + :copyright: Copyright 2016-2024 by the MSS team, see AUTHORS. + :license: APACHE-2.0, see LICENSE for details. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + + +from mslib.utils.config import config_loader +from mslib.utils.coordinate import get_distance + + +def find_location(lat, lon, tolerance=5): + """ + Checks if a location is present at given coordinates + :param lat: latitude + :param lon: longitude + :param tolerance: maximum distance between location and coordinates in km + :return: None or lat/lon, name + """ + locations = config_loader(dataset='locations') + distances = sorted([(get_distance(lat, lon, loc_lat, loc_lon), loc) + for loc, (loc_lat, loc_lon) in locations.items()]) + if len(distances) > 0 and distances[0][0] <= tolerance: + return locations[distances[0][1]], distances[0][1] + else: + return None diff --git a/requirements.d/mswms.txt b/requirements.d/mswms.txt new file mode 100644 index 000000000..f2e816bbe --- /dev/null +++ b/requirements.d/mswms.txt @@ -0,0 +1,45 @@ +# This file may be used to create an environment using: +# $ conda create --name --file +# platform: linux-64 +python +future +defusedxml +basemap>=1.3.3 +chameleon +execnet +fastkml>=0.11 +shapely>=2.0.0 +pygeoif<1.0.0 +isodate +lxml +netcdf4 +hdf4 +pillow +requests>=2.31.0 +scipy +skyfield>=1.12 +skyfield-data>=5 +tk +owslib>=0.24 +unicodecsv +fs +cftime>=1.0.1 +matplotlib-base>=3.5.3 +itsdangerous +flask>=2.3.2 +flask-httpauth +werkzeug>=2.2.3,<3.0.0 +passlib +multidict +pint +markdown +xstatic +xstatic-jquery +xstatic-bootstrap +gpxpy>=1.4.2 +metpy +pycountry +libtiff<4.5.0 +flask-wtf +python-slugify +flask-login \ No newline at end of file diff --git a/tests/_test_utils/test_coordinate.py b/tests/_test_utils/test_coordinate.py index ba5b50456..22243fab3 100644 --- a/tests/_test_utils/test_coordinate.py +++ b/tests/_test_utils/test_coordinate.py @@ -31,6 +31,7 @@ import pytest import mslib.utils.coordinate as coordinate +import mslib.utils.locations LOGGER = logging.getLogger(__name__) @@ -48,8 +49,8 @@ def test_get_distance(self): assert int(coordinate.get_distance(lat0, lon0, lat1, lon1)) == distance def test_find_location(self): - assert coordinate.find_location(50.92, 6.36) == ([50.92, 6.36], 'Juelich') - assert coordinate.find_location(50.9200002, 6.36) == ([50.92, 6.36], 'Juelich') + assert mslib.utils.locations.find_location(50.92, 6.36) == ([50.92, 6.36], 'Juelich') + assert mslib.utils.locations.find_location(50.9200002, 6.36) == ([50.92, 6.36], 'Juelich') class TestProjections: From dc4ebd7f0acd6b718b263260513cc4aea77ead58 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Fri, 24 May 2024 08:14:24 +0200 Subject: [PATCH 02/11] copyright fixed --- mslib/utils/locations.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mslib/utils/locations.py b/mslib/utils/locations.py index 3f0af9801..cf74450e8 100644 --- a/mslib/utils/locations.py +++ b/mslib/utils/locations.py @@ -8,9 +8,8 @@ This file is part of MSS. - :copyright: Copyright 2008-2014 Deutsches Zentrum fuer Luft- und Raumfahrt e.V. - :copyright: Copyright 2011-2014 Marc Rautenhaus (mr) - :copyright: Copyright 2016-2024 by the MSS team, see AUTHORS. + :copyright: Copyright 2021 May Bär + :copyright: Copyright 2021-2024 by the MSS team, see AUTHORS. :license: APACHE-2.0, see LICENSE for details. Licensed under the Apache License, Version 2.0 (the "License"); From e30e5204aecca1997fdfb8d346de03109d0db3a7 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Fri, 24 May 2024 08:18:09 +0200 Subject: [PATCH 03/11] typo --- mslib/mswms/mswms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mslib/mswms/mswms.py b/mslib/mswms/mswms.py index df71823a3..bfb73c629 100644 --- a/mslib/mswms/mswms.py +++ b/mslib/mswms/mswms.py @@ -32,7 +32,7 @@ from mslib import __version__ from mslib.utils import setup_logging from mslib.mswms.wms import app as application -q + def main(): parser = argparse.ArgumentParser() From 3455fd94133a2f9441c4436c3df7df05e0ba670d Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Fri, 24 May 2024 08:49:37 +0200 Subject: [PATCH 04/11] changes for tests --- conftest.py | 69 +++++++++++++++++++++++++++-------------------- tests/fixtures.py | 36 ++++++++++++++++++++----- tests/utils.py | 5 +++- 3 files changed, 74 insertions(+), 36 deletions(-) diff --git a/conftest.py b/conftest.py index e596983d7..b58622e97 100644 --- a/conftest.py +++ b/conftest.py @@ -36,47 +36,54 @@ import pytest import fs import shutil -import keyring +try: + import keyring +except ModuleNotFoundError: + keyring = None from mslib.mswms.demodata import DataFiles import tests.constants as constants from mslib.utils.loggerdef import configure_mpl_logger matplotlib_logger = configure_mpl_logger() -# This import must come after importing tests.constants due to MSUI_CONFIG_PATH being set there -from mslib.utils.config import read_config_file +try: + # This import must come after importing tests.constants due to MSUI_CONFIG_PATH being set there + from mslib.utils.config import read_config_file +except ModuleNotFoundError: + read_config_file = None -class TestKeyring(keyring.backend.KeyringBackend): - """A test keyring which always outputs the same password - from Runtime Configuration - https://pypi.org/project/keyring/#third-party-backends - """ - priority = 1 +if keyring is not None: + class TestKeyring(keyring.backend.KeyringBackend): + """A test keyring which always outputs the same password + from Runtime Configuration + https://pypi.org/project/keyring/#third-party-backends + """ + priority = 1 - passwords = {} + passwords = {} - def reset(self): - self.passwords = {} + def reset(self): + self.passwords = {} - def set_password(self, servicename, username, password): - self.passwords[servicename + username] = password + def set_password(self, servicename, username, password): + self.passwords[servicename + username] = password - def get_password(self, servicename, username): - return self.passwords.get(servicename + username, "password from TestKeyring") + def get_password(self, servicename, username): + return self.passwords.get(servicename + username, "password from TestKeyring") - def delete_password(self, servicename, username): - if servicename + username in self.passwords: - del self.passwords[servicename + username] + def delete_password(self, servicename, username): + if servicename + username in self.passwords: + del self.passwords[servicename + username] -# set the keyring for keyring lib -keyring.set_keyring(TestKeyring()) + # set the keyring for keyring lib + keyring.set_keyring(TestKeyring()) -@pytest.fixture(autouse=True) -def keyring_reset(): - keyring.get_keyring().reset() + @pytest.fixture(autouse=True) + def keyring_reset(): + keyring.get_keyring().reset() def generate_initial_config(): @@ -218,9 +225,11 @@ def _load_module(module_name, path): generate_initial_config() - -# This import must come after the call to generate_initial_config, otherwise SQLAlchemy will have a wrong database path -from tests.utils import create_msui_settings_file +try: + # This import must come after the call to generate_initial_config, otherwise SQLAlchemy will have a wrong database path + from tests.utils import create_msui_settings_file +except ModuleNotFoundError: + create_msui_settings_file = None @pytest.fixture(autouse=True) @@ -234,8 +243,10 @@ def reset_config(): constants.ROOT_FS.removedir(e) generate_initial_config() - create_msui_settings_file("{}") - read_config_file() + if create_msui_settings_file is not None: + create_msui_settings_file("{}") + if read_config_file is not None: + read_config_file() # Make fixtures available everywhere diff --git a/tests/fixtures.py b/tests/fixtures.py index 4005225ec..d3df57b75 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -32,13 +32,37 @@ import eventlet import eventlet.wsgi -from PyQt5 import QtWidgets +try: + from PyQt5 import QtWidgets +except ModuleNotFoundError: + QtWidgets = None from contextlib import contextmanager -from mslib.mscolab.conf import mscolab_settings -from mslib.mscolab.server import APP, initialize_managers -from mslib.mscolab.mscolab import handle_db_init, handle_db_reset -from mslib.utils.config import modify_config_file -from tests.utils import is_url_response_ok +try: + from mslib.mscolab.conf import mscolab_settings +except ModuleNotFoundError: + mscolab_settings = None + +try: + from mslib.mscolab.server import APP, initialize_managers +except ModuleNotFoundError: + APP = None + initialize_managers = None + +try: + from mslib.mscolab.mscolab import handle_db_init, handle_db_reset +except ModuleNotFoundError: + handle_db_init = None + handle_db_reset = None + +try: + from mslib.utils.config import modify_config_file +except ModuleNotFoundError: + modify_config_file = None + +try: + from tests.utils import is_url_response_ok +except ModuleNotFoundError: + is_url_response_ok = None @pytest.fixture diff --git a/tests/utils.py b/tests/utils.py index 7e0083f5d..c4405d7cb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -29,7 +29,10 @@ import fs from urllib.parse import urljoin -from mslib.mscolab.server import register_user +try: + from mslib.mscolab.server import register_user +except ModuleNotFoundError: + register_user = None from flask import json from tests.constants import MSUI_CONFIG_PATH From c947cf636bb64665532c4cd0b60618dc8a96c0af Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sat, 25 May 2024 13:31:55 +0200 Subject: [PATCH 05/11] removing entry points for a seperate mswms build --- localbuild/build_mswms_setuppy.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 localbuild/build_mswms_setuppy.patch diff --git a/localbuild/build_mswms_setuppy.patch b/localbuild/build_mswms_setuppy.patch new file mode 100644 index 000000000..671f91871 --- /dev/null +++ b/localbuild/build_mswms_setuppy.patch @@ -0,0 +1,19 @@ +diff --git a/setup.py b/setup.py +index c0f80484..31408355 100644 +--- a/setup.py ++++ b/setup.py +@@ -34,14 +34,8 @@ long_description = open('README.md').read() + execfile('mslib/version.py') + + console_scripts = [ +- "mscolab = mslib.mscolab.mscolab:main", +- "mss = mslib.msui.mss:main", +- "mssautoplot = mslib.utils.mssautoplot:main", +- "msui = mslib.msui.msui:main", + "mswms = mslib.mswms.mswms:main", + "mswms_demodata = mslib.mswms.demodata:main"] +-if os.name != 'nt': +- console_scripts.append('msidp = mslib.msidp.idp:main') + + setup( + name="mss", From 930f9c59fc4cf42ae4785576ad6146814b020c88 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sun, 26 May 2024 13:44:59 +0200 Subject: [PATCH 06/11] conda recipe based on toml attributes --- conda_recipe/README.rst | 5 + conda_recipe/bld.bat | 7 ++ conda_recipe/build.sh | 7 ++ .../build_mswms_setuppy.patch | 0 conda_recipe/menu.json | 54 ++++++++++ conda_recipe/meta.yaml | 84 ++++++++++++++++ conda_recipe/msui.ico | Bin 0 -> 2462 bytes conda_recipe/msui.png | Bin 0 -> 1911 bytes requirements.d/mswms.toml | 92 ++++++++++++++++++ requirements.d/mswms.txt | 45 --------- 10 files changed, 249 insertions(+), 45 deletions(-) create mode 100644 conda_recipe/README.rst create mode 100644 conda_recipe/bld.bat create mode 100644 conda_recipe/build.sh rename {localbuild => conda_recipe}/build_mswms_setuppy.patch (100%) create mode 100644 conda_recipe/menu.json create mode 100644 conda_recipe/meta.yaml create mode 100644 conda_recipe/msui.ico create mode 100644 conda_recipe/msui.png create mode 100644 requirements.d/mswms.toml delete mode 100644 requirements.d/mswms.txt diff --git a/conda_recipe/README.rst b/conda_recipe/README.rst new file mode 100644 index 000000000..099aa54ff --- /dev/null +++ b/conda_recipe/README.rst @@ -0,0 +1,5 @@ +localbuild is mainly a copy of the build instructions from +https://github.com/conda-forge/mss-feedstock/tree/master/recipe + +You may want to copy this directory to a different directory on your system +and alter it for your needs. diff --git a/conda_recipe/bld.bat b/conda_recipe/bld.bat new file mode 100644 index 000000000..3dec9e8b9 --- /dev/null +++ b/conda_recipe/bld.bat @@ -0,0 +1,7 @@ +mkdir "%PREFIX%\Menu" +copy /Y "%RECIPE_DIR%\menu.json" "%PREFIX%\Menu\%PKG_NAME%_menu.json" +copy /Y "%RECIPE_DIR%\msui.ico" "%PREFIX%\Menu\msui.ico" + +; conda-build issue 5311, currently we can't build for windows with pip install +%PYTHON% setup.py install --single-version-externally-managed --record record.txt +if errorlevel 1 exit 1 diff --git a/conda_recipe/build.sh b/conda_recipe/build.sh new file mode 100644 index 000000000..ab507fa63 --- /dev/null +++ b/conda_recipe/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +mkdir -p "${PREFIX}/Menu" +cp "${RECIPE_DIR}/menu.json" "${PREFIX}/Menu/${PKG_NAME}_menu.json" +cp "${RECIPE_DIR}/msui.png" "${PREFIX}/Menu/msui.png" + +"${PYTHON}" -m pip install . --no-deps -vv diff --git a/localbuild/build_mswms_setuppy.patch b/conda_recipe/build_mswms_setuppy.patch similarity index 100% rename from localbuild/build_mswms_setuppy.patch rename to conda_recipe/build_mswms_setuppy.patch diff --git a/conda_recipe/menu.json b/conda_recipe/menu.json new file mode 100644 index 000000000..a39a7cdf6 --- /dev/null +++ b/conda_recipe/menu.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema", + "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "menu_name": "Mission Support System", + "menu_items": [ + { + "name": "MSUI ({{ ENV_NAME }})", + "description": "Mission Support System MSUI", + "activate": true, + "icon": "{{ MENU_DIR }}/msui.{{ ICON_EXT }}", + "command": [ + "{{ PYTHON }}", + "{{ PREFIX }}/bin/msui" + ], + "platforms": { + "win": { + "command": [ + "{{ PYTHON }}", + "{{ SCRIPTS_DIR }}/msui-script.py" + ], + "file_extensions": [".menuinst"] + }, + "linux": { + "Categories": ["Internet", "Science"], + "Keywords": ["documentation", "information"], + "StartupNotify": true, + "MimeType": ["application/x-menuinst"], + "glob_patterns": { + "application/x-menuinst": "*.menuinst" + } + }, + "osx": { + "CFBundleDocumentTypes": [ + { + "CFBundleTypeName": "org.conda.menuinst.msui", + "CFBundleTypeRole": "Viewer", + "LSItemContentTypes": ["org.conda.menuinst.main-file-uti"], + "LSHandlerRank": "Default" + } + ], + "UTExportedTypeDeclarations": [ + { + "UTTypeConformsTo": ["public.data", "public.content"], + "UTTypeIdentifier": "org.conda.menuinst.main-file-uti", + "UTTypeTagSpecification": { + "public.filename-extension": ["menuinst"] + } + } + ] + } + } + } + ] +} diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml new file mode 100644 index 000000000..8af2a3a4c --- /dev/null +++ b/conda_recipe/meta.yaml @@ -0,0 +1,84 @@ + +{% set module = environ.get('MODULE', 'mss') %} +{% set project = load_file_data('requirements.d/mswms.toml', from_recipe_dir=False).get('project') %} +{% set name = project.get('name') %} +{% set summary = project.get('description') %} + +{% set version = project.get('version') %} +{% set maintainers = project.get('maintainers') %} + +{% set source_patches = project.get('source_patches') %} + +{% set build_deps = project.get('build_dependencies') %} +{% set host_deps = project.get('host_dependencies') %} +{% set run_deps = project.get('dependencies') %} + +{% set test_imports = project.get('test_imports') %} +{% set test_commands = project.get('test_commands') %} + +package: + name: {{ name }} + version: {{ version }} + +source: + path: ../ + patches: + {% for patch in source_patches %} + - {{ patch }} + {% endfor %} + +build: + number: 0 + +requirements: + build: + {% for dep in build_deps %} + - {{ dep }} + {% endfor %} + host: + {% for dep in host_deps %} + - {{ dep }} + {% endfor %} + run: + {% for dep in run_deps %} + - {{ dep }} + {% endfor %} +test: + imports: + {% for imp in test_imports %} + - {{ imp }} + {% endfor %} + commands: + {% for cmd in test_commands %} + - {{ cmd }} + {% endfor %} +about: + summary: {{ summary }} + home: https://github.com/open-mss/MSS + license: Apache-2.0 + license_family: APACHE + license_file: LICENSE + description: | + MSS - Mission Support System + + Documentation: + * https://mss.rtfd.io + * https://gmd.copernicus.org/articles/15/8983/2022/gmd-15-8983-2022.pdf + * http://www.geosci-model-dev.net/5/55/2012/gmd-5-55-2012.pdf + + Software for planning research Aircraft Missions. + For discussion of the possibilites of the research flights, + the Mission Support System (MSS) was developed. + This software helps to review a big amount of metereological and + model project by viewing the forecasted parameters of interest along possible regions + of a proposed flight path. Data and possible flight paths can + be displayed on a hoizontal view (map projection) or on a vertical + view (along the proposed flight path). Flight paths can be constructed + and modified on these views. Exchange through a waypoint table is also possible. + +extra: + recipe-maintainers: + {% for maintainer in maintainers %} + - {{ maintainer.get('name') }} + {% endfor %} + diff --git a/conda_recipe/msui.ico b/conda_recipe/msui.ico new file mode 100644 index 0000000000000000000000000000000000000000..5479fdbb98d212a2c7a7732382d7632d9a5a08ca GIT binary patch literal 2462 zcmb7GX;4#F6n?ao-K8^~YE`x%L8My3CYz#=1O!qIAWBFCL&6eXmPaCnCG3^}A_$Cj zQN*Q-ZD*X;`lD{+($*2Do$2Ou2W`h~#uzUNqP8107h$^kVQym3mgEXm%f z*6f(HHtwb822j&k3;mE1+Jn*1j7m^^I7}2a*B*$bJq1j=Y^bT<4WmJTI;ZIOknk)g zfzRQlV-gmY$_0g_%#W6?*|TwDIbjdL($WKCe*sEHB2j!KgfK&Ausu51+SVh%(Ctk^ zrA0uEItONZC)6c%lgtMINKFto|Jh{D&p$RcbA#cgL1#eCmO>a>tI32L$E1=mSz|_8<;xqvA?}U$UOf18u;mzX1d{|xAi^_5yR#g-#D;J_QQmV9 zLepLl<{clOm{gX-lxGyrK@@dfhTMG%n_OpLs_TKUIS-Ai17Xh!gnq|T6c0zDw4(@o z!)};`RyfxNpirNA+PH@DBQOp@A?&m zjUNyW<-Oj3hSY^kNbh@XDyBE?}J)kh!1 zy38`(w>Ax+qU9*E+&2jSmZ(FqYaCk}j>AIlYB4)er&xie1b^_=wGg(b&?4iotz3nK zv!9XeV>6O;_KN5u8^t-DuobGBhb-62TaQEO{%sn6N{6!Z2WaaLQ_O~7u5-hzR>GLC zhMAsEZwy$7S#G)}V0DPGqcKHg_WrV|Qa)2it zsyE(40@>`b|8f63DZW!NxCMFl9ccA!aK(GWM)vc>8x8sCXis0!B#kejE*Gs~2 za#Ij`*Dip4Lp%(QHe?+;34QN~r@rp8`g)WfSZx<~oF%{9#mhTChLE`u=4t`MmI{2W zi^4cz|Dp{OWt{HgItjkiNbqjnVzg!vr&RF7rF&-a1LGiH;v&ZRjGK7Zer)cz1pO90 zY&s2I=eOayPC5(Qql4W=ouucjawRO9B2<=EK%P@^)7M`XyFlc(AdYb+lGNCTEj*FO_3NoTm?@bU_w`+RR{SXzTzS$f+jbi>*_1UvP>w)z$fIm|dH=tW`k zc4xD=$IdWrC;#4LeTDT{j$^%c_K-@~ajRaEbCQtMxdDL*abka`-pzWriF&!YX$ThA zuqbTK)*kKe{sA%>A$oD#yxG7{{O9>Tk%|0GH8|$sD#j;l&eo>CPbdfH{^R$_LoS_r f!1-_!B(2=j(?Vwa&(TVzUziq#^?;ktG3-A9+;%$| literal 0 HcmV?d00001 diff --git a/conda_recipe/msui.png b/conda_recipe/msui.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6f25cda82fc4826a0d0e62d98a616f93508e42 GIT binary patch literal 1911 zcmV--2Z;EIP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Rj0~H1dG7CI-NdN!_dr3q=R7l5tmP>FOSrvxA z+uiDx)UssDwk-KA+i{%4c{q~^lSx8`O%@OysoAk$!Mrg*|9{T?&qMGMO9OQ< z_C+HndU|`lo$T&>!;Hs9bzM&YxUO5ZYW1aZp){S}%wJ!$8@Ehwaxd{EK0mxMK8_X% z)2P(j+){pgU~KpYgJZ+r=t`%$%veNdnu-v6*QJzro{v>;$YO50xVpIf*C&sj{A|{; zKaGQ|y$oPT2r5$QhqL298r?Ve*1<#BbhIssCp9WwoN_CPD% zsRE#ifUw%2H@wAUY@VUWDnk0KKVGxuKAySqc&+gBzU+__cr8yI09K^r{a^j!`^V3m z{7H7-km-8xU>j^L%iZ0hI6>qY8v#fJZlF_gI(gCEd8YsJSoNj*)UD(Ly*?bBnQAB_f=*(7+^N-vS zK6orq;wkgMSn9jhPI=s~*HG7+j{f@O{&yx%96hHSAtv-92lWzNMvLDrB$-U+=recO zZ1&Q^cmYNrgg^u}n$%kqVdDa?&_5iV&d42Ce!6)%?F0(iV7gvcTD|tP=PUf}jl< z_l!l+WHIb_>BE>1KUOiD6CYxE8lpBA7%Hyn(xgX^?m z#$#ieuImYeAS8U$FSy?eLscYiPSm(vg!NL3OvvWsSd>gc(A~R1|41I8Jb$7n0b0mI z2!XEa3FWyazT880J;5!zn|OPiR|f*nbm9?}8w(+>ekO4ADtaj3|C!>tZWSqUrHcO) zMgUD8X6+;uHOWRr^6qSeo9hX(Jq80E@Zov~fB2{$$NeI;AW-mH8d6GJ*R3j6t-k1c zKDG?ekRb%%Ny!~M!6seIZ3=#UJI4K;FkPLyBqEY?S)UUbi|KoPe72ZCRrXRVgv50W zoTh>AdswylqEarD-fz?`92uhEN0CS#*fADbDgOB=#MQeote8XJ*Vc(#*ye6W9h86z z`yJXtl501Iu$#)W6j#e}yp~R*Zc#3jrqwpPVW)a~F0^-dnXXi5wmd$lrn&wg%1m7$ zHdUtmOc`~+#WMt3F`wO5i_t)*-}ISYj5F9>Wu(`}adcJ}hjE=So6D>D`G4PeN6mSD zzE{^L(*5aUR-o~5-sI04VRHR8iL+%wBTb|ZNU_IKfkG^xBwY>)m1v-FYc!E39DO@=I;`9y<_s7pf)km9LYq#)`k^fq)3)x-3e0yuV6mgMO+n{k;QIlb46bM+T#26c4CqJ|*3wq3lhCh%ZRCG}=8C4X`bnCksm} z4_C^6sZ^>zRR~sYtuOCQzs~`xKotCkyY*RbV{6*3)s4Up`a+r(jVmFM@%W=1.3.3', + 'chameleon', + 'execnet', + 'fastkml >=0.11', + 'shapely >=2.0.0', + 'pygeoif <1.0.0', + 'isodate', + 'lxml', + 'netcdf4', + 'hdf4', + 'pillow', + 'requests >=2.31.0', + 'scipy', + 'owslib >=0.24', + 'unicodecsv', + 'fs', + 'cftime >=1.0.1', + 'matplotlib-base >=3.5.3', + 'flask >=2.3.2', + 'flask-httpauth', + 'werkzeug >=2.2.3, <3.0.0', + 'multidict', + 'pint', + 'markdown', + 'xstatic', + 'xstatic-jquery', + 'xstatic-bootstrap', + 'metpy', + 'pycountry', + 'libtiff <4.5.0', + 'python-slugify', +] + +run_constrained = [ + 'menuinst >=2.0.2' +] +build_dependencies = [ + 'python', + 'pip', + 'setuptools', + 'future', +] + +host_dependencies = [ + 'python', + 'setuptools', + 'pip', + 'future' +] + +authors = ["see AUTHORS"] + +maintainers = [ + {name = "ReimarBauer", email = "rb.proj@gmail.com"} +] + +test_imports = [ + 'mslib' +] +test_commands = [ + 'mswms -h', + 'mswms_demodata -h' +] + + +[project.urls] +Homepage = "https://open-mss.github.io/" +Documentation = "https://mss.rtfd.io" +Repository = "https://github.com/open-mss/MSS" +Issues = "https://github.com/Open-MSS/MSS/issues" +Changelog = "https://github.com/Open-MSS/MSS/blob/stable/CHANGES.rst" diff --git a/requirements.d/mswms.txt b/requirements.d/mswms.txt deleted file mode 100644 index f2e816bbe..000000000 --- a/requirements.d/mswms.txt +++ /dev/null @@ -1,45 +0,0 @@ -# This file may be used to create an environment using: -# $ conda create --name --file -# platform: linux-64 -python -future -defusedxml -basemap>=1.3.3 -chameleon -execnet -fastkml>=0.11 -shapely>=2.0.0 -pygeoif<1.0.0 -isodate -lxml -netcdf4 -hdf4 -pillow -requests>=2.31.0 -scipy -skyfield>=1.12 -skyfield-data>=5 -tk -owslib>=0.24 -unicodecsv -fs -cftime>=1.0.1 -matplotlib-base>=3.5.3 -itsdangerous -flask>=2.3.2 -flask-httpauth -werkzeug>=2.2.3,<3.0.0 -passlib -multidict -pint -markdown -xstatic -xstatic-jquery -xstatic-bootstrap -gpxpy>=1.4.2 -metpy -pycountry -libtiff<4.5.0 -flask-wtf -python-slugify -flask-login \ No newline at end of file From 520f9f8e9af73d5dd4d36afedec44f2dbe972ac9 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sun, 26 May 2024 14:06:25 +0200 Subject: [PATCH 07/11] whitespace --- requirements.d/mswms.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.d/mswms.toml b/requirements.d/mswms.toml index c8d9721dd..cd2b597b8 100644 --- a/requirements.d/mswms.toml +++ b/requirements.d/mswms.toml @@ -3,7 +3,7 @@ name = "mswms" description = 'The WMS server of the Mission Support System (MSS) - developed in the community to collaboratively create flight plans based on model data.' readme = "README.md" -keywords = ["MSS", "WNS", "science", "flight planning"] +keywords = ["MSS", "WNS", "science", "flight planning"] classifiers = [ "Development Status :: 5 - Production/Stable", "Programming Language :: Python", From 0d5a8f26a3a496d4e3dcea86d752c9bfac7f4926 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sun, 26 May 2024 16:11:04 +0200 Subject: [PATCH 08/11] removed menuinst --- requirements.d/mswms.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.d/mswms.toml b/requirements.d/mswms.toml index cd2b597b8..08aff8def 100644 --- a/requirements.d/mswms.toml +++ b/requirements.d/mswms.toml @@ -53,7 +53,6 @@ dependencies = [ ] run_constrained = [ - 'menuinst >=2.0.2' ] build_dependencies = [ 'python', From db51269590cb582f743981c5df37f8ecbe33e050 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Sun, 26 May 2024 16:24:10 +0200 Subject: [PATCH 09/11] meta.yaml --- conda_recipe/meta.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index 8af2a3a4c..837c2816e 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -12,6 +12,8 @@ {% set build_deps = project.get('build_dependencies') %} {% set host_deps = project.get('host_dependencies') %} {% set run_deps = project.get('dependencies') %} +{% set run_constrained = project.get('run_constrained') %} + {% set test_imports = project.get('test_imports') %} {% set test_commands = project.get('test_commands') %} @@ -43,6 +45,11 @@ requirements: {% for dep in run_deps %} - {{ dep }} {% endfor %} + run_constrained: + {% for dep in run_constrained %} + - {{ dep }} + {% endfor %} + test: imports: {% for imp in test_imports %} From 225815a74f44bc81e3c6b928c0a253388e326130 Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Tue, 28 May 2024 16:56:32 +0200 Subject: [PATCH 10/11] mscolab server case --- conda_recipe/meta.yaml | 2 +- conftest.py | 17 +++--- mslib/mscolab/mscolab.py | 12 ----- requirements.d/mscolab.toml | 102 ++++++++++++++++++++++++++++++++++++ tests/fixtures.py | 11 +++- 5 files changed, 123 insertions(+), 21 deletions(-) create mode 100644 requirements.d/mscolab.toml diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index 837c2816e..a902d1d58 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -1,6 +1,6 @@ {% set module = environ.get('MODULE', 'mss') %} -{% set project = load_file_data('requirements.d/mswms.toml', from_recipe_dir=False).get('project') %} +{% set project = load_file_data('requirements.d/mscolab.toml', from_recipe_dir=False).get('project') %} {% set name = project.get('name') %} {% set summary = project.get('description') %} diff --git a/conftest.py b/conftest.py index b58622e97..d8cb44e40 100644 --- a/conftest.py +++ b/conftest.py @@ -40,7 +40,10 @@ import keyring except ModuleNotFoundError: keyring = None -from mslib.mswms.demodata import DataFiles +try: # mscolab + from mslib.mswms.demodata import DataFiles +except ModuleNotFoundError: + DataFiles = None import tests.constants as constants from mslib.utils.loggerdef import configure_mpl_logger @@ -96,7 +99,7 @@ def generate_initial_config(): sample_path = os.path.join(os.path.dirname(__file__), "tests", "data") shutil.copy(os.path.join(sample_path, "example.ftml"), constants.ROOT_DIR) - if not constants.SERVER_CONFIG_FS.exists(constants.SERVER_CONFIG_FILE): + if DataFiles is not None and not constants.SERVER_CONFIG_FS.exists(constants.SERVER_CONFIG_FILE): print('\n configure testdata') # ToDo check pytest tmpdir_factory examples = DataFiles(data_fs=constants.DATA_FS, @@ -218,12 +221,14 @@ def _load_module(module_name, path): sys.modules[module_name] = module spec.loader.exec_module(module) - - _load_module("mswms_settings", constants.SERVER_CONFIG_FILE_PATH) + if DataFiles is not None: + _load_module("mswms_settings", constants.SERVER_CONFIG_FILE_PATH) _load_module("mscolab_settings", path) - -generate_initial_config() +try: # mscolab + generate_initial_config() +except TypeError: + pass try: # This import must come after the call to generate_initial_config, otherwise SQLAlchemy will have a wrong database path diff --git a/mslib/mscolab/mscolab.py b/mslib/mscolab/mscolab.py index a04afe940..ed2e96aa1 100644 --- a/mslib/mscolab/mscolab.py +++ b/mslib/mscolab/mscolab.py @@ -41,7 +41,6 @@ add_all_users_to_all_operations, delete_user from mslib.mscolab.utils import create_files from mslib.utils import setup_logging -from mslib.utils.qt import Worker, Updater def handle_start(args): @@ -355,7 +354,6 @@ def handle_sso_metadata_init(repo_exists): def main(): parser = argparse.ArgumentParser() parser.add_argument("-v", "--version", help="show version", action="store_true", default=False) - parser.add_argument("--update", help="Updates MSS to the newest version", action="store_true", default=False) subparsers = parser.add_subparsers(help='Available actions', dest='action') @@ -405,16 +403,6 @@ def main(): except git.exc.InvalidGitRepositoryError: repo_exists = False - updater = Updater() - if args.update: - updater.on_update_available.connect(lambda old, new: updater.update_mss()) - updater.on_log_update.connect(lambda s: print(s.replace("\n", ""))) - updater.on_status_update.connect(lambda s: print(s.replace("\n", ""))) - updater.run() - while Worker.workers: - list(Worker.workers)[0].wait() - sys.exit() - if args.action == "start": handle_start(args) diff --git a/requirements.d/mscolab.toml b/requirements.d/mscolab.toml new file mode 100644 index 000000000..ac92a581d --- /dev/null +++ b/requirements.d/mscolab.toml @@ -0,0 +1,102 @@ +[project] +name = "mscolab" + +description = 'The MSColab server of the Mission Support System (MSS) - developed in the community to collaboratively exchange flight plans based on model data.' +readme = "README.md" +keywords = ["MSS", "collaboratively", "science", "flight planning"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python", + "License :: OSI Approved :: Apache-2.0" +] +version = "9.0.0" + +source_patches = [ + 'build_mswms_setuppy.patch' +] + +dependencies = [ + 'python', + 'pyyaml', + 'future', + 'defusedxml', + 'chameleon', + 'execnet', + 'isodate', + 'lxml', + 'pillow', + 'requests >=2.31.0', + 'fs', + 'cftime >=1.0.1', + 'pyjwt', + 'flask >=2.3.2', + 'flask-httpauth', + 'flask-mail', + 'flask-migrate', + 'werkzeug >=2.2.3, <3.0.0', + 'flask-socketio >=5.1.0', + 'flask-sqlalchemy >=3.0.0', + 'flask-cors', + 'flask-wtf', + 'flask-login', + 'pysaml2', + 'libxmlsec1 # [not win]', + 'email_validator', + 'python-socketio >=5', + 'python-engineio >=4', + 'websocket-client', + 'passlib', + 'keyring', + 'dbus-python # [not win]', + 'gitpython', + 'git', + 'psycopg2', + 'PyMySQL >=0.9.3', + 'validate_email', + 'multidict', + 'markdown', + 'xstatic', + 'xstatic-jquery', + 'xstatic-bootstrap', + 'metpy', + 'libtiff <4.5.0', + 'python-slugify', +] + +run_constrained = [ +] +build_dependencies = [ + 'python', + 'pip', + 'setuptools', + 'future', +] + +host_dependencies = [ + 'python', + 'setuptools', + 'pip', + 'future' +] + +authors = ["see AUTHORS"] + +maintainers = [ + {name = "ReimarBauer", email = "rb.proj@gmail.com"} +] + +test_imports = [ + 'mslib' +] +test_commands = [ + 'mscolab -h', + 'msidp -h # [not win]' +] + + +[project.urls] +Homepage = "https://open-mss.github.io/" +Documentation = "https://mss.rtfd.io" +Repository = "https://github.com/open-mss/MSS" +Issues = "https://github.com/Open-MSS/MSS/issues" +Changelog = "https://github.com/Open-MSS/MSS/blob/stable/CHANGES.rst" diff --git a/tests/fixtures.py b/tests/fixtures.py index d3df57b75..00ad054c6 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -28,7 +28,11 @@ import multiprocessing import time import urllib -import mslib.mswms.mswms +try: # mscolab + import mslib.mswms.mswms +except ModuleNotFoundError: + pass + import eventlet import eventlet.wsgi @@ -178,7 +182,10 @@ def mscolab_server(mscolab_session_server, reset_mscolab): :returns: The URL where the server is running. """ # Update mscolab URL to avoid "Update Server List" message boxes - modify_config_file({"default_MSCOLAB": [mscolab_session_server]}) + try: # mscolab server tests should not access clients config + modify_config_file({"default_MSCOLAB": [mscolab_session_server]}) + except TypeError: + pass return mscolab_session_server From 6471c799c1c95f776ebdb0dbe9b706306f13ffbe Mon Sep 17 00:00:00 2001 From: ReimarBauer Date: Tue, 28 May 2024 17:06:11 +0200 Subject: [PATCH 11/11] flake8 --- tests/fixtures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index 00ad054c6..f17535b27 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -28,7 +28,7 @@ import multiprocessing import time import urllib -try: # mscolab +try: # mscolab import mslib.mswms.mswms except ModuleNotFoundError: pass @@ -182,7 +182,7 @@ def mscolab_server(mscolab_session_server, reset_mscolab): :returns: The URL where the server is running. """ # Update mscolab URL to avoid "Update Server List" message boxes - try: # mscolab server tests should not access clients config + try: # mscolab server tests should not access clients config modify_config_file({"default_MSCOLAB": [mscolab_session_server]}) except TypeError: pass