em-ftp-client 0.0.1 → 0.0.2

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
@@ -2,5 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
-
5
+ .idea
6
6
  test_client.rb
data/README CHANGED
@@ -17,12 +17,14 @@ standard usage would look like:
17
17
  ftp.list do |l2|
18
18
  puts l2
19
19
  puts
20
- ftp.stream {|d| puts "STREAMING: #{d.inspect}" }
21
- ftp.get("two.txt") do |t1|
22
- puts "COMPLETED"
23
- puts t1
24
- puts
25
- EM.stop
20
+ ftp.put("one.txt") do
21
+ ftp.stream {|d| puts "STREAMING: #{d.inspect}" }
22
+ ftp.get("two.txt") do |t1|
23
+ puts "COMPLETED"
24
+ puts t1
25
+ puts
26
+ EM.stop
27
+ end
26
28
  end
27
29
  end
28
30
  end
@@ -32,7 +34,3 @@ standard usage would look like:
32
34
 
33
35
  This library also includes the class SyncSession, which uses fibers and works
34
36
  with em-synchrony.
35
-
36
- TODO:
37
-
38
- Add support for put/STOR operations
@@ -108,7 +108,7 @@ module EventMachine
108
108
  def data_connection_closed(data)
109
109
  @data_buffer = data
110
110
  @data_connection = nil
111
- send(@responder) if @responder
111
+ send(@responder) if @responder and @response.complete?
112
112
  end
113
113
 
114
114
  def callback(&blk)
@@ -166,6 +166,19 @@ module EventMachine
166
166
  @responder = :retr_response
167
167
  end
168
168
 
169
+ def stor(filename)
170
+ send_data("STOR #{filename}\r\n")
171
+ @responder = :stor_response
172
+ end
173
+
174
+ def close
175
+ if @data_connection
176
+ raise "Can not close connection while data connection is still open"
177
+ end
178
+ send_data("QUIT\r\n")
179
+ @responder = :close_response
180
+ end
181
+
169
182
  def list
170
183
  send_data("LIST\r\n")
171
184
  @responder = :list_response
@@ -198,8 +211,10 @@ module EventMachine
198
211
 
199
212
  # Called when a response for the CWD or CDUP is received
200
213
  def cwd_response(response)
201
- @responder = nil
202
- call_callback
214
+ if response && response.code != "226"
215
+ @responder = nil
216
+ call_callback
217
+ end
203
218
  end
204
219
 
205
220
  # Called when a response for the PWD verb is received
@@ -235,6 +250,7 @@ module EventMachine
235
250
  end
236
251
 
237
252
  if response && @data_connection
253
+ @response = response
238
254
  #well we still gots to wait for the file
239
255
  elsif @data_connection
240
256
  #well we need to wait for a response
@@ -246,6 +262,18 @@ module EventMachine
246
262
  end
247
263
  end
248
264
 
265
+ def stor_response(response=nil)
266
+ if response && response.code != "226"
267
+ @data_connection.close_connection
268
+ @responder = nil
269
+ error(response)
270
+ end
271
+
272
+ @responder = nil
273
+ @data_buffer = nil
274
+ call_callback
275
+ end
276
+
249
277
  def list_response(response=nil)
250
278
  if response && response.code != "226"
251
279
  @data_connection.close_connection
@@ -262,13 +290,17 @@ module EventMachine
262
290
  old_data_buffer = @data_buffer
263
291
  @data_buffer = nil
264
292
  # parse it into a real form
265
- file_list = old_data_buffer.split("\r\n").map do |line|
266
- ::Net::FTP::List.parse(line)
293
+ file_list = old_data_buffer.split("\n").map do |line|
294
+ ::Net::FTP::List.parse(line.strip)
267
295
  end
268
296
  call_callback(file_list)
269
297
  end
270
298
  end
271
-
299
+
300
+ def close_response(response=nil)
301
+ close_connection
302
+ call_callback
303
+ end
272
304
  end
273
305
  end
274
306
  end
@@ -22,6 +22,11 @@ module EventMachine
22
22
  @buf = ''
23
23
  end
24
24
  end
25
+
26
+ def send_file(filename)
27
+ send_file_data(filename)
28
+ close_connection_after_writing
29
+ end
25
30
 
26
31
  def unbind
27
32
  succeed(@buf)
@@ -47,6 +47,23 @@ module EventMachine
47
47
  end
48
48
  control_connection.pasv
49
49
  end
