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.
- data/LICENSE +674 -0
- data/README +257 -0
- data/Rakefile +10 -0
- data/app/controllers/application.rb +40 -0
- data/app/controllers/container_controller.rb +83 -0
- data/app/controllers/content_controller.rb +61 -0
- data/app/controllers/furnitures_controller.rb +87 -0
- data/app/controllers/networks_controller.rb +269 -0
- data/app/controllers/objects_in_world_controller.rb +27 -0
- data/app/controllers/panels_controller.rb +186 -0
- data/app/helpers/application_helper.rb +31 -0
- data/app/helpers/container_helper.rb +2 -0
- data/app/helpers/content_helper.rb +2 -0
- data/app/helpers/furnitures_helper.rb +2 -0
- data/app/helpers/network_helper.rb +2 -0
- data/app/helpers/networks_helper.rb +2 -0
- data/app/helpers/objects_in_world_helper.rb +2 -0
- data/app/helpers/panels_helper.rb +2 -0
- data/app/models/container.rb +51 -0
- data/app/models/furniture.rb +60 -0
- data/app/models/mailer.rb +22 -0
- data/app/models/network.rb +38 -0
- data/app/models/object_in_world.rb +60 -0
- data/app/models/object_off_world.rb +77 -0
- data/app/models/panel.rb +136 -0
- data/app/models/panel_revision.rb +108 -0
- data/app/views/container/list.rhtml +27 -0
- data/app/views/container/show.rhtml +8 -0
- data/app/views/content/_form.rhtml +12 -0
- data/app/views/content/edit.rhtml +8 -0
- data/app/views/content/list.rhtml +26 -0
- data/app/views/content/new.rhtml +8 -0
- data/app/views/furnitures/list.rhtml +51 -0
- data/app/views/furnitures/show.rhtml +7 -0
- data/app/views/layouts/default.rhtml +30 -0
- data/app/views/mailer/avtouch.rhtml +1 -0
- data/app/views/networks/_form.rhtml +11 -0
- data/app/views/networks/_parameters_form.rhtml +8 -0
- data/app/views/networks/edit.rhtml +9 -0
- data/app/views/networks/list.rhtml +25 -0
- data/app/views/networks/new.rhtml +8 -0
- data/app/views/networks/show.rhtml +72 -0
- data/app/views/networks/show_parameters_form.rjs +5 -0
- data/app/views/objects_in_world/list.rhtml +30 -0
- data/app/views/objects_in_world/show.rhtml +8 -0
- data/app/views/panels/list.rhtml +48 -0
- data/app/views/panels/show.rhtml +8 -0
- data/bin/advertnet-install +144 -0
- data/config/boot.rb +45 -0
- data/config/database.yml.default +43 -0
- data/config/environment.rb +67 -0
- data/config/environments/development.rb +21 -0
- data/config/environments/production.rb +21 -0
- data/config/environments/test.rb +19 -0
- data/config/routes.rb +23 -0
- data/db/migrate/001_create_networks.rb +14 -0
- data/db/migrate/002_create_furnitures.rb +17 -0
- data/db/migrate/003_create_containers.rb +16 -0
- data/db/migrate/004_create_objects_in_world.rb +16 -0
- data/db/migrate/005_create_objects_off_world.rb +16 -0
- data/db/migrate/006_create_panels.rb +17 -0
- data/db/migrate/007_join_objects_in_world_panels.rb +17 -0
- data/db/migrate/008_join_objects_off_world_panels.rb +17 -0
- data/db/migrate/009_add_sessions.rb +19 -0
- data/db/migrate/010_add_or_rename_fields.rb +25 -0
- data/db/migrate/011_move_texture_to_object_in_world.rb +25 -0
- data/db/migrate/012_add_permanent_furniture_id.rb +18 -0
- data/db/migrate/013_create_panel_revisions.rb +42 -0
- data/db/schema.rb +102 -0
- data/doc/README_FOR_APP +108 -0
- data/lib/advertnet.rb +13 -0
- data/lib/second_life_validators.rb +89 -0
- data/lib/tasks/documentation.rake +16 -0
- data/lib/tasks/extract_fixtures.rake +23 -0
- data/lib/tasks/load_exported_fixtures.rake +14 -0
- data/public/404.html +30 -0
- data/public/500.html +30 -0
- data/public/dispatch.cgi +10 -0
- data/public/dispatch.fcgi +24 -0
- data/public/dispatch.rb +10 -0
- data/public/favicon.ico +0 -0
- data/public/images/rails.png +0 -0
- data/public/javascripts/application.js +2 -0
- data/public/javascripts/controls.js +833 -0
- data/public/javascripts/dragdrop.js +942 -0
- data/public/javascripts/effects.js +1088 -0
- data/public/javascripts/prototype.js +2515 -0
- data/public/robots.txt +1 -0
- data/public/stylesheets/application.css +25 -0
- data/public/stylesheets/scaffold.css +74 -0
- data/script/about +3 -0
- data/script/breakpointer +3 -0
- data/script/console +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/process/inspector +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/test/fixtures/containers.yml +44 -0
- data/test/fixtures/furnitures.yml +47 -0
- data/test/fixtures/mailer/avtouch +1 -0
- data/test/fixtures/networks.yml +31 -0
- data/test/fixtures/objects_in_world.yml +71 -0
- data/test/fixtures/objects_in_world_panels.yml +43 -0
- data/test/fixtures/objects_off_world.yml +55 -0
- data/test/fixtures/objects_off_world_panels.yml +20 -0
- data/test/fixtures/panel_revisions.yml +28 -0
- data/test/fixtures/panels.yml +79 -0
- data/test/functional/container_controller_test.rb +167 -0
- data/test/functional/content_controller_test.rb +91 -0
- data/test/functional/furnitures_controller_test.rb +134 -0
- data/test/functional/networks_controller_test.rb +248 -0
- data/test/functional/objects_in_world_controller_test.rb +42 -0
- data/test/functional/panels_controller_test.rb +173 -0
- data/test/test_helper.rb +53 -0
- data/test/unit/container_test.rb +53 -0
- data/test/unit/furniture_test.rb +68 -0
- data/test/unit/mailer_test.rb +40 -0
- data/test/unit/network_test.rb +42 -0
- data/test/unit/object_in_world_test.rb +33 -0
- data/test/unit/object_off_world_test.rb +26 -0
- data/test/unit/panel_revision_test.rb +148 -0
- data/test/unit/panel_test.rb +63 -0
- data/vendor/plugins/annotate_models/ChangeLog +46 -0
- data/vendor/plugins/annotate_models/README +31 -0
- data/vendor/plugins/annotate_models/lib/annotate_models.rb +132 -0
- data/vendor/plugins/annotate_models/tasks/annotate_models_tasks.rake +7 -0
- data/vendor/plugins/foreign_key_migrations/CHANGELOG +99 -0
- data/vendor/plugins/foreign_key_migrations/MIT-LICENSE +20 -0
- data/vendor/plugins/foreign_key_migrations/README +87 -0
- data/vendor/plugins/foreign_key_migrations/about.yml +5 -0
- data/vendor/plugins/foreign_key_migrations/init.rb +3 -0
- data/vendor/plugins/foreign_key_migrations/install.rb +1 -0
- data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/base.rb +22 -0
- data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/connection_adapters/abstract_adapter.rb +22 -0
- data/vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations/active_record/connection_adapters/table_definition.rb +28 -0
- data/vendor/plugins/redhillonrails_core/CHANGELOG +154 -0
- data/vendor/plugins/redhillonrails_core/MIT-LICENSE +20 -0
- data/vendor/plugins/redhillonrails_core/README +139 -0
- data/vendor/plugins/redhillonrails_core/init.rb +19 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/base.rb +54 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/abstract_adapter.rb +31 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/column.rb +21 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/foreign_key_definition.rb +26 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/index_definition.rb +11 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_adapter.rb +82 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/mysql_column.rb +8 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/postgresql_adapter.rb +107 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/schema_statements.rb +23 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/sqlite3_adapter.rb +9 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/connection_adapters/table_definition.rb +27 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema.rb +27 -0
- data/vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core/active_record/schema_dumper.rb +47 -0
- metadata +290 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Methods added to this helper will be available to all templates in the application.
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
|
|
4
|
+
# Affiche proprement le nom d'un object in world ou bien "none"
|
|
5
|
+
#
|
|
6
|
+
# XXX Ce helper n'est plus utilisé, on peut sans doute le supprimer.
|
|
7
|
+
#
|
|
8
|
+
# == Input
|
|
9
|
+
#
|
|
10
|
+
# +oiw+:: ObjectInWorld
|
|
11
|
+
#
|
|
12
|
+
# == Output
|
|
13
|
+
#
|
|
14
|
+
# Affiche le nom, échappé avec "<tt>h()</tt>", ou bien le mot "+none+"
|
|
15
|
+
def object_name(oiw)
|
|
16
|
+
oiw ? h(oiw.name) : "none"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Affiche proprement l'url d'un ObjectOffWorld
|
|
20
|
+
#
|
|
21
|
+
# == Input
|
|
22
|
+
#
|
|
23
|
+
# +oow+:: ObjectOffWorld
|
|
24
|
+
#
|
|
25
|
+
# == Output
|
|
26
|
+
#
|
|
27
|
+
# Affiche le nom, avec un lien hypertexte, ou bien le mot "+none+"
|
|
28
|
+
def object_url(oow)
|
|
29
|
+
oow ? "<a href=\"#{oow.content}\">#{oow.name}</a>" : "none"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Modèle Container Second Life pour le stockage des objets Second Life. Voir ObjectInWorld
|
|
2
|
+
# pour la description des objets stockés.
|
|
3
|
+
|
|
4
|
+
# Inclut la librairie ("lib/second_life_validators.rb") qui contient les
|
|
5
|
+
# validateurs Second Life
|
|
6
|
+
require 'second_life_validators'
|
|
7
|
+
|
|
8
|
+
# Conteneur Second Life de stockage des objets Second Life. Voir ObjectInWorld
|
|
9
|
+
# pour la description des objets stockés.
|
|
10
|
+
#
|
|
11
|
+
# == Schema Information
|
|
12
|
+
# Schema version: 13
|
|
13
|
+
#
|
|
14
|
+
# Table name: containers
|
|
15
|
+
#
|
|
16
|
+
# id :integer(11) not null, primary key
|
|
17
|
+
# container_key :string(64) not null
|
|
18
|
+
# sim :string(64) not null
|
|
19
|
+
# name :string(64) not null
|
|
20
|
+
# position :string(40) not null
|
|
21
|
+
# delay :integer(11) default(30), not null
|
|
22
|
+
# created_at :datetime
|
|
23
|
+
# updated_at :datetime
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
class Container < ActiveRecord::Base
|
|
27
|
+
# Pas besoin de ':dependent', on gère la cohérence (i.e. interdiction de
|
|
28
|
+
# supprimer un Container qui contient des OIWs) via les clés étrangères.
|
|
29
|
+
# --------
|
|
30
|
+
# En fait si ! Sinon on ne peut pas utiliser un appel du type
|
|
31
|
+
# "container.objects_in_wold.replace([o1, o2])"...
|
|
32
|
+
# Il faut en effet détruire les objets qui ne sont plus rattachés à un
|
|
33
|
+
# container.
|
|
34
|
+
has_many :objects_in_world,
|
|
35
|
+
:dependent => :destroy
|
|
36
|
+
|
|
37
|
+
# Correction de la sim et de la position avant validation et insertion en
|
|
38
|
+
# base de données
|
|
39
|
+
before_validation SecondLifeSimPosNormalizer.new(:sim, :position)
|
|
40
|
+
|
|
41
|
+
validates_presence_of(:name, :container_key, :sim, :position, :delay, :message => "must be given a value")
|
|
42
|
+
validates_uniqueness_of(:container_key, :message => "must be unique")
|
|
43
|
+
validates_numericality_of(:delay, :only_integer => true)
|
|
44
|
+
# Format des id d'object dans Second Life
|
|
45
|
+
validates_format_of_sl_key(:container_key)
|
|
46
|
+
# Format de la position relative dans une Sim : X,Y,Z
|
|
47
|
+
validates_format_of_sl_position(:position)
|
|
48
|
+
# Valeurs tolérées pour delay
|
|
49
|
+
# (TODO : Trouver quelle est la plage de valeur raisonnable pour delay)
|
|
50
|
+
validates_inclusion_of(:delay, :in => 5..60, :message => "is not a valid delay")
|
|
51
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
# Schema version: 13
|
|
3
|
+
#
|
|
4
|
+
# Table name: furnitures
|
|
5
|
+
#
|
|
6
|
+
# id :integer(11) not null, primary key
|
|
7
|
+
# name :string(64) not null
|
|
8
|
+
# furniture_key :string(36) not null
|
|
9
|
+
# sim :string(64) not null
|
|
10
|
+
# position :string(40) not null
|
|
11
|
+
# delay :integer(11) default(30), not null
|
|
12
|
+
# created_at :datetime
|
|
13
|
+
# updated_at :datetime
|
|
14
|
+
# permanent_id :integer(11)
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
# Inclut la librairie ("lib/second_life_validators.rb") qui contient les
|
|
18
|
+
# validateurs Second Life
|
|
19
|
+
require 'second_life_validators'
|
|
20
|
+
|
|
21
|
+
class Furniture < ActiveRecord::Base
|
|
22
|
+
# Pas besoin de ':dependent', on gère la cohérence (i.e. interdiction de
|
|
23
|
+
# supprimer un Furniture qui contient des Panels) via les clés étrangères.
|
|
24
|
+
has_many :panels
|
|
25
|
+
|
|
26
|
+
# Correction de la sim et de la position avant validation et insertion en
|
|
27
|
+
# base de données
|
|
28
|
+
before_validation SecondLifeSimPosNormalizer.new(:sim, :position)
|
|
29
|
+
|
|
30
|
+
validates_presence_of(:name, :furniture_key, :sim, :position, :delay, :message => "must be given a value")
|
|
31
|
+
validates_uniqueness_of(:furniture_key, :message => "must be unique")
|
|
32
|
+
validates_numericality_of(:delay, :only_integer => true)
|
|
33
|
+
# permanent_id peut être numérique ou nul
|
|
34
|
+
validates_numericality_of :permanent_id, :only_integer => true,
|
|
35
|
+
:if => Proc.new { |u| !u.permanent_id.nil? }
|
|
36
|
+
# Format des id d'object dans Second Life
|
|
37
|
+
validates_format_of_sl_key(:furniture_key)
|
|
38
|
+
# Format de la position relative dans une Sim : X,Y,Z
|
|
39
|
+
validates_format_of_sl_position(:position)
|
|
40
|
+
# Valeurs tolérées pour delay
|
|
41
|
+
# (TODO : Trouver quelle est la plage de valeur raisonnable pour delay)
|
|
42
|
+
validates_inclusion_of(:delay, :in => 5..60, :message => "is not a valid delay")
|
|
43
|
+
|
|
44
|
+
# Affecte l'id permanent lors de la création d'un mobilier, s'il n'a pas déjà été renseigné.
|
|
45
|
+
# Par convention, l'id permanent est l'id principal du premier mobilier créé dans SL.
|
|
46
|
+
# Lorsque l'on remplace dans SL un mobilier par une nouvelle version, on doit lui attribuer
|
|
47
|
+
# manuellement son id permanent, afin qu'il l'envoie à l'application Rails lors de l'appel
|
|
48
|
+
# de "register".
|
|
49
|
+
def after_create
|
|
50
|
+
update_attribute(:permanent_id, id) if !permanent_id?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Enregistrement d'une nouvelle révision des panneaux du mobilier à chaque enregistrement,
|
|
54
|
+
# que ce soit "save" ou "update".
|
|
55
|
+
def after_save
|
|
56
|
+
panels.each do |p|
|
|
57
|
+
PanelRevision.add(p) # Nouvelle révision du panneau
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Cette classe gère les envois de mails
|
|
2
|
+
class Mailer < ActionMailer::Base
|
|
3
|
+
|
|
4
|
+
# Envoi de mail à un container lorsqu'un avatar clique sur un panel
|
|
5
|
+
#
|
|
6
|
+
# == Input
|
|
7
|
+
# +container_key+:: Clé du container contenant l'object à envoyer
|
|
8
|
+
# +avatar_key+:: Clé de l'avatar qui a cliqué sur le panel
|
|
9
|
+
# +object_name+:: Nom de l'object à envoyer
|
|
10
|
+
#
|
|
11
|
+
# == Output
|
|
12
|
+
#
|
|
13
|
+
# * Envoi d'un mail à un container dans SL.
|
|
14
|
+
def avtouch(container_key, avatar_key, object_name)
|
|
15
|
+
@subject = 'give inventory'
|
|
16
|
+
@body = { "avatar_key" => avatar_key, "object_name" => object_name }
|
|
17
|
+
@recipients = container_key + "@lsl.secondlife.com"
|
|
18
|
+
@from = 'webia@community-chest.net'
|
|
19
|
+
@sent_on = Time.now
|
|
20
|
+
@headers = {}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
# Schema version: 13
|
|
3
|
+
#
|
|
4
|
+
# Table name: networks
|
|
5
|
+
#
|
|
6
|
+
# id :integer(11) not null, primary key
|
|
7
|
+
# name :string(64) not null
|
|
8
|
+
# active :boolean(1) default(TRUE), not null
|
|
9
|
+
# created_at :datetime
|
|
10
|
+
# updated_at :datetime
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
class Network < ActiveRecord::Base
|
|
14
|
+
# XXX : Argh avec :nullify il se passe exactement le contraire de l'effet attendu !
|
|
15
|
+
# * Avec ":dependent => :nullify"
|
|
16
|
+
# - Quand on casse l'association d'un réseau et d'un panneau, Rails *supprime* le panneau
|
|
17
|
+
# au lieu de mettre le champ network_id à NULL
|
|
18
|
+
# - Mais Rails mets bien ce champ à NULL quand on fait "network.destroy"
|
|
19
|
+
# * Sans ":dependent => :nullify"
|
|
20
|
+
# - Quand on casse l'association, Rails mets à NULL le champ network_id, ce qui est bien, mais
|
|
21
|
+
# c'est le contraire de ce que dit la doc !
|
|
22
|
+
# - Quand on fait "network.destroy", Rails ne met pas à NULL network_id. Mais heureusement
|
|
23
|
+
# les FOREIGN KEYS de MySQL, qu'on a activé grâce à un plugin, corrige le problème.
|
|
24
|
+
has_many :panels #, :dependent => :nullify
|
|
25
|
+
|
|
26
|
+
STATES = [ [ "True", true ], [ "False", false ]]
|
|
27
|
+
|
|
28
|
+
validates_presence_of(:name, :message => "must be given a value")
|
|
29
|
+
validates_uniqueness_of(:name, :message => "is already use by another network")
|
|
30
|
+
|
|
31
|
+
# Enregistrement d'une nouvelle révision des panneaux du mobilier à chaque enregistrement,
|
|
32
|
+
# que ce soit "save" ou "update".
|
|
33
|
+
def after_save
|
|
34
|
+
panels.each do |p|
|
|
35
|
+
PanelRevision.add(p) # Nouvelle révision du panneau
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
# Schema version: 13
|
|
3
|
+
#
|
|
4
|
+
# Table name: objects_in_world
|
|
5
|
+
#
|
|
6
|
+
# id :integer(11) not null, primary key
|
|
7
|
+
# name :string(64) not null
|
|
8
|
+
# object_key :string(36) not null
|
|
9
|
+
# otype :string(16) not null
|
|
10
|
+
# container_id :integer(11) not null
|
|
11
|
+
# created_at :datetime
|
|
12
|
+
# updated_at :datetime
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
# Inclut la librairie ("lib/second_life_validators.rb") qui contient les
|
|
16
|
+
# validateurs Second Life
|
|
17
|
+
require 'second_life_validators'
|
|
18
|
+
|
|
19
|
+
class ObjectInWorld < ActiveRecord::Base
|
|
20
|
+
# Type d'objets in world autorisés
|
|
21
|
+
TYPES = [ "texture", "landmark", "notecard" ]
|
|
22
|
+
|
|
23
|
+
belongs_to :container
|
|
24
|
+
has_and_belongs_to_many :panels
|
|
25
|
+
|
|
26
|
+
validates_presence_of(:object_key, :name, :otype, :container_id, :message => "must be given a value")
|
|
27
|
+
validates_uniqueness_of(:object_key, :message => "must be unique")
|
|
28
|
+
|
|
29
|
+
# Format des id d'object dans Second Life
|
|
30
|
+
validates_format_of_sl_key(:object_key)
|
|
31
|
+
|
|
32
|
+
# Format du type d'objet
|
|
33
|
+
validates_inclusion_of(:otype, :in => TYPES, :message => "is an invalid object type")
|
|
34
|
+
|
|
35
|
+
# Retourne la texture par défaut
|
|
36
|
+
def self.default_texture
|
|
37
|
+
find_by_name_and_otype("default", "texture")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#----------------------------------------------------------------------------
|
|
41
|
+
# Gestion de la création de révisions de panneaux en 2 étapes.
|
|
42
|
+
# - Avant 'destroy', on note la liste des panneaux comportant l'objet à détruire
|
|
43
|
+
# - Après 'destroy', on crée une nouvelle révision pour chaque de ces objets.
|
|
44
|
+
@panels_needing_revisions = nil
|
|
45
|
+
|
|
46
|
+
# Note les id des panneaux dont on doit créer une nouvelle révision, avant destruction des objets associés
|
|
47
|
+
def before_destroy
|
|
48
|
+
@panels_needing_revisions = self.panels.map(&:id)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Enregistrement d'une nouvelle révision des panneaux du mobilier à chaque suppression d'objet.
|
|
52
|
+
# On reprend les id de panneaux qu'on a notés avant la destruction de l'objet.
|
|
53
|
+
def after_destroy
|
|
54
|
+
@panels_needing_revisions.each do |panel_id|
|
|
55
|
+
PanelRevision.add(Panel.find(panel_id)) # Nouvelle révision du panneau
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
# Fin gestion de la création des révisions de panneaux
|
|
59
|
+
#----------------------------------------------------------------------------
|
|
60
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
# Schema version: 13
|
|
3
|
+
#
|
|
4
|
+
# Table name: objects_off_world
|
|
5
|
+
#
|
|
6
|
+
# id :integer(11) not null, primary key
|
|
7
|
+
# name :string(64) not null
|
|
8
|
+
# object_key :string(36) not null
|
|
9
|
+
# otype :string(16) not null
|
|
10
|
+
# content :text
|
|
11
|
+
# created_at :datetime
|
|
12
|
+
# updated_at :datetime
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
require 'digest/md5'
|
|
16
|
+
# Inclut la librairie ("lib/second_life_validators.rb") qui contient les
|
|
17
|
+
# validateurs Second Life
|
|
18
|
+
require 'second_life_validators'
|
|
19
|
+
|
|
20
|
+
class ObjectOffWorld < ActiveRecord::Base
|
|
21
|
+
has_and_belongs_to_many :panels
|
|
22
|
+
|
|
23
|
+
# Types d'objets autorisés. Le format de la liste imbriquée est :
|
|
24
|
+
#
|
|
25
|
+
# Premier champ:: Valeur à afficher
|
|
26
|
+
# Deuxième champ:: Valeur à stocker en base
|
|
27
|
+
#
|
|
28
|
+
# On peut étendre cette liste pour ajouter de nouveaux types.
|
|
29
|
+
TYPES = [ [ "URL", "url" ],
|
|
30
|
+
[ "Media URL", "mediaurl" ] ]
|
|
31
|
+
|
|
32
|
+
validates_presence_of(:object_key, :name, :otype, :content, :message => "must be given a value")
|
|
33
|
+
# La clé est construite à partir de 'name' et 'content', seule elle a besoin d'être
|
|
34
|
+
# unique. Voir 'before_validation' pour la génération de la clé.
|
|
35
|
+
validates_uniqueness_of(:object_key, :message => "must be unique")
|
|
36
|
+
|
|
37
|
+
# Format des id d'object dans Second Life
|
|
38
|
+
validates_format_of_sl_key(:object_key)
|
|
39
|
+
|
|
40
|
+
# Format du type d'objet
|
|
41
|
+
validates_inclusion_of(:otype, :in => TYPES.collect { |type| type[1] }, :message => "is an invalid object type")
|
|
42
|
+
|
|
43
|
+
# Pour remplir le champ 'object_key', calcule le md5 de 'name' plus 'content'
|
|
44
|
+
# et réécrit le de façon à ce que ça ressemble à une clé Second Life, en
|
|
45
|
+
# rajoutant 4 tirets aux bons endroits.
|
|
46
|
+
def before_validation
|
|
47
|
+
# Si name ou content sont indéfini on ne peut pas calculer le MD5
|
|
48
|
+
return if name.nil? or content.nil?
|
|
49
|
+
|
|
50
|
+
key = Digest::MD5.new.update(name + content).to_s
|
|
51
|
+
self.object_key = key.sub(
|
|
52
|
+
/^([[:xdigit:]]{8})([[:xdigit:]]{4})([[:xdigit:]]{4})([[:xdigit:]]{4})([[:xdigit:]]{12})$/,
|
|
53
|
+
'\1-\2-\3-\4-\5')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#----------------------------------------------------------------------------
|
|
58
|
+
# Gestion de la création de révisions de panneaux en 2 étapes.
|
|
59
|
+
# - Avant 'destroy', on note la liste des panneaux comportant l'objet à détruire
|
|
60
|
+
# - Après 'destroy', on crée une nouvelle révision pour chaque de ces objets.
|
|
61
|
+
@panels_needing_revisions = nil
|
|
62
|
+
|
|
63
|
+
# Note les id des panneaux dont on doit créer une nouvelle révision, avant destruction des objets associés
|
|
64
|
+
def before_destroy
|
|
65
|
+
@panels_needing_revisions = self.panels.map(&:id)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Enregistrement d'une nouvelle révision des panneaux du mobilier à chaque suppression d'objet.
|
|
69
|
+
# On reprend les id de panneaux qu'on a notés avant la destruction de l'objet.
|
|
70
|
+
def after_destroy
|
|
71
|
+
@panels_needing_revisions.each do |panel_id|
|
|
72
|
+
PanelRevision.add(Panel.find(panel_id)) # Nouvelle révision du panneau
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
# Fin gestion de la création des révisions de panneaux
|
|
76
|
+
#----------------------------------------------------------------------------
|
|
77
|
+
end
|
data/app/models/panel.rb
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# == Panel
|
|
2
|
+
#
|
|
3
|
+
# Panel contient les panneaux publicitaires proprement dits. Ces panneaux appartiennent à
|
|
4
|
+
# des médias, décrits par le modèle Furniture.
|
|
5
|
+
|
|
6
|
+
# Inclut la librairie ("lib/second_life_validators.rb") qui contient les
|
|
7
|
+
# validateurs Second Life
|
|
8
|
+
require 'second_life_validators'
|
|
9
|
+
|
|
10
|
+
# == Panel
|
|
11
|
+
#
|
|
12
|
+
# Panel contient les panneaux publicitaires proprement dits. Ces panneaux appartiennent à
|
|
13
|
+
# des médias, décrits par le modèle Furniture.
|
|
14
|
+
#
|
|
15
|
+
# == Schema Information
|
|
16
|
+
# Schema version: 13
|
|
17
|
+
#
|
|
18
|
+
# Table name: panels
|
|
19
|
+
#
|
|
20
|
+
# id :integer(11) not null, primary key
|
|
21
|
+
# name :string(64) not null
|
|
22
|
+
# panel_key :string(36) not null
|
|
23
|
+
# furniture_id :integer(11) not null
|
|
24
|
+
# network_id :integer(11)
|
|
25
|
+
# created_at :datetime
|
|
26
|
+
# updated_at :datetime
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
class Panel < ActiveRecord::Base
|
|
30
|
+
belongs_to :network
|
|
31
|
+
belongs_to :furniture
|
|
32
|
+
has_and_belongs_to_many :objects_in_world
|
|
33
|
+
has_and_belongs_to_many :objects_off_world
|
|
34
|
+
|
|
35
|
+
validates_presence_of(:name, :panel_key, :furniture_id, :message => "must be given a value")
|
|
36
|
+
validates_uniqueness_of(:panel_key, :message => "must be unique")
|
|
37
|
+
# Format des id d'objets dans Second Life
|
|
38
|
+
validates_format_of_sl_key(:panel_key)
|
|
39
|
+
|
|
40
|
+
# Crée dynamiquement de nouveaux accessors pour les ObjectInWorld
|
|
41
|
+
#
|
|
42
|
+
# * texture()
|
|
43
|
+
# * texture=(new_texture)
|
|
44
|
+
# * landmark()
|
|
45
|
+
# * landmark=(new_landmark)
|
|
46
|
+
# * etc.
|
|
47
|
+
ObjectInWorld::TYPES.each do |type|
|
|
48
|
+
module_eval(%Q{
|
|
49
|
+
# Applique un object in world d'un type donné à un panneau
|
|
50
|
+
def #{type}=(new_oiw)
|
|
51
|
+
oiw = objects_in_world.find_by_otype("#{type}")
|
|
52
|
+
# Suppression si argument est nil
|
|
53
|
+
if new_oiw.nil?
|
|
54
|
+
objects_in_world.delete(oiw) if oiw
|
|
55
|
+
PanelRevision.add(self) # Nouvelle révision du panneau
|
|
56
|
+
return nil
|
|
57
|
+
end
|
|
58
|
+
# Vérification de type
|
|
59
|
+
if !new_oiw.instance_of?(ObjectInWorld) or new_oiw.otype != "#{type}"
|
|
60
|
+
raise TypeError, "Argument \#{new_oiw.inspect} is not a '#{type}' object"
|
|
61
|
+
end
|
|
62
|
+
# Le nouvel object est-il égal au précédent ?
|
|
63
|
+
if new_oiw == oiw
|
|
64
|
+
return oiw
|
|
65
|
+
end
|
|
66
|
+
objects_in_world.delete(oiw) if oiw
|
|
67
|
+
objects_in_world << new_oiw
|
|
68
|
+
PanelRevision.add(self) # Nouvelle révision du panneau
|
|
69
|
+
new_oiw
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Retourne l'object in world du type donné, associé à ce panneau
|
|
73
|
+
def #{type}
|
|
74
|
+
objects_in_world.find_by_otype("#{type}")
|
|
75
|
+
end
|
|
76
|
+
}, __FILE__, __LINE__)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Crée dynamiquement de nouveaux accessors pour les ObjectOffWorld
|
|
80
|
+
#
|
|
81
|
+
# * url()
|
|
82
|
+
# * url=(new_url)
|
|
83
|
+
# * etc.
|
|
84
|
+
ObjectOffWorld::TYPES.map { |t| t[1] }.each do |type|
|
|
85
|
+
# Retourne l'object off world du type donné, associé à ce panneau
|
|
86
|
+
module_eval(%Q{
|
|
87
|
+
# Applique un object off world d'un type donné à un panneau
|
|
88
|
+
def #{type}=(new_oow)
|
|
89
|
+
oow = objects_off_world.find_by_otype("#{type}")
|
|
90
|
+
# Suppression si argument est nil
|
|
91
|
+
if new_oow.nil?
|
|
92
|
+
objects_off_world.delete(oow) if oow
|
|
93
|
+
PanelRevision.add(self) # Nouvelle révision du panneau
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
# Vérification de type
|
|
97
|
+
if !new_oow.instance_of?(ObjectOffWorld) or new_oow.otype != "#{type}"
|
|
98
|
+
raise TypeError, "Argument \#{new_oow.inspect} is not a '#{type}' object"
|
|
99
|
+
end
|
|
100
|
+
# Le nouvel object est-il égal au précédent ?
|
|
101
|
+
if new_oow == oow
|
|
102
|
+
return oow
|
|
103
|
+
end
|
|
104
|
+
objects_off_world.delete(oow) if oow
|
|
105
|
+
objects_off_world << new_oow
|
|
106
|
+
PanelRevision.add(self) # Nouvelle révision du panneau
|
|
107
|
+
new_oow
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def #{type}
|
|
111
|
+
objects_off_world.find_by_otype("#{type}")
|
|
112
|
+
end
|
|
113
|
+
}, __FILE__, __LINE__)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Retourne la liste de tous les panneaux non attribués à un réseau
|
|
117
|
+
def self.unassigned_panels
|
|
118
|
+
Panel.find(:all, :conditions => [ 'network_id IS NULL' ])
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Met une texture par défaut si aucune n'est précisée à la création
|
|
122
|
+
def before_validation # :doc:
|
|
123
|
+
if !texture
|
|
124
|
+
self.texture = ObjectInWorld.default_texture
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Enregistrement d'une nouvelle révision du panneau à chaque enregistrement,
|
|
129
|
+
# que ce soit "save" ou "update".
|
|
130
|
+
#
|
|
131
|
+
# Ce callback sera appelé aussi bien pour les modification sur le panneau
|
|
132
|
+
# que lors de modifications du réseau associé.
|
|
133
|
+
def after_save
|
|
134
|
+
PanelRevision.add(self) # Nouvelle révision du panneau
|
|
135
|
+
end
|
|
136
|
+
end
|