Skip to content

Commit 77e005d

Browse files
committed
feat : add new endpoint for global contests info
1 parent 2dcb9ea commit 77e005d

File tree

14 files changed

+304
-5
lines changed

14 files changed

+304
-5
lines changed

src/main/java/com/rajat_singh/leetcode_api/client/LeetCodeClient.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.ArrayList;
2323
import java.util.HashMap;
24+
import java.util.List;
2425
import java.util.Map;
2526

2627
import static com.rajat_singh.leetcode_api.graphql.GraphQlQueries.*;
@@ -284,4 +285,53 @@ public DailyCodingChallengeResponse fetchDailyCodingChallengeQuestions() {
284285
return restTemplate.postForObject(leetcodeApiUrl,entity,DailyCodingChallengeResponse.class);
285286
}
286287

288+
@RateLimiter(name = "leetcode-api")
289+
public List<ContestsDTO.ContestData> fetchAllPastContest() {
290+
291+
int pageNo = 1;
292+
int numPerPage = 10;
293+
294+
List<ContestsDTO.ContestData> combined = new ArrayList<>();
295+
296+
while (true) {
297+
ContestsDTO response = fetchPage(pageNo, numPerPage);
298+
299+
Logger.info("Fetched page {} of past contests", pageNo);
300+
301+
if (response == null || response.getData() == null) break;
302+
303+
List<ContestsDTO.ContestData> pageData = response.getData().getPastContests().getData();
304+
305+
if (pageData == null || pageData.isEmpty()) break;
306+
307+
combined.addAll(pageData);
308+
309+
int current = response.getData().getPastContests().getCurrentPage();
310+
int total = response.getData().getPastContests().getPageNum();
311+
312+
if (current >= total) break;
313+
314+
pageNo++;
315+
}
316+
317+
return combined;
318+
}
319+
320+
public ContestsDTO fetchPage(int pageNo, int numPerPage) {
321+
322+
HttpHeaders headers = new HttpHeaders();
323+
setHeader(headers);
324+
325+
Map<String, Object> requestBody = new HashMap<>();
326+
requestBody.put("query", FETCH_ALL_PAST_CONTESTS);
327+
requestBody.put("operationName", "pastContests");
328+
requestBody.put("variables", Map.of("pageNo", pageNo, "numPerPage", numPerPage));
329+
330+
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
331+
332+
return restTemplate.postForObject(leetcodeApiUrl, entity, ContestsDTO.class);
333+
}
334+
335+
336+
287337
}

