#!/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 = "<b>Change " + c["change"] + " by " + c["user"] + "</b><pre>" + c["desc"].gsub(/[\a\b\e]/, "") + "</pre>"
i.description += "<p><b>Affected files:</b>"
if( d[0]["depotFile"].length > 1000 )
i.description += "<div>More files than a sane human being would want to look through. #{d[0]["depotFile"].length} to be precise.</div>"
else
d[0]["depotFile"].each_index do |j|
df = d[0]["depotFile"][j]
rev = d[0]["rev"][j]
i.description += "<div><a href='" + @link + df + "?ac=22'>" + df + "#" + rev + "</a></div>"
end
end
if( f != nil && f.length > 0 )
i.description += "<p><b>Jobs fixed:</b>"
f.each do |fix|
j = $p4.run_jobs( "-l", "-e", "Job=" + fix["Job"] )
i.description += "<div><a href='" + @link + fix["Job"] + "?ac=111'>" + fix["Job"] + "</a></div>"
i.description += "<pre>" + j[0]["Description"].encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/[\a\b\e]/, "") + "</pre>"
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
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #2 | 14059 | Matt Attaway |
House cleaning in Seymour * Remove hard coded Ruby path * Fix prog name to be Seymour * Point to Swarm instead of P4Web |
||
| #1 | 14058 | Matt Attaway | Rename p4tter to Seymour so that I can actually find it |