Skip to content
This repository was archived by the owner on Jan 25, 2018. It is now read-only.

Commit 1639676

Browse files
author
Lee Kamentsky
committed
WIP
1 parent 5fc7e55 commit 1639676

10 files changed

+689
-198
lines changed

BuildCellProfiler.py

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/usr/bin/env ./batchprofiler.sh
2+
#
3+
# REST service to build CellProfiler
4+
#
5+
# CellProfiler is distributed under the GNU General Public License.
6+
# See the accompanying file LICENSE for details.
7+
#
8+
# Copyright (c) 2003-2009 Massachusetts Institute of Technology
9+
# Copyright (c) 2009-2015 Broad Institute
10+
# All rights reserved.
11+
#
12+
# Please see the AUTHORS file for credits.
13+
#
14+
# Website: http://www.cellprofiler.org
15+
16+
import cgitb
17+
cgitb.enable()
18+
import sys
19+
import cgi
20+
import json
21+
import os
22+
23+
from bputilities import build_cellprofiler, get_version_and_githash, is_built
24+
from bpformdata import RM_GET, RM_PUT, REQUEST_METHOD, REVISION, GIT_HASH, \
25+
DATETIME_VERSION, IS_BUILT, QUEUE, PROJECT, EMAIL, BATCHPROFILER_DEFAULTS
26+
27+
query_revision = BATCHPROFILER_DEFAULTS[REVISION]
28+
def do_get():
29+
if query_revision is not None:
30+
datetime_version, git_hash = get_version_and_githash(query_revision)
31+
buildstatus = is_built(version=datetime_version, git_hash=git_hash)
32+
print "Content-Type: application/json\r"
33+
print "\r"
34+
print json.dumps(
35+
{ GIT_HASH: git_hash,
36+
DATETIME_VERSION: datetime_version,
37+
IS_BUILT: buildstatus
38+
})
39+
return
40+
else:
41+
print "Content-Type: text/plain\r"
42+
print "\r"
43+
print """API for BuildCellProfiler.py
44+
45+
GET /?revision=<revision> HTTP/1.1
46+
47+
Look up the GIT hash and datetime version of a revision.
48+
49+
<revision> - a GIT treeish reference (tag, GIT hash, branch)
50+
51+
returns a JSON-encoded dictionary:
52+
{
53+
%(GIT_HASH)s:"<git-hash>",
54+
%(DATETIME_VERSION)s:"<datetime-version>",
55+
%(IS_BUILT)s:<true/false>,
56+
}
57+
<git-hash> - the full GIT hash of the reference
58+
<datetime-version> - the UTC time of the checkin in the format YYYYMMDDHHMMSS.
59+
60+
The value for %(IS_BUILT)s is true if the version of CellProfiler has been
61+
built.
62+
63+
PUT /?revision=<revision> HTTP/1.1
64+
65+
(optional JSON dictionary =
66+
{%(EMAIL)s:<email>:%(QUEUE)s:<queue>:%(PROJECT)s:<project>})
67+
68+
<email> - send user email when built
69+
<queue> - run build on this queue
70+
<project> - charge to this project
71+
72+
returns the same JSON-encoded dictionary as for GET
73+
""" % globals()
74+
75+
def do_put():
76+
datetime_version, git_hash = get_version_and_githash(query_revision)
77+
buildstatus = is_built(version=datetime_version, git_hash=git_hash)
78+
if not buildstatus:
79+
try:
80+
options = json.load(data)
81+
assert isinstance(options, dict)
82+
except:
83+
options = {}
84+
build_cellprofiler(version = datetime_version,
85+
git_hash = git_hash,
86+
queue_name = options.get(QUEUE, None),
87+
group_name = options.get(PROJECT, None),
88+
email_address = options.get(EMAIL, None))
89+
90+
print "Content-Type: application/json\r"
91+
print "\r"
92+
print json.dumps(
93+
{ GIT_HASH: git_hash,
94+
DATETIME_VERSION: datetime_version,
95+
IS_BUILT: buildstatus
96+
})
97+
98+
if REQUEST_METHOD == RM_GET:
99+
do_get()
100+
elif REQUEST_METHOD == RM_PUT:
101+
do_put()
102+
else:
103+
raise NotImplementedError(
104+
"Request method %s not implemented" % REQUEST_METHOD)
105+

