8chan IDs

Show statistics about 8chan post IDs

  1. // ==UserScript==
  2. // @name 8chan IDs
  3. // @version 1
  4. // @grant none
  5. // @include https://8chan.moe/*/res/*
  6. // @include https://8chan.se/*/res/*
  7. // @run-at document-idle
  8. // @license AGPL
  9. // @description Show statistics about 8chan post IDs
  10. // @namespace https://greatest.deepsurf.us/users/1461466
  11. // ==/UserScript==
  12.  
  13. // use https://webutility.io/csv-to-chart-online to create bar graphs with csv
  14. // remove the bottom rows with (1) posters to get a better graph
  15.  
  16. let lastresult = '';
  17.  
  18. let trash = document.createElement('div');
  19.  
  20. let button = document.createElement('button');
  21. button.setAttribute('type', 'button');
  22. button.innerHTML = 'Find schizos (click to update)';
  23. trash.append(button);
  24.  
  25. let button2 = document.createElement('button');
  26. button2.setAttribute('type', 'button');
  27. button2.innerHTML = 'Copy CSV';
  28. trash.append(button2);
  29.  
  30. button2.addEventListener('click', () => navigator.clipboard.writeText(lastresult));
  31.  
  32. let button3 = document.createElement('button');
  33. button3.setAttribute('type', 'button');
  34. button3.innerHTML = 'Hide';
  35. trash.append(button3);
  36.  
  37. let moretrash = document.createElement('div');
  38. trash.append(moretrash);
  39.  
  40. button3.addEventListener('click', () => moretrash.innerHTML = '');
  41.  
  42. document.getElementById('threadList').append(trash);
  43.  
  44. async function stalk(id)
  45. {
  46. console.log('stalking', id);
  47. let dates = {};
  48. for (let hour = 0; hour < 24; hour++)
  49. {
  50. dates[hour] = 0;
  51. }
  52. for (let post of document.getElementsByClassName('postCell'))
  53. {
  54. let labelids = post.getElementsByClassName('labelId');
  55. if (labelids.length == 1 && labelids[0].innerText == id)
  56. {
  57. let date = post.getElementsByClassName('labelCreated')[0].innerText;
  58. let hour = parseInt(/ (\d{2}):\d{2}:\d{2}/.exec(date)[1]);
  59. dates[hour] = dates[hour] + 1;
  60. }
  61. }
  62. console.log(dates);
  63. let csv = `#hour,posts by ${id}\n`;
  64. for (let hour = 0; hour < 24; hour++)
  65. {
  66. csv += `${hour},${dates[hour]}\n`;
  67. }
  68. await navigator.clipboard.writeText(csv);
  69. alert('copied to clipboard');
  70. }
  71.  
  72. function shit()
  73. {
  74. moretrash.innerHTML = '';
  75. let pairs = Array.from(document.getElementsByClassName('labelId'))
  76. // get ID
  77. .map(x => x.innerText)
  78. // drop empty ID (post template?)
  79. .filter(x => x.length > 0)
  80. // count IDs
  81. .reduce((dict, x) => {dict[x] = dict[x] === undefined ? 1 : dict[x] + 1; return dict;}, {});
  82.  
  83. let list = Object.entries(pairs);
  84.  
  85. // sort by ID
  86. list.sort((a, b) => {return a[0].localeCompare(b[0]);});
  87. // sort by most schizo
  88. list.sort((a, b) => {return b[1] - a[1];});
  89.  
  90. // number of posts with IDs
  91. let allcount = list.reduce((count, x) => count + x[1], 0);
  92.  
  93. // f*ck it I love strings
  94. let html = '<table>';
  95. let csv = '#ID,posts\n';
  96. for (const [id, count] of list)
  97. {
  98. let style = 'border: 1px solid';
  99. html += `<tr><td style="${style}">${count} (${(count / allcount * 100).toFixed(1)}%)</td><td style="${style}"><span class="labelId">${id}</span></td><td><button type="button" class="stalkbtn" data-id="${id}">stalk</button></tr>`;
  100. csv += `${id},${count}\n`;
  101. }
  102. html += '</table>';
  103. html += `All: ${list.length} / ${allcount}`
  104. moretrash.innerHTML = html;
  105. lastresult = csv;
  106. // oh no I'm a retard
  107. for (let btn of document.getElementsByClassName('stalkbtn'))
  108. {
  109. btn.addEventListener('click', (ev) => stalk(ev.currentTarget.dataset.id));
  110. }
  111. }
  112.  
  113. button.addEventListener('click', shit);