gb_mapfish_appserver 0.0.3 → 0.0.4

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.
@@ -23,10 +23,12 @@ class Layer < ActiveRecord::Base
23
23
 
24
24
  #Structure for Topic selection
25
25
  def self.list(ability, layer_type, topic_name)
26
- topic = Topic.accessible_by(ability).includes(:layers).where(:name => topic_name).first
27
- layers = topic.nil? ? [] : topic.layers.accessible_by(ability).all
28
- topic_layers = topic.nil? ? [] : topic.topics_layers.select {|tl| layers.include?(tl.layer) }
29
- wms_layer_list(ability, topic, topic_layers)
26
+ ActiveRecord::Base.silence do
27
+ topic = Topic.accessible_by(ability).includes(:layers).where(:name => topic_name).first
28
+ layers = topic.nil? ? [] : topic.layers.accessible_by(ability).all
29
+ topic_layers = topic.nil? ? [] : topic.topics_layers.select {|tl| layers.include?(tl.layer) }
30
+ wms_layer_list(ability, topic, topic_layers)
31
+ end
30
32
  end
31
33
 
32
34
  def self.wms_layer_list(ability, topic, topic_layers)
@@ -105,21 +107,20 @@ EOS
105
107
 
106
108
  def query_fields(ability)
107
109
  return '' if feature_class.nil?
108
- area_field = "ST_Area(#{geometry_column.name}) AS area"
109
- #TODO: measure -> Measure(geometry_column, lat, lon)
110
- ([pkey]+ident_fields_for(ability)+[feature_class.extent_field, area_field]).join(',')
110
+ ([pkey]+ident_fields_for(ability)+[feature_class.extent_field, feature_class.area_field]).join(',')
111
111
  end
112
112
 
113
113
  def ident_fields_for(ability)
114
114
  #attributes.accessible_by(ability) & fields
115
115
  #logger.info "************************* fields layer #{name}: #{ident_fields}"
116
116
  #logger.info "************************* roles: #{ability.roles.collect(&:name).join(',')}"
117
- allowed_fields = ident_fields.split(',').select { |f| ability.can?(:show, attribute(f)) }
117
+ fields = (ident_fields || pkey).split(',')
118
+ allowed_fields = fields.select { |f| ability.can?(:show, attribute(f)) }
118
119
  #logger.info "************************* ident_fields layer #{name}: #{allowed_fields.inspect}"
119
120
  allowed_fields
120
121
  end
121
122
 
122
- def query(ability, query_topic, searchbbox)
123
+ def query(ability, query_topic, searchgeo)
123
124
  if feature_class
124
125
  begin
125
126
  #query_topic: {... customQueries: {<layername>: <query_method> }
@@ -132,11 +133,14 @@ EOS
132
133
  custom_query_method = query_topic['customQueries'][name] rescue nil
133
134
  logger.debug "******** #{feature_class} ***************************************************"
134
135
  features = if custom_query_method
135
- logger.debug "Custom query on layer #{name}: #{query_topic.inspect}"
136
- feature_class.send(custom_query_method, self, query_topic, searchbbox)
136
+ logger.debug "*** Custom query on layer #{name}: #{query_topic.inspect}"
137
+ feature_class.send(custom_query_method, self, query_topic, searchgeo)
138
+ elsif feature_class.respond_to?(:identify_query)
139
+ logger.debug "*** Custom identify_query on layer #{name}"
140
+ feature_class.identify_query(searchgeo, searchdistance)
137
141
  else
138
- logger.debug "Identify on layer #{name} with query fields #{query_fields(ability)} at #{searchbbox.inspect}"
139
- feature_class.identify_filter(searchbbox, searchdistance).select(query_fields(ability)).all
142
+ logger.debug "*** Identify on layer #{name} with query fields #{query_fields(ability)} at #{searchgeo.inspect}"
143
+ feature_class.identify_filter(searchgeo, searchdistance).select(query_fields(ability)).all
140
144
  end
141
145
  logger.debug "Number of features: #{features.size}"
