Fix video playback for files in root directory
- Handle __root__ special case in video streaming and image endpoints - Support locations with files not organized by date folders - Add visual indicator for root-level file collections in UI
This commit is contained in:
@@ -176,6 +176,8 @@ async def get_dates(location: str) -> List[Dict]:
|
||||
raise HTTPException(status_code=404, detail="Location not found")
|
||||
|
||||
dates = []
|
||||
has_files_in_root = False
|
||||
|
||||
for item in location_path.iterdir():
|
||||
if item.is_dir():
|
||||
stat = await aiofiles.os.stat(item)
|
||||
@@ -183,6 +185,16 @@ async def get_dates(location: str) -> List[Dict]:
|
||||
"name": item.name,
|
||||
"modified": datetime.fromtimestamp(stat.st_mtime).isoformat()
|
||||
})
|
||||
elif item.is_file():
|
||||
has_files_in_root = True
|
||||
|
||||
# If no date folders but has files in root, return special marker
|
||||
if not dates and has_files_in_root:
|
||||
dates.append({
|
||||
"name": "__root__",
|
||||
"modified": None,
|
||||
"message": "📁 Files not organized by date"
|
||||
})
|
||||
|
||||
# Cache the result
|
||||
directory_cache.set(cache_key, dates)
|
||||
@@ -202,7 +214,11 @@ async def get_files(location: str, date: str) -> List[Dict]:
|
||||
if ".." in location or ".." in date or "/" in location or "/" in date:
|
||||
raise HTTPException(status_code=400, detail="Invalid path characters")
|
||||
|
||||
files_path = (FOOTAGES_PATH / location / date).resolve()
|
||||
# Handle special __root__ marker for locations with files in root
|
||||
if date == "__root__":
|
||||
files_path = (FOOTAGES_PATH / location).resolve()
|
||||
else:
|
||||
files_path = (FOOTAGES_PATH / location / date).resolve()
|
||||
|
||||
# Ensure resolved path is still within FOOTAGES_PATH
|
||||
try:
|
||||
@@ -230,7 +246,11 @@ async def stream_video(location: str, date: str, filename: str, request: Request
|
||||
if ".." in location or ".." in date or ".." in filename or "/" in location or "/" in date:
|
||||
raise HTTPException(status_code=400, detail="Invalid path characters")
|
||||
|
||||
file_path = (FOOTAGES_PATH / location / date / filename).resolve()
|
||||
# Handle __root__ case (files not in date subdirectories)
|
||||
if date == "__root__":
|
||||
file_path = (FOOTAGES_PATH / location / filename).resolve()
|
||||
else:
|
||||
file_path = (FOOTAGES_PATH / location / date / filename).resolve()
|
||||
|
||||
# Ensure resolved path is still within FOOTAGES_PATH
|
||||
try:
|
||||
@@ -304,7 +324,11 @@ async def get_image(location: str, date: str, filename: str):
|
||||
if ".." in location or ".." in date or ".." in filename or "/" in location or "/" in date:
|
||||
raise HTTPException(status_code=400, detail="Invalid path characters")
|
||||
|
||||
file_path = (FOOTAGES_PATH / location / date / filename).resolve()
|
||||
# Handle __root__ case (files not in date subdirectories)
|
||||
if date == "__root__":
|
||||
file_path = (FOOTAGES_PATH / location / filename).resolve()
|
||||
else:
|
||||
file_path = (FOOTAGES_PATH / location / date / filename).resolve()
|
||||
|
||||
# Ensure resolved path is still within FOOTAGES_PATH
|
||||
try:
|
||||
|
||||
@@ -409,15 +409,26 @@ function App() {
|
||||
<ul className="space-y-1">
|
||||
{getSortedDates().map((date) => {
|
||||
const dateName = date.name || date
|
||||
const isRootFiles = dateName === "__root__"
|
||||
const displayName = isRootFiles ? "All Files" : dateName
|
||||
const message = date.message || null
|
||||
|
||||
return (
|
||||
<li key={dateName}>
|
||||
<button
|
||||
onClick={() => handleDateClick(dateName)}
|
||||
className={`w-full text-left px-3 py-2 rounded hover:bg-blue-50 transition ${
|
||||
className={`w-full text-left px-3 py-2 rounded transition ${
|
||||
isRootFiles
|
||||
? 'bg-yellow-50 border border-yellow-200 hover:bg-yellow-100'
|
||||
: 'hover:bg-blue-50'
|
||||
} ${
|
||||
selectedDate === dateName ? 'bg-blue-100 font-semibold' : ''
|
||||
}`}
|
||||
>
|
||||
{dateName}
|
||||
<div className="font-medium">{displayName}</div>
|
||||
{message && (
|
||||
<div className="text-xs text-yellow-700 mt-1">{message}</div>
|
||||
)}
|
||||
</button>
|
||||
</li>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user