Guest User

Untitled

a guest
May 31st, 2022
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name     4chan2reddit
  3. // @namespace     fourchantoreddit
  4. // @grant GM.getValue
  5. // @grant GM.setValue
  6. // @version  1
  7. // @description Destroy free speech and rely on the discernment of children
  8. // @include      *://boards.4chan.org/*
  9. // @include      *://boards.4channel.org/*
  10. // ==/UserScript==
  11.  
  12. // User preferences will be loaded.
  13. var thresholdMinPreference = "-4";
  14. var thresholdMaxPreference = "4";
  15.  
  16. function generateRandomColor() {
  17.   return `rgb(${Math.floor((Math.random() * 256 + 255) / 2)},${Math.floor((Math.random() * 256 + 255) / 2)},${Math.floor((Math.random() * 256 + 255) / 2)})`;
  18. }
  19.  
  20. // The script will read posts and apply rules when it sees "+1", "-1", and #hashtags.
  21. const upvoteFilter = /\s\+\d+\s|up(vot|doot|boat)|t ?h ?a ?n ?k (y ?o ?)?u|bump|sauce|\bbased|good ?job|\b(nice|lol|lmao|kek|.pbp\b)/i;
  22. const downvoteFilter = /\s\-\d+\s|down(vot|doot|boat)|\bkys\b|\bcringe\b|\bcope\b|f[a]g|gay|reddit|kil+ yourself|f.ck|r.tard|nig(s|ger)|j[e]w|\bb(8|ait)\b|schizo|stfu|rent.?free|cancer|\bloser/i;
  23. const tagSearchQuery = /[^0-9a-z]#([0-9a-z]{2,})/gi;
  24.  
  25. function voteAndTag(reply, replyText, post) {
  26.   if (!post) return;
  27.   replyText = ` ${replyText} `;
  28.   const upvoted = replyText.match(upvoteFilter);
  29.   const downvoted = replyText.match(downvoteFilter);
  30.   const tags = replyText.match(tagSearchQuery);
  31.   if (upvoted && post !== reply) post.voteScore++;
  32.   else if (downvoted) post.voteScore--;
  33.   for (let i = 0; i < tags?.length; i++) {
  34.     const tag = post.tags[tags[i].toString()] || {
  35.       count: 0,
  36.       color: generateRandomColor(),
  37.     };
  38.     tag.count++;
  39.     post.tags[tags[i].toString()] = tag;
  40.   }
  41. }
  42.  
  43. function updateScores() {
  44.   // User preferences will be stored.
  45.   const thresholdMin0 = document.getElementById("thresholdMin0");
  46.   const thresholdMin1 = document.getElementById("thresholdMin1");
  47.   if (thresholdMin0 && thresholdMin0.value !== thresholdMinPreference) {
  48.     thresholdMinPreference = thresholdMin0.value || "-4";
  49.     thresholdMin0.value = thresholdMinPreference;
  50.     if (thresholdMin1) thresholdMin1.value = thresholdMinPreference;
  51.   } else if (thresholdMin1 && thresholdMin1.value !== thresholdMinPreference) {
  52.     thresholdMinPreference = thresholdMin1.value || "-4";
  53.     if (thresholdMin0) thresholdMin0.value = thresholdMinPreference;
  54.     thresholdMin1.value = thresholdMinPreference;
  55.   }
  56.   GM.setValue("minThreshold", thresholdMinPreference);
  57.  
  58.   const thresholdMax0 = document.getElementById("thresholdMax0");
  59.   const thresholdMax1 = document.getElementById("thresholdMax1");
  60.   if (thresholdMax0 && thresholdMax0.value !== thresholdMaxPreference) {
  61.     thresholdMaxPreference = thresholdMax0.value || "4";
  62.     thresholdMax0.value = thresholdMaxPreference;
  63.     if (thresholdMax1) thresholdMax1.value = thresholdMaxPreference;
  64.   } else if (thresholdMax1 && thresholdMax1.value !== thresholdMaxPreference) {
  65.     thresholdMaxPreference = thresholdMax1.value || "4";
  66.     thresholdMax1.value = thresholdMaxPreference;
  67.     if (thresholdMax0) thresholdMax0.value = thresholdMaxPreference;
  68.   }
  69.   GM.setValue("maxThreshold", thresholdMaxPreference);
  70.  
  71.   // Posts are upvoted, downvoted, and tagged by replies, so tabulate votes by most recent.
  72.   const posts = document.getElementsByClassName("postMessage");
  73.   [...posts].forEach((p) => {
  74.     p.voteScore = 0;
  75.     if (p.tags) Object.keys(p.tags).forEach((k) => (p.tags[k].count = 0));
  76.     else p.tags = {};
  77.   });
  78.   const totals = document.getElementsByClassName("totals");
  79.   while (totals.length > 0) {
  80.     totals[0].parentNode.removeChild(totals[0]);
  81.   }
  82.   const oldTags = document.getElementsByClassName("tag");
  83.   while (oldTags.length > 0) {
  84.     oldTags[0].parentNode.removeChild(oldTags[0]);
  85.   }
  86.   for (let i = posts.length - 1; i >= 0; i--) {
  87.     const post = posts[i];
  88.     const postQuotes = post.getElementsByClassName("quotelink");
  89.     const op = post.parentElement.parentElement.parentElement.getElementsByClassName("postMessage")[0]
  90.     if (postQuotes.length) {
  91.       // Parse replies to many posts into votes and tags.
  92.       let replyTo = [];
  93.       let data = "";
  94.       for (let j = 0; j < post.childNodes.length; j++) {
  95.         const node = post.childNodes[j];
  96.         if ([...postQuotes].includes(node)) {
  97.           const repliedTo = [...posts].find(
  98.             (p) => p.id.substring(1) === node.hash.substring(2)
  99.           );
  100.           if (!replyTo.includes(repliedTo)) {
  101.             if (data) {
  102.               if (replyTo.length)
  103.                 replyTo.forEach((r) => voteAndTag(post, data, r));
  104.               else voteAndTag(post, data, op);
  105.               replyTo = [];
  106.               data = "";
  107.             }
  108.             replyTo.push(repliedTo);
  109.           }
  110.         } else if (node.data) data += node.data + " ";
  111.       }
  112.       if (replyTo.length) replyTo.forEach((r) => voteAndTag(post, data, r));
  113.       else voteAndTag(post, data, op);
  114.     } else {
  115.       // Posters can self-tag and self-downvote.
  116.       voteAndTag(post, post.innerText, op);
  117.     }
  118.  
  119.     // Posts outside the user's thresholds will be hidden.
  120.     if (
  121.       post.voteScore < parseInt(thresholdMinPreference) ||
  122.       post.voteScore > parseInt(thresholdMaxPreference)
  123.     ) {
  124.       post.style.display = "none";
  125.     } else {
  126.       post.style.display = "block";
  127.       const postQuote = ">>" + post.id.substring(1) + "\n";
  128.       const upvote = document.createElement("a");
  129.       upvote.addEventListener("click", () => {
  130.         [...document.getElementsByTagName("textArea")].forEach((t) => {
  131.           t.value += (t.value.includes(postQuote) ? " " : postQuote) + "+1";
  132.         });
  133.       });
  134.       upvote.style = "display:inline;color:#0f0;font-weight:bolder;background-color:#888";
  135.       upvote.innerHTML = "&nbsp;⬆&nbsp;";
  136.       const downvote = document.createElement("a");
  137.       downvote.innerHTML = "&nbsp;⬇&nbsp;";
  138.       downvote.addEventListener("click", () => {
  139.         [...document.getElementsByTagName("textArea")].forEach((t) => {
  140.           t.value += (t.value.includes(postQuote) ? " " : postQuote) + "-1";
  141.         });
  142.       });
  143.       downvote.style = "display:inline;color:#f00;font-weight:bolder;background-color:#888";
  144.       // Individual posts will add a vote total and a tag cloud.
  145.       const total = document.createElement("div");
  146.       total.innerHTML = "&nbsp;" + post.voteScore;
  147.       total.style = "display:inline;color:#222";
  148.       const votes = document.createElement("div");
  149.       votes.innerHTML = " ";
  150.       votes.style =
  151.         "width:80%" +
  152.         (post.voteScore > 0
  153.           ? ";background-color:#8f8"
  154.           : post.voteScore < 0 ? ";background-color:#f88" : "");
  155.       votes.className = "totals";
  156.       votes.appendChild(upvote);
  157.       votes.appendChild(downvote);
  158.       votes.appendChild(total);
  159.       post.appendChild(votes);
  160.       if (post.tags)
  161.         Object.keys(post.tags).forEach((k) => {
  162.           const t = post.tags[k];
  163.           const tag = document.createElement("div");
  164.           tag.innerHTML = k + (t.count > 1 ? " x" + t.count : "");
  165.           tag.className = "tag";
  166.           tag.style = "display:inline;color:#222;background-color:" + t.color;
  167.           post.appendChild(tag);
  168.         });
  169.     }
  170.   }
  171. }
  172.  
  173. GM.getValue("minThreshold", "-4").then(async (v) => {
  174.   thresholdMinPreference = v || "-4";
  175.   thresholdMaxPreference = (await GM.getValue("maxThreshold", "4")) || "4";
  176.   setTimeout(() => {
  177.     const navLinkContainers = document.getElementsByClassName("navLinks");
  178.     for (let i = 0; i < navLinkContainers.length; i++) {
  179.       const mainContainer = document.createElement("div");
  180.       mainContainer.style = "display:inline";
  181.  
  182.       //// Add a refresh button.
  183.       //const updateScore = document.createElement("button");
  184.       //updateScore.id = "updateScore" + i;
  185.       //updateScore.type = "button";
  186.       //updateScore.innerHTML = "Update scores";
  187.       //updateScore.onclick = updateScores;
  188.       //mainContainer.innerHTML += " ";
  189.       //mainContainer.appendChild(updateScore);
  190.  
  191.       if (i < 2) {
  192.         // Threshold Min/Max textboxes will be added to the thread.
  193.         const thresholdMin = document.createElement("input");
  194.         thresholdMin.id = "thresholdMin" + i;
  195.         thresholdMin.type = "number";
  196.         thresholdMin.value = thresholdMinPreference;
  197.         const thresholdMinLabel = document.createElement("label");
  198.         thresholdMinLabel.for = thresholdMin.id;
  199.         thresholdMinLabel.innerHTML = "Minimum score";
  200.         mainContainer.innerHTML += " ";
  201.         mainContainer.appendChild(thresholdMinLabel);
  202.         mainContainer.innerHTML += " ";
  203.         mainContainer.appendChild(thresholdMin);
  204.         const thresholdMax = document.createElement("input");
  205.         thresholdMax.id = "thresholdMax" + i;
  206.         thresholdMax.type = "number";
  207.         thresholdMax.value = thresholdMaxPreference;
  208.         const thresholdMaxLabel = document.createElement("label");
  209.         thresholdMaxLabel.for = thresholdMax.id;
  210.         thresholdMaxLabel.innerHTML = "Max";
  211.         mainContainer.innerHTML += " ";
  212.         mainContainer.appendChild(thresholdMaxLabel);
  213.         mainContainer.innerHTML += " ";
  214.         mainContainer.appendChild(thresholdMax);
  215.       }
  216.       navLinkContainers[i].appendChild(mainContainer);
  217.     }
  218.     updateScores();
  219.     setInterval(updateScores, 9000)
  220.   }, 4000);
  221. });
  222.  
Add Comment
Please, Sign In to add comment