142
146
  # calculate bbox of all features
@@ -150,7 +154,7 @@ EOS
150
154
  end
151
155
  rescue Exception => e
152
156
  features = "Table: <b>#{table}</b><br/>Exception: #{e}<br/>query fields: #{query_fields(ability)}<br/>db fields: #{feature_class.column_names.join(',')}<br/>missing: <font color='red'>#{(query_fields(ability).split(',') - feature_class.column_names).join(', ')}</font><br/><br/>"
153
- logger.info "Identfy error on layer #{name} #{features}"
157
+ logger.info "Identify error on layer #{name} #{features}"
154
158
  end
155
159
  [self, features, bbox]
156
160
  else
@@ -45,13 +45,15 @@ class Permission < ActiveRecord::Base
45
45
  end
46
46
 
47
47
  def role_can?(role_id, action, resource)
48
- can = if has_resource_list?
49
- permitted_resources(role_id, action).include?(resource)
50
- else
51
- permitted?(resource, permissions(role_id, action))
48
+ ActiveRecord::Base.silence do
49
+ can = if has_resource_list?
50
+ permitted_resources(role_id, action).include?(resource)
51
+ else
52
+ permitted?(resource, permissions(role_id, action))
53
+ end
54
+ #Rails.logger.debug ">>>>>>>>>>>>>>>>>> role_can? role_id: #{role_id}, action: #{action}, resource: #{resource.name} -> #{can}"
55
+ can
52
56
  end
53
- Rails.logger.debug ">>>>>>>>>>>>>>>>>> role_can? role_id: #{role_id}, action: #{action}, resource: #{resource.name} -> #{can}"
54
- can
55
57
  end
56
58
 
57
59
  def roles_permissions(roles, action, resource = nil)
@@ -69,16 +71,18 @@ class Permission < ActiveRecord::Base
69
71
  end
70
72
 
71
73
  def add_ability(ability, roles)
72
- actions.each do |action|
73
- if has_resource_list?
74
- ids = Rails.cache.fetch("permitted_resource_ids-#{action}-#{@resource_type_name}-roles-#{roles.collect(&:id).join(',')}") do
75
- permitted_resource_ids(roles, action)
76
- end
77
- Rails.logger.debug ">>>>>>>>>>>> permitted_resource_ids with roles #{roles.collect(&:name).join(',')} can? #{action} #{@resource_type_name}: #{ids.inspect}"
78
- ability.can(action, @klass, :id => ids) unless ids.empty?
79
- else
80
- ability.can(action, @klass) do |attr|
81
- roles_can?(roles, action, attr)
74
+ ActiveRecord::Base.silence do
75
+ actions.each do |action|
76
+ if has_resource_list?
77
+ ids = Rails.cache.fetch("permitted_resource_ids-#{action}-#{@resource_type_name}-roles-#{roles.collect(&:id).join(',')}") do
78
+ permitted_resource_ids(roles, action)
79
+ end
80
+ #Rails.logger.debug ">>>>>>>>>>>> permitted_resource_ids with roles #{roles.collect(&:name).join(',')} can? #{action} #{@resource_type_name}: #{ids.inspect}"
81
+ ability.can(action, @klass, :id => ids) unless ids.empty?
82
+ else
83
+ ability.can(action, @klass) do |attr|
84
+ roles_can?(roles, action, attr)
85
+ end
82
86
  end
83
87
  end
84
88
  end
@@ -101,8 +105,8 @@ class Permission < ActiveRecord::Base
101
105
  #All resource permissionsfor a given role_id + action
102
106
  def permitted_resources(role_id, action)
103
107
  permissions = permissions(role_id, action)
104
- resources.select do
105
- |r| permitted?(r, permissions)
108
+ resources.select do |r|
109
+ permitted?(r, permissions)
106
110
  end
107
111
  end
108
112
 
@@ -1,5 +1,4 @@
1
1
  class SearchModel < GeoModel
2
- establish_connection(GEODB)
3
2
 
