Commit 598b1f3a authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

renamed folder make to scripts

revisited and renamed scripts
updated bitbucket-pipelines.yml
refactored unit-tests
added .coveragec
renamed CHANGELOG to CHANGELOG.rst
parent eeb4a86c
[run]
include =
*/eotimeseriesviewer/*
omit =
*eotimeseriesviewer/externals/*
......@@ -7,7 +7,7 @@ deploy/*
temp/
doc/build/
doc/build/*
eotimeseriesviewer/ui/resources.py
eotimeseriesviewer/ui/eotv_resources.py
eotimeseriesviewer/externals/qps/qpsresources.py
tests/outputs
tests/outputs/*
......
==============
Changelog
==============
2020-01-23 (version 1.11):
* revised unit tests for CI pipelines
* fixed smaller issues in SensorModel
......
......@@ -13,32 +13,40 @@ pipelines:
caches:
- docker
- pip
- qgisresourcecache
script: # Modify the commands below to build your repository.
- python3 -m pip install -r requirements.txt
- python3 -m pip install nose2
- apt-get update
- apt-get -y install xvfb
- apt-get -y install git-lfs
- apt-get -y install xvfb
- Xvfb :1 -screen 0 1024x768x16 &> xvfb.log &
- ps aux | grep X
- DISPLAY=:1.0
- export DISPLAY
- mkdir test-reports
- git lfs install
- git lfs fetch
- git lfs pull
- git lfs checkout
#- python3 make/setuprepository.py
#- python3 -m nose2 discover tests "test_*.py" > test-reports/test-report.txt
#- QT_QPA_PLATFORM=offscreen
#- export QT_QPA_PLATFORM
- QT_QPA_PLATFORM=offscreen
- CI=True
- export QT_QPA_PLATFORM
- export CI
- chmod +x runtests.sh
- ./runtests.sh
#- python3 tests/test_init.py
#- CI=True
#- export CI
#- python3 -m nose2 discover tests "test_*.py" > test-reports/test-report.txt
- export PYTHONPATH="${PYTHONPATH}:$(pwd)"
- python3 -m pip install -r requirements_dev.txt
- python3 scripts/setup_repository.py
- python3 -m coverage run --rcfile=.coveragec tests/test_fileFormatLoading.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_inmemorydata.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_labeling.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_layerproperties.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_main.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_mapcanvas.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_maptools.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_mapvisualization.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_qgis_environment.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_qgis_interaction.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_resources.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_settings.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_stackedbandinput.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_temporalprofiles.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_timeseries.py
- python3 -m coverage run --rcfile=.coveragec --append tests/test_utils.py
- python3 -m coverage report
definitions:
caches:
qgisresourcecache: /opt/atlassian/pipelines/agent/build/qgisresources
......@@ -6,8 +6,8 @@ from qgis.gui import *
from qgis.PyQt.QtWidgets import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from eotimeseriesviewer.tests import initQgisApplication
app = initQgisApplication()
from eotimeseriesviewer.tests import start_app
app = start_app()
from eotimeseriesviewer.utils import *
from eotimeseriesviewer.main import TimeSeriesViewer
from eotimeseriesviewer.mapvisualization import *
......
......@@ -3,9 +3,9 @@ from qgis.gui import *
from qgis.PyQt.QtWidgets import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from eotimeseriesviewer.tests import initQgisApplication
from eotimeseriesviewer.tests import start_app
app = initQgisApplication()
app = start_app()
from eotimeseriesviewer.utils import *
from eotimeseriesviewer.main import TimeSeriesViewer
......
......@@ -21,7 +21,7 @@
# noinspection PyPep8Naming
__version__ = '1.11' # sub-subversion number is added automatically
__version__ = '1.12' # sub-subversion number is added automatically
LICENSE = 'GNU GPL-3'
TITLE = 'EO Time Series Viewer'
LOG_MESSAGE_TAG = TITLE
......@@ -38,36 +38,26 @@ DEPENDENCIES = ['numpy', 'gdal']
URL_TESTDATA = r''
import os, sys, fnmatch, site, re, site
jp = os.path.join
dn = os.path.dirname
import os
import sys
import fnmatch
import site
import re
import pathlib
from qgis.core import QgsApplication, Qgis
from qgis.PyQt.QtGui import QIcon
mkdir = lambda p: os.makedirs(p, exist_ok=True)
DIR = os.path.dirname(__file__)
DIR_REPO = os.path.dirname(DIR)
DIR_UI = jp(DIR, *['ui'])
DIR_DOCS = jp(DIR, 'docs')
DIR_EXAMPLES = jp(DIR_REPO, 'example')
PATH_EXAMPLE_TIMESERIES = jp(DIR_EXAMPLES,'ExampleTimeSeries.csv')
PATH_LICENSE = jp(DIR_REPO, 'LICENSE.md')
PATH_CHANGELOG = jp(DIR_REPO, 'CHANGELOG')
PATH_ABOUT = jp(DIR_REPO, 'ABOUT.html')
DIR_QGIS_RESOURCES = jp(DIR_REPO, 'qgisresources')
DIR_SITE_PACKAGES = jp(DIR_REPO, 'site-packages')
OPENGL_AVAILABLE = False
try:
import OpenGL
OPENGL_AVAILABLE = True
except:
pass
DIR = pathlib.Path(__file__).parent
DIR_REPO = DIR.parent
DIR_UI = DIR / 'ui'
DIR_DOCS = DIR / 'docs'
DIR_EXAMPLES = DIR_REPO / 'example'
PATH_EXAMPLE_TIMESERIES = DIR_EXAMPLES / 'ExampleTimeSeries.csv'
PATH_LICENSE = DIR_REPO / 'LICENSE.md'
PATH_CHANGELOG = DIR_REPO / 'CHANGELOG'
PATH_ABOUT = DIR_REPO / 'ABOUT.html'
DIR_QGIS_RESOURCES = DIR_REPO / 'qgisresources'
URL_QGIS_RESOURCES = r'https://bitbucket.org/jakimowb/qgispluginsupport/downloads/qgisresources.zip'
# import QPS modules
# skip imports when on RTD, as we can not install the full QGIS environment as required
......@@ -78,12 +68,12 @@ if not os.environ.get('READTHEDOCS') in ['True', 'TRUE', True]:
from .externals.qps.plotstyling.plotstyling import PlotStyle, PlotStyleDialog, PlotStyleButton, PlotStyleWidget
from .externals.qps.classification.classificationscheme import ClassificationScheme, ClassInfo, ClassificationSchemeComboBox, ClassificationSchemeWidget, ClassificationSchemeDialog, hasClassification
from .externals.qps.models import Option, OptionListModel, TreeNode, TreeModel, TreeView
from .externals.qps.speclib.spectrallibraries import SpectralLibrary, SpectralProfile, SpectralLibraryPanel, SpectralLibraryWidget
from .externals.qps.layerproperties import LayerFieldConfigEditorWidget
from .externals.qps.speclib.core import SpectralLibrary, SpectralProfile
from .externals.qps.speclib.gui import SpectralLibraryPanel, SpectralLibraryWidget
from .externals.qps.layerconfigwidgets.vectorlayerfields import LayerFieldsConfigWidget
from .externals.qps.maptools import *
from .externals.qps.utils import *
UI_DIRECTORIES.append(DIR_UI)
def messageLog(msg, level=Qgis.Info):
"""
......@@ -98,17 +88,8 @@ def initResources():
Loads (or reloads) required Qt resources
:return:
"""
try:
import eotimeseriesviewer.ui.resources
eotimeseriesviewer.ui.resources.qInitResources()
except:
print('Unable to initialize EO Time Series Viewer resources', file=sys.stderr)
try:
import eotimeseriesviewer.externals.qps.qpsresources
eotimeseriesviewer.externals.qps.qpsresources.qInitResources()
except Exception as ex:
print('Unable to import qps resources', file=sys.stderr)
from eotimeseriesviewer.externals.qps.resources import initQtResources
initQtResources(pathlib.Path(__file__).parent)
def initEditorWidgets():
"""
......
......@@ -26,14 +26,14 @@ def run():
pluginDir = pathlib.Path(__file__).parents[1]
sys.path.append(pluginDir.as_posix())
print(pluginDir)
from eotimeseriesviewer.tests import initQgisApplication
from eotimeseriesviewer.tests import start_app
import qgis.utils
from qgis.gui import QgisInterface
qgisIface = isinstance(qgis.utils.iface, QgisInterface)
if not qgisIface:
qgsApp = initQgisApplication()
qgsApp = start_app()
from eotimeseriesviewer import initAll
initAll()
......
......@@ -7,8 +7,9 @@ from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from osgeo import gdal
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.externals.qps.layerproperties import *
from eotimeseriesviewer.utils import loadUI, qgisInstance
from eotimeseriesviewer.utils import loadUi
from eotimeseriesviewer.externals.qps.classification.classificationscheme \
import ClassificationSchemeWidget, ClassificationScheme, ClassInfo, ClassificationSchemeComboBox
......@@ -512,11 +513,7 @@ class LabelAttributeTypeWidgetDelegate(QStyledItemDelegate):
if cname == model.cnLabel and isinstance(w, QComboBox):
model.setData(index, w.currentData(Qt.UserRole), Qt.EditRole)
class LabelingWidget(QMainWindow, loadUI('labelingdock.ui')):
class LabelingWidget(QMainWindow):
sigVectorLayerChanged = pyqtSignal()
sigMapExtentRequested = pyqtSignal(SpatialExtent)
......@@ -524,7 +521,7 @@ class LabelingWidget(QMainWindow, loadUI('labelingdock.ui')):
def __init__(self, parent=None, canvas=None):
super(LabelingWidget, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'labelingdock.ui', self)
self.mVectorLayerComboBox = QgsMapLayerComboBox()
self.mVectorLayerComboBox.setAllowEmptyLayer(True)
......@@ -734,8 +731,8 @@ class LabelingWidget(QMainWindow, loadUI('labelingdock.ui')):
def initActions(self):
iface = qgisInstance()
import qgis.utils
iface = qgis.utils.iface
# if isinstance(iface, QgisInterface):
# self.mActionAddFeature = iface.actionAddFeature()
......
......@@ -63,7 +63,7 @@ EXTRA_SPECLIB_FIELDS = [
]
class AboutDialogUI(QDialog, loadUI('aboutdialog.ui')):
class AboutDialogUI(QDialog):
def __init__(self, parent=None):
"""Constructor."""
super(AboutDialogUI, self).__init__(parent)
......@@ -72,7 +72,7 @@ class AboutDialogUI(QDialog, loadUI('aboutdialog.ui')):
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
loadUi(DIR_UI / 'aboutdialog.ui', self)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
self.init()
......@@ -115,20 +115,14 @@ class AboutDialogUI(QDialog, loadUI('aboutdialog.ui')):
class TimeSeriesViewerUI(QMainWindow,
loadUI('timeseriesviewer.ui')):
class TimeSeriesViewerUI(QMainWindow):
sigAboutToBeClosed = pyqtSignal()
def __init__(self, parent=None):
"""Constructor."""
super(TimeSeriesViewerUI, self).__init__(parent)
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
loadUi(DIR_UI / 'timeseriesviewer.ui', self)
self.setCentralWidget(self.mMapWidget)
......@@ -676,7 +670,7 @@ class TimeSeriesViewer(QgisInterface, QObject):
Returns the SpectraLibrary of the SpectralLibrary dock
:return: SpectraLibrary
"""
from .externals.qps.speclib.spectrallibraries import SpectralLibraryPanel
from .externals.qps.speclib.gui import SpectralLibraryPanel
if isinstance(self.ui.dockSpectralLibrary, SpectralLibraryPanel):
return self.ui.dockSpectralLibrary.SLW.speclib()
else:
......@@ -1323,13 +1317,13 @@ class TimeSeriesViewer(QgisInterface, QObject):
class SaveAllMapsDialog(QDialog, loadUI('saveallmapsdialog.ui')):
class SaveAllMapsDialog(QDialog):
def __init__(self, parent=None):
super(SaveAllMapsDialog, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'saveallmapsdialog.ui', self)
self.setWindowTitle('Save Maps')
assert isinstance(self.fileWidget, QgsFileWidget)
assert isinstance(self.cbFileType, QComboBox)
......
......@@ -1172,8 +1172,8 @@ class MapCanvas(QgsMapCanvas):
menu.exec_(event.globalPos())
def addLayers2QGIS(self, mapLayers):
from eotimeseriesviewer.utils import qgisInstance
iface = qgisInstance()
import qgis.utils
iface = qgis.utils.iface
if isinstance(iface, QgisInterface):
grpNode= iface.layerTreeView().currentGroupNode()
assert isinstance(grpNode, QgsLayerTreeGroup)
......
......@@ -21,7 +21,16 @@
"""
import os, sys, re, fnmatch, collections, copy, traceback, bisect
import os
import sys
import re
import fnmatch
import collections
import copy
import traceback
import bisect
from eotimeseriesviewer import DIR_UI
from qgis.core import *
from qgis.core import QgsContrastEnhancement, QgsRasterShader, QgsColorRampShader, QgsProject, QgsCoordinateReferenceSystem, \
QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsMapLayerProxyModel, QgsColorRamp, QgsSingleBandPseudoColorRenderer
......@@ -35,7 +44,7 @@ import numpy as np
from .utils import *
from .import Option, OptionListModel
from .timeseries import SensorInstrument, TimeSeriesDate, TimeSeries, SensorProxyLayer
from .utils import loadUI
from .utils import loadUi
from .mapviewscrollarea import MapViewScrollArea
from .mapcanvas import MapCanvas, MapTools, MapCanvasInfoItem, MapCanvasMapTools
......@@ -204,7 +213,7 @@ class MapViewLayerTreeModel(QgsLayerTreeModel):
return f
class MapView(QFrame, loadUIFormClass(jp(DIR_UI, 'mapview.ui'))):
class MapView(QFrame):
"""
A MapView defines how a single map canvas visualizes sensor specific EOTS data plus additional vector overlays
"""
......@@ -218,7 +227,8 @@ class MapView(QFrame, loadUIFormClass(jp(DIR_UI, 'mapview.ui'))):
def __init__(self, name='Map View', parent=None):
super(MapView, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'mapview.ui', self)
#self.setupUi(self)
from eotimeseriesviewer.settings import defaultValues, Keys
DEFAULT_VALUES = defaultValues()
......@@ -801,7 +811,7 @@ class MapViewListModel(QAbstractListModel):
return value
class MapWidget(QFrame, loadUIFormClass(jp(DIR_UI, 'mapwidget.ui'))):
class MapWidget(QFrame):
"""
This widget contains all maps
"""
......@@ -831,7 +841,8 @@ class MapWidget(QFrame, loadUIFormClass(jp(DIR_UI, 'mapwidget.ui'))):
def __init__(self, *args, **kwds):
super(MapWidget, self).__init__(*args, **kwds)
self.setupUi(self)
loadUi(DIR_UI / 'mapwidget.ui', self)
self.setContentsMargins(1, 1, 1, 1)
self.mGrid = self.gridFrame.layout()
assert isinstance(self.mGrid, QGridLayout)
......@@ -954,7 +965,13 @@ class MapWidget(QFrame, loadUIFormClass(jp(DIR_UI, 'mapwidget.ui'))):
:param extent: SpatialExtent
:return: SpatialExtent the current SpatialExtent
"""
assert isinstance(extent, SpatialExtent)
try:
assert isinstance(extent, SpatialExtent), 'Expected SpatialExtent, but got {} {}'.format(type(extent), extent)
except Exception as ex:
traceback.print_exception(*sys.exc_info())
raise ex
if self.mSpatialExtent != extent:
self.mSpatialExtent = extent
......@@ -1639,7 +1656,7 @@ class MapWidget(QFrame, loadUIFormClass(jp(DIR_UI, 'mapwidget.ui'))):
class MapViewDock(QgsDockWidget, loadUI('mapviewdock.ui')):
class MapViewDock(QgsDockWidget):
sigMapViewAdded = pyqtSignal(MapView)
sigMapViewRemoved = pyqtSignal(MapView)
......@@ -1661,7 +1678,7 @@ class MapViewDock(QgsDockWidget, loadUI('mapviewdock.ui')):
def __init__(self, parent=None):
super(MapViewDock, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'mapviewdock.ui', self)
self.baseTitle = self.windowTitle()
......
......@@ -29,8 +29,9 @@ from qgis.PyQt.QtXml import *
from qgis.PyQt.QtGui import *
from eotimeseriesviewer import DIR_UI
from .timeseries import *
from .utils import SpatialExtent, SpatialPoint, px2geo, loadUI, nextColor
from .utils import SpatialExtent, SpatialPoint, px2geo, loadUi, nextColor
from .externals.qps.plotstyling.plotstyling import PlotStyle, PlotStyleButton, PlotStyleDialog
from .externals.pyqtgraph import ScatterPlotItem, SpotItem, GraphicsScene
from .externals.qps.externals.pyqtgraph.GraphicsScene.mouseEvents import MouseClickEvent, MouseDragEvent
......@@ -1225,12 +1226,12 @@ class PlotSettingsModel3DWidgetDelegate(QStyledItemDelegate):
class ProfileViewDockUI(QgsDockWidget, loadUI('profileviewdock.ui')):
class ProfileViewDockUI(QgsDockWidget):
def __init__(self, parent=None):
super(ProfileViewDockUI, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'profileviewdock.ui', self)
self.addActions(self.findChildren(QAction))
......
......@@ -28,13 +28,14 @@ from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.timeseries import TimeSeries, SensorInstrument, TimeSeriesDate, TimeSeriesSource
from eotimeseriesviewer.utils import loadUI
from eotimeseriesviewer.utils import loadUi
class SensorDockUI(QgsDockWidget, loadUI('sensordock.ui')):
class SensorDockUI(QgsDockWidget):
def __init__(self, parent=None):
super(SensorDockUI, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'sensordock.ui', self)
self.TS = None
......
......@@ -9,7 +9,7 @@ from qgis.PyQt.QtGui import *
from eotimeseriesviewer import *
from eotimeseriesviewer import __version__ as EOTSV_VERSION
from eotimeseriesviewer.utils import loadUI
from eotimeseriesviewer.utils import loadUi
from eotimeseriesviewer.timeseries import SensorMatching, SensorInstrument
from osgeo import gdal, gdalconst, gdal_array
......@@ -426,14 +426,14 @@ class SensorSettingsTableModel(QAbstractTableModel):
class SettingsDialog(QDialog, loadUI('settingsdialog.ui')):
class SettingsDialog(QDialog):
"""
A widget to change settings
"""
def __init__(self, title='<#>', parent=None):
super(SettingsDialog, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'settingsdialog.ui', self)
assert isinstance(self.cbDateTimePrecission, QComboBox)
from eotimeseriesviewer.timeseries import DateTimePrecision
......
......@@ -24,7 +24,7 @@
from .utils import *
from .virtualrasters import *
from .dateparser import *
from eotimeseriesviewer import DIR_UI
def datesFromDataset(dataset:gdal.Dataset)->list:
......@@ -58,7 +58,7 @@ def datesFromDataset(dataset:gdal.Dataset)->list:
for key, values in domainData.items():
for regex in searchedKeysDataSet:
if regex.search(key.strip()):
values = re.sub('[{}]', '', values)
values = re.sub(r'[{}]', '', values)
values = values.split(',')
dateValues = [extractDateTimeGroup(t) for t in values]
if checkDates(dateValues):
......@@ -663,12 +663,12 @@ class OutputImageModel(QAbstractTableModel):
class StackedBandInputDialog(QDialog, loadUI('stackedinputdatadialog.ui')):
class StackedBandInputDialog(QDialog):
def __init__(self, parent=None):
super(StackedBandInputDialog, self).__init__(parent=parent)
self.setupUi(self)
loadUi(DIR_UI / 'stackedinputdatadialog.ui', self)
self.setWindowTitle('Stacked Time Series Data Input')
self.mWrittenFiles = []
......
......@@ -29,7 +29,8 @@ from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
import numpy as np
from eotimeseriesviewer.utils import loadUI, SpatialExtent
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.utils import loadUi, SpatialExtent
PSUTIL_AVAILABLE = False
try:
......@@ -307,12 +308,12 @@ class DataLoadingModel(QAbstractTableModel):
class SystemInfoDock(QgsDockWidget, loadUI('systeminfo.ui')):
class SystemInfoDock(QgsDockWidget):
def __init__(self, parent=None):
super(SystemInfoDock, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'systeminfo.ui', self)
self.lyrModel = MapLayerRegistryModel()
self.tableViewMapLayerRegistry.setModel(self.lyrModel)
......
......@@ -36,7 +36,7 @@ from .externals.qps.plotstyling.plotstyling import PlotStyle
from .timeseries import TimeSeries, TimeSeriesDate, SensorInstrument, TimeSeriesSource
from .utils import *
from .externals.qps.speclib.spectrallibraries import createQgsField
from .externals.qps.speclib.core import createQgsField
LABEL_EXPRESSION_2D = 'DN or Index'
......
......@@ -25,7 +25,7 @@ from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from eotimeseriesviewer.externals.qps.models import Option, OptionListModel
from eotimeseriesviewer import DIR_UI
from eotimeseriesviewer.temporalprofiles import *
......@@ -362,12 +362,12 @@ class TemporalProfile3DPlotStyle(TemporalProfilePlotStyleBase):
return plotItems
class TemporalProfilePlotStyle3DWidget(QWidget, loadUI('plotstyle3Dwidget.ui')):
class TemporalProfilePlotStyle3DWidget(QWidget):
sigPlotStyleChanged = pyqtSignal(PlotStyle)
def __init__(self, title='<#>', parent=None):
super(TemporalProfilePlotStyle3DWidget, self).__init__(parent)
self.setupUi(self)
loadUi(DIR_UI / 'plotstyle3Dwidget.ui', self)
self.mBlockUpdates = False