Schedule parsing
This commit is contained in:
parent
ba2ca206bd
commit
8ad3a57b72
@ -1,6 +1,6 @@
|
||||
namespace Platonus.API.DataModels;
|
||||
|
||||
class LoginResponse
|
||||
internal class LoginResponse
|
||||
{
|
||||
/// session_id
|
||||
public string? sid { get; set; }
|
||||
|
||||
123
Platonus.API/DataModels/Schedule.cs
Normal file
123
Platonus.API/DataModels/Schedule.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Platonus.API.DataModels;
|
||||
|
||||
public class Schedule
|
||||
{
|
||||
public int SelectedYear { get; }
|
||||
public int SelectedTermNumber { get; }
|
||||
public int SelectedWeekNumber { get; }
|
||||
public int CurrentWeekNumber { get; }
|
||||
public List<int> TermWeekNumbers { get; }
|
||||
|
||||
internal Schedule(ScheduleResponse scheduleData)
|
||||
{
|
||||
SelectedYear = scheduleData.selectedStudyYear;
|
||||
SelectedTermNumber = scheduleData.selectedTerm;
|
||||
SelectedWeekNumber = scheduleData.selectedWeek;
|
||||
CurrentWeekNumber = scheduleData.activeWeekNumber;
|
||||
TermWeekNumbers = scheduleData.weekList;
|
||||
|
||||
Days = new Day[scheduleData.timetable.days.Count];
|
||||
for (int di = 0; di < Days.Length; di++)
|
||||
{
|
||||
var dayData = scheduleData.timetable.days[(di + 1).ToString()];
|
||||
Days[di] = new Day(di, dayData.lessons.Count);
|
||||
int li = 0;
|
||||
foreach (var lessonWrapper in dayData.lessons)
|
||||
{
|
||||
var lessonHourData = scheduleData.lessonHours.Find(lh => lh.number.ToString() == lessonWrapper.Key);
|
||||
if (lessonHourData is null)
|
||||
throw new NullReferenceException($"lesson hour with number {lessonWrapper.Key} not found");
|
||||
Days[di].LessonHours[li].Time = new TimeRange(lessonHourData.start, lessonHourData.finish);
|
||||
|
||||
switch (lessonWrapper.Value.lessons.Count)
|
||||
{
|
||||
case 0:
|
||||
Days[di].LessonHours[li].Lesson = null;
|
||||
break;
|
||||
case 1:
|
||||
var lessonData = lessonWrapper.Value.lessons[0];
|
||||
Days[di].LessonHours[li].Lesson = new Day.Lesson(lessonData);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"lessonWrapper has data for more than one lessons ({lessonWrapper.Value.lessons.Count})");
|
||||
}
|
||||
|
||||
li++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct TimeRange
|
||||
{
|
||||
public readonly TimeSpan Start;
|
||||
public readonly TimeSpan Finish;
|
||||
|
||||
public TimeRange(TimeSpan from, TimeSpan to)
|
||||
{
|
||||
Start = from;
|
||||
Finish = to;
|
||||
}
|
||||
|
||||
/// format: hh:mm:ss
|
||||
public TimeRange(string startStr, string finishStr)
|
||||
{
|
||||
Start = TimeSpan.ParseExact(startStr, @"hh\:mm\:ss", CultureInfo.InvariantCulture);
|
||||
Finish = TimeSpan.ParseExact(finishStr, @"hh\:mm\:ss", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// days of week (monday=0, sunday=6)
|
||||
public Day[] Days { get; }
|
||||
|
||||
public class Day
|
||||
{
|
||||
public (TimeRange Time, Lesson? Lesson)[] LessonHours { get; }
|
||||
internal DayOfWeek DayOfWeek { get; }
|
||||
internal Day(int dayIndex, int dayLessonsCount)
|
||||
{
|
||||
LessonHours = new (TimeRange, Lesson?)[dayLessonsCount];
|
||||
DayOfWeek = dayIndex switch
|
||||
{
|
||||
0 => DayOfWeek.Monday,
|
||||
1 => DayOfWeek.Tuesday,
|
||||
2 => DayOfWeek.Wednesday,
|
||||
3 => DayOfWeek.Thursday,
|
||||
4 => DayOfWeek.Friday,
|
||||
5 => DayOfWeek.Saturday,
|
||||
6 => DayOfWeek.Sunday,
|
||||
_ => throw new Exception($"there is no day of week with index {dayIndex}")
|
||||
};
|
||||
}
|
||||
|
||||
public class Lesson
|
||||
{
|
||||
// example: Жанабеков Ж.О
|
||||
public string TutorName { get; }
|
||||
/// example: 420 б
|
||||
public string Auditory { get; }
|
||||
/// example: Байзак центр
|
||||
public string Building { get; }
|
||||
|
||||
/// example: Lecture
|
||||
public string LessonTypeName { get; }
|
||||
/// example: Программирование на языке С#
|
||||
public string SubjectName { get; }
|
||||
/// may not work, idk
|
||||
public bool OnlineClass { get; }
|
||||
|
||||
internal Lesson(ScheduleResponse.Timetable.Day.LessonWrapper.Lesson lessonData)
|
||||
{
|
||||
TutorName = lessonData.tutorName;
|
||||
Auditory = lessonData.auditory;
|
||||
Building = lessonData.building;
|
||||
LessonTypeName = lessonData.groupTypeFullName;
|
||||
SubjectName = lessonData.subjectName;
|
||||
OnlineClass = lessonData.onlineClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
namespace Platonus.API.DataModels;
|
||||
|
||||
public class ScheduleRequest
|
||||
internal class ScheduleRequest
|
||||
{
|
||||
public int statusID { get; set; } = 1;
|
||||
public int studentTypeID { get; set; } = 1;
|
||||
|
||||
88
Platonus.API/DataModels/ScheduleResponse.cs
Normal file
88
Platonus.API/DataModels/ScheduleResponse.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Platonus.API.DataModels;
|
||||
|
||||
#nullable disable
|
||||
internal class ScheduleResponse
|
||||
{
|
||||
/// example: 2023
|
||||
[JsonRequired] public int selectedStudyYear { get; set; }
|
||||
|
||||
/// 1 or 2
|
||||
[JsonRequired] public int selectedTerm { get; set; }
|
||||
[JsonRequired] public int defaultSelectedTerm { get; set; }
|
||||
|
||||
/// selected week number
|
||||
[JsonRequired] public int selectedWeek { get; set; }
|
||||
[JsonRequired] public int defaultSelectedWeek { get; set; }
|
||||
/// current week number
|
||||
[JsonRequired] public int activeWeekNumber { get; set; }
|
||||
/// all week numbers
|
||||
[JsonRequired] public List<int> weekList { get; set; }
|
||||
|
||||
/// all lesson hours in the week
|
||||
[JsonRequired] public List<LessonHour> lessonHours { get; set; }
|
||||
public class LessonHour
|
||||
{
|
||||
/// number of the lesson in Timetable.Day.lessons
|
||||
[JsonRequired] public int number { get; set; }
|
||||
/// example: 08:00:00
|
||||
[JsonRequired] public string start { get; set; }
|
||||
/// example: 08:50:00
|
||||
[JsonRequired] public string finish { get; set; }
|
||||
/// duration in minutes, usually 50
|
||||
[JsonRequired] public int duration { get; set; }
|
||||
/// idk what is it
|
||||
[JsonRequired] public int shiftNumber { get; set; }
|
||||
/// idk what is it
|
||||
[JsonRequired] public int displayNumber { get; set; }
|
||||
}
|
||||
|
||||
/// all days with lesson hours with or without lessons
|
||||
[JsonRequired] public Timetable timetable { get; set; }
|
||||
public class Timetable
|
||||
{
|
||||
/// day number string, Day class
|
||||
[JsonRequired] public Dictionary<string, Day> days { get; set; }
|
||||
public class Day
|
||||
{
|
||||
/// Lesson.number string, LessonWrapper class
|
||||
[JsonRequired] public Dictionary<string, LessonWrapper> lessons { get; set; }
|
||||
public class LessonWrapper
|
||||
{
|
||||
/// one or zero lessons at time
|
||||
[JsonRequired] public List<Lesson> lessons { get; set; }
|
||||
public class Lesson
|
||||
{
|
||||
/// number of the lesson, corresponds a number in a LessonHour
|
||||
[JsonRequired] public int number { get; set; }
|
||||
/// example: Жанабеков Ж.О
|
||||
[JsonRequired] public string tutorName { get; set; }
|
||||
/// same as tutorName
|
||||
[JsonRequired] public string tutorShortName { get; set; }
|
||||
/// example: 420 б
|
||||
[JsonRequired] public string auditory { get; set; }
|
||||
/// example: Байзак центр
|
||||
[JsonRequired] public string building { get; set; }
|
||||
/// some platonus internal id
|
||||
[JsonRequired] public int lessonID { get; set; }
|
||||
/// some platonus internal group id
|
||||
[JsonRequired] public int studyGroupID { get; set; }
|
||||
/// example: SFT6541-6-L
|
||||
[JsonRequired] public string studygroupShortName { get; set; }
|
||||
/// example: Программирование на языке С#,'Л'
|
||||
[JsonRequired] public string studyGroupName { get; set; }
|
||||
/// example: L
|
||||
[JsonRequired] public string groupTypeShortName { get; set; }
|
||||
/// example: Lecture
|
||||
[JsonRequired] public string groupTypeFullName { get; set; }
|
||||
/// example: Программирование на языке С#
|
||||
[JsonRequired] public string subjectName { get; set; }
|
||||
/// may not work, idk
|
||||
[JsonRequired] public bool onlineClass { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Platonus.API;
|
||||
|
||||
public class LoggindHttpHandler : DelegatingHandler
|
||||
public class LoggingHttpHandler : DelegatingHandler
|
||||
{
|
||||
public LoggindHttpHandler(HttpMessageHandler innerHandler) : base(innerHandler)
|
||||
public LoggingHttpHandler(HttpMessageHandler innerHandler) : base(innerHandler)
|
||||
{ }
|
||||
|
||||
void LogHttpRequest(HttpRequestMessage req)
|
||||
@ -30,7 +30,7 @@ public class PlatonusClient
|
||||
{
|
||||
CookieContainer = _cookies
|
||||
};
|
||||
_http = new HttpClient(new LoggindHttpHandler(httpClientHandler))
|
||||
_http = new HttpClient(new LoggingHttpHandler(httpClientHandler))
|
||||
{
|
||||
BaseAddress = new Uri(base_url)
|
||||
};
|
||||
@ -50,54 +50,35 @@ public class PlatonusClient
|
||||
_language = userCredentials.Language;
|
||||
reqContent.Headers.Add("language", _language.Number.ToString());
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// send POST request
|
||||
var res = await _http.PostAsync("rest/api/login", reqContent);
|
||||
// parse json
|
||||
if (res.Content.Headers.ContentLength < 1)
|
||||
throw new Exception("responce doesn't have any content");
|
||||
_loginResponse = await res.Content.ReadFromJsonAsync<LoginResponse>()
|
||||
?? throw new Exception("invalid login request rezult");
|
||||
if(_loginResponse.login_status != "success")
|
||||
throw new Exception("invalid login request rezult");
|
||||
|
||||
// set session id and user token headers in HttpClient
|
||||
_http.DefaultRequestHeaders.Add("sid", _loginResponse.sid);
|
||||
_http.DefaultRequestHeaders.Add("token", _loginResponse.auth_token);
|
||||
}
|
||||
catch (HttpRequestException re)
|
||||
{
|
||||
HandleRequestException(re);
|
||||
}
|
||||
// send POST request
|
||||
var res = await _http.PostAsync("rest/api/login", reqContent);
|
||||
// parse json
|
||||
if (res.Content.Headers.ContentLength < 1)
|
||||
throw new Exception("responce doesn't have any content");
|
||||
_loginResponse = await res.Content.ReadFromJsonAsync<LoginResponse>()
|
||||
?? throw new Exception("invalid login request rezult");
|
||||
if(_loginResponse.login_status != "success")
|
||||
throw new Exception("invalid login request rezult");
|
||||
|
||||
// set session id and user token headers in HttpClient
|
||||
_http.DefaultRequestHeaders.Add("sid", _loginResponse.sid);
|
||||
_http.DefaultRequestHeaders.Add("token", _loginResponse.auth_token);
|
||||
}
|
||||
|
||||
public async Task GetScheduleAsync()
|
||||
public async Task<Schedule> GetScheduleAsync()
|
||||
{
|
||||
if (_language is null)
|
||||
throw new Exception("language is null, you need to login");
|
||||
if (_loginResponse is null)
|
||||
throw new Exception("session id is null, you need to login");
|
||||
|
||||
try
|
||||
{
|
||||
var req = JsonContent.Create<ScheduleRequest>(new ScheduleRequest());
|
||||
var res = await _http.PostAsync(
|
||||
$"rest/schedule/userSchedule/student/initial/{_language.LiteralCode}",
|
||||
req);
|
||||
// var rezult = await res.Content.ReadFromJsonAsync<ScheduleResponseData>();
|
||||
}
|
||||
catch (HttpRequestException re)
|
||||
{
|
||||
HandleRequestException(re);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void HandleRequestException(HttpRequestException re)
|
||||
{
|
||||
// TODO http exception handling
|
||||
throw re;
|
||||
var req = JsonContent.Create(new ScheduleRequest());
|
||||
var res = await _http.PostAsync(
|
||||
$"rest/schedule/userSchedule/student/initial/{_language.LiteralCode}",
|
||||
req);
|
||||
ScheduleResponse scheduleData = await res.Content.ReadFromJsonAsync<ScheduleResponse>()
|
||||
?? throw new NullReferenceException("ScheduleResponse is null");
|
||||
var schedule = new Schedule(scheduleData);
|
||||
return schedule;
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ var loginCredentials = new LoginCredentials(
|
||||
ReadString("password"),
|
||||
PlatonusLanguage.English);
|
||||
await p.LoginAsync(loginCredentials);
|
||||
await p.GetScheduleAsync();
|
||||
var schedule = await p.GetScheduleAsync();
|
||||
return;
|
||||
|
||||
string ReadString(string question)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user