OSDN Git Service

t#29312:any update
[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   has_many :panel_colors, :dependent => :destroy
11   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
12   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
13   accepts_nested_attributes_for :ground_pictures, :allow_destroy => true
14   accepts_nested_attributes_for :ground_colors, :allow_destroy => true
15   accepts_nested_attributes_for :panel_colors, :allow_destroy => true
16
17   validates :width, :presence => true, :numericality => true, :natural_number => true
18   validates :height, :presence => true, :numericality => true, :natural_number => true
19   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
20   validates :x, :numericality => {:allow_blank => true}
21   validates :y, :numericality => {:allow_blank => true}
22   validates :z, :numericality => {:allow_blank => true, :greater_than => 0}
23   validates :author_id, :presence => true, :numericality => true, :existence => true
24   
25   def supply_default
26     self.border = 2
27   end
28   
29   def overwrite au
30     return false unless au
31     self.author_id = au.id
32   end
33   
34   def self.collect_element_value elements, name, ex_nil = false
35     e = elements.map {|e|
36       e.map {|o|
37         o[name]
38       }
39     }.flatten
40     e = e.compact if ex_nil
41     e
42   end
43   
44   def self.validate_id ary, pid
45     ary.map {|v|
46       if pid
47         (v == pid or v == nil) ? nil : false
48       else
49         v ? false : nil
50       end
51     }.compact.empty?
52   end
53   
54   def self.validate_element_id elements, name, pid
55     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
56   end
57   
58   def self.validate_elements_id c
59     c.map {|conf|
60       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
61     }.compact.empty?
62   end
63   
64   def self.validate_t ary
65     i = 0
66     ary.compact.sort.each do |t|
67       break false unless t == i
68       i += 1
69     end
70     ary.compact.size == i
71   end
72   
73   def self.validate_element_t elements, name
74     Panel.validate_t(Panel.collect_element_value(elements, name, true))
75   end
76   
77   def self.validate_elements_t c
78     c.map {|conf|
79       Panel.validate_element_t(conf[:elements], conf[:name]) ? nil : false
80     }.compact.empty?
81   end
82   
83   def validate_id_list
84     r = self.speech_balloons.map {|sb|
85       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
86     }
87     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
88     r
89   end
90   
91   def validate_child
92     r1 = Panel.validate_elements_id validate_id_list
93     r2 = Panel.validate_elements_t [
94       {:elements => [self.panel_pictures, self.speech_balloons], :name => :t}
95     ]
96     r1 and r2
97   end
98   
99   def store
100     res = false
101     Panel.transaction do
102       unless validate_child
103         self.errors.add :base , 'invalid time'
104         raise ActiveRecord::Rollback
105       end
106       res = self.save
107     end
108     res
109   end
110   
111   def self.default_page_size
112     25
113   end
114   
115   def self.max_page_size
116     100
117   end
118   
119   def self.page prm = nil
120     page = prm.to_i
121     page = 1 if page < 1
122     page
123   end
124   
125   def self.page_size prm = self.default_page_size
126     page_size = prm.to_i
127     page_size = self.max_page_size if page_size > self.max_page_size
128     page_size = self.default_page_size if page_size < 1
129     page_size
130   end
131   
132   def self.offset cnt, prm = nil
133     offset = prm.to_i
134     offset = cnt - 1 if offset >= cnt
135     offset = cnt - offset.abs if offset < 0
136     offset = 0 if offset < 0
137     offset
138   end
139   
140   def self.list opt = {}, page = 1, page_size = self.default_page_size
141     opt.merge!(self.list_opt) unless opt[:include]
142     opt.merge!({:conditions => 'panels.publish > 0', :order => 'panels.updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
143     Panel.find(:all, opt)
144   end
145   
146   def self.list_opt
147     {:include => {
148       :panel_pictures => {
149         :picture => {:artist => {}, :license => {}}
150       }, 
151       :speech_balloons => {:balloons => {}, :speeches => {}},
152       :ground_pictures => {
153         :picture => {:artist => {}, :license => {}}
154       }, 
155       :ground_colors => {
156         :color => {}
157       }, 
158       :panel_colors => {
159       }, 
160       :author => {}
161     }}
162   end
163   
164   def self.list_json_opt
165     {:include => {
166       :panel_pictures => {
167         :picture => {:artist => {}, :license => {}}
168       }, 
169       :speech_balloons => {:balloons => {}, :speeches => {}},
170       :ground_pictures => {
171         :picture => {:artist => {}, :license => {}}
172       }, 
173       :ground_colors => {
174         :color => {}
175       }, 
176       :panel_colors => {
177       }, 
178       :author => {}
179     }}
180   end
181   
182   def self.mylist au, opt = {}, page = 1, panel_page_size = Author.default_panel_page_size
183     opt.merge!(self.list_opt) unless opt[:include]
184     opt.merge!({:conditions => ['panels.author_id = ?', au.id], :order => 'panels.updated_at desc', :limit => panel_page_size, :offset => (page -1) * page_size})
185     Panel.find(:all, opt)
186   end
187   
188   def self.show rid, au, opt = {}
189     r = Panel.find(rid, :include => self.show_include_opt(opt))
190     raise ActiveRecord::Forbidden unless r.visible?(au)
191     r
192   end
193   
194   def self.edit rid, au, opt = {}
195     r = Panel.find(rid, :include => self.show_include_opt(opt))
196     raise ActiveRecord::Forbidden unless r.own?(au)
197     r
198   end
199   
200   def self.show_include_opt opt = {}
201     res = {
202       :panel_pictures => {
203         :picture => {:artist => {}, :license => {}}
204       }, 
205       :speech_balloons => {:balloons => {}, :speeches => {}},
206       :ground_pictures => {
207         :picture => {:artist => {}, :license => {}}
208       }, 
209       :ground_colors => {
210         :color => {}
211       }, 
212       :panel_colors => {
213       }, 
214       :author => {}
215     }
216     res.merge!(opt[:include]) if opt[:include]
217     res
218   end
219   
220   def self.show_json_include_opt
221     {:include => {
222       :panel_pictures => {
223         :picture => {:artist => {}, :license => {}}
224       }, 
225       :speech_balloons => {:balloons => {}, :speeches => {}},
226       :ground_pictures => {
227         :picture => {:artist => {}, :license => {}}
228       }, 
229       :ground_colors => {
230         :color => {}
231       }, 
232       :panel_colors => {
233       }, 
234       :author => {}
235     }}
236   end
237   
238   def visible? au
239     return false unless au
240     self.own?(au) or self.publish?
241   end
242   
243   def own? author
244     return false unless author
245     self.author_id == author.id
246   end
247   
248   def usable? au
249     visible? au
250   end
251   
252   def publish?
253     self.publish > 0
254   end
255   
256   def sort_by_time
257     pe = []
258     self.panel_pictures.each do |picture|
259       pe[picture.t] = picture
260     end
261     self.speech_balloons.each do |sb|
262       pe[sb.t] = sb
263     end
264     pe
265   end
266   
267   def each_ground
268     (self.ground_colors || []) + (self.ground_pictures || []) + (self.panel_colors || []).each do |e|
269       yield e
270     end
271   end
272   
273   def each_element
274     self.sort_by_time.each do |e|
275       yield e
276     end
277   end
278   
279   def panel_elements
280     res = []
281     self.each_element do |elm|
282       if elm.kind_of?(PanelPicture)
283         res[elm.t] = elm.to_json({:include => {:picture => {:artist => {}, :license => {}}}})
284       end
285       if elm.kind_of?(SpeechBalloon)
286         res[elm.t] = elm.to_json({:include => {:balloons => {}, :speeches => {}}})
287       end
288     end
289     self.each_ground do |elm|
290       if elm.kind_of?(GroundColor)
291         res <<  elm.to_json({:include => :color})
292       end
293       if elm.kind_of?(GroundPicture)
294         res << elm.to_json({:include => {:picture => {:artist => {}, :license => {}}}})
295       end
296       if elm.kind_of?(PanelColor)
297         res << elm.to_json({:include => {}})
298       end
299     end
300     res
301   end
302   
303   def to_json_play
304     self.to_json :methods => :panel_elements
305   end
306   
307   def self.visible_count
308     Panel.count
309   end
310   
311 end