Spaces:
Running
Running
""" | |
User Progress Management Utilities | |
Handles tracking and resuming review progress for Phase 2 reviewers | |
""" | |
from datetime import datetime | |
from sqlalchemy.orm import Session | |
from sqlalchemy import func, and_ | |
from data.models import UserProgress, Annotation, Annotator, Validation | |
from utils.logger import get_logger | |
log = get_logger(__name__) | |
def get_user_progress(db: Session, user_id: int, target_annotator_id: int) -> UserProgress: | |
"""Get or create a progress record for the user reviewing the target annotator""" | |
progress = db.query(UserProgress).filter( | |
and_( | |
UserProgress.user_id == user_id, | |
UserProgress.target_annotator_id == target_annotator_id | |
) | |
).first() | |
if not progress: | |
# Create new progress record | |
progress = UserProgress( | |
user_id=user_id, | |
target_annotator_id=target_annotator_id, | |
last_reviewed_annotation_id=None, | |
last_position=0, | |
updated_at=datetime.now() | |
) | |
db.add(progress) | |
db.commit() | |
log.info(f"Created new progress record for user {user_id} reviewing annotator {target_annotator_id}") | |
return progress | |
def update_user_progress(db: Session, user_id: int, target_annotator_id: int, annotation_id: int, position: int): | |
"""Update user progress after they review an annotation""" | |
progress = get_user_progress(db, user_id, target_annotator_id) | |
progress.last_reviewed_annotation_id = annotation_id | |
progress.last_position = position | |
progress.updated_at = datetime.now() | |
db.commit() | |
log.info(f"Updated progress for user {user_id}: annotation {annotation_id} at position {position}") | |
def get_next_unreviewed_annotation(db: Session, user_id: int, target_annotator_id: int): | |
"""Find the next annotation that needs to be reviewed by this user""" | |
# Get all annotations for the target annotator that haven't been reviewed by this user | |
unreviewed_query = db.query(Annotation).filter( | |
Annotation.annotator_id == target_annotator_id | |
).outerjoin( | |
Validation, | |
and_( | |
Validation.annotation_id == Annotation.id, | |
Validation.validator_id == user_id | |
) | |
).filter( | |
Validation.id.is_(None) # No validation record means not reviewed | |
).order_by(Annotation.id) | |
first_unreviewed = unreviewed_query.first() | |
if first_unreviewed: | |
# Calculate the position of this annotation in the full list | |
position = db.query(Annotation).filter( | |
and_( | |
Annotation.annotator_id == target_annotator_id, | |
Annotation.id <= first_unreviewed.id | |
) | |
).count() - 1 # Convert to 0-based index | |
return first_unreviewed.id, position | |
else: | |
# All annotations have been reviewed, return the last position | |
total_count = db.query(Annotation).filter( | |
Annotation.annotator_id == target_annotator_id | |
).count() | |
return None, max(0, total_count - 1) | |
def get_last_reviewed_position(db: Session, user_id: int, target_annotator_id: int) -> int: | |
"""Get the last position this user reviewed""" | |
progress = get_user_progress(db, user_id, target_annotator_id) | |
return progress.last_position | |
def get_annotations_from_position(db: Session, target_annotator_id: int, start_position: int, batch_size: int = 10): | |
"""Load annotations starting from a specific position""" | |
annotations_query = db.query( | |
Annotation | |
).join( | |
Annotation.tts_data | |
).filter( | |
Annotation.annotator_id == target_annotator_id | |
).order_by(Annotation.id).offset(start_position).limit(batch_size) | |
return annotations_query.all() | |
def get_review_summary(db: Session, user_id: int, target_annotator_id: int): | |
"""Get a summary of review progress""" | |
# Total annotations for target annotator | |
total_count = db.query(Annotation).filter( | |
Annotation.annotator_id == target_annotator_id | |
).count() | |
# Reviewed count by this user | |
reviewed_count = db.query(Annotation).join( | |
Validation, Annotation.id == Validation.annotation_id | |
).filter( | |
and_( | |
Annotation.annotator_id == target_annotator_id, | |
Validation.validator_id == user_id | |
) | |
).count() | |
# Approved count | |
approved_count = db.query(Annotation).join( | |
Validation, Annotation.id == Validation.annotation_id | |
).filter( | |
and_( | |
Annotation.annotator_id == target_annotator_id, | |
Validation.validator_id == user_id, | |
Validation.validated == True | |
) | |
).count() | |
# Rejected count | |
rejected_count = reviewed_count - approved_count | |
return { | |
"total": total_count, | |
"reviewed": reviewed_count, | |
"approved": approved_count, | |
"rejected": rejected_count, | |
"remaining": total_count - reviewed_count, | |
"progress_percentage": (reviewed_count / total_count * 100) if total_count > 0 else 0 | |
} | |