rbbt-util 3.2.1 → 4.0.0
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/README.rdoc +65 -0
- data/bin/run_workflow.rb +142 -69
- data/lib/rbbt-util.rb +3 -3
- data/lib/rbbt.rb +12 -3
- data/lib/rbbt/annotations.rb +215 -0
- data/lib/rbbt/{util/fix_width_table.rb → fix_width_table.rb} +17 -13
- data/lib/rbbt/persist.rb +164 -0
- data/lib/rbbt/persist/tsv.rb +135 -0
- data/lib/rbbt/resource.rb +100 -0
- data/lib/rbbt/resource/path.rb +180 -0
- data/lib/rbbt/resource/rake.rb +48 -0
- data/lib/rbbt/resource/util.rb +111 -0
- data/lib/rbbt/resource/with_key.rb +28 -0
- data/lib/rbbt/tsv.rb +134 -0
- data/lib/rbbt/tsv/accessor.rb +345 -0
- data/lib/rbbt/tsv/attach.rb +183 -0
- data/lib/rbbt/tsv/attach/util.rb +277 -0
- data/lib/rbbt/{util/tsv/filters.rb → tsv/filter.rb} +76 -37
- data/lib/rbbt/tsv/index.rb +453 -0
- data/lib/rbbt/tsv/manipulate.rb +361 -0
- data/lib/rbbt/tsv/parser.rb +231 -0
- data/lib/rbbt/tsv/serializers.rb +79 -0
- data/lib/rbbt/tsv/util.rb +67 -0
- data/lib/rbbt/util/R.rb +3 -3
- data/lib/rbbt/util/chain_methods.rb +64 -0
- data/lib/rbbt/util/cmd.rb +17 -13
- data/lib/rbbt/util/excel2tsv.rb +4 -3
- data/lib/rbbt/util/log.rb +1 -0
- data/lib/rbbt/util/misc.rb +296 -285
- data/lib/rbbt/util/open.rb +9 -2
- data/lib/rbbt/util/persistence.rb +1 -1
- data/lib/rbbt/util/task/job.rb +3 -1
- data/lib/rbbt/workflow.rb +193 -0
- data/lib/rbbt/workflow/accessor.rb +249 -0
- data/lib/rbbt/workflow/annotate.rb +60 -0
- data/lib/rbbt/workflow/soap.rb +100 -0
- data/lib/rbbt/workflow/step.rb +102 -0
- data/lib/rbbt/workflow/task.rb +76 -0
- data/test/rbbt/resource/test_path.rb +12 -0
- data/test/rbbt/test_annotations.rb +106 -0
- data/test/rbbt/{util/test_fix_width_table.rb → test_fix_width_table.rb} +8 -9
- data/test/rbbt/test_resource.rb +66 -0
- data/test/rbbt/test_tsv.rb +332 -0
- data/test/rbbt/test_workflow.rb +102 -0
- data/test/rbbt/tsv/test_accessor.rb +163 -0
- data/test/rbbt/{util/tsv → tsv}/test_attach.rb +86 -43
- data/test/rbbt/{util/tsv/test_filters.rb → tsv/test_filter.rb} +31 -13
- data/test/rbbt/tsv/test_index.rb +284 -0
- data/test/rbbt/{util/tsv → tsv}/test_manipulate.rb +35 -105
- data/test/rbbt/util/test_R.rb +1 -1
- data/test/rbbt/util/test_chain_methods.rb +22 -0
- data/test/rbbt/util/test_filecache.rb +0 -1
- data/test/rbbt/util/test_misc.rb +97 -79
- data/test/rbbt/util/test_open.rb +1 -0
- data/test/rbbt/util/test_tmpfile.rb +1 -1
- data/test/rbbt/workflow/test_soap.rb +103 -0
- data/test/rbbt/workflow/test_step.rb +142 -0
- data/test/rbbt/workflow/test_task.rb +84 -0
- data/test/test_helper.rb +7 -7
- metadata +80 -54
- data/lib/rbbt/util/rake.rb +0 -176
- data/lib/rbbt/util/resource.rb +0 -355
- data/lib/rbbt/util/task.rb +0 -183
- data/lib/rbbt/util/tc_hash.rb +0 -324
- data/lib/rbbt/util/tsv.rb +0 -236
- data/lib/rbbt/util/tsv/accessor.rb +0 -312
- data/lib/rbbt/util/tsv/attach.rb +0 -416
- data/lib/rbbt/util/tsv/index.rb +0 -419
- data/lib/rbbt/util/tsv/manipulate.rb +0 -300
- data/lib/rbbt/util/tsv/misc.rb +0 -41
- data/lib/rbbt/util/tsv/parse.rb +0 -324
- data/lib/rbbt/util/tsv/resource.rb +0 -88
- data/lib/rbbt/util/workflow.rb +0 -135
- data/lib/rbbt/util/workflow/soap.rb +0 -116
- data/test/rbbt/util/test_persistence.rb +0 -201
- data/test/rbbt/util/test_rake.rb +0 -54
- data/test/rbbt/util/test_resource.rb +0 -77
- data/test/rbbt/util/test_task.rb +0 -133
- data/test/rbbt/util/test_tc_hash.rb +0 -144
- data/test/rbbt/util/test_tsv.rb +0 -221
- data/test/rbbt/util/test_workflow.rb +0 -135
- data/test/rbbt/util/tsv/test_accessor.rb +0 -150
- data/test/rbbt/util/tsv/test_index.rb +0 -241
- data/test/rbbt/util/tsv/test_parse.rb +0 -87
- data/test/rbbt/util/tsv/test_resource.rb +0 -9
data/README.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= Install
|
2
|
+
|
3
|
+
1 - install rvm: https://rvm.beginrescueend.com/ (will need git and curl installed)
|
4
|
+
|
5
|
+
:script
|
6
|
+
|
7
|
+
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
|
8
|
+
cd
|
9
|
+
cat .bash_profile > tmp.bash_profile
|
10
|
+
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >> tmp.bash_profile
|
11
|
+
cp .bash_profile .bash_profile.save
|
12
|
+
mv tmp.bash_profile .bash_profile
|
13
|
+
. .bash_profile
|
14
|
+
rvm install 1.8.7
|
15
|
+
|
16
|
+
2 - install tokyocabinet (Intructions for user install follow. For system level, make sure we have dev package)
|
17
|
+
1 - download source from http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz
|
18
|
+
2 - unpack and compile using a user-level prefix
|
19
|
+
3 - set LD_RUN_PATH and LD_LIBRARY_PATH to point there
|
20
|
+
|
21
|
+
:script
|
22
|
+
|
23
|
+
cd
|
24
|
+
mkdir -p tmp/tokyocabinet
|
25
|
+
cd tmp/tokyocabinet
|
26
|
+
wget "http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz"
|
27
|
+
tar xvfz tokyocabinet-1.4.47.tar.gz
|
28
|
+
cd tokyocabinet-1.4.47
|
29
|
+
./configure --prefix="$HOME/software/opt/tokyocabinet"
|
30
|
+
make
|
31
|
+
make install
|
32
|
+
cd
|
33
|
+
cat .bash_profile > tmp.bash_profile
|
34
|
+
echo "export LD_RUN_PATH='$LD_RUN_PATH:$HOME/software/opt/tokyocabinet/lib'" >> tmp.bash_profile
|
35
|
+
echo "export LD_LIBRARY_PATH='$LD_LIBRARY_PATH:$HOME/software/opt/tokyocabinet/lib'" >> tmp.bash_profile
|
36
|
+
echo "export PATH='$PATH:$HOME/software/opt/tokyocabinet/bin'" >> tmp.bash_profile
|
37
|
+
cp .bash_profile .bash_profile.save2
|
38
|
+
mv tmp.bash_profile .bash_profile
|
39
|
+
. .bash_profile
|
40
|
+
|
41
|
+
3 - install gems rbbt-util rbbt-sources rbbt-text rbbt-phgx
|
42
|
+
|
43
|
+
:script
|
44
|
+
|
45
|
+
gem install rbbt-util rbbt-sources rbbt-text rbbt-phgx
|
46
|
+
|
47
|
+
3.bis - Or install github repos and make ruby use them
|
48
|
+
|
49
|
+
:script
|
50
|
+
|
51
|
+
cd
|
52
|
+
cd git/
|
53
|
+
git clone git://github.com/mikisvaz/rbbt-util.git
|
54
|
+
git clone git://github.com/mikisvaz/rbbt-sources.git
|
55
|
+
git clone git://github.com/mikisvaz/rbbt-text.git
|
56
|
+
git clone git://github.com/mikisvaz/rbbt-phgx.git
|
57
|
+
alias druby="env RBBT_LOG=0 ruby $(for d in $HOME/git/rbbt-*;do echo -n "-I$d/lib ";done)"
|
58
|
+
alias drake="env RBBT_LOG=0 rake $(for d in $HOME/git/rbbt-*;do echo -n "-I$d/lib ";done)"
|
59
|
+
|
60
|
+
4 - Set up R to find the helper lib
|
61
|
+
|
62
|
+
:script
|
63
|
+
|
64
|
+
echo "source(system('rbbt_Rutil.rb', intern =T));" >> $HOME/.Rprofile
|
65
|
+
|
data/bin/run_workflow.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'rbbt
|
3
|
+
require 'rbbt'
|
4
4
|
require 'rbbt/util/simpleopt'
|
5
|
-
require 'rbbt/
|
5
|
+
require 'rbbt/workflow'
|
6
6
|
require 'pp'
|
7
7
|
|
8
8
|
def usage(task)
|
@@ -10,12 +10,11 @@ def usage(task)
|
|
10
10
|
exit -1
|
11
11
|
end
|
12
12
|
|
13
|
-
def SOPT_options(task)
|
13
|
+
def SOPT_options(workflow, task)
|
14
14
|
sopt_options = []
|
15
|
-
task.
|
16
|
-
name = info[:name]
|
15
|
+
workflow.rec_inputs(task.name).each do |name|
|
17
16
|
short = name.to_s.chars.first
|
18
|
-
boolean =
|
17
|
+
boolean = workflow.rec_input_types(task.name)[name].to_sym == :boolean
|
19
18
|
|
20
19
|
sopt_options << "-#{short}--#{name}#{boolean ? '' : '*'}"
|
21
20
|
end
|
@@ -23,28 +22,54 @@ def SOPT_options(task)
|
|
23
22
|
sopt_options * ":"
|
24
23
|
end
|
25
24
|
|
26
|
-
def fix_options(task, job_options)
|
27
|
-
option_types = task.
|
25
|
+
def fix_options(workflow, task, job_options)
|
26
|
+
option_types = workflow.rec_input_types(task.name)
|
27
|
+
|
28
|
+
workflow.resolve_locals(job_options)
|
28
29
|
|
29
30
|
job_options_cleaned = {}
|
30
31
|
|
31
32
|
job_options.each do |name, value|
|
32
|
-
value = case
|
33
|
-
when
|
33
|
+
value = case option_types[name].to_sym
|
34
|
+
when :float
|
34
35
|
value.to_f
|
35
|
-
when
|
36
|
+
when :integer
|
36
37
|
value.to_i
|
37
|
-
when
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
when :string, :text
|
39
|
+
case
|
40
|
+
when value == '-'
|
41
|
+
STDIN.read
|
42
|
+
when (String === value and File.exists?(value))
|
43
|
+
Open.read(value)
|
44
|
+
else
|
45
|
+
value
|
46
|
+
end
|
47
|
+
when :array
|
48
|
+
if Array === value
|
49
|
+
value
|
50
|
+
else
|
51
|
+
case
|
52
|
+
when value == '-'
|
53
|
+
STDIN.read
|
54
|
+
when (String === value and File.exists?(value))
|
55
|
+
Open.read(value)
|
43
56
|
else
|
44
|
-
|
45
|
-
end
|
46
|
-
|
57
|
+
value
|
58
|
+
end.split(/[,|\s]/)
|
59
|
+
end
|
60
|
+
when :tsv
|
61
|
+
if TSV === value
|
47
62
|
value
|
63
|
+
else
|
64
|
+
begin
|
65
|
+
if value == '-'
|
66
|
+
TSV.open(STDIN).to_s :sort
|
67
|
+
else
|
68
|
+
TSV.new(value).to_s :sort
|
69
|
+
end
|
70
|
+
rescue
|
71
|
+
value
|
72
|
+
end
|
48
73
|
end
|
49
74
|
else
|
50
75
|
value
|
@@ -55,64 +80,112 @@ def fix_options(task, job_options)
|
|
55
80
|
job_options_cleaned
|
56
81
|
end
|
57
82
|
|
58
|
-
options = SOPT.get "-t--task*:-l--log*:-h--help:-n--name
|
83
|
+
options = SOPT.get "-t--task*:-l--log*:-h--help:-n--name*:-cl--clean:-rcl-recursive_clean:-pn--printname:-srv--server"
|
59
84
|
|
60
|
-
# Set log, fork, clean, recursive_clean and help
|
61
|
-
Log.severity = options[:log].to_i if options.include? :log
|
62
|
-
help = !!options.delete(:help)
|
63
|
-
do_fork = !!options.delete(:fork)
|
64
|
-
clean = !!options.delete(:clean)
|
65
|
-
recursive_clean = !!options.delete(:recursive_clean)
|
66
|
-
|
67
|
-
# Get workflow
|
68
85
|
workflow = ARGV.first
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
namespace = Misc.string2const(namespace)
|
86
|
+
|
87
|
+
if options[:server]
|
88
|
+
require 'rbbt/util/log'
|
89
|
+
require 'rbbt/workflow'
|
90
|
+
require 'rbbt/workflow/rest'
|
91
|
+
require 'sinatra'
|
92
|
+
require 'compass'
|
93
|
+
|
94
|
+
Workflow.require_workflow workflow
|
95
|
+
WorkflowREST.add_workflows Workflow.workflows.last
|
96
|
+
|
97
|
+
WorkflowREST.setup
|
82
98
|
else
|
83
|
-
task_name = options.delete(:task)
|
84
|
-
task = self.tasks[task_name]
|
85
|
-
end
|
86
99
|
|
87
|
-
|
100
|
+
# Set log, fork, clean, recursive_clean and help
|
101
|
+
Log.severity = options[:log].to_i if options.include? :log
|
102
|
+
help = !!options.delete(:help)
|
103
|
+
do_fork = !!options.delete(:fork)
|
104
|
+
clean = !!options.delete(:clean)
|
105
|
+
recursive_clean = !!options.delete(:recursive_clean)
|
106
|
+
|
88
107
|
|
89
|
-
|
108
|
+
# Get workflow
|
109
|
+
|
110
|
+
if Rbbt.etc.remote_workflows.exists?
|
111
|
+
remote_workflows = Rbbt.etc.remote_workflows.yaml
|
112
|
+
else
|
113
|
+
remote_workflows = {}
|
114
|
+
end
|
115
|
+
|
116
|
+
if remote_workflows.include? workflow
|
117
|
+
require 'rbbt/workflow/rest/client'
|
118
|
+
workflow = RbbtRestClient.new remote_workflows[workflow]
|
119
|
+
else
|
120
|
+
Workflow.require_workflow workflow
|
121
|
+
workflow = Workflow.workflows.last
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set task
|
125
|
+
namespace, task = nil, nil
|
126
|
+
|
127
|
+
case
|
128
|
+
when (not options[:task])
|
129
|
+
usage if help
|
130
|
+
task = workflow.last_task
|
131
|
+
namespace = workflow
|
132
|
+
when (options[:task] =~ /\./)
|
133
|
+
namespace, task = options.delete(:task).split('.')
|
134
|
+
namespace = Misc.string2const(namespace)
|
135
|
+
else
|
136
|
+
task_name = options.delete(:task)
|
137
|
+
task = workflow.tasks[task_name]
|
138
|
+
raise "Task not found: #{ task_name }" if task.nil?
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
workflow.usage(task) if help
|
90
143
|
|
91
|
-
|
92
|
-
sopt_option_string = SOPT_options(task)
|
93
|
-
job_options = SOPT.get sopt_option_string
|
94
|
-
job_options = fix_options(task, job_options)
|
144
|
+
name = options.delete(:name) || "Default"
|
95
145
|
|
96
|
-
|
97
|
-
|
146
|
+
# get job args
|
147
|
+
sopt_option_string = SOPT_options(workflow,task)
|
148
|
+
job_options = SOPT.get sopt_option_string
|
149
|
+
job_options = fix_options(workflow,task, job_options)
|
98
150
|
|
99
|
-
|
100
|
-
job.
|
101
|
-
job.recursive_clean if recursive_clean
|
151
|
+
#- get job
|
152
|
+
job = workflow.job(task.name, name, job_options)
|
102
153
|
|
103
|
-
#
|
104
|
-
if
|
105
|
-
job.
|
106
|
-
|
107
|
-
|
108
|
-
|
154
|
+
# clean job
|
155
|
+
job.clean if clean
|
156
|
+
job.recursive_clean if recursive_clean
|
157
|
+
|
158
|
+
# run
|
159
|
+
if do_fork
|
160
|
+
job.fork
|
161
|
+
while not job.done?
|
162
|
+
Log.debug "#{job.step}: #{job.messages.last}"
|
163
|
+
sleep 2
|
164
|
+
end
|
165
|
+
raise job.messages.last if job.error?
|
166
|
+
res = job.load
|
167
|
+
else
|
168
|
+
res = job.run
|
109
169
|
end
|
110
|
-
else
|
111
|
-
job.run
|
112
|
-
end
|
113
170
|
|
114
|
-
|
115
|
-
|
171
|
+
if options.delete(:printname)
|
172
|
+
puts job.name
|
173
|
+
exit
|
174
|
+
else
|
175
|
+
Log.low "Job name: #{job.name}"
|
176
|
+
end
|
116
177
|
|
117
|
-
|
118
|
-
|
178
|
+
#- error
|
179
|
+
|
180
|
+
#print
|
181
|
+
case
|
182
|
+
when Array === res
|
183
|
+
puts res * "\n"
|
184
|
+
when TSV === res
|
185
|
+
puts res
|
186
|
+
when Hash === res
|
187
|
+
puts res.to_yaml
|
188
|
+
else
|
189
|
+
puts res
|
190
|
+
end
|
191
|
+
end
|
data/lib/rbbt-util.rb
CHANGED
@@ -3,11 +3,11 @@ require 'rbbt/util/open'
|
|
3
3
|
require 'rbbt/util/cmd'
|
4
4
|
require 'rbbt/util/tmpfile'
|
5
5
|
require 'rbbt/util/filecache'
|
6
|
-
require 'rbbt/
|
7
|
-
require 'rbbt/
|
6
|
+
require 'rbbt/tsv'
|
7
|
+
require 'rbbt/persist'
|
8
8
|
require 'rbbt/util/misc'
|
9
9
|
|
10
10
|
FileCache.cachedir = Rbbt.var.cache.filecache.find :user
|
11
11
|
Open.cachedir = Rbbt.var.cache["open-remote"].find :user
|
12
12
|
TmpFile.tmpdir = Rbbt.tmp.find :user
|
13
|
-
|
13
|
+
Persist.cachedir = Rbbt.var.cache.persistence.find :user
|
data/lib/rbbt.rb
CHANGED
@@ -1,7 +1,16 @@
|
|
1
|
-
require 'rbbt/util/
|
1
|
+
require 'rbbt/util/open'
|
2
|
+
require 'rbbt/util/tmpfile'
|
3
|
+
require 'rbbt/util/filecache'
|
4
|
+
require 'rbbt/tsv'
|
5
|
+
require 'rbbt/persist'
|
6
|
+
require 'rbbt/resource'
|
2
7
|
|
3
8
|
module Rbbt
|
4
9
|
extend Resource
|
5
|
-
|
6
|
-
|
10
|
+
pkgdir = 'rbbt'
|
7
11
|
|
12
|
+
FileCache.cachedir = var.cache.filecache.find :user
|
13
|
+
TmpFile.tmpdir = tmp.find :user
|
14
|
+
Open.cachedir = var.cache["open-remote"].find :user
|
15
|
+
Persist.cachedir = var.cache.persistence.find :user
|
16
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'rbbt/util/chain_methods'
|
2
|
+
require 'json'
|
3
|
+
module Annotated
|
4
|
+
attr_accessor :annotation_types
|
5
|
+
|
6
|
+
def self.extended(base)
|
7
|
+
base.annotation_types ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def annotations
|
11
|
+
annotation_types.collect do |mod|
|
12
|
+
mod.annotations
|
13
|
+
end.flatten.uniq
|
14
|
+
end
|
15
|
+
|
16
|
+
def info
|
17
|
+
hash = {:annotation_types => annotation_types}
|
18
|
+
annotations.each do |annotation|
|
19
|
+
value = self.send(annotation)
|
20
|
+
hash[annotation] = value unless value.nil?
|
21
|
+
end
|
22
|
+
hash
|
23
|
+
end
|
24
|
+
|
25
|
+
def id
|
26
|
+
Misc.hash2md5 info
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.load(object, info)
|
30
|
+
annotation_types = info[:annotation_types]
|
31
|
+
annotation_types.each do |mod|
|
32
|
+
mod = Misc.string2const(mod) if String === mod
|
33
|
+
mod.setup_info(object, info)
|
34
|
+
end
|
35
|
+
|
36
|
+
object
|
37
|
+
end
|
38
|
+
|
39
|
+
def tsv_values(*fields)
|
40
|
+
fields = fields.flatten
|
41
|
+
info = self.info
|
42
|
+
values = []
|
43
|
+
fields.each do |field|
|
44
|
+
values << case
|
45
|
+
when field == "JSON"
|
46
|
+
info.to_json
|
47
|
+
when field == "literal"
|
48
|
+
self.gsub(/\n|\t/, ' ')
|
49
|
+
when info.include?(field.to_sym)
|
50
|
+
info.delete(field.to_sym)
|
51
|
+
when self.respond_to?(field)
|
52
|
+
self.send(field)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
values
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.load_tsv_values(id, values, *fields)
|
59
|
+
fields = fields.flatten
|
60
|
+
info = {}
|
61
|
+
literal_pos = fields.index "literal"
|
62
|
+
|
63
|
+
object = if literal_pos.nil?
|
64
|
+
id
|
65
|
+
else
|
66
|
+
v = values[literal_pos]
|
67
|
+
v = v.first if Array === v
|
68
|
+
v
|
69
|
+
end
|
70
|
+
|
71
|
+
fields.each_with_index do |field,i|
|
72
|
+
if field == "JSON"
|
73
|
+
JSON.parse(values[i]).each do |key, value|
|
74
|
+
info[key.to_sym] = value
|
75
|
+
end
|
76
|
+
else
|
77
|
+
info[field.to_sym] = values[i]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
self.load(object, info)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.tsv(annotations, *fields)
|
85
|
+
fields = case
|
86
|
+
when ((fields.compact.empty?) and not annotations.empty?)
|
87
|
+
fields = annotations.first.annotations
|
88
|
+
fields << :annotation_types
|
89
|
+
when (fields == [:literal] and not annotations.empty?)
|
90
|
+
fields = annotations.first.annotations
|
91
|
+
fields << :literal
|
92
|
+
when (fields == [:all] and not annotations.empty?)
|
93
|
+
fields = [:annotation_types] + annotations.first.annotations
|
94
|
+
fields << :literal
|
95
|
+
else
|
96
|
+
fields.flatten
|
97
|
+
end
|
98
|
+
fields = fields.collect{|f| f.to_s}
|
99
|
+
|
100
|
+
tsv = TSV.setup({}, :key_field => "ID", :fields => fields)
|
101
|
+
|
102
|
+
annotations.each do |annotation|
|
103
|
+
tsv[annotation.id] = annotation.tsv_values(fields)
|
104
|
+
end
|
105
|
+
|
106
|
+
tsv
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.load_tsv(tsv)
|
110
|
+
tsv.collect do |id, values|
|
111
|
+
Annotated.load_tsv_values(id, values, tsv.fields)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
module Annotation
|
118
|
+
def self.extended(base)
|
119
|
+
if not base.respond_to? :annotations
|
120
|
+
class << base
|
121
|
+
attr_accessor :annotations, :inheritance, :all_inheritance, :all_annotations
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
125
|
+
base.annotations = []
|
126
|
+
base.inheritance = []
|
127
|
+
base.all_annotations = []
|
128
|
+
base.all_inheritance = []
|
129
|
+
|
130
|
+
base.module_eval do
|
131
|
+
def self.extended(object)
|
132
|
+
object.extend Annotated
|
133
|
+
if not object.annotation_types.include? self
|
134
|
+
object.annotation_types.concat self.inheritance
|
135
|
+
object.annotation_types << self
|
136
|
+
object.annotation_types.uniq!
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.included(base)
|
141
|
+
base.inheritance << self
|
142
|
+
base.all_inheritance.concat self.all_inheritance if self.respond_to? :all_inheritance
|
143
|
+
base.all_inheritance << self
|
144
|
+
base.all_inheritance.uniq!
|
145
|
+
base.update_annotations
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def update_annotations
|
153
|
+
@all_annotations = all_inheritance.inject([]){|acc,mod| acc.concat mod.annotations}.concat(@annotations)
|
154
|
+
end
|
155
|
+
|
156
|
+
def annotation(*values)
|
157
|
+
@annotations.concat values.collect{|v| v.to_sym}
|
158
|
+
update_annotations
|
159
|
+
|
160
|
+
module_eval do
|
161
|
+
attr_accessor *values
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def setup_info(object, info)
|
166
|
+
object.extend self
|
167
|
+
all_annotations.each do |annotation|
|
168
|
+
object.send(annotation.to_s + '=', info[annotation])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def setup(object, *values)
|
173
|
+
object.extend self
|
174
|
+
|
175
|
+
all_annotations.zip(values).each do |name, value|
|
176
|
+
object.send(name.to_s + '=', value)
|
177
|
+
end
|
178
|
+
|
179
|
+
object
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
module AnnotatedArray
|
184
|
+
extend ChainMethods
|
185
|
+
self.chain_prefix = :annotated_array
|
186
|
+
|
187
|
+
def annotated_array_get_brackets(pos)
|
188
|
+
value = annotated_array_clean_get_brackets(pos)
|
189
|
+
annotation_types.each do |mod|
|
190
|
+
mod.setup(value, *info.values_at(*mod.annotations))
|
191
|
+
end
|
192
|
+
value
|
193
|
+
end
|
194
|
+
|
195
|
+
def annotated_array_each
|
196
|
+
annotation_array_clean_each do |value|
|
197
|
+
annotation_types.each do |mod|
|
198
|
+
mod.setup(value, annotation)
|
199
|
+
end
|
200
|
+
yield value
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def annotated_array_collect
|
205
|
+
annotation_array_clean_collect do |value|
|
206
|
+
annotation_types.each do |mod|
|
207
|
+
mod.setup(value, annotation)
|
208
|
+
end
|
209
|
+
yield value
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
|