ruby-net-nntp 0.0.9 → 0.1.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/CHANGELOG CHANGED
@@ -1,4 +1,41 @@
1
- 2007-07-02 20:51 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (4399451e92c0 [tip])
1
+ 2007-07-14 12:22 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (5de9968582e9 [tip])
2
+
3
+ * README, lib/net/nntp.rb, lib/net/nntp/article.rb,
4
+ lib/net/nntp/group.rb, lib/net/nntp/version.rb,
5
+ test/mock/mock_socket.rb, test/unit/test_nntp_article.rb,
6
+ test/unit/test_nntp_group.rb:
7
+ NNTP can QUIT, Article redesign: parse HEAD, BODY and ARTICLE,
8
+ renamed 'id' to 'number', headers and body along with proxies added
9
+ - added QUIT to Net::NNTP
10
+ - added parse from HEAD, BODY and ARTICLE to Net::NNTP::Article
11
+ (factory)
12
+ - redesigned Net::NNTP::Article: + separate headers
13
+ and body attributes + including proxies to mimick
14
+ old attributes, deprecated + renamed the conflicting
15
+ 'id' attribute to 'number'
16
+ - improved documentation
17
+
18
+ 2007-07-09 14:34 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (d97d95ec735b)
19
+
20
+ * lib/net/nntp.rb, lib/net/nntp/article.rb, lib/net/nntp/group.rb,
21
+ lib/net/nntp/version.rb, lib/net/nntp_article.rb,
22
+ lib/net/nntp_group.rb, test/functional/test_nntp.rb,
23
+ test/mock/mock_socket.rb:
24
+ fixed overview.fmt, fixed logging
25
+ - fixed overview.fmt bug
26
+ - fixed logging for autotest/test
27
+
28
+ 2007-07-02 21:35 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (5ba29ac12969)
29
+
30
+ * lib/net/nntp/version.rb:
31
+ new release;version fix
32
+
33
+ 2007-07-02 21:34 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (8441de3d244d)
34
+
35
+ * lib/net/nntp.rb:
36
+ bugfix read_response multiline read - introduced with last release
37
+
38
+ 2007-07-02 20:51 +0200 Anton 'tony' Bangratz <anton.bangratz@gmail.com> (4399451e92c0)
2
39
 
3
40
  * lib/net/nntp/version.rb:
4
41
  Release 0.0.8, fixed version
data/README CHANGED
@@ -29,3 +29,12 @@ Net::NNTP uses a simple interface to wrap commands to communicate with an NNTP s
29
29
 
30
30
  * sudo gem install libruby-nntp or
31
31
  * sudo dpkg -r libruby-0.0.1.deb
32
+
33
+ = CHANGES
34
+
35
+ Version 0.1.0 introduces the Net::NNTP::Article#headers and #body attributes.
36
+ Due to this, the attribute Net::NNTP::Article#id has been changed to Net::NNTP::Article#number
37
+ to avoid conflicts with Object#id.
38
+
39
+ Additionally, on request, Net::NNTP::Article has been changed from being a mere proxy for Net::NNTP#xover
40
+ result lines to being able to parse HEAD, BODY and ARTICLE results and return a corresponding instance.
data/lib/net/nntp.rb CHANGED
@@ -3,13 +3,14 @@
3
3
  require 'socket'
4
4
  require 'thread'
5
5
  require 'timeout' # :nodoc:
6
- require 'net/nntp_group'
7
- require 'net/nntp_article'
6
+ require 'net/nntp/group'
7
+ require 'net/nntp/article'
8
8
  require 'net/nntp/version.rb'
9
9
  require 'rubygems'
10
10
  require 'log4r'
11
11
 
12
12
 
13
+
13
14
  module Net
14
15
  class NNTP
15
16
  include Timeout # :nodoc:
@@ -62,6 +63,15 @@ module Net
62
63
  @welcome
63
64
  end
64
65
 
66
+ # Sends QUIT command to server and closes the connection (unless force_close is set to false). Returns response.
67
+ def quit(force_close=true)
68
+ send_cmd "QUIT"
69
+ response = read_response
70
+ close if force_close
71
+ response
72
+ end
73
+
74
+
65
75
  # Closes connection. If not reconnected, subsequent calls of commands raise exceptions
66
76
  def close
67
77
  debug 'closing connection per request'
@@ -195,7 +205,7 @@ module Net
195
205
  case keyword
