#!/usr/bin/ruby require 'cgi' @cgi = CGI.new 'html4' print "Content-type: text/html\n\n" # We want to find all of the dist.xml files in the software/ tree; the paths # -1 for the project name are the catagories. Check the timestamp on the # dist.xmls in the subdirectory -- if they're newer, regenerate the index.html; # if not, serve up the the index.html Dir.chdir '..' dist_xmls = Dir.glob( 'software/**/dist.xml' ) STDERR.puts Dir.entries("software").inspect STDERR.puts dist_xmls.inspect dist_xmls.delete_if {|f| f =~ /\.svn/ } # Regenerate the menu if any dist is newer than the existing menu regen = true menu_tstamp = 0 if File.exists? 'software/menu.xml' menu_tstamp = File.stat( 'software/menu.xml' ).mtime STDERR.puts "Menu tstamp = #{menu_tstamp}" regen = dist_xmls.find{|f| File.stat( f ).mtime > menu_tstamp } end STDERR.puts "Regen = #{regen}" # Build the menu here, but only if there's a new project if regen # The next block is really ugly catagories = dist_xmls.collect { |f| # software/(/)+/dist.xml # We want to get , so we dirname twice and then remove 'software/' File.dirname(File.dirname(f))["software/".length..-1] }. uniq. delete_if { |f| f == '' }. collect { |c| c[/^\//] = '' if c =~ /^\// # Delete any leading '/' "" }. join( '' ) menu_data = File.new("software/menu_templ.xml").read.gsub(/#\{catagories\}/m, catagories) File.open( 'software/menu.xml', 'w' ) do |menu| menu.puts menu_data end # update the timestamp menu_tstamp = File.stat( 'software/menu.xml' ).mtime end # Find the current query path # Generate the current query index name catagory_index = nil catagory = '' if @cgi.path_info catagory = @cgi.path_info catagory_index = File.join( 'software', catagory, 'index.html' ) else catagory_index = File.join( 'software', 'index.html' ) end # If the menu is newer than the index, regenerate the index from the # path/*/dist.xml (grep dist_xmls?) regen = !File.exists?(catagory_index) || (menu_tstamp > File.stat(catagory_index).mtime) || catagory.strip.size == 0 if regen require 'rexml/document' # write_catagory returns an HTML branch for all of the software pieces in a catagory; # it returns the empty string if no packages were found. If this is the case, then # the catagory really isn't a catagory. def write_catagory catagory # Find all */dist.xml # Convert each dist.xml to HTML glob = if catagory.strip.length == 0 "software/**/dist.xml" else "software/#{catagory}/*/dist.xml" end projects = Dir.glob(glob).collect { |f| REXML::Document.new(File.new(f)) } names = projects.collect{ |dist| REXML::XPath.first(dist, '/project/@name' ).to_s } map = names.zip( projects ) map.sort! { |a,b| a[0] <=> b[0] } found = [] map = map.collect { |n,d| if found.include? n nil else found << n [n,d] end }.compact map.collect { |project_name,dist| version = REXML::XPath.first(dist, '/project/@version').to_s category = REXML::XPath.first(dist, '/project/category[1]/text()') web_url = "/software/#{category.to_s}/#{project_name}".gsub(/\/\//, '/') homepage = REXML::XPath.first(dist, '/project/@url' ) web_url = homepage.to_s if homepage languages = REXML::XPath.match(dist, '/project/language/@name' ).collect {|x| x.to_s} abstract = REXML::XPath.match(dist, '/project/description/node()' ).collect { |item| item.to_s }.join( ' ' ) date = REXML::XPath.first(dist, '/project/@date' ).to_s archive_files = {} REXML::XPath.each(dist, '/project/archive') {|el| archive_files[ el.attributes['file'] ] = el.attributes['title'] } blog = @cgi.div('class'=>'box') { @cgi.div('class'=>'titlebar') { @cgi.div( 'class' => 'complang' ) { languages.collect do |lang| @cgi.img( case lang when /java/i '/images/javalogo.png' when /ruby/i '/images/ruby-jewel.png' else '' end ) end.join('') }+"\n"+ @cgi.div('class'=>'titlelink') { @cgi.a( web_url ) { project_name } }+"\n"+ version }+"\n"+ @cgi.div('class'=>'abstract') { @cgi.table( 'border'=>'0', 'width'=>'100%' ) { @cgi.tr { @cgi.td('width'=>'60%') { abstract }+ @cgi.td('align'=>'right','valign'=>'top') { @cgi.b { "Downloads" }+ @cgi.hr + archive_files.keys.collect do |file| @cgi.a( "/archives/#{file}" ) { archive_files[file] } end.join( @cgi.br ) } } } }+ @cgi.div( 'class' => 'links' ) { (date ? @cgi.div( 'class' => 'date' ) { date } : '' ) } } blog }.join( "\n" ) # Return as string end catagory_string = write_catagory(catagory) if catagory_string.strip.length > 0 File.open( catagory_index, 'w' ) do |index_out| index_out.puts File.new( 'software/head.xml' ).read index_out.puts File.new( 'software/menu.xml' ).read index_out.puts File.new( 'software/body.xml' ).read index_out.puts catagory_string index_out.puts File.new( 'software/tail.xml' ).read end end end # serve up index.html print File.new(catagory_index).read print "\n"