VeuReu commited on
Commit
98bfbd9
·
verified ·
1 Parent(s): d18bae1

Update storage/media_routers.py

Browse files
Files changed (1) hide show
  1. storage/media_routers.py +225 -10
storage/media_routers.py CHANGED
@@ -139,17 +139,16 @@ def download_cast_csv(
139
  async def upload_video(
140
  video: UploadFile = File(...),
141
  token: str = Query(..., description="Token required for authorization")
142
- ):
143
  """
144
  Saves an uploaded video by hashing it with SHA1 and placing it under:
145
  /data/media/<sha1>/clip/<original_filename>
146
 
147
- Steps:
148
  - Compute SHA1 of the uploaded video.
149
- - Ensure /data/media exists.
150
- - Create folder /data/media/<sha1> if missing.
151
- - Create folder /data/media/<sha1>/clip if missing.
152
- - Save the video inside /data/media/<sha1>/clip/.
153
  """
154
  MEDIA_ROOT = Path("/data/media")
155
  file_manager = FileManager(MEDIA_ROOT)
@@ -159,10 +158,10 @@ async def upload_video(
159
  # Read content into memory (needed to compute hash twice)
160
  file_bytes = await video.read()
161
 
162
- # Create an in-memory file handler
163
  file_handler = io.BytesIO(file_bytes)
164
 
165
- # Compute SHA1 using your FileManager method
166
  try:
167
  sha1 = file_manager.compute_sha1(file_handler)
168
  except Exception as exc:
@@ -179,10 +178,17 @@ async def upload_video(
179
  clip_dir = video_root / "clip"
180
  clip_dir.mkdir(parents=True, exist_ok=True)
181
 
182
- # Final file path
 
 
 
 
 
 
 
183
  final_path = clip_dir / video.filename
184
 
185
- # Save file using your FileManager.upload_file
186
  save_result = file_manager.upload_file(io.BytesIO(file_bytes), final_path)
187
 
188
  if not save_result["operation_success"]:
@@ -322,3 +328,212 @@ def list_all_videos(
322
  })
323
 
324
  return results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  async def upload_video(
140
  video: UploadFile = File(...),
141
  token: str = Query(..., description="Token required for authorization")
142
+ ):
143
  """
144
  Saves an uploaded video by hashing it with SHA1 and placing it under:
145
  /data/media/<sha1>/clip/<original_filename>
146
 
147
+ Behavior:
148
  - Compute SHA1 of the uploaded video.
149
+ - Ensure folder structure exists.
150
+ - Delete any existing .mp4 files under /clip.
151
+ - Save the uploaded video in the clip folder.
 
152
  """
153
  MEDIA_ROOT = Path("/data/media")
154
  file_manager = FileManager(MEDIA_ROOT)
 
158
  # Read content into memory (needed to compute hash twice)
159
  file_bytes = await video.read()
160
 
161
+ # Create an in-memory file handler for hashing
162
  file_handler = io.BytesIO(file_bytes)
163
 
164
+ # Compute SHA1
165
  try:
166
  sha1 = file_manager.compute_sha1(file_handler)
167
  except Exception as exc:
 
178
  clip_dir = video_root / "clip"
179
  clip_dir.mkdir(parents=True, exist_ok=True)
180
 
181
+ # Delete old MP4 files
182
+ try:
183
+ for old_mp4 in clip_dir.glob("*.mp4"):
184
+ old_mp4.unlink()
185
+ except Exception as exc:
186
+ raise HTTPException(status_code=500, detail=f"Failed to delete old videos: {exc}")
187
+
188
+ # Save new video path
189
  final_path = clip_dir / video.filename
190
 
191
+ # Save file
192
  save_result = file_manager.upload_file(io.BytesIO(file_bytes), final_path)
193
 
194
  if not save_result["operation_success"]:
 
328
  })
329
 
330
  return results
