diff --git a/ODMTools.py b/ODMTools.py index ecbea16..57846f3 100755 --- a/ODMTools.py +++ b/ODMTools.py @@ -20,7 +20,7 @@ import pyodbc import pymysql -import psycopg2 +#import psycopg2 tool = LoggerTool() logger = tool.setupLogger('main', 'odmtools.log', 'a', logging.INFO) diff --git a/odmtools/__init__.py b/odmtools/__init__.py index df60136..5381d99 100644 --- a/odmtools/__init__.py +++ b/odmtools/__init__.py @@ -1,6 +1,5 @@ __author__ = 'Jacob' import odmdata -import odmservices import controller import gui import lib @@ -9,7 +8,6 @@ __all__ = [ 'odmdata', - 'odmservices', 'controller', 'gui', 'lib', diff --git a/odmtools/controller/frmCreateVariable.py b/odmtools/controller/frmCreateVariable.py index 5b49153..056cce6 100644 --- a/odmtools/controller/frmCreateVariable.py +++ b/odmtools/controller/frmCreateVariable.py @@ -2,7 +2,7 @@ import wx from odmtools.view.clsCreateVariable import clsCreateVariable -from odmtools.odmdata import Variable +# from odmtools.odmdata import Variable # Implementing clsCreateVariable class frmCreateVariable(clsCreateVariable): @@ -87,26 +87,30 @@ def OnBtnCreateButton(self, event): def createVariable(self): - v = Variable() - v.code = self.txtVarCode.GetValue() if self.txtVarCode.GetValue() <> u'' else None - v.name = self.cbVarName.GetValue() if self.cbVarName.GetValue() <> u'' else None - v.speciation = self.cbSpeciation.GetValue() if self.cbSpeciation.GetValue() <> u'' else None - v.variable_unit = self.series_service.get_unit_by_name( self.cbVarUnits.GetValue()) - v.variable_unit_id = v.variable_unit.id + code = self.txtVarCode.GetValue() if self.txtVarCode.GetValue() <> u'' else None + name = self.cbVarName.GetValue() if self.cbVarName.GetValue() <> u'' else None + speciation = self.cbSpeciation.GetValue() if self.cbSpeciation.GetValue() <> u'' else None - v.sample_medium = self.cbSampleMedium.GetValue() if self.cbSampleMedium.GetValue() <> u'' else None - v.value_type = self.cbValueType.GetValue() if self.cbValueType.GetValue() <> u'' else None - v.is_regular = self.cbIsRegular.GetValue() if self.cbIsRegular.GetValue() <> u'' else None - v.time_support = self.txtTSValue.GetValue() if self.txtTSValue.GetValue() <> u'' else None + variable_unit = self.series_service.get_unit_by_name( self.cbVarUnits.GetValue()) + variable_unit_id = variable_unit.id - v.time_unit = self.series_service.get_unit_by_name(self.cbTSUnits.GetValue()) - v.time_unit_id = v.time_unit.id + sample_medium = self.cbSampleMedium.GetValue() if self.cbSampleMedium.GetValue() <> u'' else None + value_type = self.cbValueType.GetValue() if self.cbValueType.GetValue() <> u'' else None + is_regular = self.cbIsRegular.GetValue() if self.cbIsRegular.GetValue() <> u'' else None + time_support = self.txtTSValue.GetValue() if self.txtTSValue.GetValue() <> u'' else None - v.data_type = self.cbDataType.GetValue() if self.cbDataType.GetValue() <> u'' else None - v.general_category = self.cbGenCat.GetValue() if self.cbGenCat.GetValue() <> u'' else None - v.no_data_value = self.txtNoDV.GetValue() if self.txtNoDV.GetValue() <> u'' else None + time_unit = self.series_service.get_unit_by_name(self.cbTSUnits.GetValue()) + time_unit_id = time_unit.id + + data_type = self.cbDataType.GetValue() if self.cbDataType.GetValue() <> u'' else None + general_category = self.cbGenCat.GetValue() if self.cbGenCat.GetValue() <> u'' else None + no_data_value = self.txtNoDV.GetValue() if self.txtNoDV.GetValue() <> u'' else None + v = self.series_service.create_variable( + code, name, speciation, variable_unit_id, sample_medium, + value_type, is_regular, time_support, time_unit_id, data_type, + general_category, no_data_value) return v def OnBtnCancelButton(self, event): diff --git a/odmtools/controller/frmDBConfig.py b/odmtools/controller/frmDBConfig.py index 6ef3005..d79c1c1 100755 --- a/odmtools/controller/frmDBConfig.py +++ b/odmtools/controller/frmDBConfig.py @@ -93,10 +93,10 @@ def validateInput(self, conn_dict): wx.MessageBox(message, 'Test Connection', wx.OK) else: #TODO add error message if user cannont connect to the database ( not using VPN) but the db is still 1.1.1) - if not (self.service_manager.get_db_version(conn_dict)): - message = "Cannot connect to the database" - else: - message = "This connection is not a 1.1.1 Database" + + + message = "Cannot connect to the database" + wx.MessageBox(message, 'Error Occurred', wx.OK | wx.ICON_ERROR) return False @@ -109,8 +109,6 @@ def validateInput(self, conn_dict): return True - - # Returns a dictionary of the database values entered in the form def getFieldValues(self): conn_dict = {} @@ -120,6 +118,7 @@ def getFieldValues(self): conn_dict['password'] = self.txtPass.GetValue() conn_dict['address'] = self.txtServer.GetValue() conn_dict['db'] = self.txtDBName.GetValue() + conn_dict['version']= self.cbVersion.GetValue() return conn_dict @@ -129,7 +128,9 @@ def set_field_values(self): self.txtServer.SetValue(conn['address']) self.txtDBName.SetValue(conn['db']) self.txtUser.SetValue(conn['user']) + self.cbVersion.SetValue(str(conn['version'])) for k, v in self.choices.iteritems(): if v == conn['engine']: self.cbDatabaseType.SetValue(k) + diff --git a/odmtools/controller/logicPlotOptions.py b/odmtools/controller/logicPlotOptions.py index 25f69b6..cb521c7 100644 --- a/odmtools/controller/logicPlotOptions.py +++ b/odmtools/controller/logicPlotOptions.py @@ -83,7 +83,6 @@ def __init__(self, memDB, taskserver): self.currentEnd = self.endDate self.isSubsetted = False - def getDates(self): return self.startDate, self.endDate, self.currentStart, self.currentEnd @@ -112,7 +111,6 @@ def resetDates(self): self.currentStart = self.startDate self.currentEnd = self.endDate - def isPlotted(self, sid): if int(sid) in self._seriesInfos: return True @@ -144,7 +142,6 @@ def setEditSeries(self, seriesID): self._seriesInfos[self.editID].plotcolor = self._seriesInfos[self.editID].color self._seriesInfos[self.editID].color = "Black" - def updateEditSeries(self): #update values if self.editID in self._seriesInfos: @@ -152,7 +149,6 @@ def updateEditSeries(self): data =self.memDB.getEditDataValuesforGraph() self._seriesInfos[self.editID].dataTable = data - def stopEditSeries(self): if self.editID in self._seriesInfos: data = self.memDB.getDataValuesforGraph( @@ -187,7 +183,6 @@ def update(self, key, isselected): #results = self.taskserver.getCompletedTasks() #self.memDB.setConnection(results["InitEditValues"]) - self._seriesInfos[key] = self.getSeriesInfo(key) self.getUpdatedData(key) @@ -219,8 +214,10 @@ def getSeriesById(self, seriesID): series = self.memDB.series_service.get_series_by_id(seriesID) self.memDB.series_service.reset_session() return series + except Exception as e : logger.error("Series Not Found %s"%e) + return None def getSelectedSeries(self, seriesID): @@ -245,20 +242,20 @@ def createSeriesInfo(self, seriesID, seriesInfo, series): unitsName = series.variable_units_name siteName = series.site_name dataType = series.data_type - noDataValue = series.variable.no_data_value + variable = self.memDB.series_service.get_variable_by_id(series.variable_id) + + noDataValue = variable.no_data_value if self.editID == seriesID: #d= DataFrame(pandas.read_sql()) logger.debug("editing -- getting datavalues for graph") data = self.memDB.getEditDataValuesforGraph() logger.debug("Finished editing -- getting datavalues for graph") - else: logger.debug("plotting -- getting datavalues for graph") data = self.memDB.getDataValuesforGraph(seriesID, noDataValue, self.currentStart, self.currentEnd) logger.debug("Finished plotting -- getting datavalues for graph") - logger.debug("assigning variables...") seriesInfo.seriesID = seriesID seriesInfo.series = series @@ -274,13 +271,11 @@ def createSeriesInfo(self, seriesID, seriesInfo, series): seriesInfo.noDataValue = noDataValue seriesInfo.dataTable = data - if len(data) > 0: seriesInfo.yrange = np.max(data['DataValue']) - np.min(data['DataValue']) else: seriesInfo.yrange = 0 - logger.debug("Finished creating SeriesInfo") return seriesInfo @@ -326,8 +321,6 @@ def buildPlotInfo(self, seriesInfo): seriesInfo.color = self.colorList.pop(0) return seriesInfo - - def updateDateRange(self, startDate=None, endDate=None): self.currentStart = startDate self.currentEnd = endDate @@ -376,7 +369,6 @@ def __init__(self, data): time = timeit.default_timer() - self.NumberofObservations = count self.ArithemticMean = round(np.mean(dvs), 5) self.Maximum = round(np.max(dvs), 5) @@ -404,7 +396,6 @@ def __init__(self, data, method): self.intervals = {} self.method = method - interval_types = ["Overall", "Year", "Month", "Season"] intervals = ["Overall", "Year", "Month", "Season"] @@ -451,7 +442,6 @@ def calculateBoxWhiskerData(self, interval, interval_type): interval_type, interval_type, results["names"], [results["median"], results["conflimit"], results["mean"], results["confint"]]) - def calculateIntervalsOnGroups(self, interval): mean = [] diff --git a/odmtools/controller/olvSeriesSelector.py b/odmtools/controller/olvSeriesSelector.py index f49fdb0..91f6dc3 100644 --- a/odmtools/controller/olvSeriesSelector.py +++ b/odmtools/controller/olvSeriesSelector.py @@ -5,6 +5,7 @@ # from ObjectListView.ObjectListView import FastObjectListView, ColumnDefn from odmtools.lib.ObjectListView import FastObjectListView, ColumnDefn + # from odmtools.common.logger import LoggerTool from odmtools.odmdata import series @@ -14,7 +15,22 @@ logger =logging.getLogger('main') OvlCheckEvent, EVT_OVL_CHECK_EVENT = wx.lib.newevent.NewEvent() - +from collections import OrderedDict +def returnDict(): + keys = ['SeriesID', 'SiteID', 'SiteCode', 'SiteName', 'VariableID', 'VariableCode', 'VariableName', 'Speciation', + 'VariableUnitsID', 'VariableUnitsName', 'SampleMedium', 'ValueType', 'TimeSupport', 'TimeUnitsID', + 'TimeUnitsName', 'DataType', 'GeneralCategory', 'MethodID', 'MethodDescription', 'SourceID', + 'SourceDescription', 'Organization', 'Citation', 'QualityControlLevelID', 'QualityControlLevelCode', + 'BeginDateTime', 'EndDateTime', 'BeginDateTimeUTC', 'EndDateTimeUTC', 'ValueCount' + ] + values = ['id', 'site_id', 'site_code', 'site_name', 'variable_id', 'variable_code', 'variable_name', 'speciation', + 'variable_units_id', 'variable_units_name', 'sample_medium', 'value_type', 'time_support', + 'time_units_id', 'time_units_name', 'data_type', 'general_category', 'method_id', 'method_description', + 'source_id', 'source_description', 'organization', 'citation', 'quality_control_level_id', + 'quality_control_level_code', 'begin_date_time', 'end_date_time', 'begin_date_time_utc', + 'end_date_time_utc', 'value_count' + ] + return OrderedDict(zip(keys, values)) class clsSeriesTable(FastObjectListView): def __init__(self, *args, **kwargs): @@ -49,7 +65,7 @@ def _buildColumns(self): ColumnDefn(key, align="left", minimumWidth=100, valueGetter=value, # stringConverter = '%s') stringConverter='%Y-%m-%d %H:%M:%S' if "date" in key.lower() else'%s') - for key, value in series.returnDict().iteritems()] + for key, value in returnDict().iteritems()] self.SetColumns(seriesColumns) """User can select series using the mouse to click on check boxes """ diff --git a/odmtools/controller/pageExisting.py b/odmtools/controller/pageExisting.py index 0544cfe..683a8ae 100644 --- a/odmtools/controller/pageExisting.py +++ b/odmtools/controller/pageExisting.py @@ -2,7 +2,7 @@ import wx from odmtools.view import clsExisting -from odmtools.odmdata import series +from odmtools.odmdata import returnDict import wx.wizard as wiz import datetime @@ -43,10 +43,12 @@ def _init_data(self, series_serv, site_id): #if q.code == self.qcl.code: # index = i + self.pnlExisting.olvSeriesList.Focus(index) self.pnlExisting.olvSeriesList.Select(index) + # Handlers for pnlExisting events. def OnOLVItemSelected(self, event): # TODO: Implement OnOLVItemSelected @@ -75,7 +77,7 @@ def initTable(self, dbservice, site_id): seriesColumns = [clsExisting.ColumnDefn(key, align="left", minimumWidth=-1, valueGetter=value, stringConverter= '%Y-%m-%d %H:%M:%S' if 'date' in key.lower() else '%s') - for key, value in series.returnDict().iteritems()] + for key, value in returnDict().iteritems()] self.pnlExisting.olvSeriesList.SetColumns(seriesColumns) objects = dbservice.get_series_by_site(site_id= site_id) diff --git a/odmtools/gui/frmFlagValues.py b/odmtools/gui/frmFlagValues.py index 32e4286..3d16ec2 100755 --- a/odmtools/gui/frmFlagValues.py +++ b/odmtools/gui/frmFlagValues.py @@ -2,7 +2,7 @@ import wx -from odmtools.odmdata import Qualifier + def create(parent): diff --git a/odmtools/gui/frmODMTools.py b/odmtools/gui/frmODMTools.py index d48f642..a153bbd 100755 --- a/odmtools/gui/frmODMTools.py +++ b/odmtools/gui/frmODMTools.py @@ -35,6 +35,7 @@ logger =logging.getLogger('main') + class frmODMToolsMain(wx.Frame): """ @@ -58,6 +59,7 @@ def __init__(self, **kwargs): self.record_service = None self.scriptcreate = False + series_service = self._init_database() if series_service: self._init_ctrls(series_service) @@ -70,7 +72,6 @@ def __init__(self, **kwargs): logger.info("System shutting down... ") sys.exit(0) - def _obtainScreenResolution(self): """ Calculates the size of ODMTools. Prevents ODMTools being larger than the available screen size typically a problem on laptops @@ -106,7 +107,6 @@ def _obtainScreenResolution(self): logger.debug("ODMTools Window Size: %s" % newSize) return newSize - #############Entire Form Sizers########## def _init_sizers(self): @@ -120,11 +120,10 @@ def _init_s_Items(self, parent): parent.AddWindow(self._ribbon, 0, wx.EXPAND) parent.AddWindow(self.pnlDocking, 85, flag=wx.ALL | wx.EXPAND) + def _init_database(self, quit_if_cancel=True): logger.info("Loading Database...") - - while True: ## Database connection is valid, therefore proceed through the rest of the program if self.service_manager.is_valid_connection(): @@ -157,6 +156,7 @@ def _init_database(self, quit_if_cancel=True): return series_service + def onChangeDBConn(self, event): db_config = frmDBConfig.frmDBConfig(None, self.service_manager, False) value = db_config.ShowModal() @@ -181,6 +181,7 @@ def onChangeDBConn(self, event): self.dataTable.clear() + def servicesValid(self, service, displayMsg=True): """ @@ -193,13 +194,14 @@ def servicesValid(self, service, displayMsg=True): ## Test if Series Catalog is empty if not service.get_used_sites(): if displayMsg: - msg = wx.MessageDialog(None, 'Series Catalog cannot be empty. Please enter in a new database connection', - 'Series Catalog is empty', wx.OK | wx.ICON_ERROR ) + msg = wx.MessageDialog(None, + 'Series Catalog cannot be empty. Please enter in a new database connection', + 'Series Catalog is empty', wx.OK | wx.ICON_ERROR) msg.ShowModal() valid = False # @TODO If Jeff runs into other issues with services not being available, we can simply test different services here - #if not service.get_all_variables(): + # if not service.get_all_variables(): # valid = False return valid @@ -210,7 +212,7 @@ def on_about_request(self, event): def MacReopenApp(self): """Called when the doc icon is clicked, and ???""" - try: # it's possible for this event to come when the frame is closed + try: # it's possible for this event to come when the frame is closed self.GetTopWindow().Raise() except: pass @@ -254,9 +256,8 @@ def _init_ctrls(self, series_service): ################ Series Selection Panel ################## logger.debug("Loading Series Selector ...") - - self.pnlSelector = FrmSeriesSelector(self.pnlDocking, series_service, plot=self.pnlPlot, taskserver=self.taskserver, memdb = self.memDB) - + self.pnlSelector = FrmSeriesSelector(self.pnlDocking, series_service, plot=self.pnlPlot, + taskserver=self.taskserver, memdb=self.memDB) ####################grid Table View################## logger.debug("Loading DataTable ...") @@ -268,15 +269,12 @@ def _init_ctrls(self, series_service): self.txtPythonConsole = ODMToolsConsole(parent=self.pnlDocking, size=wx.Size(200, 200)) wx.CallAfter(self._postStartup) - - logger.debug("Loading Python Script ...") self.txtPythonScript = pnlScript(name=u'txtPython', parent=self, - size=wx.Size(200, 200)) + size=wx.Size(200, 200)) self.Bind(wx.EVT_CLOSE, self.onClose) - Publisher.subscribe(self.onDocking, ("adjust.Docking")) Publisher.subscribe(self.onPlotSelection, ("select.Plot")) Publisher.subscribe(self.onExecuteScript, ("execute.script")) @@ -297,31 +295,31 @@ def _init_aui_manager(self): self._mgr.AddPane(self.pnlPlot, aui.AuiPaneInfo().CenterPane() .Name("Plot").Caption("Plot").MaximizeButton(True).DestroyOnClose(False) - ) + ) self._mgr.AddPane(self.dataTable, aui.AuiPaneInfo().Right().Name("Table"). Show(show=False).Caption('Table View').MinSize(wx.Size(200, 200)).Floatable().Movable(). Position(1).MinimizeButton(True).MaximizeButton(True).DestroyOnClose(False) - ) + ) self._mgr.AddPane(self.pnlSelector, aui.AuiPaneInfo().Bottom().Name("Selector").MinSize(wx.Size(50, 200)). Movable().Floatable().Position(0).MinimizeButton(True).MaximizeButton(True).CloseButton(True) .DestroyOnClose(False) - ) + ) self._mgr.AddPane(self.txtPythonScript, aui.AuiPaneInfo().Caption('Script'). Name("Script").Movable().Floatable().Right() .MinimizeButton(True).MaximizeButton(True).FloatingSize(size=(400, 400)) .CloseButton(True).Float().FloatingPosition(pos=(self.Position)) .Hide().CloseButton(True).DestroyOnClose(False) - ) + ) self._mgr.AddPane(self.txtPythonConsole, aui.AuiPaneInfo().Caption('Python Console'). Name("Console").FloatingSize(size=(300, 400)).MinimizeButton( True).Movable().Floatable().MaximizeButton(True).CloseButton(True).Float() .FloatingPosition(pos=(self.Position)).Show(show=False).DestroyOnClose(False) - ) + ) ## TODO Fix loadingDockingSettings as it doesn't load it correctly. @@ -375,7 +373,6 @@ def getDBService(self): def onPlotSelection(self, value): self.pnlPlot.selectPlot(value) - def onSetScriptTitle(self, title): scriptPane = self._mgr.GetPane(self.txtPythonScript) scriptPane.Caption(title) @@ -385,6 +382,7 @@ def onSetScriptTitle(self, title): def addEdit(self, event): + with wx.BusyInfo("Please wait for a moment while ODMTools fetches the data and stores it in our database", parent=self): self.scriptcreate = True isSelected, seriesID = self.pnlSelector.onReadyToEdit() @@ -432,16 +430,15 @@ def addEdit(self, event): logger.debug("Recording? %s" % self.record_service._record) - #self.record_service = None + # self.record_service = None self.txtPythonConsole.shell.run("edit_service = app.TopWindow.record_service", prompt=False, verbose=False) self.txtPythonConsole.shell.run("series_service = edit_service.get_series_service()", prompt=False, verbose=False) - #from meliae import scanner - #scanner.dump_all_objects("edit_plotting.dat") + # from meliae import scanner + # scanner.dump_all_objects("edit_plotting.dat") logger.info("Finished Setting up Editing Series: %s " % seriesID) - def stopEdit(self, event): self.pnlSelector.stopEdit() @@ -452,7 +449,6 @@ def stopEdit(self, event): self.record_service = None self._ribbon.toggleEditButtons(False) - def getRecordService(self): return self.record_service @@ -467,7 +463,10 @@ def createService(self, conn_dict=""): :return: """ - series_service = self.service_manager.get_series_service(conn_dict=conn_dict) + + series_service= self.service_manager.get_series_service(conn_dict=conn_dict)#=connection) + + return series_service def getServiceManager(self): @@ -516,7 +515,7 @@ def onClose(self, event): print "error saving docking data" self._mgr.UnInit() - + # Shut down processes running in background if self.taskserver.numprocesses > 0 and self.taskserver.anyAlive: busy = wx.BusyInfo("Closing ODMTools ...", parent=self) diff --git a/odmtools/gui/pageMethod.py b/odmtools/gui/pageMethod.py index df72837..de59425 100644 --- a/odmtools/gui/pageMethod.py +++ b/odmtools/gui/pageMethod.py @@ -3,7 +3,8 @@ import wx import wx.grid import wx.richtext -from odmtools.odmdata import Method +from odmtools.odmdata import ODM + [wxID_PNLMETHOD, wxID_PNLMETHODSLISTCTRL1, wxID_PNLMETHODSRBCREATENEW, wxID_PNLMETHODSRBGENERATE, wxID_PNLMETHODSRBSELECT, @@ -111,15 +112,17 @@ def OnTxtMethodDescripKillFocus(self, event): def getMethod(self): - m = Method() + m = None if self.rbGenerate.Value: genmethod = "Values derived from ODM Tools Python" + m= self.series_service.get_method_by_description(genmethod) if m is None: logger.debug("assigning new method description") - m = Method() + m = ODM.Method() m.description = genmethod + elif self.rbSelect.Value: index = self.lstMethods.GetFirstSelected() desc= self.lstMethods.GetItem(index, 0).GetText() @@ -130,6 +133,8 @@ def getMethod(self): elif self.rbCreateNew.Value: + logger.debug("assigning new method description") m.description = self.txtMethodDescrip.GetValue() + return m \ No newline at end of file diff --git a/odmtools/gui/pageQCL.py b/odmtools/gui/pageQCL.py index 57f4970..566e8c6 100644 --- a/odmtools/gui/pageQCL.py +++ b/odmtools/gui/pageQCL.py @@ -1,7 +1,7 @@ #Boa:FramePanel:pnlQCL import wx -from odmtools.odmdata import QualityControlLevel + [wxID_PNLQCL, wxID_PNLQCLLBLCODE, wxID_PNLQCLLBLDEFINITION, wxID_PNLQCLLBLEXPLANATION, wxID_PNLQCLLSTQCL, wxID_PNLQCLRBCREATE, @@ -111,8 +111,9 @@ def GetLstSelection(self): return self.lstQCL.GetFirstSelected() def getQCL(self): - q = QualityControlLevel() + q = None if self.rbCreate.Value: + q= self.series_service.create_qcl(self.txtCode.Value, self.txtDefinition.Value, self.txtExplanation.Value) q.code = self.txtCode.Value q.definition= self.txtDefinition.Value q.explanation = self.txtExplanation.Value diff --git a/odmtools/gui/pageVariable.py b/odmtools/gui/pageVariable.py index d14c90b..582ecad 100644 --- a/odmtools/gui/pageVariable.py +++ b/odmtools/gui/pageVariable.py @@ -2,7 +2,7 @@ import wx from odmtools.controller.frmCreateVariable import frmCreateVariable -from odmtools.odmdata import Variable +# from odmtools.odmdata import Variable [wxID_PNLVARIABLE, wxID_PNLVARIABLELSTVARIABLE, wxID_PNLVARIABLERBCREATE, wxID_PNLVARIABLERBCURRENT, wxID_PNLVARIABLERBSELECT,wxID_PNLVARIABLETXTNEWVAR, @@ -138,7 +138,7 @@ def OnListCtrl1ListItemSelected(self, event): def getVariable(self): - v = Variable() + v = None if self.rbCurrent.Value: v= self.prev_val elif self.rbSelect.Value: diff --git a/odmtools/odmdata/__init__.py b/odmtools/odmdata/__init__.py index dfb89a2..80b2cba 100644 --- a/odmtools/odmdata/__init__.py +++ b/odmtools/odmdata/__init__.py @@ -1,68 +1,66 @@ -from base import Base -from censor_code_cv import CensorCodeCV -from data_type_cv import DataTypeCV -from data_value import DataValue -from general_category_cv import GeneralCategoryCV -from iso_metadata import ISOMetadata -from lab_method import LabMethod -from method import Method -from odm_version import ODMVersion -from offset_type import OffsetType -from qualifier import Qualifier -from quality_control_level import QualityControlLevel -from sample import Sample -from sample_medium_cv import SampleMediumCV -from sample_type_cv import SampleTypeCV -from series import Series -from session_factory import SessionFactory -from site import Site -from site_type_cv import SiteTypeCV -from source import Source -from spatial_reference import SpatialReference -from speciation_cv import SpeciationCV -from topic_category_cv import TopicCategoryCV -from unit import Unit -from value_type_cv import ValueTypeCV -from variable import Variable -from variable_name_cv import VariableNameCV -from vertical_datum_cv import VerticalDatumCV -from memory_database import MemoryDatabase -from series import copy_series -from data_value import copy_data_value -__all__ = [ - 'Base', - 'CensorCodeCV', - 'DataTypeCV', - 'DataValue', - 'GeneralCategoryCV', - 'ISOMetadata', - 'LabMethod', - 'Method', - 'ODMVersion', - 'OffsetType', - 'Qualifier', - 'QualityControlLevel', - 'Sample', - 'SampleMediumCV', - 'SampleTypeCV', - 'Series', - 'SessionFactory', - 'Site', - 'SiteTypeCV', - 'Source', - 'SpatialReference', - 'SpeciationCV', - 'TopicCategoryCV', - 'Unit', - 'ValueTypeCV', - 'Variable', - 'VariableNameCV', - 'VerticalDatumCV', - 'MemoryDatabase', - 'copy_series', - 'copy_data_value' -] + + +#from api.versionSwitcher import ODM, refreshDB + + +# DataTypeCV=ODM.DataTypeCV +# DataValue=ODM.DataValue +# # GeneralCategoryCV=ODM.GeneralCategoryCV +# ISOMetadata=ODM.ISOMetadata +# LabMethod=ODM.LabMethod +# Method=ODM.Method +# OffsetType=ODM.OffsetType +# Qualifier=ODM.Qualifier +# QualityControlLevel=ODM.QualityControlLevel +# Sample =ODM.Sample +# SampledMediumCV= ODM.SampleMediumCV +# # SampleTypeCV=ODM.SampleTypeCV +# Series=ODM.Series +# Site= ODM.Site +# SiteType=ODM.SiteTypeCV +# Source =ODM.Source +# SpatialReferences=ODM.SpatialReference +# SpeciationCV=ODM.SpeciationCV +# # TopicCategoryCV=ODM.TopicCategoryCV +# Unit= ODM.Unit +# # ValueTypeCV=ODM.ValueTypeCV +# Variable = ODM.Variable +# VerticalDatumCV=ODM.VerticalDatumCV +# returnDict = ODM.returnDict +from odm2api.ODM1_1_1.services import SeriesService#, refreshDB +from odm2api.ODMconnection import SessionFactory, dbconnection +from odm2api.ODM2.models import _changeSchema as change_schema +from odmtools.odmdata.memory_database import MemoryDatabase +ODM = SeriesService.ODM + +from collections import OrderedDict +def returnDict(): + keys = ['SeriesID', 'SiteID', 'SiteCode', 'SiteName', 'VariableID', 'VariableCode', 'VariableName', 'Speciation', + 'VariableUnitsID', 'VariableUnitsName', 'SampleMedium', 'ValueType', 'TimeSupport', 'TimeUnitsID', + 'TimeUnitsName', 'DataType', 'GeneralCategory', 'MethodID', 'MethodDescription', 'SourceID', + 'SourceDescription', 'Organization', 'Citation', 'QualityControlLevelID', 'QualityControlLevelCode', + 'BeginDateTime', 'EndDateTime', 'BeginDateTimeUTC', 'EndDateTimeUTC', 'ValueCount' + ] + values = ['id', 'site_id', 'site_code', 'site_name', 'variable_id', 'variable_code', 'variable_name', 'speciation', + 'variable_units_id', 'variable_units_name', 'sample_medium', 'value_type', 'time_support', + 'time_units_id', 'time_units_name', 'data_type', 'general_category', 'method_id', 'method_description', + 'source_id', 'source_description', 'organization', 'citation', 'quality_control_level_id', + 'quality_control_level_code', 'begin_date_time', 'end_date_time', 'begin_date_time_utc', + 'end_date_time_utc', 'value_count' + ] + return OrderedDict(zip(keys, values)) +__all__=[ + #'SessionFactory', + 'refreshDB', + 'change_schema', + 'returnDict', + #'ODM', + 'MemoryDatabase', + 'returnDict' + 'SeriesService' + 'dbconnection' + ] diff --git a/odmtools/odmdata/base.py b/odmtools/odmdata/base.py deleted file mode 100644 index c1da040..0000000 --- a/odmtools/odmdata/base.py +++ /dev/null @@ -1,2 +0,0 @@ -from sqlalchemy.ext.declarative import declarative_base -Base = declarative_base() \ No newline at end of file diff --git a/odmtools/odmdata/censor_code_cv.py b/odmtools/odmdata/censor_code_cv.py deleted file mode 100644 index 254a825..0000000 --- a/odmtools/odmdata/censor_code_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class CensorCodeCV(Base): - __tablename__ = 'CensorCodeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/data_type_cv.py b/odmtools/odmdata/data_type_cv.py deleted file mode 100644 index da23bfe..0000000 --- a/odmtools/odmdata/data_type_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class DataTypeCV(Base): - __tablename__ = 'DataTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/data_value.py b/odmtools/odmdata/data_value.py deleted file mode 100644 index 687414a..0000000 --- a/odmtools/odmdata/data_value.py +++ /dev/null @@ -1,74 +0,0 @@ -# Declare a mapped class -from sqlalchemy import Column, Integer, Float, DateTime, ForeignKey, String -from sqlalchemy.orm import relationship -from base import Base -from site import Site -from variable import Variable -from qualifier import Qualifier -from method import Method -from source import Source -from quality_control_level import QualityControlLevel -from offset_type import OffsetType -from sample import Sample - -def copy_data_value(from_dv): - new = DataValue() - new.data_value = from_dv.data_value - new.value_accuracy = from_dv.value_accuracy - new.local_date_time = from_dv.local_date_time - new.utc_offset = from_dv.utc_offset - new.date_time_utc = from_dv.date_time_utc - new.site_id = from_dv.site_id - new.variable_id = from_dv.variable_id - new.offset_value = from_dv.offset_value - new.offset_type_id = from_dv.offset_type_id - new.censor_code = from_dv.censor_code - new.qualifier_id = from_dv.qualifier_id - new.method_id = from_dv.method_id - new.source_id = from_dv.source_id - new.sample_id = from_dv.sample_id - new.derived_from_id = from_dv.derived_from_id - new.quality_control_level_id = from_dv.quality_control_level_id - return new - -class DataValue(Base): - __tablename__ = 'DataValues' - - id = Column('ValueID', Integer, primary_key=True) - data_value = Column('DataValue', Float) - value_accuracy = Column('ValueAccuracy', Float) - local_date_time = Column('LocalDateTime', DateTime) - utc_offset = Column('UTCOffset', Float) - date_time_utc = Column('DateTimeUTC', DateTime) - site_id = Column('SiteID', Integer, ForeignKey('Sites.SiteID'), nullable=False) - variable_id = Column('VariableID', Integer, ForeignKey('Variables.VariableID'), nullable=False) - offset_value = Column('OffsetValue', Float) - offset_type_id = Column('OffsetTypeID', Integer, ForeignKey('OffsetTypes.OffsetTypeID')) - censor_code = Column('CensorCode', String) - qualifier_id = Column('QualifierID', Integer, ForeignKey('Qualifiers.QualifierID')) - method_id = Column('MethodID', Integer, ForeignKey('Methods.MethodID'), nullable=False) - source_id = Column('SourceID', Integer, ForeignKey('Sources.SourceID'), nullable=False) - sample_id = Column('SampleID', Integer, ForeignKey('Samples.SampleID')) - derived_from_id = Column('DerivedFromID', Integer) - quality_control_level_id = Column('QualityControlLevelID', Integer, ForeignKey('QualityControlLevels.QualityControlLevelID'), nullable=False) - - # relationships - site = relationship(Site) - variable = relationship(Variable) - method = relationship(Method) - source = relationship(Source) - quality_control_level = relationship(QualityControlLevel) - - qualifier = relationship(Qualifier) - offset_type = relationship(OffsetType) - sample = relationship(Sample) - - def list_repr(self): - return [self.id, self.data_value, self.value_accuracy, self.local_date_time, - self.utc_offset, self.date_time_utc, self.site_id, self.variable_id, - self.offset_value, self.offset_type_id, self.censor_code, self.qualifier_id, - self.method_id, self.source_id, self.sample_id, self.derived_from_id, - self.quality_control_level_id] - - def __repr__(self): - return "" % (self.data_value, self.local_date_time, self.value_accuracy) diff --git a/odmtools/odmdata/general_category_cv.py b/odmtools/odmdata/general_category_cv.py deleted file mode 100644 index e721166..0000000 --- a/odmtools/odmdata/general_category_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class GeneralCategoryCV(Base): - __tablename__ = 'GeneralCategoryCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/iso_metadata.py b/odmtools/odmdata/iso_metadata.py deleted file mode 100644 index cd090d4..0000000 --- a/odmtools/odmdata/iso_metadata.py +++ /dev/null @@ -1,15 +0,0 @@ -from sqlalchemy import Column, Integer, String -from base import Base - -class ISOMetadata(Base): - __tablename__ = 'ISOMetadata' - - id = Column('MetadataID', Integer, primary_key=True) - topic_category = Column('TopicCategory', String, nullable=False) - title = Column('Title', String, nullable=False) - abstract = Column('Abstract', String, nullable=False) - profile_version = Column('ProfileVersion', String, nullable=False) - metadata_link = Column('MetadataLink', String) - - def __repr__(self): - return "" % (self.id, self.topic_category, self.title) \ No newline at end of file diff --git a/odmtools/odmdata/lab_method.py b/odmtools/odmdata/lab_method.py deleted file mode 100644 index 1b933cb..0000000 --- a/odmtools/odmdata/lab_method.py +++ /dev/null @@ -1,15 +0,0 @@ -from sqlalchemy import Column, String, Integer -from base import Base - -class LabMethod(Base): - __tablename__ = 'LabMethods' - - id = Column('LabMethodID', Integer, primary_key=True) - name = Column('LabName', String, nullable=False) - organization = Column('LabOrganization', String, nullable=False) - method_name = Column('LabMethodName', String, nullable=False) - method_description = Column('LabMethodDescription', String, nullable=False) - method_link = Column('LabMethodLink', String) - - def __repr__(self): - return "" % (self.id, self.name, self.organization, self.method_name) \ No newline at end of file diff --git a/odmtools/odmdata/memory_database.py b/odmtools/odmdata/memory_database.py index 2ae1763..b10d40a 100644 --- a/odmtools/odmdata/memory_database.py +++ b/odmtools/odmdata/memory_database.py @@ -1,12 +1,12 @@ -import timeit import logging + +from sqlalchemy import bindparam + from odmtools.common.logger import LoggerTool from odmtools.odmservices import SeriesService -from odmtools.odmdata import DataValue -from sqlalchemy import update, bindparam -from odmtools.common.taskServer import TaskServerMP -from multiprocessing import cpu_count, freeze_support - +from odmtools.odmservices import ServiceManager +from odmtools.odmdata import SeriesService#ODM +ODM = SeriesService.ODM # tool = LoggerTool() # logger = tool.setupLogger(__name__, __name__ + '.log', 'w', logging.DEBUG) logger =logging.getLogger('main') @@ -22,7 +22,9 @@ def __init__(self, taskserver=None): # Series_Service handles remote database self.series_service = None # Memory_service handles in memory database - self.mem_service = SeriesService("sqlite:///:memory:") + sm = ServiceManager() + self.mem_service = sm.get_series_service(conn_string="sqlite:///:memory:") + # TODO clean up closing of program # if taskserver is None: #numproc = cpu_count() @@ -32,12 +34,15 @@ def __init__(self, taskserver=None): self.taskserver = taskserver def reset_edit(self): - self.mem_service = SeriesService("sqlite:///:memory:") + sm = ServiceManager() + self.mem_service = sm.get_series_service(conn_string="sqlite:///:memory:") + def set_series_service(self, service): self.series_service = service + ############## # DB Queries ############## @@ -83,10 +88,10 @@ def getEditDataValuesforGraph(self): return self.mem_service.get_all_plot_values() def commit(self): - self.mem_service._edit_session.commit() + self.mem_service._session.commit() def rollback(self): - self.mem_service._edit_session.rollback() + self.mem_service._session.rollback() # self.mem_service._session_factory.engine.connect().connection.rollback() #self.updateDF() @@ -100,12 +105,12 @@ def update(self, updates): updates : list of dictionary that contains 2 items, id and value ''' - stmt = (DataValue.__table__.update(). - where(DataValue.local_date_time == bindparam('id')). + stmt = (ODM.DataValue.__table__.update(). + where(ODM.DataValue.local_date_time == bindparam('id')). values(DataValue=bindparam('value')) ) - self.mem_service._edit_session.execute(stmt, updates) + self.mem_service._session.execute(stmt, updates) # self.updateDF() @@ -113,11 +118,11 @@ def update(self, updates): def updateValue(self, ids, operator, value): # query = DataValue.data_value+value if operator == '+': - query = DataValue.data_value + value + query = ODM.DataValue.data_value + value elif operator == '-': - query = DataValue.data_value - value + query = ODM.DataValue.data_value - value elif operator == '*': - query = DataValue.data_value * value + query = ODM.DataValue.data_value * value elif operator == '=': query = value @@ -125,8 +130,8 @@ def updateValue(self, ids, operator, value): #break into chunks to get around sqlites restriction. allowing user to send in only 999 arguments at once chunks=self.chunking(ids) for c in chunks: - q=self.mem_service._edit_session.query(DataValue).filter(DataValue.local_date_time.in_(c)) - q.update({DataValue.data_value: query}, False) + q=self.mem_service._session.query(ODM.DataValue).filter(ODM.DataValue.local_date_time.in_(c)) + q.update({ODM.DataValue.data_value: query}, False) #self.updateDF() @@ -141,8 +146,8 @@ def chunking(self, data): def updateFlag(self, ids, value): chunks=self.chunking(ids) for c in chunks: - self.mem_service._edit_session.query(DataValue).filter(DataValue.local_date_time.in_(c))\ - .update({DataValue.qualifier_id: value}, False) + self.mem_service._session.query(ODM.DataValue).filter(ODM.DataValue.local_date_time.in_(c))\ + .update({ODM.DataValue.qualifier_id: value}, False) def delete(self, ids): @@ -156,7 +161,7 @@ def addPoints(self, points): """ Takes in a list of points and loads each point into the database """ - stmt = DataValue.__table__.insert() + stmt = ODM.DataValue.__table__.insert() if not isinstance(points, list): points = [points] @@ -170,7 +175,7 @@ def addPoints(self, points): "SiteID": point[10], "VariableID": point[11], "MethodID": point[12], "SourceID": point[13], "QualityControlLevelID": point[14]} - self.mem_service._edit_session.execute(stmt, vals) + self.mem_service._session.execute(stmt, vals) def stopEdit(self): @@ -193,6 +198,8 @@ def updateDF(self): else: ''' self.df = self.mem_service.get_all_values_df() + print self.mem_service._version + def initEditValues(self, seriesID): """ @@ -213,12 +220,13 @@ def initEditValues(self, seriesID): # self.conn = results["InitEditValues"] else: ''' #TODO: Thread this call - if len(self.df)>0: + if self.df is not None and len(self.df)<=0: + logger.debug("no data in series") + else: + self.df.to_sql(name="DataValues", if_exists='replace', con=self.mem_service._session_factory.engine, index=False)#,flavor='sqlite', chunksize=10000) logger.debug("done loading database") - else: - logger.debug("no data in series") def changeSeriesIDs(self, var=None, qcl=None, method=None): """ @@ -229,17 +237,17 @@ def changeSeriesIDs(self, var=None, qcl=None, method=None): :return: """ - query = self.mem_service._edit_session.query(DataValue) + query = self.mem_service._session.query(ODM.DataValue) if var is not None: logger.debug(var) - query.update({DataValue.variable_id: var}) + query.update({ODM.DataValue.variable_id: var}) if method is not None: logger.debug(method) - query.update({DataValue.method_id: method}) + query.update({ODM.DataValue.method_id: method}) # check that the code is not zero # if qcl is not None and qcl.code != 0: if qcl is not None: logger.debug(qcl) - query.update({DataValue.quality_control_level_id: qcl}) + query.update({ODM.DataValue.quality_control_level_id: qcl}) diff --git a/odmtools/odmdata/method.py b/odmtools/odmdata/method.py deleted file mode 100644 index f3b9d8f..0000000 --- a/odmtools/odmdata/method.py +++ /dev/null @@ -1,12 +0,0 @@ -from sqlalchemy import Column, Integer, String -from base import Base - -class Method(Base): - __tablename__ = 'Methods' - - id = Column('MethodID', Integer, primary_key=True) - description = Column('MethodDescription', String, nullable=False) - link = Column('MethodLink', String) - - def __repr__(self): - return "" % (self.id, self.description, self.link) \ No newline at end of file diff --git a/odmtools/odmdata/odm_version.py b/odmtools/odmdata/odm_version.py deleted file mode 100644 index 3fe4420..0000000 --- a/odmtools/odmdata/odm_version.py +++ /dev/null @@ -1,10 +0,0 @@ -from sqlalchemy import String, Column -from base import Base - -class ODMVersion(Base): - __tablename__ = 'ODMVersion' - - version_number = Column('VersionNumber', String, primary_key=True) - - def __repr__(self): - return "" % (self.version_number) \ No newline at end of file diff --git a/odmtools/odmdata/offset_type.py b/odmtools/odmdata/offset_type.py deleted file mode 100644 index f1fc6ca..0000000 --- a/odmtools/odmdata/offset_type.py +++ /dev/null @@ -1,17 +0,0 @@ -from sqlalchemy import Column, Integer, ForeignKey, String -from sqlalchemy.orm import relationship -from base import Base -from unit import Unit - -class OffsetType(Base): - __tablename__ = 'OffsetTypes' - - id = Column('OffsetTypeID', Integer, primary_key=True) - unit_id = Column('OffsetUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - description = Column('OffsetDescription', String) - - # relationships - unit = relationship(Unit) - - def __repr__(self): - return "" % (self.id, self.unit_id, self.description) \ No newline at end of file diff --git a/odmtools/odmdata/qualifier.py b/odmtools/odmdata/qualifier.py deleted file mode 100644 index 052febb..0000000 --- a/odmtools/odmdata/qualifier.py +++ /dev/null @@ -1,12 +0,0 @@ -from sqlalchemy import Column, String, Integer -from base import Base - -class Qualifier(Base): - __tablename__ = 'Qualifiers' - - id = Column('QualifierID', Integer, primary_key=True) - code = Column('QualifierCode', String, nullable=False) - description = Column('QualifierDescription', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.description) \ No newline at end of file diff --git a/odmtools/odmdata/quality_control_level.py b/odmtools/odmdata/quality_control_level.py deleted file mode 100644 index 5e3c226..0000000 --- a/odmtools/odmdata/quality_control_level.py +++ /dev/null @@ -1,13 +0,0 @@ -from sqlalchemy import Column, String, Integer -from base import Base - -class QualityControlLevel(Base): - __tablename__ = 'QualityControlLevels' - - id = Column('QualityControlLevelID', Integer, primary_key=True) - code = Column('QualityControlLevelCode', String, nullable=False) - definition = Column('Definition', String, nullable=False) - explanation = Column('Explanation', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.definition, self.explanation) \ No newline at end of file diff --git a/odmtools/odmdata/sample.py b/odmtools/odmdata/sample.py deleted file mode 100644 index 9d18b33..0000000 --- a/odmtools/odmdata/sample.py +++ /dev/null @@ -1,18 +0,0 @@ -from sqlalchemy import Column, Integer, String, ForeignKey -from sqlalchemy.orm import relationship -from base import Base -from lab_method import LabMethod - -class Sample(Base): - __tablename__ = 'Samples' - - id = Column('SampleID', Integer, primary_key=True) - type = Column('SampleType', String, nullable=False) - lab_sample_code = Column('LabSampleCode', String, nullable=False) - lab_method_id = Column('LabMethodID', Integer, ForeignKey('LabMethods.LabMethodID'), nullable=False) - - # relationships - lab_method = relationship(LabMethod) - - def __repr__(self): - return "" % (self.id, self.type, self.lab_sample_code, self.lab_method_id) \ No newline at end of file diff --git a/odmtools/odmdata/sample_medium_cv.py b/odmtools/odmdata/sample_medium_cv.py deleted file mode 100644 index 277f2bd..0000000 --- a/odmtools/odmdata/sample_medium_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class SampleMediumCV(Base): - __tablename__ = 'SampleMediumCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/sample_type_cv.py b/odmtools/odmdata/sample_type_cv.py deleted file mode 100644 index caaf4c0..0000000 --- a/odmtools/odmdata/sample_type_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class SampleTypeCV(Base): - __tablename__ = 'SampleTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/session_factory.py b/odmtools/odmdata/session_factory.py deleted file mode 100644 index 0d2d488..0000000 --- a/odmtools/odmdata/session_factory.py +++ /dev/null @@ -1,57 +0,0 @@ -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker - - -class SessionFactory(): - def __init__(self, connection_string, echo): - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - pool_size=20) - self.psql_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - connect_args={'connect_timeout': 1}) - self.ms_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - connect_args={'timeout': 1}) - self.my_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - connect_args={'connect_timeout': 1}) - - ''' - # Removing pool_timeout and max_overflow allowed the tests to pass - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - pool_timeout=5, pool_size=20, max_overflow=0) - self.psql_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - pool_timeout=5, max_overflow=0, connect_args={'connect_timeout': 1}) - self.ms_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - pool_timeout=5, max_overflow=0, connect_args={'timeout': 1}) - self.my_test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, - pool_timeout=5, max_overflow=0, connect_args={'connect_timeout': 1}) - ''' - - ''' - # Old code - class SessionFactory(): - def __init__(self, connection_string, echo): - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, - #pool_size=20, - pool_recycle=3600) - - # Create session maker - self.Session = sessionmaker(bind=self.engine) - - def get_session(self): - return self.Session() - - def __repr__(self): - return "" % (self.engine) - ''' - - # Create session maker - self.Session = sessionmaker(bind=self.engine) - self.psql_test_Session = sessionmaker(bind=self.psql_test_engine) - self.ms_test_Session = sessionmaker(bind=self.ms_test_engine) - self.my_test_Session = sessionmaker(bind=self.my_test_engine) - - def get_session(self): - return self.Session() - - def __repr__(self): - return "" % (self.engine) - diff --git a/odmtools/odmdata/site.py b/odmtools/odmdata/site.py deleted file mode 100644 index c92998a..0000000 --- a/odmtools/odmdata/site.py +++ /dev/null @@ -1,37 +0,0 @@ -# Declare a mapped class -from sqlalchemy import Column, Integer, String, Float, ForeignKey -from sqlalchemy.orm import relationship -from base import Base -from spatial_reference import SpatialReference - -class Site(Base): - __tablename__ = 'Sites' - - id = Column('SiteID', Integer, primary_key=True) - code = Column('SiteCode', String) - name = Column('SiteName', String) - latitude = Column('Latitude', Float) - longitude = Column('Longitude', Float) - lat_long_datum_id = Column('LatLongDatumID', Integer, ForeignKey('SpatialReferences.SpatialReferenceID')) - elevation_m = Column('Elevation_m', Float) - vertical_datum_id = Column('VerticalDatum', Integer) - local_x = Column('LocalX', Float) - local_y = Column('LocalY', Float) - local_projection_id = Column('LocalProjectionID', Integer, ForeignKey('SpatialReferences.SpatialReferenceID')) - pos_accuracy_m = Column('PosAccuracy_m', Float) - state = Column('State', String) - county = Column('County', String) - comments = Column('Comments', String) - - type = Column('SiteType', String) - - # relationships - spatial_ref = relationship(SpatialReference, primaryjoin=("SpatialReference.id==Site.lat_long_datum_id")) - local_spatial_ref = relationship(SpatialReference, primaryjoin=("SpatialReference.id==Site.local_projection_id")) - - def __init__(self, site_code, site_name): - self.code = site_code - self.name = site_name - - def __repr__(self): - return "" % (self.code, self.name) \ No newline at end of file diff --git a/odmtools/odmdata/site_type_cv.py b/odmtools/odmdata/site_type_cv.py deleted file mode 100644 index fc41c7e..0000000 --- a/odmtools/odmdata/site_type_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class SiteTypeCV(Base): - __tablename__ = 'SiteTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/source.py b/odmtools/odmdata/source.py deleted file mode 100644 index 08452cc..0000000 --- a/odmtools/odmdata/source.py +++ /dev/null @@ -1,27 +0,0 @@ -from sqlalchemy import Column, String, Integer, ForeignKey -from sqlalchemy.orm import relationship -from base import Base -from iso_metadata import ISOMetadata - -class Source(Base): - __tablename__ = 'Sources' - - id = Column('SourceID', Integer, primary_key=True) - organization = Column('Organization', String, nullable=False) - description = Column('SourceDescription', String, nullable=False) - link = Column('SourceLink', String) - contact_name = Column('ContactName', String, nullable=False) - phone = Column('Phone', String, nullable=False) - email = Column('Email', String, nullable=False) - address = Column('Address', String, nullable=False) - city = Column('City', String, nullable=False) - state = Column('State', String, nullable=False) - zip_code = Column('ZipCode', String, nullable=False) - citation = Column('Citation', String, nullable=False) - iso_metadata_id = Column('MetadataID', Integer, ForeignKey('ISOMetadata.MetadataID'), nullable=False) - - # relationships - iso_metadata = relationship(ISOMetadata) - - def __repr__(self): - return "" % (self.id, self.organization, self.description) \ No newline at end of file diff --git a/odmtools/odmdata/spatial_reference.py b/odmtools/odmdata/spatial_reference.py deleted file mode 100644 index 2b63f39..0000000 --- a/odmtools/odmdata/spatial_reference.py +++ /dev/null @@ -1,14 +0,0 @@ -from sqlalchemy import Column, Integer, String, Boolean -from base import Base - -class SpatialReference(Base): - __tablename__ = 'SpatialReferences' - - id = Column('SpatialReferenceID', Integer, primary_key=True) - srs_id = Column('SRSID', Integer) - srs_name = Column('SRSName', String) - is_geographic = Column('IsGeographic', Boolean) - notes = Column('Notes', String) - - def __repr__(self): - return "" % (self.id, self.srs_name) \ No newline at end of file diff --git a/odmtools/odmdata/speciation_cv.py b/odmtools/odmdata/speciation_cv.py deleted file mode 100644 index 7d6c19f..0000000 --- a/odmtools/odmdata/speciation_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class SpeciationCV(Base): - __tablename__ = 'SpeciationCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/topic_category_cv.py b/odmtools/odmdata/topic_category_cv.py deleted file mode 100644 index 54f65c5..0000000 --- a/odmtools/odmdata/topic_category_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class TopicCategoryCV(Base): - __tablename__ = 'TopicCategoryCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/unit.py b/odmtools/odmdata/unit.py deleted file mode 100644 index 853da31..0000000 --- a/odmtools/odmdata/unit.py +++ /dev/null @@ -1,13 +0,0 @@ -from sqlalchemy import Column, Integer, String, Unicode -from base import Base - -class Unit(Base): - __tablename__ = 'Units' - - id = Column('UnitsID', Integer, primary_key=True) - name = Column('UnitsName', String) - type = Column('UnitsType', String) - abbreviation = Column('UnitsAbbreviation', String)#(convert_unicode=True)) - - def __repr__(self): - return "" % (self.id, self.name, self.type) \ No newline at end of file diff --git a/odmtools/odmdata/value_type_cv.py b/odmtools/odmdata/value_type_cv.py deleted file mode 100644 index 1a19d8a..0000000 --- a/odmtools/odmdata/value_type_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class ValueTypeCV(Base): - __tablename__ = 'ValueTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/variable.py b/odmtools/odmdata/variable.py deleted file mode 100644 index 77d8109..0000000 --- a/odmtools/odmdata/variable.py +++ /dev/null @@ -1,28 +0,0 @@ -from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, Float -from sqlalchemy.orm import relationship -from base import Base -from unit import Unit - -class Variable(Base): - __tablename__ = 'Variables' - - id = Column('VariableID', Integer, primary_key=True) - code = Column('VariableCode', String, nullable=False) - name = Column('VariableName', String, nullable=False) - speciation = Column('Speciation', String, nullable=False) - variable_unit_id = Column('VariableUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - sample_medium = Column('SampleMedium', String, nullable=False) - value_type = Column('ValueType', String, nullable=False) - is_regular = Column('IsRegular', Boolean, nullable=False) - time_support = Column('TimeSupport', Float, nullable=False) - time_unit_id = Column('TimeUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - data_type = Column('DataType', String, nullable=False) - general_category = Column('GeneralCategory', String, nullable=False) - no_data_value = Column('NoDataValue', Float, nullable=False) - - # relationships - variable_unit = relationship(Unit, primaryjoin=("Unit.id==Variable.variable_unit_id")) # <-- Uses class attribute names, not table column names - time_unit = relationship(Unit, primaryjoin=("Unit.id==Variable.time_unit_id")) - - def __repr__(self): - return "" % (self.id, self.code, self.name) \ No newline at end of file diff --git a/odmtools/odmdata/variable_name_cv.py b/odmtools/odmdata/variable_name_cv.py deleted file mode 100644 index 0b64596..0000000 --- a/odmtools/odmdata/variable_name_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class VariableNameCV(Base): - __tablename__ = 'VariableNameCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmdata/vertical_datum_cv.py b/odmtools/odmdata/vertical_datum_cv.py deleted file mode 100644 index b161b29..0000000 --- a/odmtools/odmdata/vertical_datum_cv.py +++ /dev/null @@ -1,11 +0,0 @@ -from sqlalchemy import Column, String -from base import Base - -class VerticalDatumCV(Base): - __tablename__ = 'VerticalDatumCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) \ No newline at end of file diff --git a/odmtools/odmservices/__init__.py b/odmtools/odmservices/__init__.py index 6d161f5..f15d43f 100644 --- a/odmtools/odmservices/__init__.py +++ b/odmtools/odmservices/__init__.py @@ -1,17 +1,20 @@ -from service_manager import ServiceManager -from series_service import SeriesService -from cv_service import CVService -from edit_service import EditService -from export_service import ExportService +# from service_manager import ServiceManager +# from series_service import SeriesService +# from cv_service import CVService +# from edit_service import EditService +# from export_service import ExportService +# +# # need to explicitly import these for pyinstaller +# import pymysql +# import pyodbc +# #import psycopg2 -# need to explicitly import these for pyinstaller -import pymysql -import pyodbc -#import psycopg2 +from odm2api.ODM1_1_1.services import SeriesService, EditService, ExportService#, , CVService, +from service_manager import ServiceManager __all__ = [ 'EditService', - 'CVService', + #'CVService', 'SeriesService', 'ExportService', 'ServiceManager', diff --git a/odmtools/odmservices/export_service.py b/odmtools/odmservices/export_service.py deleted file mode 100644 index 4b6d1eb..0000000 --- a/odmtools/odmservices/export_service.py +++ /dev/null @@ -1,401 +0,0 @@ -import csv -import xml.etree.cElementTree as ET -import datetime - - -class ExportService(): - ''' - Create with the Service Manager!!! - ''' - - def __init__(self, series_service): - self._series_service = series_service - self.dt_format_str = "%m/%d/%Y %I:%M:%S %p" - - def export_series_data(self, series_id, filename, utc=False, site=False, var=False, offset=False, qual=False, - src=False, qcl=False): - series = self._series_service.get_series_by_id(series_id) - if series is None: - return False - - writer = csv.writer(open(filename, 'wb')) - print "filename: ", filename - self.write_data_header(writer, utc, site, var, offset, qual, src, qcl) - for dv in series.data_values: - self.write_data_row(writer, series, dv, utc, site, var, offset, qual, src, qcl) - - def write_data_row(self, writer, series, dv, utc, site, var, offset, qual, src, qcl): - data = [] - data.append(series.id) - data.append(dv.id) - data.append(dv.data_value) - data.append(dv.value_accuracy) - data.append(dv.local_date_time) - if utc: - data.append(dv.utc_offset) - data.append(dv.date_time_utc) - data.append(series.site_code) - if site: - data.append(series.site_name) - data.append(series.site.type) - data.append(series.site.latitude) - data.append(series.site.longitude) - data.append(series.site.spatial_ref.srs_name) - data.append(series.variable_code) - if var: - data.append(series.variable_name) - data.append(series.speciation) - data.append(series.variable_units_name) - data.append(series.variable.variable_unit.abbreviation) - data.append(series.sample_medium) - data.append(dv.offset_value) - data.append(dv.offset_type_id) - if offset: - if dv.offset_type is not None: - data.append(dv.offset_type.description) - data.append(dv.offset_type.unit.name) - else: - data.append('') - data.append('') - data.append(dv.censor_code) - data.append(dv.qualifier_id) - if qual: - if dv.qualifier is not None: - data.append(dv.qualifier.code) - data.append(dv.qualifier.description) - else: - data.append('') - data.append('') - if src: - data.append(series.organization) - data.append(series.source_description) - data.append(series.citation) - if qcl: - data.append(series.quality_control_level_code) - data.append(series.quality_control_level.definition) - data.append(series.quality_control_level.explanation) - data.append(dv.sample_id) - - writer.writerow(data) - - def write_data_header(self, writer, utc, site, var, offset, qual, src, qcl): - # Build header list - header = [] - header.append("SeriesId") - header.append("ValueId") - header.append("DataValue") - header.append("ValueAccuracy") - header.append("LocalDateTime") - if utc: - header.append("UTCOffset") - header.append("DateTimeUTC") - header.append("SiteCode") - if site: - header.append("SiteName") - header.append("SiteType") - header.append("Latitude") - header.append("Longitude") - header.append("SRSName") - header.append("VariableCode") - if var: - header.append("VariableName") - header.append("Speciation") - header.append("VariableUnitsName") - header.append("VariableUnitsAbbreviation") - header.append("SampleMedium") - header.append("OffsetValue") - header.append("OffsetTypeID") - if offset: - header.append("OffsetDescription") - header.append("OffsetUnitsName") - header.append("CensorCode") - header.append("QualifierID") - if qual: - header.append("QualifierCode") - header.append("QualifierDescription") - if src: - header.append("Organization") - header.append("SourceDescription") - header.append("Citation") - if qcl: - header.append("QualityControlLevelCode") - header.append("Definition") - header.append("Explanation") - header.append("SampleID") - - writer.writerow(header) - - def export_series_metadata(self, series_ids, filename): - if series_ids is None: - return - - root = ET.Element("Metadata") - list_root = ET.SubElement(root, "DataSeriesList") - list_root.set("Total", str(series_ids)) - - try: - with open(filename): - file_exists = True - except IOError: - file_exists = False - - if file_exists: - # Read the file into the XML tree - pass - - if isinstance(series_ids, int): - series = self._series_service.get_series_by_id(series_ids) - self.append_series_node(series, list_root) - else: - for series_id in series_ids: - series = self._series_service.get_series_by_id(series_id) - self.append_series_node(series, list_root) - - tree = ET.ElementTree(root) - tree.write(filename) - - def append_series_node(self, series, parent): - series_node = ET.SubElement(parent, "DataSeries") - series_node.set("ID", str(series.id)) - self.append_general_info(series, series_node) - self.append_site_info(series, series_node) - self.append_var_info(series, series_node) - self.append_method_source_info(series, series_node) - self.append_misc_info(series, series_node) - - return series_node - - def append_general_info(self, series, parent): - meta = series.source.iso_metadata - general_node = ET.SubElement(parent, "GeneralInformation") - topic = ET.SubElement(general_node, "TopicCategory") - topic.text = meta.topic_category - title = ET.SubElement(general_node, "Title") - title.text = meta.title - abstract = ET.SubElement(general_node, "Abstract") - abstract.text = meta.abstract - prof_version = ET.SubElement(general_node, "ProfileVersion") - prof_version.text = meta.profile_version - metadata_link = ET.SubElement(general_node, "MetadataLink") - metadata_link.text = meta.metadata_link - date = ET.SubElement(general_node, "MetadataCreationDate") - # 7/1/2013 12:17:16 PM - date.text = datetime.datetime.now().strftime(self.dt_format_str) - - def append_site_info(self, series, parent): - site = series.site - site_node = ET.SubElement(parent, "SiteInformation") - site_code = ET.SubElement(site_node, "SiteCode") - site_code.text = site.code - site_name = ET.SubElement(site_node, "SiteName") - site_name.text = site.name - site_type = ET.SubElement(site_node, "SiteType") - site_type.text = site.type - - geo_coords = ET.SubElement(site_node, "GeographicCoordinates") - latitude = ET.SubElement(geo_coords, "Latitude") - latitude.text = str(site.latitude) - longitude = ET.SubElement(geo_coords, "Longitude") - longitude.text = str(site.longitude) - srs_id = ET.SubElement(geo_coords, "SRSID") - srs_id.text = str(site.spatial_ref.srs_id) - srs_name = ET.SubElement(geo_coords, "SRSName") - srs_name.text = site.spatial_ref.srs_name - is_geo = ET.SubElement(geo_coords, "IsGeographic") - is_geo.text = str(site.spatial_ref.is_geographic) - notes = ET.SubElement(geo_coords, "Notes") - notes.text = site.spatial_ref.notes - - local_coords = ET.SubElement(site_node, "LocalCoordinates") - local_x = ET.SubElement(local_coords, "LocalX") - local_x.text = str(site.local_x) - local_y = ET.SubElement(local_coords, "LocalY") - local_y.text = str(site.local_y) - local_srs_id = ET.SubElement(local_coords, "SRSID") - local_srs_id.text = str(site.local_spatial_ref.srs_id) - local_srs_name = ET.SubElement(local_coords, "SRSName") - local_srs_name.text = site.local_spatial_ref.srs_name - local_is_geo = ET.SubElement(local_coords, "IsGeographic") - local_is_geo.text = str(site.local_spatial_ref.is_geographic) - local_notes = ET.SubElement(local_coords, "Notes") - local_notes.text = site.local_spatial_ref.notes - elevation = ET.SubElement(local_coords, "Elevation_m") - if site.elevation_m: elevation.text = str(site.elevation_m) - vert_datum = ET.SubElement(local_coords, "VerticalDatum") - if site.vertical_datum_id: vert_datum.text = str(site.vertical_datum_id) - - pos_accuracy = ET.SubElement(site_node, "PosAccuracy_m") - pos_accuracy.text = str(site.pos_accuracy_m) - state = ET.SubElement(site_node, "State") - state.text = site.state - county = ET.SubElement(site_node, "County") - county.text = site.county - comments = ET.SubElement(site_node, "Comments") - comments.text = site.comments - - def append_var_info(self, series, parent): - variable = series.variable - var_node = ET.SubElement(parent, "VariableInformation") - - var_code = ET.SubElement(var_node, "VariableCode") - var_code.text = variable.code - var_name = ET.SubElement(var_node, "VariableName") - var_name.text = variable.name - speciation = ET.SubElement(var_node, "Speciation") - speciation.text = variable.speciation - - var_units = ET.SubElement(var_node, "VariableUnits") - units_name = ET.SubElement(var_units, "UnitsName") - units_name.text = variable.variable_unit.name - units_type = ET.SubElement(var_units, "UnitsType") - units_type.text = variable.variable_unit.type - units_abbrev = ET.SubElement(var_units, "UnitsAbbreviation") - units_abbrev.text = variable.variable_unit.abbreviation - - sample_medium = ET.SubElement(var_node, "SampleMedium") - sample_medium.text = variable.sample_medium - val_type = ET.SubElement(var_node, "ValueType") - val_type.text = variable.value_type - is_reg = ET.SubElement(var_node, "IsRegular") - is_reg.text = str(variable.is_regular) - time_support = ET.SubElement(var_node, "TimeSupport") - time_support.text = str(variable.time_support) - - time_support_units = ET.SubElement(var_node, "TimeSupportUnits") - ts_units_name = ET.SubElement(time_support_units, "UnitsName") - ts_units_name.text = variable.time_unit.name - ts_units_type = ET.SubElement(time_support_units, "UnitsType") - ts_units_type.text = variable.time_unit.type - ts_units_abbrev = ET.SubElement(time_support_units, "UnitsAbbreviation") - ts_units_abbrev.text = variable.time_unit.abbreviation - - data_type = ET.SubElement(var_node, "DataType") - data_type.text = variable.data_type - gen_cat = ET.SubElement(var_node, "GeneralCategory") - gen_cat.text = variable.general_category - no_dv = ET.SubElement(var_node, "NoDataValue") - no_dv.text = str(variable.no_data_value) - - period = ET.SubElement(var_node, "PeriodOfRecord") - begin_dt = ET.SubElement(period, "BeginDateTime") - begin_dt.text = series.begin_date_time.strftime(self.dt_format_str) - end_dt = ET.SubElement(period, "EndDateTime") - end_dt.text = series.end_date_time.strftime(self.dt_format_str) - begin_dt_utc = ET.SubElement(period, "BeginDateTimeUTC") - begin_dt_utc.text = series.begin_date_time_utc.strftime(self.dt_format_str) - end_dt_utc = ET.SubElement(period, "EndDateTimeUTC") - end_dt_utc.text = series.end_date_time_utc.strftime(self.dt_format_str) - value_count = ET.SubElement(period, "ValueCount") - value_count.text = str(series.value_count) - - def append_method_source_info(self, series, parent): - method = series.method - method_node = ET.SubElement(parent, "MethodInformation") - method_desc = ET.SubElement(method_node, "MethodDescription") - method_desc.text = method.description - method_link = ET.SubElement(method_node, "MethodLink") - method_link.text = method.link - - source = series.source - source_node = ET.SubElement(parent, "SourceInformation") - org = ET.SubElement(source_node, "Organization") - org.text = source.organization - source_desc = ET.SubElement(source_node, "SourceDescription") - source_desc.text = source.description - source_link = ET.SubElement(source_node, "SourceLink") - source_link.text = source.link - - contact = ET.SubElement(source_node, "Contact") - contact_name = ET.SubElement(contact, "ContactName") - contact_name.text = source.contact_name - phone = ET.SubElement(contact, "Phone") - phone.text = source.phone - email = ET.SubElement(contact, "Email") - email.text = source.email - address = ET.SubElement(contact, "Address") - address.text = source.address - city = ET.SubElement(contact, "City") - city.text = source.city - state = ET.SubElement(contact, "State") - state.text = source.state - zip_code = ET.SubElement(contact, "ZipCode") - zip_code.text = source.zip_code - - citation = ET.SubElement(source_node, "Citation") - citation.text = source.citation - - def append_misc_info(self, series, parent): - qcl = series.quality_control_level - - qcl_node = ET.SubElement(parent, "QualityControlLevelInformation") - qcl_code = ET.SubElement(qcl_node, "QualityControlLevelCode") - qcl_code.text = qcl.code - qcl_def = ET.SubElement(qcl_node, "Definition") - qcl_def.text = qcl.definition - qcl_expl = ET.SubElement(qcl_node, "Explanation") - qcl_expl.text = qcl.explanation - - offsets_node = ET.SubElement(parent, "OffsetInformation") - offsets = self._series_service.get_offset_types_by_series_id(series.id) - for offset in offsets: - offset_id = ET.SubElement(offsets_node, "Offset") - if offset: - offset_id.set("ID", str(offset.id)) - else: - offset_id.set("ID", "") - offset_desc = ET.SubElement(offsets_node, "OffsetDescription") - if offset: offset_desc.text = offset.description - offset_units = ET.SubElement(offsets_node, "OffsetUnits") - units_name = ET.SubElement(offset_units, "UnitsName") - if offset: units_name.text = offset.unit.name - units_type = ET.SubElement(offset_units, "UnitsType") - if offset: units_type.text = offset.unit.type - units_abbrev = ET.SubElement(offset_units, "UnitsAbbreviation") - if offset: units_abbrev.text = offset.unit.abbreviation - - qualifiers_node = ET.SubElement(parent, "QualifierInformation") - qualifiers = self._series_service.get_qualifiers_by_series_id(series.id) - for qual in qualifiers: - qual_id = ET.SubElement(qualifiers_node, "Qualifier") - if qual: - qual_id.set("ID", str(qual.id)) - else: - qual_id.set("ID", "") - qual_code = ET.SubElement(qual_id, "QualiferCode") - if qual: qual_code.text = qual.code - qual_desc = ET.SubElement(qual_id, "QualifierDescription") - if qual: qual_desc.text = qual.description - - samples_node = ET.SubElement(parent, "SampleInformation") - samples = self._series_service.get_samples_by_series_id(series.id) - for sample in samples: - sample_id = ET.SubElement(samples_node, "Sample") - if sample: - sample_id.set("ID", str(sample.id)) - else: - sample_id.set("ID", "") - sample_type = ET.SubElement(sample_id, "SampleType") - if sample: sample_type.text = sample.type - lab_code = ET.SubElement(sample_id, "LabSampleCode") - if sample: lab_code.text = sample.lab_sample_code - lab_method_id = ET.SubElement(sample_id, "LabMethodID") - if sample: lab_method_id = sample.lab_method_id - - lab_method_node = ET.SubElement(parent, "LabMethodInformation") - for sample in samples: - if sample: lab_method = sample.lab_method - lab_method_id = ET.SubElement(lab_method_node, "LabMethod") - if lab_method: - lab_method_id.set("ID", str(lab_method.id)) - else: - lab_method_id.set("ID", "") - lab_name = ET.SubElement(lab_method_id, "LabName") - if lab_method: lab_name.text = lab_method.name - lab_org = ET.SubElement(lab_method_id, "LabOrganization") - if lab_method: lab_org.text = lab_method.organization - method_name = ET.SubElement(lab_method_id, "LabMethodName") - if lab_method: method_name.text = lab_method.method_name - method_desc = ET.SubElement(lab_method_id, "LabMethodDescription") - if lab_method: method_desc.text = lab_method.method_description - method_link = ET.SubElement(lab_method_id, "LabMethodLink") - if lab_method: method_link.text = lab_method.link \ No newline at end of file diff --git a/odmtools/odmservices/service_manager.py b/odmtools/odmservices/service_manager.py index 1ad5ff1..a190839 100755 --- a/odmtools/odmservices/service_manager.py +++ b/odmtools/odmservices/service_manager.py @@ -4,31 +4,30 @@ import urllib -from sqlalchemy.exc import SQLAlchemyError#OperationalError, DBAPIError - -from odmtools.common.logger import LoggerTool -from series_service import SeriesService -from cv_service import CVService -from edit_service import EditService +from sqlalchemy.exc import SQLAlchemyError +from odmtools.odmservices import SeriesService, EditService, ExportService from odmtools.controller import EditTools -from export_service import ExportService from odmtools.lib.Appdirs.appdirs import user_config_dir -from odmtools.odmdata.session_factory import SessionFactory +from odmtools.odmdata import SeriesService, dbconnection #ODM#, refreshDBSessionFactory, + + # tool = LoggerTool() # logger = tool.setupLogger(__name__, __name__ + '.log', 'w', logging.DEBUG) logger =logging.getLogger('main') + class ServiceManager(): def __init__(self, debug=False, conn_dict = None): self.debug = debug f = self._get_file('r') self._conn_dicts = [] - self.version = 0 + #self.version = 0 self._connection_format = "%s+%s://%s:%s@%s/%s" # Read all lines (connections) in the connection.cfg file + if conn_dict is None: while True: line = f.readline() @@ -46,10 +45,13 @@ def __init__(self, debug=False, conn_dict = None): line_dict['password'] = line[2] line_dict['address'] = line[3] line_dict['db'] = line[4] + line_dict['version']= float(line[5]) if len(line)>5 else 1.1 self._conn_dicts.append(line_dict) else: self._conn_dicts.append(conn_dict) + + if len(self._conn_dicts) is not 0: # The current connection defaults to the most recent (i.e. the last written to the file) self._current_conn_dict = self._conn_dicts[-1] @@ -61,18 +63,6 @@ def __init__(self, debug=False, conn_dict = None): def get_all_conn_dicts(self): return self._conn_dicts - def is_valid_connection(self): - if self._current_conn_dict: - conn_string = self._build_connection_string(self._current_conn_dict) - logger.debug("Conn_string: %s" % conn_string) - try: - if self.testEngine(conn_string): - return self.get_current_conn_dict() - except Exception as e: - logger.fatal("The previous database for some reason isn't accessible, please enter a new connection %s" % e.message) - return None - return None - def get_current_conn_dict(self): return self._current_conn_dict @@ -85,79 +75,73 @@ def add_connection(self, conn_dict): # remove earlier connections that are identical to this one self.delete_connection(conn_dict) - if self.test_connection(conn_dict): - # write changes to connection file - self._conn_dicts.append(conn_dict) - self._current_conn_dict = self._conn_dicts[-1] - self._save_connections() - return True - else: - logger.error("Unable to save connection due to invalid connection to database") - return False - - - @classmethod - def testEngine(self, connection_string): - s = SessionFactory(connection_string, echo=False) - if 'mssql' in connection_string: - s.ms_test_Session().execute("Select top 1 VariableCode From Variables") - elif 'mysql' in connection_string: - s.my_test_Session().execute('Select "VariableCode" From Variables Limit 1') - elif 'postgresql' in connection_string: - #s.psql_test_Session().execute('Select "VariableCode" From "ODM2"."Variables" Limit 1') - s.psql_test_Session().execute('Select "VariableCode" From "Variables" Limit 1') + #assume connection has already been tested + # if self.test_connection(conn_dict): + # write changes to connection file + self._conn_dicts.append(conn_dict) + self._current_conn_dict = self._conn_dicts[-1] + self._save_connections() return True + # else: + # logger.error("Unable to save connection due to invalid connection to database") + # return False + + def is_valid_connection(self): + + if self.get_current_conn_dict(): + #conn_string = self._build_connection_string(self._current_conn_dict) + #logger.debug("Conn_string: %s" % conn_string) + conn_dict = self.get_current_conn_dict() + try: + if dbconnection.isValidConnection(dbconnection.buildConnectionString(conn_dict['engine'], conn_dict['address'], conn_dict['db'], conn_dict['user'], + conn_dict['password']), dbtype = conn_dict['version']): + return self.get_current_conn_dict() + except Exception as e: + logger.fatal( + "The previous database for some reason isn't accessible, please enter a new connection %s" % e.message) + return None + return None - def test_connection(self, conn_dict): - try: - conn_string = self._build_connection_string(conn_dict) - if self.testEngine(conn_string) and self.get_db_version(conn_string) == '1.1.1': - return True - except SQLAlchemyError as e: - logger.error("SQLAlchemy Error: %s" % e.message) - raise e - except Exception as e: - logger.error("Error: %s" % e) - raise e - return False def delete_connection(self, conn_dict): self._conn_dicts[:] = [x for x in self._conn_dicts if x != conn_dict] - # Create and return services based on the currently active connection - def get_db_version_dict(self, conn_dict): - conn_string = self._build_connection_string(conn_dict) - self.get_db_version(conn_string) - def get_db_version(self, conn_string): - if isinstance(conn_string, dict): - conn_string = self._build_connection_string(conn_string) - service = SeriesService(conn_string) - #if not self.version: - try: - self.version = service.get_db_version() - except Exception as e: - logger.error("Exception: %s" % e.message) - return None - return self.version - - def get_series_service(self, conn_dict=""): - conn_string = "" - if conn_dict: - conn_string = self._build_connection_string(conn_dict) - self._current_conn_dict = conn_dict - else: - conn_string = self._build_connection_string(self._current_conn_dict) - return SeriesService(conn_string, self.debug) + def get_series_service(self, conn_dict=None, conn_string=""): + if not conn_dict: + conn_dict = self.get_current_conn_dict() - def get_cv_service(self): - conn_string = self._build_connection_string(self._current_conn_dict) - return CVService(conn_string, self.debug) + if conn_string: + #todo how to get version from a connection string + conn = dbconnection.createConnectionFromString(conn_string, float(self.get_current_conn_dict()["version"])) + else: + conn = dbconnection.createConnection(conn_dict['engine'], conn_dict['address'], conn_dict['db'], conn_dict['user'], + conn_dict['password'], conn_dict['version']) + + + # version = 1.1 + # if conn_dict: + # conn_string = self._build_connection_string(conn_dict) + # #self._current_conn_dict = conn_dict + # + # version = float(conn_dict['version']) + # elif not conn_dict and not conn_string: + # conn_string = self._build_connection_string(self._current_conn_dict) + # version = float(self._current_conn_dict['version']) + # + # sf = SessionFactory(conn_string, self.debug, version = version) + ss= SeriesService(conn) + ss.refreshDB(conn.version) + return ss + + # def get_cv_service(self): + # conn_string = self._build_connection_string(self._current_conn_dict) + # return CVService(SessionFactory(conn_string, self.debug)) def get_edit_service(self, series_id, connection): - return EditService(series_id, connection=connection, debug=self.debug) + def get_record_service(self, script, series_id, connection): return EditTools(self, script, self.get_edit_service(series_id, connection), self._build_connection_string(self.is_valid_connection())) @@ -186,64 +170,13 @@ def _get_file(self, mode): open(fn, 'w').close() config_file = open(fn, mode) - return config_file - - def _build_connection_string(self, conn_dict): - - self._connection_format = "%s+%s://%s:%s@%s/%s" - - if conn_dict['engine'] == 'mssql' and sys.platform != 'win32': - driver = "pyodbc" - quoted = urllib.quote_plus('DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;' % (conn_dict['address'], conn_dict['user'], - conn_dict['password'])) - # quoted = urllib.quote_plus('DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;DATABASE=%s' % - # (conn_dict['address'], conn_dict['user'], conn_dict['password'],conn_dict['db'], - # )) - conn_string = 'mssql+pyodbc:///?odbc_connect={}'.format(quoted) - - elif conn_dict['engine']=='sqlite': - connformat = "%s:///%s" - conn_string = connformat%(conn_dict['engine'], conn_dict['address']) - else: - if conn_dict['engine'] == 'mssql': - driver = "pyodbc" - conn = "%s+%s://%s:%s@%s/%s?driver=SQL+Server" - if "sqlncli11.dll" in os.listdir("C:\\Windows\\System32"): - conn = "%s+%s://%s:%s@%s/%s?driver=SQL+Server+Native+Client+11.0" - self._connection_format = conn - conn_string = self._connection_format % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['password'], conn_dict['address'], - conn_dict['db']) - elif conn_dict['engine'] == 'mysql': - driver = "pymysql" - conn_string = self.constringBuilder(conn_dict, driver) - elif conn_dict['engine'] == 'postgresql': - driver = "psycopg2" - conn_string = self.constringBuilder(conn_dict, driver) - else: - driver = "None" - conn_string = self.constringBuilder(conn_dict, driver) - - - # print "******", conn_string - return conn_string - + return config_file - def constringBuilder(self, conn_dict, driver): - if conn_dict['password'] is None or not conn_dict['password']: - conn_string = self._connection_format_nopassword % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['address'], - conn_dict['db']) - else: - conn_string = self._connection_format % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['password'], conn_dict['address'], - conn_dict['db']) - return conn_string def _save_connections(self): f = self._get_file('w') for conn in self._conn_dicts: - f.write("%s %s %s %s %s\n" % (conn['engine'], conn['user'], conn['password'], conn['address'], conn['db'])) + f.write("%s %s %s %s %s %s\n" % (conn['engine'], conn['user'], conn['password'], conn['address'], conn['db'], conn['version'])) f.close() diff --git a/odmtools/view/clsDBConfig.py b/odmtools/view/clsDBConfig.py index 4d2490e..3e6231b 100644 --- a/odmtools/view/clsDBConfig.py +++ b/odmtools/view/clsDBConfig.py @@ -1,4 +1,140 @@ -# -*- coding: utf-8 -*- +# # -*- coding: utf-8 -*- +# +# # ########################################################################## +# ## Python code generated with wxFormBuilder (version Jun 5 2014) +# ## http://www.wxformbuilder.org/ +# ## +# ## PLEASE DO "NOT" EDIT THIS FILE! +# ########################################################################### +# +# import wx +# import wx.xrc +# +# ########################################################################### +# ## Class clsDBConfiguration +# ########################################################################### +# +# class clsDBConfiguration(wx.Panel): +# def __init__(self, parent): +# +# wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 291), style=wx.SIMPLE_BORDER | wx.TAB_TRAVERSAL) +# +# self.SetMinSize(wx.Size(442, 291)) +# self.SetMaxSize(wx.Size(627, 291)) +# +# formSizer = wx.BoxSizer(wx.VERTICAL) +# +# sbSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, u"Database Connection"), wx.VERTICAL) +# +# connectionSizer = wx.FlexGridSizer(0, 2, 0, 15) +# connectionSizer.AddGrowableCol(1) +# connectionSizer.SetFlexibleDirection(wx.VERTICAL) +# connectionSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) +# +# self.stConnType = wx.StaticText(self, wx.ID_ANY, u"Connection Type:", wx.DefaultPosition, wx.DefaultSize, +# wx.ALIGN_RIGHT) +# self.stConnType.Wrap(-1) +# connectionSizer.Add(self.stConnType, 0, wx.ALL | wx.EXPAND, 5) +# +# cbDatabaseTypeChoices = [] +# self.cbDatabaseType = wx.ComboBox(self, wx.ID_ANY, u"Combo!", wx.DefaultPosition, wx.DefaultSize, +# cbDatabaseTypeChoices, wx.CB_READONLY) +# connectionSizer.Add(self.cbDatabaseType, 1, wx.ALL | wx.EXPAND, 5) +# +# self.stServer = wx.StaticText(self, wx.ID_ANY, u"Server:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) +# self.stServer.Wrap(-1) +# connectionSizer.Add(self.stServer, 0, wx.ALL | wx.EXPAND, 5) +# +# self.txtServer = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, +# 0 | wx.FULL_REPAINT_ON_RESIZE | wx.SIMPLE_BORDER) +# connectionSizer.Add(self.txtServer, 1, wx.ALL | wx.EXPAND, 5) +# +# self.stDBName = wx.StaticText(self, wx.ID_ANY, u"Database:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) +# self.stDBName.Wrap(-1) +# self.stDBName.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) +# +# connectionSizer.Add(self.stDBName, 0, wx.ALL | wx.EXPAND, 5) +# +# self.txtDBName = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, +# 0 | wx.SIMPLE_BORDER) +# connectionSizer.Add(self.txtDBName, 0, wx.ALL | wx.EXPAND, 5) +# +# self.stUser = wx.StaticText(self, wx.ID_ANY, u"User:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) +# self.stUser.Wrap(-1) +# self.stUser.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) +# +# connectionSizer.Add(self.stUser, 0, wx.ALL | wx.EXPAND, 5) +# +# self.txtUser = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, +# 0 | wx.SIMPLE_BORDER) +# connectionSizer.Add(self.txtUser, 0, wx.ALL | wx.EXPAND, 5) +# +# self.stPass = wx.StaticText(self, wx.ID_ANY, u"Password:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) +# self.stPass.Wrap(-1) +# self.stPass.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) +# +# connectionSizer.Add(self.stPass, 0, wx.ALL | wx.EXPAND, 5) +# +# self.txtPass = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, +# wx.TE_PASSWORD | wx.SIMPLE_BORDER) +# connectionSizer.Add(self.txtPass, 0, wx.ALL | wx.EXPAND, 5) +# +# sbSizer.Add(connectionSizer, 1, wx.EXPAND, 5) +# +# formSizer.Add(sbSizer, 1, wx.EXPAND, 20) +# +# btnSizer = wx.FlexGridSizer(0, 3, 0, 25) +# btnSizer.AddGrowableCol(0) +# btnSizer.AddGrowableCol(1) +# btnSizer.AddGrowableCol(2) +# btnSizer.SetFlexibleDirection(wx.VERTICAL) +# btnSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) +# +# self.btnTest = wx.Button(self, wx.ID_ANY, u"Test Connection", wx.DefaultPosition, wx.DefaultSize, 0) +# btnSizer.Add(self.btnTest, 0, wx.ALL | wx.EXPAND, 5) +# +# self.btnSave = wx.Button(self, wx.ID_ANY, u"Save Connection", wx.DefaultPosition, wx.DefaultSize, 0) +# self.btnSave.Enable(False) +# +# btnSizer.Add(self.btnSave, 0, wx.ALL | wx.EXPAND, 5) +# +# self.btnCancel = wx.Button(self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0) +# btnSizer.Add(self.btnCancel, 0, wx.ALL | wx.EXPAND, 5) +# +# formSizer.Add(btnSizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.SHAPED, 15) +# +# self.SetSizer(formSizer) +# self.Layout() +# +# # Connect Events +# self.cbDatabaseType.Bind(wx.EVT_COMBOBOX, self.OnValueChanged) +# self.txtServer.Bind(wx.EVT_TEXT, self.OnValueChanged) +# self.txtDBName.Bind(wx.EVT_TEXT, self.OnValueChanged) +# self.txtUser.Bind(wx.EVT_TEXT, self.OnValueChanged) +# self.txtPass.Bind(wx.EVT_TEXT, self.OnValueChanged) +# self.btnTest.Bind(wx.EVT_BUTTON, self.OnBtnTest) +# self.btnSave.Bind(wx.EVT_BUTTON, self.OnBtnSave) +# self.btnCancel.Bind(wx.EVT_BUTTON, self.OnBtnCancel) +# +# def __del__(self): +# pass +# +# +# # Virtual event handlers, overide them in your derived class +# def OnValueChanged(self, event): +# event.Skip() +# +# +# def OnBtnTest(self, event): +# event.Skip() +# +# def OnBtnSave(self, event): +# event.Skip() +# +# def OnBtnCancel(self, event): +# event.Skip() +# +# -*- coding: utf-8 -*- # ########################################################################## ## Python code generated with wxFormBuilder (version Jun 5 2014) @@ -16,7 +152,6 @@ class clsDBConfiguration(wx.Panel): def __init__(self, parent): - wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 291), style=wx.SIMPLE_BORDER | wx.TAB_TRAVERSAL) @@ -32,19 +167,30 @@ def __init__(self, parent): connectionSizer.SetFlexibleDirection(wx.VERTICAL) connectionSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) + self.stVersion = wx.StaticText(self, wx.ID_ANY, u"DB Version:", wx.DefaultPosition, wx.DefaultSize, + wx.ALIGN_RIGHT) + self.stVersion.Wrap(-1) + connectionSizer.Add(self.stVersion, 0, wx.ALL | wx.ALIGN_RIGHT | wx.EXPAND, 5) + + version_choices = [ u"1.1", u"2.0"] + self.cbVersion = wx.ComboBox(self, wx.ID_ANY, u"1.1", wx.DefaultPosition, wx.DefaultSize, + version_choices, wx.CB_READONLY )#| wx.CB_SORT) + self.cbVersion.SetSelection(0) + connectionSizer.Add(self.cbVersion, 1, wx.ALL | wx.EXPAND, 5) + self.stConnType = wx.StaticText(self, wx.ID_ANY, u"Connection Type:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) self.stConnType.Wrap(-1) - connectionSizer.Add(self.stConnType, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.stConnType, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) cbDatabaseTypeChoices = [] - self.cbDatabaseType = wx.ComboBox(self, wx.ID_ANY, u"Combo!", wx.DefaultPosition, wx.DefaultSize, - cbDatabaseTypeChoices, wx.CB_READONLY) + self.cbDatabaseType = wx.ComboBox(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + cbDatabaseTypeChoices, wx.CB_READONLY )#| wx.CB_SORT) connectionSizer.Add(self.cbDatabaseType, 1, wx.ALL | wx.EXPAND, 5) self.stServer = wx.StaticText(self, wx.ID_ANY, u"Server:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) self.stServer.Wrap(-1) - connectionSizer.Add(self.stServer, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.stServer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) self.txtServer = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 | wx.FULL_REPAINT_ON_RESIZE | wx.SIMPLE_BORDER) @@ -54,35 +200,35 @@ def __init__(self, parent): self.stDBName.Wrap(-1) self.stDBName.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) - connectionSizer.Add(self.stDBName, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.stDBName, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) self.txtDBName = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 | wx.SIMPLE_BORDER) - connectionSizer.Add(self.txtDBName, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.txtDBName, 1, wx.ALL | wx.EXPAND, 5) self.stUser = wx.StaticText(self, wx.ID_ANY, u"User:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) self.stUser.Wrap(-1) self.stUser.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) - connectionSizer.Add(self.stUser, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.stUser, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) self.txtUser = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 | wx.SIMPLE_BORDER) - connectionSizer.Add(self.txtUser, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.txtUser, 1, wx.ALL | wx.EXPAND, 5) self.stPass = wx.StaticText(self, wx.ID_ANY, u"Password:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) self.stPass.Wrap(-1) self.stPass.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) - connectionSizer.Add(self.stPass, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.stPass, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) self.txtPass = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PASSWORD | wx.SIMPLE_BORDER) - connectionSizer.Add(self.txtPass, 0, wx.ALL | wx.EXPAND, 5) + connectionSizer.Add(self.txtPass, 1, wx.ALL | wx.EXPAND, 5) - sbSizer.Add(connectionSizer, 1, wx.EXPAND, 5) + sbSizer.Add(connectionSizer, 90, wx.EXPAND, 3) - formSizer.Add(sbSizer, 1, wx.EXPAND, 20) + formSizer.Add(sbSizer, 1, wx.ALL | wx.EXPAND, 7) btnSizer = wx.FlexGridSizer(0, 3, 0, 25) btnSizer.AddGrowableCol(0) @@ -92,17 +238,15 @@ def __init__(self, parent): btnSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) self.btnTest = wx.Button(self, wx.ID_ANY, u"Test Connection", wx.DefaultPosition, wx.DefaultSize, 0) - btnSizer.Add(self.btnTest, 0, wx.ALL | wx.EXPAND, 5) + btnSizer.Add(self.btnTest, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) self.btnSave = wx.Button(self, wx.ID_ANY, u"Save Connection", wx.DefaultPosition, wx.DefaultSize, 0) - self.btnSave.Enable(False) - - btnSizer.Add(self.btnSave, 0, wx.ALL | wx.EXPAND, 5) + btnSizer.Add(self.btnSave, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) self.btnCancel = wx.Button(self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0) - btnSizer.Add(self.btnCancel, 0, wx.ALL | wx.EXPAND, 5) + btnSizer.Add(self.btnCancel, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) - formSizer.Add(btnSizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.SHAPED, 15) + formSizer.Add(btnSizer, 10, wx.EXPAND, 2) self.SetSizer(formSizer) self.Layout() @@ -120,12 +264,10 @@ def __init__(self, parent): def __del__(self): pass - # Virtual event handlers, overide them in your derived class def OnValueChanged(self, event): event.Skip() - def OnBtnTest(self, event): event.Skip() @@ -135,3 +277,4 @@ def OnBtnSave(self, event): def OnBtnCancel(self, event): event.Skip() + diff --git a/setup/__init__.py b/setup/__init__.py new file mode 100644 index 0000000..a24dbc6 --- /dev/null +++ b/setup/__init__.py @@ -0,0 +1 @@ +__author__ = 'stephanie' diff --git a/make.py b/setup/make.py similarity index 99% rename from make.py rename to setup/make.py index f0a5aa4..b4ccbf6 100644 --- a/make.py +++ b/setup/make.py @@ -160,10 +160,11 @@ def run_pyinstaller(console=False): '--version-file=%s ' % VERSION_FILE + '--onedir ' # '--onefile ' + - '--exclude= + #'--exclude= '--noconfirm ' + APP_FILE) else: ## Non Console Version + val = os.system('pyinstaller ' '--clean ' '--distpath=%s ' % WIN_DIR + @@ -178,6 +179,7 @@ def run_pyinstaller(console=False): '--noconsole ' '--noconfirm ' + APP_FILE) + return True except Exception as e: print (e) @@ -244,6 +246,7 @@ def main(): print "Creating Windows Executable..." if run_pyinstaller(): + scriptpath = os.path.join(WIN_DIR, "odmtools_no_console.iss") run_inno(script= scriptpath) @@ -252,6 +255,7 @@ def main(): scriptpath = os.path.join(WIN_DIR, "odmtools_console.iss") run_inno(scriptpath) + print "Create No Installer " ## Create Shortcut ## Create File diff --git a/tests/test_odmservices/test_series_service.py b/tests/test_odmservices/test_series_service.py index 5cf0e81..ebeffd5 100644 --- a/tests/test_odmservices/test_series_service.py +++ b/tests/test_odmservices/test_series_service.py @@ -52,10 +52,10 @@ def setup(self): """ - def test_get_db_version(self): - version = test_util.add_version(self.session) - db_version = self.series_service.get_db_version() - assert version.version_number == db_version + # def test_get_db_version(self): + # version = test_util.add_version(self.session) + # db_version = self.series_service.get_db_version() + # assert version.version_number == db_version def test_get_all_sites_empty(self): sites = self.series_service.get_used_sites()