OSDN Git Service

merge v06sheet
[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     self.visible > 0
65   end
66   
67   def usable? au
68     visible? au
69   end
70   
71   def tag_id
72     'sheet' + self.tag_sheet_id
73   end
74   
75   def tag_sheet_id
76     self.new_record? ? '0' : self.id.to_s
77   end
78   
79   def field_tag_id f
80     self.tag_id + f.to_s
81   end
82   
83   def self.default_page_size
84     25
85   end
86   
87   def self.max_page_size
88     100
89   end
90   
91   def self.default_panel_size
92     30
93   end
94   
95   def self.max_panel_size
96     200
97   end
98   
99   def self.page prm = nil
100     page = prm.to_i
101     page = 1 if page < 1
102     page
103   end
104   
105   def self.page_size prm = self.default_page_size
106     page_size = prm.to_i
107     page_size = self.max_page_size if page_size > self.max_page_size
108     page_size = self.default_page_size if page_size < 1
109     page_size
110   end
111   
112   def self.list_where
113     'sheets.visible > 0'
114   end
115   
116   def self.mylist_where au
117     ['sheets.author_id = ?', au.id]
118   end
119   
120   def self.himlist_where au
121     ['sheets.author_id = ? and sheets.visible > 0', au.id]
122   end
123   
124   def self.list page = 1, page_size = self.default_page_size
125     Sheet.where(self.list_where()).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
126   end
127   
128   def self.mylist au, page = 1, page_size = Author.default_sheet_page_size
129     Sheet.where(self.mylist_where(au)).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
130   end
131   
132   def self.himlist au, page = 1, page_size = Author.default_sheet_page_size
133     Sheet.where(self.himlist_where(au)).includes(Sheet.list_opt).order('sheets.updated_at desc').offset((page -1) * page_size).limit(page_size)
134   end
135   
136   def self.list_paginate page = 1, page_size = self.default_page_size
137     Kaminari.paginate_array(Array.new(Sheet.where(self.list_where()).count, nil)).page(page).per(page_size)
138   end
139   
140   def self.mylist_paginate au, page = 1, page_size = Author.default_sheet_page_size
141     Kaminari.paginate_array(Array.new(Sheet.where(self.mylist_where(au)).count, nil)).page(page).per(page_size)
142   end
143   
144   def self.himlist_paginate au, page = 1, page_size = Author.default_sheet_page_size
145     Kaminari.paginate_array(Array.new(Sheet.where(self.himlist_where(au)).count, nil)).page(page).per(page_size)
146   end
147   
148   def self.list_opt
149     {:sheet_panels => {:panel => {}}, :author => {} }
150   end
151   
152   def self.list_json_opt
153     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
154   end
155   
156   def self.show sid, roles
157     opt = {}
158     opt.merge!(Sheet.show_opt)
159     res = Sheet.find(sid, opt)
160     raise ActiveRecord::Forbidden unless res.visible?(roles)
161     res
162   end
163   
164   def self.edit sid, au
165     opt = {}
166     opt.merge!(Sheet.show_opt)
167     res = Sheet.find(sid, opt)
168     raise ActiveRecord::Forbidden unless res.own?(au)
169     res
170   end
171   
172   def self.show_opt
173     {:include => {:sheet_panels => {:panel => {}}, :author => {}}}
174   end
175   
176   def self.show_json_opt
177     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
178   end
179   
180   def parts_element
181     r = []
182     self.class.each_element_class_names do |k|
183       r += (self.elements_by_class_name(k) || [])
184     end
185     r
186   end
187   
188   def zorderd_elements
189     res = []
190     self.parts_element.each do |e|
191       res[e.z-1] = e
192     end
193     res
194   end
195   
196   def sheet_elements
197     res = []
198     self.parts_element.each do |e|
199       res[e.t] = e
200     end
201     res
202   end
203   
204   def new_t
205     self.sheet_elements.size
206   end
207   
208   def new_z
209     self.sheet_elements.size + 1
210   end
211   
212   def self.visible_count
213     Sheet.count 'visible > 0'
214   end
215   
216   def self.collect_element_value elements, name
217     elements.map {|e|
218       e.map {|o|
219         if o['_destroy'] or o[:_destroy]
220           nil
221         else
222           o[name]
223         end
224       }.compact
225     }.flatten
226   end
227   
228   def self.validate_serial ary, offset = 0
229     i = offset
230     ary.compact.sort.each do |n|
231       break false unless n == i
232       i += 1
233     end
234     ary.compact.size == i - offset
235   end
236   
237   def self.validate_element_serial elements, name, offset = 0
238     Sheet.validate_serial(Sheet.collect_element_value(elements, name), offset)
239   end
240   
241   def self.validate_elements_serial c
242     c.map {|conf|
243       Sheet.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
244     }.compact.empty?
245   end
246   
247   def validate_serial_list
248     l = []
249     self.class.each_element_class_names do |k|
250       l << self.elements_by_class_name(k)
251     end
252 #    l = [self.sheet_panels]
253     [
254       {:elements => l, :name => :t, :offset => 0}, 
255       {:elements => l, :name => :z, :offset => 1}
256     ]
257   end
258   
259   def validate_child
260 #    r1 = Panel.validate_elements_id validate_id_list
261     Sheet.validate_elements_serial validate_serial_list
262   end
263   
264   def store attr, au
265     if attr == false
266       self.errors.add :base, I18n.t('errors.invalid_json')
267       return false
268     end
269     self.attributes = attr
270     self.overwrite au
271     res = false
272     Sheet.transaction do
273       res = self.save
274       unless validate_child
275         res = false
276         self.errors.add :base, I18n.t('errors.invalid_t')
277         raise ActiveRecord::Rollback
278       end
279     end
280     res
281   end
282   
283   def destroy_with_sheet_panel
284     res = false
285     Sheet.transaction do
286       self.sheet_panels.each do |sheet_panel|
287         raise ActiveRecord::Rollback unless sheet_panel.destroy
288       end
289       raise ActiveRecord::Rollback unless self.destroy
290       res = true
291     end
292     res
293   end
294   
295   def scenario
296     panels.map {|panel|
297       panel.scenario
298     }.join
299   end
300   
301   def plain_scenario
302     panels.map {|panel|
303       panel.plain_scenario
304     }.join
305   end
306   
307   def licensed_pictures
308     r = {}
309     self.sheet_elements.each do |elm|
310       r.merge!(elm.licensed_pictures)
311     end
312     r
313   end
314   
315   def copy
316     attr = self.copy_attributes
317     Sheet.each_element_class_names do |n|
318       attr.merge! Sheet.class_name_to_class(n).panelize(self.elements_by_class_name(n).map {|elm|  elm.copy_attributes})
319     end
320     attr
321   end
322   
323   def copy_attributes
324     r = self.attributes
325     r.delete 'id'
326     r.delete 'author_id'
327     r.delete 'created_at'
328     r.delete 'updated_at'
329     r
330   end
331   
332   def self.panelize sheet
333     attr = sheet.attributes
334     attr.delete 'id'
335     attr
336   end
337   
338 end