tag that is the second child of their parent tag
// 3. Get
tag inside the
string labelText = doc.QuerySelector("a#rasp-prev + div:nth-child(2) > span")!.TextContent;
// Content of the tag is supposed to be something like "Нечетная неделя (15)"
// So, we can use regular expressions to get the "15" part and parse it to an integer.
int weekNumber = int.Parse(ParserUtils.NumberRegex().Match(labelText).Value);
DateTime currentDate = DateTime.Today;
currentDate = currentDate
.AddDays(-(int)currentDate.DayOfWeek + 1) // Move to Monday
.AddDays(-7 * (weekNumber - 1)); // Move back to the first week
return currentDate;
}
// Utility method that converts faculty or group list response into a dictionary.
// It expected the reponse to be in format: "1,Group 1;2,Group2;..."
private static Dictionary ParseListResponse(string responseContent) =>
responseContent
.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(item => item.Split(','))
.ToDictionary(
parts => int.Parse(parts[0]),
parts => parts[1]
);
// Utility method for sending request to sut.ru API.
private static async Task SendRequestAsync(Dictionary formData)
{
HttpRequestMessage request = new(HttpMethod.Post, "https://cabinet.sut.ru/raspisanie_all_new.php")
{
Content = new FormUrlEncodedContent(formData)
};
using HttpClient client = new(new HttpClientHandler
{
// Sometimes Bonch being Bonch just doesn't renew its SSL certificates properly,
// so we just assume that we're in the right place.
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
});
HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
private static string GetCurrentSemesterId()
{
DateTime now = DateTime.Today;
int currentSemester = now.Month is >= 8 or < 2
? 1 // August through January - first semester
: 2; // Everything else - second
int academicYearStartYear = now.Year - 2000; // We need only last two digits (e.g. 25 for 2025)
// P.S. I am not a fun of this variable name either.
if (now.Month < 8) // Before August means we are in the second semester of the previous academic year
academicYearStartYear--;
return $"205.{academicYearStartYear}{academicYearStartYear + 1}/{currentSemester}";
}
}