Initial commit: ap_ds Code Repository System v1.0.0

This commit is contained in:
dvs
2026-08-28 11:23:52 +08:00
commit 74a93c63f2
23 changed files with 5811 additions and 0 deletions
+381
View File
@@ -0,0 +1,381 @@
<!-- 英文 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 %}