gb_mapfish_appserver 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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