#!/usr/bin/env ruby require 'rubygems' require 'rss' require 'open-uri' require 'P4' require 'cgi' require 'iconv' # NEXT UP! # stored queries # revisit Unicode support class Feed attr_accessor :title, :link, :description, :version, :label, :path, :rss, :regex, :match, :token, :feeds def initialize( link, token=nil, regex=nil ) @label = "" @title = "" @link = link @description = "" @version = "2.0" @regex = regex @match = nil @path = "//depot/..." @token = token @feeds = Array.new() if( @regex != nil ) r = Regexp.new( @regex ) @match = r.match( @token ) end end def buildFeed( date ) @rss = RSS::Maker.make( version ) do |m| m.channel.title = title m.channel.link = link m.channel.description = description m.items.do_sort = true end changes = $p4.run_changes( "-l", "-ssubmitted", "#{path}@>" + date ) changes.each do |c| next if( !isValidChange?( c ) ) d = $p4.run_describe( "-s", c["change"] ) f = $p4.run_fixes( "-c", c["change"] ) i = RSS::Rss::Channel::Item.new( ) i.title = c["change"] + ": " + truncate_cleanly( c["desc"] ) i.link = @link + c["change"] + "?ac=10" i.date = Time.at( c["time"].to_i() ) i.description = "Change " + c["change"] + " by " + c["user"] + "
" + c["desc"].gsub(/[\a\b\e]/, "") + "
" i.description += "

Affected files:" if( d[0]["depotFile"].length > 1000 ) i.description += "

More files than a sane human being would want to look through. #{d[0]["depotFile"].length} to be precise.
" else d[0]["depotFile"].each_index do |j| df = d[0]["depotFile"][j] rev = d[0]["rev"][j] i.description += "
" + df + "#" + rev + "
" end end if( f != nil && f.length > 0 ) i.description += "

Jobs fixed:" f.each do |fix| j = $p4.run_jobs( "-l", "-e", "Job=" + fix["Job"] ) i.description += "

" + fix["Job"] + "
" i.description += "
" + j[0]["Description"].encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/[\a\b\e]/, "") + "
" end end @rss.items << i end end def isValidChange?( change ) true end def to_s @rss.to_s end def self.each() ObjectSpace.each_object(Feed) { |f| yield f } end def truncate_cleanly( txt ) txt =~ /((^.*?\.\s)|(^.*))/ if( $1 != nil ) $1 else txt end end def parse( uri ) tokens = Array.new() tmp = nil # split up the URL into proper tokens while( nil != tmp = uri.slice!( %r{.*[+\-\_](?=(#{ $ids.keys.join( "|" ) })+?)} ) ) tmp =~ /(.*)([+\-\_])/ tokens << $1 << $2 end tokens << uri # build up the list of feeds, creating instances of Feed subclasses as needed tokens.each do |t| if( t == "+" || t == "-" || t == "_" ) @feeds << t else $ids.keys.each do |k| if( t.index( k ) == 0 ) @feeds << $ids[k].call( link, t ) break end end end end end end begin $ids = {} cgi = CGI.new p4wurl = 'http://swarm.perforce.com/' # load any files in the lib dir $LOAD_PATH.unshift( File.dirname(__FILE__) + '/lib' ) Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require File.basename( file ) } rf = ComboFeed.new( p4wurl ) rf.parse( cgi.keys[0] + "" ) # get our perforce data $p4 = P4.new() $p4.prog = "seymour" $p4.user = "matt" $p4.password = "foobar" $p4.port = "perforce.perforce.com:1666" $p4.connect(); # get the beginning of the month lastWeek = Time.now - ( 60 * 60 * 24 * 7 ) date = lastWeek.year().to_s() + "/" + lastWeek.month().to_s() + "/" + lastWeek.day().to_s() # do stuff rf.buildFeed( date ) cgi.out( "type" => "application/rss+xml", "status" => "OK" ) { rf.to_s } $p4.disconnect() end