基于pycharm实现html文件的快速实现问题讨论

仍然无法实现编译的功能。

1.目录结构

2.1

static-pygments.css

代码:

复制代码
/* Pygments 代码高亮样式 */
.highlight {
    background: #f8f8f8;
    border-radius: 4px;
    padding: 10px;
    overflow: auto;
}

.highlight pre {
    margin: 0;
    padding: 0;
    background: transparent;
}

.highlight .lineno {
    color: #aaa;
    padding-right: 10px;
    border-right: 1px solid #ddd;
    margin-right: 10px;
}

/* 语法高亮颜色 */
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */

2.2 static-style.css

复制代码
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.6;
    color: #333;
    background-color: #f5f5f5;
    padding: 20px;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    background: white;
    padding: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

header {
    margin-bottom: 30px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #eee;
    padding-bottom: 15px;
}

header h1 {
    color: #2c3e50;
}

.btn {
    display: inline-block;
    padding: 8px 16px;
    background: #ddd;
    color: #333;
    text-decoration: none;
    border-radius: 4px;
    border: none;
    cursor: pointer;
    font-size: 14px;
    transition: all 0.3s;
}

.btn-primary {
    background: #3498db;
    color: white;
}

.btn-secondary {
    background: #95a5a6;
    color: white;
}

.btn-outline {
    background: transparent;
    border: 1px solid #3498db;
    color: #3498db;
}

.btn:hover {
    opacity: 0.9;
    transform: translateY(-2px);
}

.form-group {
    margin-bottom: 20px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"], input[type="password"], select, textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-family: inherit;
    font-size: 14px;
}

textarea {
    resize: vertical;
    font-family: monospace;
}

.form-actions {
    margin-top: 20px;
}

.snippet-info {
    background: #f8f9fa;
    padding: 15px;
    border-radius: 4px;
    margin-bottom: 20px;
}

.snippet-info p {
    margin-bottom: 10px;
}

.snippet-info input {
    background: white;
    padding: 5px;
    width: 100%;
}

.code-container {
    border: 1px solid #ddd;
    border-radius: 4px;
    overflow: hidden;
}

pre {
    margin: 0;
    padding: 15px;
    background: #f8f9fa;
    overflow-x: auto;
}

code {
    font-family: 'Courier New', Courier, monospace;
}

.features {
    margin-top: 30px;
}

.features ul {
    list-style-type: none;
    padding-left: 0;
}

.features li {
    padding: 5px 0;
    position: relative;
    padding-left: 20px;
}

.features li:before {
    content: "✓";
    position: absolute;
    left: 0;
    color: #27ae60;
}

footer {
    margin-top: 30px;
    text-align: center;
    color: #7f8c8d;
    font-size: 14px;
}

.actions {
    display: flex;
    gap: 10px;
}

/* 创建页面布局 */
.create-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 30px;
}

.input-section, .preview-section {
    display: flex;
    flex-direction: column;
}

.preview-section h3 {
    margin-bottom: 15px;
    color: #2c3e50;
}

.preview-container {
    flex: 1;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 15px;
    background: #f8f9fa;
    min-height: 400px;
    overflow: auto;
}

.preview-placeholder {
    color: #7f8c8d;
    font-style: italic;
    text-align: center;
    margin-top: 50%;
}

.preview-error {
    color: #e74c3c;
    text-align: center;
}

/* 密码页面 */
.password-form {
    max-width: 400px;
    margin: 0 auto;
    text-align: center;
}

.password-form h2 {
    margin-bottom: 15px;
    color: #2c3e50;
}

.password-form p {
    margin-bottom: 30px;
    color: #7f8c8d;
}

.error-message {
    color: #e74c3c;
    margin-bottom: 15px;
    padding: 10px;
    background: #ffeaea;
    border-radius: 4px;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .create-container {
        grid-template-columns: 1fr;
    }

    header {
        flex-direction: column;
        align-items: flex-start;
        gap: 15px;
    }

    .actions {
        flex-wrap: wrap;
    }
}

