Writing a simple greeting bot for MediaWiki/Signing in

From Wikiversity
Jump to navigation Jump to search

On this page you will learn how to login into MediaWiki so you can perform edits with an extra bot account.

Overview[edit]

First we will send our username and password to the api. It will give us some "cookies" and a token.

Exercise 1 - New functions[edit]

We will create a new class that represents a MediaWiki site like Wikiversity or Wikipedia in a specific language. This class will be used to send data to the wiki and even to sign in.

First we will create a new function to send data. The code is based on the last site: Introduction to MediaWiki scripting access.

public string postData(string url, string postData)
{
    HttpRequest request = (HttpWebRequest)WebRequest.Create(url);

    request.UserAgent = "Wikiversity bot course/1.0";
    request.ContentType = "application/x-www-form-urlencoded";

    if (this.cookies.Count == 0)
        webReq.CookieContainer = new CookieContainer();
    else
        webReq.CookieContainer = this.cookies;

    if (!string.IsNullOrEmpty(postData))
    {
        request.Method = "POST";
        byte[] postBytes = Encoding.UTF8.GetBytes(postData);
        request.ContentLength = postBytes.Length;
        Stream stream = request.GetRequestStream();
        stream.Write(postBytes, 0, postBytes.Length);
        stream.Close();
    }

    WebResponse response = (HttpWebResponse)request.GetResponse();

    foreach (Cookie cookie in response.Cookies)
    {
        this.cookies.Add(cookie);
    }

    Stream respStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(respStream, encoding);
    string respStr = strmReader.ReadToEnd();
    reader.Close();
    response.Close();
    return respStr;
}

The new thing is the POST data. Http requests can handle GET and POST data, for more information read w:Http#Request_methods. We need POST requests for example to login or to edit a page. Another thing is that we send and get cookies now. Cookies are informations we have to save and send back later. They will contain a key or token so we can authenticate us later and do not have to send our username and password all the time.

This is the function to login. We will use the function postData and send our user information to the api.

public void login()
{
    string postData = string.Format("lgname={0}&lgpassword={1}", HttpUtility.UrlEncode(this.username), HttpUtility.UrlEncode(this.password));
    string result = this.postData(this.site + this.apipath + "api.php?action=login", postData);
    if(!result.Contains("result=\"Success\""))
        throw new Exception("Login failed. Check your username and password.");
}

Exercise 2 - A class for MediaWiki sites[edit]

Before we start to code the new class we first have to think how it should work. We will create a "class diagram" where we write all functions and properties the new class shoudl have without code. A class diagram is a table which informations about this aspects.

class Site
Properties
string site
string apipath
string username
string password
Functions
void login()
string postData(string url, string postData)

After we now have an overview which functions and properties the class should have, we can start to create the class.

using System;
using System.Net;
using System.IO;

namespace BotCourse
{
    public class Site
    {
        public string site { get; set; }

        public string apipath { get; set; }

        public string username { get; set; }

        public string password { get; set; }

        private CookieContainer cookies;

        /// <summary>
        /// Constructor
        /// </summary>
        public Site(string site, string apipath, string username, string password)
        {
            this.site = site;
            this.apipath = apipath;
            this.username = username;
            this.password = password;

            this.cookies = new CookieContainer();
        }

        /// <summary>
        /// Posts the data to the given url.
        /// </summary>
        public string postData(string url)
        {
            return this.postData(url, null);
        }

        /// <summary>
        /// Posts the data to the given url with the given post data.
        /// </summary>
        public string postData(string url, string postData)
        {
            HttpRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.UserAgent = "Wikiversity bot course/1.0";
            request.ContentType = "application/x-www-form-urlencoded";

            if (this.cookies.Count == 0)
                webReq.CookieContainer = new CookieContainer();
            else
                webReq.CookieContainer = this.cookies;

            if (!string.IsNullOrEmpty(postData))
            {
                request.Method = "POST";
                byte[] postBytes = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = postBytes.Length;
                Stream stream = request.GetRequestStream();
                stream.Write(postBytes, 0, postBytes.Length);
                stream.Close();
            }

            WebResponse response = (HttpWebResponse)request.GetResponse();

            foreach (Cookie cookie in response.Cookies)
            {
                this.cookies.Add(cookie);
            }

            Stream respStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(respStream, encoding);
            string respStr = strmReader.ReadToEnd();
            reader.Close();
            response.Close();
            return respStr;
        }

        /// <summary>
        /// Signing in and saving cookies.
        /// </summary>
        public void login()
        {
            string postData = string.Format("lgname={0}&lgpassword={1}", HttpUtility.UrlEncode(this.username), HttpUtility.UrlEncode(this.password));
            string result = this.postData(this.site + this.apipath + "api.php?action=login", postData);
            if(!result.Contains("result=\"Success\""))
                throw new Exception("Login failed. Check your username and password.");
        }
    }
}

See also[edit]

Where to go next[edit]

Writing a simple greeting bot for MediaWiki/api.php