智能代码解释器(第3版)

一个基于Web的智能代码解释器工具,调用本地AI大模型,可以自动识别代码语言,高亮显示代码,并提供代码结构分析和解释。

## 功能特点

– 📝 **代码语言自动识别**:智能检测输入代码的编程语言

– 🎨 **语法高亮显示**:美化代码展示,提高可读性

– 🏗️ **代码结构分析**:提取并展示代码中的类、函数、导入语句等结构

– 📖 **代码解释**:提供代码的详细解释(可选择使用OpenAI API获取更智能的解释)

– 💻 **用户友好界面**:简洁直观的Web界面,操作简单

## 安装说明

### 1. 安装依赖

“`bash

cd f:\TraeCN\智能代码解释器

pip install -r requirements.txt

“`

### 2. 配置OpenAI API(可选)

如果您希望使用OpenAI API获取更智能的代码解释,请按照以下步骤操作:

1. 复制`.env.example`文件并重命名为`.env`

2. 在`.env`文件中填入您的OpenAI API密钥

“`

OPENAI_API_KEY=your_api_key_here

“`

> 注意:即使没有OpenAI API密钥,工具仍然可以使用基本的代码分析功能。

## 使用方法

### 1. 启动应用

“`bash

python app.py

“`

### 2. 访问界面

打开浏览器,访问以下地址:

“`

http://localhost:5000

“`

### 3. 使用工具

1. 在代码输入框中粘贴或输入您想要分析的代码

2. 点击”分析代码”按钮

3. 在结果区域查看分析结果,包括:

   – 高亮显示的代码

   – 代码结构分析(类、函数、导入等)

   – 代码解释

## 支持的语言

工具支持多种编程语言的识别和分析,包括但不限于:

– Python

– Java

– JavaScript

– TypeScript

– HTML

– CSS

– C/C++

– C#

– Go

– Rust

– PHP

– Ruby

– Swift

– Kotlin

– SQL

– Shell/Bash

– JSON/XML/YAML

## 技术栈

**后端**:Python, Flask

**前端**:HTML, CSS, JavaScript

**代码高亮**:Pygments

**语言检测**:langdetect

**智能解释**:可选的OpenAI API集成

## 注意事项

1. 为了获得最佳体验,请使用现代浏览器(Chrome, Firefox, Edge等)

2. 大型代码文件可能需要较长时间处理

3. 使用OpenAI API需要有效的API密钥,并且可能产生费用

4. 工具仅在本地运行,不会上传您的代码到任何服务器

## 扩展与贡献

如果您想扩展或改进此工具,欢迎提交Issue或Pull Request。

## 许可证