196
206
  when /overview.fmt/
197
207
  @overview_format_raw = list
198
- @overview_format = Net::NNTP.parse_overview_format list.join
208
+ @overview_format = Net::NNTP.parse_overview_format list
199
209
  else
200
210
  create_grouplist(list)
201
211
  list
@@ -208,9 +218,10 @@ module Net
208
218
 
209
219
  # prepares overview format as read from server, used by Net::NNTP::Article and list()
210
220
  def self.parse_overview_format(format)
211
- overview_format = %w{id}
212
- format.split(/\r?\n/).each do |line|
213
- next if line[0] == ?2 || line[0] == ?.
221
+ overview_format = %w{number}
222
+ lines = format
223
+ lines.each do |line|
224
+ next if line[0] == ?2 || line[0] == ?. || line == 'full'
214
225
  ident = line.scan(/\w/).join.downcase
215
226
  unless ident[0..3] == 'xref'
216
227
  overview_format << ident
@@ -287,7 +298,7 @@ module Net
287
298
  case code
288
299
  when '223'
289
300
  code, id, msgid, what = response.split
290
- article.id = id
301
+ article.number = id
291
302
  article.messageid = msgid
292
303
  else
293
304
  raise CommandFailedError, response
@@ -300,6 +311,7 @@ module Net
300
311
  last_or_next("last")
301
312
  end
302
313
 
314
+ # Issues the NEXT command to the NNTP server, returning the raw response
303
315
  def next
304
316
  last_or_next("next")
305
317
  end
@@ -329,14 +341,24 @@ module Net
329
341
  linecnt = 0
330
342
  loop do
331
343
  str = @socket.readline
344
+ #debug " -> got line: '#{str}'"
332
345
  ra << str.chomp if str
333
- break if force_oneline || (str.chomp == "." || !str || (linecnt == 0 && ONELINE_STATUSES.include?(str[0..2])) )
346
+ break if force_oneline || (!str || str.chomp == "." || (linecnt == 0 && ONELINE_STATUSES.include?(str[0..2])) )
334
347
  linecnt += 1
335
348
  end
336
- debug "Response: '#{ra}'"
349
+ debug "Response: '#{ra.inspect}'"
337
350
  ra
338
351
  end
339
352
 
353
+ # Parses a hash in the format {:from => int, :to => int} or {:message_id => int}
354
+ # and returns a string. :to is optional, :from has precedence over :message_id if
355
+ # both are given
356
+ #
357
+ # Examples:
358
+ # numbers_or_id(:from => 1, :to => 100) #=> returns '1-100'
359
+ # numbers_or_id(:from => 1) #=> returns '1-'
360
+ # numbers_or_id(:message_id = '<abc>' #=> returns '<abc>'
361
+ # numbers_or_id(:from => 5, :message_id = '<abc>' #=> returns 'f-'
340
362
  def numbers_or_id(hash)
341
363
  return nil unless hash
342
364
  suffix = ''
