Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
227 lines (206 sloc) 6.76 KB
//
// Mono CvsSpy -- A simple program to generate Mono CVS Statistics
// for the Mono Weekly News.
//
// (C) 2003, Jaime Anguiano Olarra <jaime@gnome.org>
//
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using System.Diagnostics;
namespace MonoWeeklyNews {
public class MonoCvsSpy {
private static readonly string VERSION = "0.1";
public static void Main (string[] args)
{
string name;
if (args.Length > 0) {
if (args[0] == "--get") {
GetMonoPatches ();
}
}
Console.Write ("Enter file to parse: (default 'cvslog-prev')");
if ((name = Console.ReadLine ()) == "")
ParsePatches ("cvslog-prev");
else
ParsePatches (name);
}
static void GetMonoPatches ()
{
string url = "http://lists.ximian.com/archives/public/mono-patches/";
Console.Write ("Enter year-month.txt (f.ex. 2003-April.txt): ");
HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url + Console.ReadLine ());
Console.WriteLine ("\n\tPlease wait, downloading a mono-patches mailing-list archive (~15) may take sometime...");
HttpWebResponse res = null;
Console.WriteLine ("\n");
try {
res = (HttpWebResponse) req.GetResponse ();
}
catch (Exception e) {
Console.WriteLine (e);
}
StreamReader sr = new StreamReader (res.GetResponseStream(), Encoding.ASCII);
StreamWriter sw = new StreamWriter ("cvslog-prev");
string line;
while ((line = sr.ReadLine ()) != null)
{
sw.WriteLine (line);
}
sr.Close ();
sw.Flush ();
sw.Close ();
sr = null;
sw = null;
}
static void ParsePatches (string file)
{
int day, eday;
string line, month;
long lineCtr, startLine, endLine = 0;
int total_authors;
total_authors = 0;
Hashtable authors;
ArrayList modules;
ArrayList modules_commits;
StreamReader reader;
StreamWriter writer;
modules = new ArrayList ();
reader = new StreamReader ("modules.list");
while ((line = reader.ReadLine ()) != null)
{
modules.Add (line);
}
reader.Close ();
modules_commits = new ArrayList (modules.Count);
for (int i=0; i < modules.Count; ++i)
modules_commits.Add (0);
Console.WriteLine ("This is the time now: {0:U}", DateTime.Now);
reader = new StreamReader (file);
Console.Write ("Enter starting day (permited values [1-31]): ");
day = Convert.ToInt32(Console.ReadLine ());
Console.Write ("Enter ending day (permited values [1-31]): ");
eday = Convert.ToInt32 (Console.ReadLine ());
Console.Write ("Enter starting month (f.ex: 'Apr'): ");
month = Console.ReadLine ();
Console.WriteLine ("Searching from " + (day).ToString() + " to " + (eday).ToString() + ", " + (month).ToString());
while (day < eday + 1)
{
lineCtr = 0;
reader.Close ();
reader = new StreamReader (file);
authors = new Hashtable ();
while ((line = reader.ReadLine ()) != null)
{
++lineCtr;
if ((line.IndexOf ((day).ToString() + " " + month) > 0) && line.StartsWith ("Date"))
startLine = lineCtr; // Do this we are missing the first author :-/
if (line.StartsWith ("From:")) {
string[] frags;
string author = null;
line = line.Replace ('(', ' ');
line = line.Replace (')', ' ');
line = line.Substring (6);
line = line.Substring (line.IndexOf (' ') + 1);
frags = line.Split (' ');
for (uint i=0; i < frags.Length; ++i) {
if (frags[i].IndexOf ('@') > 0)
frags[i] = null;
author = author + " " + frags[i];
}
if (authors[author] == null)
authors.Add (author, 0);
authors[author] = Convert.ToInt32(authors[author]) + 1;
}
for (int i=0; i < modules.Count; ++i)
if (line.IndexOf ((modules[i]).ToString()) > 0)
modules_commits[i] = ((int) modules_commits[i]) + 1;
}
++day;
if (day == eday)
endLine = lineCtr;
}
reader.Close ();
reader = null;
writer = new StreamWriter ("cvsstats.html");
writer.WriteLine ("<h1>Mono CVS Statistics</h1>");
writer.WriteLine ("<p>[" + (day).ToString() + "-" + (eday).ToString() + "] " + (month).ToString() + " </p>");
WriteAuthors (authors, writer);
WriteModules (modules, modules_commits, writer);
writer.WriteLine ("<p>Statistics generated by MonoCvsSpy " + VERSION);
writer.WriteLine (" <br />you can download this tool at the <a \n"
+ "href=\"http://monoevo.sf.net/mwn/index.html\">Mono Weekly News</a> page.");
writer.Close ();
writer = null;
}
private static void WriteAuthors (Hashtable authorsTable, StreamWriter writer)
{
Author[] authors = new Author[authorsTable.Count];
uint i = 0;
foreach (DictionaryEntry de in authorsTable)
{
authors[i++] = new Author((de.Key).ToString(), (de.Value).ToString());
}
QuickSort (ref authors, 0, authors.Length - 1);
writer.WriteLine ("<p>Total authors: " + (authors.Length).ToString() + "</p>\n");
writer.WriteLine ("<p><table border=\"1\">\n");
writer.WriteLine ("<tr><td><b>Author</b></td><td><b>Commits</b></td></tr>");
for (i=0; i < authors.Length; ++i) {
writer.Write ("<tr><td>" + authors[i].Name + "</td><td>" + authors[i].Commits + "</td></tr>\n");
}
writer.WriteLine ("</table></p>");
writer.Flush ();
}
private static void WriteModules (ArrayList modules, ArrayList commits, StreamWriter writer)
{
long total_commits = 0;
writer.WriteLine ("<p><table border=\"1\">\n");
writer.WriteLine ("<tr><td><b>Module</b></td><td><b>Commits</b> (*)</td></tr>");
for (int i=0; i < modules.Count; ++i) {
if (Convert.ToInt32((commits[i]).ToString()) > 3) {
writer.WriteLine ("<tr><td>" + (modules[i]).ToString() + "</td><td>" + (commits[i]).ToString() + "</td></tr>");
total_commits += Convert.ToInt32((commits[i]).ToString());
}
}
writer.WriteLine ("</table>");
writer.WriteLine ("<p>Total commits: " + total_commits.ToString() + "</p>\n");
writer.WriteLine ("<b>(*)</b> Those modules with less than four commits are not shown.</p>");
writer.Flush ();
}
// This is almost a copy of K&R's QuickSort function
private static void QuickSort (ref Author[] array, int left, int right)
{
int last;
if (left >= right)
return;
Swap (ref array, left, (left + right) / 2);
last = left;
for (int i = left + 1; i <= right; ++i)
if (String.Compare (array[i].Name, array[left].Name) < 0)
Swap (ref array, ++last, i);
Swap (ref array, left, last);
QuickSort (ref array, left, last - 1);
QuickSort (ref array, last + 1, right);
}
private static void Swap (ref Author[] array, int i, int j)
{
Author tmp;
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
private class Author {
string name, commits;
public Author (string name, string commits)
{
this.name = name;
this.commits = commits;
}
public string Name { get { return name; } set { name = value; }}
public string Commits { get { return commits; } set { commits = value; }}
}
}
}