#!c:\Program Files\Python39\python.exe # -*- coding: UTF-8 -*- ''' $RCSfile: datasource.py,v $ $Revision$ $Author: markus $ $Date$ ''' import os.path, sys, time # ***** include the biocase.lib directory in the python sys path for importing ***** exec(open(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir, 'lib', 'biocase', 'adjustpath.py'))).read()) exec(open(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir, 'lib', 'biocase', 'appinit.py'))).read()) from biocase.archive.general import inventory_summary, DWCA_SCHEMA_NAME from biocase.configtool.general import dsaObj, form, dsa, templateDir, log, authorize, action, printOverHTTP from biocase.configtool.cmfupgrade import cmfUpgrade from biocase.datasources import Datasource from biocase.tools.templating import PageMacro from biocase.tools.htmltools import getDropDownOptionHtml from biocase.cmfinfo import CMFTemplateListClass from biocase import __version__ import biocase.configuration cfg = biocase.configuration.Cfg() ############################################################################################################ # # MAIN # #=========================================================================================================== # check authentication! if dsaObj is None: exec(compile(open(os.path.abspath(os.path.join(os.path.dirname(__file__), 'main.cgi')), "rb").read(), os.path.abspath(os.path.join(os.path.dirname(__file__), 'main.cgi')), 'exec')) sys.exit() # check authentication! authorize(form, dsa=dsa) # use the datasource.html template to get datasource overview tmpl = PageMacro('Content', PageMacro.DELMODE) tmpl.load('Content', os.path.join(templateDir, '_datasource.html')) # PSF psfObj = dsaObj.getPSFObj(tmp=False) # upgrade object upgradeObj = cmfUpgrade() # Indicate whether a mapping has been removed or recyled # Required to trigger PSF update later recyclingOperation = False def del_schema(schema, dsaObj): old = os.path.join(dsaObj.getDsaDir(), schema) new = dsaObj.getBakFileName(schema) log.debug("Removing CMF %s from datasource" % old) if os.path.isfile(new): os.unlink(new) os.rename(old, new) # # ACTIONS # if action == 'del': # "remove" CMF. renames it to a backup file name (= recycle bin), from which it can be restored later schema = form.getfirst('schema', None) del_schema(schema, dsaObj) # refresh dsaObj dsaObj = Datasource(name=dsa) recyclingOperation = True elif action == 'transfer': # upgrade an existing cmf oldCmf = os.path.join(dsaObj.getDsaDir(), form.getfirst('schema', None)) newSchema = 'cmf_' + form.getfirst('targetschema') + '.xml' newCmfObj, missingConcepts, upgradeTuple = upgradeObj.getUpgradedCmfObj(oldCmf, newSchema) if newCmfObj is None: log.error("ERROR ! CMF could not be upgraded. Unknown error") else: newCmf = os.path.join(dsaObj.getDsaDir(), upgradeTuple[0]) # Check whether there is already a cmf for that schema existingCmf = dsaObj.getSchemaListObj().getSchemaByNS(newCmfObj.rootCMFElementObj.Namespace) if existingCmf is not None: tmpl['updateHint'] = "alert('INFO: A mapping file with the same namespace as the selected schema was already existent (" + existingCmf.name + "). It has been put into the recyling bin if you change your mind.');" del_schema('cmf_' + existingCmf.name, dsaObj) newCmfObj.writeCMF(newCmf) # refresh dsaObj dsaObj = Datasource(name=dsa) elif action == 'restore': schemaFile = form.getfirst('schemafile', None) schema = schemaFile[5:-8] old = os.path.join(dsaObj.getDsaDir(), schemaFile) new = os.path.join(dsaObj.getDsaDir(), "cmf_" + schema) if os.path.isfile(new): tmpl['restoreError'] = "alert('A " + schema + " schema is already active. Please remove it first if you want to restore the " + schemaFile + " file');" else: os.rename(old, new) # refresh dsaObj dsaObj = Datasource(name=dsa) recyclingOperation = True elif action == 'purge': # "purge" CMF. schemaFile = os.path.join(dsaObj.getDsaDir(), form.getfirst('schemafile', None)) os.unlink(schemaFile) # # FILL TEMPLATE # # general tmpl['dsa'] = dsa tmpl['wrapper_url'] = dsaObj.getBioCASeAccessPoint() tmpl['ServiceTitle'] = 'BioCASe Provider Software %s' % __version__ # dbconnection status tmpl['status'] = dsaObj.getDBConnectionStatus() # number of aliases in PSF tmpl['num_ta'] = str(len(psfObj.getTableAliasList())) # list of dsa schemas slObj = dsaObj.getSchemaListObj() log.debug("DSA CMFList: %s" % str(slObj)) # list of duplicate dsa schemas with the same NS origSchemas = {} duplicateList = [] for sObj in slObj: if sObj.NS in origSchemas: duplicateList.append({'schema': sObj.name, 'schemaorig': origSchemas[sObj.NS].name}) else: origSchemas[sObj.NS] = sObj tmpl.expand('Content', 'schemaduplicatelist', duplicateList) #archive dldPath = os.path.join(cfg.archiveDownloadLocator, dsa) archivePath = os.path.join(cfg.archiveWorkLocator, dsa) if not os.path.exists(archivePath): os.makedirs(archivePath) if not os.path.exists(dldPath): os.makedirs(dldPath) archives = inventory_summary(dsaObj) # create existing cmf schema list... DsaSchemaList = [] for sObj in slObj: entry = {} entry['schema'] = sObj.name entry['schema_file'] = os.path.split(sObj.file)[1] entry['namespace'] = sObj.NS entry['num_mappings'] = str(sObj.mappings) entry['num_concepts'] = str(sObj.concepts) entry['schemalist.upgrades'] = [{'ns': t[0], 'targetschema': t[1][4:-4]} for t in upgradeObj.listPossibleUpgradeTuples(sObj.NS) if t[1][4:] != sObj.name] if len(entry['schemalist.upgrades']) == 0: entry['supress_upgrade_start'] = '' else: entry['supress_upgrade_start'] = '' entry['supress_upgrade_end'] = '' a = archives.get(sObj.name[:-4]) if a is None: entry['a_hide_s'] = "" else: entry['a_hide_s'] = "" entry['a_hide_e'] = "" entry['archive_cnt'] = a[0] entry['archive_mod'] = a[1] DsaSchemaList.append(entry) tmpl.expand('Content', 'schemalist', DsaSchemaList) # UPDATE PSF WITH THESE SCHEMAS ? CmfUpdates = [sObj.getLastUpdated() for sObj in slObj if sObj is not None] if recyclingOperation or (len(CmfUpdates) > 0): if len(CmfUpdates) > 0: lastCMFupdate = max(CmfUpdates) else: lastCMFupdate = None psfUpdate = psfObj.getPSFUpdatedWhen() if recyclingOperation or (lastCMFupdate > psfUpdate): log.debug("Need to update PSF with CMF list. Last PSF update at %s, last CMF update %s" % (str(psfUpdate), str(lastCMFupdate))) psfObj.delAllSchemas() for sObj in slObj: psfObj.addSchema(sObj.NS, sObj.file) psfObj.writePSFile() else: log.debug("No need to update PSF with CMF list. Last PSF update at %s, last CMF update %s" % (str(psfUpdate), str(lastCMFupdate))) else: log.debug("No CMFs found. PSF will not be updated") # list of cmf templates tmplSlObj = slObj tmplSlObj = CMFTemplateListClass() log.debug("Full Template CMFList: %s" % str(tmplSlObj)) # dont show already configured schemas. Do NOT remove schemas with the same namespace, as this might be confusing for the user for sObj in slObj: tmplSlObj.removeSchema(name=sObj.name) dropDown = getDropDownOptionHtml(dict([('--select--', '--select--')] + [(sObj.name, os.path.split(sObj.file)[1])for sObj in tmplSlObj]), '--select--') tmpl['newschema_options'] = dropDown # recycle bin deletedSchemas = dsaObj.getDeletedSchemaListObj() DsaDeletedSchemaList = [] for ds in deletedSchemas: s = {} s['deletedschema'] = ds.name s['schema_file'] = os.path.split(ds.file)[1] s['modtime'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.path.getmtime(ds.file))) s['num_mappings'] = str(ds.mappings) s['num_concepts'] = str(ds.concepts) # if schema with the same NS is already existing, don't allow restoring if ds.NS in origSchemas: s['restore'] = '' else: s['restore'] = 'Restore' DsaDeletedSchemaList.append(s) tmpl.expand('Content', 'recycle', DsaDeletedSchemaList) if len(DsaDeletedSchemaList) == 0: tmpl['recycleBinEmptyMessage'] = "Recycle bin is empty." tmpl['hideRecycleBinStart'] = "" # Last, DwCA a = archives.get(DWCA_SCHEMA_NAME) if a is None: tmpl['dwca_message'] = "No DarwinCore archives created so far." else: tmpl['dwca_message'] = "%s DarwinCore archive(s) for this schema, last modified %s." % (a[0], a[1]) # # print HTML ! # printOverHTTP(tmpl)