From: yasushiito Date: Wed, 4 Apr 2012 23:56:29 +0000 (+0900) Subject: picture storerer updated X-Git-Url: http://git.osdn.net/view?p=pettanr%2Fpettanr.git;a=commitdiff_plain;h=6a9d02a32b5c300f00b3a69dd0ee7669cf8dac34 picture storerer updated --- diff --git a/app/controllers/original_pictures_controller.rb b/app/controllers/original_pictures_controller.rb index 437f5ffd..363e3d22 100644 --- a/app/controllers/original_pictures_controller.rb +++ b/app/controllers/original_pictures_controller.rb @@ -5,30 +5,12 @@ class OriginalPicturesController < ApplicationController private - def set_image(prm) - img = nil - if (f = prm[:original_picture][:file]).respond_to?(:read) - if f.size > 1000000 - @original_picture.width = 0 - @original_picture.height = 0 - @original_picture.ext = 'none' - @original_picture.filesize = 1.megabytes - else - img = Magick::Image.from_blob(f.read).shift - @original_picture.width = img.columns - @original_picture.height = img.rows - @original_picture.ext = img.format.downcase - @original_picture.filesize = f.size - end + def set_image(file) + if file.respond_to?(:read) + file.read else - dat = Base64.decode64(prm[:original_picture][:file].to_s.gsub(' ', '+')) #rubyのバグ?+でデコードされるべきキャラがスペースになる - img = Magick::Image.from_blob(dat).shift - @original_picture.width = img.columns - @original_picture.height = img.rows - @original_picture.ext = img.format.downcase - @original_picture.filesize = 1000 + Base64.decode64(file.to_s.gsub(' ', '+')) #rubyのバグ?+でデコードされるべきキャラがスペースになる end - img end def authenticate_artist @@ -132,25 +114,17 @@ class OriginalPicturesController < ApplicationController # POST /original_pictures # POST /original_pictures.json def create + @picture_data = set_image params[:original_picture][:file] @original_picture = OriginalPicture.new - img = set_image params - @original_picture.artist_id = @author.artist.id - @original_picture.license_id = @author.artist.default_license_id + @original_picture.supply_default @artist respond_to do |format| - OriginalPicture.transaction do - if @original_picture.save - if @original_picture.store(img) - format.html { redirect_to @original_picture, notice: 'Original picture was successfully created.' } - format.json { render json: @original_picture, status: :created, location: @original_picture } - else - format.html { redirect_to @original_picture, notice: 'Failed! Original picture was NOT created.' } - format.json { render json: @original_picture.errors, status: :unprocessable_entity } - end - else - format.html { render action: "new" } - format.json { render json: @original_picture.errors, status: :unprocessable_entity } - end + if @original_picture.store(@picture_data, @artist, params[:original_picture][:license_id]) + format.html { redirect_to @original_picture, notice: 'Original picture was successfully created.' } + format.json { render json: @original_picture, status: :created, location: @original_picture } + else + format.html { render action: "new" } + format.json { render json: @original_picture.errors, status: :unprocessable_entity } end end end @@ -158,23 +132,17 @@ class OriginalPicturesController < ApplicationController # PUT /original_pictures/1 # PUT /original_pictures/1.json def update + @picture_data = set_image params[:original_picture][:file] @original_picture = OriginalPicture.show(params[:id], @author) - img = set_image params + @original_picture.supply_default @artist respond_to do |format| - OriginalPicture.transaction do - if @original_picture.save - if @original_picture.store(img) - format.html { redirect_to @original_picture, notice: 'Original picture was successfully updated.' } - format.json { head :ok } - else - format.html { redirect_to @original_picture, notice: 'Failed! Original picture was NOT created.' } - format.json { render json: @original_picture.errors, status: :unprocessable_entity } - end - else - format.html { render action: "edit" } - format.json { render json: @original_picture.errors, status: :unprocessable_entity } - end + if @original_picture.store(@picture_data, @artist, params[:original_picture][:license_id]) + format.html { redirect_to @original_picture, notice: 'Original picture was successfully created.' } + format.json { render json: @original_picture, status: :created, location: @original_picture } + else + format.html { render action: "new" } + format.json { render json: @original_picture.errors, status: :unprocessable_entity } end end end diff --git a/app/models/original_picture.rb b/app/models/original_picture.rb index c0032f14..d178db20 100644 --- a/app/models/original_picture.rb +++ b/app/models/original_picture.rb @@ -87,13 +87,32 @@ class OriginalPicture < ActiveRecord::Base '/original_pictures/' + filename end - def store(rimg) - bindata = rimg.to_blob - PictureIO.original_picture_io.put bindata, self.filename - res = if self.resource_picture - self.resource_picture.store rimg - else - ResourcePicture.store(rimg, self) + def store(picture_data, art, lid = nil) + res = false + begin + mgk = Magick::Image.from_blob(picture_data).shift + rescue + self.errors.add :base, 'magick failed' + return false + end + self.attributes = {:ext => mgk.format.downcase, :width => mgk.columns, :height => mgk.rows, + :filesize => mgk.filesize, :artist_id => art.id, + :license_id => lid.blank? ? art.default_license_id : lid.to_i + } + OriginalPicture.transaction do + if res = self.save + if res = PictureIO.original_picture_io.put(picture_data, self.filename) + rp = ResourcePicture.update_picture(self) + unless rp.store(mgk) + PictureIO.original_picture_io.delete(self.filename) + self.errors.add :base, 'resource picture copying error' + raise ActiveRecord::Rollback + end + else + self.errors.add :base, 'original picture io does not work' + raise ActiveRecord::Rollback + end + end end res end diff --git a/app/models/resource_picture.rb b/app/models/resource_picture.rb index 06f65ca2..be16276b 100644 --- a/app/models/resource_picture.rb +++ b/app/models/resource_picture.rb @@ -69,43 +69,57 @@ class ResourcePicture < ActiveRecord::Base end def thumbnail(rimg) - tw, th = ResourcePicture.fix_size_both(80, 80, rimg.columns, rimg.rows) + tw, th = ResourcePicture.fix_size_both(64, 64, rimg.columns, rimg.rows) ResourcePicture.resize(rimg.to_blob, tw, th).to_blob end - def self.store(img, original_picture) - - resource_picture = ResourcePicture.new( - width: original_picture.width, height: original_picture.height, - ext: original_picture.ext, filesize: original_picture.filesize, - original_picture_id: original_picture.id, artist_id: original_picture.artist_id, - license_id: original_picture.license_id - ) - res = if resource_picture.save - if resource_picture.store(img) - true - else - false - end - else - false + def self.update_picture(op) + res = op.resource_picture || ResourcePicture.new + res.attributes = {:width => op.width, :height => op.height, :ext => op.ext, :filesize => op.filesize, + :original_picture_id => op.id, :artist_id => op.artist_id, :license_id => op.license_id + } + res + end + + def to_gif? + self.dext == 'png' and self.license.no_convert == 0 + end + + def self.png_to_gif(data) + begin + mgk = Magick::Image.from_blob(data).shift + mgk.format = 'gif' + mgk.to_blob + res = mgk + rescue + res = false end res end - def store(img) + def store(mgk) res = false - bindata = img.to_blob -# begin - PictureIO.resource_picture_io.put bindata, self.filename - PictureIO.resource_picture_io.class.subdirs.each do |d| - next if d.empty? - PictureIO.resource_picture_io.put(self.__send__(d, img), self.filename, d) + if res = self.save + if res = self.store_picture(mgk) + if self.to_gif? + if gifmgk = ResourcePicture.png_to_gif(mgk.to_blob) + res = self.store_picture(gifmgk) + else + res = false + end + end end - res = true -# rescue -# res = false -# end + end + res + end + + def store_picture(mgk) + res = false + PictureIO.resource_picture_io.class.subdirs.each do |d| + picdata = d.empty? ? mgk.to_blob : self.__send__(d, mgk) + res = PictureIO.resource_picture_io.put(picdata, self.filename, d) + break unless res + end res end diff --git a/lib/DMagick.rb b/lib/DMagick.rb index 27454683..49f5a058 100644 --- a/lib/DMagick.rb +++ b/lib/DMagick.rb @@ -28,6 +28,9 @@ module Magick 'png' end + def format=(e) + end + def flip self end @@ -36,6 +39,9 @@ module Magick self end + def filesize + 1024 + end end end diff --git a/lib/local_picture.rb b/lib/local_picture.rb index 74f020c0..85160dfe 100644 --- a/lib/local_picture.rb +++ b/lib/local_picture.rb @@ -33,26 +33,44 @@ class PictureIO end def exist?(filename, subdir = nil) - File.exist?(dir(subdir) + filename) + begin + File.exist?(dir(subdir) + filename) + rescue StandardError + false + end end def put(bindata, filename, subdir = nil) mkdir subdir - open(dir(subdir) + filename, 'wb') do |f| - f.write bindata + begin + open(dir(subdir) + filename, 'wb') do |f| + f.write bindata + end + true + rescue StandardError + false end end def get(filename, subdir = nil) bindata = '' - open(dir(subdir) + filename, 'rb') do |f| - bindata += f.read + begin + open(dir(subdir) + filename, 'rb') do |f| + bindata += f.read + end + bindata + rescue StandardError + false end - bindata end def delete(filename, subdir = nil) - File.delete(dir(subdir) + filename) + begin + File.delete(dir(subdir) + filename) + true + rescue StandardError + false + end end end diff --git a/lib/s3_picture.rb b/lib/s3_picture.rb index 57bfa6cb..c4c8a767 100644 --- a/lib/s3_picture.rb +++ b/lib/s3_picture.rb @@ -28,24 +28,43 @@ class PictureIO end def exist?(filename, subdir = nil) - AWS::S3::S3Object.exist?(dir(subdir) + filename) + begin + AWS::S3::S3Object.exist?(dir(subdir) + filename) + true + rescue S3Exception + false + end end def put(bindata, filename, subdir = nil) - AWS::S3::S3Object.store(dir(subdir) + filename, bindata, base) + begin + AWS::S3::S3Object.store(dir(subdir) + filename, bindata, base) + true + rescue S3Exception + false + end end def get(filename, subdir = nil) - bindata = '' - # if AWS::S3::S3Object.exists?(fn, 'pettanr') - AWS::S3::S3Object.stream(dir(subdir) + filename, base) do |st| - bindata += st if st + begin + bindata = '' + # if AWS::S3::S3Object.exists?(fn, 'pettanr') + AWS::S3::S3Object.stream(dir(subdir) + filename, base) do |st| + bindata += st if st + end + bindata + rescue S3Exception + false end - bindata end def delete(filename, subdir = nil) - AWS::S3::S3Object.delete(dir(subdir) + filename, base) + begin + AWS::S3::S3Object.delete(dir(subdir) + filename, base) +# true + rescue S3Exception + false + end end end diff --git a/spec/models/original_picture_spec.rb b/spec/models/original_picture_spec.rb index 2b896d61..3e8505b8 100644 --- a/spec/models/original_picture_spec.rb +++ b/spec/models/original_picture_spec.rb @@ -1,5 +1,277 @@ +# -*- encoding: utf-8 -*- require 'spec_helper' describe OriginalPicture do - pending "add some examples to (or delete) #{__FILE__}" + before do + Factory :admin + @user = Factory( :user_yas) + @author = @user.author + @artist = Factory :artist_yas, :author_id => @author.id + @other_user = Factory( :user_yas) + @other_author = @other_user.author + @other_artist = Factory :artist_yas, :author_id => @other_author.id + end + + describe '検証に於いて' do + before do + end + + it 'オーソドックスなデータなら通る' do + @op = Factory.build :original_picture, :artist_id => @artist.id + @op.should be_valid + end + + context 'extを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :ext => '' + @op.should_not be_valid + end + it '5文字以上なら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :ext => 'a'*5 + @op.should_not be_valid + end + end + context 'widthを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :width => nil + @op.should_not be_valid + end + it '数値でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :width => 'a' + @op.should_not be_valid + end + it '0なら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :width => '0' + @op.should_not be_valid + end + it '負でも失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :width => -1 + @op.should_not be_valid + end + it '正なら通る' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :width => 1 + @op.should be_valid + end + end + context 'heightを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :height => nil + @op.should_not be_valid + end + it '数値でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :height => 'a' + @op.should_not be_valid + end + it '0なら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :height => '0' + @op.should_not be_valid + end + it '負でも失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :height => -1 + @op.should_not be_valid + end + it '正なら通る' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :height => 1 + @op.should be_valid + end + end + context 'filesizeを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :filesize => nil + @op.should_not be_valid + end + it '数値でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :filesize => 'a' + @op.should_not be_valid + end + it '負なら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :filesize => '-1' + @op.should_not be_valid + end + it '2MB以上なら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :filesize => 2000000 + @op.should_not be_valid + end + end + context 'artist_idを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => nil + @op.should_not be_valid + end + it '数値でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => 'a' + @op.should_not be_valid + end + it '存在する絵師でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => 0 + @op.should_not be_valid + end + end + context 'license_idを検証するとき' do + it 'nullなら失敗する' do + @op = Factory.build :original_picture, :artist_id => @artist.id, :license_id => nil + @op.should_not be_valid + end + it '数値でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => 'a', :license_id => 'a' + @op.should_not be_valid + end + it '存在する絵師でなければ失敗する' do + @op = Factory.build :original_picture, :artist_id => 0, :license_id => 0 + @op.should_not be_valid + end + end + end + + describe 'データ補充に於いて' do + before do + end + + context '初期値を補充するとき' do + it '空なら0が補充される' do + @comic.supply_default + @comic.editable.should == 0 + @comic.visible.should == 0 + end + it 'editableが空でないなら変化なし' do + @comic.editable = 1 + lambda{@comic.supply_default}.should_not change(@comic, :editable) + end + it 'visibleが空でないなら変化なし' do + @comic.visible = 1 + lambda{@comic.supply_default}.should_not change(@comic, :visible) + end + end + end + + describe '作者判定に於いて' do + before do + end + it '自作の原画ならyes' do + op = Factory :original_picture, :artist_id => @artist.id + op.own?(@author).should == true + end + it '他人のならno' do + op = Factory :original_picture, :artist_id => @other_artist. id + op.own?(@author).should_not == true + end + it '作家が不明ならno' do + op = Factory :original_picture, :artist_id => @artist.id + op.own?(nil).should_not == true + end + it '作家が絵師でないならno' do + other_user = Factory( :user_yas) + op = Factory :original_picture, :artist_id => @artist.id + op.own?(other_user).should_not == true + end + end + describe '単体取得に於いて' do + before do + @op = Factory :original_picture, :artist_id => @artist.id + end + it '指定のコミックを返す' do + pic = OriginalPicture.show @op.id + pic.should eq @op + end + context '関連テーブルオプションがないとき' do + it 'ライセンスデータだけを含んでいる' do + r = OriginalPicture.show_include_opt + r.should eq [:license] + end + end + context '関連テーブルオプションで絵師を含ませたとき' do + it 'ライセンスデータと作者データを含んでいる' do + r = OriginalPicture.show_include_opt(:include => :artist) + r.should eq [:license, :artist] + end + end + end + describe '一覧取得に於いて' do + before do + @op = Factory :original_picture, :artist_id => @artist.id + end + context 'page補正について' do + it '文字列から数値に変換される' do + OriginalPicture.page('8').should eq 8 + end + it 'nilの場合は1になる' do + OriginalPicture.page().should eq 1 + end + it '0以下の場合は1になる' do + OriginalPicture.page('0').should eq 1 + end + end + context 'page_size補正について' do + it '文字列から数値に変換される' do + OriginalPicture.page_size('7').should eq 7 + end + it 'nilの場合はOriginalPicture.default_page_sizeになる' do + OriginalPicture.page_size().should eq OriginalPicture.default_page_size + end + it '0以下の場合はOriginalPicture.default_page_sizeになる' do + OriginalPicture.page_size('0').should eq OriginalPicture.default_page_size + end + it 'OriginalPicture.max_page_sizeを超えた場合はOriginalPicture.max_page_sizeになる' do + OriginalPicture.page_size('1000').should eq OriginalPicture.max_page_size + end + end + it 'リストを返す' do + pic = OriginalPicture.list + pic.should eq [@op] + end + it '他人の原画は含んでいない' do + Factory :original_picture, :artist_id => @other_artist.id + pic = OriginalPicture.list + pic.should eq [@op] + end + it '時系列で並んでいる' do + newpic = Factory :original_picture, :artist_id => @artist.id + pic = OriginalPicture.list + pic.should eq [newpic, @op] + end + context 'DBに5件あって1ページの件数を2件に変えたとして' do + before do + @op2 = Factory :original_picture, :artist_id => @artist.id + @op3 = Factory :original_picture, :artist_id => @artist.id + @op4 = Factory :original_picture, :artist_id => @artist.id + @op5 = Factory :original_picture, :artist_id => @artist.id + OriginalPicture.stub(:default_page_size).and_return(2) + end + it '通常は2件を返す' do + pic = OriginalPicture.list + pic.should have(2).items + end + it 'page=1なら末尾2件を返す' do + #時系列で並んでいる + pic = OriginalPicture.list({}, 1) + pic.should eq [@op5, @op4] + end + it 'page=2なら中間2件を返す' do + pic = OriginalPicture.list({}, 2) + pic.should eq [@op3, @op2] + end + it 'page=3なら先頭1件を返す' do + pic = OriginalPicture.list({}, 3) + pic.should eq [@op] + end + end + end + describe '画像データ変換に於いて' do + before do + @op = Factory :original_picture, :artist_id => @artist.id + end + context 'つつがなく終わるとき' do + it '画像データをオブジェクト化している' do + end + end + end + describe '新規作成に於いて' do + before do + @op = Factory :original_picture, :artist_id => @artist.id + end + context 'つつがなく終わるとき' do + it '画像データをオブジェクト化している' do + end + end + end end diff --git a/spec/models/source_picture_spec.rb b/spec/models/source_picture_spec.rb deleted file mode 100644 index e5022190..00000000 --- a/spec/models/source_picture_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'spec_helper' - -describe SourcePicture do - pending "add some examples to (or delete) #{__FILE__}" -end