-
Notifications
You must be signed in to change notification settings - Fork 4
/
Operation.py
181 lines (155 loc) · 5.09 KB
/
Operation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#
# Operation Manager
# Author: Robert Sinn
# Last modified: 20 10 2014
#
# This file is part of Climate Analyser. The Operation script runs the
# encompassing process that sets up the relevant files. Checks for
# duplicates, sets the job status for the Django server and passes the
# Job over to the Job Selector
#
# Climate Analyser is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Climate Analyser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Climate Analyser.
# If not, see <http://www.gnu.org/licenses/>.
#
import sys
import requests
import jobSelect
import os.path
import os
import string
import random
import rsa
import urllib
import base64
import re
from cdo import *
def getFileNameFromInput(inputFile):
#Excludes variables from name
return inputFile.split('?',1)[0]
def getLocation(inputFile):
return ("/var/www/cgi-bin/Thredds/inputs/"
+ getFileNameFromInput(inputFile))
def dataLink(serverAddr,inputFile):
#Creates a opendap url including relevant variables.
loc = (serverAddr + "/thredds/dodsC/datafiles/inputs/" +
getFileNameFromInput(inputFile))
return (loc + getVariables(loc+'.dds', inputFile))
def getVariables(loc,inputFile):
if "?" in inputFile:
return "?" + ddsVariables(loc,inputFile.split('?',1)[1].split(','))
else:
return ""
def ddsVariables(url,grids):
#get all Maps associated with grids
vars = []
output = urllib.urlopen(url).read()
for grid in grids:
vars += varSearch(grid,output)
return ','.join(list(set(vars + grids)))
def varSearch(grid,output):
varstring = re.search(grid+'(.*);',output).group(1)
varstring = varstring.strip('[').strip(']')
return arrayScrub(varstring.split(']['))
def arrayScrub(inputs):
for x in range(0, len(inputs)):
inputs[x] = inputs[x].split(' = ')[0]
return inputs
def compileVarArray(serverAddr,inputs):
#Creates list of dataLinks for use by JobSelect
for x in range(0, len(inputs)):
inputs[x] = dataLink(serverAddr,inputs[x])
return inputs
def readFileExistsInThredds(name):
return os.path.isfile(name)
def filecheck(inputs):
#Deprecated, remains avalible so that url downloading support
#can be re-added
for inputFile in inputs:
if readFileExistsInThredds(getLocation(inputFile)) == 0:
downloadFile(inputFile)
def localFile(url):
#Deprecated
if not "/dodsC/" in url:
return 1
else:
return 0
def downloadFile(url):
#Deprecated, remains avalible so that url downloading support
#can be re-added
if localFile(url):
filePath = getLocation(url)
r = requests.get(url)
f = open(filePath, 'wb')
for chunk in r.iter_content(chunk_size=512 * 1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
f.close()
else:
cdo = Cdo()
print url.split('?',1)[0]
cdo.copy(input = url.split('?',1)[0], output = getLocation(url))
return
def getinputs(inputFiles):
#Deprecated, remains avalible so that url downloading support
#can be re-added
inputs = inputFiles.split(",http")
for x in range(1, len(inputs)):
inputs[x] = 'http' + inputs[x]
return inputs
def jobStatus(jobid,status):
#Contact the Django server to notify it of the job status
djangoFile = open('DjangoServer')
djangoAddr = djangoFile.read().strip()
publicfile = open('publicKey.pem')
pubdata = publicfile.read()
pubkey = rsa.PublicKey.load_pkcs1(pubdata)
wCall = djangoAddr + '/update_computation_status?id='
wCall += encryptField(pubkey,jobid)
wCall += '&status='
wCall += encryptField(pubkey,status)
urllib.urlopen(wCall)
def encryptField(pubkey, value):
crypto = rsa.encrypt(value,pubkey)
return base64.b16encode(crypto) #Encoding used for url compatibility
def getServerAddr():
serverFile = open('ThreddServer')
return serverFile.read().strip()
def Operation(Inputs,Selection,Jobid):
jobStatus(Jobid,'1') #Start of Job
inputs = Inputs.split('|')
filename = Jobid + '.nc'
outputFile = "/var/www/cgi-bin/Thredds/outputs/" + filename
serverAddr = getServerAddr()
if len(inputs) < 1:
jobStatus(Jobid,'3') #Not enough files
return
try:
if readFileExistsInThredds(outputFile):
jobStatus(Jobid,'2') #File already exists
return
except:
jobStatus(Jobid,'4')
return # "Could not open outputFile for writing."
jobSelect.jobSelect(Selection,compileVarArray(serverAddr,inputs),[outputFile])
jobStatus(Jobid,'2') #Success
return
def main():
try:
Operation(sys.argv[1],sys.argv[2],sys.argv[3])
except Exception as e:
jobStatus(sys.argv[3],'7') #Operation Failed
raise e
if __name__ == '__main__':
exitCode = main()
exit(exitCode)