ChatGPT Text File Scaler

ChatGPT utility to cut and transfer text files

目前为 2023-03-20 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name ChatGPT Text File Scaler
  3. // @version 1.0
  4. // @author refracta
  5. // @description ChatGPT utility to cut and transfer text files
  6. // @match https://chat.openai.com/*
  7. // @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com
  8. // @license MIT
  9. // @namespace https://greasyfork.org/users/467840
  10. // ==/UserScript==
  11.  
  12. (async function () {
  13. 'use strict';
  14. localStorage.buffer = localStorage.buffer ? localStorage.buffer : '';
  15. function waitFor(valueFunction, inspectPeriod = 100) {
  16. return new Promise(resolve => {
  17. let interval = setInterval(async _ => {
  18. try {
  19. let value = valueFunction();
  20. value = value instanceof Promise ? await value : value;
  21. if (value) {
  22. clearInterval(interval);
  23. resolve(value);
  24. }
  25. } catch (e) {}
  26. }, inspectPeriod);
  27. });
  28. }
  29.  
  30. function writeMessage(text) {
  31. document.querySelector('textarea').value = text;
  32. }
  33.  
  34. function clickSendButton() {
  35. document.querySelector('button.absolute').click();
  36. }
  37.  
  38. async function waitResponse() {
  39. await waitFor(_ => document.querySelector('button.absolute.p-1 > svg'));
  40. }
  41.  
  42. function clearMessages(messageLimit) {
  43. let messages = Array.from(document.querySelectorAll('.flex-1.overflow-hidden > div > div > div > div:nth-child(1) > div'));
  44. while (messages.length > messageLimit) {
  45. messages.shift().remove();
  46. }
  47. }
  48.  
  49. async function sendMessage(text) {
  50. writeMessage(text);
  51. clickSendButton();
  52. await waitResponse();
  53. }
  54.  
  55. function getText() {
  56. return new Promise(resolve => {
  57. let input = document.createElement("input");
  58. input.type = "file";
  59. input.accept = "text/plain";
  60. input.onchange = (event) => {
  61. let file = event.target.files[0];
  62. let reader = new FileReader();
  63. reader.onload = () => {
  64. resolve(reader.result);
  65. };
  66. reader.readAsText(file);
  67. };
  68. input.click();
  69. });
  70. }
  71.  
  72. function createElement(html) {
  73. var div = document.createElement('div');
  74. div.innerHTML = html.trim();
  75. return div.firstChild;
  76. }
  77.  
  78. function updateLoadTextFileSpan() {
  79. let loadTextFileSpan = document.querySelector('#load-text-file');
  80. if (loadTextFileSpan) {
  81. loadTextFileSpan.textContent = `Load text file (${localStorage.buffer.length})`;
  82. }
  83. }
  84.  
  85. async function sendTextFile() {
  86. const firstMessage = 'I am going to provide you a book in multiple messages.';
  87. const insertMessage = 'Here is the next page, please do not respond aside from confirmation:\n\n';
  88. const splitLength = 2000;
  89. const messageLimit = 30;
  90.  
  91. await sendMessage(firstMessage);
  92. while (localStorage.buffer.length > 0) {
  93. let length = splitLength - insertMessage.length;
  94. let text = localStorage.buffer.slice(0, length);
  95. await sendMessage(insertMessage + text);
  96. localStorage.buffer = localStorage.buffer.slice(length);
  97. updateLoadTextFileSpan();
  98. clearMessages(messageLimit);
  99. }
  100. }
  101.  
  102. let isUIProcessing = false;
  103. setInterval(async _ => {
  104. if (!document.querySelector('#load-text-file') && !isUIProcessing) {
  105. isUIProcessing = true;
  106. let loadTextFileButton = createElement(`<a href="#" class="flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white cursor-pointer text-sm"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg><span id="load-text-file">Load text file (${localStorage.buffer.length})</span></a>`);
  107. loadTextFileButton.addEventListener('click', async() => {
  108. localStorage.buffer = await getText();
  109. updateLoadTextFileSpan();
  110. });
  111.  
  112. let sendTextFileButton = createElement(`<a href="#" class="flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white cursor-pointer text-sm"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>Send text file</a>`);
  113. sendTextFileButton.addEventListener('click', sendTextFile);
  114.  
  115. let clearConversationButton = await waitFor(_ => Array.from(document.querySelectorAll('.py-3')).filter(e => e.textContent === 'Clear conversations')[0]);
  116. clearConversationButton.parentElement.insertBefore(loadTextFileButton, clearConversationButton);
  117. clearConversationButton.parentElement.insertBefore(sendTextFileButton, clearConversationButton);
  118. isUIProcessing = false;
  119. }
  120. }, 100);
  121. })();