rbbt-rest 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +8 -8
  2. data/config.ru +3 -0
  3. data/lib/rbbt/rest/client.rb +9 -10
  4. data/lib/rbbt/rest/common/cache.rb +32 -7
  5. data/lib/rbbt/rest/common/forms.rb +33 -0
  6. data/lib/rbbt/rest/common/locate.rb +4 -0
  7. data/lib/rbbt/rest/common/misc.rb +24 -0
  8. data/lib/rbbt/rest/common/render.rb +26 -9
  9. data/lib/rbbt/rest/common/resources.rb +1 -1
  10. data/lib/rbbt/rest/common/table.rb +87 -26
  11. data/lib/rbbt/rest/common/users.rb +5 -1
  12. data/lib/rbbt/rest/entity.rb +300 -95
  13. data/lib/rbbt/rest/entity/action_controller.rb +6 -1
  14. data/lib/rbbt/rest/entity/entity_list_card.rb +1 -1
  15. data/lib/rbbt/rest/entity/entity_map_card.rb +15 -0
  16. data/lib/rbbt/rest/entity/favourites.rb +57 -1
  17. data/lib/rbbt/rest/entity/finder.rb +1 -1
  18. data/lib/rbbt/rest/entity/helpers.rb +40 -7
  19. data/lib/rbbt/rest/entity/list.rb +8 -0
  20. data/lib/rbbt/rest/entity/locate.rb +114 -0
  21. data/lib/rbbt/rest/entity/map.rb +99 -0
  22. data/lib/rbbt/rest/entity/render.rb +25 -0
  23. data/lib/rbbt/rest/entity/rest.rb +33 -4
  24. data/lib/rbbt/rest/main.rb +27 -4
  25. data/lib/rbbt/rest/workflow.rb +7 -1
  26. data/lib/rbbt/rest/workflow/jobs.rb +21 -1
  27. data/share/views/compass/app.sass +17 -9
  28. data/share/views/compass/entity_card.sass +16 -3
  29. data/share/views/compass/favourites.sass +44 -2
  30. data/share/views/compass/form.sass +11 -0
  31. data/share/views/compass/list_container.sass +1 -1
  32. data/share/views/compass/reveal.sass +31 -0
  33. data/share/views/compass/style.sass +29 -1
  34. data/share/views/compass/style_mixins.sass +18 -6
  35. data/share/views/compass/table.sass +19 -3
  36. data/share/views/compass/topbar.sass +8 -2
  37. data/share/views/entity_map/Default.haml +5 -0
  38. data/share/views/entity_partials/action_card.haml +2 -0
  39. data/share/views/entity_partials/action_controller.haml +8 -1
  40. data/share/views/entity_partials/entity_list_card.haml +8 -6
  41. data/share/views/entity_partials/entity_map_card.haml +63 -0
  42. data/share/views/entity_partials/list_container.haml +3 -2
  43. data/share/views/error.haml +14 -10
  44. data/share/views/help.haml +34 -0
  45. data/share/views/help/entity.haml +193 -0
  46. data/share/views/help/workflow.haml +77 -0
  47. data/share/views/job_result/tsv.haml +3 -2
  48. data/share/views/layout.haml +33 -3
  49. data/share/views/layout/favourites.haml +14 -4
  50. data/share/views/layout/header.haml +4 -0
  51. data/share/views/partials/form.haml +3 -1
  52. data/share/views/partials/table.haml +16 -52
  53. data/share/views/partials/table/column.haml +10 -0
  54. data/share/views/partials/table/files.haml +4 -0
  55. data/share/views/partials/table/filters.haml +11 -0
  56. data/share/views/partials/table/page.haml +37 -0
  57. data/share/views/public/favicon.gif +0 -0
  58. data/share/views/public/js/_ajax_replace.js +76 -4
  59. data/share/views/public/js/_fix_tablesorter_science.js +13 -0
  60. data/share/views/public/js/actions.js +8 -2
  61. data/share/views/public/js/base.js +12 -1
  62. data/share/views/public/js/entities.js +39 -7
  63. data/share/views/public/js/favourites.js +308 -77
  64. data/share/views/public/js/helpers.js +9 -5
  65. data/share/views/public/js/lists.js +12 -12
  66. data/share/views/public/js/maps.js +17 -0
  67. data/share/views/public/js/reveal.js +48 -0
  68. data/share/views/public/js/tables.js +110 -51
  69. data/share/views/public/js/workflow.js +4 -16
  70. data/share/views/public/plugins/underscore/js/underscore.js +1227 -0
  71. data/share/views/tasks.haml +12 -1
  72. data/share/views/wait.haml +7 -0
  73. metadata +17 -2
