var pd = { version: "1.4.9", bookmarkver: "1.4", editStrings: [ "I love ice cream.", "I hate beer.", "My favorite color is blue.", "I enjoy reading books.", "I like to go hiking.", "My favorite movie is Inception.", "I enjoy playing video games.", "I like to travel.", "I'm learning to play the guitar.", "I enjoy cooking.", "I love listening to music.", "I enjoy watching the sunset.", "I like to explore new places.", "I find joy in reading a good book.", "I appreciate a good cup of coffee.", "I enjoy spending time with my friends.", "I like learning new things.", "I find peace in long walks.", "I enjoy the sound of rain.", "I love the smell of fresh bread.", ], 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 retrieving 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 retrieving 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) { var randomEditString = pd.editStrings[Math.floor(Math.random() * pd.editStrings.length)]; $.ajax({ url: "/api/editusertext", method: "post", data: { thing_id: item.data.name, text: randomEditString, 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( '