OSDN Git Service

dd919d0468a251f432db788d2b1880c55379f3d8
[pettanr/pettanr.git] / app / models / panel.rb
1 #コマ
2 class Panel < ActiveRecord::Base
3   belongs_to :author
4   belongs_to :resource_picture
5   has_many :stories
6   has_many :panel_pictures, :dependent => :destroy
7   has_many :speech_balloons, :dependent => :destroy
8   has_many :ground_pictures, :dependent => :destroy
9   has_many :ground_colors, :dependent => :destroy
10   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
11   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
12   accepts_nested_attributes_for :ground_pictures, :allow_destroy => true
13   accepts_nested_attributes_for :ground_colors, :allow_destroy => true
14
15   validates :width, :presence => true, :numericality => true, :natural_number => true
16   validates :height, :presence => true, :numericality => true, :natural_number => true
17   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
18   validates :x, :numericality => {:allow_blank => true}
19   validates :y, :numericality => {:allow_blank => true}
20   validates :z, :numericality => {:allow_blank => true, :greater_than => 0}
21   validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
22   validates :publish, :presence => true, :numericality => true
23   
24   before_validation :valid_encode
25   
26   def valid_encode
27     ['caption'].each do |a|
28       next if attributes[a] == nil
29       raise Pettanr::BadRequest unless attributes[a].valid_encoding?
30     end
31   end
32   
33   def supply_default
34     self.border = 2
35     self.publish = 0
36   end
37   
38   def overwrite au
39     self.author_id = au.id
40   end
41   
42   def own? roles
43     roles = [roles] unless roles.respond_to?(:each)
44     au = Panel.get_author_from_roles roles
45     return false unless au
46     self.author_id == au.id
47   end
48   
49   def visible? roles
50     if MagicNumber['run_mode'] == 0
51       return false unless guest_role_check(roles)
52     else
53       return false unless reader_role_check(roles)
54     end
55     return true if self.own?(roles)
56     self.publish?
57   end
58   
59   def usable? au
60     visible? au
61   end
62   
63   def publish?
64     self.publish > 0
65   end
66   
67   def tag_id
68     'panel' + self.tag_panel_id
69   end
70   
71   def tag_panel_id
72     self.new_record? ? '0' : self.id.to_s
73   end
74   
75   def field_tag_id f
76     self.tag_id + f.to_s
77   end
78   
79   def field_tree f
80     'panels-' + tag_panel_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.page prm = nil
92     page = prm.to_i
93     page = 1 if page < 1
94     page
95   end
96   
97   def self.page_size prm = self.default_page_size
98     page_size = prm.to_i
99     page_size = self.max_page_size if page_size > self.max_page_size
100     page_size = self.default_page_size if page_size < 1
101     page_size
102   end
103   
104   def self.list_where
105     'panels.publish > 0'
106   end
107   
108   def self.mylist_where au
109     ['panels.author_id = ?', au.id]
110   end
111   
112   def self.himlist_where au
113     ['panels.author_id = ? and panels.publish > 0', au.id]
114   end
115   
116   def self.list page = 1, page_size = self.default_page_size
117     Panel.where(self.list_where()).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
118   end
119   
120   def self.mylist au, page = 1, page_size = Author.default_panel_page_size
121     Panel.where(self.mylist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
122   end
123   
124   def self.himlist au, page = 1, page_size = Author.default_panel_page_size
125     Panel.where(self.himlist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
126   end
127   
128   def self.list_paginate page = 1, page_size = self.default_page_size
129     Kaminari.paginate_array(Array.new(Panel.where(self.list_where()).count, nil)).page(page).per(page_size)
130   end
131   
132   def self.mylist_paginate au, page = 1, page_size = Author.default_panel_page_size
133     Kaminari.paginate_array(Array.new(Panel.where(self.mylist_where(au)).count, nil)).page(page).per(page_size)
134   end
135   
136   def self.himlist_paginate au, page = 1, page_size = Author.default_panel_page_size
137     Kaminari.paginate_array(Array.new(Panel.where(self.himlist_where(au)).count, nil)).page(page).per(page_size)
138   end
139   
140   def self.list_opt
141     {
142       :panel_pictures => {
143         :picture => {:artist => {}, :license => {}}
144       }, 
145       :speech_balloons => {:balloon => {}, :speech => {}},
146       :ground_pictures => {
147         :picture => {:artist => {}, :license => {}}
148       }, 
149       :ground_colors => {
150       }, 
151       :author => {}
152     }
153   end
154   
155   def self.show rid, roles
156     opt = {}
157     opt.merge!(Panel.show_opt)
158     res = Panel.find(rid, opt)
159     raise ActiveRecord::Forbidden unless res.visible?(roles)
160     res
161   end
162   
163   def self.edit rid, au
164     opt = {}
165     opt.merge!(Panel.show_opt)
166     res = Panel.find(rid, opt)
167     raise ActiveRecord::Forbidden unless res.own?(au)
168     res
169   end
170   
171   def self.show_opt
172     {:include => {
173       :panel_pictures => {
174         :picture => {:artist => {}, :license => {}}
175       }, 
176       :speech_balloons => {:balloon => {}, :speech => {}},
177       :ground_pictures => {
178         :picture => {:artist => {}, :license => {}}
179       }, 
180       :ground_colors => {
181       }, 
182       :author => {}
183     }}
184   end
185   
186   def parts_element
187     ((self.panel_pictures || []) + (self.speech_balloons || []) + (self.ground_colors || []) + (self.ground_pictures || [])).compact
188   end
189   
190   def parts
191   end
192   
193   def zorderd_elements
194     res = []
195     self.parts_element.each do |e|
196       res[e.z-1] = e
197     end
198     res
199   end
200   
201   def panel_elements
202     res = []
203     self.parts_element.each do |e|
204       res[e.t] = e
205     end
206     res
207   end
208   
209   @@elm_json_opt = {
210     'PanelPicture' => {
211       :picture => {:artist => {}, :license => {}}
212     }, 
213     'SpeechBalloon' => {:balloon => {}, :speech => {}},
214     'GroundPicture' => {
215       :picture => {:artist => {}, :license => {}}
216     }, 
217     'GroundColor' => {
218     }, 
219   }
220   
221   def self.elm_json_opt e
222     @@elm_json_opt[e.class.to_s]
223   end
224   
225   def elements
226     self.panel_elements.map {|e|
227       #(-_-;)<... kore wa hidoi
228       JSON.parse e.to_json({:include => Panel.elm_json_opt(e)})
229     }
230   end
231   
232   def panel_elements_as_json
233     self.to_json({:include => {:author => {}}, :methods => :elements})
234   end
235   
236   def self.list_as_json_text ary
237     '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']'
238   end
239   
240   def new_t
241     self.panel_elements.size
242   end
243   
244   def new_z
245     self.panel_elements.size + 1
246   end
247   
248   def scenario
249     panel_elements.map { |e|
250       e.scenario
251     }.join
252   end
253   
254   def plain_scenario
255     panel_elements.map { |e|
256       e.plain_scenario
257     }.join
258   end
259   
260   def licensed_pictures
261     r = {}
262     ((self.panel_pictures || []) + (self.ground_pictures || [])).compact.each do |elm|
263       r[elm.picture_id] = elm.picture unless r[elm.picture_id]
264     end
265     r
266   end
267   
268   def self.visible_count
269     Panel.count
270   end
271   
272   def self.collect_element_value elements, name
273     elements.map {|e|
274       e.map {|o|
275         if o['_destroy'] or o[:_destroy]
276           nil
277         else
278           o[name]
279         end
280       }.compact
281     }.flatten
282   end
283   
284   def self.validate_serial ary, offset = 0
285     i = offset
286     ary.compact.sort.each do |n|
287       break false unless n == i
288       i += 1
289     end
290     ary.compact.size == i - offset
291   end
292   
293   def self.validate_element_serial elements, name, offset = 0
294     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
295   end
296   
297   def self.validate_elements_serial c
298     c.map {|conf|
299       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
300     }.compact.empty?
301   end
302   
303   def validate_serial_list
304     [
305       {:elements => [self.panel_pictures, self.speech_balloons, self.ground_colors, self.ground_pictures], :name => :t, :offset => 0}, 
306       {:elements => [self.panel_pictures, self.speech_balloons, self.ground_colors, self.ground_pictures], :name => :z, :offset => 1}
307     ]
308   end
309   def validate_child
310 #    r1 = Panel.validate_elements_id validate_id_list
311     Panel.validate_elements_serial validate_serial_list
312   end
313   
314   def store attr, au
315     if attr == false
316       self.errors.add :base, I18n.t('errors.invalid_json')
317       return false
318     end
319     self.attributes = attr
320     self.overwrite au
321     res = false
322     Panel.transaction do
323       res = self.save
324       unless validate_child
325         res = false
326         self.errors.add :base, I18n.t('errors.invalid_t')
327         raise ActiveRecord::Rollback
328       end
329     end
330     res
331   end
332   
333   def remove_element target, au
334     ct = target.t
335     cz = target.z
336     panel_attributes = {}
337     self.panel_elements.each do |elm|
338       attr = elm.attributes
339       if elm == target
340         attr['_destroy'] = true
341       end
342       if elm.t > ct
343         attr['t']  -= 1 
344       end
345       if elm.z > cz
346         attr['z']  -= 1 
347       end
348       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
349       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
350     end
351     self.store(panel_attributes, au)
352   end
353   
354   def destroy_with_elements
355     res = false
356     Panel.transaction do
357       self.parts_element.each do |element|
358         raise ActiveRecord::Rollback unless element.destroy
359       end
360       raise ActiveRecord::Rollback unless self.destroy
361       res = true
362     end
363     res
364   end
365   
366   def copy
367     attr = self.copy_attributes
368     attr.merge! PanelPicture.panelize(self.panel_pictures.map {|elm|  elm.copy_attributes})
369     attr.merge! SpeechBalloon.panelize(self.speech_balloons.map {|elm|  elm.copy_attributes})
370     attr.merge! GroundPicture.panelize(self.ground_pictures.map {|elm|  elm.copy_attributes})
371     attr.merge! GroundColor.panelize(self.ground_colors.map {|elm|  elm.copy_attributes})
372     p attr
373     attr
374   end
375   
376   def copy_attributes
377     r = self.attributes
378     r.delete 'id'
379     r.delete 'author_id'
380     r.delete 'created_at'
381     r.delete 'updated_at'
382     r
383   end
384   
385   def self.panelize panel
386     attr = panel.attributes
387     attr.delete 'id'
388     attr
389   end
390   
391   
392 =begin
393   def self.validate_id ary, pid
394     ary.map {|v|
395       if pid
396         (v == pid or v == nil) ? nil : false
397       else
398         v ? false : nil
399       end
400     }.compact.empty?
401   end
402   
403   def self.validate_element_id elements, name, pid
404     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
405   end
406   
407   def self.validate_elements_id c
408     c.map {|conf|
409       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
410     }.compact.empty?
411   end
412   
413   def validate_id_list
414     r = self.speech_balloons.map {|sb|
415       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
416     }
417     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
418     r
419   end
420 =end
421   
422 end