feat: Added popular search recommendation function

This commit is contained in:
levywang 2025-04-15 18:31:29 +08:00
parent 38ed99ee13
commit 246a1f7673
8 changed files with 659 additions and 416 deletions

View File

@ -55,7 +55,7 @@ python main.py
```
The default API address: `http://127.0.0.1:8000/`
You can configure a reverse proxy and domain, replacing `BASE_URL` in line 38 of `web/script.js`.
You can configure a reverse proxy and domain, replacing `BASE_URL` in line 3 of `web/config.js`.
The backend configuration file is located in `data/config.yaml`. Modify it according to your actual needs.

View File

@ -56,7 +56,7 @@ python main.py
```
默认运行的API地址`http://127.0.0.1:8000/`
可以配置反代和域名,替换 `web/script.js` 38行中的 `BASE_URL`
可以配置反代和域名,替换 `web/config.js` 3行中的 `BASE_URL`
后端运行的配置文件在 `data/config.yaml` 中,请根据实际情况修改

10
main.py
View File

@ -310,11 +310,15 @@ def main(cfg: DictConfig):
if not search_terms:
return {"status": "succeed", "data": []}
# 统计每个搜索词的出现次数并获取前N名
# 统计每个搜索词的出现次数并获取指定范围的数据
term_counts = Counter(search_terms)
top_terms = [term for term, _ in term_counts.most_common(top_n)]
most_common_all = term_counts.most_common() # 获取全部排序结果
start_index = top_n
end_index = start_index + top_n
selected_terms = most_common_all[start_index:end_index] # 切片获取指定范围
top_terms = [term for term, _ in selected_terms]
logger.info(f"Retrieved top {top_n} popular search terms from last {last_n_lines} lines")
logger.info(f"Retrieved top {top_n*2} popular search terms from last {last_n_lines} lines")
return {"status": "succeed", "data": top_terms}
except asyncio.TimeoutError:
logger.error("Timeout while reading log file")

13
web/config.js Normal file
View File

@ -0,0 +1,13 @@
// config.js
const API_CONFIG = {
BASE_URL: '/api/v1',
ENDPOINTS: {
SEARCH: '/avcode',
COLLECTIONS: '/hacg',
VIDEO: '/get_video',
HOT_SEARCHES: '/hot_searches'
}
};
// 导出配置
export default API_CONFIG;

75
web/globals.js Normal file
View File

@ -0,0 +1,75 @@
// globals.js - 包含所有需要在HTML中直接调用的全局函数
// 在此处存储全局状态
let appState = {
translations: null, // 将在初始化后从脚本中设置
currentLang: 'zh',
SORT_OPTIONS: null, // 将在初始化后从脚本中设置
};
// 注册全局函数
window.switchTab = function(tabName) {
// 调用主脚本中的函数
window.dispatchEvent(new CustomEvent('switchTab', { detail: { tabName } }));
};
window.searchMagnet = function() {
// 触发搜索事件
window.dispatchEvent(new CustomEvent('searchMagnet'));
};
window.copyToClipboard = function(text) {
// 触发复制事件
window.dispatchEvent(new CustomEvent('copyToClipboard', { detail: { text } }));
};
window.showSortMenu = function(button) {
// 触发排序菜单事件
window.dispatchEvent(new CustomEvent('showSortMenu', { detail: { button } }));
};
// 添加热门搜索词点击处理函数
window.searchWithTerm = function(term) {
// 触发热门搜索词点击事件
window.dispatchEvent(new CustomEvent('searchWithTerm', { detail: { term } }));
};
// 添加视频页面复制URL按钮点击事件
window.copyVideoUrl = function() {
const sourceUrlElement = document.getElementById('videoSourceUrl');
const sourceUrl = sourceUrlElement?.textContent;
if (!sourceUrl) return;
// 使用全局copyToClipboard函数
window.copyToClipboard(sourceUrl);
// 更新按钮状态
const copyButton = document.getElementById('copySourceUrl');
if (copyButton) {
copyButton.classList.add('copied');
const textElement = copyButton.querySelector('.tab-text');
if (textElement) {
const originalText = textElement.textContent;
textElement.textContent = appState.translations ?
appState.translations[appState.currentLang].copied :
'已复制';
setTimeout(() => {
copyButton.classList.remove('copied');
textElement.textContent = originalText;
}, 2000);
}
}
};
// 注册全局事件处理函数以便主脚本可以设置全局状态
window.setGlobalState = function(key, value) {
appState[key] = value;
};
// 为主脚本提供初始化方法
window.initializeGlobals = function(data) {
if (data.translations) appState.translations = data.translations;
if (data.currentLang) appState.currentLang = data.currentLang;
if (data.SORT_OPTIONS) appState.SORT_OPTIONS = data.SORT_OPTIONS;
};

View File

@ -7,9 +7,9 @@
<link rel="icon" href="imgs/favicon.ico">
<link href="https://testingcf.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
<link href="https://testingcf.jsdelivr.net/npm/hls.js@1.4.12/dist/hls.min.js" rel="stylesheet">
<meta name="theme-color" content="#000000">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="AvHub">
<link rel="manifest" href="manifest.json">
@ -175,7 +175,7 @@
</div>
<div class="source-url truncate font-mono" id="videoSourceUrl"></div>
</div>
<button id="copySourceUrl" class="copy-button flex items-center px-3 py-1.5 rounded">
<button id="copySourceUrl" class="copy-button flex items-center px-3 py-1.5 rounded" onclick="copyVideoUrl()">
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"></path>
</svg>
@ -193,8 +193,12 @@
</svg>
</button>
<!-- 正确位置加载HLS.js -->
<script src="https://testingcf.jsdelivr.net/npm/hls.js@1.4.12/dist/hls.min.js"></script>
<script src="script.js"></script>
<!-- 加载全局函数 -->
<script src="globals.js"></script>
<!-- 加载主脚本模块 -->
<script type="module" src="script.js"></script>
<!-- 在body末尾添加通知元素 -->
<div class="notification" id="notification">

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,9 @@ const urlsToCache = [
'/',
'/index.html',
'/style.css',
'/config.js',
'/script.js',
'/globals.js',
'/manifest.json',
'/imgs/favicon.ico',
'/imgs/icon-192x192.png',