**Commit Message:**
Enhance app with active pgroup handling and token updates Added active pgroup state management across the app for user-specific settings. Improved token handling with decoding, saving user data, and setting OpenAPI authorization. Updated components, API calls, and forms to support dynamic pgroup selection and user-specific features.
This commit is contained in:
@ -7,7 +7,6 @@ import shutil
|
||||
from app.schemas import (
|
||||
Puck as PuckSchema,
|
||||
Sample as SampleSchema,
|
||||
SampleEventResponse,
|
||||
SampleEventCreate,
|
||||
Sample,
|
||||
)
|
||||
@ -90,106 +89,69 @@ async def create_sample_event(
|
||||
return sample # Return the sample, now including `mount_count`
|
||||
|
||||
|
||||
# Route to fetch the last (most recent) sample event
|
||||
@router.get("/samples/{sample_id}/events/last", response_model=SampleEventResponse)
|
||||
async def get_last_sample_event(sample_id: int, db: Session = Depends(get_db)):
|
||||
# Ensure the sample exists
|
||||
sample = db.query(SampleModel).filter(SampleModel.id == sample_id).first()
|
||||
if not sample:
|
||||
raise HTTPException(status_code=404, detail="Sample not found")
|
||||
|
||||
# Get the most recent event for the sample
|
||||
last_event = (
|
||||
db.query(SampleEventModel)
|
||||
.filter(SampleEventModel.sample_id == sample_id)
|
||||
.order_by(SampleEventModel.timestamp.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
if not last_event:
|
||||
raise HTTPException(status_code=404, detail="No events found for the sample")
|
||||
|
||||
return SampleEventResponse(
|
||||
id=last_event.id,
|
||||
sample_id=last_event.sample_id,
|
||||
event_type=last_event.event_type,
|
||||
timestamp=last_event.timestamp,
|
||||
) # Response will automatically use the SampleEventResponse schema
|
||||
|
||||
|
||||
@router.post("/samples/{sample_id}/upload-images")
|
||||
async def upload_sample_images(
|
||||
sample_id: int,
|
||||
uploaded_files: List[UploadFile] = File(...), # Accept multiple files
|
||||
uploaded_files: list[UploadFile] = File(...),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Uploads images for a sample and stores them in a directory structure:
|
||||
images/user/date/dewar_name/puck_name/position/.
|
||||
logging.info(f"Received files: {[file.filename for file in uploaded_files]}")
|
||||
|
||||
"""
|
||||
Uploads images for a given sample and saves them to a directory structure.
|
||||
Args:
|
||||
sample_id (int): ID of the sample.
|
||||
uploaded_files (List[UploadFile]): List of image files to be uploaded.
|
||||
db (Session): SQLAlchemy database session.
|
||||
uploaded_files (list[UploadFile]): A list of files uploaded with the request.
|
||||
db (Session): Database session.
|
||||
"""
|
||||
# Fetch sample details from the database
|
||||
|
||||
# 1. Validate Sample
|
||||
sample = db.query(SampleModel).filter(SampleModel.id == sample_id).first()
|
||||
if not sample:
|
||||
raise HTTPException(status_code=404, detail="Sample not found")
|
||||
|
||||
# Retrieve associated dewar_name, puck_name and position
|
||||
puck = sample.puck
|
||||
if not puck:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"No puck associated with sample ID {sample_id}"
|
||||
)
|
||||
|
||||
dewar_name = puck.dewar.dewar_name if puck.dewar else None
|
||||
if not dewar_name:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"No dewar associated with puck ID {puck.id}"
|
||||
)
|
||||
|
||||
puck_name = puck.puck_name
|
||||
position = sample.position
|
||||
|
||||
# Retrieve username (hardcoded for now—can be fetched dynamically if needed)
|
||||
username = "e16371"
|
||||
|
||||
# Today's date in the format YYYY-MM-DD
|
||||
# 2. Define Directory Structure
|
||||
username = "e16371" # Hardcoded username; replace with dynamic logic if applicable
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
# Generate the directory path based on the structure
|
||||
base_dir = (
|
||||
Path("images") / username / today / dewar_name / puck_name / str(position)
|
||||
dewar_name = (
|
||||
sample.puck.dewar.dewar_name
|
||||
if sample.puck and sample.puck.dewar
|
||||
else "default_dewar"
|
||||
)
|
||||
|
||||
# Create directories if they don't exist
|
||||
puck_name = sample.puck.puck_name if sample.puck else "default_puck"
|
||||
position = sample.position if sample.position else "default_position"
|
||||
base_dir = Path(f"images/{username}/{today}/{dewar_name}/{puck_name}/{position}")
|
||||
base_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Save each uploaded image to the directory
|
||||
# 3. Process and Save Each File
|
||||
saved_files = []
|
||||
for file in uploaded_files:
|
||||
# Validate file content type
|
||||
# Validate MIME type
|
||||
if not file.content_type.startswith("image/"):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid file type: {file.filename}. Must be an image.",
|
||||
detail=f"Invalid file type: {file.filename}. Only images are accepted.",
|
||||
)
|
||||
|
||||
# Create a file path for storing the uploaded file
|
||||
# Save file to the base directory
|
||||
file_path = base_dir / file.filename
|
||||
|
||||
# Save the file from the file stream
|
||||
try:
|
||||
# Save the file
|
||||
with file_path.open("wb") as buffer:
|
||||
shutil.copyfileobj(file.file, buffer)
|
||||
saved_files.append(str(file_path)) # Track saved file paths
|
||||
except Exception as e:
|
||||
logging.error(f"Error saving file {file.filename}: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Error saving file {file.filename}: {str(e)}",
|
||||
detail=f"Could not save file {file.filename}."
|
||||
f" Ensure the server has correct permissions.",
|
||||
)
|
||||
|
||||
# 4. Return Saved Files Information
|
||||
logging.info(f"Uploaded {len(saved_files)} files for sample {sample_id}.")
|
||||
return {
|
||||
"message": f"{len(uploaded_files)} images uploaded successfully.",
|
||||
"path": str(base_dir), # Return the base directory for reference
|
||||
"message": f"{len(saved_files)} images uploaded successfully.",
|
||||
"files": saved_files,
|
||||
}
|
||||
|
Reference in New Issue
Block a user