Wisdom Interpreter

Python Runner for AI, You can use it to run python code in the web

  1. // ==UserScript==
  2. // @name Wisdom Interpreter
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-06-09-5
  5. // @description Python Runner for AI, You can use it to run python code in the web
  6. // @author WuJunkai2004
  7. // @license MIT
  8. // @match *://yiyan.baidu.com
  9. // @match *://tongyi.aliyun.com/qianwen/
  10. // @match *://gemini.google.com/*
  11. // @match *://chatgpt.com/*
  12. // @icon https://www.google.com/s2/favicons?sz=64&domain=baidu.com
  13. // @grant none
  14. // ==/UserScript==
  15. function get_site_info(){
  16. let url = window.location.href;
  17. let support = [
  18. {
  19. 'site': 'yiyan',
  20. 'id': '#DIALOGUE_CONTAINER_ID',
  21. "cmd": "for_baidu;"
  22. },{
  23. 'site': 'tongyi',
  24. 'id': '#chat-content',
  25. "cmd": "for_aliyun;"
  26. },{
  27. 'site': 'gemini',
  28. 'id': '.content-wrapper',
  29. "cmd": "for_gemini;"
  30. },{
  31. "site": "chatgpt.com",
  32. "id": ".pb-9",
  33. "cmd": "for_chatgpt;"
  34. }
  35. ]
  36. for(let site of support){
  37. if(url.includes(site.site)){
  38. return site;
  39. }
  40. }
  41. }
  42.  
  43. let observer = null;
  44.  
  45. async function inject_runner(){
  46. observer = new MutationObserver((mutationsList, mutationObserver) => {
  47. // insert element
  48. // debounce
  49. let last_time = localStorage.getItem('last_time') || null;
  50. last_time = last_time ? parseInt(last_time) : null;
  51. if(last_time){
  52. clearTimeout(last_time);
  53. }
  54. // run the code
  55. last_time = setTimeout(eval(get_site_info().cmd), 2000);
  56. localStorage.setItem('last_time', last_time);
  57. }).observe(document.querySelector(get_site_info().id), {
  58. childList: true,
  59. subtree: true,
  60. characterData: true
  61. });
  62. }
  63.  
  64. async function inject_stdlib(){
  65. let script = document.createElement('script');
  66. script.src = 'https://cdn.jsdelivr.net/gh/WuJunkai2004/Python-Runner-Plugin@delta/brython_stdlib.js';
  67. script.onload = inject_runner;
  68. document.body.appendChild(script);
  69. }
  70.  
  71. async function inject_brython(){
  72. if(window.location.href.includes('chatgpt.com')){
  73. // 注入meta标签
  74. // <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-fad90428-621b-47e4-815c-cd1e204b5312' 'sha256-RvbVrdDS11FSnQaULCOgXPA5u0nMP2Im1d2pGiRBGC4=' 'sha256-eMuh8xiwcX72rRYNAGENurQBAcH7kLlAUQcoOri3BIo=' http://localhost:8787">
  75. let meta = document.createElement('meta');
  76. meta.httpEquiv = 'Content-Security-Policy';
  77. let content = "script-src-elem 'self' 'nonce-642953da-fa5b-45a4-84c7-afc8d603da9a' 'sha256-RvbVrdDS11FSnQaULCOgXPA5u0nMP2Im1d2pGiRBGC4=' 'sha256-eMuh8xiwcX72rRYNAGENurQBAcH7kLlAUQcoOri3BIo=' auth0.openai.com challenges.cloudflare.com chatgpt.com/ces https://*.chatgpt.com https://*.chatgpt.com/ https://*.oaistatic.com https://api.openai.com https://apis.google.com https://chat.openai.com https://chatgpt.com/ https://chatgpt.com/backend-anon https://chatgpt.com/backend-api https://chatgpt.com/graphql https://chatgpt.com/public-api https://chatgpt.com/voice https://docs.google.com https://jidori.g1.internal.services.openai.org https://js.live.net/v7.2/OneDrive.js https://oaistatic.com https://snc.apps.openai.com https://snc.chatgpt.com/backend/se https://tcr9i.chat.openai.com https://tcr9i.chatgpt.com/ https://www-onepick-opensocial.googleusercontent.com wss://*.chatgpt.com wss://*.chatgpt.com/ http://localhost:8787";
  78. meta.content = content;
  79. await sleep(1000);
  80. document.head.appendChild(meta);
  81. }
  82. let script = document.createElement('script');
  83. script.src = 'https://cdn.jsdelivr.net/gh/WuJunkai2004/Python-Runner-Plugin@delta/brython.min.js';
  84. script.onload = inject_stdlib;
  85. document.body.appendChild(script);
  86. }
  87.  
  88. async function sleep(ms){
  89. return new Promise((resolve) => setTimeout(resolve, ms));
  90. }
  91.  
  92. async function get_dialogue_container(){
  93. let first_time = true;
  94. let container = null;
  95. let id = get_site_info().id;
  96. do{
  97. container = document.querySelector(id);
  98. if(first_time != true){
  99. await sleep(1000);
  100. } else {
  101. first_time = false;
  102. }
  103. }while(!container);
  104. return container;
  105. }
  106.  
  107. function generate_run_svg(size){
  108. //M3 2 L26 16 L3 30 L5 26 L22 16 L5 6 L5 26 L3 30 Z
  109. //it is for 32*32
  110. return `M${size*0.09375} ${size*0.0625} L${size*0.8125} ${size*0.5} L${size*0.09375} ${size*0.9375} L${size*0.15625} ${size*0.8125} L${size*0.6875} ${size*0.5} L${size*0.15625} ${size*0.1875} L${size*0.15625} ${size*0.8125} L${size*0.09375} ${size*0.9375} Z`
  111. }
  112.  
  113. function for_baidu(){
  114. console.log('baidu');
  115. function insert_after(new_node, target_node){
  116. let parent = target_node.parentNode;
  117. if(parent.lastChild == target_node){
  118. parent.appendChild(new_node);
  119. } else {
  120. parent.insertBefore(new_node, target_node.nextSibling);
  121. }
  122. };
  123. let code_block = document.querySelectorAll('.language-python');
  124. for(let code of code_block){
  125. let is_done = code.getAttribute('is-done') || null;
  126. if(is_done){
  127. continue;
  128. }
  129. code.setAttribute('is-done', true);
  130. // add the display block
  131. let id = Math.random().toString(36).slice(-8);
  132. let result = code.parentNode.cloneNode(true);
  133. result.setAttribute('id', id);
  134. result.querySelectorAll('.code-copy').forEach(element => element.remove());
  135. result.querySelector('.code-lang').innerText = 'output';
  136. result.querySelector('tbody').innerHTML = '';
  137. result.querySelector('tbody').setAttribute('id', id + '_output');
  138. result.setAttribute('hidden', true);
  139. insert_after(result, code.parentNode);
  140. // get the code script
  141. let tr_list = code.getElementsByTagName('tr');
  142. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  143. ' from browser import document\n' +
  144. ' text = " " + sep.join(list(map(str, args)))\n' +
  145. ' if init:\n' +
  146. ` document['${id}_output'].innerHTML = ''\n` +
  147. ' return\n' +
  148. ` document['${id}'].hidden = False\n` +
  149. ` document['${id}_output'].innerHTML += text + end\n` +
  150. 'print(init=True)\n'
  151. for(let tr of tr_list){
  152. code_text += tr.innerText.slice(1) + '\n';
  153. }
  154. // show the run cpy_button
  155. let cpy_button = code.getElementsByClassName('code-copy')[0];
  156. let run_button = cpy_button.cloneNode(true);
  157. run_button.addEventListener('click', () => {
  158. console.log(code_text);
  159. try{
  160. window.__BRYTHON__.runPythonSource(code_text, id);
  161. } catch(e) {
  162. document.getElementById(id + '_output').innerHTML += '\n Error: 因错误而退出\n';
  163. document.getElementById(id).hidden = false;
  164. console.log(e);
  165. }
  166. });
  167. run_button.querySelector('path').setAttribute('d', generate_run_svg(32));
  168. run_button.getElementsByClassName('code-copy-text')[0].innerText = '运行代码';
  169. insert_after(run_button, cpy_button);
  170. }
  171. }
  172.  
  173.  
  174. function for_aliyun(){
  175. function insert_after(new_node, target_node){
  176. let parent = target_node.parentNode;
  177. if(parent.lastChild == target_node){
  178. parent.appendChild(new_node);
  179. } else {
  180. parent.insertBefore(new_node, target_node.nextSibling);
  181. }
  182. };
  183. let code_block = document.querySelectorAll('.tongyi-ui-highlighter');
  184. for(let code of code_block){
  185. let is_done = code.getAttribute('is-done') || null;
  186. if(is_done){
  187. continue;
  188. }
  189. code.setAttribute('is-done', true);
  190. // 排除掉不是python的代码块
  191. if(code.querySelector('span').innerText !== "Python"){
  192. continue;
  193. }
  194. // 添加显示结果的代码块
  195. let id = Math.random().toString(36).slice(-8);
  196. let result = code.parentNode.cloneNode(true);
  197. result.setAttribute('id', id);
  198. result.querySelectorAll('.tongyi-ui-highlighter-copy-btn').forEach(element => element.remove());
  199. result.querySelector('.tongyi-ui-highlighter-lang').innerHTML = 'Output';
  200. result.querySelector('code').innerHTML = '';
  201. result.querySelector('code').setAttribute('id', id + '_output');
  202. result.setAttribute('hidden', true);
  203. insert_after(result, code.parentNode);
  204. // get the code script
  205. let text_list = code.querySelector('code').innerText.split('\n');
  206. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  207. ' from browser import document\n' +
  208. ' text = " " + sep.join(list(map(str, args)))\n' +
  209. ' if init:\n' +
  210. ` document['${id}_output'].innerHTML = ''\n` +
  211. ' return\n' +
  212. ` document['${id}'].hidden = False\n` +
  213. ` document['${id}_output'].innerHTML += text + end\n` +
  214. 'print(init=True)\n';
  215. for(let line_id=1; line_id<=text_list.length; line_id++){
  216. let id_len = line_id.toString().length;
  217. code_text += text_list[line_id-1].slice(id_len) + '\n';
  218. }
  219. // show the run cpy_button
  220. let cpy_button = code.querySelector('svg');
  221. let run_button = cpy_button.cloneNode(true);
  222. run_button.setAttribute('style', 'margin-left: 10px;');
  223. run_button.querySelector('path').setAttribute('d', generate_run_svg(12));
  224. run_button.addEventListener('click', () => {
  225. console.log(code_text);
  226. try{
  227. window.__BRYTHON__.runPythonSource(code_text, id);
  228. } catch(e) {
  229. document.getElementById(id + '_output').innerHTML += '\n Error: 因错误而退出\n';
  230. document.getElementById(id).hidden = false;
  231. console.log(e);
  232. }
  233. });
  234. insert_after(run_button, cpy_button);
  235. console.log('done');
  236. }
  237. }
  238.  
  239. function for_chatgpt(){
  240. function insert_after(new_node, target_node){
  241. let parent = target_node.parentNode;
  242. if(parent.lastChild == target_node){
  243. parent.appendChild(new_node);
  244. } else {
  245. parent.insertBefore(new_node, target_node.nextSibling);
  246. }
  247. };
  248. let code_block = document.querySelectorAll('pre');
  249. for(let code of code_block){
  250. let is_done = code.getAttribute('is-done') || null;
  251. if(is_done){
  252. continue;
  253. }
  254. code.setAttribute('is-done', true);
  255. // 排除掉不是python的代码块
  256. if(code.querySelector('span').innerText !== 'python'){
  257. continue;
  258. }
  259. // 添加显示结果的代码块
  260. let id = Math.random().toString(36).slice(-8);
  261. let result = code.cloneNode(true);
  262. result.setAttribute('id', id);
  263. result.querySelector('span').nextElementSibling.remove()
  264. result.querySelector('span').innerText = 'output';
  265. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  266. ' from browser import document\n' +
  267. ' text = " " + sep.join(list(map(str, args)))\n' +
  268. ' if init:\n' +
  269. ` document['${id}_output'].innerHTML = ''\n` +
  270. ' return\n' +
  271. ` document['${id}'].hidden = False\n` +
  272. ` document['${id}_output'].innerHTML += text + end\n` +
  273. 'print(init=True)\n';
  274. code_text += code.querySelector('code').innerText + '\n';
  275. result.querySelector('code').innerHTML = '';
  276. console.log(code_text);
  277. }
  278. }
  279.  
  280.  
  281. (async function() {
  282. 'use strict';
  283. await get_dialogue_container();
  284. console.log('Python Runner for AI is running...');
  285. await inject_brython();
  286. })();