DeleteFile.py

+23-31
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env /imaging/analysis/People/imageweb/batchprofiler/cgi-bin/python-2.6.sh
1+
#!/usr/bin/env ./batchprofiler.sh
22
"""
33
CellProfiler is distributed under the GNU General Public License.
44
See the accompanying file LICENSE for details.
@@ -16,41 +16,39 @@
1616
#
1717
import cgitb
1818
cgitb.enable()
19+
from bpformdata import *
1920
import RunBatch
2021
import StyleSheet
2122
import cgi
2223
import os
23-
import os.path
2424

2525
def remove_if_exists(path):
2626
if os.path.exists(path):
2727
os.remove(path)
2828

29-
form = cgi.FieldStorage()
30-
delete_action = form["delete_action"].value
31-
if form.has_key("run_id"):
32-
run_id = int(form["run_id"].value)
33-
my_batch,my_run = RunBatch.LoadRun(run_id)
34-
if ((delete_action.upper() == "ALL") or (delete_action.upper() == "TEXT")):
35-
remove_if_exists(RunBatch.RunTextFilePath(my_batch, my_run))
29+
def delete_run(my_batch, my_run):
30+
if delete_action in (A_DELETE_ALL, A_DELETE_TEXT):
31+
remove_if_exists(RunBatch.run_text_file_path(my_batch, my_run))
3632

37-
if (delete_action.upper() == "ALL") or (delete_action.upper() == "OUTPUT"):
33+
if delete_action in (A_DELETE_ALL, A_DELETE_OUTPUT):
3834
remove_if_exists(RunBatch.RunOutFilePath(my_batch, my_run))
39-
40-
if (delete_action.upper() == "ALL") or (delete_action.upper() == "DONE"):
41-
remove_if_exists(RunBatch.RunDoneFilePath(my_batch, my_run))
42-
elif form.has_key("batch_id"):
43-
batch_id = int(form["batch_id"].value)
44-
my_batch = RunBatch.LoadBatch(batch_id)
45-
for my_run in my_batch["runs"]:
46-
if ((delete_action.upper() == "ALL") or (delete_action.upper() == "TEXT")):
47-
remove_if_exists(RunBatch.RunTextFilePath(my_batch, my_run))
48-
49-
if (delete_action.upper() == "ALL") or (delete_action.upper() == "OUTPUT"):
50-
remove_if_exists(RunBatch.RunOutFilePath(my_batch, my_run))
51-
52-
if (delete_action.upper() == "ALL") or (delete_action.upper() == "DONE"):
53-
remove_if_exists(RunBatch.RunDoneFilePath(my_batch, my_run))
35+
36+
form = cgi.FieldStorage()
37+
delete_action = BATCHPROFILER_DEFAULTS[K_DELETE_ACTION]
38+
if delete_action is not None:
39+
delete_action = delete_action.upper()
40+
run_id = BATCHPROFILER_DEFAULTS[RUN_ID]
41+
batch_id = BATCHPROFILER_DEFAULTS[BATCH_ID]
42+
if run_id is not None and delete_action is not None:
43+
my_run = RunBatch.BPRun.select(run_id)
44+
my_batch = RunBatch.BPBatch()
45+
batch.select(run.batch_id)
46+
delete_run(my_batch, my_run)
47+
elif batch_id is not None:
48+
my_batch = RunBatch.BPBatch()
49+
my_batch.select(batch_id)
50+
for my_run in my_batch.select_runs():
51+
delete_run(my_batch, my_run)
5452

5553

5654
url = "ViewBatch.py?batch_id=%(batch_id)d"%(my_batch)
@@ -61,9 +59,3 @@ def remove_if_exists(path):
6159
print "</head>"
6260
print "<body>This page should be redirected to <a href='%(url)s'/>%(url)s</a></body>"%(globals())
6361
print "</html>"
64-
try:
65-
import cellprofiler.utilities.jutil as jutil
66-
jutil.kill_vm()
67-
except:
68-
import traceback
69-
traceback.print_exc()

FixPermissions.py

100644100755
+124-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env /imaging/analysis/People/imageweb/batchprofiler/cgi-bin/python-2.6.sh
1+
#!/usr/bin/env ./batchprofiler.sh
22
"""
33
CellProfiler is distributed under the GNU General Public License.
44
See the accompanying file LICENSE for details.
@@ -14,34 +14,131 @@
1414
#
1515
# Kill all jobs in a batch
1616
#
17-
import cgitb
18-
cgitb.enable()
1917
import RunBatch
18+
from bpformdata import *
2019
import cgi
2120
import os
21+
import json
22+
import stat
23+
import yattag
2224