331
+
332
+ @router.post("/upload_original_audio", tags=["Media Manager"])
333
+ async def upload_audio(
334
+ audio: UploadFile = File(...),
335
+ token: str = Query(..., description="Token required for authorization")
336
+ ):
337
+ """
338
+ Saves an uploaded audio file by hashing it with SHA1 and placing it under:
339
+ /data/media/<sha1>/audio/<original_filename>
340
+
341
+ Behavior:
342
+ - Compute SHA1 of the uploaded audio.
343
+ - Ensure folder structure exists.
344
+ - Delete any existing audio files under /audio.
345
+ - Save the uploaded audio in the audio folder.
346
+ """
347
+ MEDIA_ROOT = Path("/data/media")
348
+ file_manager = FileManager(MEDIA_ROOT)
349
+ HF_TOKEN = os.getenv("HF_TOKEN")
350
+ validate_token(token)
351
+
352
+ # Read content into memory (needed to compute hash twice)
353
+ file_bytes = await audio.read()
354
+
355
+ # Create an in-memory file handler for hashing
356
+ file_handler = io.BytesIO(file_bytes)
357
+
358
+ # Compute SHA1
359
+ try:
360
+ sha1 = file_manager.compute_sha1(file_handler)
361
+ except Exception as exc:
362
+ raise HTTPException(status_code=500, detail=f"SHA1 computation failed: {exc}")
363
+
364
+ # Ensure /data/media exists
365
+ MEDIA_ROOT.mkdir(parents=True, exist_ok=True)
366
+
367
+ # Path: /data/media/<sha1>
368
+ audio_root = MEDIA_ROOT / sha1
369
+ audio_root.mkdir(parents=True, exist_ok=True)
370
+
371
+ # Path: /data/media/<sha1>/audio
372
+ audio_dir = audio_root / "audio"
373
+ audio_dir.mkdir(parents=True, exist_ok=True)
374
+
375
+ # Delete old audio files
376
+ AUDIO_EXTENSIONS = ("*.mp3", "*.wav", "*.m4a", "*.aac", "*.ogg", "*.flac")
377
+ try:
378
+ for pattern in AUDIO_EXTENSIONS:
379
+ for old_audio in audio_dir.glob(pattern):
380
+ old_audio.unlink()
381
+ except Exception as exc:
382
+ raise HTTPException(status_code=500, detail=f"Failed to delete old audio files: {exc}")
383
+
384
+ # Final save path
385
+ final_path = audio_dir / audio.filename
386
+
387
+ # Save file
388
+ save_result = file_manager.upload_file(io.BytesIO(file_bytes), final_path)
389
+
390
+ if not save_result["operation_success"]:
391
+ raise HTTPException(status_code=500, detail=save_result["error"])
392
+
393
+ return JSONResponse(
394
+ status_code=200,
395
+ content={
396
+ "status": "ok",
397
+ "sha1": sha1,
398
+ "saved_to": str(final_path)
399
+ }
400
+ )
401
+
402
+ @router.get("/download_original_audio", tags=["Media Manager"])
403
+ def download_audio(
404
+ sha1: str,
405
+ token: str = Query(..., description="Token required for authorization")
406
+ ):
407
+ """
408
+ Download a stored audio file by its SHA-1 directory name.
409
+
410
+ This endpoint looks for audio stored under the path:
411
+ /data/media/<sha1>/audio/
412
+ and returns the first audio file found in that folder.
413
+
414
+ The method performs the following steps:
415
+ - Checks if the SHA-1 folder exists inside the media root.
416
+ - Validates that the "audio" subfolder exists.
417
+ - Searches for the first supported audio file.
418
+ - Uses FileManager.get_file to ensure the file is accessible.
419
+ - Returns the audio file as a FileResponse.
420
+
421
+ Parameters
422
+ ----------
423
+ sha1 : str
424
+ The SHA-1 hash corresponding to the directory where the audio is stored.
425
+
426
+ Returns
427
+ -------
428
+ FileResponse
429
+ A streaming response containing the audio file.
430
+
431
+ Raises
432
+ ------
433
+ HTTPException
434
+ - 404 if the SHA-1 folder does not exist.
435
+ - 404 if the audio folder is missing.
436
+ - 404 if no audio files are found.
437
+ - 404 if the file cannot be retrieved using FileManager.
438
+ """
439
+ MEDIA_ROOT = Path("/data/media")
440
+ file_manager = FileManager(MEDIA_ROOT)
441
+ HF_TOKEN = os.getenv("HF_TOKEN")
442
+ validate_token(token)
443
+
444
+ sha1_folder = MEDIA_ROOT / sha1
445
+ audio_folder = sha1_folder / "audio"
446
+
447
+ if not sha1_folder.exists() or not sha1_folder.is_dir():
448
+ raise HTTPException(status_code=404, detail="SHA1 folder not found")
449
+
450
+ if not audio_folder.exists() or not audio_folder.is_dir():
451
+ raise HTTPException(status_code=404, detail="Audio folder not found")
452
+
453
+ # Supported audio extensions
454
+ AUDIO_EXTENSIONS = ["*.mp3", "*.wav", "*.aac", "*.m4a", "*.ogg", "*.flac"]
455
+
456
+ audio_files = []
457
+ for pattern in AUDIO_EXTENSIONS:
458
+ audio_files.extend(list(audio_folder.glob(pattern)))
459
+
460
+ if not audio_files:
461
+ raise HTTPException(status_code=404, detail="No audio files found")
462
+
463
+ audio_path = audio_files[0]
464
+
465
+ # Convert to relative path for FileManager
466
+ relative_path = audio_path.relative_to(MEDIA_ROOT)
467
+
468
+ handler = file_manager.get_file(relative_path)
469
+ if handler is None:
470
+ raise HTTPException(status_code=404, detail="Audio file not accessible")
471
+
472
+ handler.close()
473
+
474
+ # Guess media type based on extension (simple)
475
+ media_type = "audio/" + audio_path.suffix.lstrip(".")
476
+
477
+ return FileResponse(
478
+ path=audio_path,
479
+ media_type=media_type,
480
+ filename=audio_path.name
481
+ )
482
+
483
+ @router.get("/list_original_audios", tags=["Media Manager"])
484
+ def list_all_audios(
485
+ token: str = Query(..., description="Token required for authorization")
486
+ ):
487
+ """
488
+ List all audio files stored under /data/media.
489
+
490
+ For each SHA1 folder, the endpoint returns:
491
+ - sha1: folder name
492
+ - audio_files: list of audio files inside /audio
493
+ - latest_audio: the most recently modified audio file
494
+ - audio_count: total number of audio files
495
+
496
+ Notes:
497
+ - Folders may not have an /audio folder.
498
+ - SHA1 folders without audio files are still returned.
499
+ """
500
+ validate_token(token)
501
+
502
+ results = []
503
+
504
+ MEDIA_ROOT = Path("/data/media")
505
+ AUDIO_EXTENSIONS = ["*.mp3", "*.wav", "*.aac", "*.m4a", "*.ogg", "*.flac"]
506
+
507
+ # If media root does not exist, return empty list
508
+ if not MEDIA_ROOT.exists():
509
+ return []
510
+
511
+ for sha1_dir in MEDIA_ROOT.iterdir():
512
+ if not sha1_dir.is_dir():
513
+ continue # skip non-folders
514
+
515
+ audio_dir = sha1_dir / "audio"
516
+
517
+ audio_files = []
518
+ latest_audio = None
519
+
520
+ if audio_dir.exists() and audio_dir.is_dir():
521
+ # Collect all audio files with supported extensions
522
+ files = []
523
+ for pattern in AUDIO_EXTENSIONS:
524
+ files.extend(list(audio_dir.glob(pattern)))
525
+
526
+ # Sort by modification time (newest first)
527
+ files.sort(key=lambda f: f.stat().st_mtime, reverse=True)
528
+
529
+ audio_files = [f.name for f in files]
530
+
531
+ if files:
532
+ latest_audio = files[0].name
533
+
534
+ results.append({
535
+ "sha1": sha1_dir.name,
536
+ "audio_name": latest_audio,
537
+ })
538
+
539
+ return results