50
+
51
+ def put(file, &cb)
52
+ filename = File.basename(file)
53
+ control_connection.callback do |data_connection|
54
+ data_connection.send_file(file)
55
+ control_connection.callback(&cb)
56
+ control_connection.stor filename
57
+ end
58
+ control_connection.pasv
59
+ end
60
+
61
+ def close
62
+ @control_connection.callback do
63
+ yield if block_given?
64
+ end
65
+ @control_connection.close
66
+ end
50
67
  end
51
68
  end
52
69
  end
@@ -1,7 +1,7 @@
1
1
  module Em
2
2
  module Ftp
3
3
  module Client
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
6
6
  end
7
7
  end
@@ -177,6 +177,7 @@ class ControlConnectionTest < Test::Unit::TestCase
177
177
  @control_connection.receive_line(set[2]+"\r\n") if set[2]
178
178
  end
179
179
 
180
+ # test RETR
180
181
  @control_connection.expects(:send_data).with("RETR foo.txt\r\n")
181
182
  @control_connection.retr("foo.txt")
182
183
 
@@ -189,6 +190,17 @@ class ControlConnectionTest < Test::Unit::TestCase
189
190
  @data_connection.unbind
190
191
  assert retr_completed
191
192
 
193
+ # test STOR
194
+ @control_connection.expects(:send_data).with("STOR foo.txt\r\n")
195
+ @control_connection.stor("foo.txt")
196
+
197
+ stor_completed = false
198
+ @control_connection.callback {stor_completed = true }
199
+ assert !stor_completed
200
+ @data_connection.unbind
201
+ @control_connection.receive_line("226 Hooray\r\n")
202
+ assert stor_completed
203
+
192
204
  assert started
193
205
  assert_equal "\"/foo\"", working_dir
194
206
  end
metadata CHANGED
@@ -1,117 +1,119 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: em-ftp-client
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Ben Hughes
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-06-29 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: eventmachine
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: net-ftp-list
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
39
25
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-ftp-list
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
47
38
  type: :runtime
48
- version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: shoulda
51
39
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
53
41
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: shoulda
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
61
54
  type: :development
62
- version_requirements: *id003
63
- - !ruby/object:Gem::Dependency
64
- name: mocha
65
55
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mocha
64
+ requirement: !ruby/object:Gem::Requirement
67
65
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
75
70
  type: :development
76
- version_requirements: *id004
77
- - !ruby/object:Gem::Dependency
78
- name: redgreen
79
71
  prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
81
73
  none: false
82
- requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- hash: 3
86
- segments:
87
- - 0
88
- version: "0"
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: redgreen
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
89
86
  type: :development
90
- version_requirements: *id005
91
- - !ruby/object:Gem::Dependency
92
- name: rake
93
87
  prerelease: false
94
- requirement: &id006 !ruby/object:Gem::Requirement
88
+ version_requirements: !ruby/object:Gem::Requirement
95
89
  none: false
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- hash: 3
100
- segments:
101
- - 0
102
- version: "0"
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
103
102
  type: :development
104
- version_requirements: *id006
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
105
110
  description: An FTP client designed to work well with EventMachine
106
- email:
111
+ email:
107
112
  - ben@pixelmachine.org
108
113
  executables: []
109
-
110
114
  extensions: []
111
-
112
115
  extra_rdoc_files: []
113
-
114
- files:
116
+ files:
115
117
  - .gitignore
116
118
  - Gemfile
117
119
  - LICENSE
@@ -126,40 +128,36 @@ files:
126
128
  - lib/em-ftp-client/version.rb
127
129
  - test/control_connection_test.rb
128
130
  - test/helper.rb
129
- has_rdoc: true
130
- homepage: ""
131
+ homepage: ''
131
132
  licenses: []
132
-
133
133
  post_install_message:
134
134
  rdoc_options: []
135
-
136
- require_paths:
135
+ require_paths:
137
136
  - lib
138
- required_ruby_version: !ruby/object:Gem::Requirement
137
+ required_ruby_version: !ruby/object:Gem::Requirement
139
138
  none: false
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- hash: 3
144
- segments:
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ segments:
145
144
  - 0
146
- version: "0"
147
- required_rubygems_version: !ruby/object:Gem::Requirement
145
+ hash: -1131821477746437581
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
147
  none: false
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- hash: 3
153
- segments:
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ segments:
154
153
  - 0
155
- version: "0"
154
+ hash: -1131821477746437581
156
155
  requirements: []
157
-
158
156
  rubyforge_project: em-ftp-client
159
- rubygems_version: 1.4.1
157
+ rubygems_version: 1.8.24
160
158
  signing_key:
161
159
  specification_version: 3
162
160
  summary: EventMachine FTP client
163
- test_files:
161
+ test_files:
164
162
  - test/control_connection_test.rb
165
163
  - test/helper.rb