Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #2 from bramswenson/master

FTP support
  • Loading branch information...
commit f2899695b1a8ed265e6d024f3ac545c6bc4f68d5 2 parents 0d0a009 + 6867626
@knewter knewter authored
View
55 README
@@ -1,55 +0,0 @@
-== FileTransferMixin ==
-FileTransferMixin is a module that you can include in a library. It will support various mechanisms long-term, but
-for now is focused on SFTP servers.
-
-It provides the following methods for now:
-
-- sftp_send(key, remote_location, local_file_path)
-- sftp_fetch(key, remote_path, local_path)
-- sftp_move(key, original_remote_path, new_remote_path)
-- sftp_block(key)
-
-- It expects an ENV variable named FILE_TRANSFER_MIXIN_CONFIG_PATH to be set.
-- It expects a yml configuration file in FILE_TRANSFER_MIXIN_CONFIG_PATH that looks like the following:
-
-:development:
- :sftp:
- :some_key:
- :server: 127.0.0.1
- :username: user
- :password: pass
-:test: {}
-
-:production: {}
-
-Then in a class, you would deal with it thusly:
-
-class SomeClass
- include FileTransferMixin
-
- # Some method that uploads a file
- def some_method
- sftp_send(:some_key, remote_path, local_path)
- end
-
- # Some method that fetches a file
- def fetch_method
- sftp_fetch(:some_key, remote_path, local_path)
- end
-
- # Some method that moves a file
- def move_method
- sftp_move(:some_key, original_remote_path, new_remote_path)
- end
-
- # Some method that otherwise uses Net::SFTP commands but still uses our config block
- def sftp_detailed_method
- sftp_block(:some_key) do |ftp|
- ftp.rename!('foo', 'bar')
- end
- end
-end
-
-== Motivation ==
-We have quite a few libraries that interact with remote SFTP servers, and inevitably they share massive swathes of code
-that should be unnecessary. This intends to be a mixin to make the easy things extremely easy.
View
88 README.md
@@ -0,0 +1,88 @@
+# FileTransferMixin #
+FileTransferMixin is a module that you can include in a library. It will support various mechanisms long-term, but
+for now is focused on SFTP and FTP servers.
+
+It provides the following methods for now:
+
+- sftp_send(key, remote_location, local_file_path)
+- sftp_fetch(key, remote_path, local_path)
+- sftp_move(key, original_remote_path, new_remote_path)
+- sftp_block(key)
+- ftp_send(key, remote_location, local_file_path)
+- ftp_fetch(key, remote_path, local_path)
+- ftp_move(key, original_remote_path, new_remote_path)
+- ftp_block(key)
+
+It expects an ENV variable named FILE_TRANSFER_MIXIN_CONFIG_PATH to be set.
+It expects a yml configuration file in FILE_TRANSFER_MIXIN_CONFIG_PATH that looks like the following:
+
+ :development:
+ :sftp:
+ :some_key:
+ :server: 127.0.0.1
+ :username: user
+ :password: pass
+ :ftp:
+ :some_key:
+ :server: 127.0.0.1
+ :username: user
+ :password: pass
+
+ :test: {}
+
+ :production: {}
+
+Then in a class, you would deal with it thusly:
+
+ class SomeClass
+ include FileTransferMixin
+
+ # Some method that uploads a file via sftp
+ def some_method
+ sftp_send(:some_key, remote_path, local_path)
+ end
+
+ # Some method that fetches a file via sftp
+ def fetch_method
+ sftp_fetch(:some_key, remote_path, local_path)
+ end
+
+ # Some method that moves a file via sftp
+ def move_method
+ sftp_move(:some_key, original_remote_path, new_remote_path)
+ end
+
+ # Some method that otherwise uses Net::SFTP commands but still uses our config block
+ def sftp_detailed_method
+ sftp_block(:some_key) do |sftp|
+ sftp.rename!('foo', 'bar')
+ end
+ end
+
+ # Some method that uploads a file via ftp
+ def some_method
+ ftp_send(:some_key, remote_path, local_path)
+ end
+
+ # Some method that fetches a file via ftp
+ def fetch_method
+ ftp_fetch(:some_key, remote_path, local_path)
+ end
+
+ # Some method that moves a file via ftp
+ def move_method
+ ftp_move(:some_key, original_remote_path, new_remote_path)
+ end
+
+ # Some method that otherwise uses Net::FTP commands but still uses our config block
+ def ftp_detailed_method
+ ftp_block(:some_key) do |ftp|
+ puts "foo's last modification time: #{ftp.mtime('foo')}"
+ end
+ end
+ end
+
+## Motivation ##
+We have quite a few libraries that interact with remote SFTP and FTP servers, and inevitably they share massive swathes of code
+that should be unnecessary. This intends to be a mixin to make the easy things extremely easy.
+
View
8 Rakefile
@@ -1,2 +1,10 @@
require 'bundler'
Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+
+desc 'Default: run specs.'
+task :default => :spec
+
+desc "Run specs"
+RSpec::Core::RakeTask.new
View
1  file_transfer_mixin.gemspec
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
s.add_dependency 'enviro', '~> 0.0.4'
s.add_development_dependency "bundler", ">= 1.0.0.rc.6"
s.add_development_dependency "rspec", "~> 2.4.0"
+ s.add_development_dependency "ruby-debug19"
end
View
1  lib/file_transfer_mixin.rb
@@ -1,5 +1,6 @@
require 'enviro'
require 'net/sftp'
+require 'net/ftp'
require 'forwardable'
require 'file_transfer_mixin/interfaces'
View
1  lib/file_transfer_mixin/interfaces.rb
@@ -1,4 +1,5 @@
require 'file_transfer_mixin/interfaces/sftp'
+require 'file_transfer_mixin/interfaces/ftp'
module FileTransferMixin
module Interfaces
View
52 lib/file_transfer_mixin/interfaces/ftp.rb
@@ -0,0 +1,52 @@
+module FileTransferMixin
+ module InstanceMethods
+ extend Forwardable
+
+ def_delegators :file_transfer_mixin_ftp_instance, :ftp_send, :ftp_fetch, :ftp_move, :ftp_block
+
+ private
+ def file_transfer_mixin_ftp_instance
+ ::FileTransferMixin::Interfaces::FTP.new
+ end
+ end
+
+ module Interfaces
+ class FTP
+ def configuration
+ FileTransferMixin.configuration.ftp
+ end
+
+ def ftp_block(key, &block)
+ if perform_network_operations?
+ c = configuration[key]
+ Net::FTP.open(c[:server]) do |ftp|
+ ftp.login(c[:username], c[:password])
+ yield(ftp)
+ end
+ end
+ end
+
+ def ftp_send(key, remote_path, local_path)
+ perform :put_binaryfile, key, local_path, remote_path
+ end
+
+ def ftp_fetch(key, remote_path, local_path)
+ perform :get_binaryfile, key, remote_path, local_path
+ end
+
+ def ftp_move(key, original_remote_path, new_remote_path)
+ perform :rename, key, original_remote_path, new_remote_path
+ end
+
+ def perform(action, key, *args)
+ ftp_block(key) do |ftp|
+ ftp.send(action, args)
+ end
+ end
+
+ def perform_network_operations?
+ FileTransferMixin.env.to_s != 'test'
+ end
+ end
+ end
+end
View
2  lib/file_transfer_mixin/version.rb
@@ -1,3 +1,3 @@
module FileTransferMixin
- VERSION = "0.0.5"
+ VERSION = "0.0.6"
end
View
39 spec/lib/interfaces/ftp_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe ::FileTransferMixin::Interfaces::FTP do
+
+ it "should know its parent configuration key" do
+ subject.configuration.should == @config[:development][:ftp]
+ end
+
+ it "should be able to find the server, username, and password for a given key" do
+ subject.configuration[:some_key][:server].should == '127.0.0.1'
+ subject.configuration[:some_key][:username].should == 'user'
+ subject.configuration[:some_key][:password].should == 'pass'
+ end
+
+ describe "network operations" do
+ before(:each) do
+ ftp_mock = mock('ftp')
+ ftp_mock.stub!(:put_binaryfile).and_return(true)
+ ftp_mock.stub!(:get_binaryfile).and_return(true)
+ ftp_mock.stub!(:login).and_return(true)
+ Net::FTP.stub(:open).and_return(ftp_mock)
+ @ftp_interface = TestFileTransferMixin.new
+ @ftp_interface.stub!(:perform_network_operations?).and_return(true)
+ end
+
+ it "should respond to ftp_send" do
+ lambda{ @ftp_interface.ftp_send(:some_key, 'path', 'file_path') }.should_not raise_error
+ end
+
+ it "should respond to ftp_fetch" do
+ lambda{ @ftp_interface.ftp_fetch(:some_key, 'path', 'file_path') }.should_not raise_error
+ end
+ end
+
+ it "should not perform network operations in the test environment" do
+ FileTransferMixin.stub!(:env).and_return('test')
+ TestFileTransferMixin::Interfaces::SFTP.new.perform_network_operations?.should == false
+ end
+end
View
28 spec/lib/interfaces/sftp_spec.rb
@@ -1,34 +1,6 @@
require 'spec_helper'
describe ::FileTransferMixin::Interfaces::SFTP do
- before(:each) do
- Object.send(:remove_const, :TestFileTransferMixin) if defined?(TestFileTransferMixin)
- ENV['FILE_TRANSFER_MIXIN_CONFIG_PATH'] = '/tmp/file_transfer_mixin_enviro_config.yml'
- ENV['ENVY_ENV'] = 'development'
-
- @config = {
- :development => {
- :sftp => {
- :some_key => {
- :server => '127.0.0.1',
- :username => 'user',
- :password => 'pass',
- }
- }
- },
- :test => {
- },
- :production => {
- },
- }
- File.open(ENV['FILE_TRANSFER_MIXIN_CONFIG_PATH'], 'w') do |f|
- f.write(YAML.dump(@config))
- end
-
- class TestFileTransferMixin
- include FileTransferMixin
- end
- end
it "should know its parent configuration key" do
subject.configuration.should == @config[:development][:sftp]
View
35 spec/spec_helper.rb
@@ -11,4 +11,39 @@
# == Mock Framework
config.mock_with :rspec
+
+ config.before(:each) do
+ ENV['FILE_TRANSFER_MIXIN_CONFIG_PATH'] = '/tmp/file_transfer_mixin_enviro_config.yml'
+ ENV['ENVY_ENV'] = 'development'
+
+ @config = {
+ :development => {
+ :sftp => {
+ :some_key => {
+ :server => '127.0.0.1',
+ :username => 'user',
+ :password => 'pass',
+ }
+ },
+ :ftp => {
+ :some_key => {
+ :server => '127.0.0.1',
+ :username => 'user',
+ :password => 'pass',
+ }
+ },
+ },
+ :test => {
+ },
+ :production => {
+ },
+ }
+ File.open(ENV['FILE_TRANSFER_MIXIN_CONFIG_PATH'], 'w') do |f|
+ f.write(YAML.dump(@config))
+ end
+ Object.send(:remove_const, :TestFileTransferMixin) if defined?(TestFileTransferMixin)
+ class TestFileTransferMixin
+ include FileTransferMixin
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.