vargha commited on
Commit
6cf928e
·
1 Parent(s): b21ba3c

progress tracking

Browse files
Files changed (1) hide show
  1. utils/user_progress.py +149 -0
utils/user_progress.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ User Progress Management Utilities
3
+ Handles tracking and resuming review progress for Phase 2 reviewers
4
+ """
5
+
6
+ from datetime import datetime
7
+ from sqlalchemy.orm import Session
8
+ from sqlalchemy import func, and_
9
+
10
+ from data.models import UserProgress, Annotation, Annotator, Validation
11
+ from utils.logger import get_logger
12
+
13
+ log = get_logger(__name__)
14
+
15
+
16
+ def get_user_progress(db: Session, user_id: int, target_annotator_id: int) -> UserProgress:
17
+ """Get or create a progress record for the user reviewing the target annotator"""
18
+ progress = db.query(UserProgress).filter(
19
+ and_(
20
+ UserProgress.user_id == user_id,
21
+ UserProgress.target_annotator_id == target_annotator_id
22
+ )
23
+ ).first()
24
+
25
+ if not progress:
26
+ # Create new progress record
27
+ progress = UserProgress(
28
+ user_id=user_id,
29
+ target_annotator_id=target_annotator_id,
30
+ last_reviewed_annotation_id=None,
31
+ last_position=0,
32
+ updated_at=datetime.now()
33
+ )
34
+ db.add(progress)
35
+ db.commit()
36
+ log.info(f"Created new progress record for user {user_id} reviewing annotator {target_annotator_id}")
37
+
38
+ return progress
39
+
40
+
41
+ def update_user_progress(db: Session, user_id: int, target_annotator_id: int, annotation_id: int, position: int):
42
+ """Update user progress after they review an annotation"""
43
+ progress = get_user_progress(db, user_id, target_annotator_id)
44
+
45
+ progress.last_reviewed_annotation_id = annotation_id
46
+ progress.last_position = position
47
+ progress.updated_at = datetime.now()
48
+
49
+ db.commit()
50
+ log.info(f"Updated progress for user {user_id}: annotation {annotation_id} at position {position}")
51
+
52
+
53
+ def get_next_unreviewed_annotation(db: Session, user_id: int, target_annotator_id: int):
54
+ """Find the next annotation that needs to be reviewed by this user"""
55
+
56
+ # Get all annotations for the target annotator that haven't been reviewed by this user
57
+ unreviewed_query = db.query(Annotation).filter(
58
+ Annotation.annotator_id == target_annotator_id
59
+ ).outerjoin(
60
+ Validation,
61
+ and_(
62
+ Validation.annotation_id == Annotation.id,
63
+ Validation.validator_id == user_id
64
+ )
65
+ ).filter(
66
+ Validation.id.is_(None) # No validation record means not reviewed
67
+ ).order_by(Annotation.id)
68
+
69
+ first_unreviewed = unreviewed_query.first()
70
+
71
+ if first_unreviewed:
72
+ # Calculate the position of this annotation in the full list
73
+ position = db.query(Annotation).filter(
74
+ and_(
75
+ Annotation.annotator_id == target_annotator_id,
76
+ Annotation.id <= first_unreviewed.id
77
+ )
78
+ ).count() - 1 # Convert to 0-based index
79
+
80
+ return first_unreviewed.id, position
81
+ else:
82
+ # All annotations have been reviewed, return the last position
83
+ total_count = db.query(Annotation).filter(
84
+ Annotation.annotator_id == target_annotator_id
85
+ ).count()
86
+
87
+ return None, max(0, total_count - 1)
88
+
89
+
90
+ def get_last_reviewed_position(db: Session, user_id: int, target_annotator_id: int) -> int:
91
+ """Get the last position this user reviewed"""
92
+ progress = get_user_progress(db, user_id, target_annotator_id)
93
+ return progress.last_position
94
+
95
+
96
+ def get_annotations_from_position(db: Session, target_annotator_id: int, start_position: int, batch_size: int = 10):
97
+ """Load annotations starting from a specific position"""
98
+
99
+ annotations_query = db.query(
100
+ Annotation
101
+ ).join(
102
+ Annotation.tts_data
103
+ ).filter(
104
+ Annotation.annotator_id == target_annotator_id
105
+ ).order_by(Annotation.id).offset(start_position).limit(batch_size)
106
+
107
+ return annotations_query.all()
108
+
109
+
110
+ def get_review_summary(db: Session, user_id: int, target_annotator_id: int):
111
+ """Get a summary of review progress"""
112
+
113
+ # Total annotations for target annotator
114
+ total_count = db.query(Annotation).filter(
115
+ Annotation.annotator_id == target_annotator_id
116
+ ).count()
117
+
118
+ # Reviewed count by this user
119
+ reviewed_count = db.query(Annotation).join(
120
+ Validation, Annotation.id == Validation.annotation_id
121
+ ).filter(
122
+ and_(
123
+ Annotation.annotator_id == target_annotator_id,
124
+ Validation.validator_id == user_id
125
+ )
126
+ ).count()
127
+
128
+ # Approved count
129
+ approved_count = db.query(Annotation).join(
130
+ Validation, Annotation.id == Validation.annotation_id
131
+ ).filter(
132
+ and_(
133
+ Annotation.annotator_id == target_annotator_id,
134
+ Validation.validator_id == user_id,
135
+ Validation.validated == True
136
+ )
137
+ ).count()
138
+
139
+ # Rejected count
140
+ rejected_count = reviewed_count - approved_count
141
+
142
+ return {
143
+ "total": total_count,
144
+ "reviewed": reviewed_count,
145
+ "approved": approved_count,
146
+ "rejected": rejected_count,
147
+ "remaining": total_count - reviewed_count,
148
+ "progress_percentage": (reviewed_count / total_count * 100) if total_count > 0 else 0
149
+ }