lib/bbiff/bbs_reader.rb in bbiff-0.3.5 vs lib/bbiff/bbs_reader.rb in bbiff-0.4.0

- old
+ new

@@ -1,14 +1,16 @@ require 'net/http' require 'uri' -require 'pp' if $DEBUG module Bbs class NotFoundError < StandardError end + class FormatError < StandardError + end + class Post class << self def from_s(str) Post.new(*str.split('<>', 5)) end @@ -77,18 +79,19 @@ end # ASCII-8BIT エンコーディングの文字列を返す。 def download_binary(uri) resource = @resource_cache[uri] - if resource + if resource && resource.data.size > 0 + Net::HTTP.start(uri.host, uri.port) do |http| request = Net::HTTP::Get.new(uri) request['range'] = "bytes=#{resource.data.bytesize}-" response = http.request(request) response.body.force_encoding('ASCII-8BIT') - pp response.code if $DEBUG - pp response.to_hash if $DEBUG + p response.code if $DEBUG + p response.to_hash if $DEBUG case response when Net::HTTPPartialContent p :partial if $DEBUG resource.data += response.body when Net::HTTPRequestedRangeNotSatisfiable @@ -115,12 +118,12 @@ response = nil Net::HTTP.start(uri.host, uri.port) do |http| request = Net::HTTP::Get.new(uri) response = http.request(request) response.body.force_encoding('ASCII-8BIT') - pp response.code if $DEBUG - pp response.to_hash if $DEBUG + p response.code if $DEBUG + p response.to_hash if $DEBUG case response when Net::HTTPOK else raise DownloadFailure.new(response) end @@ -270,11 +273,11 @@ def initialize(board, id, title, last = 1) super end - def posts(range) + def posts(range, opts = {}) fail ArgumentError unless range.is_a? Range dat_for_range(range).each_line.map do |line| post = create_post(line.chomp) @last = [post.no, last].max post @@ -327,18 +330,18 @@ def create_thread_from_line(line) Thread.from_line(line, self) end end - NICHAN_THREAD_URL_PATTERN = %r{\Ahttp://[a-zA-z\-\.]+(?::\d+)/test/read\.cgi\/(\w+)/(\d+)($|/)} + NICHAN_THREAD_URL_PATTERN = %r{\Ahttp://[0-9a-zA-z\-\.]+(:\d+)?/test/read\.cgi\/(\w+)/(\d+)($|/)} # 2ちゃんスレッド class Thread < ThreadBase class << self def from_url(url) if url.to_s =~ NICHAN_THREAD_URL_PATTERN - board_name, thread_num = $1, $2.to_i + board_name, thread_num = $2, $3.to_i uri = URI(url) board = Board.send(:new, uri.hostname, uri.port, board_name) thread = board.thread(thread_num) raise NotFoundError, 'no such thread' if thread.nil? return thread @@ -358,18 +361,27 @@ def initialize(board, id, title, last = 1) super end - def posts(range) + def posts(range, opts = {}) fail ArgumentError unless range.is_a? Range url = URI(dat_url) - lines = @board.send(:download_text, url) + lines = @board.send(:download_text, + if opts[:long_polling] then + url + "?long_polling=1" + else + url + end) ary = [] lines.each_line.with_index(1) do |line, res_no| next unless range.include?(res_no) - name, mail, date, body, title = line.chomp.split('<>', 5) + fields = line.chomp.split('<>', 5) + if fields.size != 5 + raise FormatError, "invalid line #{line.inspect}" + end + name, mail, date, body, title = fields post = Post.new(res_no.to_s, name, mail, date, body) ary << post @last = [post.no, last].max end return ary