Python Runner for AI

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

目前為 2024-06-09 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Python Runner for AI
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-06-09
  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 unsafeWindow
  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 = 'http://ttakods.dynv6.net:8787/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. 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 = 'http://ttakods.dynv6.net:8787/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. function insert_after(new_node, target_node){
  115. let parent = target_node.parentNode;
  116. if(parent.lastChild == target_node){
  117. parent.appendChild(new_node);
  118. } else {
  119. parent.insertBefore(new_node, target_node.nextSibling);
  120. }
  121. };
  122. let code_block = document.querySelectorAll('.language-python');
  123. for(let code of code_block){
  124. let is_done = code.getAttribute('is-done') || null;
  125. if(is_done){
  126. continue;
  127. }
  128. code.setAttribute('is-done', true);
  129. // add the display block
  130. let id = Math.random().toString(36).slice(-8);
  131. let result = code.parentNode.cloneNode(true);
  132. result.setAttribute('id', id);
  133. result.querySelectorAll('.code-copy').forEach(element => element.remove());
  134. result.querySelector('.code-lang').innerText = 'output';
  135. result.querySelector('tbody').innerHTML = '';
  136. result.querySelector('tbody').setAttribute('id', id + '_output');
  137. result.setAttribute('hidden', true);
  138. insert_after(result, code.parentNode);
  139. // get the code script
  140. let tr_list = code.getElementsByTagName('tr');
  141. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  142. ' from browser import document\n' +
  143. ' text = " " + sep.join(list(map(str, args)))\n' +
  144. ' if init:\n' +
  145. ` document['${id}_output'].innerHTML = ''\n` +
  146. ' return\n' +
  147. ` document['${id}'].hidden = False\n` +
  148. ` document['${id}_output'].innerHTML += text + end\n` +
  149. 'print(init=True)\n'
  150. for(let tr of tr_list){
  151. code_text += tr.innerText.slice(1) + '\n';
  152. }
  153. // show the run cpy_button
  154. let cpy_button = code.getElementsByClassName('code-copy')[0];
  155. let run_button = cpy_button.cloneNode(true);
  156. run_button.addEventListener('click', () => {
  157. console.log(code_text);
  158. try{
  159. __BRYTHON__.runPythonSource(code_text, id);
  160. } catch(e) {
  161. document.getElementById(id + '_output').innerHTML += '\n Error: 因错误而退出\n';
  162. document.getElementById(id).hidden = false;
  163. console.log(e);
  164. }
  165. });
  166. run_button.querySelector('path').setAttribute('d', generate_run_svg(32));
  167. run_button.getElementsByClassName('code-copy-text')[0].innerText = '运行代码';
  168. insert_after(run_button, cpy_button);
  169. }
  170. }
  171.  
  172.  
  173. function for_aliyun(){
  174. function insert_after(new_node, target_node){
  175. let parent = target_node.parentNode;
  176. if(parent.lastChild == target_node){
  177. parent.appendChild(new_node);
  178. } else {
  179. parent.insertBefore(new_node, target_node.nextSibling);
  180. }
  181. };
  182. let code_block = document.querySelectorAll('.tongyi-ui-highlighter');
  183. for(let code of code_block){
  184. let is_done = code.getAttribute('is-done') || null;
  185. if(is_done){
  186. continue;
  187. }
  188. code.setAttribute('is-done', true);
  189. // 排除掉不是python的代码块
  190. if(code.querySelector('span').innerText !== "Python"){
  191. continue;
  192. }
  193. // 添加显示结果的代码块
  194. let id = Math.random().toString(36).slice(-8);
  195. let result = code.parentNode.cloneNode(true);
  196. result.setAttribute('id', id);
  197. result.querySelectorAll('.tongyi-ui-highlighter-copy-btn').forEach(element => element.remove());
  198. result.querySelector('.tongyi-ui-highlighter-lang').innerHTML = 'Output';
  199. result.querySelector('code').innerHTML = '';
  200. result.querySelector('code').setAttribute('id', id + '_output');
  201. result.setAttribute('hidden', true);
  202. insert_after(result, code.parentNode);
  203. // get the code script
  204. let text_list = code.querySelector('code').innerText.split('\n');
  205. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  206. ' from browser import document\n' +
  207. ' text = " " + sep.join(list(map(str, args)))\n' +
  208. ' if init:\n' +
  209. ` document['${id}_output'].innerHTML = ''\n` +
  210. ' return\n' +
  211. ` document['${id}'].hidden = False\n` +
  212. ` document['${id}_output'].innerHTML += text + end\n` +
  213. 'print(init=True)\n';
  214. for(let line_id=1; line_id<=text_list.length; line_id++){
  215. let id_len = line_id.toString().length;
  216. code_text += text_list[line_id-1].slice(id_len) + '\n';
  217. }
  218. // show the run cpy_button
  219. let cpy_button = code.querySelector('svg');
  220. let run_button = cpy_button.cloneNode(true);
  221. run_button.setAttribute('style', 'margin-left: 10px;');
  222. run_button.querySelector('path').setAttribute('d', generate_run_svg(12));
  223. run_button.addEventListener('click', () => {
  224. console.log(code_text);
  225. try{
  226. __BRYTHON__.runPythonSource(code_text, id);
  227. } catch(e) {
  228. document.getElementById(id + '_output').innerHTML += '\n Error: 因错误而退出\n';
  229. document.getElementById(id).hidden = false;
  230. console.log(e);
  231. }
  232. });
  233. insert_after(run_button, cpy_button);
  234. console.log('done');
  235. }
  236. }
  237.  
  238. function for_chatgpt(){
  239. function insert_after(new_node, target_node){
  240. let parent = target_node.parentNode;
  241. if(parent.lastChild == target_node){
  242. parent.appendChild(new_node);
  243. } else {
  244. parent.insertBefore(new_node, target_node.nextSibling);
  245. }
  246. };
  247. let code_block = document.querySelectorAll('pre');
  248. for(let code of code_block){
  249. let is_done = code.getAttribute('is-done') || null;
  250. if(is_done){
  251. continue;
  252. }
  253. code.setAttribute('is-done', true);
  254. // 排除掉不是python的代码块
  255. if(code.querySelector('span').innerText !== 'python'){
  256. continue;
  257. }
  258. // 添加显示结果的代码块
  259. let id = Math.random().toString(36).slice(-8);
  260. let result = code.cloneNode(true);
  261. result.setAttribute('id', id);
  262. result.querySelector('span').nextElementSibling.remove()
  263. result.querySelector('span').innerText = 'output';
  264. let code_text = `def print(*args,sep=' ', end='\\n', file='', flush='', init=False):\n` +
  265. ' from browser import document\n' +
  266. ' text = " " + sep.join(list(map(str, args)))\n' +
  267. ' if init:\n' +
  268. ` document['${id}_output'].innerHTML = ''\n` +
  269. ' return\n' +
  270. ` document['${id}'].hidden = False\n` +
  271. ` document['${id}_output'].innerHTML += text + end\n` +
  272. 'print(init=True)\n';
  273. code_text += code.querySelector('code').innerText + '\n';
  274. result.querySelector('code').innerHTML = '';
  275. console.log(code_text);
  276. }
  277. }
  278.  
  279.  
  280. (async function() {
  281. 'use strict';
  282. await get_dialogue_container();
  283. console.log('Python Runner for AI is running...');
  284. await inject_brython();
  285. })();