Files
ap-ds-git-code/templates/code_browser.html
T

381 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 英文 SEO 标签 -->
<meta name="description" content="ap_ds official code repository. Browse branches (APDSLTS001), tags (v3.0.0), view README/setup.py with syntax highlighting, search files, and download ZIP/TAR.GZ/WHL. Self-hosted, never offline.">
<meta name="keywords" content="ap_ds source code, Python audio library code, browse repository, download WHL, self-hosted git, APDSLTS001, v3.0.0 source">
<meta property="og:title" content="ap_ds Code Repository – Browse & Download Source">
<meta property="og:description" content="Official self-hosted Git-style code browser for ap_ds. Syntax-highlighted Python files, Markdown rendering, multi-format downloads.">
<meta property="og:type" content="software">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="ap_ds Code Repository">
<!-- 中文 SEO 标签 -->
<meta name="description" lang="zh-CN" content="ap_ds 官方代码仓库。浏览分支(APDSLTS001)和版本(v3.0.0)下的所有源文件,语法高亮预览 README/setup.py,文件搜索,一键下载 ZIP/TAR.GZ/WHL。自主托管,永不掉线。">
<meta name="keywords" lang="zh-CN" content="ap_ds 源代码, Python音频库代码, 浏览仓库, 下载WHL, 自建Git仓库, APDSLTS001, v3.0.0源码">
<meta property="og:title" lang="zh-CN" content="ap_ds 代码仓库 – 浏览与下载源码">
<meta property="og:description" lang="zh-CN" content="ap_ds 官方自建代码仓库。支持语法高亮的 Python 文件预览、Markdown 渲染、多格式源码下载。">{% extends "base.html" %}
{% block content %}
{% block title %}ap_ds Code Repository – Official Self-Hosted Git Source Code & Downloads{% endblock %}<!-- 仓库头部 -->
<div class="repo-header">
<div class="repo-path">
<a href="/code">ap_ds</a>
<span class="separator">/</span>
<span>{{ current_branch if current_branch else '选择分支' }}</span>
{% if current_version %}
<span class="separator">/</span>
<span>{{ current_version }}</span>
{% endif %}
</div>
</div>
<!-- 搜索栏 -->
<div class="search-box">
<form action="{{ url_for('search') }}" method="get" style="display: flex; gap: 8px; width: 100%;">
<input type="hidden" name="branch" value="{{ current_branch }}">
<input type="hidden" name="version" value="{{ current_version }}">
<input type="text" name="q" class="search-input" placeholder="查找文件..." value="{{ search_query or '' }}">
<button type="submit" class="btn btn-primary">搜索</button>
</form>
</div>
<div class="two-column">
<!-- 左侧边栏 -->
<div class="sidebar">
<div class="sidebar-section">
<div class="sidebar-title">📌 分支</div>
<div class="branch-selector" id="branch-selector">
<span>{{ current_branch if current_branch else '选择分支' }}</span>
<span>▼</span>
</div>
<div id="branch-menu" class="branch-menu-dropdown" style="display: none;">
{% for branch_name in branches.keys() %}
<div class="branch-menu-item" data-branch="{{ branch_name }}">{{ branch_name }}</div>
{% endfor %}
</div>
</div>
<div class="sidebar-section">
<div class="sidebar-title">🏷️ 版本</div>
<div class="branch-selector" id="version-selector">
<span>{{ current_version if current_version else '选择版本' }}</span>
<span>▼</span>
</div>
<div id="version-menu" class="branch-menu-dropdown" style="display: none;">
{% if current_branch and branches[current_branch] %}
{% for version in branches[current_branch] %}
<div class="branch-menu-item" data-version="{{ version.name }}">{{ version.name }}</div>
{% endfor %}
{% endif %}
</div>
</div>
<div class="sidebar-section">
<div class="sidebar-title">📦 下载</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="{{ url_for('download_zip', branch=current_branch, version=current_version) if current_branch and current_version else '#' }}" class="btn btn-secondary {% if not current_branch or not current_version %}disabled{% endif %}" {% if not current_branch or not current_version %}style="opacity:0.5; pointer-events:none;"{% endif %}>
📥 下载 ZIP
</a>
<a href="{{ url_for('download_tar', branch=current_branch, version=current_version) if current_branch and current_version else '#' }}" class="btn btn-secondary {% if not current_branch or not current_version %}disabled{% endif %}" {% if not current_branch or not current_version %}style="opacity:0.5; pointer-events:none;"{% endif %}>
📥 下载 TAR.GZ
</a>
<a href="{{ url_for('download_whl', version=current_version) if current_version else '#' }}" class="btn btn-secondary {% if not current_version %}disabled{% endif %}" {% if not current_version %}style="opacity:0.5; pointer-events:none;"{% endif %}>
📥 下载 WHL
</a>
</div>
</div>
<div class="sidebar-section">
<div class="sidebar-title">🔗 快速链接</div>
<div style="display: flex; flex-direction: column; gap: 6px;">
<a href="/releases" class="btn btn-secondary" style="text-align: center;">查看发行版</a>
<a href="/feedback" class="btn btn-secondary" style="text-align: center;">提交反馈</a>
</div>
</div>
</div>
<!-- 右侧内容 -->
<div class="main-content">
<!-- 搜索结果 -->
{% if search_results %}
<div class="file-list">
<div class="file-list-header">
<span>🔍 搜索结果 ({{ search_results|length }})</span>
<span></span>
</div>
{% for result in search_results %}
<div class="file-row">
<div class="file-name">
<span class="icon">📄</span>
{% set relative_path = result.path.replace(current_branch + '/' + current_version + '/', '') %}
<a href="{{ url_for('view_file', file_path=relative_path, branch=current_branch, version=current_version) }}">{{ result.name }}</a>
</div>
<div class="file-message">{{ result.path }}</div>
<div class="file-time">
{% if result.size < 1024 %}
{{ result.size }} B
{% elif result.size < 1024*1024 %}
{{ (result.size/1024)|round(1) }} KB
{% else %}
{{ (result.size/(1024*1024))|round(1) }} MB
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endif %}
<!-- 文件列表 -->
{% if not search_results %}
<div class="file-list">
<div class="file-list-header">
<span>📁 文件列表</span>
<span></span>
<span>大小</span>
</div>
<!-- 文件列表中的链接改为使用完整路径 -->
{% for item in file_tree %}
<div class="file-row">
<div class="file-name">
<span class="icon">{% if item.type == 'dir' %}📁{% else %}📄{% endif %}</span>
{% if item.type == 'dir' %}
<a href="{{ url_for('browse_directory', dir_path=item.path, branch=current_branch, version=current_version) }}">{{ item.name }}</a>
{% else %}
<!-- 直接使用完整路径,不加替换 -->
<a href="{{ url_for('view_file', file_path=item.path, branch=current_branch, version=current_version) }}">{{ item.name }}</a>
{% endif %}
</div>
<div class="file-message">
{% if item.type == 'dir' %}目录{% else %}{{ item.name }}{% endif %}
</div>
<div class="file-time">
{% if item.type == 'file' %}
{% if item.size < 1024 %}
{{ item.size }} B
{% elif item.size < 1024*1024 %}
{{ (item.size/1024)|round(1) }} KB
{% else %}
{{ (item.size/(1024*1024))|round(1) }} MB
{% endif %}
{% else %}
-
{% endif %}
</div>
</div>
{% else %}
<div class="file-row">
<div class="file-name" style="justify-content: center; color: var(--repo-color-text-tertiary);">
此目录为空
</div>
<div class="file-message"></div>
<div class="file-time"></div>
</div>
{% endfor %}
</div>
{% endif %}
<!-- README 区域 -->
<div class="readme-section">
<div class="readme-header">
📖 README.md
</div>
<div class="readme-content" id="readme-content">
<div class="loading">加载中...</div>
</div>
</div>
</div>
</div>
<script>
// 获取当前 URL 基础路径
var currentUrl = "{{ url_for('code_browser') }}";
var currentBranch = "{{ current_branch }}";
var currentVersion = "{{ current_version }}";
// ========== 分支/版本选择器 ==========
var branchSelector = document.getElementById('branch-selector');
var branchMenu = document.getElementById('branch-menu');
var versionSelector = document.getElementById('version-selector');
var versionMenu = document.getElementById('version-menu');
if (branchSelector) {
branchSelector.onclick = function(e) {
e.stopPropagation();
branchMenu.style.display = branchMenu.style.display === 'none' ? 'block' : 'none';
if (versionMenu) versionMenu.style.display = 'none';
};
}
if (versionSelector) {
versionSelector.onclick = function(e) {
e.stopPropagation();
versionMenu.style.display = versionMenu.style.display === 'none' ? 'block' : 'none';
if (branchMenu) branchMenu.style.display = 'none';
};
}
document.onclick = function() {
if (branchMenu) branchMenu.style.display = 'none';
if (versionMenu) versionMenu.style.display = 'none';
};
var branchItems = document.querySelectorAll('#branch-menu .branch-menu-item');
branchItems.forEach(function(item) {
item.onclick = function(e) {
e.stopPropagation();
var branch = this.getAttribute('data-branch');
if (branch) {
window.location.href = currentUrl + '?branch=' + encodeURIComponent(branch);
}
};
});
var versionItems = document.querySelectorAll('#version-menu .branch-menu-item');
versionItems.forEach(function(item) {
item.onclick = function(e) {
e.stopPropagation();
var version = this.getAttribute('data-version');
if (version && currentBranch) {
window.location.href = currentUrl + '?branch=' + encodeURIComponent(currentBranch) + '&version=' + encodeURIComponent(version);
}
};
});
// ========== 加载 README ==========
function loadReadme() {
if (!currentBranch || !currentVersion) {
document.getElementById('readme-content').innerHTML = '<div class="info-message" style="text-align: center;">请选择分支和版本以查看 README</div>';
return;
}
var readmeUrl = '/view/' + currentBranch + '/' + currentVersion + '/README.md?branch=' + currentBranch + '&version=' + currentVersion;
fetch(readmeUrl)
.then(function(res) {
if (res.ok) {
return res.text();
}
throw new Error('README.md 不存在');
})
.then(function(html) {
var container = document.getElementById('readme-content');
if (html.indexOf('<div class="readme-content">') !== -1) {
var match = html.match(/<div class="readme-content">([\s\S]*?)<\/div>/);
if (match && match[1]) {
container.innerHTML = match[1];
} else {
container.innerHTML = html;
}
} else {
container.innerHTML = html;
}
var codeBlocks = container.querySelectorAll('pre code');
codeBlocks.forEach(function(block) {
if (typeof hljs !== 'undefined') {
hljs.highlightElement(block);
}
});
})
.catch(function(err) {
document.getElementById('readme-content').innerHTML = '<div class="info-message" style="text-align: center;">📄 暂无 README.md 文件</div>';
});
}
loadReadme();
</script>
<style>
.disabled {
opacity: 0.5;
pointer-events: none;
cursor: not-allowed;
}
.branch-menu-dropdown {
position: absolute;
background-color: var(--repo-color-bg);
border: 1px solid var(--repo-color-border);
border-radius: var(--repo-radius-md, 6px);
width: 200px;
z-index: var(--repo-z-dropdown, 100);
box-shadow: var(--repo-shadow-md);
max-height: 300px;
overflow-y: auto;
}
.branch-menu-item {
padding: var(--repo-spacing-2, 8px) var(--repo-spacing-3, 12px);
cursor: pointer;
transition: background 0.2s;
color: var(--repo-color-text);
}
.branch-menu-item:hover {
background-color: var(--repo-color-bg-hover);
}
.loading {
text-align: center;
padding: var(--repo-spacing-8, 32px);
color: var(--repo-color-text-tertiary);
}
.info-message {
text-align: center;
padding: var(--repo-spacing-8, 32px);
color: var(--repo-color-text-tertiary);
}
/* README 内容样式 */
#readme-content h1, #readme-content h2, #readme-content h3 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
}
#readme-content h1 { font-size: 2em; border-bottom: 1px solid var(--repo-color-border); padding-bottom: 0.3em; }
#readme-content h2 { font-size: 1.5em; border-bottom: 1px solid var(--repo-color-border); padding-bottom: 0.3em; }
#readme-content p { margin-bottom: 16px; line-height: 1.6; }
#readme-content code {
background-color: var(--repo-color-bg-tertiary);
padding: 0.2em 0.4em;
border-radius: 4px;
font-family: monospace;
}
#readme-content pre {
background-color: var(--repo-color-bg-tertiary);
padding: 16px;
border-radius: 8px;
overflow-x: auto;
margin-bottom: 16px;
}
#readme-content pre code {
background: none;
padding: 0;
}
#readme-content ul, #readme-content ol {
padding-left: 2em;
margin-bottom: 16px;
}
#readme-content blockquote {
border-left: 4px solid var(--repo-color-border);
padding-left: 16px;
color: var(--repo-color-text-tertiary);
margin-bottom: 16px;
}
#readme-content table {
border-collapse: collapse;
margin-bottom: 16px;
width: 100%;
}
#readme-content th, #readme-content td {
border: 1px solid var(--repo-color-border);
padding: 8px 12px;
}
#readme-content th {
background-color: var(--repo-color-bg-secondary);
}
</style>
{% endblock %}