OSDN Git Service

1f2c8f8de2d2c57ccd0ebe1b2c4ec06281f6b81f
[pettanr/pettanr.git] / lib / peta / item.rb
1 module Peta
2   class Item < ActiveRecord::Base
3     self.abstract_class = true
4     attr :boosters
5     
6     # Dynamic ClassMethods
7     
8     def self._dev?
9       Rails.env == "development"
10     end
11     
12     def self._skip_load?
13       if self._dev?
14         return true unless self.my_manifest
15         return true unless Manifest.manifest.items
16         return true unless Manifest.manifest.models
17       end
18       false
19     end
20     
21     def self.load_manifest
22       return nil if self._skip_load?
23       vc = self.my_manifest.valid_encode_columns
24       define_singleton_method("valid_encode_columns") do 
25         vc
26       end
27       cm = self.my_manifest.child_models
28       define_singleton_method("child_models") do
29         cm
30       end
31       cen = self.my_manifest.child_element_names
32       define_singleton_method("child_element_names") do
33         cen
34       end
35       # Instance Methods
36     end
37     
38     # ClassMethods
39     # class_name
40     # table_name
41     
42     before_validation :valid_encode
43     
44     def self.my_peta
45       return nil unless Manifest.manifest.items
46       Manifest.manifest.items[self.item_name]
47     end
48     
49     def self.my_controller
50       return nil unless Manifest.manifest.controllers
51       Manifest.manifest.controllers[self.table_name]
52     end
53     
54     def self.my_manifest
55       return nil unless Manifest.manifest.models
56       Manifest.manifest.models[self.item_name]
57     end
58     
59     def self.singular
60       self.to_s
61     end
62     
63     def self.plural
64       self.singular.pluralize
65     end
66     
67     def self.item_name
68       self.singular.underscore
69     end
70     
71     def self.item?
72       true
73     end
74     
75     def self.content?
76       false
77     end
78     
79     def self.element?
80       false
81     end
82     
83     def self.root?
84       false
85     end
86     
87     def self.parent_model
88       nil
89     end
90     
91     def self.path_name with_engine = false
92       self.plural.underscore
93     end
94     
95     def self.pickup_item_name
96       self.item_name
97     end
98     
99     def self.pickup_column_name
100       'id'
101     end
102     
103     def self.find_boost_name column_name
104       self.my_peta.find_boost_name column_name
105     end
106     
107     def self.extend_column? column_name
108       self.my_peta.extend_column? column_name
109     end
110     
111     def self.list_where
112       ''
113     end
114     
115     def self.list_order
116       self.table_name + '.updated_at desc'
117     end
118     
119     def self.list_opt
120       {}
121     end
122     
123     def self.list_json_opt
124       {}
125     end
126     
127     def self.show item_id, operators = nil
128       opt = {}
129       opt.merge!(self.show_opt)
130       item = self.find(item_id, opt)
131       item.boosts 'read'
132       raise ActiveRecord::Forbidden if operators and item.visible?(operators) == false
133       item
134     end
135     
136     def self.show_opt
137       {}
138     end
139     
140     def self.show_json_opt
141       {}
142     end
143     
144     def self.fold_extend_settings attr
145       self.my_peta.boost.each do |name, manifest|
146         my_settings = attr[manifest.settings_column_name]
147         if my_settings.is_a?(Hash)
148           attr[manifest.settings_column_name] = my_settings.to_json
149         end
150       end
151     end
152     
153     #InstanceMethods
154     
155     def item_name
156       self.class.item_name
157     end
158     
159     def model_name
160       self.item_name
161     end
162     
163     def table_name
164       self.class.table_name
165     end
166     
167     def path_name with_engine = false
168       self.class.path_name(with_engine)
169     end
170     
171     def pickup_item_name
172       self.class.pickup_item_name
173     end
174     
175     def pickup_column_name
176       self.class.pickup_column_name
177     end
178     
179     def pickup_id
180       self.attributes[self.pickup_column_name]
181     end
182     
183     def form_template with_engine = false
184       self.path_name(with_engine) + '/form'
185     end
186     
187     def form_name
188       self.extend_column ? self.attributes[self.extend_column] : self.item_name
189     end
190     
191     def valid_encode
192       self.class.valid_encode_columns.each do |a|
193         next if attributes[a] == nil
194         raise Pettanr::BadRequest unless self.attributes[a].valid_encoding?
195       end
196     end
197     
198     def boosts level
199       self.class.my_peta.boost.each do |boost_name, boost_manifest|
200         next if level == 'read' and boost_manifest.level == 'post'
201         self.boost boost_manifest
202       end
203     end
204     
205     def boost boost_manifest
206       @boosters ||= {}
207       @boosters[boost_manifest.name] ||= Locmare::Booster.new(boost_manifest, self)
208     end
209     
210     def boosters
211       @boosters ||= {}
212     end
213     
214     def extend_column? column_name
215       self.class.extend_column? column_name
216     end
217     
218     def supply_default
219       self.boosters.each do |boost_name, booster|
220         booster.supply_default
221       end
222     end
223     
224     def overwrite 
225       self.boosters.each do |boost_name, booster|
226         booster.overwrite
227       end
228     end
229     
230     def user_visible? operators
231       if Manifest.manifest.magic_numbers['run_mode'] == 0
232         return false unless operators.guest?
233       else
234         return false unless operators.resource_reader?
235       end
236       true
237     end
238     
239     def visible? operators
240       return false unless self.user_visible? operators
241       true
242     end
243     
244     def editize?
245       self.respond_to? :editor
246     end
247     
248     def dom_id
249       self.id.to_s
250     end
251     
252     def dom_pool_type
253       self.new_record? ? 'stored' : 'new'
254     end
255     
256     def merge_dom_item_id attr, name = nil
257       if self.editize?
258         attr.merge({'id' => self.dom_item_id(name)})
259       else
260         attr
261       end
262     end
263     
264     def tag_attributes name = nil, opt = {}
265       r = {
266         'data-pool_type' => self.dom_pool_type, 'data-id' => self.dom_id, 
267         'data-item_name' => self.item_name
268       }
269       r = self.merge_dom_item_id r, name
270       r.merge!(opt)
271       r
272     end
273     
274     def field_tag_attributes column_name, opt = {}
275       self.tag_attributes(column_name, opt).merge(
276         {'data-column_name' => column_name}
277       )
278     end
279     
280     def post_attribute_key
281       self.dom_id
282     end
283     
284     ##################################################################
285     # importer
286     ##################################################################
287     
288     def self.each_import data
289       data.each do |n, d|
290         yield n, d
291       end
292     end
293     
294     def self.import_system_picture attr
295       d = attr["text"]
296       return false if d.blank?
297       imager = PettanImager.load(Base64.decode64(d.to_s))
298       return false unless imager
299       sp = SystemPicture.store(imager)
300       return false unless sp
301       sp.id
302     end
303     
304     def self.replace_system_picture attr
305       attr.each do |name, value|
306         if value.is_a? Hash
307           r = if name.to_s =~ /_id$/
308             self.import_system_picture value
309           else
310             self.replace_system_picture value
311           end
312           return false unless r
313           attr[name] = r
314         end
315       end
316     end
317     
318     def self.modify_object(name, attr, key = 'name')
319       c = 'find_by_' + key.to_s
320       r = self.__send__ c, name
321       if r
322         r.attributes = attr
323       else
324         r = self.new attr
325         r[key] = name
326       end
327       r
328     end
329     
330     def self.import_list(attrs, &blk)
331       res = []
332       self.transaction do
333         attrs.each do |name, item|
334           m = blk.call(name, item)
335           res.push(m) unless m.valid?
336         end
337         raise ActiveRecord::Rollback unless res.empty?
338       end
339       res
340     end
341     
342     def self.import_text(text, &blk)
343       attrs = JSON.parse(text)
344       self.import_list attrs, &blk
345     end
346     
347     def self.import_file(filename, &blk)
348       text = File.open(filename, 'r').read
349       self.import_text text, &blk
350     end
351     
352     def self.import_url(url, &blk)
353       text = open(url).read
354       self.import_text text, &blk
355     end
356     
357     def self.import_urls(urls, &blk)
358       r = {}
359       urls.each do |url|
360         h = {}
361         begin
362           h[:validations] = self.import_url(url, &blk)
363         rescue
364           h[:exception] = {:location => $@, :message => $!}
365         end
366         r[url] = h
367       end
368       r
369     end
370     
371   end
372 end