OSDN Git Service

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