3.1 templates-create.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>创建代码片段 - 代码分享</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <link rel="stylesheet" href="{{ url_for('static', filename='pygments.css') }}">
    <style>
        .preview-tabs {
            display: flex;
            margin-bottom: 10px;
            border-bottom: 1px solid #ddd;
        }
        .preview-tab {
            padding: 8px 16px;
            cursor: pointer;
            border: 1px solid transparent;
            margin-right: 5px;
            border-radius: 4px 4px 0 0;
        }
        .preview-tab.active {
            background: #3498db;
            color: white;
            border-color: #3498db;
        }
        .preview-content {
            display: none;
            min-height: 300px;
        }
        .preview-content.active {
            display: block;
        }
        .execution-result, .execution-error {
            padding: 15px;
            border-radius: 4px;
            margin: 10px 0;
        }
        .execution-result {
            background: #d4edda;
            border: 1px solid #c3e6cb;
            color: #155724;
        }
        .execution-error {
            background: #f8d7da;
            border: 1px solid #f5c6cb;
            color: #721c24;
        }
        .html-preview-frame {
            width: 100%;
            height: 400px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        .css-preview-target {
            padding: 20px;
            border: 2px dashed #ddd;
            background: white;
            min-height: 200px;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>创建代码片段</h1>
            <a href="{{ url_for('index') }}" class="btn btn-secondary">返回首页</a>
        </header>

        <main>
            <div class="create-container">
                <div class="input-section">
                    <form method="POST" class="snippet-form" id="snippetForm">
                        <div class="form-group">
                            <label for="title">标题:</label>
                            <input type="text" id="title" name="title" placeholder="输入代码片段标题">
                        </div>

                        <div class="form-group">
                            <label for="language">编程语言:</label>
                            <select id="language" name="language">
                                <option value="auto">自动检测</option>
                                <option value="python">Python</option>
                                <option value="javascript">JavaScript</option>
                                <option value="html">HTML</option>
                                <option value="css">CSS</option>
                                <option value="java">Java</option>
                                <option value="cpp">C++</option>
                                <option value="php">PHP</option>
                                <option value="sql">SQL</option>
                                <option value="bash">Bash</option>
                                <option value="text">纯文本</option>
                            </select>
                        </div>

                        <div class="form-group">
                            <label for="password">密码保护 (可选):</label>
                            <input type="password" id="password" name="password" placeholder="设置查看密码">
                        </div>

                        <div class="form-group">
                            <label for="code">代码:</label>
                            <textarea id="code" name="code" rows="15" placeholder="粘贴你的代码到这里..." required></textarea>
                        </div>

                        <div class="form-actions">
                            <button type="submit" class="btn btn-primary">创建代码片段</button>
                        </div>
                    </form>
                </div>

                <div class="preview-section">
                    <h3>实时预览</h3>

                    <!-- 预览选项卡 -->
                    <div class="preview-tabs">
                        <div class="preview-tab active" data-tab="highlight">代码高亮</div>
                        <div class="preview-tab" data-tab="execution">执行效果</div>
                    </div>

                    <!-- 高亮预览 -->
                    <div id="highlight-preview" class="preview-content active">
                        <div id="highlight-result">
                            <p class="preview-placeholder">输入代码后,这里会显示语法高亮...</p>
                        </div>
                    </div>

                    <!-- 执行预览 -->
                    <div id="execution-preview" class="preview-content">
                        <div id="execution-result">
                            <p class="preview-placeholder">选择执行效果标签查看代码运行结果...</p>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const codeTextarea = document.getElementById('code');
            const languageSelect = document.getElementById('language');
            const highlightResult = document.getElementById('highlight-result');
            const executionResult = document.getElementById('execution-result');
            const previewTabs = document.querySelectorAll('.preview-tab');
            const previewContents = document.querySelectorAll('.preview-content');

            let previewTimeout;

            // 选项卡切换
            previewTabs.forEach(tab => {
                tab.addEventListener('click', function() {
                    const tabName = this.getAttribute('data-tab');

                    // 更新活跃选项卡
                    previewTabs.forEach(t => t.classList.remove('active'));
                    this.classList.add('active');

                    // 更新内容显示
                    previewContents.forEach(content => content.classList.remove('active'));
                    document.getElementById(`${tabName}-preview`).classList.add('active');

                    // 如果是执行效果标签,更新预览
                    if (tabName === 'execution') {
                        updateExecutionPreview();
                    }
                });
            });

            // 更新代码高亮预览
            function updateHighlightPreview() {
                const code = codeTextarea.value;
                const language = languageSelect.value;

                if (!code.trim()) {
                    highlightResult.innerHTML = '<p class="preview-placeholder">输入代码后,这里会显示语法高亮...</p>';
                    return;
                }

                fetch('/preview', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        code: code,
                        language: language
                    })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        highlightResult.innerHTML = data.html;
                    } else {
                        highlightResult.innerHTML = '<p class="preview-error">高亮生成失败</p>';
                    }
                })
                .catch(error => {
                    console.error('高亮预览错误:', error);
                    highlightResult.innerHTML = '<p class="preview-error">高亮生成失败</p>';
                });
            }

            // 更新执行效果预览
            function updateExecutionPreview() {
                const code = codeTextarea.value;
                const language = languageSelect.value;

                if (!code.trim()) {
                    executionResult.innerHTML = '<p class="preview-placeholder">输入代码后,这里会显示执行效果...</p>';
                    return;
                }

                // 根据语言类型执行不同的预览
                if (language === 'html' || (language === 'auto' && code.trim().startsWith('<'))) {
                    previewHTML(code);
                } else if (language === 'css' || (language === 'auto' && code.includes('{'))) {
                    previewCSS(code);
                } else if (language === 'javascript' || (language === 'auto' && (code.includes('function') || code.includes('=>')))) {
                    previewJavaScript(code);
                } else {
                    executionResult.innerHTML = '<p class="preview-placeholder">此语言类型不支持执行预览</p>';
                }
            }

            // HTML预览
            function previewHTML(htmlCode) {
                // 创建iframe来安全地预览HTML
                const iframe = document.createElement('iframe');
                iframe.className = 'html-preview-frame';
                iframe.srcdoc = htmlCode;

                executionResult.innerHTML = '<h4>HTML渲染效果:</h4>';
                executionResult.appendChild(iframe);
            }

            // CSS预览
            function previewCSS(cssCode) {
                executionResult.innerHTML = `
                    <h4>CSS样式效果:</h4>
                    <div class="css-preview-target" id="cssPreviewTarget">
                        这是一个样式预览区域
                    </div>
                    <div style="margin-top: 10px;">
                        <strong>应用的CSS:</strong>
                        <pre>${cssCode}</pre>
                    </div>
                `;

                // 应用CSS样式
                try {
                    const style = document.createElement('style');
                    style.textContent = cssCode;
                    document.head.appendChild(style);

                    // 清理之前的样式
                    setTimeout(() => {
                        if (document.head.contains(style)) {
                            document.head.removeChild(style);
                        }
                    }, 100);
                } catch (error) {
                    console.error('CSS应用错误:', error);
                }
            }

            // JavaScript预览
            function previewJavaScript(jsCode) {
                executionResult.innerHTML = '<h4>JavaScript执行结果:</h4>';

                try {
                    // 在安全环境中执行JavaScript
                    const result = Function(`"use strict"; ${jsCode}`)();

                    let output = '';
                    if (result !== undefined) {
                        output = typeof result === 'object' ?
                            JSON.stringify(result, null, 2) :
                            String(result);
                    } else {
                        output = '代码已执行,但没有返回值';
                    }

                    executionResult.innerHTML += `
                        <div class="execution-result">
                            <strong>执行成功!</strong>
                            <pre>${output}</pre>
                        </div>
                    `;
                } catch (error) {
                    executionResult.innerHTML += `
                        <div class="execution-error">
                            <strong>执行错误:</strong>
                            <pre>${error.message}</pre>
                        </div>
                    `;
                }
            }

            // 防抖更新预览
            function debouncedUpdatePreview() {
                clearTimeout(previewTimeout);
                previewTimeout = setTimeout(() => {
                    updateHighlightPreview();

                    // 如果执行效果标签是活跃的,也更新它
                    if (document.querySelector('.preview-tab[data-tab="execution"]').classList.contains('active')) {
                        updateExecutionPreview();
                    }
                }, 300);
            }

            // 事件监听
            codeTextarea.addEventListener('input', debouncedUpdatePreview);
            languageSelect.addEventListener('change', debouncedUpdatePreview);

            // 初始预览
            updateHighlightPreview();
        });
    </script>