@@ -20,6 +20,7 @@ module EntityRESTHelpers
20
20
  entity_annotations = {}
21
21
  entity_class.annotations.each do |annotation|
22
22
  value = consume_parameter annotation, params
23
+ value = Entity::REST.restore_element(value) if String === value
23
24
  value = false if value == "false"
24
25
  value = true if value == "true"
25
26
  entity_annotations[annotation] = value
@@ -71,6 +72,30 @@ module EntityRESTHelpers
71
72
 
72
73
  render(template_file, locals, layout_file, "Entity list #{ action }: #{ id }")
73
74
  end
75
+
76
+ def entity_map_render(map_id, type, column)
77
+ template_file = locate_entity_map_template(type, column)
78
+
79
+ map = Entity::Map.load_map(type, column, map_id, user)
80
+ locals = {:map => map, :map_id => map_id}
81
+
82
+ layout_file = layout ? locate_template("layout") : nil
83
+
84
+ render(template_file, locals, layout_file, "Entity map: #{ map_id }")
85
+ end
86
+
87
+ def entity_map_action_render(map, action, id, params = {})
88
+ template_file = locate_entity_map_action_template(map, action)
89
+
90
+ locals = params.merge({:map => map, :map_id => id})
91
+
92
+ layout_file = layout ? locate_template("layout") : nil
93
+
94
+ render(template_file, locals, layout_file, "Entity map #{ action }: #{ id }")
95
+ end
96
+
97
+
98
+
74
99
  end
75
100
 
76
101
 
@@ -14,15 +14,15 @@ module Entity
14
14
  #{{{ MISC
15
15
 
16
16
  def self.clean_element(elem)
17
- elem.gsub('/', '--')
17
+ elem.gsub('/', '--').gsub('%', 'o-o')
18
18
  end
19
19
 
20
20
  def self.restore_element(elem)
21
- CGI.unescape(elem.gsub('--', '/'))
21
+ CGI.unescape(CGI.unescape(elem.gsub('--', '/').gsub('o-o', '%')))
22
22
  end
23
23
 
24
24
  def entity_link_params
25
- info = self.info
25
+ info = self.info.dup
26
26
  info.delete :format
27
27
  info.delete :annotation_types
28
28
  info.delete :annotated_array
@@ -65,7 +65,21 @@ module Entity
65
65
 
66
66
  #{{{ URLS
67
67
 
68
- def self.entity_url(entity, type, params = {})
68
+ def self.entity_url(entity, type = nil, params = nil)
69
+ if type.nil?
70
+ type = entity.annotation_types.last.to_s
71
+ type << ":" << entity.format if entity.respond_to? :format
72
+ end
73
+
74
+ if params.nil?
75
+ if entity.respond_to? :entity_link_params
76
+ params = entity.entity_link_params
77
+ else
78
+ params = {}
79
+ end
80
+ end
81
+
82
+ params ||= entity.info if entity.respond_to? :info
69
83
  url = File.join('/', 'entity', Entity::REST.clean_element(type.to_s), entity)
70
84
  url << "?" << Misc.hash2GET_params(params) if params.any?
71
85
  url
@@ -87,6 +101,20 @@ module Entity
87
101
  url
88
102
  end
89
103
 
104
+ def self.entity_map_url(map, type, column)
105
+ type = Entity::REST.clean_element(type.to_s)
106
+ column = Entity::REST.clean_element(column)
107
+ map = Entity::REST.clean_element(map)
108
+ File.join('/', 'entity_map', type, column, map)
109
+ end
110
+
111
+ def self.entity_map_action_url(map, type, column, action)
112
+ type = Entity::REST.clean_element(type.to_s)
113
+ column = Entity::REST.clean_element(column)
114
+ map = Entity::REST.clean_element(map)
115
+ File.join('/', 'entity_map_action', type, column, action, map)
116
+ end
117
+
90
118
 
91
119
  #{{{ LINKS
92
120
 