4
3
  LOCATE_MAX_COUNT = 50
5
4
 
@@ -23,6 +22,10 @@ class SearchModel < GeoModel
23
22
  nil
24
23
  end
25
24
 
25
+ def self.selection_scalerange
26
+ nil
27
+ end
28
+
26
29
  #Generic location search with one search field
27
30
  def self.layer_locate(layer, search_field, locations)
28
31
  feature_class = layer.feature_class
@@ -31,7 +34,7 @@ class SearchModel < GeoModel
31
34
 
32
35
  # "261,AU4998;261,AU4999" -> [["261","AU4998"],["261","AU4999"]]
33
36
  def self.search_locations(param)
34
- locations = param.split(';')
37
+ locations = param.split('$')
35
38
  locations.collect {|l| l.split(',') }
36
39
  end
37
40
 
@@ -3,7 +3,7 @@ class Tool
3
3
 
4
4
  ALL = ['LineMeasureTool', 'AreaMeasureTool',
5
5
  'PrevTool', 'NextTool', 'LinkTool', 'PrintTool',
6
- 'ExportTool'] #, 'EditTool'
6
+ 'ExportTool', 'SelectTool'] #, 'EditTool'
7
7
 
8
8
  validates_presence_of :topic, :name
9
9
 
@@ -38,53 +38,55 @@ class Topic < ActiveRecord::Base
38
38
  #Structure for Topic selection
39
39
  def self.list(app, current_ability, zone, wms_host)
40
40
  topics = []
41
- app.gbapplications_categories.includes(:category).each do |gbapplications_category|
42
- category = gbapplications_category.category
43
- unless category.nil?
44
- category_topics = category.topics.accessible_by(current_ability).select(
45
- 'topics.*,categories_topics.sort AS categories_topics_sort')
46
- topics += category_topics.collect do |topic|
47
- subtopics = category_topics.select{|t| t.parent_id == topic.id}.collect do |subtopic|
41
+ ActiveRecord::Base.silence do
42
+ app.gbapplications_categories.includes(:category).each do |gbapplications_category|
43
+ category = gbapplications_category.category
44
+ unless category.nil?
45
+ category_topics = category.topics.accessible_by(current_ability).select(
46
+ 'topics.*,categories_topics.sort AS categories_topics_sort')
47
+ topics += category_topics.collect do |topic|
48
+ subtopics = category_topics.select{|t| t.parent_id == topic.id}.collect do |subtopic|
49
+ {
50
+ "subtopicname" => subtopic.name,
51
+ "subtopictitle" => subtopic.sub_title,
52
+ "categories_topics_sort" => subtopic['categories_topics_sort'].to_i
53
+ }
54
+ end
55
+ categorysort = gbapplications_category.sort - 1000*gbapplications_category.gbapp_specific rescue nil
56
+
57
+ tools = Tool.accessible_tools(topic, current_ability)
58
+
59
+ keywords = topic.title.split + (topic.keywords || '').split(',').collect(&:strip)
60
+
48
61
  {
49
- "subtopicname" => subtopic.name,
50
- "subtopictitle" => subtopic.sub_title,
51
- "categories_topics_sort" => subtopic['categories_topics_sort'].to_i
62
+ "name" => topic.name,
63
+ "title" => topic.title,
64
+ "print_title" => topic.print_title,
65
+ "icon" => "/images/custom/themekl-#{topic.name.downcase}.gif",
66
+ "organisationtitle" => topic.organisation.try(:title),
67
+ "organisationsort" => topic.organisation.try(:sort),
68
+ "categorytitle" => category.title,
69
+ "gbapp_specific" => gbapplications_category.gbapp_specific,
70
+ "categorysort" => categorysort,
71
+ "categories_topics_sort" => topic['categories_topics_sort'].to_i,
72
+ "keywords" => keywords,
73
+ "geoliongdd" => topic.geolion_gdd(zone),
74
+ "parent_id" => topic.parent_id,
75
+ "hassubtopics" => subtopics.size > 0,
76
+ "subtopics" => subtopics,
77
+ "missingpermission" => current_ability.cannot?(:show, topic),
78
+ "tools" => tools,
79
+ "ollayer_class" => topic.ollayer_class, #z.B. "WMS"
80
+ "ollayer_type" => topic.ollayer_args, #z.B. { name: "NASA Global Mosaic", url: "http://wms.jpl.nasa.gov/wms.cgi", params: {layers: "modis,global_mosaic"} }
81
+ "bg_topic" => topic.bg_topic.try(:name),
82
+ "overlay_topics" => topic.overlay_topics.collect(&:name),
83
+ "wms_url" => "#{wms_host}/#{topic.name}",
84
+ "background_layer" => topic.background_layer,
85
+ "main_layer" => topic.main_layer,
86
+ "overlay_layer" => topic.overlay_layer,
87
+ "minscale" => topic.minscale
52
88
  }
