#!/usr/bin/env ruby # # Author: IKARASHI Yoshinori # $Id$ # License: GPLv2 # require 'cgi' require 'rss/parser' require 'rss/0.9' require 'rss/1.0' require 'rss/2.0' require 'rss/syndication' require 'rss/dublincore' require 'rss/content' require 'uri' require 'open-uri' require 'timeout' ########################### ### Configuration parameters BASEDIR = "/tmp/rss2ini/" CACHETIME = 600 FETCHTIMEOUT = 30 OUTPUT_CHARSET = "Shift_JIS" OUTPUT_FORMAT = "[%N%] title=%TITLE% link=%URI% pubDate=%DATE% description=%DESCRIPTION% " RSSURI = '' ################### class Feed attr_accessor :uri, :output_charset, :output_format, :cachetime def initialize(uri, title = '') @basedir = BASEDIR @cachetime = CACHETIME @fetchtimeout = FETCHTIMEOUT @output_format = OUTPUT_FORMAT @output_charset = OUTPUT_CHARSET Dir.mkdir(@basedir) unless FileTest.directory?(@basedir) @uri = uri @title = title @rss = nil end def fetch rsssource = '' fetchfile = @basedir + @uri.gsub(/^https?:\/\//, '').gsub(/\//, '-').gsub(/-$/, '').to_s if(File.exist?(fetchfile) and File.mtime(fetchfile) > Time.now - @cachetime) rssfile = File.new(fetchfile, 'r') rssfile.each_line do |line| rsssource << line end rssfile.close else rssfile = File.new(fetchfile, 'w') begin page = timeout(@fetchtimeout) { URI.parse(uri).read } rssfile.print page rsssource = page rescue OpenURI::HTTPError rsssource = nil rescue StandardError, TimeoutError rsssource = nil end rssfile.close end rsssource end def rss rsssource = fetch return @rss if @rss begin rss = RSS::Parser.parse(rsssource) rescue RSS::InvalidRSSError begin rss = RSS::Parser.parse(rsssource, false) rescue RSS::NotWellFormedError rss = nil end rescue RSS::NotWellFormedError rss = nil end @rss = rss return @rss end def title return @title unless @title == '' @rss = rss if @rss == nil return 'unknown' if @rss == nil begin @rss.output_encoding = @output_charset rescue RSS::UnknownConvertMethod return '' end @title = @rss.channel.title return @title end def output(num_items=20) output = '' @rss = rss if @rss == nil return output unless @rss begin @rss.output_encoding = @output_charset rescue RSS::UnknownConvertMethod end @title = @rss.channel.title num = 0 @rss.items.each do |item| # date = item.dc_date ? Time.at(item.dc_date).strftime("%y-%m-%d %H:%M") : '' date = item.pubDate ? Time.at(item.pubDate).rfc2822 : '' line = @output_format.gsub(/%.+?%/) {|p| case p when '%N%' num + 1 when '%DATE%' date when '%URI%' item.link when '%TITLE%' item.title when '%DESCRIPTION%' item.description when '%CONTENT_ENCODED%' item.content_encoded end } output << line num += 1 break if num_items <= num end output end end ############################################ # main ############################################ cgi = CGI.new('output4') File.umask(0066) num_items = cgi.has_key?('num') ? cgi['num'].to_i : 20 output = '' feed = Feed.new(cgi['uri']) output << feed.output(num_items) if cgi.has_key?('charset') feed.output_charset = cgi['charset'] end header = {'type'=>"text/plain", 'charset'=>"#{feed.output_charset}"} puts cgi.header(header) puts output