OSDN Git Service

passed. resource picture model test
[pettanr/pettanr.git] / app / models / resource_picture.rb
1 class ResourcePicture < ActiveRecord::Base
2   belongs_to :artist
3   belongs_to :license
4   has_many :panel_pictures
5   belongs_to :original_picture
6   
7   validates :ext, :presence => true, :length => {:maximum => 4}, :inclusion => {:in => ['png', 'jpeg', 'gif']}\r
8   validates :width, :presence => true, :numericality => true, :natural_number => true
9   validates :height, :presence => true, :numericality => true, :natural_number => true
10   validates :filesize, :presence => true, :numericality => {:greater_than => 0, :less_than_or_equal_to => 2000000}, :natural_number => true
11   validates :artist_id, :presence => true, :numericality => true, :existence => true
12   validates :license_id, :presence => true, :numericality => true, :existence => true
13   validates :original_picture_id, :presence => true, :numericality => true, :existence => true
14   
15   before_destroy :destroy_with_file
16   
17   def destroy_with_file
18     PictureIO.resource_picture_io.delete self.filename
19     PictureIO.resource_picture_io.class.subdirs.each do |d|
20       next if d.empty?
21       PictureIO.resource_picture_io.delete(self.filename, d) if PictureIO.resource_picture_io.exist?(self.filename, d)
22     end
23   end
24   
25   def self.resize(data, dw, dh)
26     Magick::Image.from_blob(data).shift.resize(dw, dh)
27   end
28   
29   #サイズの調整(limw,limhに必ず収まるように合わせる)
30   def self.fix_size_both(limw, limh, w, h)
31     wr = if w > limw
32       limw*100/w
33     else
34       100
35     end
36     hr = if h > limh
37       limh*100/h
38     else
39       100
40     end
41     res = if wr < hr
42       #幅の方が圧縮率が高い
43       [w*wr/100, h*wr/100]
44     else
45       #高さの方が圧縮率が高い
46       [w*hr/100, h*hr/100]
47     end
48     res
49   end
50   
51   def dext
52     self.ext.downcase
53   end
54   
55   def filename
56     "#{self.id}.#{self.dext}"
57   end
58   
59   def mime_type
60     "image/#{self.dext}"
61   end
62   
63   def v(rimg)
64     rimg.flip.to_blob
65   end
66   
67   def h(rimg)
68     rimg.flop.to_blob
69   end
70   
71   def vh(rimg)
72     rimg.flip.flop.to_blob
73   end
74   
75   def url subdir = nil
76     '/resource_pictures/' + (subdir.to_s.empty? ? '' : subdir.to_s + '/' ) + filename
77   end
78   
79   def thumbnail(rimg)
80     tw, th = ResourcePicture.fix_size_both(64, 64, rimg.columns, rimg.rows)
81     ResourcePicture.resize(rimg.to_blob, tw, th).to_blob
82   end
83   
84   def self.update_picture(op)
85     res = op.resource_picture || ResourcePicture.new
86     res.attributes = {:width => op.width, :height => op.height, :ext => op.ext, :filesize => op.filesize, 
87       :original_picture_id => op.id, :artist_id => op.artist_id, :license_id => op.license_id
88     }
89     res
90   end
91   
92   def to_gif?
93     self.dext == 'png' and self.license.no_convert == 0
94   end
95   
96   def self.png_to_gif(data)
97     res = nil
98     begin
99       mgk = Magick::Image.from_blob(data).shift
100       mgk.format = 'gif'
101       res = mgk
102     rescue
103       res = false
104     end
105     res
106   end
107   
108   def store(mgk)
109     res = false
110     if res = self.save
111       if res = self.store_picture(mgk)
112         if self.to_gif?
113           if gifmgk = ResourcePicture.png_to_gif(mgk)
114             res = self.store_picture(gifmgk)
115           else
116             res = false
117           end
118         end
119       end
120     end
121     res
122   end
123   
124   def store_picture(mgk)
125     res = false
126     PictureIO.resource_picture_io.class.subdirs.each do |d|
127       picdata = d.empty? ? mgk.to_blob : self.__send__(d, mgk.to_blob)
128       res = PictureIO.resource_picture_io.put(picdata, self.filename, d)
129       break unless res
130     end
131     res
132   end
133   
134   def restore(subdir = nil)
135     PictureIO.resource_picture_io.get self.filename, subdir
136   end
137   
138 end