53
89
  end
54
- categorysort = gbapplications_category.sort - 1000*gbapplications_category.gbapp_specific rescue nil
55
-
56
- tools = Tool.accessible_tools(topic, current_ability)
57
-
58
- keywords = topic.title.split + (topic.keywords || '').split(',').collect(&:strip)
59
-
60
- {
61
- "name" => topic.name,
62
- "title" => topic.title,
63
- "print_title" => topic.print_title,
64
- "icon" => "/images/custom/themekl-#{topic.name.downcase}.gif",
65
- "organisationtitle" => topic.organisation.try(:title),
66
- "organisationsort" => topic.organisation.try(:sort),
67
- "categorytitle" => category.title,
68
- "gbapp_specific" => gbapplications_category.gbapp_specific,
69
- "categorysort" => categorysort,
70
- "categories_topics_sort" => topic['categories_topics_sort'].to_i,
71
- "keywords" => keywords,
72
- "geoliongdd" => topic.geolion_gdd(zone),
73
- "parent_id" => topic.parent_id,
74
- "hassubtopics" => subtopics.size > 0,
75
- "subtopics" => subtopics,
76
- "missingpermission" => current_ability.cannot?(:show, topic),
77
- "tools" => tools,
78
- "ollayer_class" => topic.ollayer_class, #z.B. "WMS"
79
- "ollayer_type" => topic.ollayer_args, #z.B. { name: "NASA Global Mosaic", url: "http://wms.jpl.nasa.gov/wms.cgi", params: {layers: "modis,global_mosaic"} }
80
- "bg_topic" => topic.bg_topic.try(:name),
81
- "overlay_topics" => topic.overlay_topics.collect(&:name),
82
- "wms_url" => "#{wms_host}/#{topic.name}",
83
- "background_layer" => topic.background_layer,
84
- "main_layer" => topic.main_layer,
85
- "overlay_layer" => topic.overlay_layer,
86
- "minscale" => topic.minscale
87
- }
88
90
  end
89
91
  end
90
92
  end
