2002-04-28 16:29:56 +00:00
|
|
|
#!/usr/local/bin/ruby
|
|
|
|
|
|
|
|
|
|
# $Id$
|
|
|
|
|
# $Source$
|
|
|
|
|
|
2002-04-28 22:06:03 +00:00
|
|
|
require 'set/intspan'
|
2002-04-28 16:29:56 +00:00
|
|
|
require 'net/nntp'
|
2002-05-05 20:07:03 +00:00
|
|
|
require 'news/newsrc'
|
2002-05-01 22:16:01 +00:00
|
|
|
require 'tempfile'
|
2002-04-28 16:29:56 +00:00
|
|
|
|
|
|
|
|
class Article
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
Debuglevel = 1
|
2002-04-28 16:29:56 +00:00
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def initialize(nntpservers, groupname, newsrc="~/.newsrc")
|
2002-04-28 22:06:03 +00:00
|
|
|
@messids = []
|
2002-04-28 16:29:56 +00:00
|
|
|
@ids = []
|
2002-05-05 20:07:03 +00:00
|
|
|
@servers = []
|
2002-04-28 16:29:56 +00:00
|
|
|
@subjects = []
|
2002-05-05 20:07:03 +00:00
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
@sorted = false
|
|
|
|
|
@grouped = false
|
2002-05-05 20:07:03 +00:00
|
|
|
#@skip_ids = Set::IntSpan.new()
|
2002-04-28 22:06:03 +00:00
|
|
|
@groups = {}
|
2002-05-05 20:07:03 +00:00
|
|
|
@gotten = {}
|
|
|
|
|
@group = groupname
|
|
|
|
|
|
|
|
|
|
@serverlist = nntpservers.split('|')
|
|
|
|
|
@connections = {}
|
|
|
|
|
@serverlist.collect{|server|
|
|
|
|
|
@connections[server] = {}
|
|
|
|
|
@connections[server]["nntp"] = Net::NNTP.new(server)
|
|
|
|
|
@connections[server]["skip_ids"] = Set::IntSpan.new()
|
|
|
|
|
@connections[server]["newsrc"] = News::Newsrc.new("#{newsrc}.#{server}")
|
|
|
|
|
set_skip_ids(server, @connections[server]["newsrc"].marked_articles(@group))
|
|
|
|
|
}
|
|
|
|
|
#@nntp = Net::NNTP.new(nntpservers)
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def add(messid, id, server, subject)
|
|
|
|
|
# print "Messid: #{messid}\n"
|
|
|
|
|
# print "Id: #{id}\n"
|
|
|
|
|
# print "Server: #{server}\n"
|
|
|
|
|
# print "Subject: #{subject}\n"
|
2002-04-28 22:06:03 +00:00
|
|
|
@messids += [messid]
|
|
|
|
|
@ids += [id.to_i]
|
2002-05-05 20:07:03 +00:00
|
|
|
@servers += [server]
|
2002-04-28 16:29:56 +00:00
|
|
|
@subjects += [subject]
|
|
|
|
|
@sorted = false
|
|
|
|
|
@grouped = false
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def get_articles(cachedir=false)
|
|
|
|
|
for server in @connections.keys
|
2002-04-28 16:29:56 +00:00
|
|
|
begin
|
2002-05-05 20:07:03 +00:00
|
|
|
resp, count, first, last, name = @connections[server]["nntp"].group(@group)
|
|
|
|
|
@connections[server]["first"] = first ? first : 0
|
|
|
|
|
@connections[server]["last"] = last ? last : 0
|
|
|
|
|
rescue Net::NNTP::RuntimeError
|
|
|
|
|
print "Couldn't open group: #{@group}\n"
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
read_cache(cachedir)
|
|
|
|
|
for server in @connections.keys
|
|
|
|
|
print "reading articles from server: #{server}\n"
|
|
|
|
|
range = Set::IntSpan.new("#{@connections[server]["first"]}-#{@connections[server]["last"]}")
|
2002-05-07 11:48:18 +00:00
|
|
|
rangelist = rechunk_runlist(range.diff(@connections[server]["skip_ids"]).run_list)
|
2002-05-07 13:46:17 +00:00
|
|
|
print "rangelist: #{rangelist}\n" if Debuglevel >1
|
2002-05-05 20:07:03 +00:00
|
|
|
print "rangelist: #{rangelist.type.to_s}\n" if Debuglevel >1
|
|
|
|
|
print "rangelsit elements: #{range.diff(@connections[server]["skip_ids"]).elements}\n" if Debuglevel >1
|
|
|
|
|
unless rangelist == nil or rangelist =~ /^$/
|
|
|
|
|
for i in rangelist.split(',')
|
|
|
|
|
print "i: #{i}\n" if Debuglevel > 1
|
|
|
|
|
begin
|
|
|
|
|
resp, subj_lines = @connections[server]["nntp"].xhdr("subject", i)
|
|
|
|
|
unless resp.to_i >= 200 and resp.to_i < 300
|
|
|
|
|
print "got response #{resp} while reading group #{@group} from #{server}\n"
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
resp, messid_lines = @connections[server]["nntp"].xhdr("message-id", i)
|
|
|
|
|
unless resp.to_i >=200 and resp.to_i < 300
|
|
|
|
|
print "got response #{resp} while reading group #{@group} from #{server}\n"
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
art = {}
|
|
|
|
|
subj_lines.collect{|x|
|
|
|
|
|
art[x[0]] = {} unless art.has_key?(x[0])
|
|
|
|
|
art[x[0]]["subject"] = x[1]
|
|
|
|
|
print "art id: #{x[0]} subj: #{x[1]}\n" if Debuglevel > 1
|
|
|
|
|
}
|
|
|
|
|
messid_lines.collect{|x|
|
|
|
|
|
art[x[0]] = {} unless art.has_key?(x[0])
|
|
|
|
|
art[x[0]]["messid"] = x[1]
|
|
|
|
|
print "art id: #{x[0]} messid: #{x[1]}\n" if Debuglevel > 1
|
|
|
|
|
}
|
|
|
|
|
for id in art.keys
|
|
|
|
|
if art[id].has_key?("subject") and art[id].has_key?("messid")
|
|
|
|
|
print "adding: #{art[id]["messid"]}, #{id}, #{server}, #{art[id]["subject"]}\n" if Debuglevel > 1
|
|
|
|
|
add(art[id]["messid"], id, server, art[id]["subject"])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
rescue Net::NNTP::RuntimeError
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2002-05-05 20:07:03 +00:00
|
|
|
|
|
|
|
|
# if xhdr doesn't work, this should be used
|
|
|
|
|
# for i in (range.diff(@connections[server]["skip_ids"]).elements)
|
|
|
|
|
# begin
|
|
|
|
|
# @connections[server]["nntp"].stat(i)
|
|
|
|
|
# resp, id, messid, list = @connections[server]["nntp"].head(i)
|
|
|
|
|
# for j in list
|
|
|
|
|
# if j =~ /Subject: (.*)/
|
|
|
|
|
# subj=$1
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
# print "get_articles messid: #{messid}\n" if Debuglevel > 1
|
|
|
|
|
# print "get_articles id: #{id}\n" if Debuglevel > 1
|
|
|
|
|
# print "get_articles server: #{server}\n" if Debuglevel > 1
|
|
|
|
|
# print "get_articles subject: #{subj}\n" if Debuglevel > 1
|
|
|
|
|
# add(messid, id, server, subj)
|
|
|
|
|
# rescue Net::NNTP::RuntimeError
|
|
|
|
|
# print "whoopsie couldn't stat #{i}\n" if Debuglevel > 1
|
|
|
|
|
# end
|
|
|
|
|
# end
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
2002-05-05 20:07:03 +00:00
|
|
|
save_cache(cachedir)
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_groups
|
|
|
|
|
group_subjects unless @grouped
|
2002-04-28 22:06:03 +00:00
|
|
|
return @groups
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
2002-05-06 11:46:56 +00:00
|
|
|
def get_groupname
|
|
|
|
|
return @group
|
|
|
|
|
end
|
|
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
def get_group_body(subj)
|
|
|
|
|
result = []
|
2002-05-06 11:46:56 +00:00
|
|
|
group_subject_sort(subj)
|
2002-05-05 20:07:03 +00:00
|
|
|
for i in (0...@groups[subj]["messages"].length)
|
|
|
|
|
unless @gotten.has_key?(@groups[subj]["messages"][i])
|
|
|
|
|
print "getting article: #{i}\n" if Debuglevel > 0
|
|
|
|
|
begin
|
|
|
|
|
print "Server: #{@groups[subj]["servers"][i]}\n"
|
|
|
|
|
print "Messid: #{@groups[subj]["messages"][i]}\n"
|
|
|
|
|
resp, id, messid, list = @connections[@groups[subj]["servers"][i]]["nntp"].body(@groups[subj]["messages"][i])
|
|
|
|
|
rescue Net::NNTPReplyError
|
2002-05-07 07:45:00 +00:00
|
|
|
print "Caught Net::NNTPReplyError in get_group_body reading article #{@groups[subj]["messages"][0]}\n"
|
2002-05-05 20:07:03 +00:00
|
|
|
end
|
|
|
|
|
result = list
|
2002-04-30 21:11:53 +00:00
|
|
|
end
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
return result
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_group_body_first(subj)
|
2002-05-06 11:46:56 +00:00
|
|
|
group_subject_sort(subj)
|
2002-04-30 15:33:13 +00:00
|
|
|
begin
|
2002-05-05 20:07:03 +00:00
|
|
|
resp, id, messid, list = @connections[@groups[subj]["servers"][0]]["nntp"].body(@groups[subj]["messages"][0])
|
2002-04-30 15:33:13 +00:00
|
|
|
rescue Net::NNTPReplyError
|
2002-05-07 07:45:00 +00:00
|
|
|
print "Caught Net::NNTPReplyError in get_group_body_first reading article #{@groups[subj]["messages"][0]}\n"
|
2002-04-30 15:33:13 +00:00
|
|
|
return false
|
|
|
|
|
end
|
2002-05-05 20:07:03 +00:00
|
|
|
print "getting article: #{subj}\n" if Debuglevel > 0
|
|
|
|
|
print "message id: #{messid}\n" if Debuglevel > 0
|
|
|
|
|
print "id: #{id}\n" if Debuglevel > 0
|
|
|
|
|
print "server: #{@groups[subj]["servers"][0]}\n" if Debuglevel > 0
|
|
|
|
|
print "full subject: #{@groups[subj]["subject"][0]}\n" if Debuglevel > 0
|
|
|
|
|
@gotten[messid] = true
|
2002-04-28 16:29:56 +00:00
|
|
|
return list
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_group_body_rest(subj, file=nil)
|
|
|
|
|
result = []
|
2002-05-05 20:07:03 +00:00
|
|
|
for i in (1...@groups[subj]["messages"].length)
|
|
|
|
|
unless @gotten.has_key?(@groups[subj]["messages"][i])
|
|
|
|
|
print "getting article: #{i}\n" if Debuglevel > 0
|
|
|
|
|
begin
|
|
|
|
|
print "Server: #{@groups[subj]["servers"][i]}\n"
|
|
|
|
|
print "Messid: #{@groups[subj]["messages"][i]}\n"
|
|
|
|
|
resp, id, messid, list = @connections[@groups[subj]["servers"][i]]["nntp"].body(@groups[subj]["messages"][i])
|
2002-05-05 22:18:44 +00:00
|
|
|
if resp == false
|
|
|
|
|
return false
|
|
|
|
|
end
|
2002-05-05 20:07:03 +00:00
|
|
|
rescue Net::NNTPReplyError
|
2002-05-07 07:45:00 +00:00
|
|
|
print "Caught Net::NNTPReplyError in get_group_body_rest reading article #{@groups[subj]["messages"][0]}\n"
|
2002-05-05 20:07:03 +00:00
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
print "getting article: #{subj}\n" if Debuglevel > 0
|
|
|
|
|
print "message id: #{messid}\n" if Debuglevel > 0
|
|
|
|
|
print "id: #{id}\n" if Debuglevel > 0
|
|
|
|
|
print "server: #{@groups[subj]["servers"][i]}\n" if Debuglevel > 0
|
|
|
|
|
print "full subject: #{@groups[subj]["subject"][i]}\n" if Debuglevel > 0
|
|
|
|
|
@gotten[ @groups[subj]["messages"][i] ] = true
|
2002-05-06 11:46:56 +00:00
|
|
|
if file
|
|
|
|
|
list.collect{|line| file.print "#{line}\n"}
|
|
|
|
|
else
|
|
|
|
|
result += list
|
|
|
|
|
end
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return result
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_group_subjects
|
|
|
|
|
group_subjects unless @grouped
|
2002-04-28 22:06:03 +00:00
|
|
|
return @groups.keys
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def get_group_messids(subject)
|
2002-04-28 22:06:03 +00:00
|
|
|
group_subjects unless @grouped
|
2002-05-05 20:07:03 +00:00
|
|
|
return @groups[subject]["messages"]
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def group_is_complete(subj)
|
2002-04-28 16:29:56 +00:00
|
|
|
group_subjects unless @grouped
|
2002-04-28 22:06:03 +00:00
|
|
|
print "length: #{@groups[subj]["messages"].length} total: #{@groups[subj]["total"].to_i}\n" if Debuglevel > 1
|
2002-05-05 20:07:03 +00:00
|
|
|
umessids = @groups[subj]["messages"].uniq
|
|
|
|
|
if (umessids.length ) >= @groups[subj]["total"].to_i
|
2002-04-28 16:29:56 +00:00
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def group_is_singlepart(subj)
|
2002-05-01 22:16:01 +00:00
|
|
|
@groups[subj]["total"].to_i == 1
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def group_is_multipart(subj)
|
2002-05-01 22:16:01 +00:00
|
|
|
@groups[subj]["total"].to_i > 1
|
|
|
|
|
end
|
|
|
|
|
|
2002-04-28 22:06:03 +00:00
|
|
|
def get_messids
|
|
|
|
|
return @messids
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_subjects
|
|
|
|
|
return @subjects
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def group_subjects
|
2002-04-28 22:06:03 +00:00
|
|
|
@groups = {}
|
2002-05-05 20:07:03 +00:00
|
|
|
for i in (0...@subjects.length)
|
2002-04-28 22:06:03 +00:00
|
|
|
print "group subjects: #{i} #{@subjects[i]}\n" if Debuglevel > 1
|
2002-04-28 16:29:56 +00:00
|
|
|
if @subjects[i] =~ /(.*)\((\d+)\/(\d+)\)(.*)/ || @subjects[i] =~ /(.*)\[(\d+)\/(\d+)\](.*)/
|
|
|
|
|
j = "#{$1}#{$4}"
|
|
|
|
|
number = $2
|
|
|
|
|
total = $3
|
|
|
|
|
else
|
|
|
|
|
j = @subjects[i]
|
|
|
|
|
number = 1
|
|
|
|
|
total = 1
|
|
|
|
|
end
|
2002-05-06 11:46:56 +00:00
|
|
|
if @groups.has_key?(j) and number.to_i !=0
|
2002-04-28 22:06:03 +00:00
|
|
|
@groups[j]["messages"] += [ @messids[i] ]
|
2002-05-05 20:07:03 +00:00
|
|
|
@groups[j]["ids"] += [ @ids[i].to_i ]
|
|
|
|
|
@groups[j]["servers"] += [ @servers[i] ]
|
|
|
|
|
@groups[j]["subject"] += [ @subjects[i] ]
|
2002-05-06 11:46:56 +00:00
|
|
|
elsif number.to_i !=0
|
|
|
|
|
@groups[j] = {}
|
|
|
|
|
@groups[j]["total"] = total
|
|
|
|
|
@groups[j]["messages"] = [ @messids[i] ]
|
|
|
|
|
@groups[j]["ids"] = [ @ids[i].to_i ]
|
|
|
|
|
@groups[j]["servers"] = [ @servers[i] ]
|
|
|
|
|
@groups[j]["subject"] = [ @subjects[i] ]
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
@grouped = true
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def set_skip_ids(server, ids)
|
2002-04-28 22:06:03 +00:00
|
|
|
set = Set::IntSpan.new(ids)
|
|
|
|
|
set.finite or return false
|
|
|
|
|
min = set.min
|
|
|
|
|
min != nil and min < 0 and return false
|
2002-05-05 20:07:03 +00:00
|
|
|
@connections[server]["skip_ids"] = set
|
2002-04-28 22:06:03 +00:00
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def group_update_newsrc(subject)
|
|
|
|
|
for i in (0...@groups[subject]["messages"].length)
|
2002-05-06 11:46:56 +00:00
|
|
|
# print "server: #{@groups[subject]["servers"][i]}\n"
|
|
|
|
|
# print "id: #{@groups[subject]["ids"][i]}\n"
|
2002-05-05 20:07:03 +00:00
|
|
|
@connections[@groups[subject]["servers"][i]]["newsrc"].mark(@group, @groups[subject]["ids"][i])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def save_newsrc()
|
|
|
|
|
for server in @connections.keys
|
|
|
|
|
@connections[server]["newsrc"].save
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def read_cache(cachedir)
|
|
|
|
|
filename = "#{cachedir}/#{@group}.ripnewscache"
|
2002-04-30 14:09:06 +00:00
|
|
|
excludes = {}
|
2002-05-05 20:07:03 +00:00
|
|
|
for server in @connections.keys
|
|
|
|
|
excludes[server] = {}
|
|
|
|
|
@connections[server]["skip_ids"].elements.collect!{|x| excludes[server][x]=true}
|
|
|
|
|
end
|
2002-04-29 21:44:36 +00:00
|
|
|
if FileTest.directory?( cachedir) and FileTest.file?( filename ) and FileTest.readable?( filename )
|
|
|
|
|
file = File.new( filename )
|
|
|
|
|
lines = file.readlines
|
2002-05-05 22:18:44 +00:00
|
|
|
lines.collect{|line|
|
2002-04-29 21:44:36 +00:00
|
|
|
#print "line: #{line}\n"
|
2002-05-07 07:45:00 +00:00
|
|
|
if line =~ /^(\d+)\|(.*?)\|(.*?)\|(.*)$/
|
|
|
|
|
#print "id: #{$1}\n"
|
|
|
|
|
#print "messid: #{$2}\n"
|
2002-05-05 20:07:03 +00:00
|
|
|
#print "server: #{$3}\n"
|
|
|
|
|
#print "subject: #{$4}\n"
|
|
|
|
|
#print "First: #{@connections[$3]["first"].to_i}\n";
|
|
|
|
|
#print "Last: #{@connections[$3]["last"].to_i}\n";
|
|
|
|
|
if @connections.has_key?($3)
|
2002-05-07 07:45:00 +00:00
|
|
|
unless excludes.has_key?($3) and excludes[$3].has_key?($1.to_i) or
|
|
|
|
|
$1.to_i < @connections[$3]["first"].to_i or
|
|
|
|
|
$1.to_i > @connections[$3]["last"].to_i
|
|
|
|
|
add($2, $1, $3, $4)
|
|
|
|
|
@connections[$3]["skip_ids"].insert($1.to_i)
|
2002-05-05 22:18:44 +00:00
|
|
|
end
|
2002-04-30 14:09:06 +00:00
|
|
|
end
|
2002-04-29 21:44:36 +00:00
|
|
|
end
|
2002-05-05 22:18:44 +00:00
|
|
|
}
|
2002-05-07 07:45:00 +00:00
|
|
|
file.close
|
2002-04-29 21:44:36 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-05 20:07:03 +00:00
|
|
|
def save_cache(cachedir)
|
|
|
|
|
filename = "#{cachedir}/#{@group}.ripnewscache"
|
2002-04-30 14:09:06 +00:00
|
|
|
if FileTest.directory?( cachedir )
|
2002-04-29 21:44:36 +00:00
|
|
|
file = File.new( filename, "w" ) or print "couldn't open cachefile for writing\n"
|
2002-05-07 07:45:00 +00:00
|
|
|
cache = []
|
2002-04-29 21:44:36 +00:00
|
|
|
for i in (0...@subjects.length)
|
2002-05-07 07:45:00 +00:00
|
|
|
cache += ["#{@ids[i]}|#{@messids[i]}|#{@servers[i]}|#{@subjects[i]}\n"]
|
2002-04-29 21:44:36 +00:00
|
|
|
end
|
2002-05-07 07:45:00 +00:00
|
|
|
cache.sort!
|
|
|
|
|
file.print cache
|
|
|
|
|
file.close
|
2002-04-29 21:44:36 +00:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
def uudecode(data, outfile=nil)
|
|
|
|
|
case data.type.to_s
|
|
|
|
|
when "Array"
|
|
|
|
|
print "Calling _uudecode_array\n" if Debuglevel>0
|
|
|
|
|
mode, file, body = _uudecode_array(data)
|
2002-05-05 20:07:03 +00:00
|
|
|
when "File", "Tempfile"
|
2002-04-28 16:29:56 +00:00
|
|
|
unless outfile
|
|
|
|
|
print "uudecode: need outfile\n"
|
|
|
|
|
exit
|
|
|
|
|
end
|
|
|
|
|
print "Calling _uudecode_file\n" if Debuglevel>0
|
|
|
|
|
mode, file, body = _uudecode_file(data, outfile)
|
2002-05-05 20:07:03 +00:00
|
|
|
else
|
|
|
|
|
print "Funny stuff in uudecode. Data of type \"#{data.type.to_s}\"\n"
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
return mode, file, body
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def _uudecode_file(file, outfile)
|
|
|
|
|
mode = 0600
|
|
|
|
|
filename = "unknown"
|
|
|
|
|
c = 0
|
|
|
|
|
lines = file.pos
|
|
|
|
|
percent = 0
|
|
|
|
|
mark = lines/100
|
|
|
|
|
file.pos=0
|
|
|
|
|
|
|
|
|
|
while (! file.eof)
|
|
|
|
|
line = file.gets
|
|
|
|
|
print "line: #{line}" if Debuglevel > 0
|
|
|
|
|
if line =~ /^begin(.*)/
|
|
|
|
|
m = $1
|
2002-04-30 21:11:53 +00:00
|
|
|
print "beginning matched; rest: #{m}\n" if Debuglevel > 0
|
2002-04-28 16:29:56 +00:00
|
|
|
if m =~ /^(\s+(\d+))?(\s+(.*?\S))?\s*\Z/
|
|
|
|
|
mode = $2
|
|
|
|
|
filename = $4
|
|
|
|
|
print "found beginning\n" if Debuglevel > 0
|
|
|
|
|
else
|
|
|
|
|
print "mode, file set to defaults: #{m}\n"
|
|
|
|
|
end
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "not uuencoded!\n" if file.eof
|
|
|
|
|
print "c: #{c} mark: #{mark} lines: #{lines}\n" if Debuglevel > 1
|
|
|
|
|
|
2002-04-30 21:11:53 +00:00
|
|
|
print " UUdecoding...\n"
|
2002-04-28 16:29:56 +00:00
|
|
|
|
|
|
|
|
while (! file.eof)
|
|
|
|
|
if Debuglevel > 1
|
|
|
|
|
c = file.pos
|
|
|
|
|
if c > mark
|
|
|
|
|
print "#{percent}%\n"
|
|
|
|
|
print "c: #{c} mark: #{mark} lines: #{lines}\n" if Debuglevel > 1
|
|
|
|
|
percent += 1
|
|
|
|
|
mark = (lines/100)*(percent+1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
line = file.gets
|
|
|
|
|
print "line: #{line}" if Debuglevel > 1
|
|
|
|
|
return mode, filename if line =~ /^end/
|
|
|
|
|
next if line =~ /[a-z]/
|
|
|
|
|
next if line == nil
|
|
|
|
|
next unless ((((line[0] - 32) & 077) + 2) / 3).to_i ==
|
|
|
|
|
(line.length/4).to_i
|
|
|
|
|
outfile.print line.unpack("u")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "No \"end\" found!!!\n"
|
|
|
|
|
return mode, file, outfile
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# gaat volgens mij niet verder als er meerdere uuencoded blocks zijn...
|
|
|
|
|
# zal dan meerdere keren aangeroepen moeten worden, grmbl...
|
|
|
|
|
# tis getting a mess as we speak...
|
|
|
|
|
# toch maar een keer aparte class van maken...
|
|
|
|
|
def _uudecode_array(data)
|
|
|
|
|
decode = []
|
|
|
|
|
# begun = false
|
|
|
|
|
mode = 0600
|
|
|
|
|
file = "unknown"
|
|
|
|
|
c = 0
|
|
|
|
|
lines = data.length
|
|
|
|
|
percent = 0
|
|
|
|
|
mark = lines/100
|
|
|
|
|
|
|
|
|
|
i = 0
|
|
|
|
|
while (i < data.length)
|
|
|
|
|
if data[i] =~ /^begin(.*)/
|
|
|
|
|
m = $1
|
2002-04-30 21:11:53 +00:00
|
|
|
print "beginning matched; rest: #{m}\n" if Debuglevel > 0
|
2002-04-28 16:29:56 +00:00
|
|
|
if m =~ /^(\s+(\d+))?(\s+(.*?\S))?\s*\Z/
|
|
|
|
|
mode = $2
|
|
|
|
|
file = $4
|
|
|
|
|
print "found beginning\n" if Debuglevel > 0
|
|
|
|
|
else
|
|
|
|
|
print "mode, file set to defaults: #{m}\n"
|
|
|
|
|
end
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
i += 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
unless (i < data.length)
|
|
|
|
|
print "not uuencoded!\n"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "UUdecoding...\n"
|
|
|
|
|
|
|
|
|
|
while (i < data.length)
|
|
|
|
|
if Debuglevel > 1
|
|
|
|
|
if c > mark
|
|
|
|
|
print "#{percent}%\n"
|
|
|
|
|
print "c: #{c} mark: #{mark} lines: #{lines} i: #{i}\n" if Debuglevel > 1
|
|
|
|
|
percent += 1
|
|
|
|
|
mark = (lines/100)*(percent+1)
|
|
|
|
|
end
|
|
|
|
|
c += 1
|
|
|
|
|
end
|
|
|
|
|
line = data[i]
|
|
|
|
|
i += 1
|
|
|
|
|
return mode, file, decode if line =~ /^end/
|
|
|
|
|
next if line =~ /[a-z]/
|
|
|
|
|
next if line == nil
|
|
|
|
|
next unless ((((line[0] - 32) & 077) + 2) / 3).to_i ==
|
|
|
|
|
(line.length/4).to_i
|
|
|
|
|
decode += line.unpack("u")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "No \"end\" found!!!\n"
|
|
|
|
|
return mode, file, decode
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-01 22:16:01 +00:00
|
|
|
#def uudecode_group(subj, file=nil, outfile=nil)
|
|
|
|
|
def uudecode_group(subj, tempdir=nil)
|
2002-04-28 16:29:56 +00:00
|
|
|
group_subjects unless @grouped
|
|
|
|
|
|
|
|
|
|
body = get_group_body_first(subj)
|
|
|
|
|
if body.to_s =~ /begin/
|
|
|
|
|
print "uuencoded!\n" if Debuglevel > 0
|
2002-05-01 22:16:01 +00:00
|
|
|
#if (file and outfile)
|
|
|
|
|
if (tempdir != nil)
|
|
|
|
|
file = Tempfile.new("#{tempdir}/riptmp")
|
|
|
|
|
body.collect{|i| file.print "#{i}\n"}
|
2002-04-28 16:29:56 +00:00
|
|
|
get_group_body_rest(subj, file)
|
|
|
|
|
mode, filename, result = uudecode(file, outfile)
|
|
|
|
|
else
|
|
|
|
|
body += get_group_body_rest(subj)
|
|
|
|
|
mode, filename, result = uudecode(body)
|
|
|
|
|
end
|
|
|
|
|
return mode, filename, result
|
|
|
|
|
else
|
|
|
|
|
print "Not uuencoded!\n" if Debuglevel > 0
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-01 22:16:01 +00:00
|
|
|
def is_uuencoded(data)
|
|
|
|
|
if data.to_s =~ /begin\s+\d+?\s+.*?\S?\s*\Z/
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-06 21:18:45 +00:00
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
|
|
def ydecode(data, outfile=nil)
|
|
|
|
|
case data.type.to_s
|
|
|
|
|
when "Array"
|
|
|
|
|
print "Calling _ydecode_array\n" if Debuglevel>0
|
|
|
|
|
mode, file, body = _ydecode_array(data)
|
|
|
|
|
when "File", "Tempfile"
|
|
|
|
|
unless outfile
|
|
|
|
|
print "ydecode: need outfile\n"
|
|
|
|
|
exit
|
|
|
|
|
end
|
|
|
|
|
print "Calling _ydecode_file\n" if Debuglevel>0
|
|
|
|
|
mode, file, body = _ydecode_file(data, outfile)
|
|
|
|
|
else
|
|
|
|
|
print "Funny stuff in ydecode. Data of type \"#{data.type.to_s}\"\n"
|
|
|
|
|
end
|
|
|
|
|
return mode, file, body
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def _ydecode_file(file, outfile)
|
|
|
|
|
mode = 0600
|
|
|
|
|
filename = "unknown"
|
|
|
|
|
lines = file.pos
|
|
|
|
|
file.pos = 0
|
|
|
|
|
bytes = 0
|
|
|
|
|
total = 0
|
|
|
|
|
|
|
|
|
|
while (! file.eof)
|
|
|
|
|
line = file.gets
|
|
|
|
|
print "line: #{line}" if Debuglevel > 0
|
|
|
|
|
if line =~ /^\=ybegin\s+(.*line\=.*)/
|
|
|
|
|
m = $1
|
|
|
|
|
print "ybegin match; rest: #{m}\n" if Debuglevel > 0
|
|
|
|
|
if m =~ /^\s*(part\=(\d+)\s+)?(line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/
|
|
|
|
|
part = $2.to_i
|
|
|
|
|
linesize = $4.to_i
|
|
|
|
|
totalsize = $6.to_i
|
|
|
|
|
filename = $8
|
|
|
|
|
print "found beginning"
|
|
|
|
|
if part
|
|
|
|
|
print " of part #{part}"
|
|
|
|
|
end
|
|
|
|
|
print ", linesize = #{linesize}, size = #{size}, filename = #{filename}\n"
|
|
|
|
|
break
|
|
|
|
|
else
|
|
|
|
|
print "not a valid yenc begin line\n"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "not yencoded!\n" if file.eof
|
|
|
|
|
|
|
|
|
|
print " ydecoding...\n"
|
|
|
|
|
|
|
|
|
|
while (! file.eof)
|
|
|
|
|
print "at #{file.pos} need to go to #{lines}\n" if Debuglevel > 1
|
|
|
|
|
line = file.gets
|
|
|
|
|
line = line[0 ... line.length - 1]
|
|
|
|
|
|
|
|
|
|
if line =~ /^=yend\s+(.*)\Z/
|
|
|
|
|
m = $1
|
|
|
|
|
m =~ /(\s*size=(\d+)\s+)(\s*part=(\d+))?(\s+crc32=(\S+))?/
|
|
|
|
|
size = $2.to_i
|
|
|
|
|
part = $4.to_i
|
|
|
|
|
crc = $6
|
|
|
|
|
if size != bytes
|
|
|
|
|
print "part size mismatch, is #{bytes}, should be #{size}\n"
|
|
|
|
|
end
|
|
|
|
|
if !part
|
|
|
|
|
return mode, filename
|
|
|
|
|
end
|
|
|
|
|
total += bytes
|
|
|
|
|
if total >= totalsize
|
|
|
|
|
if total != totalsize
|
|
|
|
|
print "total size mismatch, is #{total}, should be #{totalsize}\n"
|
|
|
|
|
end
|
|
|
|
|
return mode, filename
|
|
|
|
|
end
|
|
|
|
|
search_begin = 1
|
|
|
|
|
bytes = 0
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
if search_begin && line =~ /^\=ybegin\s+(.*)\Z/
|
|
|
|
|
m = $1
|
|
|
|
|
search_begin = 0
|
|
|
|
|
if m =~ /^\s*(part\=(\d+)\s+)?(line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/
|
|
|
|
|
part = $2.to_i
|
|
|
|
|
linesize = $4.to_i
|
|
|
|
|
totalsize = $6.to_i
|
|
|
|
|
filename = $8
|
|
|
|
|
print "found beginning of part #{part}, linesize = #{linesize}, size = #{size}, filename = #{filename}\n" if Debuglevel > 0
|
|
|
|
|
end
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
if search_begin == 1
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
if line =~ /^=ypart\s+(\s*begin=(\d+))(\s+end=(\d+))/
|
|
|
|
|
b = $2
|
|
|
|
|
e = $4
|
|
|
|
|
print "next part begin #{b}, end #{e}\n"
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# This seems to be a common 'error' - maybe I misunderstand the spec or
|
|
|
|
|
# something
|
|
|
|
|
# if line.length != linesize
|
|
|
|
|
# print "linesize mismatch, was #{line.length}, should be #{linesize}...\n"
|
|
|
|
|
# end
|
|
|
|
|
special = 0
|
|
|
|
|
line.each_byte { |b|
|
|
|
|
|
if special == 0
|
|
|
|
|
if b == 0x3d
|
|
|
|
|
special = 1
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
special = 0
|
|
|
|
|
b = (b - 64) % 256
|
|
|
|
|
end
|
|
|
|
|
outfile.putc((b - 42) % 256)
|
|
|
|
|
bytes += 1
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "No \"=yend\" found!!!\n"
|
|
|
|
|
return mode, file, outfile
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# toch maar een keer aparte class van maken... geld ook voor dit geneuzel
|
|
|
|
|
def _ydecode_array(data)
|
|
|
|
|
decode = ""
|
|
|
|
|
mode = 0600
|
|
|
|
|
filename = "unknown"
|
|
|
|
|
c = 0
|
|
|
|
|
lines = data.length
|
|
|
|
|
percent = 0
|
|
|
|
|
mark = lines/100
|
|
|
|
|
|
|
|
|
|
i = 0
|
|
|
|
|
while (i < data.length)
|
|
|
|
|
if data[i] =~ /^\=ybegin\s+(.*line\=.*)/
|
|
|
|
|
m = $1
|
|
|
|
|
print "ybegin match; rest: #{m}\n" if Debuglevel > 0
|
|
|
|
|
if m =~ /^(\s*(part\=(\d+)\s+)?line\=(\d+))(\s*size\=(\d+))(\s*name=(.*))\Z/
|
|
|
|
|
linesize = $4.to_i
|
|
|
|
|
size = $6.to_i
|
|
|
|
|
filename = $8
|
|
|
|
|
print "found beginning, linesize = #{linesize}, size = #{size}, filename = #{filename}\n" if Debuglevel > 0
|
|
|
|
|
i += 1
|
|
|
|
|
break
|
|
|
|
|
else
|
|
|
|
|
print "not a valid yenc begin line\n"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
i += 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
unless (i < data.length)
|
|
|
|
|
print "not yencoded!\n"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "ydecoding...\n"
|
|
|
|
|
|
|
|
|
|
while (i < data.length)
|
|
|
|
|
print "at #{i} need to go to #{data.length}\r" if Debuglevel > 1
|
|
|
|
|
line = data[i]
|
|
|
|
|
i += 1
|
|
|
|
|
if line =~ /^\=yend(\s+size=(\d+))(\s+crc32=(\S+))?/
|
|
|
|
|
size = $2.to_i
|
|
|
|
|
crc = $4
|
|
|
|
|
if size != decode.length
|
|
|
|
|
print "size mismatch, was #{decode.length}, should be #{size}\n"
|
|
|
|
|
end
|
|
|
|
|
dec = [ decode ]
|
|
|
|
|
return mode, filename, dec
|
|
|
|
|
end
|
|
|
|
|
if line =~ /^\=ypart.*\Z/
|
|
|
|
|
# ignore for now
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# This seems to be a common 'error' - maybe I misunderstand the spec or
|
|
|
|
|
# something
|
|
|
|
|
# if line.length != linesize
|
|
|
|
|
# print "#{i}: linesize mismatch, was #{line.length}, should be #{linesize}...\n"
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
special = 0
|
|
|
|
|
str = ""
|
|
|
|
|
line.each_byte { |b|
|
|
|
|
|
if special == 0
|
|
|
|
|
if b == 0x3d
|
|
|
|
|
special = 1
|
|
|
|
|
next
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
special = 0
|
|
|
|
|
b = (b - 64) % 256
|
|
|
|
|
end
|
|
|
|
|
str += ((b - 42) % 256).chr
|
|
|
|
|
}
|
|
|
|
|
decode += str
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print "${i}: no \"=yend\" found!!!\n"
|
|
|
|
|
dec = [ decode ]
|
|
|
|
|
return mode, filename, dec
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def ydecode_group(subj, tempdir=nil)
|
|
|
|
|
group_subjects unless @grouped
|
|
|
|
|
|
|
|
|
|
body = get_group_body_first(subj)
|
|
|
|
|
if body.to_s =~ /=ybegin/
|
|
|
|
|
print "yencoded!\n" if Debuglevel > 0
|
|
|
|
|
#if (file and outfile)
|
|
|
|
|
if (tempdir != nil)
|
|
|
|
|
file = Tempfile.new("#{tempdir}/riptmp")
|
|
|
|
|
body.collect{|i| file.print "#{i}\n"}
|
|
|
|
|
get_group_body_rest(subj, file)
|
|
|
|
|
mode, filename, result = ydecode(file, outfile)
|
|
|
|
|
else
|
|
|
|
|
body += get_group_body_rest(subj)
|
|
|
|
|
mode, filename, result = ydecode(body)
|
|
|
|
|
end
|
|
|
|
|
return mode, filename, result
|
|
|
|
|
else
|
|
|
|
|
print "Not yencoded!\n" if Debuglevel > 0
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def is_yencoded(data)
|
|
|
|
|
if data.to_s =~ /=ybegin/
|
|
|
|
|
return true
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
###############################################################
|
|
|
|
|
|
2002-05-06 11:46:56 +00:00
|
|
|
def group_subject_sort(subj)
|
2002-05-07 22:07:17 +00:00
|
|
|
#print "Sorting articles\n"
|
2002-05-07 20:31:05 +00:00
|
|
|
serverhash = {}
|
|
|
|
|
for i in (0...@serverlist.length)
|
|
|
|
|
serverhash[@serverlist[i]] = i
|
|
|
|
|
end
|
2002-05-06 11:46:56 +00:00
|
|
|
sort_arr = []
|
|
|
|
|
for i in (0...@groups[subj]["subject"].length)
|
|
|
|
|
print "subj sort #{@groups[subj]["subject"][i]}\n" if Debuglevel > 2
|
|
|
|
|
print "subj sort #{@groups[subj]["messages"][i]}\n" if Debuglevel > 2
|
|
|
|
|
print "subj sort #{@groups[subj]["ids"][i]}\n" if Debuglevel > 2
|
|
|
|
|
print "subj sort #{@groups[subj]["servers"][i]}\n" if Debuglevel > 2
|
2002-05-07 20:31:05 +00:00
|
|
|
sort_arr += [ [
|
2002-05-07 22:07:17 +00:00
|
|
|
@groups[subj]["subject"][i].dup,
|
|
|
|
|
@groups[subj]["messages"][i].dup,
|
|
|
|
|
@groups[subj]["ids"][i].dup,
|
|
|
|
|
@groups[subj]["servers"][i].dup
|
2002-05-07 20:31:05 +00:00
|
|
|
] ]
|
|
|
|
|
end
|
|
|
|
|
sort_arr.sort!{|a,b|
|
|
|
|
|
r = ward_sort(a[0], b[0])
|
2002-05-07 22:07:17 +00:00
|
|
|
if r == 0
|
|
|
|
|
r = serverhash[a[3]] <=> serverhash[b[3]]
|
|
|
|
|
end
|
|
|
|
|
r
|
2002-05-07 20:31:05 +00:00
|
|
|
}
|
2002-05-06 11:46:56 +00:00
|
|
|
@groups[subj].clear
|
|
|
|
|
sort_arr.collect{|i|
|
|
|
|
|
if @groups[subj].has_key?("messages")
|
2002-05-07 20:31:05 +00:00
|
|
|
@groups[subj]["subject"] += [i[0]]
|
|
|
|
|
@groups[subj]["messages"] += [i[1]]
|
|
|
|
|
@groups[subj]["ids"] += [i[2]]
|
|
|
|
|
@groups[subj]["servers"] += [i[3]]
|
2002-05-06 11:46:56 +00:00
|
|
|
else
|
2002-05-07 20:31:05 +00:00
|
|
|
@groups[subj]["subject"] = [i[0]]
|
|
|
|
|
@groups[subj]["messages"] = [i[1]]
|
|
|
|
|
@groups[subj]["ids"] = [i[2]]
|
|
|
|
|
@groups[subj]["servers"] = [i[3]]
|
2002-05-06 11:46:56 +00:00
|
|
|
end
|
2002-05-07 20:31:05 +00:00
|
|
|
print "subject sort: #{i[0]}\n" if Debuglevel > 2
|
|
|
|
|
print "server: #{i[3]}\n" if Debuglevel > 2
|
2002-05-06 11:46:56 +00:00
|
|
|
}
|
2002-05-07 22:07:17 +00:00
|
|
|
#print "Done sorting\n"
|
2002-05-06 11:46:56 +00:00
|
|
|
end
|
|
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
def ward_sort(a, b)
|
2002-05-07 20:31:05 +00:00
|
|
|
c = a.to_s.split(/([0-9]+)/)
|
|
|
|
|
d = b.to_s.split(/([0-9]+)/)
|
2002-04-28 16:29:56 +00:00
|
|
|
|
2002-05-07 22:07:17 +00:00
|
|
|
c.collect{|x|
|
2002-04-28 16:29:56 +00:00
|
|
|
y = d.shift
|
|
|
|
|
r = ((x.to_s =~ /^[0-9]+$/) && (y.to_s =~ /^[0-9]+$/)) ?
|
|
|
|
|
(x.to_i <=> y.to_i) :
|
|
|
|
|
(x.to_s <=> y.to_s)
|
|
|
|
|
if r != 0
|
|
|
|
|
return r
|
|
|
|
|
end
|
2002-05-07 22:07:17 +00:00
|
|
|
}
|
|
|
|
|
return -1 if (d != [])
|
2002-04-28 16:29:56 +00:00
|
|
|
return 0
|
|
|
|
|
end
|
|
|
|
|
|
2002-05-07 11:48:18 +00:00
|
|
|
def rechunk_runlist(runlist)
|
2002-05-07 13:46:17 +00:00
|
|
|
return nil if runlist == nil
|
2002-05-07 11:48:18 +00:00
|
|
|
blalist = runlist.split(',')
|
|
|
|
|
blalist.collect!{|x|
|
|
|
|
|
result = ""
|
|
|
|
|
if x =~ /(.*)-(.*)/
|
|
|
|
|
a = $1
|
|
|
|
|
while ($2.to_i - a.to_i) > 200
|
|
|
|
|
result += "#{a}-#{a.to_i+199},"
|
|
|
|
|
a = a.to_i + 200
|
|
|
|
|
end
|
|
|
|
|
result += "#{a}-#{$2}"
|
|
|
|
|
else
|
|
|
|
|
x
|
|
|
|
|
end
|
|
|
|
|
blup = blalist.join(",")
|
|
|
|
|
return blup
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
2002-04-28 16:29:56 +00:00
|
|
|
def quit
|
2002-05-05 20:07:03 +00:00
|
|
|
for server in @connections.keys
|
|
|
|
|
@connections[server]["nntp"].quit
|
|
|
|
|
end
|
2002-04-28 16:29:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private :ward_sort
|
|
|
|
|
|
|
|
|
|
end # class
|