@@ -0,0 +1,176 @@
1
+ require 'ostruct'
2
+
3
+ # a slightly modified OpenStruct
4
+ class HeaderStruct < OpenStruct
5
+ # adds of modifies a new key/value pair
6
+ def add_pair(key, value)
7
+ @table[key.to_sym] = value
8
+ new_ostruct_member(key)
9
+ end
10
+ end
11
+
12
+ module Net
13
+ class NNTP
14
+ class Article
15
+ attr_accessor :group, :headers, :body
16
+ attr_reader :overview_format
17
+
18
+ def initialize
19
+ @overview_format = %w{number}
20
+ @headers ||= HeaderStruct.new
21
+ @body = []
22
+ end
23
+
24
+ # Former versions attribute proxy
25
+ #
26
+ # Deprecated: use corresponding headers attribute instead
27
+ def number
28
+ @headers.number
29
+ end
30
+
31
+ # Former versions attribute proxy
32
+ #
33
+ # Deprecated: use corresponding headers attribute instead
34
+ def number=(number)
35
+ @headers.number = number
36
+ end
37
+
38
+ # Former versions attribute proxy
39
+ #
40
+ # Deprecated: use corresponding headers attribute instead
41
+ def messageid
42
+ @headers.message_id
43
+ end
44
+
45
+ # Former versions attribute proxy
46
+ #
47
+ # Deprecated: use corresponding headers attribute instead
48
+ def messageid=(id)
49
+ @headers.message_id = id
50
+ end
51
+
52
+ # Former versions attribute proxy
53
+ #
54
+ # Deprecated: use corresponding headers attribute instead
55
+ def subject
56
+ @headers.subject
57
+ end
58
+
59
+ # Former versions attribute proxy
60
+ #
61
+ # Deprecated: use corresponding headers attribute instead
62
+ def subject=(subject)
63
+ @headers.subject=subject
64
+ end
65
+
66
+ # Former versions attribute proxy
67
+ #
68
+ # Deprecated: use corresponding headers attribute instead
69
+ def bytes
70
+ @headers.bytes
71
+ end
72
+
73
+ # Former versions attribute proxy
74
+ #
75
+ # Deprecated: use corresponding headers attribute instead
76
+ def lines
77
+ @headers.lines
78
+ end
79
+
80
+ # Former versions attribute proxy
81
+ #
82
+ # Deprecated: use corresponding headers attribute instead
83
+ def xref
84
+ @headers.xref
85
+ end
86
+
87
+ # Former versions attribute proxy
88
+ #
89
+ # Deprecated: use corresponding headers attribute instead
90
+ def date
91
+ @headers.date
92
+ end
93
+
94
+ # Former versions attribute proxy
95
+ #
96
+ # Deprecated: use corresponding headers attribute instead
97
+ def from
98
+ @headers.from
99
+ end
100
+
101
+ # Sets the overview format to use for parsing article from XOVER command results.
102
+ #
103
+ #
104
+ # Takes either a tab separated line as result from 'LIST OVERVIEW.FMT' and
105
+ # parses it into an array (see Net::NNTP::parse_overview_format) or takes
106
+ # an already parsed array to set the format directly.
107
+ def overview_format=(format)
108
+ if Array === format
109
+ @overview_format = format
110
+ else
111
+ @overview_format = Net::NNTP.parse_overview_format format
112
+ end
113
+ end
114
+
115
+ # Parses data from XOVER command
116
+ #
117
+ # Takes the tab separated line corresponding to an article from the XOVER command
118
+ # result and sets the header fields accordingly. CAVEAT! The overview format (see
119
+ # Net::NNTP::Article#overview_format= has to be set prior of attempting this, and
120
+ # has to actually correspond with the fields.
121
+ def overview(over)
122
+ over.split(/\t/).each_with_index do |value, index|
123
+ ident = @overview_format[index]
124
+ @headers.add_pair(ident, value)
125
+ if @headers.messageid
126
+ @headers.message_id = @headers.messageid
127
+ end
128
+ end
129
+ end
130
+
131
+ # Sets a header from the result line
132
+ #
133
+ # Parses a line of the format "Header: Value" and sets the @headers accordingly.
134
+ # (Example: "Message-ID: <abc@def.gh>" will become @headers.message_id with the
135
+ # value '<abc@def.gh>'.
136
+ def set_header(line)
137
+ name, value = line.scan(/^(.*)?: (.*)$/).flatten
138
+ key = name.strip.gsub(/[^\w]/, '_').downcase
139
+ @headers.add_pair(key, value)
140
+ @headers
141
+ end
142
+
143
+ # Creates an Net::NNTP::Article from a HEAD, BODY or ARTICLE result
144
+ #
145
+ # Takes the full result (including response line and stop marker ".")
146
+ # and creates a Net::NNTP::Article instance with the headers in @headers and
147
+ # the body in @body.
148
+ def self.parse(lines)
149
+ responsecode = lines[0][0..2]
150
+ do_header = responsecode == '221'
151
+ do_body = responsecode == '222'
152
+ if responsecode == '220'
153
+ do_header = do_body = true
154
+ end
155
+ article = Net::NNTP::Article.new
156
+ count = 0
157
+ lines.each do |line|
158
+ count += 1
159
+ next if count == 1
160
+ break if line =~ /^.$/
161
+ do_header = (do_header && line !~ /^$/)
162
+ next if line =~ /^$/
163
+ if do_header
164
+ article.set_header(line)
165
+ else
166
+ if do_body
167
+ article.body << line
168
+ end
169
+ end
170
+ end
171
+ article
172
+ end
173
+
174
+ end # class Net::NNTP::Article
175
+ end
176
+ end
@@ -13,6 +13,9 @@ module Net
13
13
  @article_first = @article_last = @article_count = nil
14
14
  end
15
15
 
