Skip to content

Commit 6ca099c

Browse files
authored
Merge pull request #100 from crux-bphc/fix-handle-changed
fix(backend): resolve historic handles issues
2 parents 8604e3d + aea6d3a commit 6ca099c

4 files changed

Lines changed: 53 additions & 2 deletions

File tree

backend/src/codeforces_api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ export async function verifySubmission(
6868
export async function linkCfHandle(cfHandle: string, userId: string) {
6969
try {
7070
const res = await fetch(
71-
`https://codeforces.com/api/user.info?handles=${cfHandle}`
71+
`https://codeforces.com/api/user.info?handles=${cfHandle}&checkHistoricHandles=true`
7272
);
7373
const fetchedUser = await res.json();
7474
if (fetchedUser.status === "OK") {
7575
const userData = fetchedUser.result[0] as User;
7676
const [linkedUser] = await db
7777
.update(users)
7878
.set({
79-
cfHandle: cfHandle,
79+
cfHandle: userData.handle,
8080
cfRating: userData.rating,
8181
})
8282
.where(eq(users.id, userId))

backend/src/controllers/codeforces.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,31 @@ export async function fetchUserSubmissions(
119119
`Enqueued fetchUserSubmissions job for ${cfHandle} (Priority: ${priority})`
120120
);
121121
}
122+
123+
export async function refreshHistoricHandles(priority: number = 5) {
124+
const dateKey = new Date().toISOString().slice(0, 10);
125+
const userData = await db
126+
.select({
127+
cfHandle: users.cfHandle,
128+
userId: users.id,
129+
})
130+
.from(users);
131+
132+
for (const user of userData) {
133+
if (!user.cfHandle || !user.userId) continue;
134+
135+
await addWithRetry(
136+
codeforcesQueue,
137+
"cf-job",
138+
{
139+
type: "user.resolveHandle",
140+
handle: user.cfHandle,
141+
userId: user.userId,
142+
},
143+
{
144+
priority,
145+
jobId: `${user.userId}-ResolveHandle-${dateKey}`,
146+
}
147+
);
148+
}
149+
}

backend/src/cron.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ import {
44
fetchProblems,
55
fetchSubmissions,
66
fetchRatingChanges,
7+
refreshHistoricHandles,
78
} from "./controllers/codeforces";
89

10+
function isDec21ToJan11UTC(d: Date) {
11+
const month = d.getUTCMonth() + 1;
12+
const day = d.getUTCDate();
13+
14+
return (month === 12 && day >= 21) || (month === 1 && day <= 11);
15+
}
16+
917
export function startCronJobs() {
1018
cron.schedule("0 */2 * * *", async () => {
1119
console.log(
@@ -26,4 +34,14 @@ export function startCronJobs() {
2634
);
2735
await fetchRatingChanges();
2836
});
37+
38+
cron.schedule("0 0 * * *", async () => {
39+
const now = new Date();
40+
if (!isDec21ToJan11UTC(now)) return;
41+
42+
console.log(
43+
`[Cron] Refreshing historic CF handles at ${now.toISOString()}`
44+
);
45+
await refreshHistoricHandles();
46+
});
2947
}

backend/src/workers/codeforcesWorker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
updateProblems,
1111
updateUserRatings,
1212
} from "../utils/dbHelpers";
13+
import { linkCfHandle } from "../codeforces_api";
1314

1415
//Keep track of problem key to problem id relations in local map
1516
//Problem key is contestId-problemIndex, like 2323-B, 122-C, etc.
@@ -45,6 +46,10 @@ async function init() {
4546
url = `https://codeforces.com/api/user.rating?handle=${handle}`;
4647
} else if (type === "user.submissions") {
4748
url = `https://codeforces.com/api/user.status?handle=${handle}`;
49+
} else if (type === "user.resolveHandle") {
50+
//This returns unlike the other ones as the url logic is already handled in linkCfHandle() function itself so I'm just calling the function directly.
51+
await linkCfHandle(handle, userId);
52+
return;
4853
} else if (type === "problemset.problems") {
4954
url = `https://codeforces.com/api/problemset.problems`;
5055
} else if (type === "contest.list") {

0 commit comments

Comments
 (0)