OSDN Git Service

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