paperclip-storage-ftp 1.0.4 → 1.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/.travis.yml +0 -12
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/gemfiles/Gemfile.paperclip-2.x +2 -0
- data/gemfiles/Gemfile.paperclip-3.x +1 -1
- data/lib/paperclip/storage/ftp.rb +46 -17
- data/lib/paperclip/storage/ftp/server.rb +16 -27
- data/paperclip-storage-ftp.gemspec +1 -1
- data/spec/integration_spec.rb +32 -12
- data/spec/paperclip/storage/ftp/server_spec.rb +15 -23
- data/spec/paperclip/storage/ftp_spec.rb +58 -23
- data/spec/spec_helper.rb +3 -0
- data/spec/support/integration/ftp_server.rb +4 -2
- data/spec/support/integration/user.rb +9 -2
- data/vendor/apache-ftpserver/res/conf/users.properties +20 -19
- metadata +11 -14
    
        data/.gitignore
    CHANGED
    
    | @@ -4,6 +4,7 @@ | |
| 4 4 | 
             
            .config
         | 
| 5 5 | 
             
            .yardoc
         | 
| 6 6 | 
             
            Gemfile.lock
         | 
| 7 | 
            +
            gemfiles/Gemfile.*.lock
         | 
| 7 8 | 
             
            InstalledFiles
         | 
| 8 9 | 
             
            _yardoc
         | 
| 9 10 | 
             
            coverage
         | 
| @@ -21,5 +22,7 @@ tmp | |
| 21 22 | 
             
            .ruby-gemset
         | 
| 22 23 | 
             
            vendor/apache-ftpserver/res/ftpd.pid*
         | 
