Content deleted Content added
Pathoschild (talk | contribs) Designed header infobox per Titoxd's request on IRC |
→PurgeContribs.java: bug resolved, increase version to 3.40 ^_^ |
||
Line 451: | Line 451: | ||
* @author Titoxd |
* @author Titoxd |
||
* @program HTML -> ContribFile converter for Flcelloguy's Tool |
* @program HTML -> ContribFile converter for Flcelloguy's Tool |
||
* @version 3. |
* @version 3.40; released January 28, 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; |
||
Line 564: | Line 565: | ||
while (endLoop == false); |
while (endLoop == false); |
||
/**** |
/**** flush the StringTokenizer ****/ |
||
if (token.hasMoreTokens() == true) |
|||
StringBuilder tokenDump = new StringBuilder(); |
|||
String dump; |
|||
if (token.hasMoreTokens() == true) // |
|||
{ |
{ |
||
do |
|||
dummy = token.nextToken(); // read whether it is <span or <strong> |
|||
if (dummy.compareTo("<span") == 0) // <span: there is an edit summary |
|||
{ |
{ |
||
tokenDump.append(token.nextToken()); |
|||
tokenDump.append(' '); |
|||
String midSummary = dummySummary.substring(17); |
|||
} while (token.hasMoreTokens()==true); |
|||
String endSummary = null; |
|||
tokenDump.trimToSize(); |
|||
StringBuilder summ = new StringBuilder(); |
|||
dump = tokenDump.toString(); |
|||
if (midSummary.endsWith("</span>")== true) //one-word edit summary (will only trigger when there's no section editing) |
|||
{ |
|||
autoSummary = null; |
|||
summ.append(midSummary); |
|||
} |
|||
else |
|||
{ |
|||
if (midSummary.compareTo("<span") == 0) // autosummary |
|||
{ |
|||
do |
|||
{ |
|||
endSummary = token.nextToken(); // read until "-</span>" is reached |
|||
if (endSummary.startsWith("href") == true) |
|||
{ |
|||
String summaries[] = endSummary.split("#", 2); |
|||
if (sectionParsed == false) |
|||
{ |
|||
autoSummary = summaries[1]; |
|||
sectionParsed = true; |
|||
} |
|||
} |
|||
} |
|||
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); |
|||
} |
|||
} |
} |
||
else //not top edit, no edit summary |
|||
if (token.hasMoreTokens() == true) |
|||
{ |
{ |
||
dump = null; |
|||
dummy = token.nextToken(); // read whether <strong> is present |
|||
} |
|||
if (dummy.compareTo("<strong>") == 0) // top edit) |
|||
/**** Top edit? ****/ |
|||
if (dump != null && dump.contains("<strong> (top)</strong>") == true) |
|||
{ |
{ |
||
token.nextToken(); // get rid of (top)</strong>" |
|||
newestEdit = true; |
newestEdit = true; |
||
dump = dump.substring(0,dump.indexOf("<strong> (top)</strong>")); //truncate to remove rollback links and other garbage |
|||
dump = dump.trim(); |
|||
} |
} |
||
else newestEdit = false; |
|||
/**** Process edit summary ****/ |
|||
String[] summaries = ParseSummary(dump); |
|||
autoSummary = summaries[0]; |
|||
editSummary = summaries[1]; |
|||
Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, |
|||
editSummary, autoSummary, newestEdit); |
|||
return contrib; |
|||
} |
|||
/** |
|||
* @param dump |
|||
* @return String[2] array, String[0] is the auto summary, String[1] is the manual summary |
|||
*/ |
|||
private static String[] ParseSummary(String dump) |
|||
{ |
|||
/****Check that there is an edit summary to begin with ****/ |
|||
String[] summaryArray = new String[2]; |
|||
boolean sectionParsed = false; |
|||
if (dump == null | dump=="") |
|||
{ |
|||
summaryArray[0]=null; |
|||
summaryArray[1]=null; |
|||
} |
} |
||
else |
else |
||
// edit is not the most recent edit to page |
|||
{ |
{ |
||
if (dump.indexOf("<span class=\"autocomment\">") != -1) //autocomment present |
|||
newestEdit = false; |
|||
{ |
|||
String autoSummary = dump.substring(dump.indexOf("<span class=\"autocomment\">"),dump.indexOf("</span>")+7); |
|||
String summaries[] = autoSummary.split("#", 2); |
|||
if (sectionParsed == false) |
|||
{ |
|||
summaryArray[0] = summaries[1]; |
|||
sectionParsed = true; |
|||
} |
|||
summaryArray[1]= dump.substring(0,dump.indexOf(autoSummary)); |
|||
summaryArray[1] = summaryArray[1].concat(dump.substring(dump.indexOf(autoSummary)+ autoSummary.length()).trim()); |
|||
summaryArray[0] = summaryArray[0].substring(0,summaryArray[0].lastIndexOf("<")); |
|||
summaryArray[0] = summaryArray[0].substring(summaryArray[0].lastIndexOf(">")+1); |
|||
if (summaryArray[0].endsWith(" -")== true) |
|||
{ |
|||
summaryArray[0] = summaryArray[0].substring(0,summaryArray[0].length()-1); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (dump != "") summaryArray[1] = dump; |
|||
} |
|||
if (summaryArray[0]=="") summaryArray[0]=null; |
|||
if (summaryArray[1]=="") summaryArray[1]=null; //so the edge cases don't trigger exceptions |
|||
if (summaryArray[1] != null) |
|||
{ |
|||
if (summaryArray[1].length() != 0) |
|||
{ |
|||
summaryArray[1] = summaryArray[1].substring(summaryArray[1].indexOf(">")+1,summaryArray[1].lastIndexOf("<")); |
|||
summaryArray[1] = summaryArray[1].trim(); |
|||
} |
|||
} |
|||
if (summaryArray[0] != null) summaryArray[0] = summaryArray[0].trim(); |
|||
} |
} |
||
return summaryArray; |
|||
Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, |
|||
editSummary, autoSummary, newestEdit); |
|||
return contrib; |
|||
} |
} |
||
}</nowiki></pre> |
}</nowiki></pre> |
||
Revision as of 01:39, 29 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)
- Adding support for direct analysis of Special:Contributions (beta version can process in 1,000-edit intervals) (done, will be available in 4.0)
- Add "kill bit" functionality for turning off tool remotely when server load requires it (done, will be available in 4.0)
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
- Exceptions not handled sometimes, need to process correctly
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.
- v3.30: Enabling parsing of edit summaries and automatic section-edit summaries.
- v3.31: Bug fix in edit summary parsing: now processes one-word edit summaries correctly
Code
Stats.java (same file as Flcelloguy's tool, only updated)
/** * @author Flcelloguy et al. * @program Flcelloguy's Tool (Stats.java) * @version 3.32; 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.40; released January 28, 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; boolean sectionParsed = 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); /**** flush the StringTokenizer ****/ StringBuilder tokenDump = new StringBuilder(); String dump; if (token.hasMoreTokens() == true) // { do { tokenDump.append(token.nextToken()); tokenDump.append(' '); } while (token.hasMoreTokens()==true); tokenDump.trimToSize(); dump = tokenDump.toString(); } else //not top edit, no edit summary { dump = null; } /**** Top edit? ****/ if (dump != null && dump.contains("<strong> (top)</strong>") == true) { newestEdit = true; dump = dump.substring(0,dump.indexOf("<strong> (top)</strong>")); //truncate to remove rollback links and other garbage dump = dump.trim(); } else newestEdit = false; /**** Process edit summary ****/ String[] summaries = ParseSummary(dump); autoSummary = summaries[0]; editSummary = summaries[1]; Contrib contrib = new Contrib(timeStamp, pageName, minorEdit, editSummary, autoSummary, newestEdit); return contrib; } /** * @param dump * @return String[2] array, String[0] is the auto summary, String[1] is the manual summary */ private static String[] ParseSummary(String dump) { /****Check that there is an edit summary to begin with ****/ String[] summaryArray = new String[2]; boolean sectionParsed = false; if (dump == null | dump=="") { summaryArray[0]=null; summaryArray[1]=null; } else { if (dump.indexOf("<span class=\"autocomment\">") != -1) //autocomment present { String autoSummary = dump.substring(dump.indexOf("<span class=\"autocomment\">"),dump.indexOf("</span>")+7); String summaries[] = autoSummary.split("#", 2); if (sectionParsed == false) { summaryArray[0] = summaries[1]; sectionParsed = true; } summaryArray[1]= dump.substring(0,dump.indexOf(autoSummary)); summaryArray[1] = summaryArray[1].concat(dump.substring(dump.indexOf(autoSummary)+ autoSummary.length()).trim()); summaryArray[0] = summaryArray[0].substring(0,summaryArray[0].lastIndexOf("<")); summaryArray[0] = summaryArray[0].substring(summaryArray[0].lastIndexOf(">")+1); if (summaryArray[0].endsWith(" -")== true) { summaryArray[0] = summaryArray[0].substring(0,summaryArray[0].length()-1); } } else { if (dump != "") summaryArray[1] = dump; } if (summaryArray[0]=="") summaryArray[0]=null; if (summaryArray[1]=="") summaryArray[1]=null; //so the edge cases don't trigger exceptions if (summaryArray[1] != null) { if (summaryArray[1].length() != 0) { summaryArray[1] = summaryArray[1].substring(summaryArray[1].indexOf(">")+1,summaryArray[1].lastIndexOf("<")); summaryArray[1] = summaryArray[1].trim(); } } if (summaryArray[0] != null) summaryArray[0] = summaryArray[0].trim(); } return summaryArray; } }
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; } }