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 String username, representing a valid username * @param String password, representing the password for the username * @return A boolean representing whether the login was successful or not; * unsuccessful logins require a wait of 60 seconds * @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) { 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; 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 name of the page to be edited * @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 (!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 responseHTML = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { responseHTML.append(line + "\n"); } reader.close(); Pattern pattern = Pattern.compile("<input type='hidden' value=\"(.*?)\" name=\"(.*?)\" />"); Matcher matcher = pattern.matcher(responseHTML.toString()); StringBuffer textToSend = new StringBuffer(); //all of the following parameters are required. If one cannot be found, //it will not be included; the data will be sent, but the edit won't happen while (matcher.find()) { if (matcher.group(2).equals("wpStarttime")) textToSend.append("&wpStarttime=" + matcher.group(1)); if (matcher.group(2).equals("wpEdittime")) textToSend.append("&wpEdittime=" + matcher.group(1)); if (matcher.group(2).equals("wpEditToken")) textToSend.append("&wpEditToken=" + matcher.group(1)); } 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") + "\n\nAddendum", "minor test edit", true); } }
The above code would result in this.