OSDN Git Service

Merge branch 'v06' of git.sourceforge.jp:/gitroot/pettanr/pettanr into v06
[pettanr/pettanr.git] / app / models / sheet.rb
1 class Sheet < ActiveRecord::Base
2   has_many :sheet_panels
3   has_many :story_sheets
4   belongs_to :author
5   
6   validates :caption, :presence => true, :length => {:maximum => 100}
7   validates :width, :presence => true, :numericality => true, :natural_number => true
8   validates :height, :presence => true, :numericality => true, :natural_number => true
9   validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1}
10   accepts_nested_attributes_for :sheet_panels, :allow_destroy => true
11   before_validation :valid_encode
12   
13   def valid_encode
14     ['caption'].each do |a|
15       next if attributes[a] == nil
16       raise Pettanr::BadRequest unless attributes[a].valid_encoding?
17     end
18   end
19   
20   def self.each_element_class_names
21     {'SheetPanel' => 'sheet_panels'}.each do |k, n|
22       yield k
23     end
24   end
25   
26   def self.class_name_to_class k
27     Object.const_get k
28   end
29   
30   def self.each_element_classes
31     self.each_element_class_names do |k|
32       e = self.class_name_to_class k
33       yield e
34     end
35   end
36   
37   def elements_by_class_name class_name
38     self.__send__ class_name.tableize
39   end
40   
41   def supply_default
42     self.visible = 0 if self.visible.blank?
43   end
44   
45   def overwrite au
46     return false unless au
47     self.author_id = au.id
48   end
49   
50   def own? roles
51     roles = [roles] unless roles.respond_to?(:each)
52     au = Sheet.get_author_from_roles roles
53     return false unless au
54     self.author_id == au.id
55   end
56   
57   def visible? roles
58     if MagicNumber['run_mode'] == 0
59       return false unless guest_role_check(roles)
60     else
61       return false unless reader_role_check(roles)
62     end
63     return true if self.own?(roles)
64     return true if self.new_record?
65     self.visible > 0
66   end
67   
68   def usable? au
69     visible? au
70   end
71   
72   def tag_id
73     'sheet' + self.tag_sheet_id
74   end
75   
76   def tag_sheet_id
77     self.new_record? ? '0' : self.id.to_s
78   end
79   
80   def field_tag_id f
81     self.tag_id + f.to_s
82   end
83   
84   def self.default_page_size
85     25
86   end
87   
88   def self.max_page_size
89     100
90   end
91   
92   def self.default_panel_size
93     30
94   end
95   
96   def self.max_panel_size
97     200
98   end
99   
100   def self.page prm = nil
101     page = prm.to_i
102     page = 1 if page < 1
103     page
104   end
105   
106   def self.page_size prm = self.default_page_size
107     page_size = prm.to_i
108     page_size = self.max_page_size if page_size > self.max_page_size
109     page_size = self.default_page_size if page_size < 1
110     page_size
111   end
112   
113   def self.list_where
114     'sheets.visible > 0'
115   end
116   
117   def self.mylist_where au
118     ['sheets.author_id = ?', au.id]
119   end
120   
121   def self.himlist_where au
122     ['sheets.author_id = ? and sheets.visible > 0', au.id]
123   end
124   
125   def self.list page = 1, page_size = self.default_page_size
126     Sheet.where(self.list_where()).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
127   end
128   
129   def self.mylist au, page = 1, page_size = Author.default_sheet_page_size
130     Sheet.where(self.mylist_where(au)).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
131   end
132   
133   def self.himlist au, page = 1, page_size = Author.default_sheet_page_size
134     Sheet.where(self.himlist_where(au)).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
135   end
136   
137   def self.list_paginate page = 1, page_size = self.default_page_size
138     Kaminari.paginate_array(Array.new(Sheet.where(self.list_where()).count, nil)).page(page).per(page_size)
139   end
140   
141   def self.mylist_paginate au, page = 1, page_size = Author.default_sheet_page_size
142     Kaminari.paginate_array(Array.new(Sheet.where(self.mylist_where(au)).count, nil)).page(page).per(page_size)
143   end
144   
145   def self.himlist_paginate au, page = 1, page_size = Author.default_sheet_page_size
146     Kaminari.paginate_array(Array.new(Sheet.where(self.himlist_where(au)).count, nil)).page(page).per(page_size)
147   end
148   
149   def self.list_opt
150     {:sheet_panels => {:panel => {}}, :author => {} }
151   end
152   
153   def self.list_json_opt
154     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
155   end
156   
157   def self.show sid, roles
158     opt = {}
159     opt.merge!(Sheet.show_opt)
160     res = Sheet.find(sid, opt)
161     raise ActiveRecord::Forbidden unless res.visible?(roles)
162     res
163   end
164   
165   def self.edit sid, au
166     opt = {}
167     opt.merge!(Sheet.show_opt)
168     res = Sheet.find(sid, opt)
169     raise ActiveRecord::Forbidden unless res.own?(au)
170     res
171   end
172   
173   def self.show_opt
174     {:include => {:sheet_panels => {:panel => {}}, :author => {}}}
175   end
176   
177   def self.show_json_opt
178     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
179   end
180   
181   def parts_element
182     r = []
183     self.class.each_element_class_names do |k|
184       r += (self.elements_by_class_name(k) || [])
185     end
186     r
187   end
188   
189   def zorderd_elements
190     res = []
191     self.parts_element.each do |e|
192       res[e.z-1] = e
193     end
194     res
195   end
196   
197   def sheet_elements
198     res = []
199     self.parts_element.each do |e|
200       res[e.t] = e
201     end
202     res
203   end
204   
205   def new_t
206     self.sheet_elements.size
207   end
208   
209   def new_z
210     self.sheet_elements.size + 1
211   end
212   
213   def self.visible_count
214     Sheet.count 'visible > 0'
215   end
216   
217   def self.collect_element_value elements, name
218     elements.map {|e|
219       e.map {|o|
220         if o['_destroy'] or o[:_destroy]
221           nil
222         else
223           o[name]
224         end
225       }.compact
226     }.flatten
227   end
228   
229   def self.validate_serial ary, offset = 0
230     i = offset
231     ary.compact.sort.each do |n|
232       break false unless n == i
233       i += 1
234     end
235     ary.compact.size == i - offset
236   end
237   
238   def self.validate_element_serial elements, name, offset = 0
239     Sheet.validate_serial(Sheet.collect_element_value(elements, name), offset)
240   end
241   
242   def self.validate_elements_serial c
243     c.map {|conf|
244       Sheet.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
245     }.compact.empty?
246   end
247   
248   def validate_serial_list
249     l = []
250     self.class.each_element_class_names do |k|
251       l << self.elements_by_class_name(k)
252     end
253 #    l = [self.sheet_panels]
254     [
255       {:elements => l, :name => :t, :offset => 0}, 
256       {:elements => l, :name => :z, :offset => 1}
257     ]
258   end
259   
260   def validate_child
261 #    r1 = Panel.validate_elements_id validate_id_list
262     Sheet.validate_elements_serial validate_serial_list
263   end
264   
265   def boost
266     @new_element_index = 0
267     self.panel_elements.each do |elm|
268       if elm.new_record?
269         elm.new_index = @new_element_index
270         @new_element_index += 1
271       end
272     end
273   end 
274   
275   def store attr, au
276     if attr == false
277       self.errors.add :base, I18n.t('errors.invalid_json')
278       return false
279     end
280     self.attributes = attr
281     self.overwrite au
282     res = false
283     Sheet.transaction do
284       self.sheet_elements.each do |elm|
285         elm.new_sheet = self
286         elm.boost au
287       end
288       res = self.save
289       unless validate_child
290         res = false
291         self.errors.add :base, I18n.t('errors.invalid_t')
292         raise ActiveRecord::Rollback
293       end
294     end
295     res
296   end
297   
298   def destroy_with_sheet_panel
299     res = false
300     Sheet.transaction do
301       self.sheet_panels.each do |sheet_panel|
302         raise ActiveRecord::Rollback unless sheet_panel.destroy
303       end
304       raise ActiveRecord::Rollback unless self.destroy
305       res = true
306     end
307     res
308   end
309   
310   def scenario
311     panels.map {|panel|
312       panel.scenario
313     }.join
314   end
315   
316   def plain_scenario
317     panels.map {|panel|
318       panel.plain_scenario
319     }.join
320   end
321   
322   def licensed_pictures
323     r = {}
324     self.sheet_elements.each do |elm|
325       r.merge!(elm.licensed_pictures)
326     end
327     r
328   end
329   
330   def copyable?
331     r = true
332     Sheet.each_element_class_names do |n|
333       self.elements_by_class_name(n).each do |elm|
334         next if elm.copyable?
335         r = false
336         break
337       end
338       break unless r
339     end
340     r
341   end
342   
343   def copy
344     attr = self.copy_attributes
345     Sheet.each_element_class_names do |n|
346       element_attr = Sheet.class_name_to_class(n).panelize(
347         self.elements_by_class_name(n).map {|elm|
348           elm.copy_attributes.merge elm.panel_attributes
349         }
350       )
351       attr.merge! element_attr
352     end
353     attr
354   end
355   
356   def copy_attributes
357     r = self.attributes
358     r.delete 'id'
359     r.delete 'author_id'
360     r.delete 'created_at'
361     r.delete 'updated_at'
362     r
363   end
364   
365   def self.panelize sheet
366     attr = sheet.attributes
367     attr.delete 'id'
368     attr
369   end
370   
371 end