0.9.9
parent
33ac56aec1
commit
155eb06f8a
|
|
@ -1327,8 +1327,8 @@ class DownloadPositionRequest(BaseModel):
|
|||
dates: list[str] # List of dates in YYYY-MM-DD format
|
||||
|
||||
|
||||
@router.post("/positions/download")
|
||||
async def download_positions(
|
||||
@router.post("/positions/download-async")
|
||||
async def download_positions_async(
|
||||
request: DownloadPositionRequest,
|
||||
background_tasks: BackgroundTasks,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
|
|
@ -1359,6 +1359,141 @@ async def download_positions(
|
|||
}
|
||||
|
||||
|
||||
@router.post("/positions/download")
|
||||
async def download_positions(
|
||||
request: DownloadPositionRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Download position data for specified bodies on specified dates (Synchronous)
|
||||
|
||||
This endpoint will:
|
||||
1. Query NASA Horizons API for the position at 00:00:00 UTC on each date
|
||||
2. Save the data to the positions table
|
||||
3. Return the downloaded data
|
||||
|
||||
Args:
|
||||
- body_ids: List of celestial body IDs
|
||||
- dates: List of dates (YYYY-MM-DD format)
|
||||
|
||||
Returns:
|
||||
- Summary of downloaded data with success/failure status
|
||||
"""
|
||||
logger.info(f"Downloading positions (sync) for {len(request.body_ids)} bodies on {len(request.dates)} dates")
|
||||
|
||||
try:
|
||||
results = []
|
||||
total_success = 0
|
||||
total_failed = 0
|
||||
|
||||
for body_id in request.body_ids:
|
||||
# Check if body exists
|
||||
body = await celestial_body_service.get_body_by_id(body_id, db)
|
||||
if not body:
|
||||
results.append({
|
||||
"body_id": body_id,
|
||||
"status": "failed",
|
||||
"error": "Body not found"
|
||||
})
|
||||
total_failed += 1
|
||||
continue
|
||||
|
||||
body_results = {
|
||||
"body_id": body_id,
|
||||
"body_name": body.name_zh or body.name,
|
||||
"dates": []
|
||||
}
|
||||
|
||||
for date_str in request.dates:
|
||||
try:
|
||||
# Parse date and set to midnight UTC
|
||||
target_date = datetime.strptime(date_str, "%Y-%m-%d")
|
||||
|
||||
# Check if data already exists for this date
|
||||
existing = await position_service.get_positions(
|
||||
body_id=body_id,
|
||||
start_time=target_date,
|
||||
end_time=target_date.replace(hour=23, minute=59, second=59),
|
||||
session=db
|
||||
)
|
||||
|
||||
if existing and len(existing) > 0:
|
||||
body_results["dates"].append({
|
||||
"date": date_str,
|
||||
"status": "exists",
|
||||
"message": "Data already exists"
|
||||
})
|
||||
total_success += 1
|
||||
continue
|
||||
|
||||
# Download from NASA Horizons
|
||||
positions = horizons_service.get_body_positions(
|
||||
body_id=body_id,
|
||||
start_time=target_date,
|
||||
end_time=target_date,
|
||||
step="1d"
|
||||
)
|
||||
|
||||
if positions and len(positions) > 0:
|
||||
# Save to database
|
||||
position_data = [{
|
||||
"time": target_date,
|
||||
"x": positions[0].x,
|
||||
"y": positions[0].y,
|
||||
"z": positions[0].z,
|
||||
"vx": getattr(positions[0], 'vx', None),
|
||||
"vy": getattr(positions[0], 'vy', None),
|
||||
"vz": getattr(positions[0], 'vz', None),
|
||||
}]
|
||||
|
||||
await position_service.save_positions(
|
||||
body_id=body_id,
|
||||
positions=position_data,
|
||||
source="nasa_horizons",
|
||||
session=db
|
||||
)
|
||||
|
||||
body_results["dates"].append({
|
||||
"date": date_str,
|
||||
"status": "success",
|
||||
"position": {
|
||||
"x": positions[0].x,
|
||||
"y": positions[0].y,
|
||||
"z": positions[0].z
|
||||
}
|
||||
})
|
||||
total_success += 1
|
||||
else:
|
||||
body_results["dates"].append({
|
||||
"date": date_str,
|
||||
"status": "failed",
|
||||
"error": "No data returned from NASA"
|
||||
})
|
||||
total_failed += 1
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to download {body_id} on {date_str}: {e}")
|
||||
body_results["dates"].append({
|
||||
"date": date_str,
|
||||
"status": "failed",
|
||||
"error": str(e)
|
||||
})
|
||||
total_failed += 1
|
||||
|
||||
results.append(body_results)
|
||||
|
||||
return {
|
||||
"message": f"Downloaded {total_success} positions ({total_failed} failed)",
|
||||
"total_success": total_success,
|
||||
"total_failed": total_failed,
|
||||
"results": results
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Download failed: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.get("/tasks")
|
||||
async def list_tasks(
|
||||
limit: int = 20,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
-- Insert Tasks menu if it doesn't exist
|
||||
INSERT INTO menus (name, title, icon, path, component, parent_id, sort_order, is_active)
|
||||
SELECT 'system_tasks', 'System Tasks', 'schedule', '/admin/tasks', 'admin/Tasks', m.id, 30, true
|
||||
FROM menus m
|
||||
WHERE m.name = 'platform_management'
|
||||
AND NOT EXISTS (SELECT 1 FROM menus WHERE name = 'system_tasks' AND parent_id = m.id);
|
||||
|
||||
-- Assign to admin role
|
||||
INSERT INTO role_menus (role_id, menu_id, created_at)
|
||||
SELECT r.id, m.id, NOW()
|
||||
FROM roles r, menus m
|
||||
WHERE r.name = 'admin' AND m.name = 'system_tasks'
|
||||
AND NOT EXISTS (SELECT 1 FROM role_menus rm WHERE rm.role_id = r.id AND rm.menu_id = m.id);
|
||||
Loading…
Reference in New Issue