</body>
</html>

3.2templates-index.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单代码分享</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="container">
        <header>
            <h1>简单代码分享</h1>
            <p>快速分享你的代码片段</p>
        </header>

        <main>
            <div class="actions">
                <a href="{{ url_for('create_snippet') }}" class="btn btn-primary">创建新代码片段</a>
            </div>

            <div class="features">
                <h2>功能特性</h2>
                <ul>
                    <li>简单易用的代码粘贴</li>
                    <li>实时预览效果</li>
                    <li>自动过期机制(7天)</li>
                    <li>支持多种编程语言</li>
                    <li>原始代码查看</li>
                </ul>
            </div>
        </main>

        <footer>
            <p>&copy; 2023 简单代码分享</p>
        </footer>
    </div>
</body>
</html>

3.3templates-password.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>密码保护 - 代码分享</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="container">
        <header>
            <h1>密码保护</h1>
            <a href="{{ url_for('index') }}" class="btn btn-secondary">返回首页</a>
        </header>

        <main>
            <div class="password-form">
                <h2>此代码片段受密码保护</h2>
                <p>请输入密码查看 "{{ snippet.title }}"</p>

                <form method="POST">
                    <div class="form-group">
                        <label for="password">密码:</label>
                        <input type="password" id="password" name="password" placeholder="输入密码" required>
                    </div>

                    {% if error %}
                    <div class="error-message">
                        {{ error }}
                    </div>
                    {% endif %}

                    <div class="form-actions">
                        <button type="submit" class="btn btn-primary">查看代码</button>
                    </div>
                </form>
            </div>
        </main>
    </div>