16
+ # Set article_count, article_first, article_last (from GROUP command)
17
+ #
18
+ # Takes an array [count, first, last] as argument
16
19
  def article_info=(art_array)
17
20
  @article_count = art_array[0].to_i
18
21
  @article_first = art_array[1].to_i
@@ -27,6 +30,7 @@ module Net
27
30
  @articles = articles
28
31
  end
29
32
 
33
+ # Sets hi and lo watermark alont with postingmode (from LIST ACTIVE command)
30
34
  def listinfo(hi, lo, postingmode)
31
35
  @hi = hi
32
36
  @lo = lo
@@ -45,6 +49,7 @@ module Net
45
49
  @articles ||=[]
46
50
  end
47
51
 
52
+ # Stores articles in group attribute, using Net::NNTP::Article instances
48
53
  def build_from_over(over, format)
49
54
  article = Article.new
50
55
  article.overview_format = format
@@ -60,6 +65,8 @@ module Net
60
65
  @articles << article
61
66
  end
62
67
 
68
+ # Creates one Net::NNTP::Article instance, sets the group attribute to the
69
+ # including group instances and adds the article to articles before returning it
63
70
  def create
64
71
  a = Article.new
65
72
  a.group = self.group
@@ -1,5 +1,5 @@
1
1
  module Net
2
- class NNTP
3
- VERSION = "0.0.9"
4
- end
2
+ class NNTP
3
+ VERSION = "0.1.0"
4
+ end
5
5
  end
@@ -4,18 +4,18 @@ require 'net/nntp.rb'
4
4
  require 'mock/mock_socket'
5
5
 
6
6
 
7
+ unless defined? log
8
+ log = Log4r::Logger.new('net::nntp')
9
+ fileout = Log4r::FileOutputter.new('net::nntp::fileout', :filename => File.join('logs', 'autotest.log'), :trunc => true)
10
+ fileout.formatter = Log4r::PatternFormatter.new(:pattern => '%d [%5l] : %m')
11
+ log.add fileout
12
+ log.level = Log4r::ALL
13
+ end
7
14
 
8
15
  module TestNet
9
16
  class TestNNTP < Test::Unit::TestCase
10
17
 
11
18
  def setup
12
- unless @log
13
- @log = Log4r::Logger.new('net::nntp')
14
- fileout = Log4r::FileOutputter.new('net::nntp::fileout', :filename => File.join('logs', 'autotest.log'))
15
- fileout.formatter = Log4r::PatternFormatter.new(:pattern => '%d [%5l] : %m')
16
- @log.add fileout
17
- @log.level = Log4r::ALL
18
- end
19
19
  nntp_connect_and_auth('localhost', 119, 'dummy', 'test')
20
20
  end
21
21
 
@@ -105,7 +105,7 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
105
105
  when /^list\b\s*(.*)\r\n$/
106
106
  case $1
107
107
  when /overview.fmt/i
108
- @io = ["215 Order of fields in overview database.\r\nSubject:\r\nFrom:\r\nDate:\r\nMessage-ID:\r\nReferences:\r\nBytes:\r\nLines:\r\nXref:full\r\n.\r\n" ]
108
+ @io = ["215 Order of fields in overview database.\r\n", "Subject:\r\n", "From:\r\n", "Date:\r\n", "Message-ID:\r\n", "References:\r\n", "Bytes:\r\n", "Lines:\r\n", "Xref:full\r\n", ".\r\n" ]
109
109
  when /active\s*(.*)/
110
110
  @io = ["215 Newsgroups in form \"group high low flags\".", "at.test 200 100 y\r\n", "at.linux 100 90 n\r\n", ".\r\n"]
111
111
  when /^\s*$/
@@ -186,10 +186,10 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
186
186
  "1374\r\n",
187
187
  "1375\r\n",
188
188
  ".\r\n"
189
- ]
190
- else
191
- if @group_selected
192
- @io = [
189
+ ]
190
+ else
191
+ if @group_selected
192
+ @io = [
193
193
  "211 Article list for at.linux follows\r\n",
194
194
  "1363\r\n",
195
195
  "1364\r\n",
@@ -205,31 +205,31 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
205
205
  "1374\r\n",
206
206
  "1375\r\n",
207
207
  ".\r\n"
208
- ]
208
+ ]
209
+ else
210
+ @io = ['412 No Group selected']
211
+ end
212
+ end
213
+ when "quit\r\n" then
214
+ @io = ["200 Good bye"]
215
+ when "authinfo user dummy\r\n"
216
+ @io = ["381 More authentication details needed"]
217
+ when "authinfo pass test\r\n"
218
+ @io = ["281 Welcome to dummytest"]
219
+ when /^group\s+(.+)\s*\r\n$/
220
+ case $1
221
+ when 'at.linux'
222
+ @io = ["211 12 1363 1375 at.linux"]
223
+ @group_selected = 'at.linux'
209
224
  else
210
- @io = ['412 No Group selected']
225
+ @io = ["411 No such group"]
211
226
  end
212
- end
213
- when "quit\r\n" then
214
- @io = ["200 Good bye"]
215
- when "authinfo user dummy\r\n"
216
- @io = ["381 More authentication details needed"]
217
- when "authinfo pass test\r\n"
218
- @io = ["281 Welcome to dummytest"]
219
- when /^group\s+(.+)\s*\r\n$/
220
- case $1
221
- when 'at.linux'
222
- @io = ["211 12 1363 1375 at.linux"]
223
- @group_selected = 'at.linux'
224
- else
225
- @io = ["411 No such group"]
226
- end
227
- when "xhdr subject <slrnf26akq.ci5.hjp-usenet2@zeno.hjp.at>\r\n"
228
- @io =
229
- ["1375 Re: Bitte um Meinungen ==> Virtualisierung\r\n"]
230
- when "xhdr subject 1363-1375\r\n"
231
- if @group_selected
232
- @io = [
227
+ when "xhdr subject <slrnf26akq.ci5.hjp-usenet2@zeno.hjp.at>\r\n"
228
+ @io =
229
+ ["1375 Re: Bitte um Meinungen ==> Virtualisierung\r\n"]
230
+ when "xhdr subject 1363-1375\r\n"
231
+ if @group_selected
232
+ @io = [
233
233
  "221 Subject header (from overview) for postings 1363-1375\r\n",
234
234
  "1363 Re: Bitte um Meinungen ==> Virtualisierung\r\n",
235
235
  "1364 Re: Bitte um Meinungen ==> Virtualisierung\r\n",
@@ -245,11 +245,11 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
245
245
  "1374 Re: Bitte um Meinungen ==> Virtualisierung\r\n",
246
246
  "1375 Re: Bitte um Meinungen ==> Virtualisierung\r\n",
247
247
  ".\r\n"
248
- ]
249
- else
250
- @io = ['412 No group selected']
251
- end
252
- when "xover 1363-1375\r\n"
248
+ ]
249
+ else
250
+ @io = ['412 No group selected']
251
+ end
252
+ when "xover 1363-1375\r\n"
253
253
  if @group_selected
254
254
  @io = [
255
255
  "224 Overview information for postings 1363-1375:\r\n",
@@ -267,9 +267,9 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
267
267
  "1374 Re: Bitte um Meinungen ==> Virtualisierung Andreas Labres <al-nospam0310&bounce@labres.at> Mon, 16 Apr 2007 08:57:43 +0200 <1tnru1ccirb05.dlg@al.lab.at> <4621dbb8$0$2310$91cee783@newsreader01.highway.telekom.at> <dh49f4-qem.ln1@this.is.a.news.server.you.goddamn.stupid.program> <slrnf23snh.dfm.hjp-usenet2@zeno.hjp.at> <4621ff58$0$2307$91cee783@newsreader01.highway.telekom.at> 1702 19 Xref: sensor.twincode.net at.linux:1374\r\n",
268
268
  "1375 Re: Bitte um Meinungen ==> Virtualisierung \"Peter J. Holzer\" <hjp-usenet2@hjp.at> Mon, 16 Apr 2007 09:49:46 +0200 <slrnf26akq.ci5.hjp-usenet2@zeno.hjp.at> <4621dbb8$0$2310$91cee783@newsreader01.highway.telekom.at> <dh49f4-qem.ln1@this.is.a.news.server.you.goddamn.stupid.program> <slrnf23snh.dfm.hjp-usenet2@zeno.hjp.at> <4621ff58$0$2307$91cee783@newsreader01.highway.telekom.at> <1tnru1ccirb05.dlg@al.lab.at> 2127 33 Xref: sensor.twincode.net at.linux:1375\r\n",
269
269
  ".\r\n"
270
- ]
271
- else
272
- @io = ["412 No Group selected"]
270
+ ]
271
+ else
272
+ @io = ["412 No Group selected"]
273
273
  end
