workflow-to-galaxy 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +6 -0
- data/LICENSE +23 -0
- data/README +60 -0
- data/Rakefile +54 -0
- data/bin/workflow_to_galaxy.rb +110 -0
- data/doc/rdoc/classes/Generator.html +215 -0
- data/doc/rdoc/classes/WorkflowToGalaxy.html +105 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/LICENSE.html +133 -0
- data/doc/rdoc/files/README.html +192 -0
- data/doc/rdoc/files/lib/workflow-to-galaxy/generator_rb.html +108 -0
- data/doc/rdoc/files/lib/workflow-to-galaxy_rb.html +108 -0
- data/doc/rdoc/fr_class_index.html +28 -0
- data/doc/rdoc/fr_file_index.html +30 -0
- data/doc/rdoc/fr_method_index.html +28 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/lib/workflow-to-galaxy.rb +5 -0
- data/lib/workflow-to-galaxy/generator.rb +497 -0
- metadata +132 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>File: workflow-to-galaxy.rb</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
11
|
+
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
12
|
+
<script type="text/javascript">
|
13
|
+
// <![CDATA[
|
14
|
+
|
15
|
+
function popupCode( url ) {
|
16
|
+
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
17
|
+
}
|
18
|
+
|
19
|
+
function toggleCode( id ) {
|
20
|
+
if ( document.getElementById )
|
21
|
+
elem = document.getElementById( id );
|
22
|
+
else if ( document.all )
|
23
|
+
elem = eval( "document.all." + id );
|
24
|
+
else
|
25
|
+
return false;
|
26
|
+
|
27
|
+
elemStyle = elem.style;
|
28
|
+
|
29
|
+
if ( elemStyle.display != "block" ) {
|
30
|
+
elemStyle.display = "block"
|
31
|
+
} else {
|
32
|
+
elemStyle.display = "none"
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Make codeblocks hidden by default
|
39
|
+
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
40
|
+
|
41
|
+
// ]]>
|
42
|
+
</script>
|
43
|
+
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
<div id="fileHeader">
|
50
|
+
<h1>workflow-to-galaxy.rb</h1>
|
51
|
+
<table class="header-table">
|
52
|
+
<tr class="top-aligned-row">
|
53
|
+
<td><strong>Path:</strong></td>
|
54
|
+
<td>lib/workflow-to-galaxy.rb
|
55
|
+
</td>
|
56
|
+
</tr>
|
57
|
+
<tr class="top-aligned-row">
|
58
|
+
<td><strong>Last Update:</strong></td>
|
59
|
+
<td>Mon Dec 13 15:22:40 +0100 2010</td>
|
60
|
+
</tr>
|
61
|
+
</table>
|
62
|
+
</div>
|
63
|
+
<!-- banner header -->
|
64
|
+
|
65
|
+
<div id="bodyContent">
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
<div id="contextContent">
|
70
|
+
|
71
|
+
|
72
|
+
<div id="requires-list">
|
73
|
+
<h3 class="section-bar">Required files</h3>
|
74
|
+
|
75
|
+
<div class="name-list">
|
76
|
+
workflow-to-galaxy/generator
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
</div>
|
81
|
+
|
82
|
+
|
83
|
+
</div>
|
84
|
+
|
85
|
+
|
86
|
+
<!-- if includes -->
|
87
|
+
|
88
|
+
<div id="section">
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
<!-- if method_list -->
|
98
|
+
|
99
|
+
|
100
|
+
</div>
|
101
|
+
|
102
|
+
|
103
|
+
<div id="validator-badges">
|
104
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
105
|
+
</div>
|
106
|
+
|
107
|
+
</body>
|
108
|
+
</html>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
3
|
+
<!DOCTYPE html
|
4
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
5
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
6
|
+
|
7
|
+
<!--
|
8
|
+
|
9
|
+
Classes
|
10
|
+
|
11
|
+
-->
|
12
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
13
|
+
<head>
|
14
|
+
<title>Classes</title>
|
15
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
16
|
+
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
17
|
+
<base target="docwin" />
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="index">
|
21
|
+
<h1 class="section-bar">Classes</h1>
|
22
|
+
<div id="index-entries">
|
23
|
+
<a href="classes/Generator.html">Generator</a><br />
|
24
|
+
<a href="classes/WorkflowToGalaxy.html">WorkflowToGalaxy</a><br />
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</body>
|
28
|
+
</html>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
3
|
+
<!DOCTYPE html
|
4
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
5
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
6
|
+
|
7
|
+
<!--
|
8
|
+
|
9
|
+
Files
|
10
|
+
|
11
|
+
-->
|
12
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
13
|
+
<head>
|
14
|
+
<title>Files</title>
|
15
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
16
|
+
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
17
|
+
<base target="docwin" />
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="index">
|
21
|
+
<h1 class="section-bar">Files</h1>
|
22
|
+
<div id="index-entries">
|
23
|
+
<a href="files/LICENSE.html">LICENSE</a><br />
|
24
|
+
<a href="files/README.html">README</a><br />
|
25
|
+
<a href="files/lib/workflow-to-galaxy_rb.html">lib/workflow-to-galaxy.rb</a><br />
|
26
|
+
<a href="files/lib/workflow-to-galaxy/generator_rb.html">lib/workflow-to-galaxy/generator.rb</a><br />
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</body>
|
30
|
+
</html>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
3
|
+
<!DOCTYPE html
|
4
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
5
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
6
|
+
|
7
|
+
<!--
|
8
|
+
|
9
|
+
Methods
|
10
|
+
|
11
|
+
-->
|
12
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
13
|
+
<head>
|
14
|
+
<title>Methods</title>
|
15
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
16
|
+
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
17
|
+
<base target="docwin" />
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="index">
|
21
|
+
<h1 class="section-bar">Methods</h1>
|
22
|
+
<div id="index-entries">
|
23
|
+
<a href="classes/Generator.html#M000002">generate_script (Generator)</a><br />
|
24
|
+
<a href="classes/Generator.html#M000001">generate_xml (Generator)</a><br />
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
</body>
|
28
|
+
</html>
|
data/doc/rdoc/index.html
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
5
|
+
|
6
|
+
<!--
|
7
|
+
|
8
|
+
workflow-to-galaxy Docs
|
9
|
+
|
10
|
+
-->
|
11
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
12
|
+
<head>
|
13
|
+
<title>workflow-to-galaxy Docs</title>
|
14
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
15
|
+
</head>
|
16
|
+
<frameset rows="20%, 80%">
|
17
|
+
<frameset cols="25%,35%,45%">
|
18
|
+
<frame src="fr_file_index.html" title="Files" name="Files" />
|
19
|
+
<frame src="fr_class_index.html" name="Classes" />
|
20
|
+
<frame src="fr_method_index.html" name="Methods" />
|
21
|
+
</frameset>
|
22
|
+
<frame src="files/README.html" name="docwin" />
|
23
|
+
</frameset>
|
24
|
+
</html>
|
@@ -0,0 +1,208 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
font-family: Verdana,Arial,Helvetica,sans-serif;
|
4
|
+
font-size: 90%;
|
5
|
+
margin: 0;
|
6
|
+
margin-left: 40px;
|
7
|
+
padding: 0;
|
8
|
+
background: white;
|
9
|
+
}
|
10
|
+
|
11
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
12
|
+
h1 { font-size: 150%; }
|
13
|
+
h2,h3,h4 { margin-top: 1em; }
|
14
|
+
|
15
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
16
|
+
a:hover { background: #039; color: #eef; }
|
17
|
+
|
18
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
19
|
+
td > a {
|
20
|
+
background: transparent;
|
21
|
+
color: #039;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* and inside a section title */
|
26
|
+
.section-title > a {
|
27
|
+
background: transparent;
|
28
|
+
color: #eee;
|
29
|
+
text-decoration: none;
|
30
|
+
}
|
31
|
+
|
32
|
+
/* === Structural elements =================================== */
|
33
|
+
|
34
|
+
div#index {
|
35
|
+
margin: 0;
|
36
|
+
margin-left: -40px;
|
37
|
+
padding: 0;
|
38
|
+
font-size: 90%;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
div#index a {
|
43
|
+
margin-left: 0.7em;
|
44
|
+
}
|
45
|
+
|
46
|
+
div#index .section-bar {
|
47
|
+
margin-left: 0px;
|
48
|
+
padding-left: 0.7em;
|
49
|
+
background: #ccc;
|
50
|
+
font-size: small;
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
div#classHeader, div#fileHeader {
|
55
|
+
width: auto;
|
56
|
+
color: white;
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
58
|
+
margin: 0;
|
59
|
+
margin-left: -40px;
|
60
|
+
border-bottom: 3px solid #006;
|
61
|
+
}
|
62
|
+
|
63
|
+
div#classHeader a, div#fileHeader a {
|
64
|
+
background: inherit;
|
65
|
+
color: white;
|
66
|
+
}
|
67
|
+
|
68
|
+
div#classHeader td, div#fileHeader td {
|
69
|
+
background: inherit;
|
70
|
+
color: white;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
div#fileHeader {
|
75
|
+
background: #057;
|
76
|
+
}
|
77
|
+
|
78
|
+
div#classHeader {
|
79
|
+
background: #048;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
.class-name-in-header {
|
84
|
+
font-size: 180%;
|
85
|
+
font-weight: bold;
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
div#bodyContent {
|
90
|
+
padding: 0 1.5em 0 1.5em;
|
91
|
+
}
|
92
|
+
|
93
|
+
div#description {
|
94
|
+
padding: 0.5em 1.5em;
|
95
|
+
background: #efefef;
|
96
|
+
border: 1px dotted #999;
|
97
|
+
}
|
98
|
+
|
99
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
100
|
+
color: #125;;
|
101
|
+
background: transparent;
|
102
|
+
}
|
103
|
+
|
104
|
+
div#validator-badges {
|
105
|
+
text-align: center;
|
106
|
+
}
|
107
|
+
div#validator-badges img { border: 0; }
|
108
|
+
|
109
|
+
div#copyright {
|
110
|
+
color: #333;
|
111
|
+
background: #efefef;
|
112
|
+
font: 0.75em sans-serif;
|
113
|
+
margin-top: 5em;
|
114
|
+
margin-bottom: 0;
|
115
|
+
padding: 0.5em 2em;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
/* === Classes =================================== */
|
120
|
+
|
121
|
+
table.header-table {
|
122
|
+
color: white;
|
123
|
+
font-size: small;
|
124
|
+
}
|
125
|
+
|
126
|
+
.type-note {
|
127
|
+
font-size: small;
|
128
|
+
color: #DEDEDE;
|
129
|
+
}
|
130
|
+
|
131
|
+
.xxsection-bar {
|
132
|
+
background: #eee;
|
133
|
+
color: #333;
|
134
|
+
padding: 3px;
|
135
|
+
}
|
136
|
+
|
137
|
+
.section-bar {
|
138
|
+
color: #333;
|
139
|
+
border-bottom: 1px solid #999;
|
140
|
+
margin-left: -20px;
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
.section-title {
|
145
|
+
background: #79a;
|
146
|
+
color: #eee;
|
147
|
+
padding: 3px;
|
148
|
+
margin-top: 2em;
|
149
|
+
margin-left: -30px;
|
150
|
+
border: 1px solid #999;
|
151
|
+
}
|
152
|
+
|
153
|
+
.top-aligned-row { vertical-align: top }
|
154
|
+
.bottom-aligned-row { vertical-align: bottom }
|
155
|
+
|
156
|
+
/* --- Context section classes ----------------------- */
|
157
|
+
|
158
|
+
.context-row { }
|
159
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
160
|
+
.context-item-value { font-size: small; color: #448; }
|
161
|
+
.context-item-desc { color: #333; padding-left: 2em; }
|
162
|
+
|
163
|
+
/* --- Method classes -------------------------- */
|
164
|
+
.method-detail {
|
165
|
+
background: #efefef;
|
166
|
+
padding: 0;
|
167
|
+
margin-top: 0.5em;
|
168
|
+
margin-bottom: 1em;
|
169
|
+
border: 1px dotted #ccc;
|
170
|
+
}
|
171
|
+
.method-heading {
|
172
|
+
color: black;
|
173
|
+
background: #ccc;
|
174
|
+
border-bottom: 1px solid #666;
|
175
|
+
padding: 0.2em 0.5em 0 0.5em;
|
176
|
+
}
|
177
|
+
.method-signature { color: black; background: inherit; }
|
178
|
+
.method-name { font-weight: bold; }
|
179
|
+
.method-args { font-style: italic; }
|
180
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
181
|
+
|
182
|
+
/* --- Source code sections -------------------- */
|
183
|
+
|
184
|
+
a.source-toggle { font-size: 90%; }
|
185
|
+
div.method-source-code {
|
186
|
+
background: #262626;
|
187
|
+
color: #ffdead;
|
188
|
+
margin: 1em;
|
189
|
+
padding: 0.5em;
|
190
|
+
border: 1px dashed #999;
|
191
|
+
overflow: hidden;
|
192
|
+
}
|
193
|
+
|
194
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
195
|
+
|
196
|
+
/* --- Ruby keyword styles --------------------- */
|
197
|
+
|
198
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
199
|
+
|
200
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
201
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
202
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
203
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
204
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
205
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
206
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
207
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
208
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
@@ -0,0 +1,497 @@
|
|
1
|
+
#
|
2
|
+
# The Generator module contains two public methods that generate a Galaxy's tool
|
3
|
+
# XML and script files
|
4
|
+
#
|
5
|
+
module Generator
|
6
|
+
|
7
|
+
# private methods
|
8
|
+
private
|
9
|
+
|
10
|
+
# Used to create indentation when generating code
|
11
|
+
def indent(n)
|
12
|
+
ind = ""
|
13
|
+
n.times { ind += " " }
|
14
|
+
ind
|
15
|
+
end
|
16
|
+
|
17
|
+
# Galaxy's XML tool tag
|
18
|
+
def tool_begin_tag(out, name)
|
19
|
+
out.write("<tool id=\"#{name}_id\" name=\"#{name}\">\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Galaxy's XML command tag
|
23
|
+
def command_tag(out, t2_workflow, script)
|
24
|
+
out.write indent(1) + "<command interpreter=\"ruby\">\n"
|
25
|
+
out.write indent(2) + script + "\n"
|
26
|
+
|
27
|
+
# inputs
|
28
|
+
t2_workflow.inputs.each do |i|
|
29
|
+
out.write indent(2) + "#if $#{i.name}_source.history_or_textfield == \"textfield\":\n"
|
30
|
+
out.write indent(3) + "false \"$#{i.name}_source.textfield_#{i.name}\"\n"
|
31
|
+
out.write indent(2) + "#else:\n"
|
32
|
+
out.write indent(3) + "true \"$#{i.name}_source.history_#{i.name}\"\n"
|
33
|
+
out.write indent(2) + "#end if\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
# results as zip input
|
37
|
+
out.write indent(2) + "$results_as_zip\n"
|
38
|
+
|
39
|
+
# outputs
|
40
|
+
out.write indent(2)
|
41
|
+
t2_workflow.outputs.each do |o|
|
42
|
+
out.write "$#{o.name} "
|
43
|
+
end
|
44
|
+
|
45
|
+
# result zip output
|
46
|
+
out.write "$result_zip\n"
|
47
|
+
|
48
|
+
out.write indent(1) + "</command>\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# Galaxy's XML inputs tag
|
53
|
+
def inputs_tag(out, inputs)
|
54
|
+
out.write indent(1) + "<inputs>\n"
|
55
|
+
if inputs.size >= 1
|
56
|
+
inputs.each do |i|
|
57
|
+
out.write indent(2) + "<conditional name=\"#{i.name}_source\">\n"
|
58
|
+
out.write indent(3) + "<param name=\"history_or_textfield\" type=\"select\" label=\"Select source for #{i.name}\">\n"
|
59
|
+
out.write indent(4) + "<option value=\"history\">From history</option>\n"
|
60
|
+
out.write indent(4) + "<option value=\"textfield\" selected=\"true\">Type manually</option>\n"
|
61
|
+
out.write indent(3) + "</param>\n"
|
62
|
+
out.write indent(3) + "<when value=\"history\">\n"
|
63
|
+
out.write indent(4) + "<param name=\"history_#{i.name}\" type=\"data\" label=\"Select #{i.name}\"/>\n"
|
64
|
+
out.write indent(3) + "</when>\n"
|
65
|
+
out.write indent(3) + "<when value=\"textfield\">\n"
|
66
|
+
out.write indent(4) + "<param name=\"textfield_#{i.name}\" type=\"text\" area=\"True\" size=\"2x50\" "
|
67
|
+
if i.examples.size >= 1
|
68
|
+
# escape double quotes characters for galaxy's xml file
|
69
|
+
ex = i.examples[0].to_s.gsub('"', '"')
|
70
|
+
# convert newlines to HTML newlines to display in textareas inputs
|
71
|
+
ex = ex.gsub(/[\n]/, '
')
|
72
|
+
out.write "value=\"#{ex}\" "
|
73
|
+
end
|
74
|
+
out.write "label=\"Enter #{i.name}\"/>\n"
|
75
|
+
out.write indent(3) + "</when>\n"
|
76
|
+
out.write indent(2) + "</conditional>\n"
|
77
|
+
end
|
78
|
+
else
|
79
|
+
out.write indent(2) + "<param name=\"input\" type=\"select\" display=\"radio\" size=\"250\" label=\"This workflow has no inputs\" />\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
# result as zip input
|
83
|
+
out.write indent(2) + "<param name=\"results_as_zip\" type=\"select\" label=\"Would you also like the raw results as a zip file\">\n"
|
84
|
+
out.write indent(3) + "<option value=\"yes\">Yes</option>\n"
|
85
|
+
out.write indent(3) + "<option value=\"no\" selected=\"true\">No</option>\n"
|
86
|
+
out.write indent(2) + "</param>\n"
|
87
|
+
|
88
|
+
out.write indent(1) + "</inputs>\n"
|
89
|
+
end
|
90
|
+
|
91
|
+
# Galaxy's XML outputs tag
|
92
|
+
def outputs_tag(out, outputs)
|
93
|
+
out.write indent(1) + "<outputs>\n"
|
94
|
+
outputs.each do |o|
|
95
|
+
out.write indent(2) + "<data format=\"tabular\" name=\"#{o.name}\" label=\"#{o.name}\"/>\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
# result zip output
|
99
|
+
out.write indent(2) + "<data format=\"zip\" name=\"result_zip\" label=\"Compressed Results (zip)\">\n"
|
100
|
+
out.write indent(3) + "<filter>results_as_zip == \"yes\"</filter>\n"
|
101
|
+
out.write indent(2) + "</data>\n"
|
102
|
+
|
103
|
+
out.write indent(1) + "</outputs>\n"
|
104
|
+
end
|
105
|
+
|
106
|
+
# Galaxy's XML help tag
|
107
|
+
def help_tag(out, t2_workflow)
|
108
|
+
out.write indent(1) + "<help>\n"
|
109
|
+
out.write "**What it does**\n\n"
|
110
|
+
|
111
|
+
description = t2_workflow.description + "\n\n"
|
112
|
+
|
113
|
+
# Sometimes the workflow description contains HTML tags that are not allowed
|
114
|
+
# in Galaxy's xml interface specification and thus are removed! Same for
|
115
|
+
# HTML entities!
|
116
|
+
# TODO go through tags and find Galaxy's equivalent to include
|
117
|
+
description.gsub!(/<.*?>|&.*?;/, '')
|
118
|
+
|
119
|
+
# To remove ^M (cntl-v + cntl-m) characters that DOS files might have
|
120
|
+
description.gsub!(/\r/, '')
|
121
|
+
|
122
|
+
# TODO that works as a literal too but font changes to courier!
|
123
|
+
#out.write "::\n\n" # Start Galaxy's literal block to ignore indendation
|
124
|
+
|
125
|
+
# remove indendation from all description lines since Galaxy is confused by it
|
126
|
+
description.split(/[\n]/).each { |l| out.write "#{l.gsub(/^\s+/, '')}\n" }
|
127
|
+
|
128
|
+
# endline makes the following be parsed as a Galaxy GUI construct
|
129
|
+
out.write "\n"
|
130
|
+
|
131
|
+
# if at least one input add it to tool's UI help description
|
132
|
+
if t2_workflow.inputs.size >= 1
|
133
|
+
out.write "-----\n\n"
|
134
|
+
out.write "**Inputs**\n\n"
|
135
|
+
t2_workflow.inputs.each do |i|
|
136
|
+
out.write "- **#{i.name}** "
|
137
|
+
if i.descriptions.size >= 1
|
138
|
+
i.descriptions.each do |desc|
|
139
|
+
out.write desc.to_s + " "
|
140
|
+
end
|
141
|
+
end
|
142
|
+
if i.examples.size >= 1
|
143
|
+
out.write "Examples include:\n\n"
|
144
|
+
i.examples.each do |ex|
|
145
|
+
# some examples have a newline between them that breaks Galaxy's GUI
|
146
|
+
# so we substitute it with ' '
|
147
|
+
#out.write " - " + ex.to_s.gsub(/[\n]/, ' ') + "\n"
|
148
|
+
|
149
|
+
# We could substitute them with with 
 that works for HTML (e.g. wkf 1180)
|
150
|
+
# But if an example input is truly multiline then input descr. will
|
151
|
+
# display them all as separate inputs...
|
152
|
+
out.write " - " + ex.to_s.gsub(/[\n]/, '
 - ') + "\n"
|
153
|
+
|
154
|
+
# display example inputs as verbatim/literal so it is not our responsibility!!
|
155
|
+
# add indendation after each newline to specify the literal block
|
156
|
+
# TODO this looks ugly if we don't remove all the bullet points!
|
157
|
+
#out.write "::\n\n " + ex.to_s.gsub(/\n/, '
 ') + "\n"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
out.write "\n"
|
161
|
+
end
|
162
|
+
out.write "\n"
|
163
|
+
end
|
164
|
+
|
165
|
+
# if at least one output add it to tool's UI help description
|
166
|
+
if t2_workflow.outputs.size >= 1
|
167
|
+
out.write "-----\n\n"
|
168
|
+
out.write "**Outputs**\n\n"
|
169
|
+
t2_workflow.outputs.each do |o|
|
170
|
+
out.write "- **#{o.name}** "
|
171
|
+
if o.descriptions.size >= 1
|
172
|
+
o.descriptions.each do |desc|
|
173
|
+
out.write desc.to_s + " "
|
174
|
+
end
|
175
|
+
end
|
176
|
+
if o.examples.size >= 1
|
177
|
+
out.write "Examples include:\n\n"
|
178
|
+
o.examples.each do |ex|
|
179
|
+
out.write " - " + ex.to_s + "\n"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
out.write "\n"
|
183
|
+
end
|
184
|
+
out.write "\n"
|
185
|
+
end
|
186
|
+
|
187
|
+
out.write "-----\n\n"
|
188
|
+
out.write ".. class:: warningmark\n\n"
|
189
|
+
out.write "**Please note that some workflows are not up-to-date or have dependencies** " <<
|
190
|
+
"that cannot be met by the specific Taverna server that you specified during " <<
|
191
|
+
"generation of this tool. You can make sure that the workflow is valid " <<
|
192
|
+
"by running it in the Taverna Workbench first to confirm that it works " <<
|
193
|
+
"before running it via Galaxy.\n\n"
|
194
|
+
|
195
|
+
if t2_workflow.input_type == TavernaWorkflow::MY_EXPERIMENT
|
196
|
+
out.write "-----\n\n"
|
197
|
+
out.write ".. class:: warningmark\n\n"
|
198
|
+
out.write "**Please note that there might be some repetitions in the workflow description** " <<
|
199
|
+
"in some of the generated workflows. This is due to a backwards compatibility " <<
|
200
|
+
"issue on the myExperiment repository which keeps the old descriptions to make " <<
|
201
|
+
"sure that no information is lost.\n\n"
|
202
|
+
|
203
|
+
out.write "-----\n\n"
|
204
|
+
out.write ".. class:: infomark\n\n"
|
205
|
+
out.write "**For more information on that workflow please visit** #{t2_workflow.xml_uri.gsub(/(.*workflows\/\d+)[\/.].*/, '\1')}.\n\n"
|
206
|
+
end
|
207
|
+
|
208
|
+
out.write indent(1) + "</help>\n"
|
209
|
+
end
|
210
|
+
|
211
|
+
# Galaxy's XML tool tag close
|
212
|
+
def tool_end_tag(out)
|
213
|
+
out.write("</tool>\n")
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
# Galaxy's script preample
|
219
|
+
def script_preample(out)
|
220
|
+
out.write("#!/usr/bin/env ruby\n\n")
|
221
|
+
out.write("require 'rubygems'\n")
|
222
|
+
out.write("require 't2-server'\n")
|
223
|
+
out.write("require 'open-uri'\n")
|
224
|
+
out.write("require 'zip/zipfilesystem'\n\n")
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
# Galaxy's script utility methods
|
229
|
+
# TODO: use ruby's flatten instead of our own !!!
|
230
|
+
def script_util_methods(out)
|
231
|
+
|
232
|
+
out.write <<'UTIL_METHODS'
|
233
|
+
|
234
|
+
# sends the zip file to specified output
|
235
|
+
def output_zip_file(uuid, zip_out)
|
236
|
+
File.open("/tmp/#{uuid}.zip") do |zip|
|
237
|
+
while data = zip.read(4096)
|
238
|
+
zip_out.write data
|
239
|
+
end
|
240
|
+
end
|
241
|
+
File.delete("/tmp/#{uuid}.zip")
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
#
|
246
|
+
# replicates the directory result structure as constructed by the
|
247
|
+
# taverna server and recreates it in a zip File
|
248
|
+
#
|
249
|
+
def add_to_zip_file(output_dir, data_lists, zip_out)
|
250
|
+
zip_out.dir.mkdir("#{output_dir}")
|
251
|
+
data_lists.each_with_index do |item, index|
|
252
|
+
if item.instance_of? Array
|
253
|
+
add_to_zip_file("#{output_dir}/#{index+1}", item, zip_out)
|
254
|
+
else
|
255
|
+
zip_out.file.open("#{output_dir}/#{index+1}", "w") { |f| f.puts item }
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
# method that flattens the list of list of list ... result of get_output
|
262
|
+
def print_flattened_result(out, data_lists)
|
263
|
+
data_lists.each do |l|
|
264
|
+
if l.instance_of? Array
|
265
|
+
print_flattened_result(out, l)
|
266
|
+
else
|
267
|
+
out.puts l
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
#
|
274
|
+
# Method that acquires all the results of the specified output directory.
|
275
|
+
# If valid zip File is passed it also accumulates results as a zip file.
|
276
|
+
#
|
277
|
+
def get_outputs(run, refs, outfile, dir, zip_out=nil)
|
278
|
+
data_lists = run.get_output(dir, refs)
|
279
|
+
print_flattened_result(outfile, data_lists)
|
280
|
+
if zip_out
|
281
|
+
add_to_zip_file(dir, data_lists, zip_out)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
#
|
287
|
+
# Sanitize all special characters in UI inputs that Galaxy substitutes for
|
288
|
+
# security reasons. This methods turns them back to their original values before
|
289
|
+
# using them (i.e. sending them to the taverna server
|
290
|
+
# NB: note that double quote is sanitized to "'" that is because the double code
|
291
|
+
# confuses the Taverna server ruby library. Apparently, this is not trivial
|
292
|
+
# to fix.
|
293
|
+
#
|
294
|
+
def sanitize(string)
|
295
|
+
string.gsub(/(__sq__|__dq__|__at__|__cr__|__cn__|__tc__|__gt__|__lt__|__ob__|__cb__|__oc__|__cc__)/) do
|
296
|
+
if $1 == '__sq__'
|
297
|
+
"'"
|
298
|
+
elsif $1 == '__dq__'
|
299
|
+
"'"
|
300
|
+
elsif $1 == '__cr__'
|
301
|
+
"\r"
|
302
|
+
elsif $1 == '__cn__'
|
303
|
+
"\n"
|
304
|
+
elsif $1 == '__tc__'
|
305
|
+
"\t"
|
306
|
+
elsif $1 == '__gt__'
|
307
|
+
'>'
|
308
|
+
elsif $1 == '__lt__'
|
309
|
+
'<'
|
310
|
+
elsif $1 == '__ob__'
|
311
|
+
'['
|
312
|
+
elsif $1 == '__cb__'
|
313
|
+
']'
|
314
|
+
elsif $1 == '__oc__'
|
315
|
+
'{'
|
316
|
+
elsif $1 == '__cc__'
|
317
|
+
'}'
|
318
|
+
else
|
319
|
+
'@'
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
#
|
325
|
+
# Deletes last new line of file if it exists! It is needed for t2 workflows that
|
326
|
+
# do not sanitize properly, i.e. via a user-provided beanshell script
|
327
|
+
#
|
328
|
+
def chomp_last_newline(file)
|
329
|
+
|
330
|
+
if File.file?(file) and File.size(file) > 1
|
331
|
+
f = open(file, "rb+")
|
332
|
+
f.seek(-1, File::SEEK_END)
|
333
|
+
f.truncate(File.size(file) - 1) if f.read(1) == "\n"
|
334
|
+
f.close
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
|
340
|
+
UTIL_METHODS
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
# Galaxy's script taverna 2 run
|
345
|
+
def script_create_t2_run(out, wkf, t2_uri)
|
346
|
+
if wkf.input_type == TavernaWorkflow::MY_EXPERIMENT
|
347
|
+
out.write "# use the uri reference to download the workflow locally\n"
|
348
|
+
out.write "wkf_file = URI.parse('#{wkf.xml_uri}')\n"
|
349
|
+
out.write "in_wkf = open(wkf_file)\n"
|
350
|
+
else # TavernaWorkflow::T2_FLOW
|
351
|
+
out.write "# uri contains local t2flow file\n"
|
352
|
+
out.write "in_wkf = open('#{wkf.xml_uri}')\n"
|
353
|
+
end
|
354
|
+
|
355
|
+
out.write <<CREATE_T2_RUN
|
356
|
+
|
357
|
+
wkf = in_wkf.read()
|
358
|
+
|
359
|
+
# create run
|
360
|
+
begin
|
361
|
+
run = T2Server::Run.create('#{t2_uri}', wkf)
|
362
|
+
rescue T2Server::T2ServerError => e
|
363
|
+
exit 1
|
364
|
+
end
|
365
|
+
|
366
|
+
CREATE_T2_RUN
|
367
|
+
|
368
|
+
end
|
369
|
+
|
370
|
+
|
371
|
+
# Galaxy's script input handling
|
372
|
+
def script_init_inputs(out, t2_workflow)
|
373
|
+
out.write "#\n"
|
374
|
+
out.write "# Get input arguments -- for each input a boolean specifies if it's from history\n"
|
375
|
+
out.write "# thus, for each t2_workflow input we have two arguments in the script!\n"
|
376
|
+
out.write "#\n"
|
377
|
+
t2_workflow.inputs.each_with_index do |input, i|
|
378
|
+
i_name = input.name.to_s
|
379
|
+
out.write "#{i_name}_from_history = ARGV[#{i*2}].chomp\n"
|
380
|
+
out.write "#{i_name}_tmp = ARGV[#{i*2+1}].chomp\n"
|
381
|
+
out.write "if #{i_name}_from_history == \"true\"\n"
|
382
|
+
out.write " chomp_last_newline(#{i_name}_tmp)\n"
|
383
|
+
out.write " run.upload_input_file('#{i_name}', #{i_name}_tmp)\n"
|
384
|
+
out.write "else\n"
|
385
|
+
out.write " run.set_input('#{i_name}', sanitize(#{i_name}_tmp))\n"
|
386
|
+
out.write "end\n"
|
387
|
+
end
|
388
|
+
|
389
|
+
# add code to handle results_as_zip input, i.e. create zip file
|
390
|
+
out.write "\n# get results_as_zip input and open zip file if appropriate\n"
|
391
|
+
# get argument index after workflow inputs
|
392
|
+
zip_index = t2_workflow.inputs.size * 2
|
393
|
+
out.write "zipped = ARGV[#{zip_index}].chomp == \"yes\"\n"
|
394
|
+
out.write 'zip_out = Zip::ZipFile.open("/tmp/#{run.uuid}.zip", Zip::ZipFile::CREATE) if zipped' + "\n"
|
395
|
+
|
396
|
+
end
|
397
|
+
|
398
|
+
|
399
|
+
# Galaxy's script starting taverna run
|
400
|
+
def script_start_run(out)
|
401
|
+
out.write <<START_RUN
|
402
|
+
|
403
|
+
|
404
|
+
# start run and wait until it is finished
|
405
|
+
run.start
|
406
|
+
run.wait(:progress => true)
|
407
|
+
|
408
|
+
START_RUN
|
409
|
+
end
|
410
|
+
|
411
|
+
|
412
|
+
# Galaxy's script output handling
|
413
|
+
def script_get_outputs(out, t2_workflow)
|
414
|
+
# outputs start after all inputs plus the results_as_zip input
|
415
|
+
outputs_start_index = t2_workflow.inputs.size * 2 + 1
|
416
|
+
outputs_end_index = outputs_start_index + t2_workflow.outputs.size - 1
|
417
|
+
out.write "# get output arguments and associated them with a file\n"
|
418
|
+
outputs_start_index.upto(outputs_end_index) do |o|
|
419
|
+
out.write "output#{o} = File.open(ARGV[#{o}], \"w\")\n"
|
420
|
+
out.write "begin\n"
|
421
|
+
out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + "', zip_out)\n"
|
422
|
+
out.write "rescue Exception => err\n"
|
423
|
+
out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + ".error', zip_out)\n"
|
424
|
+
out.write "ensure\n"
|
425
|
+
out.write " output#{o}.close\n"
|
426
|
+
out.write "end\n"
|
427
|
+
end
|
428
|
+
|
429
|
+
# close zip file if created when dealing with the inputs
|
430
|
+
#--
|
431
|
+
# ideally that would semantically belong to a separate method
|
432
|
+
out.write "\n# close zip_out (the newly created zip file) if opened\n"
|
433
|
+
out.write "zip_out.close if zip_out\n"
|
434
|
+
|
435
|
+
# dealing with zip output here -- zip arg index is outputs_end_index (last
|
436
|
+
# output) plus 1
|
437
|
+
out.write "\n# open galaxy zip output and write zip file\n"
|
438
|
+
out.write "if zipped\n"
|
439
|
+
out.write " galaxy_zip_out = File.open(ARGV[#{outputs_end_index+1}], \"w\")\n"
|
440
|
+
out.write " output_zip_file(run.uuid, galaxy_zip_out)\n"
|
441
|
+
out.write " galaxy_zip_out.close\n"
|
442
|
+
out.write "end\n"
|
443
|
+
|
444
|
+
end
|
445
|
+
|
446
|
+
|
447
|
+
# Galaxy's script cleaning taverna run
|
448
|
+
def script_finish_run(out)
|
449
|
+
out.write "\n# delete run\n"
|
450
|
+
out.write "run.delete\n"
|
451
|
+
end
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
|
456
|
+
|
457
|
+
# public methods from here onwards
|
458
|
+
public
|
459
|
+
|
460
|
+
# Generates the Galaxy tool's xml file responsible for the UI.
|
461
|
+
#
|
462
|
+
# :call-seq:
|
463
|
+
# Generator.generate_xml(my_exp_rest, xml_file) -> nil
|
464
|
+
#
|
465
|
+
# [+t2_workflow+] a _Workflow_ object as returned from <em>MyExperimentREST::Workflows.new.read(url)</em>
|
466
|
+
# [+xml_file+] a string containing the name of the generated XML file
|
467
|
+
# [+xml_out+] the file handler to write the generated XML tags
|
468
|
+
def generate_xml(t2_workflow, xml_file, xml_out)
|
469
|
+
tool_begin_tag(xml_out, t2_workflow.title)
|
470
|
+
command_tag(xml_out, t2_workflow, xml_file.gsub('.xml', '.rb'))
|
471
|
+
inputs_tag(xml_out, t2_workflow.inputs)
|
472
|
+
outputs_tag(xml_out, t2_workflow.outputs)
|
473
|
+
help_tag(xml_out, t2_workflow)
|
474
|
+
tool_end_tag(xml_out)
|
475
|
+
end
|
476
|
+
|
477
|
+
|
478
|
+
# Generates the Galaxy tool's script file responsible for talking to the
|
479
|
+
# taverna server
|
480
|
+
#
|
481
|
+
# :call-seq:
|
482
|
+
# Generator.generate_script(my_exp_rest, t2_server, script_file) -> nil
|
483
|
+
#
|
484
|
+
# [+my_exp_rest+] a _Workflow_ object as returned from <em>MyExperimentREST.ReadWorkflow.new(url)</em>
|
485
|
+
# [<tt>t2_server</tt>] a string containing the URL of the taverna 2 server
|
486
|
+
# [+script_out+] the file handler to write the generated script code
|
487
|
+
def generate_script(t2_workflow, t2_server, script_out)
|
488
|
+
script_preample(script_out)
|
489
|
+
script_util_methods(script_out)
|
490
|
+
script_create_t2_run(script_out, t2_workflow, t2_server)
|
491
|
+
script_init_inputs(script_out, t2_workflow)
|
492
|
+
script_start_run(script_out)
|
493
|
+
script_get_outputs(script_out, t2_workflow)
|
494
|
+
script_finish_run(script_out)
|
495
|
+
end
|
496
|
+
|
497
|
+
end
|