OSDN Git Service

92da32ba3e6ccca28d5c00cd91c0ab5a10494507
[pettanr/pettanr.git] / app / models / resource_picture.rb
1 #素材
2 class ResourcePicture < Pettanr::Item
3   belongs_to :artist
4   belongs_to :license
5   belongs_to :picture
6   belongs_to :original_picture
7   
8   validates :ext, :presence => true, :length => {:maximum => 4}, :inclusion => {:in => ['png', 'jpeg', 'gif']}
9   validates :width, :presence => true, :numericality => true, :natural_number => true
10   validates :height, :presence => true, :numericality => true, :natural_number => true
11   validates :filesize, :presence => true, :numericality => {:greater_than => 0, :less_than_or_equal_to => 2000000}, :natural_number => true
12   validates :md5, :presence => true, :length => {:minimum => 32, :maximum => 32}
13   validates :artist_id, :presence => true, :numericality => true, :existence => {:both => false}
14   validates :license_id, :presence => true, :numericality => true, :existence => {:both => false}
15   validates :original_picture_id, :presence => true, :numericality => true, :existence => {:both => false}
16   validates :artist_name, :presence => true
17   validates :classname, :presence => true, :length => {:maximum => 50}
18   validates :picture_id, :presence => true, :numericality => true, :existence => {:both => false}
19   
20   def self.singular
21     'ResourcePicture'
22   end
23   
24   def self.plural
25     'ResourcePictures'
26   end
27   
28   def self.owner_type
29     :author
30   end
31   
32   def self.valid_encode_columns
33     super.merge ['artist_name', 'classname', 'credit', 'settings']
34   end
35   
36   def supply_default
37   end
38   
39   def overwrite op
40     attr = {:width => op.width, :height => op.height, :ext => op.ext, :filesize => op.filesize, 
41       :original_picture_id => op.id, :artist_id => op.artist_id, :md5 => op.md5
42     }
43     self.attributes = attr
44   end
45   
46   def own? roles
47     roles = [roles] unless roles.respond_to?(:each)
48     ar = ResourcePicture.get_artist_from_roles roles
49     return false unless ar
50     self.artist_id == ar.id
51   end
52   
53   def visible? roles
54     if MagicNumber['run_mode'] == 0
55       return false unless guest_role_check(roles)
56     else
57       return false unless resource_reader_role_check(roles)
58     end
59     true
60   end
61   
62   def filename
63     "#{self.id}.#{self.ext}"
64   end
65   
66   def gifname
67     "#{self.id}.gif"
68   end
69   
70   def mime_type
71     "image/#{self.ext}"
72   end
73   
74   def url subdir = nil
75     '/resource_pictures/' + (subdir.to_s.empty? ? '' : subdir.to_s + '/' ) + filename
76   end
77   
78   def to_gif?
79     self.ext == 'png' and self.flag_gif_convert >= 0
80   end
81   
82   def thumbnail(imager)
83     tw, th = ResourcePicture.fix_size_both(MagicNumber['thumbnail_width'], MagicNumber['thumbnail_height'], rimg.columns, rimg.rows)
84     ResourcePicture.resize(rimg.to_blob, tw, th).to_blob
85   end
86   
87   def tmb_opt_img_tag
88     tw, th = PettanImager.thumbnail_size(self.width, self.height)
89     {:src => self.url, :width => tw, :height => th}
90   end
91   
92   def opt_img_tag
93     {:src => self.url('full'), :width => self.width, :height => self.height}
94   end
95   
96   def symbol_option
97     self.tmb_opt_img_tag
98   end
99   
100   def self.default_page_size
101     25
102   end
103   
104   def self.max_page_size
105     100
106   end
107   
108   def self.page prm = nil
109     page = prm.to_i
110     page = 1 if page < 1
111     page
112   end
113   
114   def self.page_size prm = self.default_page_size
115     page_size = prm.to_i
116     page_size = self.max_page_size if page_size > self.max_page_size
117     page_size = self.default_page_size if page_size < 1
118     page_size
119   end
120   
121   def self.mylist_where ar
122     ['resource_pictures.artist_id = ?', ar.id]
123   end
124   
125   def self.himlist_where ar
126     ['resource_pictures.artist_id = ?', ar.id]
127   end
128   
129   def self.list page = 1, page_size = self.default_page_size
130     ResourcePicture.includes(ResourcePicture.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
131   end
132   
133   def self.mylist ar, page = 1, page_size = Author.default_resource_picture_page_size
134     ResourcePicture.where(self.mylist_where(ar)).includes(ResourcePicture.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
135   end
136   
137   def self.himlist ar, page = 1, page_size = Author.default_resource_picture_page_size
138     ResourcePicture.where(self.himlist_where(ar)).includes(ResourcePicture.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
139   end
140   
141   def self.list_paginate page = 1, page_size = self.default_page_size
142     Kaminari.paginate_array(Array.new(ResourcePicture.count, nil)).page(page).per(page_size)
143   end
144   
145   def self.mylist_paginate ar, page = 1, page_size = Author.default_resource_picture_page_size
146     Kaminari.paginate_array(Array.new(ResourcePicture.where(self.mylist_where(ar)).count, nil)).page(page).per(page_size)
147   end
148   
149   def self.himlist_paginate ar, page = 1, page_size = Author.default_resource_picture_page_size
150     Kaminari.paginate_array(Array.new(ResourcePicture.where(self.himlist_where(ar)).count, nil)).page(page).per(page_size)
151   end
152   
153   def self.list_by_original_picture_where original_picture_id
154     ['resource_pictures.original_picture_id = ?', original_picture_id]
155   end
156   
157   def self.list_by_original_picture original_picture_id, roles, page = 1, page_size = self.default_page_size
158     self.where(self.list_by_original_picture_where(original_picture_id)).includes(self.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
159   end
160   
161   def self.list_by_license_where license_id
162     ['resource_pictures.license_id = ?', license_id]
163   end
164   
165   def self.list_by_license license_id, roles, page = 1, page_size = self.default_page_size
166     self.where(self.list_by_license_where(license_id)).includes(self.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
167   end
168   
169   def self.list_by_artist_where artist_id
170     ['resource_pictures.artist_id = ?', artist_id]
171   end
172   
173   def self.list_by_artist artist_id, roles, page = 1, page_size = self.default_page_size
174     self.where(self.list_by_artist_where(artist_id)).includes(self.list_opt).order('resource_pictures.updated_at desc').offset((page -1) * page_size).limit(page_size)
175   end
176   
177   def self.list_opt
178     {:license => {}, :artist => {}, :picture => {} }
179   end
180   
181   def self.list_json_opt
182     {:include => {:license => {}, :artist => {}, :picture => {}} }
183   end
184   
185   def self.show rid, roles
186     opt = {}
187     opt.merge!(self.show_opt)
188     r = ResourcePicture.find(rid, opt)
189     raise ActiveRecord::Forbidden unless r.visible?(roles)
190     r
191   end
192   
193   def self.show_opt
194     {:include => {:license => {}, :artist => {}, :picture => {}} }
195   end
196   
197   def self.show_json_opt
198     {:include => {:license => {}, :artist => {}, :picture => {}} }
199   end
200   
201   def self.edit rid, ar
202     opt = {}
203     opt.merge!(self.show_opt)
204     r = ResourcePicture.find(rid, opt)
205     raise ActiveRecord::Forbidden unless r.own?(ar)
206     r
207   end
208   
209   def new_picture imager
210     pc = Picture.new
211     pc.supply_default
212     pc.overwrite self
213     r = pc.store imager
214     return pc if r
215     self.errors.add :base, Picture.model_name.human + I18n.t('errors.not_create')
216     false
217   end
218   
219   def store imager
220     return false unless imager
221     res = false
222     self.overwrite self.original_picture
223     ResourcePicture.transaction do
224       self.original_picture.published_at = Time.now
225       self.original_picture.stopped_at = nil
226       raise ActiveRecord::Rollback unless self.original_picture.save
227       pc = self.new_picture imager
228       if pc
229         self.picture_id = pc.id
230         if res = self.save
231           res = self.store_picture_with_gif(imager)
232         end
233       else
234       end
235       raise ActiveRecord::Rollback unless res
236     end
237     res
238   end
239   
240   def store_picture_with_gif(imager)
241     if res = self.store_picture(imager, self.filename)
242       if self.to_gif?
243         if gifimager = imager.to_gif
244           if res = self.store_picture(gifimager, self.gifname)
245           else
246             self.errors.add :base, I18n.t('picture_io.error')
247           end
248         else
249           self.errors.add :base, I18n.t('errors.not_convert')
250           res = false
251         end
252       end
253     else
254       self.errors.add :base, I18n.t('picture_io.error')
255     end
256     res
257   end
258   
259   def store_picture(imager, fn)
260     res = false
261     thumbnail_imager = self.flag_thumbnail >= 0 ? imager.to_thumbnail : imager
262     return false unless thumbnail_imager
263     begin
264       PictureIO.resource_picture_io.put(thumbnail_imager.binary, fn)
265       PictureIO.resource_picture_io.put(imager.binary, fn, 'full')
266       res = true
267     rescue PictureIO::Error
268       res = false
269     end
270     res
271   end
272   
273   def restore(subdir = nil)
274     PictureIO.resource_picture_io.get self.filename, subdir
275   end
276   
277   def unpublish
278     res = false
279     ResourcePicture.transaction do
280       self.original_picture.published_at = nil
281       self.original_picture.stopped_at = Time.now
282       raise ActiveRecord::Rollback unless self.original_picture.save
283       begin
284         PictureIO.resource_picture_io.delete(self.filename) if PictureIO.resource_picture_io.exist?(self.filename)
285         PictureIO.resource_picture_io.delete(self.filename, 'full') if PictureIO.resource_picture_io.exist?(self.filename, 'full')
286       rescue PictureIO::Error
287         res = false
288         raise ActiveRecord::Rollback
289       end
290       res = self.destroy
291       raise ActiveRecord::Rollback unless res
292     end
293     res
294   end
295   
296   def self.visible_count
297     ResourcePicture.count
298   end
299   
300   def picture_data
301     Base64.encode64(self.restore 'full')
302   end
303   
304   def credit_template
305     "#{self.classname.tableize}/attributes/credit"
306   end
307   
308   def full_credit_template
309     "#{self.classname.tableize}/attributes/full_credit"
310   end
311   
312   def credit_data
313     begin
314       @credit_data = JSON.parse(self.credit) unless @credit_data
315     rescue 
316     end
317     @credit_data
318   end
319   
320   def flags
321     begin
322       @flags = JSON.parse(self.settings) unless @flags
323     rescue 
324     end
325     @flags
326   end
327   
328   def flags=(s)
329     @flags = s
330   end
331   
332   def flag_open
333     @flag_open = flags["open"] unless @flag_open
334     @flag_open
335   end
336   
337   def flag_commercial
338     @flag_commercial = flags["commercial"] unless @flag_commercial
339     @flag_commercial
340   end
341   
342   def flag_official
343     @flag_official = flags["official"] unless @flag_official
344     @flag_official
345   end
346   
347   def flag_attribution
348     @flag_attribution = flags["attribution"] unless @flag_attribution
349     @flag_attribution
350   end
351   
352   def flag_derive
353     @flag_derive = flags["derive"] unless @flag_derive
354     @flag_derive
355   end
356   
357   def flag_thumbnail
358     @flag_thumbnail = flags["thumbnail"] unless @flag_thumbnail
359     @flag_thumbnail
360   end
361   
362   def flag_gif_convert
363     @flag_gif_convert = flags["gif_convert"] unless @flag_gif_convert
364     @flag_gif_convert
365   end
366   
367   def flag_reverse
368     @flag_reverse = flags["reverse"] unless @flag_reverse
369     @flag_reverse
370   end
371   
372   def flag_resize
373     @flag_resize = flags["resize"] unless @flag_resize
374     @flag_resize
375   end
376   
377   def flag_sync_vh
378     @flag_sync_vh = flags["sync_vh"] unless @flag_sync_vh
379     @flag_sync_vh
380   end
381   
382   def flag_overlap
383     @flag_overlap = flags["overlap"] unless @flag_overlap
384     @flag_overlap
385   end
386   
387 end