codeforces.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { SiteDescription, Contest, Problem } from "../types";
  2. import * as vscode from 'vscode';
  3. import JSSoup from 'jssoup';
  4. import * as got from 'got';
  5. import { getText } from './util';
  6. /**
  7. * contestId: ${contest}
  8. * http://codeforces.com/contest/${contest}/
  9. *
  10. * Example:
  11. * http://codeforces.com/contest/1081/
  12. */
  13. export async function parseContest(contestId: string) {
  14. let url = `http://codeforces.com/contest/${contestId}`;
  15. let response = await got.get(url);
  16. if (response.statusCode !== 200){
  17. throw new Error(`Contest ${url} not downloaded. ${response.statusCode}`);
  18. }
  19. vscode.window.showInformationMessage(`Downloading contest ${contestId}...`);
  20. let soup = new JSSoup(response.body);
  21. let name: string = soup.find("div", {"id" : "sidebar"}).find("a").text;
  22. name = name.toLowerCase().replace(' ', '-');
  23. let problemsTable = soup.find("table", "problems");
  24. let problems: Problem[] = [];
  25. let problemSection = problemsTable.findAll("td", "id");
  26. for (let i = 0; i < problemSection.length; i++){
  27. let section = problemSection[i];
  28. let hrefData = section.find("a").attrs.href.split('/');
  29. let pid = hrefData[hrefData.length - 1];
  30. console.log(`Problem ${contestId}-${pid}`);
  31. let prob = await parseProblem(contestId + "-" + pid);
  32. problems.push(prob);
  33. }
  34. return new Contest(name, problems);
  35. }
  36. /**
  37. * problemId: ${contest}-${problem}
  38. * http://codeforces.com/contest/${contest}/problem/${problem}
  39. *
  40. * Example:
  41. * http://codeforces.com/contest/1081/problem/E
  42. */
  43. export async function parseProblem(problemId: string) {
  44. let data = problemId.split('-');
  45. let contest = data[0];
  46. let pid = data[1];
  47. let url = `http://codeforces.com/contest/${contest}/problem/${pid}`;
  48. let response = await got.get(url);
  49. if (response.statusCode !== 200){
  50. throw new Error(`Problem ${url} not downloaded. ${response.statusCode}`);
  51. }
  52. let soup = new JSSoup(response.body);
  53. let problemDescription = soup.find("div", "problemindexholder");
  54. let name = problemDescription.find("div", "title").text;
  55. let inputTC: string[] = [];
  56. let outputTC: string[] = [];
  57. problemDescription.findAll("div", "input").forEach((element: any) =>{
  58. let tc = element.find("pre");
  59. inputTC.push(getText(tc));
  60. });
  61. problemDescription.findAll("div", "output").forEach((element: any) =>{
  62. let tc = element.find("pre");
  63. outputTC.push(getText(tc));
  64. });
  65. vscode.window.showInformationMessage(`Downloaded problem ${problemId}!`);
  66. return new Problem(pid, name, inputTC, outputTC);
  67. }
  68. export const CODEFORCES = new SiteDescription(
  69. "codeforces",
  70. "codeforces.com",
  71. "{contest id} (Ex: 1095)",
  72. "{contest id}-{problem id} (Ex: 1095-A)",
  73. parseContest,
  74. parseProblem,
  75. );