Skip to content

Commit 5dd81ad

Browse files
ChanMoclaude
andcommitted
Release v0.7.1: 移动端双列布局与功能增强
- feat: browse 页面移动端改为双列瀑布流布局,展示更多内容 - feat: 添加收藏过滤功能到 browse 页面 - feat: 增强设置页面统计信息(视频、图片、收藏数量) - feat: 添加缓存清理 API 和缓存大小统计 - improve: 优化版本号获取逻辑,开发模式下从 pyproject.toml 读取 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 30ec2d5 commit 5dd81ad

File tree

5 files changed

+344
-83
lines changed

5 files changed

+344
-83
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "TikLocal"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
description = "A local media server that combines the features of TikTok and Pinterest"
55
authors = ["ChanMo <chan.mo@outlook.com>"]
66
readme = "README.md"

tiklocal/app.py

Lines changed: 114 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import io
23
import json
34
import random
45
import datetime
@@ -12,10 +13,36 @@
1213
from tiklocal.services import LibraryService, FavoriteService, RecommendService
1314
from tiklocal.services.thumbnail import ThumbnailService
1415

15-
try:
16-
app_version = version("tiklocal")
17-
except PackageNotFoundError:
18-
app_version = '1.0.0'
16+
17+
def get_app_version():
18+
"""获取应用版本号,开发模式下从 pyproject.toml 读取"""
19+
# 开发模式:优先从 pyproject.toml 读取
20+
pyproject_path = Path(__file__).parent.parent / 'pyproject.toml'
21+
if pyproject_path.exists():
22+
try:
23+
import tomllib
24+
except ImportError:
25+
try:
26+
import tomli as tomllib
27+
except ImportError:
28+
tomllib = None
29+
30+
if tomllib:
31+
try:
32+
with open(pyproject_path, 'rb') as f:
33+
data = tomllib.load(f)
34+
return data.get('tool', {}).get('poetry', {}).get('version', '1.0.0')
35+
except Exception:
36+
pass
37+
38+
# 生产模式:从已安装的包元数据获取
39+
try:
40+
return version("tiklocal")
41+
except PackageNotFoundError:
42+
return '1.0.0'
43+
44+
45+
app_version = get_app_version()
1946

2047
def create_app(test_config=None):
2148
app = Flask(__name__, instance_relative_config=True)
@@ -71,32 +98,35 @@ def browse():
7198
"""Video Library List"""
7299
# Using scan_videos instead of recursive get_files
73100
videos = library_service.scan_videos()
74-
101+
75102
# Filter Logic
76-
size_mode = request.args.get('size', 'all')
103+
filter_mode = request.args.get('filter', 'all')
77104
min_mb = int(request.args.get('min_mb', 50))
78-
79-
if size_mode == 'big':
105+
106+
if filter_mode == 'big':
80107
threshold = min_mb * 1024 * 1024
81108
videos = [v for v in videos if v.stat().st_size >= threshold]
109+
elif filter_mode == 'favorite':
110+
favorites = favorite_service.load()
111+
videos = [v for v in videos if library_service.get_relative_path(v) in favorites]
82112

83113
# Pagination
84114
count = len(videos)
85115
page = int(request.args.get('page', 1))
86116
length = 20
87117
offset = length * (page - 1)
88-
118+
89119
# Convert to relative strings for template
90120
sliced_videos = [library_service.get_relative_path(v) for v in videos[offset:offset+length]]
91-
121+
92122
return render_template(
93123
'browse.html',
94124
page=page,
95125
count=count,
96126
length=length,
97127
files=sliced_videos,
98128
menu='browse',
99-
size_mode=size_mode,
129+
filter=filter_mode,
100130
min_mb=min_mb,
101131
has_min_mb=request.args.get('min_mb') is not None,
102132
has_previous=page > 1,
@@ -105,8 +135,29 @@ def browse():
105135

106136
@app.route('/settings/')
107137
def settings_view():
138+
from tiklocal.paths import get_thumbnails_dir
139+
140+
# 获取各类统计
108141
video_count = len(library_service.scan_videos())
109-
return render_template('settings.html', menu='settings', version=app_version, videos=video_count)
142+
image_count = len(library_service.scan_images())
143+
favorite_count = len(favorite_service.load())
144+
145+
# 缩略图缓存信息
146+
thumb_dir = get_thumbnails_dir()
147+
thumb_files = list(thumb_dir.glob('*.jpg'))
148+
cache_count = len(thumb_files)
149+
cache_size_mb = round(sum(f.stat().st_size for f in thumb_files if f.exists()) / (1024 * 1024), 2)
150+
151+
return render_template(
152+
'settings.html',
153+
menu='settings',
154+
version=app_version,
155+
videos=video_count,
156+
images=image_count,
157+
favorites=favorite_count,
158+
cache_count=cache_count,
159+
cache_size_mb=cache_size_mb
160+
)
110161

111162
@app.route('/library')
112163
def library_redirect():
@@ -251,17 +302,65 @@ def api_favorite(name):
251302
def api_set_thumbnail(name):
252303
target = library_service.resolve_path(name)
253304
if not target: return {'success': False, 'error': 'Invalid path'}, 400
254-
305+
255306
payload = request.get_json(silent=True) or {}
256307
ts = payload.get('time')
257-
308+
258309
# This logic is a bit specific to app.py still, ideally move to ThumbnailService
259310
# But for now, we just need to regen the thumb
260311
thumb_path = thumbnail_service._get_thumb_path(name)
261312
success = thumbnail_service._generate(target, thumb_path, timestamp=float(ts) if ts else None)
262-
313+
263314
if success:
264315
return {'success': True, 'url': f"/thumb?uri={quote(name)}&v={int(datetime.datetime.now().timestamp())}"}
265316
return {'success': False, 'error': 'Failed to generate'}, 500
266317

318+
@app.route('/api/cache/clear', methods=['POST'])
319+
def api_clear_cache():
320+
"""清理缩略图缓存"""
321+
from tiklocal.paths import get_thumbnails_dir
322+
323+
thumb_dir = get_thumbnails_dir()
324+
deleted_count = 0
325+
freed_bytes = 0
326+
327+
try:
328+
for thumb_file in thumb_dir.glob('*.jpg'):
329+
try:
330+
freed_bytes += thumb_file.stat().st_size
331+
thumb_file.unlink()
332+
deleted_count += 1
333+
except Exception:
334+
continue
335+
336+
return {
337+
'success': True,
338+
'deleted_count': deleted_count,
339+
'freed_mb': round(freed_bytes / (1024 * 1024), 2)
340+
}
341+
except Exception as e:
342+
return {'success': False, 'error': str(e)}, 500
343+
344+
@app.route('/api/library/stats')
345+
def api_library_stats():
346+
"""获取媒体库统计信息"""
347+
from tiklocal.paths import get_thumbnails_dir
348+
349+
videos = library_service.scan_videos()
350+
images = library_service.scan_images()
351+
favorites = favorite_service.load()
352+
353+
# 计算缩略图缓存信息
354+
thumb_dir = get_thumbnails_dir()
355+
thumb_files = list(thumb_dir.glob('*.jpg'))
356+
thumb_size = sum(f.stat().st_size for f in thumb_files if f.exists())
357+
358+
return {
359+
'videos': len(videos),
360+
'images': len(images),
361+
'favorites': len(favorites),
362+
'cache_count': len(thumb_files),
363+
'cache_mb': round(thumb_size / (1024 * 1024), 2)
364+
}
365+
267366
return app

0 commit comments

Comments
 (0)