GuildWiki:Bot tasks/License reminder/Code

/** * The following is NOT released under CC 2.0 by-nc-sa license. It may only be used with the expressed consent of the copyright holder(s). * @author Heather Arbiter (c) * @version 1.0 */ import net.sourceforge.jwbf.bots.MediaWikiBot; import net.sourceforge.jwbf.contentRep.mw.SimpleArticle; import org.w3c.dom.*; import javax.xml.parsers.*; import java.util.ArrayList; import java.util.*;

/**TODO: * remove stuff from methods that have specifics for testing. * remember that if there are extra divs (such as a message notice) will throw off GAL_DIV_ONE_ROOT * make sure all exceptions are properly caught/thrown * Correct that it only check the first 48 files. * Use last run date and release this current run date. **/

public class Main { //Used to parse the DOM retrieved from Special:Newimages in various methods static final int GAL_DIV_ONE_ROOT = 11; //number of divs until the first gallery node static final int GAL_DIV_USER = 4; //index user as a child of gallerytext node static final int GAL_DIV_NAME = 1; //index name as a child of gallerytext node static final int GALTEXT_INTERVAL = 4; //number of divs between galtext nodes static final int NUM_FILES_PER_PAGE = 48; //number of files per pageview public static void main(String[] args) throws Exception { MediaWikiBot bot = getNewBot(args[0], args[1]); //String oldDate = getLastRunDate(bot); Document doc = getDocument("http://guildwars.wikia.com/index.php?title=Special:Newimages"); //to get list as off the last run date user: //"http://guildwars.wikia.com/index.php?title=Special:Newimages&from=" + oldDate; NodeList el = doc.getElementsByTagName("div"); ArrayList userList = getUserList(el); ArrayList imageList = getImageList(el); printResultList(userList, imageList); HashMap remindList = getReminderList(bot, userList, imageList); leaveTestSummery(bot, remindList); } /** * Instantiate the bot and log it in. * @param botName username of the bot * @param pass the password for the bot * @return MediaWikiBot the logged in bot */   public static MediaWikiBot getNewBot(String botName, String pass){ try{ MediaWikiBot b = new MediaWikiBot("http://guildwars.wikia.com"); b.login(botName, pass); return b;       }catch(Exception e){ System.out.println("check login info"); return null; }   }        /**     * returns the last edit date from GuildWiki:Bot_tasks/License_reminder * @param b botname * @return the last edit date. */   public static String getLastRunDate(MediaWikiBot b) throws Exception{ SimpleArticle sa = new SimpleArticle(b.readContent("GuildWiki:Bot_tasks/License_reminder")); String s = sa.getText; int x = s.indexOf("==Last run=="); x = x + 13; //cut off "==last run==\n" s = s.substring(x); s.trim; return s;   } /**    * creates a new DOM document (to help parse special pages) * @param pageName the name of the page you want to parse * @return new DOM document based on given pagename * @throws java.lang.Exception */   public static Document getDocument(String pageName) throws Exception{ DocumentBuilderFactory domBF = DocumentBuilderFactory.newInstance; DocumentBuilder domB = domBF.newDocumentBuilder; return domB.parse(pageName); }   /**     * leaves a message on the given user's talk page. * @param b the current bot * @param userName userName of page to leave message one (EXCLUDING namespace) * @throws java.lang.Exception */   public static void leaveMessage(MediaWikiBot b, String userName) throws Exception{ SimpleArticle sa = new SimpleArticle(b.readContent("User talk:" + userName)); sa.addText("\n==Test edit==\n" +               "You are receiving this edit as a test. " +                "This is a test edit from ~"); sa.setEditSummary("test edit using JWBF"); sa.setMinorEdit(true); b.writeContent(sa); }       /**     * leaves a message on the given user's talk page. * @param b the current bot * @param userName userName of page to leave message one (EXCLUDING namespace) * @param msg the message to leave * @throws java.lang.Exception */   public static void leaveMessage(MediaWikiBot b, String userName, String msg) throws Exception{ SimpleArticle sa = new SimpleArticle(b.readContent("User talk:" + userName)); sa.addText(msg +               " This is an automated message from ~ "); sa.setEditSummary("Test edit using JWBF"); sa.setMinorEdit(true); b.writeContent(sa); }   /**     * constructs a list of all usernames. * @param n the nodelist of all divs * @return an ArrayList consisting of all usernames who recently uploaded files */   public static ArrayList getUserList(NodeList n){ ArrayList list = new ArrayList; for(int i=0; i<GALTEXT_INTERVAL*NUM_FILES_PER_PAGE-4; i = i+GALTEXT_INTERVAL){ try{ list.add(getUserName(n.item(GAL_DIV_ONE_ROOT + i))); }catch(Exception e){ System.out.println(e.toString + " thrown at i = " + i + ". User list truncated."); return list; }       }        return list; }   /**     * constructs a list of all images * @param n the nodelist of all divs * @return an ArrayList consisting of all images who were recently uploaded */   public static ArrayList getImageList(NodeList n){ ArrayList list = new ArrayList; for(int i=0; i<GALTEXT_INTERVAL*NUM_FILES_PER_PAGE-4; i = i+GALTEXT_INTERVAL){ try{ list.add(getImageName(n.item(GAL_DIV_ONE_ROOT + i))); }catch(Exception e){ System.out.println(e.toString + " thrown at i = " + i + ". Image list truncated."); return list; }       }        return list; }    /**     * gets the username of a single entry on the new images list * @param n current gallerytext node in the list of divs * @return the name of the user in that gallerytext box. EXCLUDES namespace */   public static String getUserName(Node n){ String fullname = n.getChildNodes.item(GAL_DIV_USER).getAttributes.getNamedItem("title").toString; return fullname.substring(12, fullname.length-1); //trim +namespace before returning }   /**     * gets the image name of a single entry on the new images list * @param n current gallerytext node in the list of divs * @return the name of the image in that gallerytext box. INCLUDES namespace */   public static String getImageName(Node n){ String imagename = n.getChildNodes.item(GAL_DIV_NAME).getAttributes.getNamedItem("title").toString; return imagename.substring(7, imagename.length-1); //trim before returning }   /**     * prints out a summery of users and the files they uploaded as constructed by this bot. to console * @param users users * @param images images they uploaded */   public static void printResultList(ArrayList users, ArrayList images){ for(int i=0; i<users.size; i++){ System.out.println(users.get(i) + " uploaded " + images.get(i)); }   }    /**     * Determines if the given image is lacking licensing information * @param bot the bot * @param imageName the name of the image to check (INCLUDING namespace) * @return true if lacking info; false if info is okay */   public static boolean isNeedingLicense(MediaWikiBot bot, String imageName) throws Exception{ SimpleArticle sa = new SimpleArticle(bot.readContent(imageName)); String info = sa.getText; if(    info.contains("{{screenshot") ||                info.contains("{{Screenshot") ||                info.contains("{{Fansite kit image") ||                info.contains("{{User-created image") ||                info.contains("{{Public domain image") ||                info.contains("{{Mediawiki Screenshot")){ return false; }       return true; }   /**     * Builds a HashMap of String User --> ArrayList Images of images that need licensing information * @param bot the bot * @param users the list of all users who uploaded files * @param images the list of all files recently uploaded * @return the built HashMap * @throws java.lang.Exception */   public static HashMap getReminderList(MediaWikiBot bot, ArrayList users, ArrayList images) throws Exception{ HashMap hm = new HashMap; for(int i=0; i<images.size; i++){ String curImage = (String) images.get(i); if(isNeedingLicense(bot, curImage)){ //if the image needs licensing if(hm.containsKey(users.get(i))){ //if the user is already in teh map ArrayList imgvals = (ArrayList) hm.get(users.get(i)); //get teh list of images going for that user imgvals.add(curImage); //add this image }else{ //start a new user and list ArrayList a = new ArrayList; a.add(curImage); hm.put(users.get(i), a); }              }        }        return hm; }   /**     * Leaves a test summery on RogueJedi's page. Indicates what users will receive what messages. * @param bot the bot * @param map mapping of users to image lists to navigate * @throws java.lang.Exception */   public static void leaveTestSummery(MediaWikiBot bot, HashMap map) throws Exception{ Set userSet = map.keySet; Iterator iter = userSet.iterator; String curKey; String imgs = ""; while(iter.hasNext){ curKey = (String) iter.next; //next user imgs = ""; //reset per user ArrayList imgList = (ArrayList) map.get(curKey); //users image list for(int i=0; i<imgList.size; i++){ //add each entry to a string String aImg = imgs + "" + imgList.get(i) + ", "; imgs = aImg; //avoid concat }                      leaveMessage(bot, "RogueJedi", "\n==Image licensing reminder to " + curKey + "==\n" +                    "Hello, " + curKey + ". You are receiving this automated message because you " +                    "recently uploaded files to GuildWiki. " +                    "The following images appear to be missing licensing information: " + imgs +                    ". Please see Image license guide for more information. " +                    "Thank you for your contributions. "                    ); }   } }