feat(config): stats vidéo + user 1000:1000 dans docker-compose
Admin stats : ajout video (count + size_bytes) dans /api/admin/stats. ConfigPage : grille médias 3 colonnes (Photos / Audio / Vidéos). docker-compose : backend et backend-worker tournent en user 1000:1000 pour que les fichiers écrits dans ./data/ appartiennent à l'utilisateur hôte et non à root. v0.5.6 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,12 +33,14 @@ async def get_stats(session: AsyncSession = Depends(get_session)):
|
|||||||
uploads = settings.upload_path
|
uploads = settings.upload_path
|
||||||
photos = _dir_stats(uploads / "images" / "originals") if (uploads / "images" / "originals").exists() else {"count": 0, "size_bytes": 0}
|
photos = _dir_stats(uploads / "images" / "originals") if (uploads / "images" / "originals").exists() else {"count": 0, "size_bytes": 0}
|
||||||
audio = _dir_stats(uploads / "audio") if (uploads / "audio").exists() else {"count": 0, "size_bytes": 0}
|
audio = _dir_stats(uploads / "audio") if (uploads / "audio").exists() else {"count": 0, "size_bytes": 0}
|
||||||
|
video = _dir_stats(uploads / "videos") if (uploads / "videos").exists() else {"count": 0, "size_bytes": 0}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"db_size_bytes": db_size,
|
"db_size_bytes": db_size,
|
||||||
"media": {
|
"media": {
|
||||||
"photos": photos,
|
"photos": photos,
|
||||||
"audio": audio,
|
"audio": audio,
|
||||||
|
"video": video,
|
||||||
},
|
},
|
||||||
"counts": {
|
"counts": {
|
||||||
"notes": notes_count,
|
"notes": notes_count,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ services:
|
|||||||
|
|
||||||
backend:
|
backend:
|
||||||
build: ./backend
|
build: ./backend
|
||||||
|
user: "1000:1000"
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: postgresql+asyncpg://homehub:homehub@db:5432/homehub
|
DATABASE_URL: postgresql+asyncpg://homehub:homehub@db:5432/homehub
|
||||||
UPLOAD_DIR: /data/uploads
|
UPLOAD_DIR: /data/uploads
|
||||||
@@ -44,6 +45,7 @@ services:
|
|||||||
|
|
||||||
backend-worker:
|
backend-worker:
|
||||||
build: ./backend
|
build: ./backend
|
||||||
|
user: "1000:1000"
|
||||||
command: arq app.workers.notes_worker.WorkerSettings
|
command: arq app.workers.notes_worker.WorkerSettings
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: postgresql+asyncpg://homehub:homehub@db:5432/homehub
|
DATABASE_URL: postgresql+asyncpg://homehub:homehub@db:5432/homehub
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "homehub-frontend",
|
"name": "homehub-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.5.5",
|
"version": "0.5.6",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export interface AppStats {
|
|||||||
media: {
|
media: {
|
||||||
photos: { count: number; size_bytes: number }
|
photos: { count: number; size_bytes: number }
|
||||||
audio: { count: number; size_bytes: number }
|
audio: { count: number; size_bytes: number }
|
||||||
|
video: { count: number; size_bytes: number }
|
||||||
}
|
}
|
||||||
counts: {
|
counts: {
|
||||||
notes: number
|
notes: number
|
||||||
|
|||||||
@@ -155,10 +155,11 @@ export default function ConfigPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Médias */}
|
{/* Médias */}
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
|
||||||
{[
|
{[
|
||||||
{ icon: 'image', label: 'Photos', data: stats.media.photos },
|
{ icon: 'image', label: 'Photos', data: stats.media.photos },
|
||||||
{ icon: 'microphone', label: 'Audio', data: stats.media.audio },
|
{ icon: 'microphone', label: 'Audio', data: stats.media.audio },
|
||||||
|
{ icon: 'video', label: 'Vidéos', data: stats.media.video },
|
||||||
].map(item => (
|
].map(item => (
|
||||||
<div key={item.label} style={{ background: 'var(--bg-4)', borderRadius: 8, padding: '8px 10px', display: 'flex', alignItems: 'center', gap: 8 }}>
|
<div key={item.label} style={{ background: 'var(--bg-4)', borderRadius: 8, padding: '8px 10px', display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||||
<i className={`fa-solid fa-${item.icon}`} style={{ color: 'var(--info)', fontSize: 14, flexShrink: 0 }} />
|
<i className={`fa-solid fa-${item.icon}`} style={{ color: 'var(--info)', fontSize: 14, flexShrink: 0 }} />
|
||||||
|
|||||||
Reference in New Issue
Block a user