src/main/java/com/rajat_singh/leetcode_api/constants/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ public class Constants {
55

66
public final static int DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;
77

8+
public final static long MONTH_IN_MILLISECONDS = 30 * 24 * 60 * 60 * 1000L;
9+
810
public final static String PROBLEM_URL_PREFIX = "https://leetcode.com/problems/";
911

1012
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.rajat_singh.leetcode_api.controller;
2+
3+
import com.rajat_singh.leetcode_api.dto.ContestDTO;
4+
import com.rajat_singh.leetcode_api.dto.ContestsDTO;
5+
import com.rajat_singh.leetcode_api.service.LeetCodeContestService;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springdoc.core.annotations.ParameterObject;
8+
import org.springframework.data.domain.Page;
9+
import org.springframework.data.domain.Pageable;
10+
import org.springframework.http.ResponseEntity;
11+
import org.springframework.web.bind.annotation.GetMapping;
12+
import org.springframework.web.bind.annotation.RequestMapping;
13+
import org.springframework.web.bind.annotation.RestController;
14+
import org.tinylog.Logger;
15+
16+
17+
@RestController
18+
@RequestMapping("/api/v1/globalContestInfo")
19+
@RequiredArgsConstructor
20+
public class GlobalContestInfoController {
21+
22+
private final LeetCodeContestService leetCodeContestService;
23+
24+
@GetMapping("/fetchContests")
25+
public ResponseEntity<Page<ContestDTO>> getContestsInfo(@ParameterObject Pageable pageable) {
26+
Logger.info("Fetching contests info");
27+
return ResponseEntity.ok(leetCodeContestService.getContestsInfo(pageable));
28+
}
29+
30+
}

src/main/java/com/rajat_singh/leetcode_api/controller/LeetCodeQuestionsController.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
public class LeetCodeQuestionsController {
2727

2828
private final LeetCodeQuestionsService leetCodeQuestionsService;
29+
/**
30+
* TODO: Migrate questionsRepo's logic inside leetCodeQuestionsService for clean controller
31+
*/
2932
private final QuestionsRepository questionsRepository;
3033
private final QuestionMapper questionMapper;
3134

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.rajat_singh.leetcode_api.dto;
2+
3+
import lombok.Data;
4+
import java.util.List;
5+
6+
@Data
7+
public class ContestDTO {
8+
private Long id;
9+
private String title;
10+
private String titleSlug;
11+
private long startTime;
12+
private long originStartTime;
13+
private String cardImg;
14+
private List<ContestsDTO.Sponsor> sponsors;
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.rajat_singh.leetcode_api.dto;
2+
3+
import lombok.Data;
4+
import java.util.List;
5+
6+
@Data
7+
public class ContestsDTO {
8+
9+
private ResponseData data;
10+
11+
@Data
12+
public static class ResponseData {
13+
private PastContests pastContests;
14+
}
15+
16+
@Data
17+
public static class PastContests {
18+
private int pageNum;
19+
private int currentPage;
20+
private int totalNum;
21+
private int numPerPage;
22+
private List<ContestData> data;
23+
}
24+
25+
@Data
26+
public static class ContestData {
27+
private String title;
28+
private String titleSlug;
29+
private long startTime;
30+
private long originStartTime;
31+
private String cardImg;
32+
private List<Sponsor> sponsors;
33+
}
34+
35+
@Data
36+
public static class Sponsor {
37+
private String name;
38+
private String lightLogo;
39+
private String darkLogo;
40+
}
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.rajat_singh.leetcode_api.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.Data;
5+
import java.util.List;
6+
7+
@Entity
8+
@Data
9+
@Table(name = "contest_data")
10+
public class ContestDataEntity {
11+
12+
@Id
13+
@GeneratedValue(strategy = GenerationType.IDENTITY)
14+
private Long id;
15+
16+
private String title;
17+
private String titleSlug;
18+
private long startTime;
19+
private long originStartTime;
20+
private String cardImg;
21+
22+
@OneToMany(mappedBy = "contestData", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
23+
private List<SponsorEntity> sponsors;
24+
}
25+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.rajat_singh.leetcode_api.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.Data;
5+
6+
@Entity
7+
@Data
8+
@Table(name = "sponsors")
9+
public class SponsorEntity {
10+
11+
@Id
12+
@GeneratedValue(strategy = GenerationType.IDENTITY)
13+
private Long id;
14+
15+
private String name;
16+
private String lightLogo;
17+
private String darkLogo;
18+
19+
@ManyToOne(fetch = FetchType.LAZY)
20+
@JoinColumn(name = "contest_id")
21+
private ContestDataEntity contestData;
22+
}

src/main/java/com/rajat_singh/leetcode_api/graphql/GraphQlQueries.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,5 +298,27 @@ query userProfileCalendar($username: String!, $year: Int) {
298298
}
299299
""";
300300

301+
public static final String FETCH_ALL_PAST_CONTESTS = """
302+
query pastContests($pageNo: Int, $numPerPage: Int) {
303+
pastContests(pageNo: $pageNo, numPerPage: $numPerPage) {
304+
pageNum
305+
currentPage
306+
totalNum
307+
numPerPage
308+
data {
309+
title
310+
titleSlug
311+
startTime
312+
originStartTime
313+
cardImg
314+
sponsors {
315+
name
316+
lightLogo
317+
darkLogo
318+
}
319+
}
320+
}
321+
}
322+
""";
301323

302324
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.rajat_singh.leetcode_api.mappers;
2+
3+
import com.rajat_singh.leetcode_api.dto.ContestDTO;
4+
import com.rajat_singh.leetcode_api.dto.ContestsDTO;
5+
import com.rajat_singh.leetcode_api.entity.ContestDataEntity;
6+
import com.rajat_singh.leetcode_api.entity.SponsorEntity;
7+
import org.mapstruct.Mapper;
8+
9+
import java.util.List;
10+
11+
@Mapper(componentModel = "spring")
12+
public interface ContestMapper {
13+
ContestDTO entityToDTO(ContestDataEntity entity);
14+
SponsorEntity dtoToSponsorEntity(ContestsDTO.Sponsor dto);
15+
ContestDataEntity dtoToEntity(ContestDTO dto);
16+
}

0 commit comments

Comments
 (0)