OSDN Git Service

pass test: Picture.store
[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 url subdir = nil
64     '/resource_pictures/' + (subdir.to_s.empty? ? '' : subdir.to_s + '/' ) + filename
65   end
66   
67   def thumbnail(rimg)
68     tw, th = ResourcePicture.fix_size_both(64, 64, rimg.columns, rimg.rows)
69     ResourcePicture.resize(rimg.to_blob, tw, th).to_blob
70   end
71   
72   def self.update_picture(op)
73     res = op.resource_picture || ResourcePicture.new
74     res.attributes = {:width => op.width, :height => op.height, :ext => op.ext, :filesize => op.filesize, 
75       :original_picture_id => op.id, :artist_id => op.artist_id, :license_id => op.license_id
76     }
77     res
78   end
79   
80   def to_gif?
81     self.dext == 'png' and self.license.no_convert == 0
82   end
83   
84   def self.png_to_gif(data)
85     res = nil
86     begin
87       mgk = Magick::Image.from_blob(data).shift
88       mgk.format = 'gif'
89       res = mgk
90     rescue
91       res = false
92     end
93     res
94   end
95   
96   def store(mgk)
97     res = false
98     if res = self.save
99       if res = self.store_picture(mgk)
100         if self.to_gif?
101           if gifmgk = ResourcePicture.png_to_gif(mgk.to_blob)
102             res = self.store_picture(gifmgk)
103           else
104             res = false
105           end
106         end
107       end
108     end
109     res
110   end
111   
112   def store_picture(mgk)
113     res = false
114     PictureIO.resource_picture_io.class.subdirs.each do |d|
115       picdata = d.empty? ? mgk.to_blob : self.__send__(d, mgk)
116       res = PictureIO.resource_picture_io.put(picdata, "#{self.id}.#{mgk.format}", d)
117       break unless res
118     end
119     res
120   end
121   
122   def restore(subdir = nil)
123     PictureIO.resource_picture_io.get self.filename, subdir
124   end
125   
126   def self.default_page_size
127     25
128   end
129   
130   def self.max_page_size
131     100
132   end
133   
134   def self.page prm = nil
135     page = prm.to_i
136     page = 1 if page < 1
137     page
138   end
139   
140   def self.page_size prm = self.default_page_size
141     page_size = prm.to_i
142     page_size = self.max_page_size if page_size > self.max_page_size
143     page_size = self.default_page_size if page_size < 1
144     page_size
145   end
146   
147   def self.offset cnt, prm = nil
148     offset = prm.to_i
149     offset = cnt - 1 if offset >= cnt
150     offset = cnt - offset.abs if offset < 0
151     offset = 0 if offset < 0
152     offset
153   end
154   
155   def self.list opt = {}, page = 1, page_size = self.default_page_size
156     opt.merge!(self.list_opt) unless opt[:include]
157     opt.merge!({:order => 'updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
158     ResourcePicture.find(:all, opt)
159   end
160   
161   def self.list_opt
162     {:include => [:license, :artist]}
163   end
164   
165   def self.list_json_opt
166     {:include => [:license, :artist]}
167   end
168   
169   def self.show rid, opt = {}
170     r = ResourcePicture.find(rid, :include => self.show_include_opt(opt))
171 #    raise ActiveRecord::Forbidden unless c.visible?(au)
172     r
173   end
174   
175   def self.show_include_opt opt = {}
176     res = [:license, :artist]
177     res.push(opt[:include]) if opt[:include]
178     res
179   end
180   
181   def self.show_json_include_opt
182     {:include => [:license, :artist]}
183   end
184   
185   def self.visible_count
186     ResourcePicture.count
187   end
188   
189 end