Greasy Fork 还支持 简体中文。

Dune Csv Export

Downloading the queries csv export for free subscription users

目前為 2024-04-29 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Dune Csv Export
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Downloading the queries csv export for free subscription users
  6. // @author Rv
  7. // @match https://dune.com/queries*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=dune.com
  9. // @grant none
  10. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js
  11. // ==/UserScript==
  12.  
  13. function getElementByXpath(path){
  14. return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  15. }
  16.  
  17. function getHeaders(table){
  18. const headers = [];
  19. $.each($(table).find("thead").find("tr").find("th"), function (key, val2) {
  20. headers[key] = $(val2).find("div").text();
  21. });
  22. return headers;
  23. }
  24.  
  25. function getValues(table){
  26. const values = []
  27. $.each($(table).find("tbody").find("tr"), function (key, val) {
  28. const row = [];
  29. $.each($(val).find("td"), function (tkey, tval) {
  30. row[tkey] = $(tval).find("div").first().text();
  31. });
  32. values[key] = row;
  33. });
  34. return values;
  35. }
  36.  
  37. function collectLoop(last_values=[]){
  38. let nextButton = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[2]/ul/li[6]/button');
  39. let table = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[1]/table');
  40. const values = getValues(table);
  41. const newValues = last_values.concat(values);
  42.  
  43. if (!$(nextButton).is(":disabled") && nextButton != null){
  44. $(nextButton).trigger("click");
  45. setTimeout(()=>{
  46. return collectLoop(newValues);
  47. }, 20)
  48. } else {
  49. const headers = getHeaders(table);
  50. download_csv(headers, newValues);
  51. }
  52. }
  53.  
  54.  
  55. function download_csv(headers, rows) {
  56. let csvHeaders = headers.join(",") + "\n";
  57. let csvRows = rows.map(row => row.join(",")).join("\n");
  58. let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
  59. let custom_name = document.getElementById("customName").value;
  60.  
  61.  
  62. var downloadBtn = document.createElement("a");
  63. downloadBtn.href = "data:text/csv;charset=utf-8,"+encodeURI(csvHeaders+csvRows);
  64. downloadBtn.target = "_blank";
  65.  
  66. if (custom_name.length > 1) {
  67. downloadBtn.download = custom_name+".csv";
  68. } else {
  69. let url = window.location.href;
  70.  
  71. downloadBtn.download = "query_"+url.split("queries/")[1].replace("/", "_")+".csv"
  72. }
  73.  
  74. downloadBtn.click();
  75.  
  76. csvButton.disabled = false;
  77.  
  78.  
  79. }
  80.  
  81.  
  82. function collectCsv() {
  83. let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
  84.  
  85. csvButton.disabled = "disabled";
  86.  
  87.  
  88. let nextButton = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[2]/ul/li[6]/button');
  89. if (nextButton == null){
  90. console.log("Butt not exists");
  91. collectLoop();
  92. } else {
  93. // go to first
  94. let firstPageBtn = getElementByXpath('//*[@id="results"]/div/div[2]/div/div[2]/ul/li[3]/button');
  95. if (firstPageBtn != null && !$(firstPageBtn).is(":disabled")){
  96. $(firstPageBtn).trigger("click");
  97. setTimeout(()=>{
  98. collectLoop();
  99. }, 5);
  100. } else {
  101. collectLoop();
  102. }
  103. }
  104.  
  105. }
  106.  
  107. function changeCsvButton(){
  108. // console.log("Running Dune Script");
  109. let csvButton = getElementByXpath('//*[@id="results"]/div/div[1]/div[1]/div/button');
  110. if (csvButton != null && $(csvButton).is(":disabled")){
  111. csvButton.disabled = false;
  112. csvButton.onclick = collectCsv;
  113.  
  114. // adding a input for custom csv file name
  115. var inp_element = document.createElement('input');
  116. inp_element.className = "IconButton_iconButton___v3YQ buttonThemes_button__jfRFC buttonThemes_theme-tertiary__v7VoN IconButton_size-M__FIXfN";
  117. inp_element.id = "customName";
  118. inp_element.placeholder = "Custom filename";
  119.  
  120. getElementByXpath('//*[@id="results"]/div/div[1]/div[1]').appendChild(inp_element);
  121.  
  122. } else {
  123. setTimeout(()=>{
  124. changeCsvButton();
  125. }, 1000)
  126. }
  127. }
  128.  
  129.  
  130. (function() {
  131. 'use strict';
  132.  
  133.  
  134. $(document).ready ( function(){
  135. changeCsvButton();
  136. });
  137.  
  138.  
  139. })();