274
274
  when /xover \<.+\>/
275
275
  @io = ["502 Usage: OVER first[-[last]]"]
@@ -300,11 +300,11 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
300
300
  "X-Complaints-To: usenet-abuse@arcor.de\r\n",
301
301
  "Xref: sensor.twincode.net at.linux:1430\r\n",
302
302
  ".\r\n"
303
- ]
303
+ ]
304
304
 
305
305
  when /^\s?$/
306
- if @group_selected
307
- @io = [
306
+ if @group_selected
307
+ @io = [
308
308
  "221 1430 <462dfa6f$0$23135$9b4e6d93@newsspool1.arcor-online.net> article retrieved - head follows\r\n",
309
309
  "Path: vietwist00.chello.at!newsfeed02.chello.at!newsfeed01.chello.at!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail\r\n",
310
310
  "Message-ID: <462dfa6f$0$23135$9b4e6d93@newsspool1.arcor-online.net>\r\n",
@@ -326,18 +326,18 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
326
326
  "X-Complaints-To: usenet-abuse@arcor.de\r\n",
327
327
  "Xref: sensor.twincode.net at.linux:1430\r\n",
328
328
  ".\r\n"
329
- ]
330
- else
331
- @io = ["412 No Group selected"]
332
- end
329
+ ]
330
+ else
331
+ @io = ["412 No Group selected"]
332
+ end
333
333
  else
334
334
  @io = ["501 Bad Command"]
335
335
  end
336
- else
337
- @io = ["500 Unknown Command"]
338
- end
339
- return str.length
336
+ else
337
+ @io = ["500 Unknown Command"]
340
338
  end
339
+ return str.length
340
+ end
341
341
 
342
342
  def readline
343
343
  super
@@ -349,4 +349,4 @@ class MockSocket < Test::Unit::MockObject( TCPSocket )
349
349
  $stdout.puts x
350
350
  end
351
351
 
352
- end
352
+ end
@@ -1,6 +1,3 @@
1
- require 'test/unit'
2
- require 'net/nntp.rb'
3
-
4
1
  class TestNNTPArticle < Test::Unit::TestCase
5
2
 
6
3
  def setup
@@ -12,9 +9,9 @@ class TestNNTPArticle < Test::Unit::TestCase
12
9
  a = Net::NNTP::Article.new
13
10
  end
14
11
 
15
- def test_article_id
16
- @article.id = 1
17
- assert_equal 1, @article.id
12
+ def test_article_number
13
+ @article.number = 1
14
+ assert_equal 1, @article.number
18
15
  end
19
16
 
20
17
  def test_article_messageid
@@ -32,7 +29,7 @@ class TestNNTPArticle < Test::Unit::TestCase
32
29
  def test_from_xover
33
30
  over = "1\tTesting\t\"abc\" abc@ide.invalid\t17 Aug 2004 14:00:00 GMT\t<this.post@is.invalid>\t\t200\t2\tXref: this.host.invalid alt.test:1"
34
31
  @article.overview(over)
35
- assert_equal '1', @article.id
32
+ assert_equal '1', @article.number
36
33
  assert_equal '<this.post@is.invalid>', @article.messageid
37
34
  assert_equal 'Testing', @article.subject
38
35
  assert_equal 200, @article.bytes.to_i
@@ -41,8 +38,8 @@ class TestNNTPArticle < Test::Unit::TestCase
41
38
  end
42
39
 
43
40
  def test_overview_fmt=
44
-
45
41
  @article.overview_format = "215 Order of fields in overview database.\r\nSubject:\r\nFrom:\r\nDate:\r\nMessage-ID:\r\nReferences:\r\nBytes:\r\nLines:\r\nXref:full\r\n.\r\n"
42
+ assert_equal 'number', @article.overview_format[0]
46
43
  assert_equal 'subject', @article.overview_format[1]
47
44
  assert_equal 'from', @article.overview_format[2]
48
45
  assert_equal 'date', @article.overview_format[3]
@@ -53,4 +50,41 @@ class TestNNTPArticle < Test::Unit::TestCase
53
50
  assert_equal 'xref', @article.overview_format[8]
54
51
  end
55
52
 
53
+ def test_set_header
54
+ @article.set_header('Subject: Test')
55
+ assert_equal 'Test', @article.headers.subject
56
+ @article.set_header('Message-ID: <this.post@is.invalid>')
57
+ assert_equal '<this.post@is.invalid>', @article.headers.message_id
58
+ end
59
+
60
+ def test_parse
61
+ article = Net::NNTP::Article.parse(["220 1 article retrieved - text follows",
62
+ "Date: 17 Aug 2004 14:00:00 GMT",
63
+ "From: \"abc\" abc@ide.invalid",
64
+ "Message-ID: <this.post@is.invalid>",
65
+ "Subject: ignore test",
66
+ "",
67
+ "test please ignore",
68
+ "test ",
69
+ "."])
70
+ assert_equal '17 Aug 2004 14:00:00 GMT', article.headers.date
71
+ assert_equal '"abc" abc@ide.invalid', article.headers.from
72
+ assert_equal '<this.post@is.invalid>', article.headers.message_id
73
+ assert_equal 'ignore test', article.headers.subject
74
+ assert_equal 2, article.body.size
75
+ assert_equal 'test please ignore', article.body[0]
76
+ assert_equal 'test ', article.body[1]
77
+ article = Net::NNTP::Article.parse(["221 1 article retrieved - head follows", "Date: 17 Aug 2004 14:00:00 GMT", "From: \"abc\" abc@ide.invalid",
78
+ "Message-ID: <this.post@is.invalid>", "Subject: ignore test", "."])
79
+ assert_equal '17 Aug 2004 14:00:00 GMT', article.headers.date
80
+ assert_equal '"abc" abc@ide.invalid', article.headers.from
81
+ assert_equal '<this.post@is.invalid>', article.headers.message_id
82
+ assert_equal 'ignore test', article.headers.subject
83
+ assert_equal 0, article.body.size
84
+ article = Net::NNTP::Article.parse(["222 1 article retrieved - body follows", "test please ignore", "test ", "."])
85
+ assert_equal 2, article.body.size
86
+ assert_equal 'test please ignore', article.body[0]
87
+ assert_equal 'test ', article.body[1]
88
+ end
89
+
56
90
  end
@@ -56,5 +56,5 @@ class TestNNTPGroup< Test::Unit::TestCase
56
56
  assert_kind_of String, @group.inspect
57
57
  end
58
58
 
59
-
59
+
60
60
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
2
+ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby-net-nntp
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.9
7
- date: 2007-07-02 00:00:00 +02:00
6
+ version: 0.1.0
7
+ date: 2007-07-14 00:00:00 +02:00
8
8
  summary: Net::XXX style NNTP Library for easy access.
9
9
  require_paths:
10
10
  - lib
@@ -31,9 +31,9 @@ authors:
31
31
  files:
32
32
  - lib/net
33
33
  - lib/net/nntp
34
+ - lib/net/nntp/article.rb
35
+ - lib/net/nntp/group.rb
34
36
  - lib/net/nntp/version.rb
35
- - lib/net/nntp_article.rb
36
- - lib/net/nntp_group.rb
37
37
  - lib/net/nntp.rb
38
38
  - test/functional
39
39
  - test/functional/test_nntp.rb
@@ -42,6 +42,7 @@ files:
42
42
  - test/unit
43
43
  - test/unit/test_nntp_article.rb
44
44
  - test/unit/test_nntp_group.rb
45
+ - test/logs
45
46
  - README
46
47
  - CHANGELOG
47
48
  - MIT-LICENSE
@@ -53,6 +54,7 @@ test_files:
53
54
  - test/unit
54
55
  - test/unit/test_nntp_article.rb
55
56
  - test/unit/test_nntp_group.rb
57
+ - test/logs
56
58
  rdoc_options:
57
59
  - -S
58
60
  - -N
@@ -1,28 +0,0 @@
1
- module Net
2
- class NNTP
3
- class Article
4
- attr_accessor :id, :messageid, :subject, :group
5
- attr_reader :overview_format, :bytes, :lines, :xref, :date, :from
6
-
7
- def initialize
8
- @overview_format = %w{id}
9
- end
10
-
11
- def overview_format=(format)
12
- if Array === format
13
- @overview_format = format
14
- else
15
- @overview_format = Net::NNTP.parse_overview_format format
16
- end
17
- end
18
-
19
- def overview(over)
20
- over.split(/\t/).each_with_index do |value, index|
21
- ident = @overview_format[index]
22
- eval "@#{ident} = value;"
23
- end
24
- end
25
-
26
- end
27
- end
28
- end