23-
form = cgi.FieldStorage()
24-
batch_id = int(form["batch_id"].value)
25-
my_batch = RunBatch.LoadBatch(batch_id)
26-
status_dir = "%(data_dir)s/status/"%(my_batch)
27-
txt_output_dir = "%(data_dir)s/txt_output/"%(my_batch)
28-
if os.path.exists(status_dir):
29-
os.chmod(status_dir,0777)
30-
if os.path.exists(txt_output_dir):
31-
os.chmod(txt_output_dir,0777)
25+
def maybe_chmod(path, mode, d):
26+
'''Change the mode of a file if it exists and needs changing
3227
33-
for run in my_batch["runs"]:
34-
for path in [RunBatch.RunTextFilePath(my_batch,run),
35-
RunBatch.RunDoneFilePath(my_batch,run),
36-
RunBatch.RunOutFilePath(my_batch,run)]:
37-
if os.path.exists(path):
38-
os.chmod(path,0644)
39-
40-
url = "ViewBatch.py?batch_id=%(batch_id)d"%(my_batch)
41-
print "Content-Type: text/html"
42-
print
43-
print "<html><head>"
44-
print "<meta http-equiv='refresh' content='0; URL=%(url)s' />"%(globals())
45-
print "</head>"
46-
print "<body>This page should be redirected to <a href='%(url)s'/>%(url)s</a></body>"%(globals())
47-
print "</html>"
28+
path - path to file or directory
29+
mode - the new mode
30+
d - add the key/value of path:mode to the dictionary if the mode was changed
31+
'''
32+
if os.path.exists(path) and \
33+
stat.S_IMODE(os.stat(directory).st_mode) != mode:
34+
os.chmod(directory, mode)
35+
what_i_did[directory] = mode
36+
37+
def handle_post():
38+
batch_id = BATCHPROFILER_DEFAULTS[BATCH_ID]
39+
my_batch = RunBatch.BPBatch()
40+
my_batch.select(batch_id)
41+
txt_output_dir = RunBatch.text_file_directory(my_batch)
42+
job_script_dir = RunBatch.script_file_directory(my_batch)
43+
what_i_did = {}
44+
maybe_chmod(txt_output_dir, 0777, what_i_did)
45+
maybe_chmod(job_script_dir, 0777, what_i_did)
46+
47+
for run in my_batch.select_runs():
48+
for path in [RunBatch.run_text_file_path(my_batch, run),
49+
RunBatch.run_out_file_path(my_batch, run),
50+
RunBatch.run_err_file_path(my_batch, run)]:
51+
maybe_chmod(path, 0644, what_i_did)
52+
53+
print "Content-Type: application/json"
54+
print
55+
print json.dumps(what_i_did)
56+
57+
'''Javascript for fixPermissions function
58+
59+
Assumes that batch ID is in the element
60+
with the name, "input_batch_id".
61+
62+
button = button that was pressed
63+
'''
64+
FIX_PERMISSIONS_AJAX_JAVASCRIPT = '''
65+
function fix_permissions(button) {
66+
var batch_id_elem = document.getElementById("input_%(BATCH_ID)s");
67+
var batch_id = batch_id_elem.value;
68+
var oldInnerText = button.innerText;
69+
button.innerText = "Fixing permissions for batch " + batch_id;
70+
button.disabled = true
71+
var xmlhttp = new XMLHttpRequest();
72+
xmlhttp.onreadystatechange=function() {
73+
if (xmlhttp.readyState == 4) {
74+
if (xmlhttp.status == 200) {
75+
var result = JSON.parse(xmlhttp.responseText);
76+
var count = Object.keys(result).length
77+
alert("Changed permissions for "+count+" file(s) / folder(s)");
78+
} else {
79+
alert("Failed to change permissions.\n" + xmlhttp.responseText);
80+
}
81+
button.innerText = oldInnerText;
82+
button.disabled = false;
83+
}
84+
}
85+
xmlhttp.open(
86+
"POST",
87+
"FixPermissions.py", true);
88+
xmlhttp.setRequestHeader(
89+
"Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
90+
xmlhttp.send("%(BATCH_ID)s=" + batch_id);
91+
}
92+
''' % globals()
93+
94+
TITLE = "BatchProfiler: fix file permissions"
95+
def handle_get():
96+
'''Display a form for fixing the permissions'''
97+
batch_id_id = "input_%s" % BATCH_ID
98+
button_id = "button_%s" % BATCH_ID
99+
fix_permissions_action = \
100+
"fix_permissions(document.getElementById('%s'));" % button_id
101+
doc, tag, text = yattag.Doc().tagtext()
102+
assert isinstance(doc, yattag.Doc)
103+
with tag("html"):
104+
with tag("head"):
105+
with tag("title"):
106+
text(TITLE)
107+
with tag("script", language="JavaScript"):
108+
doc.asis(FIX_PERMISSIONS_AJAX_JAVASCRIPT)
109+
with tag("body"):
110+
with tag("h1"):
111+
text(TITLE)
112+
with tag("div"):
113+
text("""
114+
This webpage fixes permission problems for the files and folders in your batch
115+
that were created outside BatchProfiler's control. It will grant read
116+
permission for the job script folder, the text output folder, the text and
117+
error output files and the measurements file.""")
118+
with tag("div"):
119+
with tag("label", **{ "for":batch_id_id }):
120+
text("Batch ID")
121+
doc.input(name=BATCH_ID, id=batch_id_id, type="text")
122+
with tag("button", id=button_id,
123+
onclick=fix_permissions_action):
124+
text("Fix permissions")
125+
print "Content-Type: text/html"
126+
print
127+
print '<!DOCTYPE html PUBLIC ' \
128+
'"-//W3C//DTD XHTML 1.0 Transitional//EN"' \
129+
'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
130+
print yattag.indent(doc.getvalue())
131+
132+
if __name__ == "__main__":
133+
import cgitb
134+
cgitb.enable()
135+
136+
if REQUEST_METHOD == RM_GET:
137+
handle_get()
138+
elif REQUEST_METHOD == RM_POST:
139+
handle_post()
140+
else:
141+
raise ValueError("Unhandled request method: %s" % REQUEST_METHOD)
142+
143+
144+

