OSDN Git Service

picture storerer updated
authoryasushiito <yasushiito@git.sourceforge.jp>
Wed, 4 Apr 2012 23:56:29 +0000 (08:56 +0900)
committeryasushiito <yasushiito@git.sourceforge.jp>
Wed, 4 Apr 2012 23:56:29 +0000 (08:56 +0900)
app/controllers/original_pictures_controller.rb
app/models/original_picture.rb
app/models/resource_picture.rb
lib/DMagick.rb
lib/local_picture.rb
lib/s3_picture.rb
spec/models/original_picture_spec.rb
spec/models/source_picture_spec.rb [deleted file]

index 437f5ff..363e3d2 100644 (file)
@@ -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
index c0032f1..d178db2 100644 (file)
@@ -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
index 06f65ca..be16276 100644 (file)
@@ -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
   
index 2745468..49f5a05 100644 (file)
@@ -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
index 74f020c..85160df 100644 (file)
@@ -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
index 57bfa6c..c4c8a76 100644 (file)
@@ -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
index 2b896d6..3e8505b 100644 (file)
@@ -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 (file)
index e502219..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-require 'spec_helper'
-
-describe SourcePicture do
-  pending "add some examples to (or delete) #{__FILE__}"
-end