User:Gracenotes/Java code
Appearance
Java classes
The following classes would be useful for making a bot in java.
WikiSessionManager.java
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLConnection;
/**
* WikiSessionManager is a utility class that logs into the English
* Wikipedia and facilitates making HTTP requests with cookies.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @author Gracenotes
* @version 0.1
**/
public class WikiSessionManager
{
private String cookie;
private String sessionData;
private boolean loggedIn;
/**
* Constructor for objects of class WikiSessionManager
*/
public WikiSessionManager()
{
this.loggedIn = false;
this.sessionData = "";
this.cookie = "";
}
/**
* Gets the cookies needed to make edits
*
* @param username a String representing a valid username
* @param password a String representing the password for the username
* @throws java.io.IOException if something goes awry with the connection
*/
public void userLogin(String username, String password) throws IOException
{
username = username.trim();
password = password.trim();
if (username.length() == 0 || password.length() == 0) throw new IllegalArgumentException("Blank parameter");
URL url = new URL("http://en.wikipedia.org/w/api.php?action=login" +
"&lgname=" + URLEncoder.encode(username, "UTF-8") +
"&lgpassword=" + URLEncoder.encode(password, "UTF-8"));
URLConnection connection = url.openConnection();
String headerName;
StringBuffer receivedCookie = new StringBuffer();
int i = 0;
while ((headerName = connection.getHeaderFieldKey(++i)) != null)
{
if (headerName.equalsIgnoreCase("Set-Cookie"))
{
receivedCookie.append(connection.getHeaderField(i).split(";")[0] + "; ");
}
}
this.cookie = receivedCookie.toString();
this.loggedIn = this.cookie.indexOf("enwikiToken=") != -1;
}
/**
* Logs a user out
*
* @throws java.io.IOException if something goes awry with the connection
*/
public void userLogout() throws IOException
{
if (!this.loggedIn)
return;
URL url = new URL("http://en.wikipedia.org/w/index.php?title=Special:Userlogout");
URLConnection connection = url.openConnection();
this.loggedIn = false;
this.cookie = "";
}
/**
* Indicates whether a user is logged in or not
*
* @return A boolean showing whether a user is logged in or not
*/
public boolean isLoggedIn()
{
return this.loggedIn;
}
/**
* Sets a connection to use cookies
*
* @param connection The URLConnection on which the cookie header should be set
* @throws java.io.IOException if something goes awry with the connection
*/
public void addCookies(URLConnection connection)
{
connection.setRequestProperty("Cookie", this.cookie + this.sessionData);
}
/**
* Finds a user's session data; for some reason, it's not received from the login.
* This should be done at some point before making a POST request
*
* @param connection The URLConnection from which the session data should be retrieved
* @returns A boolean, if the session data could be retrieved or not
* @throws java.io.IOException if something goes awry with the connection
*/
public boolean findSessionData(URLConnection connection)
{
sessionData = "";
String headerName;
int i = 0;
while ((headerName = connection.getHeaderFieldKey(++i)) != null)
{
if (headerName.equals("Set-Cookie") && connection.getHeaderField(i).indexOf("enwiki_session") == 0)
this.sessionData = connection.getHeaderField(i).split(";")[0];
}
return sessionData != "";
}
}
WikiEdit
import java.io.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLConnection;
/**
* WikiEdit is a class that depends on WikiSessionManager. It gets wikitext
* of articles and edits them
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* @author Gracenotes
* @version 0.1
**/
public class WikiEdit
{
private WikiSessionManager session;
/**
* Constructor for objects of class WikiEdit
*
* @param username a String representing a valid username
* @param password a String representing the password for the username
* @throws java.io.IOException if something goes awry with the connection
*/
public WikiEdit(String username, String password) throws IOException
{
session = new WikiSessionManager();
session.userLogin(username, password);
}
/**
* Indicates whether a user is logged in or not
*
* @return A boolean showing whether a user is logged in or not
*/
public boolean isLoggedIn()
{
return session.isLoggedIn();
}
/**
* Gets the wikitext of a page. TODO: Use api.php to get wikitext, not index.php
*
* @param page A String representing the title of the page from which wikitext should be received
* @return The wikitext of a page, a String
* @throws java.io.IOException if something goes awry with the connection, or if the page does not exist
*/
public String getWikitext(String page) throws IOException
{
URL url = new URL("http://en.wikipedia.org/w/index.php?title=" + URLEncoder.encode(page, "UTF-8") + "&action=raw");
URLConnection connection = url.openConnection();
session.addCookies(connection);
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer responseText = new StringBuffer();
String line;
while ((line = reader.readLine()) != null)
{
responseText.append(line + "\n");
}
reader.close();
return responseText.toString();
}
/**
* Edits a page. TODO: include support for maxlag
*
* @param page A String representing the name of the page to be edited
* @param wikitext A String representing the text to send for the edit
* @param editsum A String representing the edit summary for the edit
* @param minor A boolean: If the edit should be marked as minor
* @throws java.io.IOException if something goes awry with the connection
*/
public void editPage(String page, String wikitext, String editsum, boolean minor) throws IOException
{
//if we're not logged in
if (!this.isLoggedIn())
return;
String pageURL = "http://en.wikipedia.org/w/index.php?title=" + URLEncoder.encode(page, "UTF-8");
String sessionData = "";
String headerName;
int i = 0;
URL url = new URL(pageURL + "&action=edit");
URLConnection connection = url.openConnection();
session.addCookies(connection);
//if we couldn't get the session data
if (!session.findSessionData(connection))
return;
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer textToSend = new StringBuffer();
String line;
String inputName;
Pattern pattern = Pattern.compile("<input type='hidden' value=\"(.*?)\" name=\"(.*?)\" />");
Matcher matcher = pattern.matcher("h");
boolean couldRetreiveEditToken = false;
while ((line = reader.readLine()) != null)
{
if (line.indexOf("<input type='hidden'") != -1)
{
matcher = pattern.matcher(line);
matcher.find();
inputName = matcher.group(2);
if (inputName.equals("wpStarttime"))
textToSend.append("&wpStarttime=" + matcher.group(1));
else if (inputName.equals("wpEdittime"))
textToSend.append("&wpEdittime=" + matcher.group(1));
else if (inputName.equals("wpEditToken"))
{
textToSend.append("&wpEditToken=" + matcher.group(1));
couldRetreiveEditToken = true;
break; //we don't need anything else
}
}
}
reader.close();
//if we couldn't get the edit token
if (!couldRetreiveEditToken)
return;
textToSend.append("&wpTextbox1=" + URLEncoder.encode(wikitext, "UTF-8"));
textToSend.append("&wpSummary=" + URLEncoder.encode(editsum, "UTF-8"));
if (minor)
textToSend.append("&wpMinoredit=0");
textToSend.deleteCharAt(0);
//now, send the data
url = new URL(pageURL + "&action=submit");
connection = url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
session.addCookies(connection);
OutputStreamWriter output = new OutputStreamWriter(connection.getOutputStream());
output.write(textToSend.toString());
output.flush();
output.close();
BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer responseText = new StringBuffer();
while ((line = input.readLine()) != null)
{
responseText.append(line + "\n");
}
}
}
WikiEditTest
import java.net.*;
import java.io.*;
public class WikiEditTest
{
public static void main() throws IOException
{
WikiEdit edit = new WikiEdit("Gracenotes", "password");
if (!edit.isLoggedIn())
{
System.out.println("Not logged in");
return;
}
edit.editPage("User:Gracenotes/Sandbox", edit.getWikitext("User:Gracenotes/Sandbox") + "\nAddendum", "minor test edit", true);
}
}
The above code would result in this.