advertnet 1.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.
Files changed (159) hide show
  1. data/LICENSE +674 -0
  2. data/README +257 -0
  3. data/Rakefile +10 -0
  4. data/app/controllers/application.rb +40 -0
  5. data/app/controllers/container_controller.rb +83 -0
  6. data/app/controllers/content_controller.rb +61 -0
  7. data/app/controllers/furnitures_controller.rb +87 -0
  8. data/app/controllers/networks_controller.rb +269 -0
  9. data/app/controllers/objects_in_world_controller.rb +27 -0
  10. data/app/controllers/panels_controller.rb +186 -0
  11. data/app/helpers/application_helper.rb +31 -0
  12. data/app/helpers/container_helper.rb +2 -0
  13. data/app/helpers/content_helper.rb +2 -0
  14. data/app/helpers/furnitures_helper.rb +2 -0
  15. data/app/helpers/network_helper.rb +2 -0
  16. data/app/helpers/networks_helper.rb +2 -0
  17. data/app/helpers/objects_in_world_helper.rb +2 -0
  18. data/app/helpers/panels_helper.rb +2 -0
  19. data/app/models/container.rb +51 -0
  20. data/app/models/furniture.rb +60 -0
  21. data/app/models/mailer.rb +22 -0
  22. data/app/models/network.rb +38 -0
  23. data/app/models/object_in_world.rb +60 -0
  24. data/app/models/object_off_world.rb +77 -0
  25. data/app/models/panel.rb +136 -0
  26. data/app/models/panel_revision.rb +108 -0
  27. data/app/views/container/list.rhtml +27 -0
  28. data/app/views/container/show.rhtml +8 -0
  29. data/app/views/content/_form.rhtml +12 -0
  30. data/app/views/content/edit.rhtml +8 -0
  31. data/app/views/content/list.rhtml +26 -0
  32. data/app/views/content/new.rhtml +8 -0
  33. data/app/views/furnitures/list.rhtml +51 -0
  34. data/app/views/furnitures/show.rhtml +7 -0
  35. data/app/views/layouts/default.rhtml +30 -0
  36. data/app/views/mailer/avtouch.rhtml +1 -0
  37. data/app/views/networks/_form.rhtml +11 -0
  38. data/app/views/networks/_parameters_form.rhtml +8 -0
  39. data/app/views/networks/edit.rhtml +9 -0
  40. data/app/views/networks/list.rhtml +25 -0
  41. data/app/views/networks/new.rhtml +8 -0
  42. data/app/views/networks/show.rhtml +72 -0
  43. data/app/views/networks/show_parameters_form.rjs +5 -0
  44. data/app/views/objects_in_world/list.rhtml +30 -0
  45. data/app/views/objects_in_world/show.rhtml +8 -0
  46. data/app/views/panels/list.rhtml +48 -0
  47. data/app/views/panels/show.rhtml +8 -0
  48. data/bin/advertnet-install +144 -0
  49. data/config/boot.rb +45 -0
  50. data/config/database.yml.default +43 -0
  51. data/config/environment.rb +67 -0
  52. data/config/environments/development.rb +21 -0
  53. data/config/environments/production.rb +21 -0
  54. data/config/environments/test.rb +19 -0
  55. data/config/routes.rb +23 -0
  56. data/db/migrate/001_create_networks.rb +14 -0
  57. data/db/migrate/002_create_furnitures.rb +17 -0
  58. data/db/migrate/003_create_containers.rb +16 -0
  59. data/db/migrate/004_create_objects_in_world.rb +16 -0
  60. data/db/migrate/005_create_objects_off_world.rb +16 -0
  61. data/db/migrate/006_create_panels.rb +17 -0
  62. data/db/migrate/007_join_objects_in_world_panels.rb +17 -0
  63. data/db/migrate/008_join_objects_off_world_panels.rb +17 -0
  64. data/db/migrate/009_add_sessions.rb +19 -0
  65. data/db/migrate/010_add_or_rename_fields.rb +25 -0
  66. data/db/migrate/011_move_texture_to_object_in_world.rb +25 -0
  67. data/db/migrate/012_add_permanent_furniture_id.rb +18 -0
  68. data/db/migrate/013_create_panel_revisions.rb +42 -0
  69. data/db/schema.rb +102 -0
  70. data/doc/README_FOR_APP +108 -0
  71. data/lib/advertnet.rb +13 -0
  72. data/lib/second_life_validators.rb +89 -0
  73. data/lib/tasks/documentation.rake +16 -0
  74. data/lib/tasks/extract_fixtures.rake +23 -0
  75. data/lib/tasks/load_exported_fixtures.rake +14 -0
  76. data/public/404.html +30 -0
  77. data/public/500.html +30 -0
  78. data/public/dispatch.cgi +10 -0
  79. data/public/dispatch.fcgi +24 -0
  80. data/public/dispatch.rb +10 -0
  81. data/public/favicon.ico +0 -0
  82. data/public/images/rails.png +0 -0
  83. data/public/javascripts/application.js +2 -0
  84. data/public/javascripts/controls.js +833 -0
  85. data/public/javascripts/dragdrop.js +942 -0
  86. data/public/javascripts/effects.js +1088 -0
  87. data/public/javascripts/prototype.js +2515 -0
  88. data/public/robots.txt +1 -0
  89. data/public/stylesheets/application.css +25 -0
  90. data/public/stylesheets/scaffold.css +74 -0
  91. data/script/about +3 -0
  92. data/script/breakpointer +3 -0
  93. data/script/console +3 -0
  94. data/script/destroy +3 -0
  95. data/script/generate +3 -0
  96. data/script/performance/benchmarker +3 -0
  97. data/script/performance/profiler +3 -0
  98. data/script/plugin +3 -0
  99. data/script/process/inspector +3 -0
  100. data/script/process/reaper +3 -0
  101. data/script/process/spawner +3 -0
  102. data/script/runner +3 -0
  103. data/script/server +3 -0
  104. data/test/fixtures/containers.yml +44 -0
  105. data/test/fixtures/furnitures.yml +47 -0
  106. data/test/fixtures/mailer/avtouch +1 -0
  107. data/test/fixtures/networks.yml +31 -0
  108. data/test/fixtures/objects_in_world.yml +71 -0
  109. data/test/fixtures/objects_in_world_panels.yml +43 -0
  110. data/test/fixtures/objects_off_world.yml +55 -0
  111. data/test/fixtures/objects_off_world_panels.yml +20 -0
  112. data/test/fixtures/panel_revisions.yml +28 -0
  113. data/test/fixtures/panels.yml +79 -0
  114. data/test/functional/container_controller_test.rb +167 -0
  115. data/test/functional/content_controller_test.rb +91 -0
  116. data/test/functional/furnitures_controller_test.rb +134 -0
  117. data/test/functional/networks_controller_test.rb +248 -0
  118. data/test/functional/objects_in_world_controller_test.rb +42 -0
  119. data/test/functional/panels_controller_test.rb +173 -0
  120. data/test/test_helper.rb +53 -0
  121. data/test/unit/container_test.rb +53 -0
  122. data/test/unit/furniture_test.rb +68 -0
  123. data/test/unit/mailer_test.rb +40 -0
  124. data/test/unit/network_test.rb +42 -0
  125. data/test/unit/object_in_world_test.rb +33 -0
  126. data/test/unit/object_off_world_test.rb +26 -0
  127. data/test/unit/panel_revision_test.rb +148 -0
  128. data/test/unit/panel_test.rb +63 -0
  129. data/vendor/plugins/annotate_models/ChangeLog +46 -0
  130. data/vendor/plugins/annotate_models/README +31 -0
  131. data/vendor/plugins/annotate_models/lib/annotate_models.rb +132 -0
  132. data/vendor/plugins/annotate_models/tasks/annotate_models_tasks.rake +7 -0
  133. data/vendor/plugins/foreign_key_migrations/CHANGELOG +99 -0
  134. data/vendor/plugins/foreign_key_migrations/MIT-LICENSE +20 -0
  135. data/vendor/plugins/foreign_key_migrations/README +87 -0
  136. data/vendor/plugins/foreign_key_migrations/about.yml +5 -0
  137. data/vendor/plugins/foreign_key_migrations/init.rb +3 -0
  138. data/vendor/plugins/foreign_key_migrations/install.rb +1 -0
  139. data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/base.rb +22 -0
  140. data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/connection_adapters/abstract_adapter.rb +22 -0
  141. data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/connection_adapters/table_definition.rb +28 -0
  142. data/vendor/plugins/redhillonrails_core/CHANGELOG +154 -0
  143. data/vendor/plugins/redhillonrails_core/MIT-LICENSE +20 -0
  144. data/vendor/plugins/redhillonrails_core/README +139 -0
  145. data/vendor/plugins/redhillonrails_core/init.rb +19 -0
  146. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/base.rb +54 -0
  147. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb +31 -0
  148. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/column.rb +21 -0
  149. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb +26 -0
  150. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb +11 -0
  151. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb +82 -0
  152. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb +8 -0
  153. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb +107 -0
  154. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb +23 -0
  155. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb +9 -0
  156. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb +27 -0
  157. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema.rb +27 -0
  158. data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema_dumper.rb +47 -0
  159. metadata +290 -0
