您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A dedicated library for loading the Pyodide runtime and executing Python code for TriX.
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.org/scripts/542306/1622816/TriX%20Python%20Runner%20Library.js
// ==UserScript== // @name TriX Python Runner Library // @namespace https://github.com/YourUsername/TriX-Executor // @version 1.0.0 // @description A dedicated library for loading the Pyodide runtime and executing Python code for TriX. // @author You // @require https://cdn.jsdelivr.net/pyodide/v0.25.1/full/pyodide.js // @license MIT // ==/UserScript== const TriX_Python = (function() { 'use strict'; const PyodideManager = { pyodide: null, isLoading: false, isSkipped: false, // This init function is now much simpler. // The @require directive ensures 'loadPyodide' is already available. async init(isPreloading = false, progressCallback = null) { if (this.pyodide || this.isLoading || this.isSkipped) return; this.isLoading = true; // Give initial feedback if (!isPreloading) { TriX_UI.setPythonStatus('loading'); TriX_UI.log('Initializing Python runtime (Pyodide)...', 'info'); TriX_UI.createProgressBar(); } try { if (typeof loadPyodide !== 'function') { throw new Error("Fatal: `loadPyodide` was not loaded by @require."); } // Use the globally available loadPyodide function this.pyodide = await loadPyodide({ indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.25.1/full/', // Use the progress callback to update the loader UI fullErrHandler: (err) => { if (progressCallback) progressCallback({ what: err }) }, stdout: (msg) => { if (progressCallback) progressCallback({ what: msg }) }, }); // Final success feedback if (!isPreloading) { document.getElementById('trix-py-progress-container')?.remove(); TriX_UI.log('Python runtime ready.', 'info'); TriX_UI.setPythonStatus('ready'); } } catch (err) { if (!isPreloading) { document.getElementById('trix-py-progress-container')?.remove(); TriX_UI.setPythonStatus('error'); } TriX_UI.log(`Error loading Pyodide: ${err.message}.`, 'error'); throw err; } finally { this.isLoading = false; } }, async run(code, packages) { if (this.isSkipped) return TriX_UI.log('Python was skipped during startup. Please reload to enable.', 'warn'); if (!this.pyodide) { TriX_UI.log('Python runtime is not ready yet. Please wait.', 'warn'); if (this.isLoading) return; await this.init(); if (!this.pyodide) return; } TriX_UI.setPythonStatus('running'); try { if (packages) { const packageList = packages.split(',').map(p => p.trim()).filter(p => p); if (packageList.length > 0) { TriX_UI.log(`Loading Python packages: ${packageList.join(', ')}`, 'info'); await this.pyodide.loadPackage("micropip"); const micropip = this.pyodide.pyimport("micropip"); await micropip.install(packageList); TriX_UI.log('Packages loaded.', 'info'); } } TriX_UI.log('Executing Python script...', 'info'); this.pyodide.setStdout({ batched: (msg) => TriX_UI.log(`${msg}`, 'log') }); this.pyodide.setStderr({ batched: (msg) => TriX_UI.log(`[Python Error]: ${msg}`, 'error') }); await this.pyodide.runPythonAsync(code); } catch (err) { TriX_UI.log(`Python Error: ${err}`, 'error'); } finally { TriX_UI.setPythonStatus('ready'); } } }; return PyodideManager; })();