|
|
'''
|
|
|
views for docs app
|
|
|
|
|
|
@author: Bill Rideout
|
|
|
@contact: brideout@haystack.mit.edu
|
|
|
|
|
|
$Id: views.py 7285 2020-12-04 16:55:17Z brideout $
|
|
|
'''
|
|
|
# standard python imports
|
|
|
import os, os.path, sys
|
|
|
import random
|
|
|
import datetime
|
|
|
import re
|
|
|
import xml.dom.minidom
|
|
|
import hashlib
|
|
|
|
|
|
# django imports
|
|
|
import django, django.http
|
|
|
from django.shortcuts import render
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
|
from . import forms
|
|
|
|
|
|
# madrigal imports
|
|
|
import madrigal.metadata
|
|
|
import madrigal.ui.web
|
|
|
import madrigal.openmadrigal
|
|
|
import subversion_operations
|
|
|
|
|
|
# helper methods
|
|
|
def get_exp_info(control_file, rev):
|
|
|
"""get_exp_info returns a tuple of (exp_desc, cyc_desc, control_file_text) for the input control_file and revision.
|
|
|
|
|
|
For now grabs info from Subversion on apollo
|
|
|
"""
|
|
|
exp_desc = ''
|
|
|
cyc_desc = ''
|
|
|
control_file_text = ''
|
|
|
|
|
|
subObj = subversion_operations.reader()
|
|
|
xmlFilename = control_file.replace('.dat', '.xml')
|
|
|
output = os.path.join('/tmp', control_file)
|
|
|
sub_path = 'millstone_geospace_radar/control/ISRExperiments'
|
|
|
|
|
|
try:
|
|
|
subObj.getFile(os.path.join(sub_path, control_file), '/tmp', rev)
|
|
|
except:
|
|
|
try:
|
|
|
subObj.getFile(os.path.join(sub_path, control_file), '/tmp')
|
|
|
except:
|
|
|
return((exp_desc, cyc_desc, control_file_text))
|
|
|
|
|
|
f = open(output)
|
|
|
control_file_text = f.read()
|
|
|
f.close()
|
|
|
|
|
|
try:
|
|
|
subObj.getFile(os.path.join(sub_path, xmlFilename), '/tmp', rev)
|
|
|
except:
|
|
|
try:
|
|
|
subObj.getFile(os.path.join(sub_path, xmlFilename), '/tmp')
|
|
|
except:
|
|
|
return((exp_desc, cyc_desc, control_file_text))
|
|
|
|
|
|
f = open(output)
|
|
|
xml_file_text = f.read()
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
# now build complete xml file
|
|
|
cvsText = '<?xml version="1.0"?>\n<ExperimentDescriptionFile>\n'
|
|
|
cvsText += xml_file_text
|
|
|
|
|
|
# closing tag
|
|
|
cvsText += '</ExperimentDescriptionFile>'
|
|
|
|
|
|
|
|
|
expDescDoc = xml.dom.minidom.parseString(cvsText)
|
|
|
|
|
|
|
|
|
# get all experiments
|
|
|
expElemList = expDescDoc.getElementsByTagName("Experiment")
|
|
|
|
|
|
for exp in expElemList:
|
|
|
|
|
|
# get one exp name from exp list
|
|
|
nameEl = exp.getElementsByTagName("ExperimentName")[0]
|
|
|
|
|
|
# get text node, convert from unicode to ascii
|
|
|
expName = ''
|
|
|
for elem in nameEl.childNodes:
|
|
|
if elem.nodeType == elem.TEXT_NODE:
|
|
|
expName += elem.data.encode('utf-8')
|
|
|
|
|
|
# get exp descriptions from exp list
|
|
|
expDescElList = exp.getElementsByTagName("ExperimentDescription")
|
|
|
|
|
|
for expDescEl in expDescElList:
|
|
|
|
|
|
# get text node, convert from unicode to ascii
|
|
|
expDesc = ''
|
|
|
for elem in expDescEl.childNodes:
|
|
|
if elem.nodeType == elem.TEXT_NODE:
|
|
|
expDesc += elem.data.encode('utf-8')
|
|
|
if len(exp_desc) == 0:
|
|
|
exp_desc = expDesc # make sure we get something even if no id match
|
|
|
|
|
|
# get one CVS_rev
|
|
|
cvsEl = expDescEl.getElementsByTagName("CVS_rev")[0]
|
|
|
|
|
|
cvs = ''
|
|
|
for elem in cvsEl.childNodes:
|
|
|
if elem.nodeType == elem.TEXT_NODE:
|
|
|
cvs += elem.data.encode('utf-8')
|
|
|
|
|
|
if cvs == rev:
|
|
|
# right rev - overwrite
|
|
|
if len(expDesc) == 0:
|
|
|
exp_desc = expDesc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# get cycle descriptions from exp list
|
|
|
cycDescElList = exp.getElementsByTagName("CycleDescription")
|
|
|
|
|
|
for cycDescEl in cycDescElList:
|
|
|
|
|
|
# get text node, convert from unicode to ascii
|
|
|
cycDesc = ''
|
|
|
for elem in cycDescEl.childNodes:
|
|
|
if elem.nodeType == elem.TEXT_NODE:
|
|
|
cycDesc += elem.data.encode('utf-8')
|
|
|
|
|
|
if len(cyc_desc) == 0:
|
|
|
cyc_desc = cycDesc # make sure we get something even if no id match
|
|
|
|
|
|
# get one CVS_rev
|
|
|
cvsEl = cycDescEl.getElementsByTagName("CVS_rev")[0]
|
|
|
|
|
|
cvs = ''
|
|
|
for elem in cvsEl.childNodes:
|
|
|
if elem.nodeType == elem.TEXT_NODE:
|
|
|
cvs += elem.data.encode('utf-8')
|
|
|
|
|
|
if cvs == rev:
|
|
|
# right rev - overwrite
|
|
|
if len(cycDesc) == 0:
|
|
|
cyc_desc = cycDesc
|
|
|
|
|
|
|
|
|
return((exp_desc, cyc_desc, control_file_text))
|
|
|
|
|
|
|
|
|
|
|
|
@csrf_exempt
|
|
|
def get_log_admin(request):
|
|
|
"""get_log_admin returns the admin access log page.
|
|
|
|
|
|
Inputs:
|
|
|
request
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
bg_color = madDB.getBackgroundColor()
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
form =forms.AdminLogForm(request.POST)
|
|
|
if form.is_valid():
|
|
|
|
|
|
cleaned_data = form.cleaned_data
|
|
|
kinstList = [int(item) for item in eval(cleaned_data['kinst'])]
|
|
|
startDT = datetime.datetime(cleaned_data['startDate'].year, cleaned_data['startDate'].month, cleaned_data['startDate'].day)
|
|
|
endDT = datetime.datetime(cleaned_data['endDate'].year, cleaned_data['endDate'].month, cleaned_data['endDate'].day)
|
|
|
madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
|
|
|
stageDir = os.path.join(madDB.getMadroot(), 'experiments/stage')
|
|
|
tmpFile = os.path.join(stageDir, 'admin_%i.log' % (random.randint(0, 1000000)))
|
|
|
madWebObj.filterLog(tmpFile, kinstList, startDT, endDT)
|
|
|
f = open(tmpFile, 'r')
|
|
|
thisFile = django.core.files.File(f)
|
|
|
response = django.http.HttpResponse(thisFile, content_type='application/x-octet-stream')
|
|
|
response['Content-Disposition'] = 'attachment; filename="' + os.path.basename(tmpFile) + '"'
|
|
|
response['Content-Length'] = os.path.getsize(tmpFile)
|
|
|
response.set_cookie('fileDownload', 'true', path='/', samesite='Strict')
|
|
|
return(response)
|
|
|
|
|
|
else:
|
|
|
form =forms.AdminLogForm()
|
|
|
|
|
|
responseDict = {'bg_color': bg_color}
|
|
|
responseDict['form'] = form
|
|
|
return render(request, 'get_log_admin.html', responseDict)
|
|
|
|
|
|
|
|
|
def get_latest_metadata_version(request):
|
|
|
"""get_latest_metadata_version returns the latest version of the specified metadata file
|
|
|
|
|
|
Inputs:
|
|
|
request - contains key fullPath - full path to the Madrigal file in Subversion relative to trunk
|
|
|
(example: 'madroot/metadata/siteTab.txt')
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
fullPath = request.GET['fullPath']
|
|
|
|
|
|
subObj = subversion_operations.reader('OpenMadrigal')
|
|
|
output = os.path.join('/tmp', os.path.basename(fullPath))
|
|
|
path = os.path.join('trunk', fullPath)
|
|
|
subObj.getFile(path, '/tmp')
|
|
|
|
|
|
f = open(output)
|
|
|
fileStr = f.read()
|
|
|
f.close()
|
|
|
try:
|
|
|
os.remove(output)
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
return(django.http.HttpResponse(fileStr))
|
|
|
|
|
|
|
|
|
def get_all_metadata_versions(request):
|
|
|
"""get_all_metadata_versions returns the a page listing all versions numbers available for a given metadata
|
|
|
file, one line for each version string
|
|
|
|
|
|
Inputs:
|
|
|
request - contains key fullPath - full path to the Madrigal file in Subversion relative to trunk
|
|
|
(example: 'madroot/metadata/siteTab.txt')
|
|
|
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
fullPath = request.GET['fullPath']
|
|
|
|
|
|
subObj = subversion_operations.reader('OpenMadrigal')
|
|
|
path = os.path.join('trunk', fullPath)
|
|
|
revDict = subObj.getFileRevsDates(path)
|
|
|
|
|
|
retStr = ''
|
|
|
for k in sorted(revDict):
|
|
|
retStr += '%i\n' % (revDict[k])
|
|
|
|
|
|
return(django.http.HttpResponse(retStr))
|
|
|
|
|
|
|
|
|
def get_metadata_version(request):
|
|
|
"""get_metadata_version returns the specifed version of the specified metadata file
|
|
|
|
|
|
Inputs:
|
|
|
request - contains key fullPath - full path to the Madrigal file in Subversion relative to trunk
|
|
|
(example: 'madroot/metadata/siteTab.txt'), and key version
|
|
|
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
fullPath = request.GET['fullPath']
|
|
|
version = request.GET['version']
|
|
|
|
|
|
subObj = subversion_operations.reader('OpenMadrigal')
|
|
|
output = os.path.join('/tmp', os.path.basename(fullPath))
|
|
|
path = os.path.join('trunk', fullPath)
|
|
|
subObj.getFile(path, '/tmp', version)
|
|
|
|
|
|
f = open(output, 'rb')
|
|
|
text = f.read()
|
|
|
f.close()
|
|
|
try:
|
|
|
os.remove(output)
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
return(django.http.HttpResponse(text))
|
|
|
|
|
|
|
|
|
def get_open_madrigal_shared_files(request):
|
|
|
"""get_open_madrigal_shared_files returns the specifed version of the shared OpenMadrigal file
|
|
|
|
|
|
Inputs:
|
|
|
request - contains key filename - in form siteName_siteID/expTab.txt or siteName_siteID/fileTab.txt
|
|
|
|
|
|
For now hardcoded path to files
|
|
|
"""
|
|
|
path = '/usr/local/apache2/htdocs/madrigal/distributionFiles/metadata'
|
|
|
path3 = '/usr/local/apache2/htdocs/madrigal/distributionFiles/metadata3' # used because siteTab.txt for mad3 is incompatible
|
|
|
filename = request.GET['filename']
|
|
|
if filename == 'siteTab.txt':
|
|
|
fullPath = os.path.join(path3, filename)
|
|
|
else:
|
|
|
fullPath = os.path.join(path, filename)
|
|
|
f = open(fullPath, 'r')
|
|
|
text = f.read()
|
|
|
f.close()
|
|
|
return(django.http.HttpResponse(text))
|
|
|
|
|
|
|
|
|
def get_madrigal_videos(request):
|
|
|
"""get_madrigal_videos returns the Madrigal video tutorials page
|
|
|
|
|
|
Inputs:
|
|
|
request
|
|
|
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
bg_color = madDB.getBackgroundColor()
|
|
|
responseDict = {'bg_color': bg_color}
|
|
|
return render(request, 'get_video_tutorials.html', responseDict)
|
|
|
|
|
|
def get_exp_notes(request):
|
|
|
"""get_exp_notes returns the description of the control file - links from catalog in MLH files
|
|
|
|
|
|
Inputs:
|
|
|
request
|
|
|
|
|
|
"""
|
|
|
responseDict = {}
|
|
|
responseDict['control_file'] = request.GET['exp']
|
|
|
responseDict['rev'] = request.GET['rev']
|
|
|
|
|
|
exp_desc, cyc_desc, control_file_text = get_exp_info(responseDict['control_file'],
|
|
|
responseDict['rev'])
|
|
|
|
|
|
responseDict['exp_desc'] = exp_desc
|
|
|
responseDict['cyc_desc'] = cyc_desc
|
|
|
responseDict['control_file_text'] = control_file_text
|
|
|
|
|
|
|
|
|
return render(request, 'exp_notes.html', responseDict)
|
|
|
|
|
|
|
|
|
def compare_to_archive(request):
|
|
|
"""compare_to_archive implements the old compareToArchive.py cgi script
|
|
|
|
|
|
Now checks newest to oldest, up to 50 max
|
|
|
"""
|
|
|
filePath = request.GET['filePath']
|
|
|
fileTextMd5 = request.GET['fileTextMd5']
|
|
|
strip = False
|
|
|
if 'strip' in request.GET:
|
|
|
strip = True
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
openMadObj = madrigal.openmadrigal.OpenMadrigal(madDB)
|
|
|
revList = openMadObj.getAllRevisionNumbers(filePath)
|
|
|
revList.reverse() # check newest first
|
|
|
|
|
|
if len(revList) == 0:
|
|
|
return(django.http.HttpResponse('None None'))
|
|
|
|
|
|
# loop through all revisions, looking for a match
|
|
|
for rev in revList[:50]:
|
|
|
thisText = openMadObj.getCvsVersion(filePath, rev)
|
|
|
if thisText is None:
|
|
|
continue
|
|
|
if strip:
|
|
|
data = thisText.strip().encode()
|
|
|
thisMd5 = hashlib.md5(data)
|
|
|
else:
|
|
|
thisMd5 = hashlib.md5(thisText.encode())
|
|
|
if thisMd5.hexdigest() == fileTextMd5:
|
|
|
return(django.http.HttpResponse('%s %s' % (revList[0], rev)))
|
|
|
|
|
|
# no matches found
|
|
|
return(django.http.HttpResponse('%s None' % (revList[0])))
|
|
|
|
|
|
|
|
|
def open_madrigal(request):
|
|
|
"""openmadrigal implements the openmadigal page
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
madSiteObj = madrigal.metadata.MadrigalSite(madDB)
|
|
|
responseDict = {}
|
|
|
site_list = []
|
|
|
for siteId, siteName in madSiteObj.getSiteList():
|
|
|
if madSiteObj.getSiteServer(siteId).find('http') == -1:
|
|
|
url = 'http://' + os.path.join(madSiteObj.getSiteServer(siteId),
|
|
|
madSiteObj.getSiteDocRoot(siteId))
|
|
|
else:
|
|
|
url = os.path.join(madSiteObj.getSiteServer(siteId),
|
|
|
madSiteObj.getSiteDocRoot(siteId))
|
|
|
site_list.append((url, siteName))
|
|
|
|
|
|
responseDict['site_list'] = site_list
|
|
|
return(render(request, 'openmadrigal.html', responseDict))
|
|
|
|
|
|
def madrigal_admin(request):
|
|
|
"""madrigal_admin implements the openmadigal admin page
|
|
|
"""
|
|
|
responseDict = {}
|
|
|
return(render(request, 'admin.html', responseDict))
|
|
|
|
|
|
def madrigal_download(request):
|
|
|
"""madrigal_download implements the openmadigal download page
|
|
|
"""
|
|
|
responseDict = {}
|
|
|
return(render(request, 'madDownload.html', responseDict))
|
|
|
|
|
|
def get_citation_group_service(request):
|
|
|
"""get_citation_group returns a list of citations created as a group using a group id
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
id = int(request.GET['id'])
|
|
|
citations = madDB.getListFromGroupId(id)
|
|
|
|
|
|
text = ''
|
|
|
for url in citations:
|
|
|
text += '%s\n' % (url)
|
|
|
|
|
|
return render(request, 'service.html', {'text': django.utils.safestring.mark_safe(text)})
|
|
|
|
|
|
def create_citation_group_with_list(request):
|
|
|
"""create_citation_group_with_list create a citation group through passed in group of citations.
|
|
|
|
|
|
Returns citation to group
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
try:
|
|
|
user_fullname = request.GET['user_fullname']
|
|
|
except KeyError:
|
|
|
return render(request, 'service.html', {'text': 'user_fullname argument missing'})
|
|
|
try:
|
|
|
user_email = request.GET['user_email']
|
|
|
except KeyError:
|
|
|
return render(request, 'service.html', {'text': 'user_email argument missing'})
|
|
|
try:
|
|
|
user_affiliation = request.GET['user_affiliation']
|
|
|
except KeyError:
|
|
|
return render(request, 'service.html', {'text': 'user_affiliation argument missing'})
|
|
|
citations=request.GET.getlist('url')
|
|
|
if len(citations) == 0:
|
|
|
return render(request, 'service.html', {'text': 'url argument missing; multiple allowed'})
|
|
|
# verify citations in proper format
|
|
|
for citation in citations:
|
|
|
if citation[:11] not in ('https://w3i', 'experiments'):
|
|
|
return render(request, 'service.html', {'text': 'Illegal url %s' % (citation)})
|
|
|
id = madDB.createGroupIdWithList(user_fullname, user_email, user_affiliation, citations)
|
|
|
return render(request, 'service.html', {'text': 'http://cedar.openmadrigal.org/getCitationGroup?id=%i\n' % (id)})
|
|
|
|
|
|
|
|
|
def get_citation_group_with_filters(request):
|
|
|
"""get_citation_group_with_filters returns a list of citations (one per line) using filters similar to globalDownload.
|
|
|
Result can then be used to create citation group using create_citation_group_with_list
|
|
|
|
|
|
Request contains to following keys:
|
|
|
startDate: start datetime to filter experiments before in YYYY-MM-DD (required)
|
|
|
endDate: end datetime to filter experiments after in YYYY-MM-DD (required)
|
|
|
inst: a list of instrument codes or names. If not set, all instruments used.
|
|
|
For names fnmatch will be used
|
|
|
kindat: a list of kind of data codes or names. If not set, all kindats used.
|
|
|
For names fnmatch will be used
|
|
|
seasonalStartDate: in form MM/DD, rejects all days earlier in year. If not set,
|
|
|
implies 01/01
|
|
|
seasonalEndDate: in form MM/DD, rejects all days later in year. If not set,
|
|
|
implies 12/31
|
|
|
includeNonDefault: if set, include realtime files when there are no default. If not set,
|
|
|
implies only default files.
|
|
|
expName: string - filter experiments by the experiment name. fnmatch rules
|
|
|
If not set, no filtering by experiment name.
|
|
|
excludeExpName: string - exclude experiments by the experiment name. fnmatch rules
|
|
|
If not set, no excluding experiments by experiment name.
|
|
|
fileDesc: filter files using input file Description string via fnmatch.
|
|
|
If not set, no filtering by file name
|
|
|
|
|
|
Returns a list with all citations in group, one per line
|
|
|
"""
|
|
|
madDB = madrigal.metadata.MadrigalDB()
|
|
|
madWebObj = madrigal.ui.web.MadrigalWeb(madDB)
|
|
|
if not 'startDate' in request.GET:
|
|
|
return(django.http.HttpResponse('<p>startDate required for getCitationGroupWithFilters</p>'))
|
|
|
startDate = request.GET.get('startDate')
|
|
|
startDate = datetime.datetime.strptime(startDate, '%Y-%m-%d')
|
|
|
endDate = request.GET.get('endDate')
|
|
|
endDate = datetime.datetime.strptime(endDate, '%Y-%m-%d')
|
|
|
inst = request.GET.getlist('inst')
|
|
|
if len(inst) == 0:
|
|
|
inst = None
|
|
|
kindat = request.GET.getlist('kindat')
|
|
|
if len(kindat) == 0:
|
|
|
kindat = None
|
|
|
seasonalStartDate = request.GET.get('seasonalStartDate')
|
|
|
seasonalEndDate = request.GET.get('seasonalEndDate')
|
|
|
if 'includeNonDefault' in request.GET:
|
|
|
includeNonDefault = True
|
|
|
else:
|
|
|
includeNonDefault = False
|
|
|
expName = request.GET.get('expName')
|
|
|
excludeExpName = request.GET.get('excludeExpName')
|
|
|
fileDesc = request.GET.get('fileDesc')
|
|
|
citations = madWebObj.global_file_search(startDate, endDate, inst, kindat,
|
|
|
seasonalStartDate, seasonalEndDate,
|
|
|
includeNonDefault, expName, excludeExpName,
|
|
|
fileDesc, returnCitation=True)
|
|
|
if len(citations) == 0:
|
|
|
return render(request, 'service.html', {'text': 'No citations found with given filters - no group citation created'})
|
|
|
else:
|
|
|
text = ''
|
|
|
for url in citations:
|
|
|
text += '%s\n' % (url)
|
|
|
return render(request, 'service.html', {'text': text})
|
|
|
|
|
|
|
|
|
|