Skip to content

Commit d2e2f7c

Browse files
authored
Merge pull request #73 from Khushal928/praveshan
remove submitted_late, reference_link and resolve merge issues with alembic
2 parents f2b0255 + c63ff55 commit d2e2f7c

File tree

6 files changed

+104
-83
lines changed

6 files changed

+104
-83
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
"""Create initial tables
1+
"""remove reference_link from submissions
22
3-
Revision ID: b54e3fce90a9
4-
Revises: 12599f674ee9
5-
Create Date: 2025-08-02 00:29:32.968656
3+
Revision ID: 40774b92ab4a
4+
Revises: 8f84ff4de4af
5+
Create Date: 2025-08-05 09:27:59.401932
66
77
"""
88
from typing import Sequence, Union
@@ -12,21 +12,21 @@
1212

1313

1414
# revision identifiers, used by Alembic.
15-
revision: str = 'b54e3fce90a9'
16-
down_revision: Union[str, None] = '12599f674ee9'
15+
revision: str = '40774b92ab4a'
16+
down_revision: Union[str, None] = '8f84ff4de4af'
1717
branch_labels: Union[str, Sequence[str], None] = None
1818
depends_on: Union[str, Sequence[str], None] = None
1919

2020

2121
def upgrade() -> None:
2222
"""Upgrade schema."""
2323
# ### commands auto generated by Alembic - please adjust! ###
24-
pass
24+
op.drop_column('submissions', 'reference_link')
2525
# ### end Alembic commands ###
2626

2727

2828
def downgrade() -> None:
2929
"""Downgrade schema."""
3030
# ### commands auto generated by Alembic - please adjust! ###
31-
pass
31+
op.add_column('submissions', sa.Column('reference_link', sa.TEXT(), autoincrement=False, nullable=False))
3232
# ### end Alembic commands ###
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""remove submitted_late
2+
3+
Revision ID: 8f84ff4de4af
4+
Revises: 12599f674ee9
5+
Create Date: 2025-07-30 06:27:06.564253
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = '8f84ff4de4af'
16+
down_revision: Union[str, None] = '12599f674ee9'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
op.drop_column('submissions', 'submitted_late')
24+
25+
26+
def downgrade() -> None:
27+
"""Downgrade schema."""
28+
op.add_column('your_table_name', sa.Column('submitted_late', sa.Boolean(), default=False))

app/db/crud.py

Lines changed: 66 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,86 @@
1-
import os
2-
import json
3-
import gspread
41
from typing import Optional
52
from app.schemas.submission import SubmissionOut
6-
from sqlalchemy.orm import Session
3+
from sqlalchemy.orm import Session,joinedload
74
from app.db import models
8-
from datetime import datetime, date, timedelta
5+
from datetime import date, timedelta
96
from sqlalchemy import func
107
from app.db.db import SessionLocal
8+
import gspread
9+
from oauth2client.service_account import ServiceAccountCredentials
10+
import os
1111

12-
def _get_gspread_client():
13-
creds_json_str = os.getenv("GOOGLE_CREDENTIALS_JSON")
14-
if not creds_json_str:
15-
raise ValueError("GOOGLE_CREDENTIALS_JSON environment variable is not set.")
16-
17-
creds_info = json.loads(creds_json_str)
18-
client = gspread.service_account_from_dict(creds_info)
19-
return client
12+
SCOPE = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
13+
CREDS_FILE = "credentials.json"
2014

2115
def get_user_by_email(db: Session, email: str):
2216
return db.query(models.User).filter(models.User.email == email).first()
2317

2418
def get_task(db: Session, track_id: int, task_no: int):
2519
return db.query(models.Task).filter_by(track_id=track_id, task_no=task_no).first()
2620

27-
def submit_task(db: Session, mentee_id: int, task_id: int, reference_link: str, start_date: date, commit_hash: str):
21+
def submit_task(db: Session, mentee_id: int, task_id: int, start_date: date, commit_hash: str):
2822
existing = db.query(models.Submission).filter_by(mentee_id=mentee_id, task_id=task_id).first()
2923
if existing:
30-
return None
24+
return None # Already submitted
3125

3226
mentee = db.query(models.User).filter(models.User.id == mentee_id).first()
27+
3328
task = db.query(models.Task).filter(models.Task.id == task_id).first()
3429
if not task:
3530
raise Exception("Task not found")
3631

37-
start_date = datetime.combine(start_date, datetime.min.time())
32+
# convert start_date into a datetime object
33+
start_date = start_date
3834
deadline = start_date + timedelta(days=task.deadline_days)
39-
submitted_at = datetime.now()
35+
submitted_at = date.today()
4036

37+
# Check if the submission is late
4138
if deadline >= submitted_at:
42-
submitted_late = False
43-
elif deadline + timedelta(hours=12) >= submitted_at:
44-
submitted_late = True
45-
else:
46-
return "late submission not allowed"
47-
48-
submission = models.Submission(
49-
mentee_id=mentee_id,
50-
task_id=task.id,
51-
task_name=task.title,
52-
task_no=task.task_no,
53-
reference_link=reference_link,
54-
submitted_at=date.today(),
55-
status="submitted",
56-
start_date=start_date,
57-
submitted_late=submitted_late,
58-
commit_hash=commit_hash
59-
)
39+
submission = models.Submission(
40+
mentee_id=mentee_id,
41+
task_id=task.id,
42+
task_name=task.title,
43+
task_no=task.task_no,
44+
submitted_at=date.today(),
45+
status="submitted",
46+
start_date=start_date,
47+
commit_hash = commit_hash
48+
)
6049

61-
client = _get_gspread_client()
62-
sheet_name = "Copy of Praveshan 2025 Master DB"
63-
64-
if task.track_id == 1:
65-
worksheet_name = "S1 Submissions"
66-
elif task.track_id == 2:
67-
worksheet_name = "S2 Submissions"
50+
credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDS_FILE, SCOPE)
51+
client = gspread.authorize(credentials)
52+
if(task.track_id == 1):
53+
sheet = client.open("Copy of Praveshan 2025 Master DB").worksheet("S1 Submissions")
54+
cell = sheet.find(mentee.name)
55+
if not cell:
56+
name_column = sheet.col_values(1)
57+
row = len(name_column) + 1
58+
sheet.update_cell(row, 1, mentee.name)
59+
sheet.update_cell(row, task.task_no+2, commit_hash)
60+
else:
61+
row = cell.row
62+
sheet.update_cell(row, task.task_no+2, commit_hash)
63+
elif(task.track_id == 2):
64+
sheet = client.open("Copy of Praveshan 2025 Master DB").worksheet("S2 Submissions")
65+
cell = sheet.find(mentee.name)
66+
if not cell:
67+
name_column = sheet.col_values(1)
68+
row = len(name_column) + 1
69+
sheet.update_cell(row, 1, mentee.name)
70+
sheet.update_cell(row, task.task_no+2, commit_hash)
71+
else:
72+
row = cell.row
73+
sheet.update_cell(row, task.task_no+2, commit_hash)
74+
75+
76+
77+
db.add(submission)
78+
db.commit()
79+
db.refresh(submission)
80+
81+
return submission
6882
else:
69-
worksheet_name = None
70-
71-
if worksheet_name:
72-
sheet = client.open(sheet_name).worksheet(worksheet_name)
73-
cell = sheet.find(mentee.name)
74-
if not cell:
75-
row = len(sheet.col_values(1)) + 1
76-
sheet.update_cell(row, 1, mentee.name)
77-
sheet.update_cell(row, task.task_no + 2, commit_hash)
78-
else:
79-
row = cell.row
80-
sheet.update_cell(row, task.task_no + 2, commit_hash)
81-
82-
db.add(submission)
83-
db.commit()
84-
db.refresh(submission)
85-
86-
return submission
83+
return "late submission not allowed"
8784

8885
def approve_submission(db: Session, submission_id: int, mentor_feedback: str, status: str):
8986
sub = db.query(models.Submission).filter_by(id=submission_id).first()
@@ -103,6 +100,7 @@ def is_mentor_of(db: Session, mentor_id: int, mentee_id: int):
103100
return db.query(models.MentorMenteeMap).filter_by(mentor_id=mentor_id, mentee_id=mentee_id).first() is not None
104101

105102
def get_leaderboard_data(db: Session, track_id: int):
103+
106104
return (
107105
db.query(
108106
models.User.name,
@@ -117,7 +115,6 @@ def get_leaderboard_data(db: Session, track_id: int):
117115
.order_by(func.sum(models.Task.points).desc())
118116
.all()
119117
)
120-
121118
def get_otp_by_email(db, email):
122119
return db.query(models.OTP).filter(models.OTP.email == email).first()
123120

@@ -131,6 +128,7 @@ def create_or_update_otp(db, email, otp, expires_at):
131128
db.add(entry)
132129
db.commit()
133130

131+
134132
def get_submissions_for_user(db: Session, email: str, track_id: Optional[int] = None) -> list[SubmissionOut]:
135133
user = db.query(models.User).filter(models.User.email == email).first()
136134
if not user:
@@ -152,7 +150,6 @@ def get_submissions_for_user(db: Session, email: str, track_id: Optional[int] =
152150
task_id=sub.task_id,
153151
task_name=sub.task_name,
154152
task_no=sub.task_no,
155-
reference_link=sub.reference_link,
156153
status=sub.status,
157154
submitted_at=sub.submitted_at.date() if sub.submitted_at else None,
158155
approved_at=sub.approved_at.date() if sub.approved_at else None,
@@ -163,12 +160,9 @@ def get_submissions_for_user(db: Session, email: str, track_id: Optional[int] =
163160
]
164161

165162
def get_sheet_data():
166-
client = _get_gspread_client()
167-
sheet_id = os.getenv("GOOGLE_SHEET_ID")
168-
if not sheet_id:
169-
raise ValueError("GOOGLE_SHEET_ID environment variable not set.")
170-
171-
worksheet = client.open_by_key(sheet_id).worksheet("Form Responses")
163+
creds = ServiceAccountCredentials.from_json_keyfile_name(CREDS_FILE, SCOPE)
164+
client = gspread.authorize(creds)
165+
worksheet = client.open_by_key(os.getenv("GOOGLE_SHEET_ID")).worksheet("Praveshan Phase 3") # Change sheet name
172166
expected_headers = ["Name", "Email Address"]
173167
data = worksheet.get_all_records(expected_headers=expected_headers)
174168
return data
@@ -177,6 +171,7 @@ def sync_users_from_sheet():
177171
db: Session = SessionLocal()
178172
try:
179173
rows = get_sheet_data()
174+
print(f"Loaded {len(rows)} rows from sheet.")
180175
inserted_count = 0
181176
for row in rows:
182177
email = row.get("Email Address", "").strip()
@@ -190,5 +185,8 @@ def sync_users_from_sheet():
190185
inserted_count += 1
191186

192187
db.commit()
188+
print(f"Inserted {inserted_count} new users.")
189+
except Exception as e:
190+
print(f"Error syncing users: {e}")
193191
finally:
194192
db.close()

app/db/models.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@ class Submission(Base):
4040
task_id = Column(Integer, ForeignKey("tasks.id"), nullable=False)
4141
task_name = Column(String, nullable=False)
4242
task_no = Column(Integer, nullable=False)
43-
reference_link = Column(Text, nullable=False)
4443
status = Column(String, default="submitted") # submitted / approved / paused / rejected
4544
submitted_at = Column(DateTime, default=datetime.utcnow)
4645
start_date = Column(DateTime, nullable=False)
4746
approved_at = Column(DateTime, nullable=True)
4847
mentor_feedback = Column(Text, nullable=True)
49-
submitted_late = Column(Boolean, default=False)
5048
mentee = relationship("User")
5149
task = relationship("Task")
5250
commit_hash = Column(String, nullable=False)

app/routes/progress.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def submit_task(data: SubmissionCreate, db: Session = Depends(get_db)):
1919
raise HTTPException(status_code=404, detail="Task not found")
2020

2121
# 3. Submit
22-
submission = crud.submit_task(db, mentee_id=mentee.id, task_id=task.id, reference_link=data.reference_link, start_date=data.start_date, commit_hash=data.commit_hash)
22+
submission = crud.submit_task(db, mentee_id=mentee.id, task_id=task.id, start_date=data.start_date, commit_hash=data.commit_hash)
2323
if not submission:
2424
raise HTTPException(status_code=400, detail="Task already submitted")
2525
if submission == "late submission not allowed":

app/schemas/submission.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from pydantic import BaseModel
22
from typing import Optional
3-
from datetime import date,datetime
3+
from datetime import date
44

55
class SubmissionBase(BaseModel):
66
track_id: int
77
task_no: int
8-
reference_link: str
98
start_date: date
109
class SubmissionCreate(SubmissionBase):
1110
mentee_email: str
@@ -18,13 +17,11 @@ class SubmissionOut(BaseModel):
1817
task_id: int
1918
task_no: int
2019
task_name: str
21-
reference_link: str
2220
status: str
2321
submitted_at: date
2422
approved_at: Optional[date] = None
2523
mentor_feedback: Optional[str] = None
2624
start_date: date
27-
submitted_late: bool
2825
commit_hash: str
2926
class Config:
3027
orm_mode = True

0 commit comments

Comments
 (0)