Jump to content

User:Gracenotes/Java code

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Gracenotes (talk | contribs) at 10:18, 4 June 2007 (code). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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] + "; ");
            }
            System.out.println(connection.getHeaderField(i));
        }
        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 (!this.isLoggedIn())
           throw new IOException("You must be logged in to edit a page.");
        
        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;
        Pattern pattern = Pattern.compile("<input type='hidden' value=\"(.*?)\" name=\"(.*?)\" />");
        Matcher matcher = pattern.matcher("h");
        while ((line = reader.readLine()) != null)
        {
            if (line.indexOf("<input type='hidden'") != -1)
            {
                matcher = pattern.matcher(line);
                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));
            }
        }
        reader.close();
      
        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);
        System.out.print(textToSend);
        
        //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.