| 23 24 | 
             
            vendor/apache-ftpserver/res/home/*
         | 
| 25 | 
            +
            vendor/apache-ftpserver/res/user1/*
         | 
| 26 | 
            +
            vendor/apache-ftpserver/res/user2/*
         | 
| 24 27 | 
             
            vendor/apache-ftpserver/res/log/*
         | 
| 25 28 | 
             
            .jrubyrc
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -1,21 +1,9 @@ | |
| 1 1 | 
             
            language: ruby
         | 
| 2 2 | 
             
            rvm:
         | 
| 3 | 
            -
              - 1.8.7
         | 
| 4 | 
            -
              - 1.9.2
         | 
| 5 3 | 
             
              - 1.9.3
         | 
| 6 4 | 
             
              - 2.0.0
         | 
| 7 | 
            -
              - jruby-18mode
         | 
| 8 5 | 
             
              - jruby-19mode
         | 
| 9 | 
            -
              - rbx-18mode
         | 
| 10 6 | 
             
              - rbx-19mode
         | 
| 11 7 | 
             
            gemfile:
         | 
| 12 8 | 
             
              - gemfiles/Gemfile.paperclip-2.x
         | 
| 13 9 | 
             
              - gemfiles/Gemfile.paperclip-3.x
         | 
| 14 | 
            -
            matrix:
         | 
| 15 | 
            -
              exclude:
         | 
| 16 | 
            -
              - rvm: 1.8.7
         | 
| 17 | 
            -
                gemfile: gemfiles/Gemfile.paperclip-3.x
         | 
| 18 | 
            -
              - rvm: jruby-18mode
         | 
| 19 | 
            -
                gemfile: gemfiles/Gemfile.paperclip-3.x
         | 
| 20 | 
            -
              - rvm: rbx-18mode
         | 
| 21 | 
            -
                gemfile: gemfiles/Gemfile.paperclip-3.x
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -61,7 +61,7 @@ class User < ActiveRecord::Base | |
| 61 61 | 
             
                    :user     => "foo",
         | 
| 62 62 | 
             
                    :password => "bar",
         | 
| 63 63 | 
             
                    :port     => 2121, # optional, 21 by default
         | 
| 64 | 
            -
                    :passive  =>  | 
| 64 | 
            +
                    :passive  => false # optional, true by default
         | 
| 65 65 | 
             
                  }
         | 
| 66 66 | 
             
                ]
         | 
| 67 67 | 
             
            end
         | 
| @@ -82,7 +82,7 @@ end | |
| 82 82 |  | 
| 83 83 | 
             
            You can find out more about our work on our [dev blog](http://devblog.xing.com).
         | 
| 84 84 |  | 
| 85 | 
            -
            Copyright (c)  | 
| 85 | 
            +
            Copyright (c) 2013 [XING AG](http://www.xing.com)
         | 
| 86 86 |  | 
| 87 87 | 
             
            Released under the MIT license. For full details see [LICENSE](https://github.com/xing/paperclip-storage-ftp/blob/master/LICENSE)
         | 
| 88 88 | 
             
            included in this distribution.
         | 
| @@ -8,7 +8,10 @@ module Paperclip | |
| 8 8 | 
             
              module Storage
         | 
| 9 9 | 
             
                module Ftp
         | 
| 10 10 | 
             
                  def exists?(style_name = default_style)
         | 
| 11 | 
            -
                     | 
| 11 | 
            +
                    return false unless original_filename
         | 
| 12 | 
            +
                    with_primary_ftp_server do |server|
         | 
| 13 | 
            +
                      server.file_exists?(path(style_name))
         | 
| 14 | 
            +
                    end
         | 
| 12 15 | 
             
                  end
         | 
| 13 16 |  | 
| 14 17 | 
             
                  def to_file(style_name = default_style)
         | 
| @@ -20,20 +23,25 @@ module Paperclip | |
| 20 23 | 
             
                      extname  = File.extname(filename)
         | 
| 21 24 | 
             
                      basename = File.basename(filename, extname)
         | 
| 22 25 | 
             
                      file     = Tempfile.new([basename, extname])
         | 
| 23 | 
            -
                       | 
| 26 | 
            +
                      with_primary_ftp_server do |server|
         | 
| 27 | 
            +
                        server.get_file(filename, file.path)
         | 
| 28 | 
            +
                      end
         | 
| 24 29 | 
             
                      file.rewind
         | 
| 25 30 | 
             
                      file
         | 
| 26 31 | 
             
                    end
         | 
| 27 32 | 
             
                  end
         | 
| 28 33 |  | 
| 29 34 | 
             
                  def flush_writes
         | 
| 30 | 
            -
                     | 
| 31 | 
            -
                       | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 35 | 
            +
                    with_ftp_servers do |servers|
         | 
| 36 | 
            +
                      servers.map do |server|
         | 
| 37 | 
            +
                        Thread.new do
         | 
| 38 | 
            +
                          @queued_for_write.each do |style_name, file|
         | 
| 39 | 
            +
                            remote_path = path(style_name)
         | 
| 40 | 
            +
                            log("saving ftp://#{server.user}@#{server.host}:#{remote_path}")
         | 
| 41 | 
            +
                            server.put_file(file.path, remote_path)
         | 
| 42 | 
            +
                          end
         | 
| 43 | 
            +
                        end
         | 
| 44 | 
            +
                      end.each(&:join)
         | 
| 37 45 | 
             
                    end
         | 
| 38 46 |  | 
| 39 47 | 
             
                    after_flush_writes # allows attachment to clean up temp files
         | 
| @@ -42,26 +50,47 @@ module Paperclip | |
| 42 50 | 
             
                  end
         | 
| 43 51 |  | 
| 44 52 | 
             
                  def flush_deletes
         | 
| 45 | 
            -
                     | 
| 46 | 
            -
                       | 
| 47 | 
            -
                         | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 53 | 
            +
                    with_ftp_servers do |servers|
         | 
| 54 | 
            +
                      servers.map do |server|
         | 
| 55 | 
            +
                        Thread.new do
         | 
| 56 | 
            +
                          @queued_for_delete.each do |path|
         | 
| 57 | 
            +
                            log("deleting ftp://#{server.user}@#{server.host}:#{path}")
         | 
| 58 | 
            +
                            server.delete_file(path)
         | 
| 59 | 
            +
                          end
         | 
| 60 | 
            +
                        end
         | 
| 61 | 
            +
                      end.each(&:join)
         | 
| 50 62 | 
             
                    end
         | 
| 63 | 
            +
             | 
| 51 64 | 
             
                    @queued_for_delete = []
         | 
| 52 65 | 
             
                  end
         | 
| 53 66 |  | 
| 54 67 | 
             
                  def copy_to_local_file(style, destination_path)
         | 
| 55 | 
            -
                     | 
| 68 | 
            +
                    with_primary_ftp_server do |server|
         | 
| 69 | 
            +
                      server.get_file(path(style), destination_path)
         | 
| 70 | 
            +
                    end
         | 
| 56 71 | 
             
                  end
         | 
| 57 72 |  | 
| 58 | 
            -
                  def  | 
| 59 | 
            -
                     | 
| 73 | 
            +
                  def with_primary_ftp_server(&blk)
         | 
| 74 | 
            +
                    primary_ftp_server.establish_connection
         | 
| 75 | 
            +
                    yield primary_ftp_server
         | 
| 76 | 
            +
                  ensure
         | 
| 77 | 
            +
                    primary_ftp_server.close_connection
         | 
| 60 78 | 
             
                  end
         | 
| 61 79 |  | 
| 62 80 | 
             
                  def primary_ftp_server
         | 
| 63 81 | 
             
                    ftp_servers.first
         | 
| 64 82 | 
             
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  def with_ftp_servers(&blk)
         | 
| 85 | 
            +
                    ftp_servers.each(&:establish_connection)
         | 
| 86 | 
            +
                    yield ftp_servers
         | 
| 87 | 
            +
                  ensure
         | 
| 88 | 
            +
                    ftp_servers.each(&:close_connection)
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  def ftp_servers
         | 
| 92 | 
            +
                    @ftp_servers ||= @options[:ftp_servers].map{|config| Server.new(config) }
         | 
| 93 | 
            +
                  end
         | 
| 65 94 | 
             
                end
         | 
| 66 95 | 
             
              end
         | 
| 67 96 | 
             
            end
         | 
| @@ -6,19 +6,27 @@ module Paperclip | |
| 6 6 | 
             
                module Ftp
         | 
| 7 7 | 
             
                  class Server
         | 
| 8 8 |  | 
| 9 | 
            -
                     | 
| 10 | 
            -
             | 
| 11 | 
            -
                    def self.clear_connections
         | 
| 12 | 
            -
                      @@connections.clear
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                    attr_accessor :host, :user, :password, :passive
         | 
| 16 | 
            -
                    attr_writer   :port
         | 
| 9 | 
            +
                    attr_accessor :host, :user, :password, :port, :passive
         | 
| 10 | 
            +
                    attr_reader :connection
         | 
| 17 11 |  | 
| 18 12 | 
             
                    def initialize(options = {})
         | 
| 19 13 | 
             
                      options.each do |k,v|
         | 
| 20 14 | 
             
                        send("#{k}=", v)
         | 
| 21 15 | 
             
                      end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                      @port    = Net::FTP::FTP_PORT if @port.nil?
         | 
| 18 | 
            +
                      @passive = true if @passive.nil?
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    def establish_connection
         | 
| 22 | 
            +
                      @connection = Net::FTP.new
         | 
| 23 | 
            +
                      @connection.passive = passive
         | 
| 24 | 
            +
                      @connection.connect(host, port)
         | 
| 25 | 
            +
                      @connection.login(user, password)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    def close_connection
         | 
| 29 | 
            +
                      connection.close if connection && !connection.closed?
         | 
| 22 30 | 
             
                    end
         | 
| 23 31 |  | 
| 24 32 | 
             
                    def file_exists?(path)
         | 
| @@ -42,25 +50,6 @@ module Paperclip | |
| 42 50 | 
             
                      connection.delete(remote_file_path)
         | 
| 43 51 | 
             
                    end
         | 
| 44 52 |  | 
| 45 | 
            -
                    def connection
         | 
| 46 | 
            -
                      connection = @@connections["#{host}:#{port}"] ||= build_connection
         | 
| 47 | 
            -
                      connection.close
         | 
| 48 | 
            -
                      connection.connect(host, port)
         | 
| 49 | 
            -
                      connection.login(user, password)
         | 
| 50 | 
            -
                      connection
         | 
| 51 | 
            -
                    end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                    def build_connection
         | 
| 54 | 
            -
                      connection = Net::FTP.new
         | 
| 55 | 
            -
                      connection.passive = passive
         | 
| 56 | 
            -
                      connection.connect(host, port)
         | 
| 57 | 
            -
                      connection
         | 
| 58 | 
            -
                    end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    def port
         | 
| 61 | 
            -
                      @port || Net::FTP::FTP_PORT
         | 
| 62 | 
            -
                    end
         | 
| 63 | 
            -
             | 
| 64 53 | 
             
                    def mkdir_p(dirname)
         | 
| 65 54 | 
             
                      pathname = Pathname.new(dirname)
         | 
| 66 55 | 
             
                      pathname.descend do |p|
         | 
| @@ -11,7 +11,7 @@ Gem::Specification.new do |gem| | |
| 11 11 | 
             
              gem.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 12 12 | 
             
              gem.name          = "paperclip-storage-ftp"
         | 
| 13 13 | 
             
              gem.require_paths = ["lib"]
         | 
| 14 | 
            -
              gem.version       = "1.0. | 
| 14 | 
            +
              gem.version       = "1.1.0.rc1"
         | 
| 15 15 |  | 
| 16 16 | 
             
              gem.add_dependency("paperclip")
         | 
| 17 17 |  | 
    
        data/spec/integration_spec.rb
    CHANGED
    
    | @@ -1,37 +1,57 @@ | |
| 1 1 | 
             
            require "spec_helper"
         | 
| 2 2 |  | 
| 3 | 
            -
            describe " | 
| 4 | 
            -
             | 
| 3 | 
            +
            describe "paperclip-storage-ftp", :integration => true do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              before(:all) do
         | 
| 5 6 | 
             
                require "support/integration/ftp_server"
         | 
| 6 7 | 
             
                require "support/integration/user"
         | 
| 7 | 
            -
                FtpServer.clear
         | 
| 8 8 | 
             
                FtpServer.start
         | 
| 9 9 | 
             
              end
         | 
| 10 10 |  | 
| 11 | 
            +
              before(:each) do
         | 
| 12 | 
            +
                FtpServer.clear
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 11 15 | 
             
              let(:file) { File.new(File.expand_path("../support/integration/avatar.jpg", __FILE__), "rb") }
         | 
| 16 | 
            +
              let(:user) { User.new }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              let(:uploaded_file_server1)         { FtpServer::USER1_PATH + "/#{user.id}/original/avatar.jpg" }
         | 
| 19 | 
            +
              let(:uploaded_file_server1_medium)  { FtpServer::USER1_PATH + "/#{user.id}/medium/avatar.jpg"   }
         | 
| 20 | 
            +
              let(:uploaded_file_server1_thumb)   { FtpServer::USER1_PATH + "/#{user.id}/thumb/avatar.jpg"    }
         | 
| 21 | 
            +
              let(:uploaded_file_server2)         { FtpServer::USER2_PATH + "/#{user.id}/original/avatar.jpg" }
         | 
| 22 | 
            +
              let(:uploaded_file_server2_medium)  { FtpServer::USER2_PATH + "/#{user.id}/medium/avatar.jpg"   }
         | 
| 23 | 
            +
              let(:uploaded_file_server2_thumb)   { FtpServer::USER2_PATH + "/#{user.id}/thumb/avatar.jpg"    }
         | 
| 12 24 |  | 
| 13 25 | 
             
              it "stores the attachment on the ftp servers" do
         | 
| 14 | 
            -
                user = User.new
         | 
| 15 26 | 
             
                user.avatar = file
         | 
| 16 27 | 
             
                user.save!
         | 
| 17 | 
            -
                file.close
         | 
| 18 28 |  | 
| 19 | 
            -
                File.exists?( | 
| 29 | 
            +
                File.exists?(uploaded_file_server1).should be_true
         | 
| 30 | 
            +
                File.exists?(uploaded_file_server1_medium).should be_true
         | 
| 31 | 
            +
                File.exists?(uploaded_file_server1_thumb).should be_true
         | 
| 32 | 
            +
                File.exists?(uploaded_file_server2).should be_true
         | 
| 33 | 
            +
                File.exists?(uploaded_file_server2_medium).should be_true
         | 
| 34 | 
            +
                File.exists?(uploaded_file_server2_thumb).should be_true
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                file.size.should == File.size(uploaded_file_server1)
         | 
| 37 | 
            +
                file.size.should == File.size(uploaded_file_server2)
         | 
| 20 38 | 
             
              end
         | 
| 21 39 |  | 
| 22 40 | 
             
              it "deletes an attachment from the ftp servers" do
         | 
| 23 | 
            -
                user = User.new
         | 
| 24 41 | 
             
                user.avatar = file
         | 
| 25 42 | 
             
                user.save!
         | 
| 26 | 
            -
                file.close
         | 
| 27 43 |  | 
| 28 44 | 
             
                user.destroy
         | 
| 29 45 |  | 
| 30 | 
            -
                File.exists?( | 
| 46 | 
            +
                File.exists?(uploaded_file_server1).should be_false
         | 
| 47 | 
            +
                File.exists?(uploaded_file_server1_medium).should be_false
         | 
| 48 | 
            +
                File.exists?(uploaded_file_server1_thumb).should be_false
         | 
| 49 | 
            +
                File.exists?(uploaded_file_server2).should be_false
         | 
| 50 | 
            +
                File.exists?(uploaded_file_server2_medium).should be_false
         | 
| 51 | 
            +
                File.exists?(uploaded_file_server2_thumb).should be_false
         | 
| 31 52 | 
             
              end
         | 
| 32 53 |  | 
| 33 54 | 
             
              it "survives temporarily closed ftp connections" do
         | 
| 34 | 
            -
                user = User.new
         | 
| 35 55 | 
             
                user.avatar = file
         | 
| 36 56 | 
             
                user.save!
         | 
| 37 57 |  | 
| @@ -42,8 +62,8 @@ describe "Integration", :integration => true do | |
| 42 62 |  | 
| 43 63 | 
             
                user.avatar = file
         | 
| 44 64 | 
             
                user.save!
         | 
| 45 | 
            -
                file.close
         | 
| 46 65 |  | 
| 47 | 
            -
                File.exists?( | 
| 66 | 
            +
                File.exists?(uploaded_file_server1).should be_true
         | 
| 67 | 
            +
                File.exists?(uploaded_file_server2).should be_true
         | 
| 48 68 | 
             
              end
         | 
| 49 69 | 
             
            end
         | 
| @@ -1,10 +1,6 @@ | |
| 1 1 | 
             
            require "spec_helper"
         | 
| 2 2 |  | 
| 3 3 | 
             
            describe Paperclip::Storage::Ftp::Server do
         | 
| 4 | 
            -
              before(:each) do
         | 
| 5 | 
            -
                Paperclip::Storage::Ftp::Server.clear_connections
         | 
| 6 | 
            -
              end
         | 
| 7 | 
            -
             | 
| 8 4 | 
             
              let(:server) { Paperclip::Storage::Ftp::Server.new }
         | 
| 9 5 |  | 
| 10 6 | 
             
              context "initialize" do
         | 
| @@ -14,7 +10,7 @@ describe Paperclip::Storage::Ftp::Server do | |
| 14 10 | 
             
                    :user     => "user",
         | 
| 15 11 | 
             
                    :password => "password",
         | 
| 16 12 | 
             
                    :port     => 2121,
         | 
| 17 | 
            -
                    :passive  =>  | 
| 13 | 
            +
                    :passive  => false
         | 
| 18 14 | 
             
                  }
         | 
| 19 15 | 
             
                  server = Paperclip::Storage::Ftp::Server.new(options)
         | 
| 20 16 | 
             
                  server.host.should     == options[:host]
         | 
| @@ -28,6 +24,11 @@ describe Paperclip::Storage::Ftp::Server do | |
| 28 24 | 
             
                  server = Paperclip::Storage::Ftp::Server.new
         | 
| 29 25 | 
             
                  server.port.should == Net::FTP::FTP_PORT
         | 
| 30 26 | 
             
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                it "sets passive to true by default" do
         | 
| 29 | 
            +
                  server = Paperclip::Storage::Ftp::Server.new
         | 
| 30 | 
            +
                  server.passive.should be_true
         | 
| 31 | 
            +
                end
         | 
| 31 32 | 
             
              end
         | 
| 32 33 |  | 
| 33 34 | 
             
              context "#file_exists?" do
         | 
| @@ -90,24 +91,15 @@ describe Paperclip::Storage::Ftp::Server do | |
| 90 91 | 
             
                end
         | 
| 91 92 | 
             
              end
         | 
| 92 93 |  | 
| 93 | 
            -
              context "# | 
| 94 | 
            -
                it " | 
| 95 | 
            -
                   | 
| 96 | 
            -
                   | 
| 97 | 
            -
                   | 
| 98 | 
            -
                   | 
| 99 | 
            -
                   | 
| 100 | 
            -
                   | 
| 101 | 
            -
             | 
| 102 | 
            -
              end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
              context "#build_connection" do
         | 
| 105 | 
            -
                it "returns an ftp connection for the given server" do
         | 
| 106 | 
            -
                  connection = double("connection")
         | 
| 107 | 
            -
                  Net::FTP.should_receive(:new).and_return(connection)
         | 
| 108 | 
            -
                  connection.should_receive(:passive=).with(server.passive)
         | 
| 109 | 
            -
                  connection.should_receive(:connect).with(server.host, server.port)
         | 
| 110 | 
            -
                  server.build_connection.should == connection
         | 
| 94 | 
            +
              context "#establish_connection" do
         | 
| 95 | 
            +
                it "creates the ftp connection for the given server" do
         | 
| 96 | 
            +
                  ftp = double("ftp")
         | 
| 97 | 
            +
                  Net::FTP.should_receive(:new).and_return(ftp)
         | 
| 98 | 
            +
                  ftp.should_receive(:passive=).with(server.passive)
         | 
| 99 | 
            +
                  ftp.should_receive(:connect).with(server.host, server.port)
         | 
| 100 | 
            +
                  ftp.should_receive(:login).with(server.user, server.password)
         | 
| 101 | 
            +
                  server.establish_connection
         | 
| 102 | 
            +
                  server.connection.should == ftp
         | 
| 111 103 | 
             
                end
         | 
| 112 104 | 
             
              end
         | 
| 113 105 |  | 
| @@ -26,6 +26,9 @@ describe Paperclip::Storage::Ftp do | |
| 26 26 | 
             
                })
         | 
| 27 27 | 
             
              end
         | 
| 28 28 |  | 
| 29 | 
            +
              let(:first_server)  { Paperclip::Storage::Ftp::Server.new }
         | 
| 30 | 
            +
              let(:second_server) { Paperclip::Storage::Ftp::Server.new }
         | 
| 31 | 
            +
             | 
| 29 32 | 
             
              context "#exists?" do
         | 
| 30 33 | 
             
                it "returns false if original_filename not set" do
         | 
| 31 34 | 
             
                  attachment.stub(:original_filename).and_return(nil)
         | 
| @@ -33,12 +36,14 @@ describe Paperclip::Storage::Ftp do | |
| 33 36 | 
             
                end
         | 
| 34 37 |  | 
| 35 38 | 
             
                it "returns true if the file exists on the primary server" do
         | 
| 36 | 
            -
                   | 
| 39 | 
            +
                  first_server.should_receive(:file_exists?).with("/files/original/foo.jpg").and_return(true)
         | 
| 40 | 
            +
                  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
         | 
| 37 41 | 
             
                  attachment.exists?.should be_true
         | 
| 38 42 | 
             
                end
         | 
| 39 43 |  | 
| 40 44 | 
             
                it "accepts an optional style_name parameter to build the correct file path" do
         | 
| 41 | 
            -
                   | 
| 45 | 
            +
                  first_server.should_receive(:file_exists?).with("/files/thumb/foo.jpg").and_return(true)
         | 
| 46 | 
            +
                  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
         | 
| 42 47 | 
             
                  attachment.exists?(:thumb)
         | 
| 43 48 | 
             
                end
         | 
| 44 49 | 
             
              end
         | 
| @@ -49,7 +54,8 @@ describe Paperclip::Storage::Ftp do | |
| 49 54 | 
             
                  tempfile.should_receive(:path).and_return("/tmp/foo")
         | 
| 50 55 | 
             
                  tempfile.should_receive(:rewind).with(no_args)
         | 
| 51 56 | 
             
                  Tempfile.should_receive(:new).with(["foo", ".jpg"]).and_return(tempfile)
         | 
| 52 | 
            -
                   | 
| 57 | 
            +
                  first_server.should_receive(:get_file).with("/files/original/foo.jpg", "/tmp/foo").and_return(:foo)
         | 
| 58 | 
            +
                  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
         | 
| 53 59 | 
             
                  attachment.to_file.should == tempfile
         | 
| 54 60 | 
             
                end
         | 
| 55 61 |  | 
| @@ -58,7 +64,8 @@ describe Paperclip::Storage::Ftp do | |
| 58 64 | 
             
                  tempfile.should_receive(:path).and_return("/tmp/foo")
         | 
| 59 65 | 
             
                  tempfile.should_receive(:rewind).with(no_args)
         | 
| 60 66 | 
             
                  Tempfile.should_receive(:new).with(["foo", ".jpg"]).and_return(tempfile)
         | 
| 61 | 
            -
                   | 
| 67 | 
            +
                  first_server.should_receive(:get_file).with("/files/thumb/foo.jpg", anything)
         | 
| 68 | 
            +
                  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
         | 
| 62 69 | 
             
                  attachment.to_file(:thumb)
         | 
| 63 70 | 
             
                end
         | 
| 64 71 |  | 
| @@ -80,12 +87,13 @@ describe Paperclip::Storage::Ftp do | |
| 80 87 | 
             
                    :thumb    => thumb_file
         | 
| 81 88 | 
             
                  })
         | 
| 82 89 |  | 
| 83 | 
            -
                   | 
| 84 | 
            -
                   | 
| 85 | 
            -
                   | 
| 86 | 
            -
                   | 
| 87 | 
            -
             | 
| 88 | 
            -
                  attachment. | 
| 90 | 
            +
                  first_server.should_receive(:put_file).with("/tmp/original/foo.jpg", "/files/original/foo.jpg")
         | 
| 91 | 
            +
                  first_server.should_receive(:put_file).with("/tmp/thumb/foo.jpg", "/files/thumb/foo.jpg")
         | 
| 92 | 
            +
                  second_server.should_receive(:put_file).with("/tmp/original/foo.jpg", "/files/original/foo.jpg")
         | 
| 93 | 
            +
                  second_server.should_receive(:put_file).with("/tmp/thumb/foo.jpg", "/files/thumb/foo.jpg")
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  attachment.should_receive(:with_ftp_servers).and_yield([first_server, second_server])
         | 
| 96 | 
            +
             | 
| 89 97 | 
             
                  attachment.should_receive(:after_flush_writes).with(no_args)
         | 
| 90 98 |  | 
| 91 99 | 
             
                  attachment.flush_writes
         | 
| @@ -100,10 +108,13 @@ describe Paperclip::Storage::Ftp do | |
| 100 108 | 
             
                    "/files/original/foo.jpg",
         | 
| 101 109 | 
             
                    "/files/thumb/foo.jpg"
         | 
| 102 110 | 
             
                  ])
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                   | 
| 105 | 
            -
                   | 
| 106 | 
            -
                   | 
| 111 | 
            +
             | 
| 112 | 
            +
                  first_server.should_receive(:delete_file).with("/files/original/foo.jpg")
         | 
| 113 | 
            +
                  first_server.should_receive(:delete_file).with("/files/thumb/foo.jpg")
         | 
| 114 | 
            +
                  second_server.should_receive(:delete_file).with("/files/original/foo.jpg")
         | 
| 115 | 
            +
                  second_server.should_receive(:delete_file).with("/files/thumb/foo.jpg")
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  attachment.should_receive(:with_ftp_servers).and_yield([first_server, second_server])
         | 
| 107 118 |  | 
| 108 119 | 
             
                  attachment.flush_deletes
         | 
| 109 120 |  | 
| @@ -112,17 +123,47 @@ describe Paperclip::Storage::Ftp do | |
| 112 123 | 
             
              end
         | 
| 113 124 |  | 
| 114 125 | 
             
              context "#copy_to_local_file" do
         | 
| 126 | 
            +
                before do
         | 
| 127 | 
            +
                  attachment.should_receive(:with_primary_ftp_server).and_yield(first_server)
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 115 130 | 
             
                it "returns the file from the primary server and stores it in the path specified" do
         | 
| 116 | 
            -
                   | 
| 117 | 
            -
                  attachment.copy_to_local_file(:original, "/local/foo")
         | 
| 131 | 
            +
                  first_server.should_receive(:get_file).with("/files/original/foo.jpg", "/local/foo").and_return(:foo)
         | 
| 132 | 
            +
                  attachment.copy_to_local_file(:original, "/local/foo").should == :foo
         | 
| 118 133 | 
             
                end
         | 
| 119 134 |  | 
| 120 135 | 
             
                it "accepts the style parameter to build the correct path" do
         | 
| 121 | 
            -
                   | 
| 136 | 
            +
                  first_server.should_receive(:get_file).with("/files/thumb/foo.jpg", "/local/thumb/foo")
         | 
| 122 137 | 
             
                  attachment.copy_to_local_file(:thumb, "/local/thumb/foo")
         | 
| 123 138 | 
             
                end
         | 
| 124 139 | 
             
              end
         | 
| 125 140 |  | 
| 141 | 
            +
              context "#with_primary_ftp_server" do
         | 
| 142 | 
            +
                it "yields the connected primary ftp server, closes the connection afterwards" do
         | 
| 143 | 
            +
                  attachment.stub(:primary_ftp_server).and_return(first_server)
         | 
| 144 | 
            +
                  first_server.should_receive(:establish_connection).ordered
         | 
| 145 | 
            +
                  first_server.should_receive(:close_connection).ordered
         | 
| 146 | 
            +
                  expect { |b| attachment.with_primary_ftp_server(&b) }.to yield_with_args(first_server)
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
              end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
              context "#primary_ftp_server" do
         | 
| 151 | 
            +
                it "returns the first server in the list" do
         | 
| 152 | 
            +
                  attachment.primary_ftp_server.should equal(attachment.ftp_servers.first)
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
              end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
              context "#with_ftp_servers" do
         | 
| 157 | 
            +
                it "yields the connected ftp servers, closes the connections afterwards" do
         | 
| 158 | 
            +
                  attachment.stub(:ftp_servers).and_return([first_server, second_server])
         | 
| 159 | 
            +
                  first_server.should_receive(:establish_connection).ordered
         | 
| 160 | 
            +
                  second_server.should_receive(:establish_connection).ordered
         | 
| 161 | 
            +
                  first_server.should_receive(:close_connection).ordered
         | 
| 162 | 
            +
                  second_server.should_receive(:close_connection).ordered
         | 
| 163 | 
            +
                  expect { |b| attachment.with_ftp_servers(&b) }.to yield_with_args([first_server, second_server])
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
             | 
| 126 167 | 
             
              context "#ftp_servers" do
         | 
| 127 168 | 
             
                it "returns the configured ftp servers" do
         | 
| 128 169 | 
             
                  attachment.ftp_servers.first.host.should      == "ftp1.example.com"
         | 
| @@ -135,10 +176,4 @@ describe Paperclip::Storage::Ftp do | |
| 135 176 | 
             
                  attachment.ftp_servers.second.passive.should  == true
         | 
| 136 177 | 
             
                end
         | 
| 137 178 | 
             
              end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
              context "#primary_ftp_server" do
         | 
| 140 | 
            -
                it "returns the first server in the list" do
         | 
| 141 | 
            -
                  attachment.primary_ftp_server.should == attachment.ftp_servers.first
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
              end
         | 
| 144 179 | 
             
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
| @@ -3,7 +3,8 @@ require "daemon_controller" | |
| 3 3 | 
             
            class FtpServer
         | 
| 4 4 |  | 
| 5 5 | 
             
              INSTALL_PATH = File.expand_path("../../../../vendor/apache-ftpserver", __FILE__)
         | 
| 6 | 
            -
               | 
| 6 | 
            +
              USER1_PATH   = INSTALL_PATH + "/res/user1"
         | 
| 7 | 
            +
              USER2_PATH   = INSTALL_PATH + "/res/user2"
         | 
| 7 8 |  | 
| 8 9 | 
             
              def self.start
         | 
| 9 10 | 
             
                daemon_controller.start unless daemon_controller.running?
         | 
| @@ -14,7 +15,8 @@ class FtpServer | |
| 14 15 | 
             
              end
         | 
| 15 16 |  | 
| 16 17 | 
             
              def self.clear
         | 
| 17 | 
            -
                FileUtils.rm_r(Dir.glob( | 
| 18 | 
            +
                FileUtils.rm_r(Dir.glob(USER1_PATH + "/*"))
         | 
| 19 | 
            +
                FileUtils.rm_r(Dir.glob(USER2_PATH + "/*"))
         | 
| 18 20 | 
             
              end
         | 
| 19 21 |  | 
| 20 22 | 
             
              private
         | 
| @@ -19,12 +19,19 @@ class User < ActiveRecord::Base | |
| 19 19 |  | 
| 20 20 | 
             
              has_attached_file :avatar,
         | 
| 21 21 | 
             
                :storage  => :ftp,
         | 
| 22 | 
            +
                :styles   => { :medium => "50x50>", :thumb => "10x10>" },
         | 
| 22 23 | 
             
                :path     => "/:id/:style/:filename",
         | 
| 23 24 | 
             
                :ftp_servers => [
         | 
| 24 25 | 
             
                  {
         | 
| 25 26 | 
             
                    :host     => "127.0.0.1",
         | 
| 26 | 
            -
                    :user     => " | 
| 27 | 
            -
                    :password => " | 
| 27 | 
            +
                    :user     => "user1",
         | 
| 28 | 
            +
                    :password => "secret1",
         | 
| 29 | 
            +
                    :port     => 2121
         | 
| 30 | 
            +
                  },
         | 
| 31 | 
            +
                  {
         | 
| 32 | 
            +
                    :host     => "127.0.0.1",
         | 
| 33 | 
            +
                    :user     => "user2",
         | 
| 34 | 
            +
                    :password => "secret2",
         | 
| 28 35 | 
             
                    :port     => 2121
         | 
| 29 36 | 
             
                  }
         | 
| 30 37 | 
             
                ]
         | 
| @@ -15,23 +15,24 @@ | |
| 15 15 | 
             
            # specific language governing permissions and limitations
         | 
| 16 16 | 
             
            # under the License.
         | 
| 17 17 |  | 
| 18 | 
            -
            # Password is " | 
| 19 | 
            -
            ftpserver.user. | 
| 20 | 
            -
            ftpserver.user. | 
| 21 | 
            -
            ftpserver.user. | 
| 22 | 
            -
            ftpserver.user. | 
| 23 | 
            -
            ftpserver.user. | 
| 24 | 
            -
            ftpserver.user. | 
| 25 | 
            -
            ftpserver.user. | 
| 26 | 
            -
            ftpserver.user. | 
| 27 | 
            -
            ftpserver.user. | 
| 18 | 
            +
            # Password is "secret1"
         | 
| 19 | 
            +
            ftpserver.user.user1.userpassword=E52D98C459819A11775936D8DFBB7929
         | 
| 20 | 
            +
            ftpserver.user.user1.homedirectory=./res/user1
         | 
| 21 | 
            +
            ftpserver.user.user1.enableflag=true
         | 
| 22 | 
            +
            ftpserver.user.user1.writepermission=true
         | 
| 23 | 
            +
            ftpserver.user.user1.maxloginnumber=0
         | 
| 24 | 
            +
            ftpserver.user.user1.maxloginperip=0
         | 
| 25 | 
            +
            ftpserver.user.user1.idletime=0
         | 
| 26 | 
            +
            ftpserver.user.user1.uploadrate=0
         | 
| 27 | 
            +
            ftpserver.user.user1.downloadrate=0
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
            ftpserver.user. | 
| 31 | 
            -
            ftpserver.user. | 
| 32 | 
            -
            ftpserver.user. | 
| 33 | 
            -
            ftpserver.user. | 
| 34 | 
            -
            ftpserver.user. | 
| 35 | 
            -
            ftpserver.user. | 
| 36 | 
            -
            ftpserver.user. | 
| 37 | 
            -
            ftpserver.user. | 
| 29 | 
            +
            # Password is "secret2"
         | 
| 30 | 
            +
            ftpserver.user.user2.userpassword=E54CFB3714F76CEDD4B27889E1F6A174
         | 
| 31 | 
            +
            ftpserver.user.user2.homedirectory=./res/user2
         | 
| 32 | 
            +
            ftpserver.user.user2.enableflag=true
         | 
| 33 | 
            +
            ftpserver.user.user2.writepermission=true
         | 
| 34 | 
            +
            ftpserver.user.user2.maxloginnumber=0
         | 
| 35 | 
            +
            ftpserver.user.user2.maxloginperip=0
         | 
| 36 | 
            +
            ftpserver.user.user2.idletime=0
         | 
| 37 | 
            +
            ftpserver.user.user2.uploadrate=0
         | 
| 38 | 
            +
            ftpserver.user.user2.downloadrate=0
         | 
    
        metadata
    CHANGED
    
    | @@ -1,25 +1,25 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: paperclip-storage-ftp
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              prerelease: 
         | 
| 5 | 
            -
              version: 1.0. | 
| 4 | 
            +
              prerelease: 6
         | 
| 5 | 
            +
              version: 1.1.0.rc1
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| 8 8 | 
             
            - Sebastian Röbke
         | 
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013- | 
| 12 | 
            +
            date: 2013-07-02 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: paperclip
         | 
| 16 | 
            +
              type: :runtime
         | 
| 16 17 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 18 | 
             
                requirements:
         | 
| 18 19 | 
             
                - - ! '>='
         | 
| 19 20 | 
             
                  - !ruby/object:Gem::Version
         | 
| 20 21 | 
             
                    version: '0'
         | 
| 21 22 | 
             
                none: false
         | 
| 22 | 
            -
              type: :runtime
         | 
| 23 23 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 24 24 | 
             
                requirements:
         | 
| 25 25 | 
             
                - - ! '>='
         | 
| @@ -29,13 +29,13 @@ dependencies: | |
| 29 29 | 
             
              prerelease: false
         | 
| 30 30 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 31 | 
             
              name: rspec
         | 
| 32 | 
            +
              type: :development
         | 
| 32 33 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 34 | 
             
                requirements:
         | 
| 34 35 | 
             
                - - ! '>='
         | 
| 35 36 | 
             
                  - !ruby/object:Gem::Version
         | 
| 36 37 | 
             
                    version: '0'
         | 
| 37 38 | 
             
                none: false
         | 
| 38 | 
            -
              type: :development
         | 
| 39 39 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -45,13 +45,13 @@ dependencies: | |
| 45 45 | 
             
              prerelease: false
         | 
| 46 46 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 47 47 | 
             
              name: rake
         | 
| 48 | 
            +
              type: :development
         | 
| 48 49 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 50 | 
             
                requirements:
         | 
| 50 51 | 
             
                - - ! '>='
         | 
| 51 52 | 
             
                  - !ruby/object:Gem::Version
         | 
| 52 53 | 
             
                    version: '0'
         | 
| 53 54 | 
             
                none: false
         | 
| 54 | 
            -
              type: :development
         | 
| 55 55 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 56 56 | 
             
                requirements:
         | 
| 57 57 | 
             
                - - ! '>='
         | 
| @@ -61,13 +61,13 @@ dependencies: | |
| 61 61 | 
             
              prerelease: false
         | 
| 62 62 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 63 63 | 
             
              name: daemon_controller
         | 
| 64 | 
            +
              type: :development
         | 
| 64 65 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 65 66 | 
             
                requirements:
         | 
| 66 67 | 
             
                - - ! '>='
         | 
| 67 68 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 69 | 
             
                    version: 1.1.0
         | 
| 69 70 | 
             
                none: false
         | 
| 70 | 
            -
              type: :development
         | 
| 71 71 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 73 | 
             
                - - ! '>='
         | 
| @@ -77,13 +77,13 @@ dependencies: | |
| 77 77 | 
             
              prerelease: false
         | 
| 78 78 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 79 79 | 
             
              name: activerecord
         | 
| 80 | 
            +
              type: :development
         | 
| 80 81 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 81 82 | 
             
                requirements:
         | 
| 82 83 | 
             
                - - ! '>='
         | 
| 83 84 | 
             
                  - !ruby/object:Gem::Version
         | 
| 84 85 | 
             
                    version: '0'
         | 
| 85 86 | 
             
                none: false
         | 
| 86 | 
            -
              type: :development
         | 
| 87 87 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 88 88 | 
             
                requirements:
         | 
| 89 89 | 
             
                - - ! '>='
         | 
| @@ -158,17 +158,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 158 158 | 
             
                - !ruby/object:Gem::Version
         | 
| 159 159 | 
             
                  segments:
         | 
| 160 160 | 
             
                  - 0
         | 
| 161 | 
            -
                  hash: - | 
| 161 | 
            +
                  hash: -1768079343982146071
         | 
| 162 162 | 
             
                  version: '0'
         | 
| 163 163 | 
             
              none: false
         | 
| 164 164 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 165 165 | 
             
              requirements:
         | 
| 166 | 
            -
              - - ! ' | 
| 166 | 
            +
              - - ! '>'
         | 
| 167 167 | 
             
                - !ruby/object:Gem::Version
         | 
| 168 | 
            -
                   | 
| 169 | 
            -
                  - 0
         | 
| 170 | 
            -
                  hash: -3461514716041370557
         | 
| 171 | 
            -
                  version: '0'
         | 
| 168 | 
            +
                  version: 1.3.1
         | 
| 172 169 | 
             
              none: false
         | 
| 173 170 | 
             
            requirements: []
         | 
| 174 171 | 
             
            rubyforge_project: 
         |