Advertisement
Guest User

Untitled

a guest
Dec 6th, 2024
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.16 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Entered Giveaway Counter - SteamGifts Giveaways
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.6.1
  5. // @description Script for retrieving and counting table column headings from SteamGifts Giveaways page, only from 2024 dates
  6. // @author meneldur with several codes from missingtexture, SquishedPotatoe, kivan, lav29, greatmastermario, ngoclong19
  7. // @match https://www.steamgifts.com/giveaways/entered*
  8. // ==/UserScript==
  9.  
  10. console.log('Background script loaded.');
  11.  
  12. // Function to ensure button styles are applied
  13. function styleButton(button) {
  14. button.classList.add('featured__action-button');
  15. button.style.position = 'fixed';
  16. button.style.bottom = '10px';
  17. button.style.left = '10px';
  18. button.style.zIndex = '9999';
  19. button.style.padding = '10px';
  20. button.style.backgroundColor = '#6BA9DB';
  21. button.style.color = 'white';
  22. button.style.border = 'none';
  23. button.style.borderRadius = '4px';
  24. button.style.cursor = 'pointer';
  25. }
  26.  
  27. // Create the main button
  28. const button = document.createElement('button');
  29. button.textContent = 'Retrieve Data';
  30. styleButton(button);
  31. document.body.appendChild(button);
  32.  
  33. // Create a button to copy the table data
  34. const copyButton = document.createElement('button');
  35. copyButton.textContent = 'Copy Data';
  36. copyButton.style.position = 'fixed';
  37. copyButton.style.bottom = '10px';
  38. copyButton.style.left = '150px';
  39. styleButton(copyButton);
  40. copyButton.classList.add('is-hidden');
  41. document.body.appendChild(copyButton);
  42.  
  43. // Create a div element to display the result
  44. const resultDisplay = document.createElement('div');
  45. resultDisplay.style.cssText = `
  46. position: fixed;
  47. left: 10px;
  48. bottom: 50px;
  49. border: 1px solid #ccc;
  50. padding: 10px;
  51. background-color: white;
  52. max-width: 600px;
  53. max-height: 500px;
  54. overflow: auto;
  55. z-index: 9999;
  56. `;
  57. resultDisplay.classList.add('is-hidden');
  58. document.body.appendChild(resultDisplay);
  59.  
  60. // Object to store the count of each table column heading across all pages
  61. let headingsCount = {};
  62.  
  63. // Function to retrieve column headings from a page
  64. async function retrieveColumnHeadings(page = 1) {
  65. console.log(`Retrieving column headings for page ${page}.`);
  66. resultDisplay.textContent = `Processing page ${page}...`;
  67.  
  68. let resp = await fetch(`https://www.steamgifts.com/giveaways/entered/search?page=${page}&sort=all`, {
  69. method: 'GET'
  70. });
  71. console.log(`Received response for page ${page}.`);
  72. const parser = new DOMParser();
  73. const doc = parser.parseFromString(await resp.text(), 'text/html');
  74. const innerWrap = doc.querySelectorAll('.table__row-inner-wrap');
  75. let continueRetrieving = true;
  76.  
  77. innerWrap.forEach(wrap => {
  78. const dateSpan = wrap.querySelector('div > span[data-timestamp]');
  79. if (dateSpan) {
  80. const dateTimestamp = parseInt(dateSpan.getAttribute('data-timestamp'), 10) * 1000;
  81. const date = new Date(dateTimestamp);
  82. const year = date.getFullYear();
  83.  
  84. // Only process entries from 2024; stop if we encounter an entry outside 2024
  85. if (year === 2024) {
  86. let key = { text: wrap.querySelector('.table__column__heading').childNodes[0].textContent.trim(), appID: 0 };
  87. let thumbnail = wrap.querySelector('.table_image_thumbnail');
  88. if (thumbnail) {
  89. key.appID = thumbnail.style.backgroundImage.substring(48);
  90. key.appID = key.appID.substring(0, key.appID.search('/'));
  91. }
  92. let keyText = JSON.stringify(key);
  93. headingsCount[keyText] = (headingsCount[keyText] || 0) + 1;
  94. } else {
  95. continueRetrieving = false;
  96. }
  97. }
  98. });
  99.  
  100. if (continueRetrieving && innerWrap.length > 0) {
  101. // Continue retrieving column headings from the next page after a delay
  102. setTimeout(() => {
  103. retrieveColumnHeadings(page + 1);
  104. }, 1000); // 1 second delay
  105. } else {
  106. // Display results when done
  107. console.log('All pages processed. Sending result to content script.');
  108. displayResultsAsTable();
  109. button.disabled = false;
  110. }
  111. }
  112.  
  113. // Function to display results as a table
  114. function displayResultsAsTable() {
  115. let entriesCountMap = {};
  116. const table = document.createElement('table');
  117. table.style.cssText = `border-collapse: collapse; width: 100%;`;
  118. table.innerHTML = `
  119. <style>
  120. tr:nth-child(odd) { background-color: #f2f2f2; }
  121. tr:nth-child(even) { background-color: white; }
  122. </style>
  123. `;
  124.  
  125. const sortedHeadings = Object.entries(headingsCount)
  126. .sort(([keyTextA, countA], [keyTextB, countB]) => {
  127. if (countB !== countA) {
  128. return countB - countA;
  129. } else {
  130. if (keyTextA < keyTextB) return -1;
  131. if (keyTextA > keyTextB) return 1;
  132. return 0;
  133. }
  134. });
  135.  
  136. let rowIndex = 1;
  137.  
  138. sortedHeadings.forEach(([keyText, count]) => {
  139. const row = document.createElement('tr');
  140.  
  141. const numCell = document.createElement('td');
  142. numCell.textContent = `${rowIndex++}.`;
  143. numCell.style.padding = '3px 8px';
  144. row.appendChild(numCell);
  145.  
  146. const key = JSON.parse(keyText);
  147. const headingText = key.appID === 0
  148. ? key.text.replaceAll('<', '&lt;').replaceAll('>', '&gt;')
  149. : `<a href='https://store.steampowered.com/app/${key.appID}/' style='color: #6BA9DB;'>${key.text.replaceAll('<', '&lt;').replaceAll('>', '&gt;')}</a>`;
  150.  
  151. const headingCell = document.createElement('td');
  152. headingCell.innerHTML = headingText;
  153. row.appendChild(headingCell);
  154.  
  155. const countCell = document.createElement('td');
  156. countCell.textContent = ` (${count}x) `;
  157. countCell.style.paddingLeft = '10px';
  158. countCell.style.paddingRight = '8px';
  159. countCell.style.paddingTop = '3px';
  160. countCell.style.paddingBottom = '3px';
  161. row.appendChild(countCell);
  162. table.appendChild(row);
  163.  
  164. entriesCountMap[count] = (entriesCountMap[count] || 0) + 1;
  165. });
  166.  
  167. button.textContent = 'Retrieve Column Headings';
  168. resultDisplay.innerHTML = '';
  169. resultDisplay.appendChild(table);
  170. copyButton.classList.remove('is-hidden');
  171.  
  172. const entriesCountTable = document.createElement('table');
  173. entriesCountTable.style.marginTop = '20px';
  174. entriesCountTable.style.textAlign = 'right';
  175. entriesCountTable.style.color = '#6BA9DB';
  176. entriesCountTable.innerHTML = `<style>td, th { padding: 3px 8px; }</style>`;
  177. const row = document.createElement('tr');
  178.  
  179. const header1Cell = document.createElement('th');
  180. header1Cell.textContent = 'Entries';
  181. row.appendChild(header1Cell);
  182.  
  183. const header2Cell = document.createElement('th');
  184. header2Cell.textContent = 'Games';
  185. row.appendChild(header2Cell);
  186. entriesCountTable.appendChild(row);
  187.  
  188. Object.entries(entriesCountMap)
  189. .sort(([entrieA, ], [entrieB, ]) => entrieB - entrieA)
  190. .forEach(([entries, count]) => {
  191. const row = document.createElement('tr');
  192.  
  193. const entriesCell = document.createElement('td');
  194. entriesCell.textContent = `${entries}x`;
  195. row.appendChild(entriesCell);
  196.  
  197. const countCell = document.createElement('td');
  198. countCell.textContent = count;
  199. row.appendChild(countCell);
  200. entriesCountTable.appendChild(row);
  201. });
  202. resultDisplay.appendChild(entriesCountTable);
  203. }
  204.  
  205. // Function to copy the table data
  206. async function copyTableData() {
  207. const input = prompt('Enter the row numbers or ranges you want to copy (e.g., "1,3-5,7"):');
  208. if (input === null) return;
  209.  
  210. function parseRowIndices(input) {
  211. const indices = [];
  212. input.split(',').forEach(range => {
  213. if (range.includes('-')) {
  214. const [start, end] = range.split('-').map(Number);
  215. for (let i = start; i <= end; i++) {
  216. indices.push(i);
  217. }
  218. } else {
  219. indices.push(Number(range));
  220. }
  221. });
  222. return indices;
  223. }
  224.  
  225. const rowIndices = parseRowIndices(input);
  226. const table = resultDisplay.querySelector('table');
  227. let data = [];
  228. table.querySelectorAll('tr').forEach((row, index) => {
  229. if (rowIndices.includes(index + 1)) {
  230. let rowData = [];
  231. row.querySelectorAll('td').forEach((cell) => {
  232. rowData.push(cell.textContent.trim());
  233. });
  234. data.push(rowData.join('\t'));
  235. }
  236. });
  237. await navigator.clipboard.writeText(data.join('\n'));
  238. alert('Data copied to clipboard!');
  239. }
  240.  
  241. copyButton.addEventListener('click', copyTableData);
  242.  
  243. button.addEventListener('click', async () => {
  244. headingsCount = {};
  245. resultDisplay.innerHTML = '';
  246. resultDisplay.classList.remove('is-hidden');
  247. button.disabled = true;
  248. await retrieveColumnHeadings(1);
  249. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement