Initial commit: ap_ds Code Repository System v1.0.0
This commit is contained in:
@@ -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 %}
|
||||
Reference in New Issue
Block a user