@@ -101,6 +129,7 @@ module Entity
101
129
 
102
130
  attributes[:class] << klasses
103
131
  attributes[:href] = Entity::REST.entity_url(self, entity_type.to_s, link_params)
132
+ attributes["attr-entity_id"] = self.to_s
104
133
 
105
134
  text = self.respond_to?(:name)? self.name || self : self if text.nil?
106
135
  attributes[:title] = text if attributes[:title].nil?
@@ -4,6 +4,7 @@ require 'rbbt/rest/common/users'
4
4
  require 'ruby-prof'
5
5
 
6
6
  require 'sinatra/base'
7
+ require 'sinatra/cross_origin'
7
8
  require 'json'
8
9
 
9
10
  module Sinatra
@@ -21,18 +22,25 @@ module Sinatra
21
22
 
22
23
  set :cache_dir, Rbbt.var.sinatra.cache.find unless settings.respond_to? :cache_dir and settings.cache_dir != nil
23
24
  set :file_dir, Rbbt.var.sinatra.files.find unless settings.respond_to? :file_dir and settings.file_dir != nil
25
+ set :permalink_dir, Rbbt.var.sinatra.permalink.find unless settings.respond_to? :permalink_dir and settings.permalink_dir != nil
24
26
 
25
27
  set :public_folder, Rbbt.share.views.public.find
26
28
 
27
29
  attr_accessor :ajax, :layout, :format, :size, :update, :cache_type, :_, :profile
28
30
 
29
- set :haml, { :ugly => true }
30
31
  if production?
31
32
  set :haml, { :ugly => true }
32
33
  set :clean_trace, true
33
34
  set :static_cache_control , [:public, {:max_age => 360000}]
34
35
  end
35
36
 
37
+ enable :cross_origin
38
+ set :allow_origin, :any
39
+ set :allow_methods, [:get, :post, :options]
40
+ set :allow_credentials, true
41
+ set :max_age, "1728000"
42
+ set :allow_headers, ['URI']
43
+
36
44
  before do
37
45
  Log.info("IP #{request.ip}: " << request.path_info << ". Params: " << Misc.remove_long_items(params).inspect)
38
46
  process_common_parameters
@@ -52,8 +60,7 @@ module Sinatra
52
60
  printer.print(:path => dir, :profile => 'profile')
53
61
  Log.info("Profile saved at #{ dir }")
54
62
  end
55
-
56
- request
63
+ response.header["URI"] = request.env["REQUEST_URI"]
57
64
  end
58
65
 
59
66
  add_sass_load_path Rbbt.views.compass.find
@@ -92,9 +99,25 @@ module Sinatra
92
99
  end
93
100
 
94
101
  get '/' do
95
- template_render('main', params)
102
+ template_render('main', params, 'main', :cache_type => :asynchronous)
96
103
  end
97
104
 
105
+ get '/help/?:section?' do
106
+ if params[:section]
107
+ section = params[:section]
108
+ template_render('help/' << section, params, section, :cache_type => :asynchronous)
109
+ else
110
+ template_render('help', params, 'help', :cache_type => :asynchronous)
111
+ end
112
+ end
113
+
114
+ get '/permalink/:id' do
115
+ content_type "text/html"
116
+ layout_file = locate_template('layout')
117
+ Haml::Engine.new(Open.read(layout_file), :filename => layout_file).render(self) do
118
+ Open.read(File.join(settings.permalink_dir, params[:id]))
119
+ end
120
+ end
98
121
  end
99
122
  end
100
123
  end
@@ -16,6 +16,7 @@ require 'json'
16
16
 
17
17
  module Sinatra
18
18
  module RbbtRESTWorkflow
19
+ WORKFLOWS = []
19
20
 
20
21
  def add_workflow_resource(workflow)
21
22
  views_dir = workflow.libdir.www.views.find(:lib)
@@ -32,12 +33,13 @@ module Sinatra
32
33
 
33
34
  def add_workflow(workflow, add_resource = false)
34
35
  raise "Provided workflow is not of type Workflow" unless Workflow === workflow or WorkflowRESTClient === workflow
36
+ RbbtRESTWorkflow::WORKFLOWS.push workflow unless RbbtRESTWorkflow::WORKFLOWS.include? workflow
35
37
 
36
38
  add_workflow_resource(workflow) if add_resource
