Content deleted Content added
→Under development: finished working on edit summaries, will commit once autocomment parsing is done |
→Code: code commit - edit summaries and automatic section summaries now parsed, working on processing |
||
Line 73: | Line 73: | ||
* @author Flcelloguy et al. |
* @author Flcelloguy et al. |
||
* @program Flcelloguy's Tool (Stats.java) |
* @program Flcelloguy's Tool (Stats.java) |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot code from http://en.wikipedia.org/wiki/User:Flcelloguy/Tool |
* @docRoot code from http://en.wikipedia.org/wiki/User:Flcelloguy/Tool |
||
Line 80: | Line 80: | ||
* Please leave this block in. |
* Please leave this block in. |
||
* Note: This new version does not require cut-and-pasting. Just go to http://en.wikipedia.org/w/index.php?title=Special:Contributions&target={{USERNAME}}&offset=0&limit=5000, where {{USERNAME}} is the name of the user you want to run a check on. |
* Note: This new version does not require cut-and-pasting. Just go to http://en.wikipedia.org/w/index.php?title=Special:Contributions&target={{USERNAME}}&offset=0&limit=5000, where {{USERNAME}} is the name of the user you want to run a check on. |
||
*/ |
*/ |
||
import javax.swing.JOptionPane; |
import javax.swing.JOptionPane; |
||
import java.io.BufferedReader; |
import java.io.BufferedReader; |
||
Line 88: | Line 87: | ||
import java.io.FileWriter; |
import java.io.FileWriter; |
||
import java.io.IOException; |
import java.io.IOException; |
||
//import java.util.FileReader; |
|||
// import java.util.FileReader; |
|||
public class Stats |
public class Stats |
||
{ |
{ |
||
private static StringBuilder console = new StringBuilder(); |
private static StringBuilder console = new StringBuilder(); |
||
private static int numEdits = 0; |
private static int numEdits = 0; |
||
private static int minorEdits = 0; |
private static int minorEdits = 0; |
||
private static int Mainspace = 0; |
private static int Mainspace = 0; |
||
private static int Talk = 0; |
private static int Talk = 0; |
||
private static int User = 0; |
private static int User = 0; |
||
private static int User_talk = 0; |
private static int User_talk = 0; |
||
private static int Wikipedia = 0; |
private static int Wikipedia = 0; |
||
private static int Wikipedia_talk = 0; |
private static int Wikipedia_talk = 0; |
||
private static int Image = 0; |
private static int Image = 0; |
||
private static int Image_talk= 0; |
private static int Image_talk = 0; |
||
private static int MediaWiki = 0; |
private static int MediaWiki = 0; |
||
private static int MediaWiki_talk = 0; |
private static int MediaWiki_talk = 0; |
||
Line 113: | Line 113: | ||
private static int Portal = 0; |
private static int Portal = 0; |
||
private static int Portal_talk = 0; |
private static int Portal_talk = 0; |
||
private static int Special = 0; |
private static int Special = 0; // these two are listed at |
||
// [[Wikipedia:Namespace]], |
|||
private static int Media = 0; |
private static int Media = 0; // so I'm adding support for them, but I'm |
||
// not sure they are used. |
|||
public static void reset() |
public static void reset() |
||
{ |
{ |
||
console = new StringBuilder(); |
console = new StringBuilder(); |
||
numEdits = 0; |
numEdits = 0; |
||
minorEdits = 0; |
minorEdits = 0; |
||
Mainspace = 0; |
Mainspace = 0; |
||
Talk = 0; |
Talk = 0; |
||
User = 0; |
User = 0; |
||
User_talk = 0; |
User_talk = 0; |
||
Wikipedia = 0; |
Wikipedia = 0; |
||
Wikipedia_talk = 0; |
Wikipedia_talk = 0; |
||
Image = 0; |
Image = 0; |
||
Image_talk= 0; |
Image_talk = 0; |
||
MediaWiki = 0; |
MediaWiki = 0; |
||
MediaWiki_talk = 0; |
MediaWiki_talk = 0; |
||
Line 139: | Line 141: | ||
Portal = 0; |
Portal = 0; |
||
Portal_talk = 0; |
Portal_talk = 0; |
||
Special = 0; |
Special = 0; // these two are listed at [[Wikipedia:Namespace]], |
||
Media = 0; |
Media = 0; // so I'm adding support for them, but I'm not sure they are |
||
// used. |
|||
} |
|||
} |
|||
public static void main(String args[]) throws IOException |
public static void main(String args[]) throws IOException |
||
{ |
{ |
||
/** |
/** |
||
* the GUI is too complex to screw |
* the GUI is too complex to screw up clean, crisp code like this, so |
||
* I'm moving it to a separate class. --Titoxd |
|||
* up clean, crisp code like this, |
|||
*/ |
|||
* so I'm moving it to a separate class. |
|||
MainGUI.main(null); |
|||
* --Titoxd |
|||
*/ |
|||
MainGUI.main(null); |
|||
} |
} |
||
public static void mainSingle |
public static void mainSingle(String inFile$) throws IOException |
||
{ |
|||
{ |
|||
if (inFile$==null) |
if (inFile$ == null) |
||
inFile$ = JOptionPane.showInputDialog("Input file:", inFile$); |
|||
JOptionPane.showMessageDialog( |
JOptionPane |
||
.showMessageDialog( |
|||
"Current status: \n " |
null, |
||
"Current status: \n " |
|||
"Editcount only \n " |
+ "Editcount only \n " |
||
"Coming soon: \n " |
+ "Coming soon: \n " |
||
"Breakdown by namespace \n Minor edits usage \n User friendly version \n Edit summary usage \n First edit date", |
+ "Breakdown by namespace \n Minor edits usage \n User friendly version \n Edit summary usage \n First edit date", |
||
"Information", JOptionPane.INFORMATION_MESSAGE); |
|||
JOptionPane.showMessageDialog(null, "Number of edits: " |
|||
+ editcount(inFile$), "Results", |
|||
JOptionPane.INFORMATION_MESSAGE); |
JOptionPane.INFORMATION_MESSAGE); |
||
} |
|||
JOptionPane.showMessageDialog(null, |
|||
"Number of edits: " + editcount(inFile$), "Results", |
|||
JOptionPane.INFORMATION_MESSAGE); |
|||
} |
|||
public static int editcount(String inFile$) throws IOException |
public static int editcount(String inFile$) throws IOException |
||
{ |
{ |
||
System.out.println("Computing..."); |
System.out.println("Computing..."); |
||
FileReader reader = new FileReader(inFile$); |
FileReader reader = new FileReader(inFile$); |
||
BufferedReader in = new BufferedReader(reader); |
BufferedReader in = new BufferedReader(reader); |
||
//FileWriter writer = new FileWriter(outFile$); |
// FileWriter writer = new FileWriter(outFile$); //for debugging |
||
//BufferedWriter out = new BufferedWriter(writer); |
// BufferedWriter out = new BufferedWriter(writer); //for debugging |
||
String inString =""; |
String inString = ""; |
||
Contrib outContrib; |
Contrib outContrib; |
||
boolean endContribs = false; |
boolean endContribs = false; // marks whether all the contributions |
||
// have been parsed |
|||
inString = in.readLine(); |
inString = in.readLine(); // read from file and discard |
||
do |
do |
||
{ |
{ |
||
if ((inString.trim().compareTo("<ul>")==0) |
if ((inString.trim().compareTo("<ul>") == 0) |
||
&& (endContribs == false)) // until the <ul> tag is |
|||
// reached, |
|||
{ |
{ |
||
do |
do |
||
{ |
{ |
||
inString = in.readLine(); |
inString = in.readLine(); // then start reading and |
||
if ((inString.trim().compareTo("</ul>")!=0)) |
// recording |
||
if ((inString.trim().compareTo("</ul>") != 0)) |
|||
{ |
{ |
||
//System.out.println(inString.trim()); |
// System.out.println(inString.trim()); |
||
outContrib = PurgeContribs.Parse(inString.trim()); |
outContrib = PurgeContribs.Parse(inString.trim()); |
||
//System.out.println(outString.trim()); |
// System.out.println(outString.trim()); |
||
AnalyzeContrib(outContrib); |
AnalyzeContrib(outContrib); |
||
//out.newLine(); |
// out.newLine(); |
||
} |
} |
||
else |
else |
||
Line 207: | Line 215: | ||
endContribs = true; |
endContribs = true; |
||
} |
} |
||
} |
} |
||
while (endContribs != true); |
|||
} |
} |
||
inString = in.readLine(); |
inString = in.readLine(); // read from file and discard |
||
} |
} |
||
while (inString != null); |
|||
in.close(); |
in.close(); |
||
//out.close(); |
// out.close(); |
||
//Prints out statistics |
// Prints out statistics |
||
System.out.println("-------------------"); |
System.out.println("-------------------"); |
||
System.out.println("Breakdown by namespace:"); |
System.out.println("Breakdown by namespace:"); |
||
if (Mainspace != 0) |
if (Mainspace != 0) |
||
{ |
|||
console.append("Main (articles): " + Mainspace + "\n"); |
console.append("Main (articles): " + Mainspace + "\n"); |
||
System.out.println("Main (articles): " + Mainspace); |
System.out.println("Main (articles): " + Mainspace); |
||
} |
|||
if (Talk != 0) |
if (Talk != 0) |
||
{ |
|||
console.append("Article talk: " + Talk + "\n"); |
console.append("Article talk: " + Talk + "\n"); |
||
System.out.println("Article talk: " + Talk); |
|||
} |
|||
} |
|||
if (User != 0) |
if (User != 0) |
||
{ |
|||
console.append("User: " + User + "\n"); |
console.append("User: " + User + "\n"); |
||
System.out.println("User: " + User); |
System.out.println("User: " + User); |
||
} |
|||
if (User_talk != 0) |
if (User_talk != 0) |
||
{ |
|||
console.append("User talk: " + User_talk + "\n"); |
console.append("User talk: " + User_talk + "\n"); |
||
System.out.println("User talk: " + User_talk); |
System.out.println("User talk: " + User_talk); |
||
} |
|||
if (Wikipedia != 0) |
if (Wikipedia != 0) |
||
{ |
|||
console.append("Project: " + Wikipedia + "\n"); |
console.append("Project: " + Wikipedia + "\n"); |
||
System.out.println("Project: " + Wikipedia); |
System.out.println("Project: " + Wikipedia); |
||
} |
|||
if (Wikipedia_talk != 0) |
if (Wikipedia_talk != 0) |
||
{ |
|||
console.append("Project talk: " + Wikipedia_talk + "\n"); |
console.append("Project talk: " + Wikipedia_talk + "\n"); |
||
System.out.println("Project talk: " + Wikipedia_talk); |
System.out.println("Project talk: " + Wikipedia_talk); |
||
} |
|||
if (Image != 0) |
if (Image != 0) |
||
{ |
|||
console.append("Image: " + Image + "\n"); |
console.append("Image: " + Image + "\n"); |
||
System.out.println("Image: " + Image); |
System.out.println("Image: " + Image); |
||
} |
|||
if (Image_talk != 0) |
if (Image_talk != 0) |
||
{ |
|||
console.append("Image talk: " + Image_talk + "\n"); |
console.append("Image talk: " + Image_talk + "\n"); |
||
System.out.println("Image talk: " + Image_talk); |
System.out.println("Image talk: " + Image_talk); |
||
} |
|||
if (MediaWiki != 0) |
if (MediaWiki != 0) |
||
{ |
|||
console.append("MediaWiki: " + MediaWiki + "\n"); |
console.append("MediaWiki: " + MediaWiki + "\n"); |
||
System.out.println("MediaWiki: " + MediaWiki); |
System.out.println("MediaWiki: " + MediaWiki); |
||
} |
|||
if (MediaWiki_talk != 0) |
if (MediaWiki_talk != 0) |
||
{ |
|||
console.append("MediaWiki talk: " + MediaWiki_talk + "\n"); |
console.append("MediaWiki talk: " + MediaWiki_talk + "\n"); |
||
System.out.println("MediaWiki talk: " + MediaWiki_talk); |
System.out.println("MediaWiki talk: " + MediaWiki_talk); |
||
} |
|||
if (Template != 0) |
if (Template != 0) |
||
{ |
|||
console.append("Template: " + Template + "\n"); |
console.append("Template: " + Template + "\n"); |
||
System.out.println("Template: " + Template); |
System.out.println("Template: " + Template); |
||
} |
|||
if (Template_talk != 0) |
if (Template_talk != 0) |
||
{ |
|||
console.append("Template talk: " + Template_talk + "\n"); |
console.append("Template talk: " + Template_talk + "\n"); |
||
System.out.println("Template talk: " + Template_talk); |
System.out.println("Template talk: " + Template_talk); |
||
} |
|||
if (Help != 0) |
if (Help != 0) |
||
{ |
|||
console.append("Help: " + Help +"\n"); |
console.append("Help: " + Help + "\n"); |
||
System.out.println("Help: " + Help); |
System.out.println("Help: " + Help); |
||
} |
|||
if (Help_talk != 0) |
if (Help_talk != 0) |
||
{ |
|||
console.append("Help talk: " + Help_talk + "\n"); |
console.append("Help talk: " + Help_talk + "\n"); |
||
System.out.println("Help talk: " + Help_talk); |
System.out.println("Help talk: " + Help_talk); |
||
} |
|||
if (Category != 0) |
if (Category != 0) |
||
{ |
|||
console.append("Category:" + Category + "\n"); |
console.append("Category: " + Category + "\n"); |
||
System.out.println("Category:" + Category); |
System.out.println("Category: " + Category); |
||
} |
|||
if (Category_talk != 0) |
if (Category_talk != 0) |
||
{ |
|||
console.append("Category talk: " + Category_talk + "\n"); |
console.append("Category talk: " + Category_talk + "\n"); |
||
System.out.println("Category talk: " + Category_talk); |
System.out.println("Category talk: " + Category_talk); |
||
} |
|||
if (Portal != 0) |
if (Portal != 0) |
||
{ |
|||
console.append("Portal: " + Portal + "\n"); |
console.append("Portal: " + Portal + "\n"); |
||
System.out.println("Portal: " + Portal); |
System.out.println("Portal: " + Portal); |
||
} |
|||
if (Portal_talk != 0) |
if (Portal_talk != 0) |
||
{ |
|||
console.append("Portal talk: " + Portal_talk + "\n"); |
console.append("Portal talk: " + Portal_talk + "\n"); |
||
System.out.println("Portal talk: " + Portal_talk); |
System.out.println("Portal talk: " + Portal_talk); |
||
} |
|||
if (Special != 0) |
if (Special != 0) |
||
{ |
|||
console.append("Special: " + Special + "\n"); |
console.append("Special: " + Special + "\n"); |
||
System.out.println("Special: " + Special); |
System.out.println("Special: " + Special); |
||
} |
|||
if (Media != 0) |
if (Media != 0) |
||
{ |
|||
console.append("Media: " + Media + "\n"); |
console.append("Media: " + Media + "\n"); |
||
System.out.println("Media: " + Media); |
System.out.println("Media: " + Media); |
||
} |
|||
System.out.println("-------------------"); |
System.out.println("-------------------"); |
||
System.out.println("Overall statistics: "); |
|||
System.out.println("Total edits: " + numEdits); |
|||
console.append("-------------------" + "\n" + "Overall statistics:" |
console.append("-------------------" + "\n" + "Overall statistics:" |
||
+ "\n" + "Total edits: " + numEdits + "\n"); |
|||
System.out.println("Minor edits: " + minorEdits); |
System.out.println("Minor edits: " + minorEdits); |
||
console.append("Minor edits: " + minorEdits+ "\n"); |
console.append("Minor edits: " + minorEdits + "\n"); |
||
System.out.println("Percentage of minor edits: " |
System.out.println("Percentage of minor edits: " |
||
+ (int) (((double) minorEdits) / numEdits * 100.0) + "% *"); |
|||
console.append("Percentage of minor edits: " |
console.append("Percentage of minor edits: " |
||
+ (int) (((double) minorEdits) / numEdits * 100.0) + "% *\n"); |
|||
System.out.println("* - percentage is always rounded down to nearest whole number percentage."); |
System.out |
||
.println("* - percentage is always rounded down to nearest whole number percentage."); |
|||
//console.append("* - percentage is always rounded down to nearest whole number percentage.\n"); |
// console.append("* - percentage is always rounded down to nearest |
||
// whole number percentage.\n"); |
|||
System.out.println("Percent edit summary: Not available yet."); |
System.out.println("Percent edit summary: Not available yet."); |
||
System.out.println("-------------------"); |
System.out.println("-------------------"); |
||
console.append("-------------------\n"); |
console.append("-------------------\n"); |
||
Line 333: | Line 350: | ||
return numEdits; |
return numEdits; |
||
} |
} |
||
private static void AnalyzeContrib(Contrib contrib) |
private static void AnalyzeContrib(Contrib contrib) |
||
{ |
{ |
||
if (contrib.minorEdit==true) |
if (contrib.minorEdit == true) |
||
{ |
{ |
||
minorEdits++; |
minorEdits++; |
||
Line 361: | Line 378: | ||
if (contrib.namespace.equals("Special")) Special++; |
if (contrib.namespace.equals("Special")) Special++; |
||
if (contrib.namespace.equals("Media")) Media++; |
if (contrib.namespace.equals("Media")) Media++; |
||
numEdits++; |
numEdits++; |
||
} |
} |
||
Line 367: | Line 384: | ||
public static void mainMulti(String[] args) throws IOException |
public static void mainMulti(String[] args) throws IOException |
||
{ |
{ |
||
String outFile$=null; |
String outFile$ = null; |
||
String inFile$=null; |
String inFile$ = null; |
||
outFile$ = JOptionPane.showInputDialog(null, |
outFile$ = JOptionPane.showInputDialog(null, |
||
"Enter the filename of the output file:", |
"Enter the filename of the output file:", outFile$, |
||
JOptionPane.QUESTION_MESSAGE); |
|||
FileWriter writer = new FileWriter(outFile$); |
|||
BufferedWriter out = new BufferedWriter(writer); |
|||
FileWriter writer = new FileWriter(outFile$); |
|||
out.write("<ul>",0,"<ul>".length()); |
|||
BufferedWriter out = new BufferedWriter(writer); |
|||
out.write("<ul>", 0, "<ul>".length()); |
|||
out.newLine(); |
out.newLine(); |
||
inFile$ = JOptionPane.showInputDialog(null, |
|||
"Enter the filename of the next contributions file:", |
"Enter the filename of the next contributions file:", inFile$, |
||
JOptionPane.QUESTION_MESSAGE); |
|||
while (inFile$ != null) |
|||
{ |
{ |
||
FileReader reader = new FileReader(inFile$); |
FileReader reader = new FileReader(inFile$); |
||
BufferedReader in = new BufferedReader(reader); |
BufferedReader in = new BufferedReader(reader); |
||
String inString =""; |
|||
boolean endContribs = false; //marks whether all the contributions have been parsed |
|||
inString = in.readLine(); //read from file and discard |
|||
do |
|||
{ |
|||
if ((inString.trim().compareTo("<ul>")==0) && (endContribs==false)) //until the <ul> tag is reached, |
|||
{ |
|||
do |
|||
{ |
|||
inString = in.readLine(); //then start reading and recording |
|||
if ((inString.trim().compareTo("</ul>")!=0)) |
|||
{ |
|||
out.write(inString.trim(),0,inString.length()); |
|||
out.newLine(); |
|||
String inString = ""; |
|||
boolean endContribs = false; // marks whether all the |
|||
} |
|||
// contributions have been parsed |
|||
else |
|||
{ |
|||
inString = in.readLine(); // read from file and discard |
|||
endContribs = true; |
|||
} |
|||
do |
|||
} while (endContribs != true); |
|||
{ |
|||
} |
|||
if ((inString.trim().compareTo("<ul>") == 0) |
|||
inString = in.readLine(); //read from file and discard |
|||
&& (endContribs == false)) // until the <ul> tag is |
|||
} while (inString != null); |
|||
// reached, |
|||
in.close(); |
|||
{ |
|||
inFile$ = JOptionPane.showInputDialog(null, |
|||
do |
|||
"Enter the filename of the next contributions file:", |
|||
{ |
|||
inFile$, JOptionPane.QUESTION_MESSAGE); |
|||
inString = in.readLine(); // then start reading and |
|||
// recording |
|||
if ((inString.trim().compareTo("</ul>") != 0)) |
|||
{ |
|||
out.write(inString.trim(), 0, inString.length()); |
|||
out.newLine(); |
|||
// System.out.println(inString.trim()); |
|||
} |
|||
else |
|||
{ |
|||
endContribs = true; |
|||
} |
|||
} |
|||
while (endContribs != true); |
|||
} |
|||
inString = in.readLine(); // read from file and discard |
|||
} |
|||
while (inString != null); |
|||
in.close(); |
|||
inFile$ = JOptionPane.showInputDialog(null, |
|||
"Enter the filename of the next contributions file:", |
|||
inFile$, JOptionPane.QUESTION_MESSAGE); |
|||
} |
} |
||
out.write("</ul>", 0, "</ul>".length()); |
|||
out.newLine(); |
out.newLine(); |
||
out.close(); |
|||
mainSingle(outFile$); |
|||
} |
} |
||
}</nowiki></pre> |
}</nowiki></pre> |
||
Line 434: | Line 457: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program HTML -> ContribFile converter for Flcelloguy's Tool |
* @program HTML -> ContribFile converter for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
||
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
||
*/ |
*/ |
||
import java.io.IOException; |
import java.io.IOException; |
||
import java.util.StringTokenizer; |
import java.util.StringTokenizer; |
||
public class PurgeContribs |
public class PurgeContribs |
||
{ |
{ |
||
/** |
|||
* @param purgedLine |
|||
/** |
|||
* |
* (input line in raw HTML, leading and trailing whitespace |
||
* removed) |
|||
* @return Contrib class object: for analysis |
* @return Contrib class object: for analysis |
||
* @throws IOException |
* @throws IOException |
||
*/ |
*/ |
||
public static Contrib Parse(String purgedLine) throws IOException |
|||
{ |
|||
/**** Take out the <li> tags ****/ |
|||
String midString1; |
|||
String timeStamp; |
|||
String editSummary = null; |
|||
String autoSummary = null; |
|||
boolean minorEdit = false; |
|||
boolean endLoop = false; |
|||
boolean newestEdit = false; |
|||
midString1 = purgedLine.substring(4, purgedLine.length() - 5); |
|||
/**** Process the time stamp ****/ |
|||
StringTokenizer token; |
|||
token = new StringTokenizer(midString1.trim()); |
|||
{ |
{ |
||
String time = token.nextToken(); |
|||
/**** Take out the <li> tags ****/ |
|||
String |
String day = token.nextToken(); |
||
String |
String month = token.nextToken(); |
||
String |
String year = token.nextToken(); |
||
timeStamp = time + " " + day + " " + month + " " + year; |
|||
boolean minorEdit = false; |
|||
} |
|||
boolean endLoop = false; |
|||
boolean newestEdit = false; |
|||
/**** Process the page name ****/ |
|||
midString1 = purgedLine.substring(4,purgedLine.length()-5); |
|||
String dummy = token.nextToken(); // get rid of (<a |
|||
/**** Process the time stamp ****/ |
|||
String URL = token.nextToken(); |
|||
String pageName = URL.substring(25, URL.length() - 20); |
|||
token = new StringTokenizer(midString1.trim()); |
|||
/**** Get rid of a few extra tokens ****/ |
|||
do |
|||
{ |
|||
endLoop = false; |
|||
dummy = token.nextToken(); |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
{ |
{ |
||
if (dummy.substring(dummy.lastIndexOf('<'), |
|||
String time = token.nextToken(); |
|||
dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) |
|||
String day = token.nextToken(); |
|||
endLoop = true; |
|||
String year = token.nextToken(); |
|||
timeStamp = time + " " + day + " " + month + " " + year; |
|||
} |
} |
||
} |
|||
while (endLoop == false); |
|||
/**** Process the page name ****/ |
|||
/**** Do the same with the diff link ****/ |
|||
String dummy = token.nextToken(); //get rid of (<a |
|||
dummy = token.nextToken(); // get rid of (<a |
|||
String dummyURL = token.nextToken(); // this URL is not needed, so it |
|||
String pageName = URL.substring(25,URL.length()-20); |
|||
// is dummied out |
|||
String dummyPageName = URL.substring(25, dummyURL.length() - 20); // ditto |
|||
/**** Get rid of a few extra tokens ****/ |
|||
do |
|||
{ |
|||
endLoop = false; |
|||
dummy = token.nextToken(); |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
{ |
{ |
||
if (dummy.substring(dummy.lastIndexOf('<'), |
|||
endLoop = false; |
|||
dummy |
dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) |
||
endLoop = true; |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
{ |
|||
if (dummy.substring(dummy.lastIndexOf('<'),dummy.lastIndexOf('<')+3).compareTo("</a>") != 0) endLoop = true; |
|||
} |
|||
} |
} |
||
} |
|||
while (endLoop==false); |
|||
while (endLoop == false); |
|||
/**** Do the same with the diff link ****/ |
|||
/**** Determine if edit is minor or not ****/ |
|||
dummy = token.nextToken(); //get rid of (<a |
|||
dummy = token.nextToken(); // get rid of (<span |
|||
dummy = token.nextToken(); // read the next token; it should be |
|||
String dummyPageName = URL.substring(25,dummyURL.length()-20); //ditto |
|||
// class="minor">m</span> if a minor edit |
|||
do |
|||
if (dummy.compareTo("class=\"minor\">m</span>") == 0) |
|||
{ |
|||
{ |
|||
endLoop = false; |
|||
minorEdit = true; |
|||
dummyPageName = null; |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
} |
|||
else |
|||
if (dummy.substring(dummy.lastIndexOf('<'),dummy.lastIndexOf('<')+3).compareTo("</a>") != 0) endLoop = true; |
|||
{ |
|||
minorEdit = false; |
|||
} |
|||
dummyPageName = dummy; |
|||
while (endLoop==false); |
|||
} |
|||
if (dummyPageName == null) // if it was a minor edit, advance token |
|||
// cursor to match non-minor edits |
|||
dummy = token.nextToken(); //get rid of (<span |
|||
{ |
|||
dummy = token.nextToken(); //read the next token; it should be class="minor">m</span> if a minor edit |
|||
dummy = token.nextToken(); // get rid of <a |
|||
if (dummy.compareTo("class=\"minor\">m</span>")==0) |
|||
dummyPageName = token.nextToken(); |
|||
} |
|||
do |
|||
{ |
|||
endLoop = false; |
|||
dummy = token.nextToken(); |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
{ |
{ |
||
if (dummy.substring(dummy.lastIndexOf('<'), |
|||
minorEdit = true; |
|||
dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) |
|||
dummyPageName = null; |
|||
endLoop = true; |
|||
} |
|||
else |
|||
{ |
|||
minorEdit = false; |
|||
dummyPageName = dummy; |
|||
} |
} |
||
} |
|||
while (endLoop == false); |
|||
/**** Process edit summaries ****/ |
|||
if (dummyPageName==null) //if it was a minor edit, advance token cursor to match non-minor edits |
|||
if (token.hasMoreTokens() == true) |
|||
{ |
|||
dummy = token.nextToken(); // read whether it is <span or <strong> |
|||
if (dummy.compareTo("<span") == 0) // <span: there is an edit |
|||
// summary |
|||
{ |
{ |
||
String dummySummary = token.nextToken(); |
|||
String midSummary = dummySummary.substring(17); |
|||
String endSummary = null; |
|||
} |
|||
StringBuilder summ = new StringBuilder(); |
|||
if (midSummary.compareTo("<span") == 0) // autosummary |
|||
do |
|||
{ |
|||
endLoop = false; |
|||
dummy = token.nextToken(); |
|||
if (dummy.lastIndexOf('<') != -1) |
|||
{ |
{ |
||
do |
|||
if (dummy.substring(dummy.lastIndexOf('<'),dummy.lastIndexOf('<')+3).compareTo("</a>") != 0) endLoop = true; |
|||
{ |
|||
endSummary = token.nextToken(); // read until "-</span>" |
|||
// is reached |
|||
if (endSummary.substring(0, 4).compareTo("href") == 0) |
|||
{ |
|||
String summaries[] = endSummary.split("#", 2); |
|||
autoSummary = summaries[1]; |
|||
} |
|||
} |
|||
while (endSummary.compareTo("-</span>") != 0); |
|||
} |
} |
||
else |
|||
} while (endLoop==false); |
|||
/*if (token.hasMoreTokens()==true) |
|||
{ |
|||
dummy = token.nextToken(); //read whether it is <span or <strong> |
|||
if (dummy.compareTo("<span")==0) //<span: there is an edit summary |
|||
{ |
{ |
||
endSummary = midSummary; |
|||
String dummySummary = token.nextToken(); |
|||
summ.append(endSummary); |
|||
} |
} |
||
endLoop = false; |
|||
do |
|||
//class='comment'>(added link to magnesium hydroxide page)</span> |
|||
{ |
|||
//(top)</strong> |
|||
summ.append(" "); |
|||
endSummary = token.nextToken(); // read edit summary for |
|||
// processing |
|||
summ.append(endSummary); |
|||
summ.trimToSize(); |
|||
if (summ.length() > 7) |
|||
{ |
|||
if (summ.substring(summ.length() - 7).compareTo( |
|||
"</span>") == 0) endLoop = true; |
|||
} |
|||
} |
|||
while (endLoop == false); |
|||
editSummary = summ.toString().substring(0, summ.length() - 8); |
|||
} |
} |
||
} |
|||
else //no edit summaries, edit is not the most recent edit to page |
|||
if (token.hasMoreTokens() == true) |
|||
{ |
|||
dummy = token.nextToken(); // read whether <strong> is present |
|||
if (dummy.compareTo("<strong>") == 0) // top edit) |
|||
{ |
{ |
||
String dummySummary = token.nextToken(); // get rid of |
|||
editSummary = null; |
|||
// "(top)</strong>" |
|||
newestEdit = false; |
|||
newestEdit = true; |
|||
} |
} |
||
} |
|||
else |
|||
Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, null, false); |
|||
// edit is not the most recent edit to page |
|||
return contrib; |
|||
{ |
|||
newestEdit = false; |
|||
} |
|||
Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, |
|||
editSummary, autoSummary, newestEdit); |
|||
return contrib; |
|||
} |
} |
||
}</nowiki></pre> |
}</nowiki></pre> |
||
Line 566: | Line 647: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program Contribution class for Flcelloguy's Tool |
* @program Contribution class for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
||
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
||
*/ |
*/ |
||
public class Contrib |
public class Contrib |
||
{ |
{ |
||
public Contrib(String inStamp, String inName, boolean inMin, String inSummary, boolean inTop) |
public Contrib(String inStamp, String inName, boolean inMin, String inSummary, String inAuto, boolean inTop) |
||
{ |
{ |
||
timeStamp = inStamp; |
timeStamp = inStamp; |
||
Line 582: | Line 662: | ||
shortName = FindShortName(pageName); |
shortName = FindShortName(pageName); |
||
minorEdit = inMin; |
minorEdit = inMin; |
||
editSummary= inSummary; |
editSummary = inSummary; |
||
autoSummary = inAuto; |
|||
topEdit = inTop; |
topEdit = inTop; |
||
Line 619: | Line 700: | ||
public boolean minorEdit; |
public boolean minorEdit; |
||
public String editSummary; |
public String editSummary; |
||
public String autoSummary; |
|||
public boolean topEdit; |
public boolean topEdit; |
||
private static String[] namespaceArray = //list of namespaces from [[Wikipedia:Namespace]] |
private static String[] namespaceArray = //list of namespaces from [[Wikipedia:Namespace]] |
||
Line 644: | Line 726: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program Graphical User Interface shell for Flcelloguy's Tool |
* @program Graphical User Interface shell for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
||
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
||
*/ |
*/ |
||
import javax.swing.JDesktopPane; |
import javax.swing.JDesktopPane; |
||
import javax.swing.JMenu; |
import javax.swing.JMenu; |
||
Line 779: | Line 860: | ||
}); |
}); |
||
} |
} |
||
}</nowiki></pre> |
}</nowiki></pre> |
||
Line 786: | Line 868: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program Query Graphical User Interface for Flcelloguy's Tool |
* @program Query Graphical User Interface for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
||
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
||
*/ |
*/ |
||
import javax.swing.BorderFactory; |
import javax.swing.BorderFactory; |
||
import javax.swing.JButton; |
import javax.swing.JButton; |
||
Line 898: | Line 979: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program Results Graphical User Interface for Flcelloguy's Tool |
* @program Results Graphical User Interface for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.30; released January 15, 2006 |
||
* @see [[User:Flcelloguy/Tool]] |
* @see [[User:Flcelloguy/Tool]] |
||
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
* @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool |
||
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
* @copyright Permission is granted to distribute freely, provided attribution is granted. |
||
*/ |
*/ |
||
import javax.swing.BorderFactory; |
import javax.swing.BorderFactory; |
||
import javax.swing.JInternalFrame; |
import javax.swing.JInternalFrame; |
||
Line 969: | Line 1,049: | ||
return panel; |
return panel; |
||
} |
} |
||
}</nowiki></pre> |
}</nowiki></pre> |
Revision as of 05:17, 16 January 2006
This is an extension of Flcelloguy's Tool which processes the HTML from a contribs file and parses it into a file readable by the tool. It is not finished, but the core is done, so I'm publishing it as v1.00.
Titoxd(?!? - did you read this?) 04:21, 8 December 2005 (UTC)
Compiling and executing the tool requires the JDK for Java 1.4.
Requirements
You must have a Java IDE and JDK (freeware available; see below). Thus, you must make two downloads - one from Sun Microsystems, which developed Java, and another from a Java run-time developement program. We recommend JCreator, BlueJ, or Eclipse.
Links
- Java 2 Platform Standard Edition 5.0
- Java(TM) 2 SDK, Standard Edition 1.4.2_10
- JCreator
- BlueJ
- Eclipse
Capabilities
Current Capabilities
- Count the number of edits
- Break down count by project namespace
- Count percentage and number of "minor" flag usage
Under development
- Correct parsing of edit summaries (through PurgeContribs.java) commit comming soon
- Adding support for direct analysis of Special:Contributions (beta version can process in 1,000-edit intervals)
- Add "kill bit" functionality for turning off tool remotely when server load requires it
Future developments (see also Feature requests)
- Merge the two pages (this page and User:Titoxd/Flcelloguy's Tool, perhaps under a WP:TOOLS subfile; rename to reflect that it's not "my" tool, but both my and Titoxd's tool
- Test and release Titoxd's contributions, which parses from the source code, instead of copying and pasting contributions
- Add more buttons to that, make more user friendly
- Add more detailed statistics with the parsing of timestamps, etc. available in Titoxd's code
- Better and more detailed instructions on how to download and use (perhaps a JAR?)
- JAR file done, just needs hosting
- Output to
txt
file for debugging (already done) and also to make copying results to the project easier - Add "First edit" date
- Count percentage of edit summary usage
- Attempt to make counting less crude by using a query
Known bugs
- User UI is not completely user-friendly, needs improvements and suggestions
- Need to create/update documentation to reflect move to WikiProject
Revisions
- v1.00: Original version, parses contribs to HTML file
- v1.01: Revision, split into a separate class, removed print command to system buffer (slowing down tool, only used for debugging)
- v2.00: begun processing the raw HTML file, parsed date/time stamp and page name into a special "Contrib" class. Minor edits, edit summaries and most recent edits still to be implemented.
- v2.10: Minor edits implemented, some code for edit summaries created (not operational yet).
- v2.15: Contrib class parses namespaces.
- v3.00: Merged my code with Flcelloguy's code.
- v3.10: Removed 5,000-edit limit (the program now allows input from multiple sources) and added a basic Graphical user interface.
- v3.20: Enhanced the GUI, output now sent to a window, not to console.
Code
Stats.java (same file as Flcelloguy's tool, only updated)
/** * @author Flcelloguy et al. * @program Flcelloguy's Tool (Stats.java) * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot code from http://en.wikipedia.org/wiki/User:Flcelloguy/Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. * Capabilities: Count edits, break down by namespace, count minor edits and calculate percentage * Please leave this block in. * Note: This new version does not require cut-and-pasting. Just go to http://en.wikipedia.org/w/index.php?title=Special:Contributions&target={{USERNAME}}&offset=0&limit=5000, where {{USERNAME}} is the name of the user you want to run a check on. */ import javax.swing.JOptionPane; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; // import java.util.FileReader; public class Stats { private static StringBuilder console = new StringBuilder(); private static int numEdits = 0; private static int minorEdits = 0; private static int Mainspace = 0; private static int Talk = 0; private static int User = 0; private static int User_talk = 0; private static int Wikipedia = 0; private static int Wikipedia_talk = 0; private static int Image = 0; private static int Image_talk = 0; private static int MediaWiki = 0; private static int MediaWiki_talk = 0; private static int Template = 0; private static int Template_talk = 0; private static int Help = 0; private static int Help_talk = 0; private static int Category = 0; private static int Category_talk = 0; private static int Portal = 0; private static int Portal_talk = 0; private static int Special = 0; // these two are listed at // [[Wikipedia:Namespace]], private static int Media = 0; // so I'm adding support for them, but I'm // not sure they are used. public static void reset() { console = new StringBuilder(); numEdits = 0; minorEdits = 0; Mainspace = 0; Talk = 0; User = 0; User_talk = 0; Wikipedia = 0; Wikipedia_talk = 0; Image = 0; Image_talk = 0; MediaWiki = 0; MediaWiki_talk = 0; Template = 0; Template_talk = 0; Help = 0; Help_talk = 0; Category = 0; Category_talk = 0; Portal = 0; Portal_talk = 0; Special = 0; // these two are listed at [[Wikipedia:Namespace]], Media = 0; // so I'm adding support for them, but I'm not sure they are // used. } public static void main(String args[]) throws IOException { /** * the GUI is too complex to screw up clean, crisp code like this, so * I'm moving it to a separate class. --Titoxd */ MainGUI.main(null); } public static void mainSingle(String inFile$) throws IOException { if (inFile$ == null) inFile$ = JOptionPane.showInputDialog("Input file:", inFile$); JOptionPane .showMessageDialog( null, "Current status: \n " + "Editcount only \n " + "Coming soon: \n " + "Breakdown by namespace \n Minor edits usage \n User friendly version \n Edit summary usage \n First edit date", "Information", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(null, "Number of edits: " + editcount(inFile$), "Results", JOptionPane.INFORMATION_MESSAGE); } public static int editcount(String inFile$) throws IOException { System.out.println("Computing..."); FileReader reader = new FileReader(inFile$); BufferedReader in = new BufferedReader(reader); // FileWriter writer = new FileWriter(outFile$); //for debugging // BufferedWriter out = new BufferedWriter(writer); //for debugging String inString = ""; Contrib outContrib; boolean endContribs = false; // marks whether all the contributions // have been parsed inString = in.readLine(); // read from file and discard do { if ((inString.trim().compareTo("<ul>") == 0) && (endContribs == false)) // until the <ul> tag is // reached, { do { inString = in.readLine(); // then start reading and // recording if ((inString.trim().compareTo("</ul>") != 0)) { // System.out.println(inString.trim()); outContrib = PurgeContribs.Parse(inString.trim()); // System.out.println(outString.trim()); AnalyzeContrib(outContrib); // out.newLine(); } else { endContribs = true; } } while (endContribs != true); } inString = in.readLine(); // read from file and discard } while (inString != null); in.close(); // out.close(); // Prints out statistics System.out.println("-------------------"); System.out.println("Breakdown by namespace:"); if (Mainspace != 0) { console.append("Main (articles): " + Mainspace + "\n"); System.out.println("Main (articles): " + Mainspace); } if (Talk != 0) { console.append("Article talk: " + Talk + "\n"); System.out.println("Article talk: " + Talk); } if (User != 0) { console.append("User: " + User + "\n"); System.out.println("User: " + User); } if (User_talk != 0) { console.append("User talk: " + User_talk + "\n"); System.out.println("User talk: " + User_talk); } if (Wikipedia != 0) { console.append("Project: " + Wikipedia + "\n"); System.out.println("Project: " + Wikipedia); } if (Wikipedia_talk != 0) { console.append("Project talk: " + Wikipedia_talk + "\n"); System.out.println("Project talk: " + Wikipedia_talk); } if (Image != 0) { console.append("Image: " + Image + "\n"); System.out.println("Image: " + Image); } if (Image_talk != 0) { console.append("Image talk: " + Image_talk + "\n"); System.out.println("Image talk: " + Image_talk); } if (MediaWiki != 0) { console.append("MediaWiki: " + MediaWiki + "\n"); System.out.println("MediaWiki: " + MediaWiki); } if (MediaWiki_talk != 0) { console.append("MediaWiki talk: " + MediaWiki_talk + "\n"); System.out.println("MediaWiki talk: " + MediaWiki_talk); } if (Template != 0) { console.append("Template: " + Template + "\n"); System.out.println("Template: " + Template); } if (Template_talk != 0) { console.append("Template talk: " + Template_talk + "\n"); System.out.println("Template talk: " + Template_talk); } if (Help != 0) { console.append("Help: " + Help + "\n"); System.out.println("Help: " + Help); } if (Help_talk != 0) { console.append("Help talk: " + Help_talk + "\n"); System.out.println("Help talk: " + Help_talk); } if (Category != 0) { console.append("Category: " + Category + "\n"); System.out.println("Category: " + Category); } if (Category_talk != 0) { console.append("Category talk: " + Category_talk + "\n"); System.out.println("Category talk: " + Category_talk); } if (Portal != 0) { console.append("Portal: " + Portal + "\n"); System.out.println("Portal: " + Portal); } if (Portal_talk != 0) { console.append("Portal talk: " + Portal_talk + "\n"); System.out.println("Portal talk: " + Portal_talk); } if (Special != 0) { console.append("Special: " + Special + "\n"); System.out.println("Special: " + Special); } if (Media != 0) { console.append("Media: " + Media + "\n"); System.out.println("Media: " + Media); } System.out.println("-------------------"); System.out.println("Overall statistics: "); System.out.println("Total edits: " + numEdits); console.append("-------------------" + "\n" + "Overall statistics:" + "\n" + "Total edits: " + numEdits + "\n"); System.out.println("Minor edits: " + minorEdits); console.append("Minor edits: " + minorEdits + "\n"); System.out.println("Percentage of minor edits: " + (int) (((double) minorEdits) / numEdits * 100.0) + "% *"); console.append("Percentage of minor edits: " + (int) (((double) minorEdits) / numEdits * 100.0) + "% *\n"); System.out .println("* - percentage is always rounded down to nearest whole number percentage."); // console.append("* - percentage is always rounded down to nearest // whole number percentage.\n"); System.out.println("Percent edit summary: Not available yet."); System.out.println("-------------------"); console.append("-------------------\n"); MainGUI.createTextFrame(console.toString()); return numEdits; } private static void AnalyzeContrib(Contrib contrib) { if (contrib.minorEdit == true) { minorEdits++; } if (contrib.namespace.equals("Main")) Mainspace++; if (contrib.namespace.equals("Talk")) Talk++; if (contrib.namespace.equals("User")) User++; if (contrib.namespace.equals("User_talk")) User_talk++; if (contrib.namespace.equals("Wikipedia")) Wikipedia++; if (contrib.namespace.equals("Wikipedia_talk")) Wikipedia_talk++; if (contrib.namespace.equals("Image")) Image++; if (contrib.namespace.equals("Image_talk")) Image_talk++; if (contrib.namespace.equals("MediaWiki")) MediaWiki++; if (contrib.namespace.equals("MediaWiki_talk")) MediaWiki_talk++; if (contrib.namespace.equals("Template")) Template++; if (contrib.namespace.equals("Template_talk")) Template_talk++; if (contrib.namespace.equals("Help")) Help++; if (contrib.namespace.equals("Help_talk")) Help_talk++; if (contrib.namespace.equals("Category")) Category++; if (contrib.namespace.equals("Category_talk")) Category_talk++; if (contrib.namespace.equals("Portal")) Portal++; if (contrib.namespace.equals("Portal_talk")) Portal_talk++; if (contrib.namespace.equals("Special")) Special++; if (contrib.namespace.equals("Media")) Media++; numEdits++; } public static void mainMulti(String[] args) throws IOException { String outFile$ = null; String inFile$ = null; outFile$ = JOptionPane.showInputDialog(null, "Enter the filename of the output file:", outFile$, JOptionPane.QUESTION_MESSAGE); FileWriter writer = new FileWriter(outFile$); BufferedWriter out = new BufferedWriter(writer); out.write("<ul>", 0, "<ul>".length()); out.newLine(); inFile$ = JOptionPane.showInputDialog(null, "Enter the filename of the next contributions file:", inFile$, JOptionPane.QUESTION_MESSAGE); while (inFile$ != null) { FileReader reader = new FileReader(inFile$); BufferedReader in = new BufferedReader(reader); String inString = ""; boolean endContribs = false; // marks whether all the // contributions have been parsed inString = in.readLine(); // read from file and discard do { if ((inString.trim().compareTo("<ul>") == 0) && (endContribs == false)) // until the <ul> tag is // reached, { do { inString = in.readLine(); // then start reading and // recording if ((inString.trim().compareTo("</ul>") != 0)) { out.write(inString.trim(), 0, inString.length()); out.newLine(); // System.out.println(inString.trim()); } else { endContribs = true; } } while (endContribs != true); } inString = in.readLine(); // read from file and discard } while (inString != null); in.close(); inFile$ = JOptionPane.showInputDialog(null, "Enter the filename of the next contributions file:", inFile$, JOptionPane.QUESTION_MESSAGE); } out.write("</ul>", 0, "</ul>".length()); out.newLine(); out.close(); mainSingle(outFile$); } }
PurgeContribs.java
/** * @author Titoxd * @program HTML -> ContribFile converter for Flcelloguy's Tool * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. */ import java.io.IOException; import java.util.StringTokenizer; public class PurgeContribs { /** * @param purgedLine * (input line in raw HTML, leading and trailing whitespace * removed) * @return Contrib class object: for analysis * @throws IOException */ public static Contrib Parse(String purgedLine) throws IOException { /**** Take out the <li> tags ****/ String midString1; String timeStamp; String editSummary = null; String autoSummary = null; boolean minorEdit = false; boolean endLoop = false; boolean newestEdit = false; midString1 = purgedLine.substring(4, purgedLine.length() - 5); /**** Process the time stamp ****/ StringTokenizer token; token = new StringTokenizer(midString1.trim()); { String time = token.nextToken(); String day = token.nextToken(); String month = token.nextToken(); String year = token.nextToken(); timeStamp = time + " " + day + " " + month + " " + year; } /**** Process the page name ****/ String dummy = token.nextToken(); // get rid of (<a String URL = token.nextToken(); String pageName = URL.substring(25, URL.length() - 20); /**** Get rid of a few extra tokens ****/ do { endLoop = false; dummy = token.nextToken(); if (dummy.lastIndexOf('<') != -1) { if (dummy.substring(dummy.lastIndexOf('<'), dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) endLoop = true; } } while (endLoop == false); /**** Do the same with the diff link ****/ dummy = token.nextToken(); // get rid of (<a String dummyURL = token.nextToken(); // this URL is not needed, so it // is dummied out String dummyPageName = URL.substring(25, dummyURL.length() - 20); // ditto do { endLoop = false; dummy = token.nextToken(); if (dummy.lastIndexOf('<') != -1) { if (dummy.substring(dummy.lastIndexOf('<'), dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) endLoop = true; } } while (endLoop == false); /**** Determine if edit is minor or not ****/ dummy = token.nextToken(); // get rid of (<span dummy = token.nextToken(); // read the next token; it should be // class="minor">m</span> if a minor edit if (dummy.compareTo("class=\"minor\">m</span>") == 0) { minorEdit = true; dummyPageName = null; } else { minorEdit = false; dummyPageName = dummy; } if (dummyPageName == null) // if it was a minor edit, advance token // cursor to match non-minor edits { dummy = token.nextToken(); // get rid of <a dummyPageName = token.nextToken(); } do { endLoop = false; dummy = token.nextToken(); if (dummy.lastIndexOf('<') != -1) { if (dummy.substring(dummy.lastIndexOf('<'), dummy.lastIndexOf('<') + 3).compareTo("</a>") != 0) endLoop = true; } } while (endLoop == false); /**** Process edit summaries ****/ if (token.hasMoreTokens() == true) { dummy = token.nextToken(); // read whether it is <span or <strong> if (dummy.compareTo("<span") == 0) // <span: there is an edit // summary { String dummySummary = token.nextToken(); String midSummary = dummySummary.substring(17); String endSummary = null; StringBuilder summ = new StringBuilder(); if (midSummary.compareTo("<span") == 0) // autosummary { do { endSummary = token.nextToken(); // read until "-</span>" // is reached if (endSummary.substring(0, 4).compareTo("href") == 0) { String summaries[] = endSummary.split("#", 2); autoSummary = summaries[1]; } } while (endSummary.compareTo("-</span>") != 0); } else { endSummary = midSummary; summ.append(endSummary); } endLoop = false; do { summ.append(" "); endSummary = token.nextToken(); // read edit summary for // processing summ.append(endSummary); summ.trimToSize(); if (summ.length() > 7) { if (summ.substring(summ.length() - 7).compareTo( "</span>") == 0) endLoop = true; } } while (endLoop == false); editSummary = summ.toString().substring(0, summ.length() - 8); } } if (token.hasMoreTokens() == true) { dummy = token.nextToken(); // read whether <strong> is present if (dummy.compareTo("<strong>") == 0) // top edit) { String dummySummary = token.nextToken(); // get rid of // "(top)</strong>" newestEdit = true; } } else // edit is not the most recent edit to page { newestEdit = false; } Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, editSummary, autoSummary, newestEdit); return contrib; } }
Contrib.java
/** * @author Titoxd * @program Contribution class for Flcelloguy's Tool * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. */ public class Contrib { public Contrib(String inStamp, String inName, boolean inMin, String inSummary, String inAuto, boolean inTop) { timeStamp = inStamp; pageName = inName; namespace = FindNameSpace(pageName); shortName = FindShortName(pageName); minorEdit = inMin; editSummary = inSummary; autoSummary = inAuto; topEdit = inTop; } private String FindNameSpace(String inName) { String[] nameArray=inName.split(":",2); if (nameArray[0].compareTo(inName)==0) { nameArray[0] = namespaceArray[0]; } return nameArray[0]; } private String FindShortName(String inName) { String name=null; if (inName.contains(":")) { String[] nameArray=inName.split(":",2); name = nameArray[1]; } else { name = inName; } return name; } public String timeStamp; public String pageName; public String namespace; public String shortName; public boolean minorEdit; public String editSummary; public String autoSummary; public boolean topEdit; private static String[] namespaceArray = //list of namespaces from [[Wikipedia:Namespace]] { "Main", "Talk", "User", "User_talk", "Wikipedia", "Wikipedia_talk", "Image", "Image_talk", "MediaWiki", "MediaWiki_talk", "Template", "Template_talk", "Help", "Help_talk", "Category", "Category_talk", "Portal", "Portal_talk", "Media", "Special", }; public String toString() { String returnString = "Time: " + timeStamp + "\r" + "Page: " + pageName + " (Namespace: " + namespace + "; Article: " + shortName + ")\r" + "Minor edit: " + minorEdit + "\r" + "Edit Summary: " + editSummary + "\r" + "Most recent edit: " + topEdit; return returnString; } }
MainGUI.java
/** * @author Titoxd * @program Graphical User Interface shell for Flcelloguy's Tool * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. */ import javax.swing.JDesktopPane; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JMenuBar; import javax.swing.JFrame; import javax.swing.KeyStroke; import javax.swing.UIManager; import java.awt.event.*; import java.awt.*; public class MainGUI extends JFrame implements ActionListener { static JDesktopPane desktop; public MainGUI() { super("Flcelloguy's Tool"); //Make the big window be indented 50 pixels from each edge //of the screen. int inset = 100; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setBounds(inset, inset, screenSize.width - inset*2, screenSize.height - inset*2); //Set up the GUI. desktop = new JDesktopPane(); //a specialized layered pane createFrame(); //create first "window" setContentPane(desktop); setJMenuBar(createMenuBar()); //Make dragging a little faster but perhaps uglier. desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); } protected JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); //Set up the lone menu. JMenu menu = new JMenu("Document"); menu.setMnemonic(KeyEvent.VK_D); menuBar.add(menu); //Set up the first menu item. JMenuItem menuItem = new JMenuItem("New Query"); menuItem.setMnemonic(KeyEvent.VK_N); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_N, ActionEvent.ALT_MASK)); menuItem.setActionCommand("new"); menuItem.addActionListener(this); menu.add(menuItem); //Set up the second menu item. menuItem = new JMenuItem("Quit"); menuItem.setMnemonic(KeyEvent.VK_Q); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_Q, ActionEvent.ALT_MASK)); menuItem.setActionCommand("quit"); menuItem.addActionListener(this); menu.add(menuItem); return menuBar; } //React to menu selections. public void actionPerformed(ActionEvent e) { if ("new".equals(e.getActionCommand())) { //new createFrame(); } else { //quit quit(); } } //Create a new internal frame. protected void createFrame() { QueryFrame frame = new QueryFrame(); frame.setVisible(true); desktop.add(frame); try { frame.setSelected(true); } catch (java.beans.PropertyVetoException e) {} } protected static void createTextFrame(String passedString) { ResultsFrame frame = new ResultsFrame(passedString); frame.setVisible(true); desktop.add(frame); try { frame.setSelected(true); } catch (java.beans.PropertyVetoException e) {} } protected void quit() { System.exit(0); } /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { } //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); //Create and set up the window. MainGUI frame = new MainGUI(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Display the window. frame.setVisible(true); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }
QueryFrame.java
/** * @author Titoxd * @program Query Graphical User Interface for Flcelloguy's Tool * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. */ import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JPanel; import java.awt.event.*; import java.awt.*; import java.io.IOException; /* Used by MainGUI.java. */ public class QueryFrame extends JInternalFrame implements ActionListener { static int openFrameCount = 0; static final int xOffset = 30, yOffset = 30; private JLabel topLabel = new JLabel("Look at the online help: http://en.wikipedia.org/wiki/User:Flcelloguy/Tool/Help"); private JLabel label = new JLabel("Flcelloguy's Tool: Statistics for editcounters."); private String[] phases = { "Single file (up to 5,000 edits)", "Multiple files (5000 edits or more)"}; private JComboBox box = new JComboBox(phases); private JButton button = new JButton("Proceed"); public QueryFrame() { super("New Query "+ (++openFrameCount), true, //resizable true, //closable true, //maximizable true);//iconifiable //...Create the GUI and put it in the window... JPanel panel = (JPanel) createComponents(); panel.setBorder(BorderFactory.createEmptyBorder( 20, //top 30, //left 10, //bottom 30) //right ); getContentPane().add(panel); //...Then set the window size or call pack... pack(); //Set the window's location. setLocation(xOffset*openFrameCount, yOffset*openFrameCount); } public Component createComponents() { label.setLabelFor(button); button.setMnemonic('i'); button.addActionListener(this); box.setSelectedIndex(0); box.addActionListener(this); JPanel panel = new JPanel(new GridLayout(0,1)); panel.add(topLabel); panel.add(box); panel.add(button); panel.add(label); return panel; } public void actionPerformed(ActionEvent event) { if ("comboBoxChanged".equals(event.getActionCommand())) { if (box.getSelectedItem().equals(phases[0])) label.setText("This method asks you to parse a single contributions file."); if (box.getSelectedItem().equals(phases[1])) label.setText("This method asks you for several contributions files to parse."); } if ("Proceed".equals(event.getActionCommand())) { if (box.getSelectedItem().equals(phases[0])) try { Stats.reset(); Stats.mainSingle(null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (box.getSelectedItem().equals(phases[1])) try { Stats.reset(); Stats.mainMulti(null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } dispose(); } } }
ResultsFrame.java
/** * @author Titoxd * @program Results Graphical User Interface for Flcelloguy's Tool * @version 3.30; released January 15, 2006 * @see [[User:Flcelloguy/Tool]] * @docRoot http://en.wikipedia.org/wiki/User:Titoxd/Flcelloguy's_Tool * @copyright Permission is granted to distribute freely, provided attribution is granted. */ import javax.swing.BorderFactory; import javax.swing.JInternalFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import java.awt.*; /* Used by MainGUI.java. */ public class ResultsFrame extends JInternalFrame { private static final long serialVersionUID = -132302847428809365L; static int openFrameCount = 0; static final int xOffset = 30, yOffset = 30; private String consoleText=null; public ResultsFrame(String inText) { super("Query Results "+ (++openFrameCount), true, //resizable true, //closable true, //maximizable true);//iconifiable //...Create the GUI and put it in the window... consoleText = inText; JPanel panel = (JPanel) createComponents(); panel.setBorder(BorderFactory.createEmptyBorder( 20, //top 30, //left 10, //bottom 30) //right ); getContentPane().add(panel); //...Then set the window size or call pack... pack(); //Set the window's location. setLocation(xOffset*openFrameCount, yOffset*openFrameCount); } public Component createComponents() { //Create a text area. JTextArea textArea = new JTextArea(consoleText); textArea.setFont(new Font("Monospace", Font.PLAIN, 12)); textArea.setLineWrap(true); textArea.setWrapStyleWord(true); JScrollPane areaScrollPane = new JScrollPane(textArea); areaScrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); areaScrollPane.setPreferredSize(new Dimension(250, 250)); areaScrollPane.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("WikiText"), BorderFactory.createEmptyBorder(5,5,5,5)), areaScrollPane.getBorder())); JPanel panel = new JPanel(new GridLayout(0,1)); panel.add(areaScrollPane); return panel; } }