ftp_service 0.1.1 → 0.2.0

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 CHANGED
@@ -16,6 +16,8 @@ tmtags
16
16
  ## PROJECT::GENERAL
17
17
  coverage
18
18
  rdoc
19
+ doc
19
20
  pkg
21
+ .yardoc
20
22
 
21
23
  ## PROJECT::SPECIFIC
@@ -0,0 +1,10 @@
1
+ # v0.2.0 (2010-03-08)
2
+
3
+ * Add `FtpService#write_request` and `FtpService#read_response` methods,
4
+ making this thing actually usable.
5
+
6
+ * Switch to Markdown + Yardoc for rdocs.
7
+
8
+ # v0.1.1 (2010-03-08)
9
+
10
+ * First version. Opens a connection but that's it. Useful, huh?
data/README.markdown ADDED
@@ -0,0 +1,37 @@
1
+ # FTP Service
2
+
3
+ An FTP Service is like a web service except stupid. You send your
4
+ request by uploading an xml file and get your response by downloading
5
+ another xml file. Have you ever had to deal with something like that? I
6
+ have.
7
+
8
+ RDocs on [rdoc.info](http://rdoc.info/projects/blaix/ftp_service).
9
+
10
+ Source code on [github](http://github.com/blaix/ftp_service).
11
+
12
+ ## Installation
13
+
14
+ gem install ftp_service
15
+
16
+ ## Usage
17
+
18
+ require 'ftp_service'
19
+
20
+ FtpService.open('host', 'user', 'pass') do |service|
21
+ path = '/the/remote/path'
22
+ service.write_request("#{path}/request.xml", '<foo>bar</foo>')
23
+ response = service.read_response("#{path}/response.xml")
24
+ end
25
+
26
+ * `read_response` will block while it polls the server waiting for a
27
+ response.
28
+ * Temp files are created for the local request and response files and
29
+ deleted when no longer needed.
30
+
31
+ For more details, see the
32
+ [RDocs](http://rdoc.info/projects/blaix/ftp_service) (sike they are
33
+ really yardocs!).
34
+
35
+ ## Copyright
36
+
37
+ Copyright (c) 2010 Justin Blake. See LICENSE for details.
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.authors = ["Justin Blake"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
14
  gem.add_development_dependency "mocha", ">= 0.9.8"
15
+ gem.add_development_dependency "yard", ">= 0"
15
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
17
  end
17
18
  Jeweler::GemcutterTasks.new
@@ -25,6 +26,14 @@ Spec::Rake::SpecTask.new(:spec) do |spec|
25
26
  spec.spec_files = FileList['spec/**/*_spec.rb']
26
27
  end
27
28
 
29
+ namespace :spec do
30
+ Spec::Rake::SpecTask.new(:doc) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.spec_files = FileList['spec/**/*_spec.rb']
33
+ spec.spec_opts << '--format specdoc'
34
+ end
35
+ end
36
+
28
37
  Spec::Rake::SpecTask.new(:rcov) do |spec|
29
38
  spec.libs << 'lib' << 'spec'
30
39
  spec.pattern = 'spec/**/*_spec.rb'
@@ -35,12 +44,13 @@ task :spec => :check_dependencies
35
44
 
36
45
  task :default => :spec
37
46
 
38
- require 'rake/rdoctask'
39
- Rake::RDocTask.new do |rdoc|
40
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
-
42
- rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "ftp_service #{version}"
44
- rdoc.rdoc_files.include('README*')
45
- rdoc.rdoc_files.include('lib/**/*.rb')
47
+ begin
48
+ require 'yard'
49
+ YARD::Rake::YardocTask.new do |y|
50
+ y.files << '-' << 'CHANGELOG.*'
51
+ end
52
+ rescue LoadError
53
+ task :yardoc do
54
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
55
+ end
46
56
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/ftp_service.gemspec CHANGED
@@ -5,29 +5,31 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ftp_service}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin Blake"]
12
- s.date = %q{2010-03-05}
12
+ s.date = %q{2010-03-08}
13
13
  s.description = %q{An FTP Service is like a web service except stupid. You send your request by uploading an xml file and get your response by downloading another xml file.}
14
14
  s.email = %q{justin@megablaix.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.markdown"
18
18
  ]
19
19
  s.files = [
20
- ".document",
21
- ".gitignore",
20
+ ".gitignore",
21
+ "CHANGELOG.markdown",
22
22
  "LICENSE",
23
- "README.rdoc",
23
+ "README.markdown",
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "ftp_service.gemspec",
27
27
  "lib/ftp_service.rb",
28
+ "lib/tempfile_helper.rb",
28
29
  "spec/ftp_service_spec.rb",
29
30
  "spec/spec.opts",
30
- "spec/spec_helper.rb"
31
+ "spec/spec_helper.rb",
32
+ "spec/tempfile_helper_spec.rb"
31
33
  ]
32
34
  s.homepage = %q{http://github.com/blaix/ftp_service}
33
35
  s.rdoc_options = ["--charset=UTF-8"]
@@ -36,7 +38,8 @@ Gem::Specification.new do |s|
36
38
  s.summary = %q{A class for dealing with the worst possible type of "web" service.}
37
39
  s.test_files = [
38
40
  "spec/ftp_service_spec.rb",
39
- "spec/spec_helper.rb"
41
+ "spec/spec_helper.rb",
42
+ "spec/tempfile_helper_spec.rb"
40
43
  ]
41
44
 
42
45
  if s.respond_to? :specification_version then
@@ -46,13 +49,16 @@ Gem::Specification.new do |s|
46
49
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
50
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
48
51
  s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
52
+ s.add_development_dependency(%q<yard>, [">= 0"])
49
53
  else
50
54
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
51
55
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
56
+ s.add_dependency(%q<yard>, [">= 0"])
52
57
  end
53
58
  else
54
59
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
55
60
  s.add_dependency(%q<mocha>, [">= 0.9.8"])
61
+ s.add_dependency(%q<yard>, [">= 0"])
56
62
  end
57
63
  end
58
64
 
data/lib/ftp_service.rb CHANGED
@@ -1,17 +1,31 @@
1
1
  require 'net/ftp'
2
+ require 'tempfile_helper'
2
3
 
3
4
  # Class for dealing with a service that acts like a web service, except
4
5
  # over FTP. Meaning an xml request is uploaded as a file, and the
5
6
  # response xml is downloaded as another file.
7
+ #
8
+ # Typical usage:
9
+ #
10
+ # FtpService.open('host', 'user', 'pass') do |service|
11
+ # path = '/the/remote/path'
12
+ # service.write_request("#{path}/request.xml", '<foo>bar</foo>')
13
+ # response = service.read_response("#{path}/response.xml")
14
+ # end
15
+ #
16
+ # or (the sucky way):
17
+ #
18
+ # path = '/the/remote/path'
19
+ # service = FtpService.new('host', 'user', 'pass')
20
+ # service.write_request("#{path}/request.xml", '<foo>bar</foo>')
21
+ # response = service.read_response("#{path}/response.xml")
22
+ # service.close
6
23
  class FtpService
7
24
 
8
25
  # Open a connection to the FTP server and return an FtpService object.
9
- # The object must be closed explicitely.
10
- #
11
- # ftp_service = FtpService.open(host, user, pass)
12
- # ftp_service.write_request(path, request)
13
- # response = ftp_service.read_response(path)
14
- # ftp_service.close
26
+ # The object must be closed explicitely. See FtpServier#open for a
27
+ # better way to do this that will automatically close the connection,
28
+ # even if an exception is raised.
15
29
  def initialize(host, user, pass)
16
30
  @ftp = Net::FTP.open(host, user, pass)
17
31
  end
@@ -19,11 +33,6 @@ class FtpService
19
33
  # Open a connection and pass an FtpService instance to the block. The
20
34
  # instance will be closed when the block finishes, or when an
21
35
  # exception is raised.
22
- #
23
- # FtpService.open(host, user, pass) do |ftp_service|
24
- # ftp_service.write_request(path, request)
25
- # response = ftp_service.read_response(path)
26
- # end
27
36
  def self.open(host, user, pass)
28
37
  instance = new(host, user, pass)
29
38
  begin
@@ -33,6 +42,21 @@ class FtpService
33
42
  end
34
43
  end
35
44
 
45
+ # Write `request` to a local temp file and upload it to `remote_path`
46
+ # on the FTP server.
47
+ def write_request(request, remote_path)
48
+ tmp = TempfileHelper.write(request, 'request')
49
+ @ftp.puttextfile(tmp.path, remote_path)
50
+ end
51
+
52
+ # Download the file at `remote_path` from the FTP server to a local
53
+ # temp file and return its contents.
54
+ def read_response(remote_path)
55
+ TempfileHelper.read('response') do |tmp|
56
+ @ftp.gettextfile(remote_path, tmp.path)
57
+ end
58
+ end
59
+
36
60
  # Close the connection to the FTP server.
37
61
  def close
38
62
  @ftp.close
@@ -0,0 +1,20 @@
1
+ require 'tempfile'
2
+
3
+ module TempfileHelper
4
+ extend self
5
+
6
+ def read(name = nil)
7
+ tempfile = nil
8
+ name ||= Time.now.to_f
9
+ Tempfile.open(name) { |tempfile| yield(tempfile) }
10
+ File.read(tempfile.path)
11
+ end
12
+
13
+ def write(content, name = nil)
14
+ name ||= Time.now.to_f.to_s
15
+ file = Tempfile.new(name)
16
+ file.write(content)
17
+ file.close
18
+ file
19
+ end
20
+ end
@@ -7,35 +7,35 @@ describe "FtpService" do
7
7
  end
8
8
 
9
9
  describe '.new(host, user, pass)' do
10
- it 'should connect to the requested ftp server' do
10
+ it 'connects to the requested ftp server' do
11
11
  Net::FTP.expects(:open).with('host', 'user', 'pass').returns(@ftp)
12
12
  FtpService.new('host', 'user', 'pass')
13
13
  end
14
14
 
15
- it 'should yield an instance of the ftp service' do
15
+ it 'returns an instance of the ftp service' do
16
16
  service = FtpService.new('host', 'user', 'pass')
17
17
  service.should be_a(FtpService)
18
18
  end
19
19
  end
20
20
 
21
21
  describe '.open(host, user, pass)' do
22
- it 'should connect to the requested ftp server' do
22
+ it 'connects to the requested ftp server' do
23
23
  Net::FTP.expects(:open).with('host', 'user', 'pass').returns(@ftp)
24
24
  FtpService.open('host', 'user', 'pass') {}
25
25
  end
26
26
 
27
- it 'should yield an instance of the ftp service' do
27
+ it 'yields an instance of the ftp service' do
28
28
  service = nil
29
29
  FtpService.open('host', 'user', 'pass') { |service| }
30
30
  service.should be_a(FtpService)
31
31
  end
32
32
 
33
- it 'should automatically close the connection' do
33
+ it 'automatically closes the connection' do
34
34
  @ftp.expects(:close)
35
35
  FtpService.open('host', 'user', 'pass') {}
36
36
  end
37
37
 
38
- it 'should close the connection even if an exception is raised' do
38
+ it 'closes the connection even if an exception is raised' do
39
39
  @ftp.expects(:close)
40
40
  lambda {
41
41
  FtpService.open('host', 'user', 'pass') { raise "boom" }
@@ -43,8 +43,43 @@ describe "FtpService" do
43
43
  end
44
44
  end
45
45
 
46
+ describe '#write_request(path, request)' do
47
+ before do
48
+ @tempfile = stub('tempfile', :path => '/local/path')
49
+ @service = FtpService.new('host', 'user', 'pass')
50
+ end
51
+
52
+ it "saves the request to a temp file" do
53
+ TempfileHelper.expects(:write).with('request', optionally(anything)).returns(@tempfile)
54
+ @service.write_request('request', '/remote/path')
55
+ end
56
+
57
+ it "uploads the request to `path` on the FTP server" do
58
+ TempfileHelper.stubs(:write).returns(@tempfile)
59
+ @ftp.expects(:puttextfile).with('/local/path', '/remote/path')
60
+ @service.write_request('request', '/remote/path')
61
+ end
62
+ end
63
+
64
+ describe '#read_response(path)' do
65
+ before do
66
+ tempfile = stub('tempfile', :path => '/local/path')
67
+ TempfileHelper.stubs(:read).returns('response').yields(tempfile)
68
+ @service = FtpService.new('host', 'user', 'pass')
69
+ end
70
+
71
+ it "downloads the response at `path` from the FTP server" do
72
+ @ftp.expects(:gettextfile).with('/remote/path', '/local/path')
73
+ @service.read_response('/remote/path')
74
+ end
75
+
76
+ it "returns the contents of the downloaded response" do
77
+ @service.read_response('/remote/path').should == "response"
78
+ end
79
+ end
80
+
46
81
  describe '#close' do
47
- it 'should close the connection to the ftp server' do
82
+ it 'closes the connection to the ftp server' do
48
83
  @ftp.expects(:close)
49
84
  FtpService.new('host', 'user', 'pass').close
50
85
  end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'tempfile_helper'
3
+
4
+ describe "TempfileHelper" do
5
+ describe '.read([name]) { |tempfile| }' do
6
+ before do
7
+ @tempfile = nil
8
+ TempfileHelper.read { |@tempfile| }
9
+ end
10
+
11
+ it "yields a Tempfile object" do
12
+ @tempfile.should be_a(Tempfile)
13
+ end
14
+
15
+ it "closes the tempfile object after the block executes" do
16
+ @tempfile.should be_closed
17
+ end
18
+
19
+ it "closes the tempfile object even if an exception is raised" do
20
+ tempfile = nil
21
+ lambda {
22
+ TempfileHelper.read { |tempfile| raise "boom" }
23
+ }.should raise_error
24
+ tempfile.should be_closed
25
+ end
26
+
27
+ it "accepts an optional name for the tempfile" do
28
+ tempfile = nil
29
+ TempfileHelper.read('the_name') { |tempfile| }
30
+ tempfile.path.should include('the_name')
31
+ end
32
+
33
+ it "returns contents of the tempfile after the block is executed" do
34
+ TempfileHelper.read do |tempfile|
35
+ tempfile.write('the contents')
36
+ end.should == 'the contents'
37
+ end
38
+ end
39
+
40
+ describe '.write_temp_file(content[, name])' do
41
+ before do
42
+ @tempfile = TempfileHelper.write('the content')
43
+ end
44
+
45
+ it "returns a tempfile object" do
46
+ @tempfile.should be_a(Tempfile)
47
+ end
48
+
49
+ it "writes the passed content to the temp file" do
50
+ File.read(@tempfile.path).should == 'the content'
51
+ end
52
+
53
+ it "closes the tempfile object" do
54
+ @tempfile.should be_closed
55
+ end
56
+
57
+ it "accepts an optional name for the temp file" do
58
+ tempfile = TempfileHelper.write('the content', 'the_name')
59
+ tempfile.path.should include('the_name')
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Justin Blake
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-05 00:00:00 -05:00
17
+ date: 2010-03-08 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -45,6 +45,18 @@ dependencies:
45
45
  version: 0.9.8
46
46
  type: :development
47
47
  version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: yard
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id003
48
60
  description: An FTP Service is like a web service except stupid. You send your request by uploading an xml file and get your response by downloading another xml file.
49
61
  email: justin@megablaix.com
50
62
  executables: []
@@ -53,19 +65,21 @@ extensions: []
53
65
 
54
66
  extra_rdoc_files:
55
67
  - LICENSE
56
- - README.rdoc
68
+ - README.markdown
57
69
  files:
58
- - .document
59
70
  - .gitignore
71
+ - CHANGELOG.markdown
60
72
  - LICENSE
61
- - README.rdoc
73
+ - README.markdown
62
74
  - Rakefile
63
75
  - VERSION
64
76
  - ftp_service.gemspec
65
77
  - lib/ftp_service.rb
78
+ - lib/tempfile_helper.rb
66
79
  - spec/ftp_service_spec.rb
67
80
  - spec/spec.opts
68
81
  - spec/spec_helper.rb
82
+ - spec/tempfile_helper_spec.rb
69
83
  has_rdoc: true
70
84
  homepage: http://github.com/blaix/ftp_service
71
85
  licenses: []
@@ -99,3 +113,4 @@ summary: A class for dealing with the worst possible type of "web" service.
99
113
  test_files:
100
114
  - spec/ftp_service_spec.rb
101
115
  - spec/spec_helper.rb
116
+ - spec/tempfile_helper_spec.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/README.rdoc DELETED
@@ -1,40 +0,0 @@
1
- = FTP Service
2
-
3
- An FTP Service is like a web service except stupid. You send your
4
- request by uploading an xml file and get your response by downloading
5
- another xml file. Have you ever had to deal with something like that? I
6
- have.
7
-
8
- == Installation
9
-
10
- gem install ftp_service
11
-
12
- == Usage
13
-
14
- require 'ftp_service'
15
-
16
- FtpService.open('host', 'user', 'pass') do |service|
17
- path = '/the/remote/path'
18
- service.write_request("#{path}/request.xml", '<foo>bar</foo>')
19
- response = service.read_response("#{path}/response.xml")
20
- end
21
-
22
- * +read_response+ will block while it polls the server waiting for a
23
- response.
24
- * Temp files are created for the local request and response files and
25
- deleted when no longer needed.
26
-
27
- == Note on Patches/Pull Requests
28
-
29
- * Fork the project.
30
- * Make your feature addition or bug fix.
31
- * Add tests for it. This is important so I don't break it in a
32
- future version unintentionally.
33
- * Commit, do not mess with rakefile, version, or history. (if you want
34
- to have your own version, that is fine but bump version in a commit by
35
- itself I can ignore when I pull)
36
- * Send me a pull request. Bonus points for topic branches.
37
-
38
- == Copyright
39
-
40
- Copyright (c) 2010 Justin Blake. See LICENSE for details.