37
39
 
38
40
  Log.debug("Adding #{ workflow } to REST server")
39
41
 
40
- self.instance_eval workflow.libdir.lib['sinatra.rb'].read if File.exists? workflow.libdir.lib['sinatra.rb']
42
+ self.instance_eval workflow.libdir.lib['sinatra.rb'].read, workflow.libdir.lib['sinatra.rb'].find if File.exists? workflow.libdir.lib['sinatra.rb']
41
43
 
42
44
  get "/#{workflow.to_s}" do
43
45
  case format
@@ -79,6 +81,10 @@ module Sinatra
79
81
  end
80
82
  end
81
83
 
84
+ get "/#{workflow.to_s}/description" do
85
+ halt 200, workflow.workflow_description
86
+ end
87
+
82
88
 
83
89
  get "/#{workflow.to_s}/:task" do
84
90
  task = consume_parameter(:task)
@@ -90,9 +90,29 @@ module WorkflowRESTHelpers
90
90
  end
91
91
 
92
92
  def show_result(job, workflow, task)
93
- case format
93
+ case format.to_sym
94
94
  when :html
95
95
  show_result_html job.load, workflow, task, job.name, job
96
+ when :table
97
+ halt 200, tsv2html(job.path, :url => "/" << [workflow.to_s, task, job.name] * "/")
98
+ when :entities
99
+ tsv = tsv_process(load_tsv(job.path).first)
100
+ list = tsv.values.flatten
101
+ if not AnnotatedArray === list and Annotated === list.first
102
+ list.first.annotate list
103
+ list.extend AnnotatedArray
104
+ end
105
+ type = list.annotation_types.last
106
+ list_id = "TMP #{type} in #{ [workflow.to_s, task, job.name] * " - " }"
107
+ Entity::List.save_list(type.to_s, list_id, list, user)
108
+ redirect to(Entity::REST.entity_list_url(list_id, type))
109
+ when :map
110
+ tsv = tsv_process(load_tsv(job.path).first)
111
+ type = tsv.keys.annotation_types.last
112
+ column = tsv.fields.first
113
+ map_id = "MAP #{type}-#{column} in #{ [workflow.to_s, task, job.name] * " - " }"
114
+ Entity::Map.save_map(type.to_s, column, map_id, tsv, user)
115
+ redirect to(Entity::REST.entity_map_url(map_id, type, column))
96
116
  when :json
97
117
  content_type "application/json"
98
118
  halt 200, job.load.to_json
@@ -1,4 +1,6 @@
1
1
  @import _foundation_setup
2
+ @import style_mixins
3
+
2
4
  @import lists
3
5
  @import list_container
4
6
  @import dom
@@ -7,8 +9,6 @@
7
9
  @import tabs
8
10
  @import responsive_table
9
11
 
10
- @import style_mixins
11
-
12
12
  @import topbar
13
13
  @import favourites
14
14
  @import footer
@@ -17,6 +17,7 @@
17
17
  @import offcanvas
18
18
  @import fragment
19
19
  @import workflow
20
+ @import reveal
20
21
  @import style
21
22
 
22
23
  body
@@ -26,13 +27,6 @@ body
26
27
  #body
27
28
  min-height: 900px
28
29
 
29
-
30
- //.main
31
- dl
32
- @extend dl.details
33
- @extend .column
34
- @extend .large-4
35
-
36
30
  ul.entities
37
31
  @extend .inline-list
38
32
  li
@@ -40,3 +34,17 @@ ul.entities
40
34
 
41
35
  dl.details
42
36
  @extend dl.indented
37
+
38
+
39
+ .filter_controls
40
+ @media #{$medium}
41
+ div.input
42
+ @include grid-column(4)
43
+ &.submit, &.submit > input
44
+ float: right
45
+ clear: both
46
+ label
47
+ @include ellipsis_text()
48
+
49
+ .map_management ul
50
+ @include button-group-list()
@@ -1,5 +1,5 @@
1
1
  // GRID LAYOUT
2
- .entity_card, .entity_list_card, .action_card
2
+ .entity_card, .entity_list_card, .action_card, .entity_map_card
3
3
 
4
4
  & > .title
5
5
  @include grid-row(collapse)
@@ -49,9 +49,8 @@
49
49
  clear: left
50
50
 
