OSDN Git Service

t#30102#30122:update i18n index
[pettanr/pettanr.git] / app / models / story.rb
1 #ストーリー
2 class Story < ActiveRecord::Base
3   belongs_to :author
4   belongs_to :panel
5   belongs_to :comic
6   
7   validates :comic_id, :presence => true, :numericality => true, :existence => true
8   validates :panel_id, :presence => true, :numericality => true, :existence => true
9   validates :author_id, :presence => true, :numericality => true, :existence => true
10   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
11   
12   def supply_default
13     self.t = nil
14   end
15   
16   def overwrite au
17     return false unless au
18     self.author_id = au.id
19   end
20   
21   def own? au
22     return false unless au.is_a?(Author)
23     self.author_id == au.id
24   end
25   
26   def visible? au
27     if au == nil
28       return false if MagicNumber['run_mode'] == 1
29     elsif au.is_a?(Author)
30       return true if self.comic.own?(au)
31     else
32       return false
33     end
34     self.comic.visible? au
35   end
36   
37   def self.default_panel_size
38     30
39   end
40   
41   def self.max_panel_size
42     200
43   end
44   
45   def self.offset cnt, prm = nil
46     offset = prm.to_i
47     offset = cnt - 1 if offset >= cnt
48     offset = cnt - offset.abs if offset < 0
49     offset = 0 if offset < 0
50     offset
51   end
52   
53   def self.panel_count cnt, prm = self.default_panel_size
54     count = prm.to_i
55     count = self.max_panel_size if count > self.max_panel_size
56     count = self.default_panel_size if count < 1
57     count
58   end
59   
60   def self.play_list comic, author, offset = 0, limit = Story.default_panel_size
61     opt = {}
62     opt.merge!(Story.list_opt)
63     opt.merge!({:offset => offset, :limit => limit}) if limit > 0
64     opt.merge!({:conditions => ['stories.comic_id = ?', comic.id], :order => 'stories.t'})
65     Story.find(:all, opt)
66   end
67   
68   def self.list_opt
69     {:include => {
70       :author => {}, 
71       :comic => {
72         :author => {}
73       }, 
74       :panel => {
75         :author => {}, 
76         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
77         :speech_balloons =>{:balloons => {}, :speeches => {}}
78       }
79     }}
80   end
81   
82   def self.list_json_opt
83     {:include => {
84       :author => {}, 
85       :comic => {
86         :author => {}
87       }, 
88       :panel => {
89         :author => {}, 
90         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
91         :speech_balloons =>{:balloons => {}, :speeches => {}}
92       }
93     }}
94   end
95   
96   def self.default_page_size
97     25
98   end
99   
100   def self.max_page_size
101     100
102   end
103   
104   def self.page prm = nil
105     page = prm.to_i
106     page = 1 if page < 1
107     page
108   end
109   
110   def self.page_size prm = self.default_page_size
111     page_size = prm.to_i
112     page_size = self.max_page_size if page_size > self.max_page_size
113     page_size = self.default_page_size if page_size < 1
114     page_size
115   end
116   
117   def self.list page = 1, page_size = self.default_page_size
118     opt = {}
119     opt.merge!(self.list_opt)
120     opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
121     opt.merge!({:order => 'updated_at desc'})
122     Story.find(:all, opt)
123   end
124   
125   def self.mylist au, page = 1, page_size = Author.default_story_page_size
126     opt = {}
127     opt.merge!(Story.list_opt)
128     opt.merge!({:limit => page_size, :offset => (page -1) * page_size}) if page_size > 0
129     opt.merge!({:conditions => ['stories.author_id = ?', au.id], :order => 'stories.updated_at desc'})
130     Story.find(:all, opt)
131   end
132   
133   def self.show sid, au
134     opt = {}
135     opt.merge!(Story.show_opt)
136     res = Story.find sid, opt
137     raise ActiveRecord::Forbidden unless res.visible?(au)
138     res
139   end
140   
141   def self.edit sid, au
142     opt = {}
143     opt.merge!(Story.show_opt)
144     res = Story.find sid, opt
145     raise ActiveRecord::Forbidden unless res.own?(au)
146     res
147   end
148   
149   def self.show_opt
150     {:include => {
151       :author => {}, 
152       :comic => {
153         :author => {}
154       }, 
155       :panel => {
156         :author => {}, 
157         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
158         :speech_balloons =>{:balloons => {}, :speeches => {}}
159       }
160     }}
161   end
162   
163   def elements
164     self.panel.elements
165   end
166   
167   def story_as_json au
168     panel_include = if self.panel and self.panel.visible?(au)
169       {:include => {:author => {}}, :methods => :elements}
170     else
171       {:include => {:author => {}}}
172     end
173     self.to_json({:include => {:comic => {:include => {:author => {}}}, :author => {}, :panel => panel_include}})
174   end
175   
176   def self.list_as_json_text ary, au
177     '[' + ary.map {|i| i.story_as_json(au) }.join(',') + ']'
178   end
179   
180   def self.licensed_pictures stories
181     r = {}
182     stories.each do |story|
183       r.merge! story.panel.licensed_pictures
184     end
185     r
186   end
187   
188   def self.new_t comic_id
189     r = Story.max_t(comic_id)
190     r.blank? ? 0 : r.to_i + 1
191   end
192   
193   def self.max_t comic_id
194     Story.maximum(:t, :conditions => ['comic_id = ?', comic_id])
195   end
196   
197   def self.find_t comic_id, t
198     Story.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
199   end
200   
201   def self.collect_t story
202     r = Story.find(:all, :conditions => ['comic_id = ?', story.comic_id], :order => 't')
203     r.map {|s| s.t}
204   end
205   
206   def self.serial? ary
207     i = 0
208     ary.compact.sort.each do |t|
209       break false unless t == i
210       i += 1
211     end
212     ary.compact.size == i
213   end
214   
215   def self.validate_t story
216     Story.serial?(Story.collect_t(story))
217   end
218   
219   def insert_shift
220     Story.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
221   end
222   
223   def lesser_shift old_t
224     self.t = 0 if self.t < 0
225     Story.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, self.t, old_t])
226   end
227   
228   def higher_shift old_t
229     nf = Story.find_t(self.comic_id, self.t)
230     max_t = Story.max_t(self.comic_id).to_i
231     self.t = max_t if self.t > max_t
232     Story.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, old_t, self.t])
233   end
234   
235   def update_shift old_t
236     if self.t > old_t
237       higher_shift old_t
238     else
239       lesser_shift old_t
240     end
241   end
242   
243   def rotate old_t = nil
244     if self.new_record?
245       if self.t.blank?
246         self.t = Story.new_t self.comic_id
247       else
248         self.insert_shift
249       end
250     else
251       if self.t.blank?
252       else
253         self.update_shift old_t
254       end
255     end
256   end
257   
258   def allow?
259     c = self.comic
260     pl = self.panel
261     c and c.own?(self.author) and pl and pl.usable?(self.author)
262   end
263   
264   def store old_t = nil
265     res = false
266     raise ActiveRecord::Forbidden unless self.allow?
267     Story.transaction do
268       self.rotate old_t
269       res = self.save
270       raise ActiveRecord::Rollback unless res
271       res = Story.validate_t(self) 
272       unless res
273         self.errors.add :t, 'unserialized'
274         raise ActiveRecord::Rollback 
275       end
276     end
277     res
278   end
279   
280   def destroy_and_shorten
281     Story.transaction do
282       Story.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t])
283       raise ActiveRecord::Rollback unless self.destroy
284     end
285   end
286   
287   
288 end