OSDN Git Service

Merge branch 'v05' of git.sourceforge.jp:/gitroot/pettanr/pettanr into v05
[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     100
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     {:include => {: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.find(:all, opt)
133   end
134   
135   def self.show rid, roles
136     opt = {}
137     opt.merge!(self.show_opt)
138     r = ResourcePicture.find(rid, opt)
139     raise ActiveRecord::Forbidden unless r.visible?(roles)
140     r
141   end
142   
143   def self.show_opt
144     {:include => {:license => {}, :artist => {}, :picture => {}} }
145   end
146   
147   def self.show_json_opt
148     {:include => {:license => {}, :artist => {}, :picture => {}} }
149   end
150   
151   def self.edit rid, ar
152     opt = {}
153     opt.merge!(self.show_opt)
154     r = ResourcePicture.find(rid, opt)
155     raise ActiveRecord::Forbidden unless r.own?(ar)
156     r
157   end
158   
159   def new_picture imager
160     pc = Picture.new
161     pc.supply_default
162     pc.overwrite self
163     r = pc.store imager
164     return pc if r
165     self.errors.add :base, Picture.model_name.human + I18n.t('errors.not_create')
166     false
167   end
168   
169   def store imager
170     return false unless imager
171     res = false
172     self.overwrite self.original_picture
173     ResourcePicture.transaction do
174       self.original_picture.published_at = Time.now
175       self.original_picture.stopped_at = nil
176       raise ActiveRecord::Rollback unless self.original_picture.save
177       pc = self.new_picture imager
178       if pc
179         self.picture_id = pc.id
180         if res = self.save
181           res = self.store_picture_with_gif(imager)
182         end
183       else
184       end
185       raise ActiveRecord::Rollback unless res
186     end
187     res
188   end
189   
190   def store_picture_with_gif(imager)
191     if res = self.store_picture(imager, self.filename)
192       if self.to_gif?
193         if gifimager = imager.to_gif
194           if res = self.store_picture(gifimager, self.gifname)
195           else
196             self.errors.add :base, I18n.t('picture_io.error')
197           end
198         else
199           self.errors.add :base, I18n.t('errors.not_convert')
200           res = false
201         end
202       end
203     else
204       self.errors.add :base, I18n.t('picture_io.error')
205     end
206     res
207   end
208   
209   def store_picture(imager, fn)
210     res = false
211     thumbnail_imager = self.flag_thumbnail >= 0 ? imager.to_thumbnail : imager
212     return false unless thumbnail_imager
213     begin
214       PictureIO.resource_picture_io.put(thumbnail_imager.binary, fn)
215       PictureIO.resource_picture_io.put(imager.binary, fn, 'full')
216       res = true
217     rescue PictureIO::Error
218       res = false
219     end
220     res
221   end
222   
223   def restore(subdir = nil)
224     PictureIO.resource_picture_io.get self.filename, subdir
225   end
226   
227   def unpublish
228     res = false
229     ResourcePicture.transaction do
230       self.original_picture.published_at = nil
231       self.original_picture.stopped_at = Time.now
232       raise ActiveRecord::Rollback unless self.original_picture.save
233       begin
234         PictureIO.resource_picture_io.delete(self.filename) if PictureIO.resource_picture_io.exist?(self.filename)
235         PictureIO.resource_picture_io.delete(self.filename, 'full') if PictureIO.resource_picture_io.exist?(self.filename, 'full')
236       rescue PictureIO::Error
237         res = false
238         raise ActiveRecord::Rollback
239       end
240       res = self.destroy
241       raise ActiveRecord::Rollback unless res
242     end
243     res
244   end
245   
246   def self.visible_count
247     ResourcePicture.count
248   end
249   
250   def picture_data
251     Base64.encode64(self.restore 'full')
252   end
253   
254   def credit_template
255     "#{self.classname.tableize}/attributes/credit"
256   end
257   
258   def full_credit_template
259     "#{self.classname.tableize}/attributes/full_credit"
260   end
261   
262   def credit_data
263     begin
264       @credit_data = JSON.parse(self.credit) unless @credit_data
265     rescue 
266     end
267     @credit_data
268   end
269   
270   def flags
271     begin
272       @flags = JSON.parse(self.settings) unless @flags
273     rescue 
274     end
275     @flags
276   end
277   
278   def flags=(s)
279     @flags = s
280   end
281   
282   def flag_open
283     @flag_open = flags["open"] unless @flag_open
284     @flag_open
285   end
286   
287   def flag_commercial
288     @flag_commercial = flags["commercial"] unless @flag_commercial
289     @flag_commercial
290   end
291   
292   def flag_official
293     @flag_official = flags["official"] unless @flag_official
294     @flag_official
295   end
296   
297   def flag_attribution
298     @flag_attribution = flags["attribution"] unless @flag_attribution
299     @flag_attribution
300   end
301   
302   def flag_derive
303     @flag_derive = flags["derive"] unless @flag_derive
304     @flag_derive
305   end
306   
307   def flag_thumbnail
308     @flag_thumbnail = flags["thumbnail"] unless @flag_thumbnail
309     @flag_thumbnail
310   end
311   
312   def flag_gif_convert
313     @flag_gif_convert = flags["gif_convert"] unless @flag_gif_convert
314     @flag_gif_convert
315   end
316   
317   def flag_reverse
318     @flag_reverse = flags["reverse"] unless @flag_reverse
319     @flag_reverse
320   end
321   
322   def flag_resize
323     @flag_resize = flags["resize"] unless @flag_resize
324     @flag_resize
325   end
326   
327   def flag_sync_vh
328     @flag_sync_vh = flags["sync_vh"] unless @flag_sync_vh
329     @flag_sync_vh
330   end
331   
332   def flag_overlap
333     @flag_overlap = flags["overlap"] unless @flag_overlap
334     @flag_overlap
335   end
336   
337 end