AutoArchive

// 
var AutoArchive = {
	subpage: "Archive", // subpage name, followed by a space and the archive number
	reason: "Archiving", // archiving summary when renaming the page to a subpage archive
	size: 10000, // archive at this size (in bytes)
	newTalkText: "{{:User:" + mw.config.get("wgUserName") + "/ArchiveTalk}}" // new talk page text. by default its a template for [[Special:MyPage/ArchiveTalk]]
}
// ~~ SCRIPT
/* ================================================ *\
	# reconstruct object
\* ================================================ */
// main object
AutoArchive = window.AutoArchive || {};
// reconstruct crucial properties
AutoArchive.isArchivingOnThisWebpage = false;
AutoArchive.subpage = AutoArchive.subpage || "Archive";
AutoArchive.reason = AutoArchive.reason || "Archiving";
AutoArchive.size = AutoArchive.size || 10000;
AutoArchive.newTalkText = AutoArchive.newTalkText || "{{:User:" + mw.mw.config.get("wgUserName") + "/ArchiveTalk}}";
// additional properties
AutoArchive.fn = {};
/* ================================================ *\
	# functions
\* ================================================ */
// check if there's need to archive the talk page
AutoArchive.fn.check = function() {
	console.info("-- function executed; AutoArchive.fn.check");
	if (localStorage.AutoArchive != "on") {
		// prevent conflicts with other pages
		AutoArchive.fn.setState("on");
		AutoArchive.fn.getUsertalkContent(function(data) {
			if (data.length >= AutoArchive.size) {
				// reached maximum size - need to archive
				console.log("A large talk page size has been detected - archiving is now taking place");
				AutoArchive.fn.archive();
			} else {
				// no need to archive for now
				console.log("no need to archive for now");
				AutoArchive.fn.setState("off");
			}
		});
	} else {
		console.log("an archive is currently performed via a different tab - archive has turned off until it is done to prevent conflicts");
	}
}
// get talk page content, and return the content
AutoArchive.fn.getUsertalkContent = function(callback) {
	console.info("-- function executed; AutoArchive.fn.getUsertalkContent");
	// prevent conflicts with other pages
	AutoArchive.fn.setState("on");
	$.get("/wiki/User_talk:" + encodeURIComponent(mw.config.get("wgUserName").replace(/ /g, "_")) + "?action=raw&cb=" + new Date().getTime(), function(data) {
		callback(data);
	});
}
// archiving
AutoArchive.fn.archive = function(callback) {
	console.info("-- function executed; AutoArchive.fn.archive");
	AutoArchive.fn.getLastArchiveNumber(function(n) {
		AutoArchive.fn.rename(n, function() {
			AutoArchive.fn.recreateTalkPage(function() {
				AutoArchive.fn.onArchiveComplete();
			});
		});
	});
}
// error
AutoArchive.fn.onerror = function() {
	console.info("-- function executed; AutoArchive.fn.onerror");
	AutoArchive.fn.setState("off");
	console.error("AutoArchive error: there was a problem archiving the talk page");
}
// archiving - check number of existing archives
AutoArchive.fn.getLastArchiveNumber = function(success) {
	console.info("-- function executed; AutoArchive.fn.getLastArchiveNumber");
	$.getJSON("/api.php?action=query&format=json&list=allpages&apprefix=" + encodeURIComponent(mw.config.get("wgUserName").replace(/ /g, "_") + "/" + AutoArchive.subpage + "_") + "&apnamespace=3&apdir=descending&aplimit=1&cb=" + new Date().getTime(), function(data) {
		var m0 = data.query.allpages[0];
		try {
			// already has archives
			var m1 = m0.title.match(/ (\d+)$/)[1],
				m2 = Number(m1);
			success(m2 + 1);
		} catch(msg) {
			// this will be the first archive
			success(1);
		}
	});
}
// rename talk page (override)
AutoArchive.fn.rename = function(newArchiveNumber, success) {
	console.info("-- function executed; AutoArchive.fn.rename");
	$.ajax({
		url: mw.util.wikiScript("api"),
		data: {
			"format": "json",
			"action": "move",
			"from": "User_talk:" + mw.config.get("wgUserName").replace(/ /g, "_"),
			"to": "User_talk:" + mw.config.get("wgUserName").replace(/ /g, "_") + "/" + AutoArchive.subpage + "_" + newArchiveNumber,
			"reason": AutoArchive.reason,
			"noredirect": "",
			"token": mw.user.tokens.get("editToken")
		},
		dataType: "json",
		type: "POST",
		success: function(data) {
			success(data);
		},
		error: function() {
			AutoArchive.fn.onerror();
		}
	});
}
// recreate talk page
AutoArchive.fn.recreateTalkPage = function(success) {
	console.info("-- function executed; AutoArchive.fn.recreateTalkPage");
	$.ajax({
		url: mw.util.wikiScript("api"),
		data: {
			"format": "json",
			"action": "edit",
			"title": "User_talk:" + mw.config.get("wgUserName").replace(/ /g, "_"),
			"text": AutoArchive.newTalkText,
			"token": mw.user.tokens.get("editToken")
		},
		dataType: "json",
		type: "POST",
		success: function(data) {
			if (data && data.edit && data.edit.result == "Success") {
				success(data);
			} else {
				AutoArchive.fn.onerror();
			}
		},
		error: function() {
			AutoArchive.fn.onerror();
		}
	});
}
// when done
AutoArchive.fn.onArchiveComplete = function(data) {
	AutoArchive.fn.setState("off");
	alert("Your talk page has been successfully archived!");
	console.log("Your talk page has been successfully archived!");
}
// when done archiving
AutoArchive.fn.setState = function(state) {
	switch(state) {
		case "on":
			localStorage.AutoArchive = "on";
			AutoArchive.isArchivingOnThisWebpage = true;
			break;
		case "off":
			localStorage.AutoArchive = "off";
			AutoArchive.isArchivingOnThisWebpage = false;
			break;
	}
}
/* ================================================ *\
	# prevent exiting the page while terminating
\* ================================================ */
$(window).on("beforeunload", function() {
	if (localStorage.AutoArchive == "on" && AutoArchive.isArchivingOnThisWebpage) {
		return "Note!\nThis webpage is currently checking if your talk page requires archiving. This process should only take a few seconds. In case the script has detected a large talk page size and begun archiving, exiting now might cause unexpected issues in this process.\nDo you wish to exit the page now, or wait for it to end?";
	}
});
//