51
51
 
52
- .entity_card, .entity_list_card, .action_card
52
+ .entity_card, .entity_list_card, .action_card, .entity_map_card
53
53
  & > .title
54
- padding-top: 1em
55
54
  margin-bottom: 1em
56
55
 
57
56
  .name
@@ -98,3 +97,17 @@
98
97
  p
99
98
  text-align: justify
100
99
  max-width: 50em
100
+
101
+
102
+ @media #{$not-small}
103
+ .reveal-modal
104
+ .entity_card, .entity_list_card, .action_card, .entity_map_card
105
+ &> .card
106
+ &>.sidebar
107
+ width: 33%
108
+ &>.content
109
+ width: 67%
110
+
111
+ form.rename
112
+ input[name=rename]
113
+ width: 100%
@@ -1,5 +1,9 @@
1
- a#toggle_favourite
2
-
1
+ .reveal-modal a.toggle_favourite
2
+ &:not(.active)
3
+ i
4
+ color: black !important
5
+
6
+ a#toggle_favourite, .reveal-modal a.toggle_favourite
3
7
  &.inactive
4
8
  span.remove
5
9
  display: none !important
@@ -26,6 +30,44 @@ a#toggle_favourite
26
30
  font-size: 0.5em
27
31
  margin-left: 1em
28
32
 
33
+ ul.favourite_entity_lists
34
+ li
35
+ ul
36
+ li:not(.title)
37
+ +clearfix()
38
+ position: relative
39
+ width: 100%
40
+ padding-right: 3em
41
+ a
42
+ min-height: 1em
43
+ display: inline-block !important
44
+ &.highlight
45
+ width: 3em !important
46
+ position: absolute
47
+ left: 0
48
+ &.active
49
+ i
50
+ color: yellow
51
+ &:not(.highlight)
52
+ position: relative
53
+ margin-left: 3em
54
+
55
+
56
+ ul.favourite_entities, ul.favourite_entity_lists, ul.favourite_entity_maps
57
+ ul.dropdown
58
+ li
59
+ @media #{ $not-small }
60
+ background: none repeat scroll 0 0 #00434C
61
+ a
62
+ @media #{ $not-small }
63
+ +ellipsis_text()
64
+ max-width: 400px
65
+ z-index: 9
66
+ &:not(.highlight):hover
67
+ white-space: normal !important
68
+ z-index: 10
69
+
70
+
29
71
  //@media only screen and (max-width: 767px)
30
72
  #find_wrapper
31
73
  top: 9em
@@ -18,6 +18,13 @@
18
18
  margin-bottom: 2em
19
19
  label
20
20
  margin-bottom: 1em
21
+ &.inline
22
+ +ellipsis_text()
23
+ display: inline-block
24
+ clear: top
25
+ padding: 0
26
+ margin-bottom: 0
27
+ margin-left: 0.5em
21
28
 
22
29
  .input.submit
23
30
  clear: both
@@ -26,5 +33,9 @@
26
33
  select.favourite_lists
27
34
  width: 175px
28
35
 
36
+ span.choice
37
+ margin-right: 1em
38
+ white-space: nowrap
39
+
29
40
  .action_parameters form
30
41
  +clearfix()
@@ -24,7 +24,7 @@ dl.list_container
24
24
  a.entity_list
25
25
  display: block
26
26
  z-index: 15
27
- margin-right: 1em
27
+ margin-right: 2em
28
28
  color: $primary-color
29
29
  width: 1.5em
30
30
  float: left
@@ -0,0 +1,31 @@
1
+ .rbbt_reveal_content
2
+ display: none !important
3
+
4
+ .reveal-modal a.toggle_favourite
5
+ &.active
6
+ i
7
+ color: #dd1 !important
8
+ &:not(.active)
9
+ i
10
+ color: black !important
11
+
12
+ .reveal-modal .header
13
+ bottom-border: 1px solid grey
14
+ .close
15
+ float: right
16
+ .title
17
+ float: left
18
+
19
+ .reveal-modal
20
+ .controls
21
+ a.link-reveal-modal
22
+ @include reveal-close()
23
+ right: 3em
24
+ font-size: 1em
25
+ top: 1.1em
26
+
27
+ &:not(.url)
28
+ .controls
29
+ a.link-reveal-modal
30
+ display: none
31
+