diff --git a/trunk/ripnews/news/article.rb b/trunk/ripnews/news/article.rb index 6cf3263..3154a50 100644 --- a/trunk/ripnews/news/article.rb +++ b/trunk/ripnews/news/article.rb @@ -3,6 +3,7 @@ # $Id$ # $Source$ +require 'set/intspan' require 'net/nntp' class Article @@ -10,16 +11,19 @@ class Article Debuglevel = 1 def initialize(server) + @messids = [] @ids = [] @subjects = [] @sorted = false @grouped = false - @agroups = {} + @groups = {} @nntp = Net::NNTP.new(server) + @skip_ids = Set::IntSpan.new() end -def add(id, subject) - @ids += [id] +def add(messid, id, subject) + @messids += [messid] + @ids += [id.to_i] @subjects += [subject] @sorted = false @grouped = false @@ -27,48 +31,54 @@ end def get_articles(group) resp, count, first, last,name = @nntp.group(group) - for i in (first.to_i..last.to_i) + range = Set::IntSpan.new("#{first}-#{last}") +# for i in (first.to_i..last.to_i) + for i in (range.diff(@skip_ids).elements) begin @nntp.stat(i) - resp, nr, messid, list = @nntp.head(i) + resp, id, messid, list = @nntp.head(i) for j in list if j =~ /Subject: (.*)/ subj=$1 end end - add(messid, subj) + print "get_articles messid: #{messid}\n" if Debuglevel > 1 + print "get_articles id: #{id}\n" if Debuglevel > 1 + print "get_articles subject: #{subj}\n" if Debuglevel > 1 + add(messid, id, subj) rescue Net::NNTP::RuntimeError - print "whoopsie couldn't stat #{i}\n" if Debuglevel > 0 + print "whoopsie couldn't stat #{i}\n" if Debuglevel > 1 end end end def get_groups group_subjects unless @grouped - return @agroups + return @groups end def get_group_body(subj) result = [] - for i in @agroups[subj][1..@agroups[subj].length] - resp, nr, id, list = @nntp.body(i) + for i in @groups[subj]["messages"][1..@groups[subj]["messages"].length] + resp, id, messid, list = @nntp.body(i) result = list end return result end def get_group_body_first(subj) - resp, nr, id, list = @nntp.body(@agroups[subj][1]) + resp, id, messid, list = @nntp.body(@groups[subj]["messages"][0]) print "getting article: #{subj}\n" if Debuglevel > 0 - print "article id: #{id}\n" if Debuglevel > 0 + print "message id: #{messid}\n" if Debuglevel > 0 + print "id: #{id}\n" if Debuglevel > 0 return list end def get_group_body_rest(subj, file=nil) result = [] - for i in @agroups[subj][2..@agroups[subj].length] + for i in @groups[subj]["messages"][1..@groups[subj]["messages"].length] print "getting article: #{i}\n" if Debuglevel > 0 - resp, nr, id, list = @nntp.body(i) + resp, id, messid, list = @nntp.body(i) if file for line in list file.print "#{line}\n" @@ -82,21 +92,26 @@ end def get_group_subjects group_subjects unless @grouped - return @agroups.keys + return @groups.keys +end + +def get_group_ids(subject) + group_subjects unless @grouped + return @groups[subject]["ids"] end def group_complete(subj) group_subjects unless @grouped - print "length: #{@agroups[subj].length} total: #{@agroups[subj][0].to_i}\n" if Debuglevel > 0 - if (@agroups[subj].length - 1 ) >= @agroups[subj][0].to_i + print "length: #{@groups[subj]["messages"].length} total: #{@groups[subj]["total"].to_i}\n" if Debuglevel > 1 + if (@groups[subj]["messages"].length ) >= @groups[subj]["total"].to_i return true else return false end end -def get_ids - return @ids +def get_messids + return @messids end def get_subjects @@ -104,10 +119,11 @@ def get_subjects end def group_subjects - @agroups = {} + @groups = {} subject_sort unless @sorted prev_subj = "" for i in (0..@subjects.length) + print "group subjects: #{i} #{@subjects[i]}\n" if Debuglevel > 1 if @subjects[i] =~ /(.*)\((\d+)\/(\d+)\)(.*)/ || @subjects[i] =~ /(.*)\[(\d+)\/(\d+)\](.*)/ j = "#{$1}#{$4}" number = $2 @@ -117,18 +133,31 @@ def group_subjects number = 1 total = 1 end - if j == prev_subj - @agroups[j] += [ @ids[i] ] + if j == prev_subj and number.to_i !=0 + @groups[j]["messages"] += [ @messids[i] ] + @groups[j]["ids"] += [ @ids[i].to_i ] else - unless number == 0 + unless number.to_i == 0 prev_subj = j - @agroups[j] = [ total, @ids[i] ] + @groups[j] = {} + @groups[j]["total"] = total + @groups[j]["messages"] = [ @messids[i] ] + @groups[j]["ids"] = [ @ids[i].to_i ] end end end @grouped = true end +def set_skip_ids(ids) + set = Set::IntSpan.new(ids) + set.finite or return false + min = set.min + min != nil and min < 0 and return false + @skip_ids = set + return true +end + def uudecode(data, outfile=nil) case data.type.to_s when "Array" @@ -292,23 +321,29 @@ end def subject_sort sort_arr = [] for i in (0..@subjects.length) - sort_arr += ["#{@subjects[i]} #{@ids[i]}"] + print "subj sort #{@subjects[i]}\n" if Debuglevel >2 + print "subj sort #{@messids[i]}\n" if Debuglevel >2 + print "subj sort #{@ids[i]}\n" if Debuglevel >2 + sort_arr += ["#{@subjects[i]} #{@messids[i]} #{@ids[i]}"] end sort_arr.sort!{|a,b| ward_sort(a, b)} + @messids = [] @ids = [] @subjects = [] for i in sort_arr - i =~ /^(.*) (<[^<]*>)$/ || i =~ /^(.*) \[<[^<]*>\]$/ - @ids += [$2] + i =~ /^(.*) (<[^<]*>) (\d+)$/ || i =~ /^(.*) \[<[^<]*>\] (\d+)$/ + @messids += [$2] + @ids += [$3] @subjects += [$1] + print "subject sort: #{$1}\n" if Debuglevel >2 end @sorted = true end def ward_sort(a, b) - a =~ /^(.*) (<[^<]*>)$/ + a =~ /^(.*) (<[^<]*> \d+)$/ c = $1.to_s.split(/([0-9]+)/) - b =~ /^(.*) (<[^<]*>)$/ + b =~ /^(.*) (<[^<]*> \d+)$/ d = $1.to_s.split(/([0-9]+)/) for x in c