</body>
</html>

3.4 templates-view.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ snippet.title }} - 简单代码分享</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
    <script>hljs.highlightAll();</script>
</head>
<body>
    <div class="container">
        <header>
            <h1>{{ snippet.title }}</h1>
            <div class="actions">
                <a href="{{ url_for('index') }}" class="btn btn-secondary">返回首页</a>
                <a href="{{ url_for('create_snippet') }}" class="btn btn-primary">创建新片段</a>
                <a href="{{ url_for('raw_snippet', snippet_id=snippet.id) }}" class="btn btn-outline" target="_blank">查看原始代码</a>
            </div>
        </header>

        <main>
            <div class="snippet-info">
                <p><strong>创建时间:</strong> {{ snippet.created_at[:16] }}</p>
                <p><strong>过期时间:</strong> {{ snippet.expires_at[:16] }}</p>
                <p><strong>分享链接:</strong> <input type="text" value="{{ request.url }}" readonly onclick="this.select()"></p>
            </div>

            <div class="code-container">
                <pre><code class="language-{{ snippet.language }}">{{ snippet.code }}</code></pre>
            </div>
        </main>
    </div>
</body>
</html>

4.1 app.py

复制代码
from flask import Flask, render_template, request, redirect, url_for, jsonify
import uuid
import datetime
import sqlite3
import markdown
import html
import pygments
from pygments import highlight
from pygments.lexers import get_lexer_by_name, guess_lexer
from pygments.formatters import HtmlFormatter
import re
import os

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'


# 初始化数据库(包含迁移逻辑)
def init_db():
    conn = sqlite3.connect('snippets.db')
    c = conn.cursor()

    # 创建表(如果不存在)
    c.execute('''CREATE TABLE IF NOT EXISTS snippets
                 (id TEXT PRIMARY KEY, 
                  title TEXT, 
                  code TEXT, 
                  language TEXT,
                  created_at TIMESTAMP,
                  expires_at TIMESTAMP,
                  password TEXT)''')

    # 检查并添加缺失的列
    c.execute("PRAGMA table_info(snippets)")
    columns = [column[1] for column in c.fetchall()]

    if 'password' not in columns:
        c.execute("ALTER TABLE snippets ADD COLUMN password TEXT")
        print("已添加 password 列到数据库")

    conn.commit()
    conn.close()
    print("数据库初始化完成")


def get_db():
    conn = sqlite3.connect('snippets.db')
    conn.row_factory = sqlite3.Row
    return conn


