From: Kouhei Sutou Date: 2006-02-18T12:04:10+09:00 Subject: Re: File.exist? svn2rss.rb ----Next_Part(Sat_Feb_18_12_03_56_2006_822)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Sat_Feb_18_12_03_56_2006_822)--" ----Next_Part(Sat_Feb_18_12_03_56_2006_822)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, In "Re: File.exist? svn2rss.rb" on Fri, 17 Feb 2006 06:23:39 +0900, Bil Kleb wrote: > I am looking for a single-purpose, 20-liner (maybe by using > Weirich's Builder?) that I'll be able to understand within > a couple minutes 3 years from now... :) Here is another one. It uses RSS::Maker. But... this has 190 lines... Usage: % svn2rss.rb REPOS_PATH REVISION \ --name YOUR_REPOSITORY_NAME_OPTIONAL \ --repository-uri http://YOUR.REPOSITORY/URI \ --rss-path /OUTPUTTED/RSS/PATH.rdf \ --rss-uri http://OUTPUTTED/RSS/URI.rdf Thanks, -- kou ----Next_Part(Sat_Feb_18_12_03_56_2006_822)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="svn2rss.rb" #!/usr/bin/env ruby require "optparse" require "ostruct" def parse(args) options = OpenStruct.new options.repository_uri = nil options.rss_path = nil options.rss_uri = nil options.name = nil opts = OptionParser.new do |opts| opts.banner = opts.banner.gsub(/(\[options\])/, 'REPOS REV \1') opts.separator "" opts.on("-I", "--include [PATH]", "Add [PATH] to load path") do |path| $LOAD_PATH.unshift(path) end opts.on("--repository-uri [URI]", "[MUST] Use [URI] as URI of repository") do |uri| options.repository_uri = uri end opts.on("--rss-path [PATH]", "[MUST] Use [PATH] as output RSS path") do |path| options.rss_path = path end opts.on("--rss-uri [URI]", "[MUST] Use [URI] as output RSS URI") do |uri| options.rss_uri = uri end opts.on("--name [NAME]", "Use [NAME] as repository name") do |name| options.name = name end opts.on_tail("--help", "Show this message") do puts opts exit end end opts.parse!(args) if options.repository_uri and options.rss_path and options.rss_uri options else puts opts exit(1) end end CHANGED_TYPE = { :added => "Added", :modified => "Modified", :deleted => "Deleted", :copied => "Copied", :property_changed => "Property changed", } CHANGED_MARK = Hash.new("=") CHANGED_MARK[:property_changed] = "_" def diff_info(info, uri) info.diffs.collect do |key, values| [ key, values.collect do |type, value| case type when :added rev = info.revision.to_s when :modified, :property_changed rev = "#{info.revision - 1}:#{info.revision}" when :deleted rev = (info.revision - 1).to_s when :copied rev = (info.revision - 1).to_s else raise "unknown diff type: #{value.type}" end link = [uri, key].compact.join("/") line_info = "+#{value.added_line} -#{value.deleted_line}" desc = <<-HEADER #{CHANGED_TYPE[value.type]}: #{key} (#{line_info}) #{CHANGED_MARK[value.type] * 67} HEADER desc << value.body [desc, link] end ] end end def output_rss(name, file, rss_uri, repos_uri, info) prev_rss = nil begin if File.exist?(file) File.open(file) do |f| prev_rss = RSS::Parser.parse(f) end end rescue RSS::Error end File.open(file, "w") do |f| f.print(make_rss(prev_rss, name, rss_uri, repos_uri, info).to_s) end end def make_rss(base_rss, name, rss_uri, repos_uri, info) RSS::Maker.make("1.0") do |maker| maker.encoding = "UTF-8" maker.channel.about = rss_uri maker.channel.title = rss_title(name || repos_uri) maker.channel.link = repos_uri maker.channel.description = rss_title(name || repos_uri) maker.channel.dc_date = info.date if base_rss base_rss.items.each do |item| item.setup_maker(maker) end end diff_info(info, repos_uri).each do |name, infos| infos.each do |desc, link| item = maker.items.new_item item.title = name item.description = info.log item.content_encoded = "
#{h(desc)}
" item.link = link item.dc_date = info.date item.dc_creator = info.author end end maker.items.do_sort = true maker.items.max_size = 15 end end def rss_title(name) "Repository of #{name}" end def rss_items(items, info, repos_uri) diff_info(info, repos_uri).each do |name, infos| infos.each do |desc, link| items << [link, name, desc, info.date] end end items.sort_by do |uri, title, desc, date| date end.reverse end def main repos, revision, *rest = ARGV options = parse(rest) require "svn/info" require "svn/client" info = Svn::Info.new(repos, revision) require "rss/1.0" require "rss/dublincore" require "rss/content" require "rss/maker" include RSS::Utils output_rss(options.name, options.rss_path, options.rss_uri, options.repository_uri, info) end main ----Next_Part(Sat_Feb_18_12_03_56_2006_822)---- ----Next_Part(Sat_Feb_18_12_03_56_2006_822)----