scan media folder
This commit is contained in:
@@ -30,10 +30,19 @@ def create_asset(data: AssetCreate):
|
||||
if not path.exists():
|
||||
raise HTTPException(status_code=400, detail="File not found")
|
||||
|
||||
# Store path relative to media root
|
||||
import os
|
||||
|
||||
media_root = Path(os.environ.get("MEDIA_ROOT", "/app/media"))
|
||||
try:
|
||||
rel_path = str(path.relative_to(media_root))
|
||||
except ValueError:
|
||||
rel_path = path.name
|
||||
|
||||
# Create asset
|
||||
asset = MediaAsset.objects.create(
|
||||
filename=data.filename or path.name,
|
||||
file_path=str(path.absolute()),
|
||||
file_path=rel_path,
|
||||
file_size=path.stat().st_size,
|
||||
)
|
||||
|
||||
@@ -88,3 +97,68 @@ def update_asset(asset_id: UUID, data: AssetUpdate, asset=Depends(get_asset)):
|
||||
def delete_asset(asset_id: UUID, asset=Depends(get_asset)):
|
||||
"""Delete an asset."""
|
||||
asset.delete()
|
||||
|
||||
|
||||
@router.post("/scan", response_model=dict)
|
||||
def scan_media_folder():
|
||||
"""
|
||||
Scan the media folder for new video/audio files and register them as assets.
|
||||
|
||||
Returns a summary of files found and registered.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from mpr.media_assets.models import MediaAsset
|
||||
|
||||
# Get media root from environment
|
||||
media_root = os.environ.get("MEDIA_ROOT", "/app/media")
|
||||
media_path = Path(media_root)
|
||||
|
||||
if not media_path.exists():
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"Media folder not found: {media_root}"
|
||||
)
|
||||
|
||||
# Supported video/audio extensions
|
||||
video_exts = {".mp4", ".mkv", ".avi", ".mov", ".webm", ".flv", ".wmv", ".m4v"}
|
||||
audio_exts = {".mp3", ".wav", ".flac", ".aac", ".ogg", ".m4a"}
|
||||
supported_exts = video_exts | audio_exts
|
||||
|
||||
# Get existing filenames to avoid duplicates
|
||||
existing_filenames = set(MediaAsset.objects.values_list("filename", flat=True))
|
||||
|
||||
# Scan for media files
|
||||
found_files = []
|
||||
registered_files = []
|
||||
skipped_files = []
|
||||
|
||||
for file_path in media_path.rglob("*"):
|
||||
if file_path.is_file() and file_path.suffix.lower() in supported_exts:
|
||||
found_files.append(str(file_path))
|
||||
|
||||
# Skip if already registered
|
||||
if file_path.name in existing_filenames:
|
||||
skipped_files.append(file_path.name)
|
||||
continue
|
||||
|
||||
# Register new asset with path relative to media root
|
||||
rel_path = str(file_path.relative_to(media_path))
|
||||
try:
|
||||
asset = MediaAsset.objects.create(
|
||||
filename=file_path.name,
|
||||
file_path=rel_path,
|
||||
file_size=file_path.stat().st_size,
|
||||
)
|
||||
registered_files.append(file_path.name)
|
||||
|
||||
# TODO: Queue probe task to extract metadata
|
||||
except Exception as e:
|
||||
print(f"Error registering {file_path.name}: {e}")
|
||||
|
||||
return {
|
||||
"found": len(found_files),
|
||||
"registered": len(registered_files),
|
||||
"skipped": len(skipped_files),
|
||||
"files": registered_files,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user