var pd = { version: "1.4.8", bookmarkver: "1.4", init: function () { pd.checks.versions(); if (window.pd_processing !== true) { if (pd.checks.location()) { $("#pd__central").find(".complete,.processing").hide(); $("#pd__form").show(); pd.setup.basicSettings(); pd.setup.applyDom(); } else { if ( confirm( "This script can only be run from your own user profile on reddit. Would you like to go there now?" ) ) { document.location = "https://old.reddit.com/u/me/overview"; } } } }, checks: { versions: function () { function checkBookmarkletVersion() { if ( typeof window.bookmarkver === "undefined" || window.bookmarkver !== pd.bookmarkver ) { if ( confirm( "There's been an update to the bookmarklet. Would you like to go to the Github repo in order to get the latest version?" ) ) { alert( 'Sadly, there]\'s no way to automatically update the bookmark. :/\nScroll down to the "Install PowerDeleteSuite" button on the github page. Replace your CURRENT bookmark with the one found there to install the latest bookmark.' ); document.location.href = "https://github.com/j0be/PowerDeleteSuite"; return false; } } return true; } function checkAppVersion() { pd.prevRunVersion = localStorage.getItem("pd_ver") ? localStorage.getItem("pd_ver") : "0"; localStorage.setItem("pd_ver", pd.version); if (pd.version !== pd.prevRunVersion) { if ( confirm( "You've gotten the latest update! You are now running PowerDeleteSuite v" + pd.version + ". Would you like to open the changelog in a new tab?" ) ) { $.ajax({ url: "/r/PowerDeleteSuite/new.json" }).then( function (data) { window.open( "https://reddit.com" + data.data.children[0].data.permalink ); }, function () { window.open("https://reddit.com/r/PowerDeleteSuite"); } ); } } return true; } return pd.debugging || (checkBookmarkletVersion() && checkAppVersion()); }, location: function () { return ( document.location.hostname.split(".").slice(-2).join(".") == "reddit.com" && document.location.href.match("/user/") && document.location.href.match("/overview") && $(".titlebox h1").first().text() === $("#header-bottom-right .user a").first().text() ); }, }, setup: { basicSettings: function () { pd.config = { uh: $("#config").innerHTML ? $("#config") .innerHTML.replace(/.*?modhash.{1}: .{1}/, "") .replace(/[^a-z0-9].*/, "") : $("#config")[0] .innerHTML.replace(/.*?modhash.{1}: .{1}/, "") .replace(/[^a-z0-9].*/, ""), user: $("#header-bottom-right .user a").first().text(), }; pd.endpoints = { comments: "/user/" + pd.config.user + "/comments/.json", submissions: "/user/" + pd.config.user + "/submitted/.json", search: "/search.json", }; }, applyDom: function () { if (pd.debugging) { $("#pd__central,#pd__style").remove(""); } document.title = pd.config.user + " | Power Delete Suite"; $(window).on("error", pd.error); $(".sitetable,.neverEndingReddit").remove(); if ($("#pd__central").length === 0) { $("body>.content[role='main']").append("
"); } if ($("#pd__style").length === 0) { $("head").first().append(""); } pd.setup.applyStyles(); pd.setup.applyCentral(); }, applyStyles: function () { $.ajax({ url: "/r/PowerDeleteSuite/about/stylesheet/.json", context: $("#pd__style"), }).then( function (data) { $(this)[0].innerHTML = data.data.stylesheet; $("#pd__central").show(); }, function () { alert("Error retreiving CSS from /r/PowerDeleteSuite"); } ); }, applyCentral: function () { $.ajax({ url: "/r/PowerDeleteSuite/wiki/centralform.json", context: $("#pd__central"), }).then( function (data) { $(this).html($("").html(data.data.content_md).text()); if ($("#pd__style").html() === "") { $(this).hide(); } if (pd.debugging) { $(this).find(".debugging").removeClass("debugging"); } $(this) .find("h2") .first() .text("Power Delete Suite v" + pd.version); pd.setup.applySubList(); pd.setup.bindUI(); pd.helpers.restoreSettings(); }, function () { alert("Error retreiving markup from /r/PowerDeleteSuite"); } ); }, applySubList: function () { var sub_arr = [], i, sid; $("#per-sr-karma tbody th").each(function () { sub_arr.push($(this).text()); }); sub_arr = sub_arr.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); $("#pd__sub-list").append( '' ); for (i = 0; i < sub_arr.length; i++) { sid = "sub--" + sub_arr[i]; $("#pd__sub-list").append( "" ); } $("#side-mod-list li").each(function () { $( ".sub--" + $(this) .text() .replace(/\/?[ru]\//, "") ).prepend("[M]"); }); }, createProcessStream: function () { window.pd_processing = true; pd.exportItems = []; pd.exportIds = []; pd.task = { after: "", info: { numPages: Math.min( ($("#pd__submissions").is(":checked") ? 8 : 0) + ($("#pd__comments").is(":checked") ? 4 : 0) + ($("#pd__comments-edit").is(":checked") ? 12 : 0), 12 ), numItems: 0, donePages: 0, doneItems: 0, pageCalls: 0, edited: 0, deleted: 0, errors: 0, ignored: 0, exported: 0, ignoreReasons: { subs: 0, gold: 0, saved: 0, mod: 0, score: 0, date: 0, }, }, config: { isExporting: $("#pd__export").is(":checked"), isRemovingPosts: $("#pd__submissions").is(":checked"), isRemovingComments: $("#pd__comments").is(":checked"), isEditing: $("#pd__comments-edit").is(":checked"), editText: $("#pd__comments-edit-text").val(), }, paths: { sections: !$("#pd__submissions").is(":checked") && !$("#pd__export").is(":checked") ? [ "comments", "search", "submissions", ] /* Search is actually more efficient than submissions if we're not handling submissions (`self:1`) */ : ["comments", "submissions", "search"], sorts: ["new", "hot", "top", "controversial"], timeframes: ["all", "hour", "day", "week", "month", "year"], }, }; pd.filters = { subs: { enabled: $("#pd__subreddits").is(":checked"), list: $( "#pd__sub-list input" + ($("#pd__subreddits").is(":checked") ? ":checked" : "") ).map(function () { return $(this).attr("data-sub"); }), }, score: { enabled: $("#pd__score").is(":checked"), gt: $("#pd__score-dirtoggle").is(":checked"), num: parseFloat($("#pd__score-num").val()), }, date: { enabled: $("#pd__date").is(":checked"), gt: $("#pd__date-dirtoggle").is(":checked"), num: Math.floor(new Date().getTime() / 1000) - parseFloat($("#pd__date-num").val()) * 60, }, gilded: $("#pd__gilded").is(":checked"), saved: $("#pd__saved").is(":checked"), mod: $("#pd__mod").is(":checked"), }; }, resetSorts: function () { pd.task.paths.sorts = ["new", "hot", "top", "controversial"]; }, resetTimes: function () { pd.task.paths.timeframes = [ "all", "hour", "day", "week", "month", "year", ]; }, bindUI: function () { $("#pd__form").submit(function (e) { e.preventDefault(); pd.setup.createProcessStream(); var validation = pd.helpers.validate(); window.pd_processing = validation.valid; if (validation.valid) { $("#pd__central .complete, #pd__form").hide(); $("#pd__central .processing").show(); pd.actions.page.next(); } else { alert(validation.reason); } }); $(".pd__q").click(function (e) { e.preventDefault(); alert($(this).closest("[data-help]").attr("data-help")); }); $("#pd__form input").change(function () { pd.helpers.saveSettings(); }); $(".mass_sel").click(function () { $(this) .closest(".xtr-section") .find("input") .prop("checked", $(this).hasClass("sel_all")); pd.helpers.saveSettings(); }); $(".gt-toggle").change(function () { var greaterThan = $(this).hasClass("greater"); $(this).attr( "class", "gt-toggle hidden " + (greaterThan ? "less" : "greater") ); }); $(".num-only").blur(function () { $(this).val( $(this) .val() .replace(/[^\d-]/g, "") ); $(this).change(); }); $(".pd__insert").click(function () { $($(this).attr("data-target")).val($(this).attr("data-value")).change(); }); }, }, helpers: { validate: function () { if (pd.task.config.isEditing && pd.task.config.editText === "") { return { valid: false, reason: "Please enter something to edit your comments / self posts to.", }; } else if (pd.filters.score && $("#pd_score-num").val() === "") { return { valid: false, reason: "Please enter a score to filter with." }; } else if ( !( pd.task.config.isRemovingPosts || pd.task.config.isEditing || pd.task.config.isRemovingComments || pd.task.config.isExporting ) ) { return { valid: false, reason: "There are no actions chosen, so we've got nothing to do. Please select an action.", }; } return { valid: true, reason: "valid" }; }, shouldBeActedOn: function (item) { var check = { subs: !pd.filters.subs.enabled || (pd.filters.subs.enabled && $.inArray(item.data.subreddit, pd.filters.subs.list) >= 0), gold: !(pd.filters.gilded && item.data.gilded == 1), saved: !(pd.filters.saved && item.data.saved == true), mod: !(pd.filters.mod && item.data.distinguished != null), score: !pd.filters.score.enabled || (pd.filters.score.enabled && ((pd.filters.score.gt === true && parseFloat(item.data.score) > pd.filters.score.num) || (pd.filters.score.gt === false && parseFloat(item.data.score) < pd.filters.score.num))), date: !pd.filters.date.enabled || (pd.filters.date.enabled && ((pd.filters.date.gt === true && parseFloat(item.data.created_utc) > pd.filters.date.num) || (pd.filters.date.gt === false && parseFloat(item.data.created_utc) < pd.filters.date.num))), }; for (var key in check) { if (!check[key]) { pd.task.info.ignoreReasons[key]++; pd.task.items[0].pdIgnoreReasons = check; } } return ( check.subs && check.gold && check.saved && check.mod && check.score && check.date ); }, csvEscape: function (str) { return str.replace(/#/g, "%23").replace(/'/g, "`").replace(/"/g, '""'); }, csvCell: function (str) { return '"' + str + '",'; }, getSettings: function () { return localStorage.getItem("pd_storage") ? JSON.parse(localStorage.getItem("pd_storage")) : false; }, restoreSettings: function () { var settings = pd.helpers.getSettings(), rememberSettings = $("#pd__remember").is(":checked"); if (settings !== false && rememberSettings) { $("#pd__form input").prop("checked", false).val(""); //Reset all for (var i = 0; i < settings.length; i++) { var setting = settings[i], selector = "*[name='" + setting.name + "']"; if (setting.value == "on" || setting.value === "") { $(selector).prop("checked", true); } else { $(selector).val(setting.value); } } $(".gt-toggle").not(":checked").change(); } }, saveSettings: function () { if ($("#pd__remember").is(":checked")) { if (!$("#pd__subreddits").is(":checked")) { $("#pd__sub-list input").prop("checked", false); } localStorage.setItem( "pd_storage", JSON.stringify($("#pd__form").serializeArray()) ); } else { localStorage.removeItem("pd_storage"); } }, }, actions: { page: { next: function () { if (pd.debugging && pd.task.info.donePages % 5 == 3) { pd.actions.page.shift(); } if (pd.task.paths.sections.length > 0) { pd.ui.updateDisplay(); pd.actions.page.handle(); } else { pd.ui.done(); } }, shift: function () { if ( pd.task.paths.sorts[0] === "top" || pd.task.paths.sorts[0] === "controversial" ) { pd.task.paths.timeframes.splice(0, 1); if (pd.task.paths.timeframes.length === 0) { pd.setup.resetTimes(); pd.task.paths.sorts.splice(0, 1); if (pd.task.paths.sorts.length === 0) { pd.setup.resetSorts(); pd.task.paths.sections.splice(0, 1); } } return false; } pd.task.paths.sorts.splice(0, 1); if (pd.task.paths.sorts.length === 0) { pd.setup.resetSorts(); pd.task.paths.sections.splice(0, 1); } return true; }, handle: function () { pd.task.pageCalls++; $.ajax({ url: pd.endpoints[pd.task.paths.sections[0]], data: { q: pd.task.paths.sections[0] == "search" ? "author:" + pd.config.user + (!pd.task.config.isRemovingPosts && !pd.task.config.isExporting ? " self:1" : "") : null, after: pd.task.after, sort: pd.task.paths.sorts[0], t: pd.task.paths.timeframes[0], }, }).then( function (resp) { if (resp.data) { var children = resp.data.children; pd.task.info.donePages++; if (children.length > 0) { pd.task.info.doneItems = 0; pd.task.info.numItems = children.length; pd.task.items = children; pd.actions.children.handleGroup(); } else { pd.task.after = ""; pd.actions.page.shift(); pd.actions.page.next(); } } else { pd.task.info.errors++; if ( confirm( "Reddit seems to be under heavy load. Would you like to continue processing?" ) ) { pd.actions.page.shift(); pd.actions.page.handle(); } else { pd.ui.done(); } } }, function () { pd.task.info.errors++; if ( confirm( "Error getting " + pd.task.paths.sections[0] + " page. Would you like to retry?" ) ) { pd.actions.page.handle(); } else { pd.actions.page.shift(); pd.actions.page.next(); } } ); }, }, children: { handleGroup: function () { pd.ui.updateDisplay(); if (pd.task.items.length > 0) { pd.actions.children.handleSingle(); } else { pd.actions.page.next(); } }, handleSingle: function () { pd.ui.updateDisplay(); var item = pd.task.items[0], shouldBeActedOn = pd.helpers.shouldBeActedOn(item), earlyExitNewItems = pd.task.paths.sorts[0] == "new" && pd.filters.date.gt === true && pd.task.items[0].pdIgnoreReasons && !pd.task.items[0].pdIgnoreReasons.date; if (earlyExitNewItems) { console.log("Skipping the rest of the things sorted by new"); pd.task.items[0].pdIgnored = true; pd.actions.children.finishItem(); pd.actions.page.shift(); pd.actions.page.next(); } else if (shouldBeActedOn) { if ( !item.pdEdited && (item.data.is_self || item.kind == "t1") && pd.task.config.isEditing ) { pd.actions.edit(item); } else if ( !item.pdDeleted && ((item.kind == "t3" && pd.task.config.isRemovingPosts) || (item.kind == "t1" && pd.task.config.isRemovingComments)) ) { pd.actions.delete(item); } else { pd.actions.children.finishItem(); pd.actions.children.handleGroup(); } } else { pd.task.items[0].pdIgnored = true; pd.actions.children.finishItem(); pd.actions.children.handleGroup(); } }, finishItem: function () { pd.task.after = pd.task.items[0].pdDeleted ? pd.task.after : pd.task.items[0].data.name; pd.task.info.doneItems++; pd.task.info.deleted += pd.task.items[0].pdDeleted ? 1 : 0; pd.task.info.edited += pd.task.items[0].pdEdited ? 1 : 0; pd.task.info.ignored += pd.task.items[0].pdIgnored ? 1 : 0; if (pd.task.config.isExporting && !pd.task.items[0].pdIgnored) { pd.actions.children.exportItem(pd.task.items[0]); } pd.task.items.splice(0, 1); }, exportItem: function (item) { var str = ""; if (pd.exportItems.length == 0) { str += pd.helpers.csvCell("Title"); str += pd.helpers.csvCell("Body"); str += pd.helpers.csvCell("Permalink"); str += pd.helpers.csvCell("Score"); str += pd.helpers.csvCell("Timestamp UTC"); str += pd.helpers.csvCell("Actions"); pd.exportItems.push(str); } if (pd.exportIds.indexOf(item.data.id) == -1) { str = ""; str += pd.helpers.csvCell( pd.helpers.csvEscape(item.data.title ? item.data.title : "") ); str += pd.helpers.csvCell( pd.helpers.csvEscape( item.data.body ? item.data.body : item.data.selftext ? item.data.selftext : "" ) ); str += pd.helpers.csvCell( item.data.permalink ? "https://reddit.com" + item.data.permalink : "https://reddit.com/r/" + item.data.subreddit + "/comments/" + item.data.link_id.replace(/^t\d_/, "") + "/x/" + item.data.id + "?context=3" ); str += pd.helpers.csvCell(item.data.score); str += pd.helpers.csvCell(item.data.created_utc); str += pd.helpers.csvCell( (item.pdEdited ? "edited " : "") + (item.pdDeleted ? "deleted " : "") ); pd.exportItems.push(str); pd.exportIds.push(item.data.id); pd.task.info.exported++; } }, }, delete: function (item) { setTimeout(() => { if (pd.performActions) { $.ajax({ url: "/api/del", method: "post", data: { id: item.data.name, executed: "deleted", uh: pd.config.uh, renderstyle: "html", }, }).then( function () { pd.task.items[0].pdDeleted = true; pd.actions.children.handleSingle(); }, function () { pd.task.info.errors++; if ( confirm( "Error deleting " + (item.kind == "t3" ? "post" : "comment") + ", would you like to retry?" ) ) { pd.actions.children.handleSingle(); } else { pd.actions.children.finishItem(); pd.actions.children.handleGroup(); } } ); } else { pd.task.items[0].pdDeleted = true; pd.task.after = pd.task.items[0].data.name; pd.actions.children.handleSingle(); } }, 5000); }, edit: function (item) { setTimeout(() => { if (pd.performActions) { $.ajax({ url: "/api/editusertext", method: "post", data: { thing_id: item.data.name, text: pd.task.config.editText, id: "#form-" + item.data.name, r: item.data.subreddit, uh: pd.config.uh, renderstyle: "html", }, }).then( function () { pd.task.items[0].pdEdited = true; pd.actions.children.handleSingle(); }, function () { pd.task.info.errors++; if ( !confirm( "Error editing " + (item.kind == "t3" ? "post" : "comment") + ", would you like to retry?" ) ) { item.pdEdited = true; } pd.actions.children.handleSingle(); } ); } else { pd.task.items[0].pdEdited = true; pd.actions.children.handleSingle(); } }, 5000); }, }, ui: { updateDisplay: function () { $("#pd__central h2") .first() .html( "Power Delete Suite v" + pd.version + "Completed after making " + pd.task.info.ajaxCalls + ' calls to the reddit servers.
If you need to re run the script, click here to go back to the beginning!
' ); } else { $("#pd__central .complete .summary").html( "All Done! It seems like all " + pd.task.info.ignored + ' items we came across were ignored.
If you need to re run the script, click here to go back to the beginning!
' ); } $("#pd__central .complete .summary .restart").click(function () { pd.init(); }); var numSubs = $("#pd__sub-list input:checked").length; $("#pd__sub-list input").prop("checked", false); var debugInfo = JSON.stringify($("#pd__form").serializeArray()) + " number of subreddits: " + numSubs; $("#pd__central .complete .goodbye").html( '