KillJobs.py

100644100755
+8-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env /imaging/analysis/People/imageweb/batchprofiler/cgi-bin/python-2.6.sh
1+
#!/usr/bin/env ./batchprofiler.sh
22
#
33
# Kill all jobs in a batch
44
#
@@ -14,11 +14,12 @@
1414
1515
Website: http://www.cellprofiler.org
1616
"""
17-
print "Content-Type: text/html"
18-
print
17+
print "Content-Type: text/html\r"
18+
print "\r"
1919
import cgitb
2020
cgitb.enable()
2121
import RunBatch
22+
import bputilities
2223
import cgi
2324
import subprocess
2425
import sys
@@ -56,12 +57,13 @@
5657
"""
5758
p = subprocess.Popen(["bash"],stdin = subprocess.PIPE,
5859
stdout=subprocess.PIPE)
59-
listing = p.communicate(". /broad/lsf/conf/profile.lsf;bjobs\n")[0]
60+
listing = p.communicate(
61+
". /broad/software/scripts/useuse;reuse GridEngine8;qjobs\n")[0]
6062
listing_lines = listing.split('\n')
6163
header = listing_lines[0]
6264
columns = [header.find(x) for x in header.split(' ') if len(x)]
6365
columns.append(1000)
64-
body = listing_lines[1:]
66+
body = listing_lines[2:]
6567
print """
6668
<h2>Jobs on imageweb</h2>
6769
<table>
@@ -75,9 +77,4 @@
7577
</table>
7678
</body>
7779
"""
78-
try:
79-
import cellprofiler.utilities.jutil as jutil
80-
jutil.kill_vm()
81-
except:
82-
import traceback
83-
traceback.print_exc()
80+
bputilities.shutdown_cellprofiler()

0 commit comments

Comments
 (0)