// ==UserScript== // @name Fet Group Blocker // @namespace http://tampermonkey.net/ // @version 0.1 // @description Block all users in a given FetLife Group // @author ⬡-Drone 4661 // @match https://fetlife.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=fetlife.com // @grant none // ==/UserScript== const expiration = 6000000; const appendButton = () => { let joinButton = document.getElementsByClassName("flex-none pl-3.5 pt-2 xs:pl-8 lg:pt-0"); if (joinButton.length < 1) { return; } let parentFlex = joinButton[0].parentElement; let buttonLabel = "🛑 Block Group Members"; if (localStorage.getItem("FetlifeBlocker") !== null) { let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); if (blocker.group.toString() === window.location.href.split("/")[4]) { if (blocker.activation + expiration /*10 minutes*/ < Date.now() || blocker.status === "expired") { console.log("Expired but from the button adder"); buttonLabel = "❌ Auto-Block Expired"; } else { switch (blocker.status) { case "nav": case "scrape": buttonLabel = "🔄️ Scanning..."; break; case "block": buttonLabel = "🔄️ Blocking..."; break; case "complete": buttonLabel = "✅ Blocking Complete"; break; default: break; } } } } parentFlex.innerHTML = parentFlex.innerHTML + `
'; let blockMemberButton = document.getElementById("blockMemberButton"); blockMemberButton.onclick = () => { // Scrape group members // Block each member if (localStorage.getItem("FetlifeBlocker") === null) { // First click localStorage.setItem("FetlifeBlocker", JSON.stringify({ "origin": window.location.href, "members": [], "group": parseInt(window.location.href.split("/")[4]), "activation": Date.now(), "status": "nav" })); window.location.href = "https://fetlife.com/groups/" + parseInt(window.location.href.split("/")[4]) + "/members?page=1"; } else { let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); if (blocker.status == "complete" || blocker.status == "expired") { // First click localStorage.setItem("FetlifeBlocker", JSON.stringify({ "origin": window.location.href, "members": [], "group": parseInt(window.location.href.split("/")[4]), "activation": Date.now(), "status": "nav" })); window.location.href = "https://fetlife.com/groups/" + parseInt(window.location.href.split("/")[4]) + "/members?page=1"; } } }; return; }; const navigateToNextPage = () => { // get next page num from processed nav // if already last page, update localStorage and return to origin // localstorage (FetlifeBlocker -> null, FetLifeBlockedUsers -> +=members) let nav = document.getElementsByClassName("pagination mt-6 text-center"); if (nav.length > 0) { if (nav[0].children[nav[0].children.length - 1].toString().includes("members")){ // not last page yet window.location.href = nav[0].children[nav[0].children.length - 1].toString(); return; } } // last page // All members have been scraped let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); blocker.status = "block"; localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); window.location.href = blocker.origin; return; }; const scrapeMembers = () => { if ( document.body.classList.toString().includes("page-loading") ) { // still loading // Retry after 1.5 seconds setTimeout(scrapeMembers, 1500); return; } // get all members let users = []; // Foe each column document.getElementsByClassName("w-full px-1 md:w-1/2").forEach(i => { // For each member element for (let y = 0; y < i.children.length; y++){ let userElement = i.children[y].children[0].children[0].children[1].children[0].children[0]; let UserID = userElement.href.split("/")[4]; let UserName = userElement.innerText; users.push({ "id": UserID, "name": UserName }); } }); let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); users.forEach(i => { if (!blocker.members.some(e => e.id === i.id)) { blocker.members.push(i); } }); localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); navigateToNextPage(); }; const nextUser = () => { let userBlock = JSON.parse(localStorage.getItem("FetlifeUserBlock")); if (userBlock === null) { window.location.href = "https://fetlife.com/groups"; return; } // Navigate to next user if (userBlock.users.length < 1) { // No users left let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); blocker.status = "complete"; localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); localStorage.removeItem("FetlifeUserBlock"); window.location.href = userBlock.origin; } else { window.location.href = "https://fetlife.com/users/" + userBlock.users[0].id; } return; }; (function() { 'use strict'; switch (window.location.pathname.split("/")[1]) { case "groups": if (/^[0-9]+$/.test(window.location.pathname.split("/")[2].toLowerCase())){ appendButton(); if (localStorage.getItem("FetlifeBlocker") !== null) { let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); // Block run expired.. reset to null if (blocker.activation + expiration /*10 minutes*/ < Date.now()) { console.log("Expired"); blocker.status = "expired"; blocker.members = []; localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); // localStorage.removeItem("FetlifeBlocker"); return; } switch (blocker.status) { case "nav": if (!window.location.href.toLowerCase().startsWith("https://fetlife.com/groups/" + blocker.group + "/members")) { // not on a member page, navigate to next page window.location.href = "https://fetlife.com/groups/" + blocker.group + "/members?page=1"; return; }else { // on a member page now blocker.status = "scrape"; localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); window.location.href = "https://fetlife.com/groups/" + blocker.group + "/members?page=1"; return; } break; case "scrape": scrapeMembers(); break; case "block": // Prepare data for user page cycling localStorage.setItem("FetlifeUserBlock", JSON.stringify({ "origin": blocker.origin, "users": blocker.members, "activation": Date.now(), })); // Navigate to first user window.location.href = "https://fetlife.com/users/" + blocker.members[0].id; break; case "complete": console.log("TODO: Announce errors if any, otherwise complete!"); let errors = localStorage.getItem("FetlifeError")?JSON.parse(localStorage.getItem("FetlifeError")):[]; if (errors.length > 0) { console.log("Errors: ", errors.length); } else { console.log("No errors"); } localStorage.removeItem("FetlifeError"); break; case "expired": console.log("Expired, but from status processing"); localStorage.removeItem("FetlifeError"); break; default: // TODO? break; } } } break; case "users": // If on a user page if (/^[0-9]+$/.test(window.location.pathname.split("/")[2].toLowerCase())){ console.log("User page"); // check localstorage if (localStorage.getItem("FetlifeUserBlock") !== null) { let userBlock = JSON.parse(localStorage.getItem("FetlifeUserBlock")); console.log("UserBlock: ", window.location.pathname.split("/")[2]); // check within 10 minutes if (userBlock.activation + expiration /*10 minutes*/ < Date.now()) { localStorage.removeItem("FetlifeUserBlock"); console.log("Expired"); return; } // if user in list, block and nav to next user if (userBlock.users.some(e => e.id.toString() === window.location.pathname.split("/")[2])) { // If user already blocked, remove from list and skip if (document.getElementsByTagName("body")[0].innerText.toLowerCase().includes("you've blocked")){ console.log(`User ${window.location.pathname.split("/")[2]} already blocked`); // Remove user listing from localstorage userBlock.users = userBlock.users.filter(e => e.id.toString() !== window.location.pathname.split("/")[2]); localStorage.setItem("FetlifeUserBlock", JSON.stringify(userBlock)); // Navigate to next user nextUser(); return; } else if (document.getElementsByTagName("body")[0].innerText.toLowerCase().includes("isn't available")) { console.log(`User ${window.location.pathname.split("/")[2]} not available`); // Remove user listing from localstorage userBlock.users = userBlock.users.filter(e => e.id.toString() !== window.location.pathname.split("/")[2]); localStorage.setItem("FetlifeUserBlock", JSON.stringify(userBlock)); let errors = localStorage.getItem("FetlifeError")?JSON.parse(localStorage.getItem("FetlifeError")):[]; errors.push({ "user": window.location.pathname.split("/")[2], "error": "User not available" }); localStorage.setItem("FetlifeError", JSON.stringify(errors)); // Navigate to next user nextUser(); return; } else { // Block user console.log("TODO: Block user"); let blockButton = document.querySelectorAll('[title="Block"]'); if (blockButton.length > 0) { console.log("Clicking block"); blockButton[0].click(); setTimeout( () => { // If can't block let confirmButton = document.getElementsByClassName("relative no-underline items-center rounded-sm select-none border link red-100 border-red-600 hover-red-100 bg-red-600 hover:bg-red-700 transition fill-red-100 leading-tighter text-md py-2 px-2 xs:px-3.5 font-normal text-center justify-center flex w-full"); if (confirmButton.length > 0) { userBlock.users = userBlock.users.filter(e => e.id.toString() !== window.location.pathname.split("/")[2]); localStorage.setItem("FetlifeUserBlock", JSON.stringify(userBlock)); if (confirmButton[0].innerText.toLowerCase().includes("gotcha")) { // Cannot block user console.log("Cannot block user" + window.location.pathname.split("/")[2]); let FetLifeError = localStorage.getItem("FetlifeError")?JSON.parse(localStorage.getItem("FetlifeError")):[]; FetLifeError.push({ "user": window.location.pathname.split("/")[2], "error": "Cannot block user" }); // remove user from list userBlock.users = userBlock.users.filter(e => e.id.toString() !== window.location.pathname.split("/")[2]); localStorage.setItem("FetlifeUserBlock", JSON.stringify(userBlock)); localStorage.setItem("FetlifeError", JSON.stringify(FetLifeError)); nextUser(); } else { console.log("User " + window.location.pathname.split("/")[2] + " blocked"); confirmButton[0].click(); setTimeout( () => { location.reload(); }, 5000); } } }, 500); } else { console.log("No block button"); } } }else { // Navigate to fist user in list if (userBlock.users.length < 1) { // No users left console.log("Missing current page user: No users left"); localStorage.removeItem("FetlifeUserBlock"); let blocker = JSON.parse(localStorage.getItem("FetlifeBlocker")); blocker.status = "complete"; localStorage.setItem("FetlifeBlocker", JSON.stringify(blocker)); window.location.href = userBlock.origin; } else { console.log("Missing current page user: Navigating to next user"); window.location.href = "https://fetlife.com/users/" + userBlock.users[0].id; } return; } return; } else { console.log("No users to block"); } } else { console.log("Not a user page"); } break; default: console.log("Not a group or user page"); break; } })();