@@ -0,0 +1,87 @@
1
+ # == Contrôleur de gestion du mobilier urbain, Furniture.
2
+ #
3
+ # Ce contrôleur permet de :
4
+ # * lister le mobilier existant, sans permettre de le modifier pour l'instant.
5
+ # * enregistrer un nouveau mobilier.
6
+ #
7
+ # Suite à l'enregistrement d'un nouveau mobilier, ses panneaux (Panel) s'enregistreront.
8
+ class FurnituresController < ApplicationController
9
+ # Mise en page globale du site
10
+ layout "default"
11
+
12
+ # Filtre de récupération des paramètres Second Life
13
+ before_filter :get_secondlife_attrs, :only => [ :register ]
14
+
15
+ # Renvoie vers l'action 'list'
16
+ def index
17
+ list
18
+ render :action => 'list'
19
+ end
20
+
21
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
22
+ verify :method => :post, :only => [ :register ],
23
+ :redirect_to => { :action => :list }
24
+
25
+ # Liste des panneaux.
26
+ def list
27
+ @furniture_pages, @furnitures = paginate :furnitures, :per_page => 10
28
+ end
29
+
30
+ # Détail d'un panneau.
31
+ def show
32
+ @furniture = Furniture.find(params[:id])
33
+ end
34
+
35
+ # Enregistrement d'un nouveau mobilier
36
+ #
37
+ # == Input
38
+ # * Environnement Second Life transmis en HTTP
39
+ # * <tt>permanent_id=permanent_id</tt> : identifiant permanent du mobilier, s'il existe déjà
40
+ #
41
+ # +permanent_id+ est optionnel, si le mobilier n'en remplace pas un qui existait déjà.
42
+ #
43
+ # == Output
44
+ # * Le délai de mise à jour et l'identifiant permanent, sous la forme :
45
+ #
46
+ # delay=delay
47
+ # permanent_id=permanent_id
48
+ def register
49
+ # Création ou mise à jour du mobilier.
50
+ # Attention à l'astuce "slattrs.delete(:key)". Grâce à celle-ci, l'appel à
51
+ # 'update_attributes' ne reçoit que les 3 paramètres à mettre à jour, moins "key".
52
+ furniture = Furniture.find_or_initialize_by_furniture_key(@slattrs.delete(:key))
53
+ furniture.update_attributes!(@slattrs.merge({ :permanent_id => params[:permanent_id]}))
54
+
55
+ render :text => "delay=#{furniture.delay}\npermanent_id=#{furniture.permanent_id}\n",
56
+ :layout => false,
57
+ :content_type => "text/plain"
58
+ end
59
+
60
+ # Suppression d'un mobilier. Le mobilier disparaît de la base si ses panneaux ont été
61
+ # supprimés car non updatés depuis 5 fois le delay (furniture vide)
62
+
63
+ def destroy
64
+ #Panel.find(:first,:conditions => [ "furniture_id = ?", "1"])
65
+ furniture = Furniture.find(params[:id])
66
+ if panel=Panel.find(:first,:conditions => [ "furniture_id = ?", params[:id]]) == nil
67
+ render :text => "Furniture removed from database"
68
+ furniture.destroy
69
+ else
70
+
71
+ redirect_to(:action => :list)
72
+ end
73
+ end
74
+
75
+ # Détruit tous les mobiliers qui n'ont plus de panneaux associés
76
+ def destroydead
77
+ for furniture in Furniture.find_all
78
+ for column in Furniture.content_columns
79
+ if Panel.find(:first,:conditions => [ "furniture_id = ?", params[:id]]) == nil
80
+ furniture.destroy
81
+ end
82
+ end
83
+ end
84
+ redirect_to :action => 'list'
85
+ end
86
+
87
+ end
@@ -0,0 +1,269 @@
1
+ require 'ostruct'
2
+
3
+ # == Gestion des réseaux de publicité
4
+ #
5
+ # Ce contrôleur gère les objets Network. Il permet de :
6
+ #
7
+ # * Lister les réseaux
8
+ # * Créer/supprimer des réseaux
9
+ # * Afficher et modifier le nom et le statut d'un réseau
10
+ # * Modifier les paramètres d'un réseau :
11
+ # * Texture
12
+ # * Landmark
13
+ # * Notecard
14
+ # * URL
15
+ # * Media URL
16
+ # * etc.
17
+ # * Ajouter/enlever des panneaux (Panel) d'un réseau.
18
+ class NetworksController < ApplicationController
19
+ # Mise en page globale du site
20
+ layout "default"
21
+
22
+ # Renvoie vers l'action 'list'
23
+ def index
24
+ list
25
+ render :action => 'list'
26
+ end
27
+
28
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
29
+ verify :method => :post, :only => [ :destroy, :create, :update, :set_parameters, :remove_panel, :add_panel ],
30
+ :redirect_to => { :action => :list }
31
+
32
+ # Liste des réseaux
33
+ def list
34
+ @network_pages, @networks = paginate :networks, :per_page => 10
35
+ end
36
+
37
+ # Affiche un réseau, ses caractéristiques et l'ensemble des panneaux membres.
38
+ # Affiche aussi les formulaire permettant de modifier le réseau, son paramétrage
39
+ # et sa composition.
40
+ def show
41
+ @network = Network.find(params[:id])
42
+ # La liste de tous les panneaux disponibles.
43
+ @unassigned_panels = Panel.unassigned_panels.map { |p| [ "#{p.name} (#{p.furniture.name})", p.id ]}
44
+ # On extrait les caractéristiques du réseau depuis le premier panneau
45
+ # XXX : Ceci suppose que tous les panneaux du réseau sont strictement dans la même configuration.
46
+ panel1 = @network.panels.first
47
+ if panel1
48
+ @network_parameters = OpenStruct.new(
49
+ :texture => panel1.objects_in_world.find_by_otype("texture"),
50
+ :landmark => panel1.objects_in_world.find_by_otype("landmark"),
51
+ :notecard => panel1.objects_in_world.find_by_otype("notecard"),
52
+ :url => panel1.objects_off_world.find_by_otype("url"),
53
+ :mediaurl => panel1.objects_off_world.find_by_otype("mediaurl")
54
+ )
55
+ # @network_parameters.texture_id = @network_parameters.texture.id rescue nil
56
+ # @network_parameters.landmark_id = @network_parameters.landmark.id rescue nil
57
+ # @network_parameters.notecard_id = @network_parameters.notecard.id rescue nil
58
+ # @network_parameters.url_id = @network_parameters.url.id rescue nil
59
+ # @network_parameters.mediaurl_id = @network_parameters.mediaurl.id rescue nil
60
+ #
61
+ # @textures = ObjectInWorld.find_all_by_otype("texture", :order => "name").map { |t| [ t.name, t.id ] }
62
+ # @landmarks = [ [ 'No Landmark', nil ] ] + ObjectInWorld.find_all_by_otype("landmark", :order => "name").map { |t| [ t.name, t.id ] }
63
+ # @notecards = [ [ 'No Notecard', nil ] ] + ObjectInWorld.find_all_by_otype("notecard", :order => "name").map { |t| [ t.name, t.id ] }
64
+ # @urls = [ [ 'No URL', nil ] ] + ObjectOffWorld.find_all_by_otype("url", :order => "name").map { |t| [ "#{t.name} : #{t.content}", t.id ] }
65
+ # @mediaurls = [ [ 'No Media URL', nil ] ] + ObjectOffWorld.find_all_by_otype("mediaurl", :order => "name").map { |t| [ "#{t.name} : #{t.content}", t.id ] }
66
+ else
67
+ @network_parameters = nil
68
+ end
69
+ end
70
+
71
+ # Affiche le formulaire de modification des paramètres du réseau, en AJAX
72
+ #
73
+ # == Input
74
+ #
75
+ # * id : Network id
76
+ def show_parameters_form
77
+ @network = Network.find(params[:id])
78
+ # On extrait les caractéristiques du réseau depuis le premier panneau
79
+ # XXX : Ceci suppose que tous les panneaux du réseau sont strictement dans la même configuration.
80
+ panel1 = @network.panels.first
81
+ @network_parameters = OpenStruct.new(
82
+ :texture => panel1.objects_in_world.find_by_otype("texture"),
83
+ :landmark => panel1.objects_in_world.find_by_otype("landmark"),
84
+ :notecard => panel1.objects_in_world.find_by_otype("notecard"),
85
+ :url => panel1.objects_off_world.find_by_otype("url"),
86
+ :mediaurl => panel1.objects_off_world.find_by_otype("mediaurl")
87
+ )
88
+ @network_parameters.texture_id = @network_parameters.texture.id rescue nil
89
+ @network_parameters.landmark_id = @network_parameters.landmark.id rescue nil
90
+ @network_parameters.notecard_id = @network_parameters.notecard.id rescue nil
91
+ @network_parameters.url_id = @network_parameters.url.id rescue nil
92
+ @network_parameters.mediaurl_id = @network_parameters.mediaurl.id rescue nil
93
+
94
+ @textures = ObjectInWorld.find_all_by_otype("texture", :order => "name").map { |t| [ t.name, t.id ] }
95
+ @landmarks = [ [ 'No Landmark', nil ] ] + ObjectInWorld.find_all_by_otype("landmark", :order => "name").map { |t| [ t.name, t.id ] }
96
+ @notecards = [ [ 'No Notecard', nil ] ] + ObjectInWorld.find_all_by_otype("notecard", :order => "name").map { |t| [ t.name, t.id ] }
97
+ @urls = [ [ 'No URL', nil ] ] + ObjectOffWorld.find_all_by_otype("url", :order => "name").map { |t| [ "#{t.name} : #{t.content}", t.id ] }
98
+ @mediaurls = [ [ 'No Media URL', nil ] ] + ObjectOffWorld.find_all_by_otype("mediaurl", :order => "name").map { |t| [ "#{t.name} : #{t.content}", t.id ] }
99
+ end
100
+
101
+ # Formulaire de création d'un nouveau réseau.
102
+ def new
103
+ @network = Network.new
104
+ end
105
+
106
+ # Création d'un nouveau réseau vide.
107
+ #
108
+ # == Input
109
+ #
110
+ # * <tt>network[]</tt> : Paramètres de création du réseau
111
+ def create
112
+ @network = Network.new(params[:network])
113
+ if @network.save
114
+ flash[:notice] = 'Network was successfully created.'
115
+ redirect_to :action => 'show', :id => @network
116
+ else
117
+ render :action => 'new'
118
+ end
119
+ end
120
+
121
+ # Formulaire d'édition d'un réseau.
122
+ #
123
+ # == Input
124
+ #
125
+ # * +id+ : Network id
126
+ def edit
127
+ @network = Network.find(params[:id])
128
+ end
129
+
130
+ # Edition d'un réseau.
131
+ #
132
+ # == Input
133
+ #
134
+ # * +id+ : Network id
135
+ def update
136
+ @network = Network.find(params[:id])
137
+ if @network.update_attributes(params[:network])
138
+ flash[:notice] = 'Network was successfully updated.'
139
+ redirect_to :action => 'show', :id => @network
140
+ else
141
+ render :action => 'edit'
142
+ end
143
+ end
144
+
145
+ # Suppression d'un réseau.
146
+ #
147
+ # Tous les panneaux membres du réseau deviennent disponibles.
148
+ #
149
+ # == Input
150
+ #
151
+ # * +id+ : Network id
152
+ def destroy
153
+ network = Network.find(params[:id])
154
+ network.destroy
155
+ flash[:notice] = "Network '#{network.name}' deleted."
156
+ redirect_to :action => 'list'
157
+ end
158
+
159
+ # Modifie les paramètres du réseau et de ses panneaux :
160
+ #
161
+ # * Texture
162
+ # * Notecard
163
+ # * Landmark
164
+ # * URL
165
+ # * Media URL
166
+ # * etc.
167
+ #
168
+ # La liste des ObjectInWold et ObjectOffWorld est dans les constantes TYPES
169
+ # définies dans chacun des deux modèles.
170
+ #
171
+ # Les paramètres sont fournis par l'action 'show'.
172
+ #
173
+ # == Input
174
+ #
175
+ # * +id+ : Network id
176
+ def set_parameters
177
+ network = Network.find(params[:id])
178
+
179
+ # liste des panneaux à mettre à jour
180
+ panels = network.panels
181
+ # Messages à afficher
182
+ messages = []
183
+
184
+ # Traitement Texture, Landmark et Notecard (et autres)
185
+ ObjectInWorld::TYPES.each do |obj_type|
186
+ obj_id = params[:network_parameters]["#{obj_type}_id".intern]
187
+ # Si obj_id est une chaîne vide, alors il faut supprimer l'association avec ce type d'objet
188
+ # uniquement. Sinon il faut aussi le remplacer dans le nouvel objet.
189
+ obj = ObjectInWorld.find(obj_id) rescue nil
190
+ obj_name = obj ? obj.name : 'None'
191
+ panels.each do |p|
192
+ # On simule les expressions de type "p.texture = obj" avec 'send'
193
+ p.send("#{obj_type}=", obj)
194
+ end
195
+ messages << "#{obj_type.humanize} set to '%s'." % obj_name
196
+ end
197
+
198
+ # Traitement URL, Media URL, etc
199
+ ObjectOffWorld::TYPES.collect { |t| t.last }.each do |obj_type|
200
+ obj_id = params[:network_parameters]["#{obj_type}_id".intern]
201
+ # Si obj_id est une chaîne vide, alors il faut supprimer l'association avec ce type d'objet
202
+ # uniquement. Sinon il faut aussi le remplacer dans le nouvel objet.
203
+ obj = ObjectOffWorld.find(obj_id) rescue nil
204
+ obj_name = obj ? obj.name : 'None'
205
+ panels.each do |p|
206
+ # On simule les expressions de type "p.url = obj" avec 'send'
207
+ p.send("#{obj_type}=", obj)
208
+ end
209
+ messages << "#{obj_type.humanize} set to '%s'." % obj_name
210
+ end
211
+
212
+ if messages.empty?
213
+ flash[:notice] = "Network not modified"
214
+ else
215
+ panels.each { |p| p.save! }
216
+ flash[:notice] = messages.join(" ")
217
+ end
218
+ redirect_to :action => 'show', :id => network
219
+ end
220
+
221
+ # Enlève un panneau d'un réseau, sans le supprimer.
222
+ #
223
+ # == Input
224
+ #
225
+ # * +id+ : Network id
226
+ # * Variable POST +panel_id+ : Panel id
227
+ def remove_panel
228
+ network = Network.find(params[:id])
229
+ panel = network.panels.find(params[:panel_id])
230
+ network.panels.delete(panel)
231
+ flash[:notice] = "Panel '#{panel.name} : #{panel.furniture.name}' removed from network."
232
+ redirect_to :action => 'show', :id => network
233
+ rescue ActiveRecord::RecordNotFound
234
+ flash[:notice] = "Remove panel: Invalid network id ('#{params[:id]}') or panel id ('#{params[:panel_id]}')."
235
+ redirect_to :action => 'list'
236
+ end
237
+
238
+ # Ajoute un panneau dans un réseau.
239
+ #
240
+ # == Input
241
+ #
242
+ # * Variable POST +panel_id+
243
+ def add_panel
244
+ network = Network.find(params[:id])
245
+ panel = Panel.find(params[:panel_id])
246
+ # On n'ajoute pas un panneau déjà membre d'un autre réseau
247
+ if panel.network.nil?
248
+ # Si le réseau a déjà des panneaux, donc des caractéristiques, il faut les appliquer
249
+ # au nouveau panneau
250
+ reference_panel = network.panels.first
251
+ if reference_panel
252
+ panel.texture = reference_panel.texture
253
+ panel.notecard = reference_panel.notecard
254
+ panel.landmark = reference_panel.landmark
255
+ panel.url = reference_panel.url
256
+ panel.mediaurl = reference_panel.mediaurl
257
+ end
258
+ # Et maintenant on ajoute le panneau au réseau
259
+ network.panels << panel
260
+ flash[:notice] = "Panel '#{panel.name} : #{panel.furniture.name}' added to network."
261
+ else
262
+ flash[:notice] = "Panel '#{panel.name} : #{panel.furniture.name}' already belongs to a network ('#{panel.network.name}')."
263
+ end
264
+ redirect_to :action => 'show', :id => network
265
+ rescue ActiveRecord::RecordNotFound
266
+ flash[:notice] = "Add panel: Invalid network id ('#{params[:id]}') or panel id ('#{params[:panel_id]}')."
267
+ redirect_to :action => 'list'
268
+ end
269
+ end
@@ -0,0 +1,27 @@
1
+ # == Contrôleur de gestion des ObjectInWorld
2
+ #
3
+ # Ce contrôleur liste les ObjectInWorld.
4
+ class ObjectsInWorldController < ApplicationController
5
+ # Mise en page globale du site
6
+ layout "default"
7
+
8
+ # Renvoie vers l'action 'list'
9
+ def index
10
+ list
11
+ render :action => 'list'
12
+ end
13
+
14
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
15
+ verify :method => :post, :only => [ :destroy, :create, :update ],
16
+ :redirect_to => { :action => :list }
17
+
18
+ # Liste des ObjectInWorld
19
+ def list
20
+ @object_in_world_pages, @objects_in_world = paginate :objects_in_world, :per_page => 10
21
+ end
22
+
23
+ # Détail d'un ObjectInWorld
24
+ def show
25
+ @object_in_world = ObjectInWorld.find(params[:id])
26
+ end
27
+ end
@@ -0,0 +1,186 @@
1
+ # == Gestion des panneaux
2
+ #
3
+ # Ce contrôleur gère les panneaux (Panel). Il permet de :
4
+ #
5
+ # * Liste les panneaux
6
+ # * Enregistrer un nouveau panneau depuis SL
7
+ # * Mettre à jour un panneau depuis SL
8
+ # * Enregistrer le clic d'un avatar dans SL et lui envoyer URL ou Media URL
9
+ class PanelsController < ApplicationController
10
+ # Mise en page globale du site
11
+ layout "default"
12
+
13
+ # Filtre de récupération des paramètres Second Life
14
+ before_filter :get_secondlife_attrs, :only => [ :register, :update, :avtouch ]
15
+
16
+ # Affiche l'index, par défaut la liste des panneaux
17
+ def index
18
+ list
19
+ render :action => 'list'
20
+ end
21
+
22
+ # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
23
+ verify :method => :post, :only => [ :register ],
24
+ :redirect_to => { :action => :list }
25
+
26
+ # Liste des panneauxs disponibles
27
+ def list
28
+ @panel_pages, @panels = paginate :panels, :per_page => 10
29
+ end
30
+
31
+ # Affiche le détail d'un panneau
32
+ def show
33
+ @panel = Panel.find(params[:id])
34
+ end
35
+
36
+ # Enregistrement d'un nouveau panneau
37
+ #
38
+ # == Input
39
+ # * Environnement Second Life transmis en HTTP
40
+ # * +furniture_key+:: Clé SL du mobilier possédant ce panneau
41
+ #
42
+ # == Output
43
+ # * Le délai de mise à jour, sous la forme :
44
+ #
45
+ # delay=delay
46
+ def register
47
+ # Quel est le mobilier parent ?
48
+ furniture_key = params[:furniture_key]
49
+ furniture = Furniture.find_by_furniture_key(furniture_key)
50
+ if furniture.nil?
51
+ render :text => "The furniture id '#{furniture_key}' does not exist.",
52
+ :status => "409 Undefined furniture '#{furniture_key}'",
53
+ :layout => false,
54
+ :content_type => "text/plain"
55
+ return
56
+ end
57
+ # Création ou mise à jour du panneau
58
+ panel = Panel.find_or_initialize_by_panel_key(@slattrs[:key])
59
+ panel.furniture = furniture
60
+ panel.update_attributes!(:name => @slattrs[:name])
61
+
62
+ render :text => "delay=%#{furniture.delay}%",
63
+ :layout => false,
64
+ :content_type => "text/plain"
65
+ end
66
+
67
+ # Mise à jour du panel
68
+ #
69
+ # == Input
70
+ # * Environnement Second Life transmis en HTTP
71
+ #
72
+ # == Output
73
+ # * Le délai de mise à jour, la texture, l'url, la media url sous la forme suivante avec un attribut par ligne :
74
+ #
75
+ # delay=delay
76
+ # texture=texture_key
77
+ # url=url
78
+ # mediaurl=mediaurl
79
+ #
80
+ # Quand il n'y a pas d'URL ou de Media URL, le contenu envoyé est respectivement +nourl+ ou +nomedia+.
81
+ def update
82
+ # Mise à jour du panel
83
+ panel = Panel.find_by_panel_key(@slattrs[:key])
84
+ if panel.nil?
85
+ render :text => "The panel id '#{@slattrs[:key]}' does not exist.",
86
+ :status => "409 Undefined panel '#{@slattrs[:key]}'",
87
+ :layout => false,
88
+ :content_type => "text/plain"
89
+ return
90
+ end
91
+ # Trouve la texture associée
92
+ texture = panel.texture.object_key
93
+ # Trouve les URL et Media URL associées, ou une valeur par défaut
94
+ url = if (obj = panel.url)
95
+ obj.content
96
+ else "nourl" end
97
+ mediaurl = if (obj = panel.mediaurl)
98
+ obj.content
99
+ else "nomedia" end
100
+
101
+ # Construit et envoie la réponse
102
+ panel_response = [ ["delay", panel.furniture.delay],
103
+ ["texture", texture],
104
+ ["url", url],
105
+ ["mediaurl", mediaurl] ].map { |pair| "#{pair[0]}=#{pair[1]}" }.join("\n")
106
+ render :text => panel_response,
107
+ :layout => false,
108
+ :content_type => "text/plain"
109
+ end
110
+
111
+ # Un avatar clique sur le panel
112
+ #
113
+ # == Input
114
+ # * Environnement Second Life transmis en HTTP
115
+ # * +avatar_key+ : Clé SL de l'avatar qui a cliqué
116
+ #
117
+ # == Output
118
+ # * Le serveur envoie 1 ou 2 mails à des containers pour qu'ils envoient à leur tour
119
+ # un landmark et/ou une notecard à l'avatar.
120
+ def avtouch
121
+ # Récupère le panel, l'avatar, la notecard, le landmark
122
+ panel = Panel.find_by_panel_key(@slattrs[:key])
123
+ if panel.nil?
124
+ render :text => "The panel id '#{@slattrs[:key]}' does not exist.",
125
+ :status => "409 Undefined panel '#{@slattrs[:key]}'",
126
+ :layout => false,
127
+ :content_type => "text/plain"
128
+ return
129
+ end
130
+ if !(avatar_key = params[:avatar_key])
131
+ render :text => "Missing avatar key.",
132
+ :status => "409 Missing avatar key",
133
+ :layout => false,
134
+ :content_type => "text/plain"
135
+ return
136
+ end
137
+ # Trouve les landmark et notecard associés, ou une valeur par défaut
138
+ landmark = panel.landmark
139
+ notecard = panel.notecard
140
+
141
+ # On envoie successivement un mail pour landmark et un pour notecard,
142
+ # mais uniquement s'il y a quelque chose à envoyer (!= nil).
143
+ [ landmark, notecard ].each do |obj|
144
+ Mailer.deliver_avtouch(obj.container.container_key,
145
+ avatar_key,
146
+ obj.name) if obj
147
+ end
148
+ # Fini
149
+ render :text => "Objects sent.",
150
+ :layout => false,
151
+ :content_type => "text/plain"
152
+ end
153
+
154
+ # Si le panneau n'a pas donné signe de vie depuis 5 fois le délais prévu
155
+ # on le supprime de la base
156
+ def destroy
157
+ # On récupère le delay du furniture associé
158
+ panel = Panel.find(params[:id])
159
+ delay = Furniture.find(panel.furniture.id).delay
160
+ updated_time = panel.updated_at + 5 * delay * 60
161
+ # Si la date actuelle est > à date du updated_at + 5xdelay (également présent dans la vue)
162
+ #
163
+ # on affiche le bouton de suppression
164
+ if updated_time < Time::now
165
+ # On sauve dans la table revision
166
+ # save_to_revision_table
167
+ panel.destroy
168
+ end
169
+ redirect_to :action => 'list'
170
+ end
171
+
172
+ # Détruit tous les panneaux qui n'ont pas contacté le serveur
173
+ # depuis 5 x le delay
174
+ def destroydead
175
+ for panel in Panel.find_all
176
+ for column in Panel.content_columns
177
+ if (panel.updated_at + 5 * Furniture.find(panel.furniture.id).delay * 60) < Time.now
178
+ panel.destroy
179
+ end
180
+ end
181
+ end
182
+ redirect_to :action => 'list'
183
+ end
184
+
185
+ end
186
+