@@ -0,0 +1,182 @@
1
+ require 'acts_as_tree'
2
+
3
+ # OpenLayers "layer" (WMS, etc.)
4
+ class Topic < ActiveRecord::Base
5
+ acts_as_tree #parent_id could be replaced with topics_topics relation
6
+
7
+ has_many :categories_topics, :dependent => :destroy
8
+ has_many :categories, :through => :categories_topics
9
+ belongs_to :bg_topic, :class_name => 'Topic'
10
+ has_and_belongs_to_many :overlay_topics, :class_name => 'Topic', :association_foreign_key => 'overlay_topic_id'
11
+ has_many :topics_layers
12
+ has_many :layers, :through => :topics_layers
13
+ belongs_to :organisation
14
+
15
+ attr_protected []
16
+
17
+ accepts_nested_attributes_for :topics_layers, :allow_destroy => true
18
+ accepts_nested_attributes_for :layers, :allow_destroy => true
19
+
20
+ serialize :ollayer_args, JSON
21
+
22
+ validates :name, :presence => true, :uniqueness => true
23
+
24
+ # Enum for RailsAdmin form
25
+ def category_enum
26
+ Category.all.collect {|p| [ p.name, p.id ] }
27
+ end
28
+
29
+ # Enum for RailsAdmin form (causes exception in name search)
30
+ #def parent_enum
31
+ # Topic.all.collect {|p| [ p.name, p.id ] }
32
+ #end
33
+
34
+ def geolion_gdd(site)
35
+ site == SITE_DEFAULT ? geolion_gdd_internet : geolion_gdd_intranet
36
+ end
37
+
38
+ #Structure for Topic selection
39
+ def self.list(app, current_ability, zone, wms_host)
40
+ topics = []
41
+ ActiveRecord::Base.silence do
42
+ app.gbapplications_categories.includes(:category).each do |gbapplications_category|
43
+ category = gbapplications_category.category
44
+ unless category.nil?
45
+ category_topics = category.topics.accessible_by(current_ability).select(
46
+ 'topics.*,categories_topics.sort AS categories_topics_sort')
47
+ topics += category_topics.collect do |topic|
48
+ subtopics = category_topics.select{|t| t.parent_id == topic.id}.collect do |subtopic|
49
+ {
50
+ "subtopicname" => subtopic.name,
51
+ "subtopictitle" => subtopic.sub_title,
52
+ "categories_topics_sort" => subtopic['categories_topics_sort'].to_i
53
+ }
54
+ end
55
+ categorysort = gbapplications_category.sort - 1000*gbapplications_category.gbapp_specific rescue nil
56
+
57
+ tools = Tool.accessible_tools(topic, current_ability)
58
+
59
+ keywords = topic.title.split + (topic.keywords || '').split(',').collect(&:strip)
60
+
61
+ {
62
+ "name" => topic.name,
63
+ "title" => topic.title,
64
+ "print_title" => topic.print_title,
65
+ "icon" => "/images/custom/themekl-#{topic.name.downcase}.gif",
66
+ "organisationtitle" => topic.organisation.try(:title),
67
+ "organisationsort" => topic.organisation.try(:sort),
68
+ "categorytitle" => category.title,
69
+ "gbapp_specific" => gbapplications_category.gbapp_specific,
70
+ "categorysort" => categorysort,
71
+ "categories_topics_sort" => topic['categories_topics_sort'].to_i,
72
+ "keywords" => keywords,
73
+ "geoliongdd" => topic.geolion_gdd(zone),
74
+ "parent_id" => topic.parent_id,
75
+ "hassubtopics" => subtopics.size > 0,
76
+ "subtopics" => subtopics,
77
+ "missingpermission" => current_ability.cannot?(:show, topic),
78
+ "tools" => tools,
79
+ "ollayer_class" => topic.ollayer_class, #z.B. "WMS"
80
+ "ollayer_type" => topic.ollayer_args, #z.B. { name: "NASA Global Mosaic", url: "http://wms.jpl.nasa.gov/wms.cgi", params: {layers: "modis,global_mosaic"} }
81
+ "bg_topic" => topic.bg_topic.try(:name),
82
+ "overlay_topics" => topic.overlay_topics.collect(&:name),
83
+ "wms_url" => "#{wms_host}/#{topic.name}",
84
+ "background_layer" => topic.background_layer,
85
+ "main_layer" => topic.main_layer,
86
+ "overlay_layer" => topic.overlay_layer,
87
+ "minscale" => topic.minscale
88
+ }
89
+ end
90
+ end
91
+ end
92
+ end
93
+ {
94
+ "success" => true,
95
+ #"activeTopic" => {"topicname" => "av", "grouping" => "theme"}, #TODO: from session
96
+ "gbtopics" => topics,
97
+ "results" => topics.size
98
+ }
99
+ end
100
+
101
+ def icon_fname
102
+ "themekl-#{name.downcase}.gif"
103
+ end
104
+
105
+ #Topic legend collection
106
+ def legend_fname
107
+ "_#{name.downcase}_legend.html.erb"
108
+ end
109
+
110
+ def legend_file
111
+ File.join(Rails.root, 'app', 'views', 'topics', 'custom', legend_fname)
112
+ end
113
+
114
+ def legend_file_auto
115
+ File.join(Rails.root, 'app', 'views', 'topics', 'custom', 'auto', legend_fname)
116
+ end
117
+
118
+ def legend
119
+ @legend ||= begin
120
+ if File.exist?(legend_file)
121
+ "topics/custom/#{legend_fname[1..-10]}"
122
+ elsif File.exist?(legend_file_auto)
123
+ "topics/custom/auto/#{legend_fname[1..-10]}"
124
+ else
125
+ nil
126
+ end
127
+ end
128
+ end
129
+
130
+ def info_header_fname
131
+ "_#{name.downcase}_info.html.erb"
132
+ end
133
+
134
+ def info_header_file
135
+ File.join(Rails.root, 'app', 'views', 'topics', 'custom', info_header_fname)
136
+ end
137
+
138
+ def info_header
139
+ @info_header ||= File.exist?(info_header_file) ? "topics/custom/#{info_header_fname[1..-10]}" : nil
140
+ end
141
+
142
+ # print disclaimer
143
+
144
+ def self.default_print_disclaimer
145
+ File.open(File.join(Rails.root, 'app', 'views', 'topics', '_print_disclaimer.txt'), 'r') { |f| f.read }
146
+ end
147
+
148
+ def print_disclaimer
149
+ @disclaimer ||= begin
150
+ fname = File.join(Rails.root, 'app', 'views', 'topics', 'custom', "_#{name.downcase}_print_disclaimer.txt")
151
+ if File.exist?(fname)
152
+ # use custom topic disclaimer if there exists a corresponding text file
153
+ File.open(fname, 'r') { |f| f.read }
154
+ else
155
+ Topic.default_print_disclaimer
156
+ end
157
+ end
158
+ end
159
+
160
+ def roles
161
+ perms = Permission.where(:resource_type => 'Topic', :resource => name).includes(:role)
162
+ perms.collect(&:role)
163
+ end
164
+
165
+ def query(ability, query_topic, searchbbox)
166
+ active_layers = query_topic['layers'].split(',')
167
+ qlayers = query_layers(ability, active_layers)
168
+ results = []
169
+ qlayers.each do |layer|
170
+ result = layer.query(ability, query_topic, searchbbox)
171
+ results << result unless result.nil?
172
+ end
173
+ results
174
+ end
175
+
176
+ def query_layers(ability, active_layers) #TODO: 0.5s
177
+ layers.accessible_by(ability).where('topics_layers.queryable').order('topics_layers.leg_sort DESC').find_all do |layer|
178
+ active_layers.include?(layer.name)
179
+ end
180
+ end
181
+
182
+ end
@@ -7,7 +7,7 @@ class User < ActiveRecord::Base
7
7
  :authentication_keys => [ :login ]
8
8
 
9
9
  validates :login, :presence => true, :uniqueness => true
10
- validates_format_of :login, :with => /\A[A-Za-z][\w-]*\Z/
10
+ validates_format_of :login, :with => /\A[A-Za-z][.\w-]*\Z/
11
11
 
12
12
  attr_accessor :requested_group
13
13
 
@@ -28,8 +28,20 @@ class User < ActiveRecord::Base
28
28
  roles.any? { |role| role.name == rolename.to_s }
29
29
  end
30
30
 
31
+ def group_admin?(group)
32
+ has_role?(:admin) || group.admins.include?(self)
33
+ end
34
+
31
35
  def add_requested_group
32
36
  groups << Group.find(requested_group) if requested_group #with granted => false
33
37
  end
34
38
 
39
+ def merge_app_infos(new_app_infos)
40
+ if app_infos.nil?
41
+ update_attribute(:app_infos, new_app_infos)
42
+ else
43
+ update_attribute(:app_infos, app_infos.merge(new_app_infos))
44
+ end
45
+ end
46
+
35
47
  end