# 代码高亮函数
def highlight_code(code, language):
    try:
        if language == 'auto':
            lexer = guess_lexer(code)
        else:
            lexer = get_lexer_by_name(language, stripall=True)
        formatter = HtmlFormatter(linenos=True, cssclass="highlight")
        result = highlight(code, lexer, formatter)
        return result
    except:
        # 如果高亮失败,返回转义的HTML
        return f'<pre><code>{html.escape(code)}</code></pre>'


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


# 创建代码片段
@app.route('/create', methods=['GET', 'POST'])
def create_snippet():
    if request.method == 'POST':
        title = request.form.get('title', 'Untitled')
        code = request.form.get('code', '')
        language = request.form.get('language', 'text')
        password = request.form.get('password', '')

        snippet_id = str(uuid.uuid4())[:8]
        created_at = datetime.datetime.now()
        expires_at = created_at + datetime.timedelta(days=7)

        conn = get_db()
        c = conn.cursor()
        c.execute("INSERT INTO snippets VALUES (?, ?, ?, ?, ?, ?, ?)",
                  (snippet_id, title, code, language, created_at, expires_at, password))
        conn.commit()
        conn.close()

        return redirect(url_for('view_snippet', snippet_id=snippet_id))

    return render_template('create.html')


# 查看代码片段
@app.route('/view/<snippet_id>', methods=['GET', 'POST'])
def view_snippet(snippet_id):
    conn = get_db()
    c = conn.cursor()
    c.execute("SELECT * FROM snippets WHERE id = ?", (snippet_id,))
    snippet = c.fetchone()
    conn.close()

    if snippet is None:
        return "代码片段不存在", 404

    expires_at = datetime.datetime.fromisoformat(snippet['expires_at'])
    if datetime.datetime.now() > expires_at:
        return "此代码片段已过期", 410

    # 检查密码保护
    if snippet['password']:
        if request.method == 'POST':
            if request.form.get('password') == snippet['password']:
                # 密码正确,显示代码
                highlighted_code = highlight_code(snippet['code'], snippet['language'])
                return render_template('view.html', snippet=snippet, highlighted_code=highlighted_code)
            else:
                error = "密码错误"
                return render_template('password.html', snippet=snippet, error=error)
        else:
            return render_template('password.html', snippet=snippet)

    highlighted_code = highlight_code(snippet['code'], snippet['language'])
    return render_template('view.html', snippet=snippet, highlighted_code=highlighted_code)


# 实时预览API
# 实时预览API - 确保这个路由存在
@app.route('/preview', methods=['POST'])
def preview():
    try:
        code = request.json.get('code', '')
        language = request.json.get('language', 'text')

        highlighted_code = highlight_code(code, language)

        return jsonify({
            'success': True,
            'html': highlighted_code
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        })


# 原始代码
@app.route('/raw/<snippet_id>')
def raw_snippet(snippet_id):
    conn = get_db()
    c = conn.cursor()
    c.execute("SELECT code FROM snippets WHERE id = ?", (snippet_id,))
    snippet = c.fetchone()
    conn.close()

    if snippet is None:
        return "代码片段不存在", 404

    return snippet['code'], 200, {'Content-Type': 'text/plain; charset=utf-8'}


if __name__ == '__main__':
    init_db()
    app.run(debug=True)
相关推荐
IT_陈寒2 小时前
SpringBoot3踩坑实录:一个@Async注解让我多扛了5000QPS
前端·人工智能·后端
kura_tsuki2 小时前
[Web网页] 零基础入门 HTML
前端·html
岁月宁静3 小时前
🎨 打造 AI 应用的 “门面”:Vue3.5 + MarkdownIt 实现高颜值、高性能的答案美化组件
前端·javascript·vue.js
golang学习记3 小时前
从0死磕全栈之Next.js Server Actions 入门实战:在服务端安全执行逻辑,告别 API 路由!
前端
光影少年3 小时前
vue3新增哪些内容以及api更改了哪些
前端·vue.js·掘金·日新计划
这儿有一堆花3 小时前
三种 弹出广告 代码开发实战
前端·html
练习时长一年3 小时前
Bean后处理器
java·服务器·前端
excel3 小时前
Vue 中 v-if 与 v-for 的优先级及最佳实践(Vue2 / Vue3 对比)
前端
吃饭最爱3 小时前
tomcat的功能和作用
前端