此项目采用MIT许可证。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能代码解释器</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 20px;
            min-height: 100vh;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        .header {
            background: linear-gradient(135deg, #1890ff 0%, #722ed1 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        .header h1 {
            margin: 0;
            font-size: 2.5em;
            font-weight: 600;
        }
        .content {
            padding: 30px;
        }
        .input-section {
            margin-bottom: 30px;
        }
        .input-section h2,
        .result-section h2 {
            color: #333;
            margin-bottom: 15px;
            font-weight: 600;
        }
        #code-input {
            width: 100%;
            min-height: 300px;
            padding: 15px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            resize: vertical;
        }
        #analyze-btn {
            background: #1890ff;
            color: white;
            border: none;
            padding: 12px 24px;
            margin-top: 10px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 500;
            transition: background 0.3s;
        }
        #analyze-btn:hover {
            background: #40a9ff;
        }
        .result-section {
            display: none;
        }
        .result-tabs {
            display: flex;
            border-bottom: 1px solid #d9d9d9;
            margin-bottom: 20px;
        }
        .tab {
            padding: 10px 20px;
            cursor: pointer;
            border-bottom: 2px solid transparent;
            transition: all 0.3s;
        }
        .tab.active {
            color: #1890ff;
            border-bottom-color: #1890ff;
            font-weight: 500;
        }
        .tab-content {
            display: none;
        }
        .tab-content.active {
            display: block;
        }
        .highlight-box {
            background: #f5f5f5;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            padding: 0;
            overflow-x: auto;
            position: relative;
        }
        .code-with-line-numbers {
            display: flex;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
        }
        .line-numbers {
            background: #e8e8e8;
            color: #666;
            padding: 15px 10px;
            text-align: right;
            user-select: none;
            border-right: 1px solid #d9d9d9;
            min-width: 40px;
        }
        .line-number {
            display: block;
            line-height: 1.5;
            font-size: 14px;
        }
        .code-content {
            padding: 15px;
            white-space: pre-wrap;
            word-wrap: break-word;
            flex: 1;
        }
        /* 基于功能的代码高亮 */
        .keyword { color: #708; font-weight: bold; }
        .string { color: #a31515; }
        .comment { color: #008000; font-style: italic; }
        .number { color: #098658; }
        .operator { color: #0000ff; font-weight: bold; }
        .function { color: #795e26; }
        .variable { color: #000000; }
        .class { color: #267f99; font-weight: bold; }
        .import { color: #001080; }
        .control-structure { color: #af00db; font-weight: bold; }
        .language-info {
            background: #e6f7ff;
            color: #1890ff;
            padding: 8px 12px;
            border-radius: 4px;
            font-size: 14px;
            display: inline-block;
            margin-bottom: 10px;
        }
        .structure-info {
            background: #f6ffed;
            border: 1px solid #b7eb8f;
            border-radius: 6px;
            padding: 15px;
            margin-bottom: 20px;
        }
        .structure-item {
            margin-bottom: 10px;
        }
        .structure-item h4 {
            margin: 0 0 8px 0;
            color: #389e0d;
            font-weight: 600;
        }
        .structure-list {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        .structure-list li {
            padding: 4px 0;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 13px;
            color: #595959;
        }
        .explanation-box {
            background: #fff7e6;
            border: 1px solid #ffd591;
            border-radius: 6px;
            padding: 25px;
            line-height: 1.7;
            color: #d46b08;
            overflow-x: auto;
            text-align: left;
        }
        .explanation-box h1, 
        .explanation-box h2, 
        .explanation-box h3, 
        .explanation-box h4, 
        .explanation-box h5, 
        .explanation-box h6 {
            margin-top: 30px;
            margin-bottom: 15px;
            color: #d46b08;
            font-weight: 600;
            clear: both;
        }
        .explanation-box h1 { font-size: 2em; }
        .explanation-box h2 { 
            font-size: 1.7em; 
            border-bottom: 2px solid #ffd591; 
            padding-bottom: 8px;
            margin-top: 40px;
        }
        .explanation-box h3 { 
            font-size: 1.4em;
            margin-top: 30px;
        }
        .explanation-box h4 { 
            font-size: 1.2em;
            margin-top: 25px;
        }
        .explanation-box h5 { font-size: 1.1em; }
        .explanation-box h6 { font-size: 1em; }
        
        .explanation-box ul,
        .explanation-box ol {
            margin: 15px 0;
            padding-left: 30px;
        }
        .explanation-box ul ul,
        .explanation-box ul ol,
        .explanation-box ol ul,
        .explanation-box ol ol {
            margin: 8px 0;
            padding-left: 25px;
        }
        .explanation-box li {
            margin: 10px 0;
            line-height: 1.6;
            text-align: left;
        }
        .explanation-box pre {
            background: #f0f0f0;
            border-radius: 6px;
            padding: 15px;
            overflow-x: auto;
            margin: 20px 0;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 13px;
            border: 1px solid #e0e0e0;
        }
        .explanation-box code {
            background: #f5f5f5;
            padding: 3px 6px;
            border-radius: 3px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 0.9em;
            border: 1px solid #e8e8e8;
        }
        .explanation-box pre code {
            background: none;
            padding: 0;
            border: none;
        }
        .explanation-box strong {
            font-weight: 700;
            color: #a84700;
        }
        .explanation-box p {
              margin: 15px 0;
              text-align: left;
              line-height: 1.7;
          }
        .loading-overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }
        .loading-spinner {
            background: white;
            padding: 30px;
            border-radius: 8px;
            text-align: center;
        }
        .loading-spinner span {
            display: block;
            margin-top: 10px;
            color: #333;
        }
        @media (max-width: 768px) {
            .container {
                border-radius: 8px;
            }
            .header h1 {
                font-size: 2em;
            }
            .content {
                padding: 20px;
            }
            .result-tabs {
                flex-wrap: wrap;
            }
            .tab {
                padding: 8px 16px;
                font-size: 14px;
            }
        }
        /* 滚动条样式 */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }
        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 4px;
        }
        ::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 4px;
        }
        ::-webkit-scrollbar-thumb:hover {
            background: #a8a8a8;
        }
        /* 加载动画 */
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>智能代码解释器</h1>
        </div>
        <div class="content">
            <div class="input-section">
                <h2>输入代码</h2>
                <textarea id="code-input" placeholder="请在此粘贴或输入代码..."></textarea>
                <button id="analyze-btn">分析代码</button>
            </div>
            
            <div class="result-section" id="result-section">
                <div class="language-info" id="language-info">检测到的语言: <span id="detected-language">Python</span></div>
                
                <div class="result-tabs">
                    <div class="tab active" data-tab="highlight">高亮代码</div>
                    <div class="tab" data-tab="structure">代码结构</div>
                    <div class="tab" data-tab="explanation">代码解释</div>
                </div>
                
                <div class="tab-content active" id="highlight-content">
                    <style id="highlight-css"></style>
                    <div class="highlight-box">
                        <div id="code-with-line-numbers" class="code-with-line-numbers">
                            <div class="line-numbers" id="line-numbers"></div>
                            <div class="code-content" id="code-content"></div>
                        </div>
                    </div>
                </div>
                
                <div class="tab-content" id="structure-content">
                    <div class="structure-info">
                        <div class="structure-item">
                            <h4>类定义</h4>
                            <ul class="structure-list" id="classes-list"></ul>
                        </div>
                        <div class="structure-item">
                            <h4>函数定义</h4>
                            <ul class="structure-list" id="functions-list"></ul>
                        </div>
                        <div class="structure-item">
                            <h4>导入语句</h4>
                            <ul class="structure-list" id="imports-list"></ul>
                        </div>
                        <div class="structure-item">
                            <h4>变量声明</h4>
                            <ul class="structure-list" id="variables-list"></ul>
                        </div>
                        <div class="structure-item">
                            <h4>控制结构</h4>
                            <ul class="structure-list" id="control-structures-list"></ul>
                        </div>
                    </div>
                </div>
                
                <div class="tab-content" id="explanation-content">
                    <div class="explanation-box" id="code-explanation"></div>
                </div>
            </div>
        </div>
    </div>
    
    <div class="loading-overlay" id="loading-overlay">
        <div class="loading-spinner">
            <div style="width: 40px; height: 40px; margin: 0 auto; border: 4px solid #f3f3f3; border-top: 4px solid #1890ff; border-radius: 50%; animation: spin 1s linear infinite;"></div>
            <span>正在分析代码,请稍候...</span>
        </div>
    </div>
    
    <script>
        // 加载动画
        const loadingOverlay = document.getElementById('loading-overlay');
        
        function showLoading() {
            loadingOverlay.style.display = 'flex';
        }
        
        function hideLoading() {
            loadingOverlay.style.display = 'none';
        }
        
        // 选项卡切换
        const tabs = document.querySelectorAll('.tab');
        tabs.forEach(tab => {
            tab.addEventListener('click', () => {
                // 移除所有活动状态
                document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
                
                // 添加当前活动状态
                tab.classList.add('active');
                const tabId = tab.getAttribute('data-tab');
                document.getElementById(`${tabId}-content`).classList.add('active');
            });
        });
        
        // 分析按钮点击事件
        document.getElementById('analyze-btn').addEventListener('click', () => {
            const code = document.getElementById('code-input').value;
            
            if (!code.trim()) {
                alert('请输入代码后再分析');
                return;
            }
            
            showLoading();
            
            // 发送AJAX请求
            fetch('/analyze', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ code })
            })
            .then(response => response.json())
            .then(data => {
                hideLoading();
                
                if (data.error) {
                    alert('错误: ' + data.error);
                    return;
                }
                
                try {
                    // 安全地访问数据,提供默认值
                    const safeData = {
                        language: data.language || '未知',
                        css: data.css || '',
                        code: data.code || '',
                        highlighted_code: data.highlighted_code || '',
                        analysis: data.analysis || {},
                        explanation: data.explanation || '无法生成代码解释。'
                    };
                    
                    // 更新语言信息
                    document.getElementById('detected-language').textContent = safeData.language;
                    
                    // 更新高亮代码和行号
                    document.getElementById('highlight-css').textContent = safeData.css;
                    
                    // 生成行号
                    const codeForLineNumbers = safeData.code || safeData.highlighted_code;
                    const codeLines = codeForLineNumbers ? codeForLineNumbers.split('\n') : [''];
                    const lineNumbersContainer = document.getElementById('line-numbers');
                    lineNumbersContainer.innerHTML = '';
                    
                    codeLines.forEach((line, index) => {
                        const lineNumber = document.createElement('span');
                        lineNumber.className = 'line-number';
                        lineNumber.textContent = index + 1;
                        lineNumbersContainer.appendChild(lineNumber);
                    });
                    
                    // 安全地更新代码内容
                    try {
                        if (safeData.code) {
                            document.getElementById('code-content').innerHTML = highlightCodeByFunctionality(safeData.code, safeData.language);
                        } else {
                            document.getElementById('code-content').innerHTML = safeData.highlighted_code;
                        }
                    } catch (e) {
                        console.error('代码高亮失败:', e);
                        document.getElementById('code-content').textContent = safeData.code || safeData.highlighted_code || '无法显示代码';
                    }
                    
                    // 安全地更新代码结构
                    const analysis = safeData.analysis;
                    updateStructureList('classes-list', Array.isArray(analysis.classes) ? analysis.classes : [], 'name');
                    updateStructureList('functions-list', Array.isArray(analysis.functions) ? analysis.functions : [], 'name');
                    updateStructureList('imports-list', Array.isArray(analysis.imports) ? analysis.imports : [], 'content');
                    updateStructureList('variables-list', Array.isArray(analysis.variables) ? analysis.variables : [], 'name');
                    updateStructureList('control-structures-list', Array.isArray(analysis.control_structures) ? analysis.control_structures : [], 'content');
                    
                    // 安全地更新代码解释
                    try {
                        const formattedExplanation = formatMarkdown(safeData.explanation);
                        document.getElementById('code-explanation').innerHTML = formattedExplanation;
                    } catch (e) {
                        console.error('Markdown格式化失败:', e);
                        document.getElementById('code-explanation').textContent = safeData.explanation;
                    }
                    
                    // 显示结果部分
                    document.getElementById('result-section').style.display = 'block';
                } catch (e) {
                    console.error('处理分析结果时出错:', e);
                    alert('显示结果时出现错误。请检查控制台获取更多信息。');
                }
            })
            .catch(error => {
                hideLoading();
                alert('分析过程中出错: ' + error.message);
            });
        });
        
        // 更新结构列表
        function updateStructureList(elementId, items, displayKey) {
            const listElement = document.getElementById(elementId);
            listElement.innerHTML = '';
            
            if (items.length === 0) {
                listElement.innerHTML = '<li>未检测到</li>';
                return;
            }
            
            // 显示所有项目,不做任何截断
            items.forEach(item => {
                const li = document.createElement('li');
                li.textContent = `第${item.line}行: ${item[displayKey]}`;
                listElement.appendChild(li);
            });
        }
        
        // 基于功能的代码高亮函数 - 安全版本
        function highlightCodeByFunctionality(code, language) {
            try {
                // 安全检查输入
                if (!code || typeof code !== 'string') {
                    return code || '';
                }
                if (!language || typeof language !== 'string') {
                    language = 'plaintext';
                }
                
                // 不同语言的关键字和规则
                const keywords = {
                    'python': ['def', 'class', 'if', 'elif', 'else', 'for', 'while', 'in', 'return', 'import', 'from', 'as', 'try', 'except', 'finally', 'with', 'lambda', 'pass', 'continue', 'break', 'and', 'or', 'not', 'is', 'None', 'True', 'False'],
                    'javascript': ['function', 'var', 'let', 'const', 'if', 'else', 'for', 'while', 'do', 'return', 'import', 'export', 'try', 'catch', 'finally', 'class', 'extends', 'super', 'new', 'this', 'typeof', 'instanceof', 'in', 'continue', 'break', 'switch', 'case', 'default', 'throw', 'async', 'await', 'true', 'false', 'null', 'undefined'],
                    'java': ['public', 'private', 'protected', 'class', 'interface', 'extends', 'implements', 'static', 'final', 'if', 'else', 'for', 'while', 'do', 'return', 'import', 'package', 'try', 'catch', 'finally', 'throw', 'throws', 'new', 'this', 'super', 'void', 'int', 'long', 'double', 'float', 'boolean', 'char', 'byte', 'short', 'true', 'false', 'null', 'continue', 'break', 'switch', 'case', 'default'],
                    'cpp': ['class', 'struct', 'public', 'private', 'protected', 'if', 'else', 'for', 'while', 'do', 'return', '#include', 'using', 'namespace', 'try', 'catch', 'throw', 'new', 'delete', 'this', 'const', 'static', 'virtual', 'override', 'final', 'int', 'long', 'double', 'float', 'bool', 'char', 'void', 'unsigned', 'signed', 'short', 'continue', 'break', 'switch', 'case', 'default', 'true', 'false', 'nullptr']
                };
                
                let highlightedCode = code;
                
                // 转义HTML特殊字符
                highlightedCode = highlightedCode
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;');
                
                // 安全地高亮注释
                try {
                    // Python
                    if (language === 'python') {
                        highlightedCode = highlightedCode.replace(/#.*$/gm, '<span class="comment">$&</span>');
                    }
                    // C-like languages
                    else {
                        // 单行注释
                        highlightedCode = highlightedCode.replace(/\/\/.*$/gm, '<span class="comment">$&</span>');
                        // 多行注释 (安全实现)
                        highlightedCode = highlightedCode.replace(/\/\*[\s\S]*?\*\//g, '<span class="comment">$&</span>');
                    }
                } catch (e) {
                    console.error('注释高亮失败:', e);
                }
                
                // 安全地高亮字符串
                try {
                    highlightedCode = highlightedCode.replace(/"([^"\\]|\\.)*"/g, '<span class="string">$&</span>');
                    highlightedCode = highlightedCode.replace(/'([^'\\]|\\.)*'/g, '<span class="string">$&</span>');
                } catch (e) {
                    console.error('字符串高亮失败:', e);
                }
                
                // 安全地高亮数字
                try {
                    highlightedCode = highlightedCode.replace(/\b\d+(\.\d+)?\b/g, '<span class="number">$&</span>');
                } catch (e) {
                    console.error('数字高亮失败:', e);
                }
                
                // 安全地高亮运算符 - 修复正则表达式
                try {
                    const operators = ['+', '-', '*', '/', '%', '=', '==', '!=', '<', '>', '<=', '>=', '&&', '||', '!', '++', '--', '+=', '-=', '*=', '/=', '%=', '<<', '>>', '>>>', '|', '&', '^', '~'];
                    // 按照运算符长度排序,长的先处理
                    operators.sort((a, b) => b.length - a.length);
                    
                    operators.forEach(op => {
                        try {
                            // 正确转义所有特殊字符
                            const escapedOp = op.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                            // 避免使用单词边界,因为运算符不是单词字符
                            const regex = new RegExp(`(${escapedOp})`, 'g');
                            highlightedCode = highlightedCode.replace(regex, '<span class="operator">$1</span>');
                        } catch (e) {
                            console.error(`运算符高亮失败 (${op}):`, e);
                        }
                    });
                } catch (e) {
                    console.error('运算符高亮总体失败:', e);
                }
                
                // 安全地高亮关键字
                try {
                    const langKeywords = keywords[language.toLowerCase()] || [];
                    langKeywords.forEach(keyword => {
                        try {
                            const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                            highlightedCode = highlightedCode.replace(new RegExp(`\\b${escapedKeyword}\\b`, 'g'), '<span class="keyword">$&</span>');
                        } catch (e) {
                            console.error(`关键字高亮失败 (${keyword}):`, e);
                        }
                    });
                } catch (e) {
                    console.error('关键字高亮总体失败:', e);
                }
                
                // 安全地高亮函数 - 修复捕获组问题
                try {
                    if (language === 'python') {
                        highlightedCode = highlightedCode.replace(/def\s+(\w+)\s*\(/g, 'def <span class="function">$1</span> (');
                    } else if (language === 'javascript' || language === 'java' || language === 'cpp') {
                        highlightedCode = highlightedCode.replace(/function\s+(\w+)\s*\(/g, 'function <span class="function">$1</span> (');
                        // 修复捕获组编号错误
                        highlightedCode = highlightedCode.replace(/\b(\w+)\s+(\w+)\s*\(/g, '$1 <span class="function">$2</span> (');
                    }
                } catch (e) {
                    console.error('函数高亮失败:', e);
                }
                
                // 安全地高亮类
                try {
                    highlightedCode = highlightedCode.replace(/class\s+(\w+)/g, 'class <span class="class">$1</span>');
                } catch (e) {
                    console.error('类高亮失败:', e);
                }
                
                // 安全地高亮导入
                try {
                    if (language === 'python') {
                        highlightedCode = highlightedCode.replace(/import\s+(\w+)/g, '<span class="import">import</span> <span class="variable">$1</span>');
                        highlightedCode = highlightedCode.replace(/from\s+(\w+)\s+import/g, '<span class="import">from</span> <span class="variable">$1</span> <span class="import">import</span>');
                    }
                } catch (e) {
                    console.error('导入高亮失败:', e);
                }
                
                return highlightedCode;
            } catch (e) {
                console.error('代码高亮总体失败:', e);
                // 发生错误时,至少转义HTML特殊字符并返回
                if (code && typeof code === 'string') {
                    return code
                        .replace(/&/g, '&amp;')
                        .replace(/</g, '&lt;')
                        .replace(/>/g, '&gt;')
                        .replace(/"/g, '&quot;')
                        .replace(/'/g, '&#39;');
                }
                return code || '';
            }
        }
        
        // 改进的Markdown格式化
        function formatMarkdown(text) {
            try {
                // 安全检查输入
                if (!text || typeof text !== 'string') {
                    return text || '';
                }
                
                // 替换制表符为空格,防止格式混乱
                text = text.replace(/\t/g, '    ');
                
                // 首先处理代码块 (```)
                let codeBlocks = [];
                let codeBlockCounter = 0;
                text = text.replace(/```[\s\S]*?```/g, (match) => {
                    const codeBlockId = `CODE_BLOCK_PLACEHOLDER_${codeBlockCounter++}`;
                    codeBlocks.push(match);
                    return codeBlockId;
                });
                
                // 特殊处理行号标记,确保它们在代码块外正确显示
                text = text.replace(/\*\*\[行号 (\d+)\]\*\*:\s*`([^`]+)`/g, '<p><strong>[行号 $1]</strong>: <code>$2</code></p>');
                
                // 处理行内代码和粗体
                text = text.replace(/`(.*?)`/g, '<code>$1</code>');
                text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
                
                // 处理标题
                text = text.replace(/^# (.*?)$/gm, '<h1>$1</h1>');
                text = text.replace(/^## (.*?)$/gm, '<h2>$1</h2>');
                text = text.replace(/^### (.*?)$/gm, '<h3>$1</h3>');
                text = text.replace(/^#### (.*?)$/gm, '<h4>$1</h4>');
                text = text.replace(/^##### (.*?)$/gm, '<h5>$1</h5>');
                text = text.replace(/^###### (.*?)$/gm, '<h6>$1</h6>');
                
                // 拆分段落
                const paragraphs = text.split(/\n\n+/);
                let result = '';
                
                // 处理每个段落
                paragraphs.forEach(paragraph => {
                    paragraph = paragraph.trim();
                    if (!paragraph) return;
                    
                    // 检查是否已经被处理为标题或行号标记
                    if (paragraph.match(/^<h[1-6]>/) && paragraph.match(/<\/h[1-6]>$/)) {
                        result += paragraph + '\n';
                        return;
                    }
                    if (paragraph.match(/^<p><strong>\[行号/)) {
                        result += paragraph;
                        return;
                    }
                    
                    // 检查是否是列表
                    if (paragraph.match(/^(\s*[-*]|\s*\d+\.) /m)) {
                        // 处理列表
                        let inList = false;
                        let currentListLevel = 0;
                        let listContent = '';
                        
                        const listLines = paragraph.split('\n');
                        listLines.forEach(line => {
                            line = line.trim();
                            if (!line) return;
                            
                            // 计算列表缩进级别
                            let level = 0;
                            const indentMatch = line.match(/^(\s*)/)[0];
                            level = Math.floor(indentMatch.length / 4);
                            
                            // 提取列表标记和内容
                            const listMatch = line.match(/^(\s*[-*]|\s*\d+\.)\s+(.*)$/);
                            if (listMatch) {
                                const content = listMatch[2];
                                
                                // 处理列表嵌套
                                while (currentListLevel > level) {
                                    listContent += '</li></ul>';
                                    currentListLevel--;
                                }
                                while (currentListLevel < level) {
                                    listContent += '<ul>';
                                    currentListLevel++;
                                }
                                if (!inList) {
                                    listContent += '<ul>';
                                    currentListLevel++;
                                    inList = true;
                                } else if (currentListLevel === level) {
                                    // 同一级别的下一个列表项
                                    listContent += '</li>';
                                }
                                listContent += `<li>${content}`;
                            }
                        });
                        
                        // 关闭所有未闭合的列表标签
                        while (currentListLevel > 0) {
                            listContent += '</li></ul>';
                            currentListLevel--;
                        }
                        
                        result += listContent;
                    } else {
                        // 普通段落
                        result += `<p>${paragraph}</p>`;
                    }
                });
                
                // 恢复代码块
                codeBlocks.forEach((codeBlock, index) => {
                    const codeContent = codeBlock.slice(codeBlock.indexOf('\n') + 1, codeBlock.lastIndexOf('\n'));
                    result = result.replace(`CODE_BLOCK_PLACEHOLDER_${index}`, `<pre><code>${codeContent}</code></pre>`);
                });
                
                return result;
            } catch (e) {
                console.error('Markdown格式化错误:', e);
                // 返回原始文本而不进行格式化
                return text || '';
            }
        }
    </script>
</body>
</html>
# Ollama配置
# 本地Ollama可执行文件路径
OLLAMA_PATH=F:\\OllamaAI\\ollama.exe
# 使用的模型名称
OLLAMA_MODEL=deepseek-r1:14b
# Ollama配置示例
# 本地Ollama可执行文件路径
OLLAMA_PATH=F:\\OllamaAI\\ollama.exe
# 使用的模型名称
OLLAMA_MODEL=deepseek-r1:14b
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request, jsonify
import os
import re
import subprocess
import json
from pygments import highlight
from pygments.lexers import guess_lexer, get_lexer_by_name
from pygments.formatters import HtmlFormatter
import langdetect
from dotenv import load_dotenv
import traceback
import time
import threading
from concurrent.futures import ThreadPoolExecutor

# 加载环境变量
load_dotenv()

app = Flask(__name__)

# Ollama配置 - 修复路径格式问题
OLLAMA_PATH = os.getenv('OLLAMA_PATH', 'F:\\OllamaAI\\ollama.exe')
# 备选路径列表,增加找到Ollama的可能性
OLLAMA_PATHS = [
    OLLAMA_PATH,
    'F:/OllamaAI/ollama.exe',
    'C:/Program Files/Ollama/ollama.exe',
    'C:/Program Files (x86)/Ollama/ollama.exe',
    'ollama.exe'  # 尝试在PATH中查找
]

# 确保使用存在的Ollama路径
for path in OLLAMA_PATHS:
    if os.path.exists(path):
        OLLAMA_PATH = path
        break

OLLAMA_MODEL = os.getenv('OLLAMA_MODEL', 'deepseek-r1:14b')

# 语言映射字典,用于将技术语言名称映射为常用名称
LANGUAGE_MAPPING = {
    'python': 'Python',
    'javascript': 'JavaScript',
    'java': 'Java',
    'c++': 'C++',
    'c#': 'C#',
    'ruby': 'Ruby',
    'go': 'Go',
    'rust': 'Rust',
    'php': 'PHP',
    'swift': 'Swift',
    'kotlin': 'Kotlin',
    'typescript': 'TypeScript',
    'html': 'HTML',
    'css': 'CSS',
    'sql': 'SQL',
    'shell': 'Shell脚本',
    'bash': 'Bash脚本',
    'powershell': 'PowerShell',
    'plaintext': '纯文本'
}

# 使用线程池提高性能
executor = ThreadPoolExecutor(max_workers=8)

def analyze_code_structure(code):
    """完整分析代码结构,提取所有关键信息"""
    result = {
        'imports': [],
        'classes': [],
        'functions': [],
        'variables': [],
        'control_structures': []
    }
    
    lines = code.split('\n')
    
    # 分析所有代码行,不限制行数
    for i, line in enumerate(lines, 1):
        line_stripped = line.strip()
        
        # 跳过空行和注释,提高处理速度
        if not line_stripped or line_stripped.startswith('#') or line_stripped.startswith('//'):
            continue
        
        # 使用字符串方法提高性能
        if line_stripped.startswith('import ') or line_stripped.startswith('from '):
            # 提取导入信息
            result['imports'].append({
                'line': i,
                'content': line_stripped
            })
        elif line_stripped.startswith('class '):
            # 提取类名
            class_name = line_stripped.split('class ')[1].split('(')[0].split(':')[0].strip()
            result['classes'].append({
                'line': i,
                'name': class_name,
                'content': line_stripped
            })
        elif line_stripped.startswith('def ') or line_stripped.startswith('function '):
            # 提取函数名
            func_parts = line_stripped.split('(')[0]
            if func_parts.startswith('def '):
                func_name = func_parts.split('def ')[1].strip()
            else:
                func_name = func_parts.split('function ')[1].strip()
            result['functions'].append({
                'line': i,
                'name': func_name,
                'content': line_stripped
            })
        elif line_stripped.startswith('if ') or line_stripped.startswith('for ') or \
             line_stripped.startswith('while ') or line_stripped.startswith('switch ') or \
             line_stripped.startswith('try') or line_stripped.startswith('catch') or \
             line_stripped.startswith('finally') or line_stripped.startswith('else'):
            # 识别控制结构
            result['control_structures'].append({
                'line': i,
                'content': line_stripped
            })
        elif '=' in line_stripped and not any(op in line_stripped for op in ['==', '!=', '<=', '>=']):
            # 识别变量赋值
            var_name = line_stripped.split('=')[0].strip().split(' ')[-1]
            result['variables'].append({
                'line': i,
                'name': var_name,
                'content': line_stripped
            })
    
    return result

# 详细代码解释函数 - 本地版本
def detailed_local_explain(code, language, analysis):
    """生成详细的代码解释,保留所有代码结构信息和完整分析"""
    explanation = f"# {language}代码详细分析\n\n"
    
    # 完整的整体结构分析
    explanation += "## 代码结构概览\n\n"
    explanation += f"- 代码行数: {len(code.split('\n'))}\n"
    
    if analysis.get('classes'):
        explanation += f"- 类数量: {len(analysis['classes'])}\n"
        for cls in analysis['classes']:
            explanation += f"  - {cls['name']} (第{cls['line']}行)\n"
    
    if analysis.get('functions'):
        explanation += f"- 函数数量: {len(analysis['functions'])}\n"
        for func in analysis['functions']:
            explanation += f"  - {func['name']} (第{func['line']}行)\n"
    
    if analysis.get('imports'):
        explanation += f"- 导入语句: {len(analysis['imports'])}个\n"
    if analysis.get('variables'):
        explanation += f"- 变量声明: {len(analysis['variables'])}个\n"
    if analysis.get('control_structures'):
        explanation += f"- 控制结构: {len(analysis['control_structures'])}个\n"
    
    # 详细分析类定义
    if analysis.get('classes'):
        explanation += "\n## 类定义详情\n\n"
        for cls in analysis['classes']:
            explanation += f"- **第{cls['line']}行**: `{cls['content']}`\n"
            explanation += f"  - 类名: {cls['name']}\n"
            
            # 提取继承信息
            if '(' in cls['content'] and ')' in cls['content']:
                parent_class = cls['content'].split('(')[1].split(')')[0].strip()
                explanation += f"  - 继承关系: 继承自 {parent_class}\n"
            else:
                explanation += "  - 继承关系: 无显式继承\n"
            
            explanation += "  - 作用: 定义了一个新的数据类型,封装相关数据和方法\n"
    
    # 详细分析函数定义
    if analysis.get('functions'):
        explanation += "\n## 函数定义详情\n\n"
        for func in analysis['functions']:
            explanation += f"- **第{func['line']}行**: `{func['content']}`\n"
            explanation += f"  - 函数名: {func['name']}\n"
            
            # 提取参数信息
            if '(' in func['content'] and ')' in func['content']:
                params_str = func['content'].split('(')[1].split(')')[0].strip()
                if params_str:
                    params = [p.strip() for p in params_str.split(',')]
                    explanation += f"  - 参数: {', '.join(params)}\n"
                else:
                    explanation += "  - 参数: 无参数\n"
            
            explanation += "  - 作用: 封装可重用的代码逻辑,执行特定任务\n"
    
    # 完整的代码逐行分析
    explanation += "\n## 代码逐行分析\n\n"
    explanation += "以下是代码的详细逐行分析:\n\n"
    
    lines = code.split('\n')
    # 分析所有代码行,不限制行数
    for i, line in enumerate(lines, 1):
        original_line = line
        line = line.strip()
        
        if not line:
            explanation += f"**[行{i}]**: `[空行]`\n"
        elif line.startswith('#') or line.startswith('//'):
            explanation += f"**[行{i}]**: `{original_line}`\n"
            explanation += "  - 注释行:提供代码解释,不执行\n"
        else:
            explanation += f"**[行{i}]**: `{original_line}`\n"
            
            # 详细分析各种代码类型
            if line.startswith('import ') or line.startswith('from '):
                explanation += "  - 导入语句:引入外部模块或库\n"
                
                # 分析导入类型
                if 'as' in line:
                    parts = line.split('as')
                    imported = parts[0].strip()
                    alias = parts[1].strip()
                    explanation += f"  - 导入内容: {imported.replace('import', '').strip()},别名: {alias}\n"
                elif 'from' in line:
                    parts = line.split('import')
                    module = parts[0].replace('from', '').strip()
                    components = parts[1].strip()
                    explanation += f"  - 从 {module} 导入: {components}\n"
            elif line.startswith('class '):
                explanation += "  - 类定义:创建一个新的类\n"
            elif line.startswith('def ') or line.startswith('function '):
                explanation += "  - 函数定义:创建一个可重用的代码块\n"
            elif '=' in line and not any(op in line for op in ['==', '!=', '<=', '>=']):
                explanation += "  - 变量赋值:给变量分配值\n"
                
                # 分析赋值运算符
                if '+=' in line:
                    explanation += "  - '+=' 加法赋值运算符:将右侧值加到左侧变量并赋值\n"
                elif '-=' in line:
                    explanation += "  - '-=' 减法赋值运算符:从左侧变量减去右侧值并赋值\n"
                elif '*=' in line:
                    explanation += "  - '*=' 乘法赋值运算符:将左侧变量乘以右侧值并赋值\n"
                elif '/=' in line:
                    explanation += "  - '/=' 除法赋值运算符:将左侧变量除以右侧值并赋值\n"
                else:
                    var_name = line.split('=')[0].strip()
                    value_part = line.split('=')[1].strip() if '=' in line else ''
                    explanation += f"  - 变量名: {var_name}\n"
                    if value_part:
                        explanation += f"  - 赋值内容: {value_part}\n"
            elif line.startswith('if ') or line.startswith('else ') or line.startswith('elif '):
                explanation += "  - 条件语句:根据条件执行不同代码\n"
                if 'if' in line:
                    condition = line.split('if')[1].split(':')[0].strip()
                    explanation += f"  - 条件表达式: {condition}\n"
            elif line.startswith('for ') or line.startswith('while '):
                explanation += "  - 循环语句:重复执行代码块\n"
                if 'for' in line:
                    loop_info = line.split('for')[1].split(':')[0].strip()
                    explanation += f"  - 循环条件: {loop_info}\n"
                elif 'while' in line:
                    loop_condition = line.split('while')[1].split(':')[0].strip()
                    explanation += f"  - 循环条件: {loop_condition}\n"
            elif line.startswith('return '):
                explanation += "  - 返回语句:从函数返回值\n"
                return_value = line.split('return')[1].strip() if 'return' in line else ''
                if return_value:
                    explanation += f"  - 返回值: {return_value}\n"
            elif line.startswith('print(') or line.startswith('console.log('):
                explanation += "  - 输出语句:打印信息到控制台\n"
            elif line.startswith('try:') or line.startswith('catch') or line.startswith('except') or line.startswith('finally:'):
                explanation += "  - 异常处理:捕获和处理运行时错误\n"
            elif line.startswith('break') or line.startswith('continue'):
                explanation += "  - 流程控制:中断或继续循环\n"
            elif line.startswith('def '):
                explanation += "  - 函数定义:创建一个新函数\n"
                func_name = line.split('def ')[1].split('(')[0].strip()
                explanation += f"  - 函数名: {func_name}\n"
            
            # 分析运算符
            operators = {
                '+': '加法运算符',
                '-': '减法运算符',
                '*': '乘法运算符',
                '/': '除法运算符',
                '%': '取模运算符',
                '**': '幂运算符',
                '//': '整除运算符',
                '==': '等于运算符',
                '!=': '不等运算符',
                '<': '小于运算符',
                '>': '大于运算符',
                '<=': '小于等于运算符',
                '>=': '大于等于运算符',
                'and': '逻辑与运算符',
                'or': '逻辑或运算符',
                'not': '逻辑非运算符'
            }
            
            # 检查是否包含运算符并解释
            for op, desc in operators.items():
                # 避免将复合运算符中的部分单独识别
                if op in line and not any(full_op in line for full_op in [op+'=', op+op, op+' ']):
                    explanation += f"  - {op} {desc}\n"
                    
                    # 提供更详细的运算符说明
                    op_details = {
                        '+': '用于数值相加或字符串拼接',
                        '-': '用于数值相减',
                        '*': '用于数值相乘',
                        '/': '用于浮点除法,得到浮点数结果',
                        '%': '计算除法的余数',
                        '**': '计算幂次方,如 2**3 = 8',
                        '//': '整除运算符,结果取整',
                        '==': '比较两个值是否相等',
                        '!=': '比较两个值是否不相等',
                        '<': '比较左侧值是否小于右侧值',
                        '>': '比较左侧值是否大于右侧值',
                        '<=': '比较左侧值是否小于或等于右侧值',
                        '>=': '比较左侧值是否大于或等于右侧值',
                        'and': '逻辑与,两个条件都为真时结果为真',
                        'or': '逻辑或,至少一个条件为真时结果为真',
                        'not': '逻辑非,取反布尔值'}
                    if op in op_details:
                        explanation += f"  - 作用: {op_details[op]}\n"
                    break

# 使用Ollama进行详细代码解释
def explain_with_ollama(code, language):
    """使用Ollama本地大模型进行代码解释,提高GPU利用率"""
    try:
        # 首先检查Ollama是否可用
        if not os.path.exists(OLLAMA_PATH):
            print(f"Ollama不可用,路径不存在: {OLLAMA_PATH}")
            return None
            
        # 构建详细的提示词,确保模型生成高质量的解释
        prompt = f"""
请详细分析以下{language}代码,解释每一行的功能、作用以及使用的语法。
特别注意解释运算符的作用和各种语法结构的意义。
请按行号依次解释每一行代码,不要跳过任何一行。
代码:
```
{code}
```
请以Markdown格式输出,包括:
1. 代码整体结构概览
2. 逐行详细解释,包含行号
3. 运算符和特殊语法的详细说明
4. 代码的主要功能和工作原理
"""

        # 使用优化的命令行参数调用Ollama
        cmd = [OLLAMA_PATH, "run", OLLAMA_MODEL, "--options", "num_gpu=1", "--options", "num_thread=16"]
        
        # 启动子进程执行Ollama命令
        process = subprocess.Popen(
            cmd,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            encoding='utf-8',
            creationflags=subprocess.CREATE_NEW_CONSOLE if os.name == 'nt' else 0
        )

        # 写入提示词
        stdout, stderr = process.communicate(prompt, timeout=45)  # 增加超时时间

        # 检查执行结果
        if process.returncode != 0:
            print(f"Ollama执行错误: {stderr}")
            return None

        # 处理输出,提取实际回答
        cleaned_output = stdout.strip()
        
        # 如果输出为空或者过于简短,返回None
        if not cleaned_output or len(cleaned_output) < 50:
            return None
            
        return cleaned_output

    except Exception as e:
        print(f"Ollama调用出错: {str(e)}")
        return None

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/analyze', methods=['POST'])
def analyze():
    try:
        # 确保请求有JSON数据
        if not request.is_json:
            return jsonify({'error': '无效的请求格式,请提供JSON数据'}), 400
        
        data = request.get_json()
        code = data.get('code', '').strip()
        
        if not code:
            return jsonify({
                'error': '请输入代码'
            })
        
        # 高效的语言检测
        try:
            # 优化的语言检测
            if 'import' in code and 'def' in code:
                language = 'python'
            elif 'function' in code and ('var' in code or 'let' in code or 'const' in code):
                language = 'javascript'
            elif '<html>' in code.lower() or '<body>' in code.lower():
                language = 'html'
            elif 'select' in code.lower() and 'from' in code.lower():
                language = 'sql'
            elif '#include' in code:
                language = 'c++'
            else:
                try:
                    lexer = guess_lexer(code)
                    language = lexer.name.lower()
                except:
                    language = 'plaintext'
            
            display_language = LANGUAGE_MAPPING.get(language, language.title())
        except:
            language = 'plaintext'
            display_language = '纯文本'
        
        # 语法高亮
        try:
            lexer = get_lexer_by_name(language)
            formatter = HtmlFormatter(nowrap=True, cssclass='highlight', noclasses=True)
            highlighted_code = highlight(code, lexer, formatter)
        except:
            highlighted_code = code.replace('<', '&lt;').replace('>', '&gt;')
        
        # 并行执行代码结构分析
        future = executor.submit(analyze_code_structure, code)
        analysis = future.result()
        
        # 生成CSS样式
        formatter = HtmlFormatter(noclasses=True)
        css = formatter.get_style_defs('.highlight')
        
        # 尝试使用Ollama进行解释,同时准备本地解释作为备选
        # 使用线程池并行执行Ollama调用,避免阻塞主线程
        future_ollama = executor.submit(explain_with_ollama, code, display_language)
        ollama_explanation = future_ollama.result()
        
        # 如果Ollama调用成功并返回有效结果,使用Ollama的解释
        if ollama_explanation:
            explanation = ollama_explanation
        else:
            # 否则使用本地详细解释
            print("Ollama调用失败或结果不完整,使用本地解释")
            # 并行执行本地解释生成
            future_local = executor.submit(detailed_local_explain, code, display_language, analysis)
            explanation = future_local.result()
        
        # 返回完整数据,不省略任何内容
        response_data = {
            'language': display_language,
            'highlighted_code': highlighted_code,
            'css': css,
            'analysis': analysis,
            'explanation': explanation,
            'code': code,
            'explain_method': 'ollama' if ollama_explanation else 'local'
        }
        
        return jsonify(response_data)
        
    except Exception as e:
        print(f"处理失败: {e}")
        traceback.print_exc()  # 打印详细异常堆栈
        
        # 异常处理,确保返回有意义的错误信息
        return jsonify({
            'error': f'处理失败: {str(e)}',
            'language': '未知',
            'highlighted_code': '',
            'css': '',
            'analysis': {
                'classes': [],
                'functions': [],
                'imports': [],
                'variables': [],
                'control_structures': []
            },
            'explanation': f'处理失败: {str(e)}',
            'code': code if 'code' in locals() else ''
        })

if __name__ == '__main__':
    # 大幅优化GPU性能的环境变量设置
    # 核心GPU设置
    os.environ['OLLAMA_GPU'] = '1.0'  # 100% GPU使用率
    
    # 内存和缓存优化
    os.environ['OLLAMA_MAX_LOADED_MODELS'] = '1'
    os.environ['OLLAMA_KEEP_ALIVE'] = '30m'  # 延长模型保持时间
    
    # 并行处理优化 - 显著增加并行度
    os.environ['OLLAMA_NUM_PARALLEL'] = '16'  # 增加到16个并行处理
    os.environ['OLLAMA_BATCH_SIZE'] = '256'  # 增加批处理大小到256
    os.environ['OLLAMA_THREADS'] = '16'  # 增加线程数到16
    
    # CUDA和TensorRT优化
    os.environ['OLLAMA_TENSORRT'] = '1'  # 启用TensorRT加速
    os.environ['OLLAMA_CUDA_DMMV_X'] = '32'  # 优化CUDA矩阵乘法
    os.environ['OLLAMA_CUDA_DMMV_Y'] = '1'
    
    # 新增更多GPU相关优化环境变量
    os.environ['OLLAMA_CUDA_BLOCK_SIZE'] = '128'  # 设置CUDA块大小
    os.environ['OLLAMA_CUDA_KV_QM_K'] = '16'  # 优化KV缓存量化矩阵
    os.environ['OLLAMA_CUDA_KV_QM_V'] = '16'
    os.environ['OLLAMA_CUDA_MMV_X'] = '16'  # 优化矩阵乘法向量
    os.environ['OLLAMA_CUDA_MMV_Y'] = '1'
    os.environ['OLLAMA_GPU_LAYERS'] = '20'  # 设置GPU处理的层数
    os.environ['OLLAMA_CUDA_FORCE_MMQ'] = '1'  # 强制使用混合精度量化
    os.environ['OLLAMA_CUDA_PEER_ACCESS'] = '1'  # 启用GPU间对等访问
    os.environ['OLLAMA_CUDA_MMQ_ENABLED'] = '1'  # 启用MMQ量化
    
    # 设置CUDA优化环境变量
    os.environ['CUDA_VISIBLE_DEVICES'] = '0'  # 确保使用GPU 0
    os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID'  # 按PCI总线ID排序设备
    os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8'  # 优化cuBLAS性能
    os.environ['CUDA_CACHE_DISABLE'] = '0'  # 启用CUDA缓存
    os.environ['CUDA_MODULE_LOADING'] = 'LAZY'  # 使用延迟加载以提高性能
    os.environ['CUDA_LAUNCH_BLOCKING'] = '0'  # 禁用同步启动以提高性能
    os.environ['CUDA_FORCE_PTX_JIT'] = '1'  # 强制PTX JIT编译以获得最佳性能
    
    # 确保templates文件夹存在
    if not os.path.exists('templates'):
        os.makedirs('templates')
        print("请确保templates目录下有index.html文件")
    
    # 运行Flask应用
    app.run(debug=True, host='0.0.0.0', port=5555)
flask==2.3.2
pygments==2.15.1
langdetect==1.0.9
python-dotenv==1.0.0

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