commit ba2ca206bd2abf7d81cf27b561b6c6585a866026 Author: Timerix22 Date: Sat Sep 2 18:08:26 2023 +0600 implemented requests diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd42ee3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/ +obj/ diff --git a/.idea/.idea.PlatonusSchedule/.idea/.gitignore b/.idea/.idea.PlatonusSchedule/.idea/.gitignore new file mode 100644 index 0000000..ce5c076 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/contentModel.xml +/modules.xml +/projectSettingsUpdater.xml +/.idea.PlatonusSchedule.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.PlatonusSchedule/.idea/dictionaries/User.xml b/.idea/.idea.PlatonusSchedule/.idea/dictionaries/User.xml new file mode 100644 index 0000000..08c65e5 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/dictionaries/User.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/encodings.xml b/.idea/.idea.PlatonusSchedule/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/indexLayout.xml b/.idea/.idea.PlatonusSchedule/.idea/indexLayout.xml new file mode 100644 index 0000000..f5a863a --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/inspectionProfiles/Project_Default.xml b/.idea/.idea.PlatonusSchedule/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..8d66637 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/markdown.xml b/.idea/.idea.PlatonusSchedule/.idea/markdown.xml new file mode 100644 index 0000000..00405d5 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/markdown.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/misc.xml b/.idea/.idea.PlatonusSchedule/.idea/misc.xml new file mode 100644 index 0000000..3ce3588 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/.idea.PlatonusSchedule/.idea/vcs.xml b/.idea/.idea.PlatonusSchedule/.idea/vcs.xml new file mode 100644 index 0000000..9661ac7 --- /dev/null +++ b/.idea/.idea.PlatonusSchedule/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Platonus.API/DataModels/LoginResponse.cs b/Platonus.API/DataModels/LoginResponse.cs new file mode 100644 index 0000000..443b98d --- /dev/null +++ b/Platonus.API/DataModels/LoginResponse.cs @@ -0,0 +1,10 @@ +namespace Platonus.API.DataModels; + +class LoginResponse +{ + /// session_id + public string? sid { get; set; } + public string? auth_token { get; set; } + /// should be "success" + public string? login_status { get; set; } +} \ No newline at end of file diff --git a/Platonus.API/DataModels/ScheduleRequest.cs b/Platonus.API/DataModels/ScheduleRequest.cs new file mode 100644 index 0000000..3e95fca --- /dev/null +++ b/Platonus.API/DataModels/ScheduleRequest.cs @@ -0,0 +1,8 @@ +namespace Platonus.API.DataModels; + +public class ScheduleRequest +{ + public int statusID { get; set; } = 1; + public int studentTypeID { get; set; } = 1; + public int week { get; set; } = 1; +} \ No newline at end of file diff --git a/Platonus.API/LoggindHttpHandler.cs b/Platonus.API/LoggindHttpHandler.cs new file mode 100644 index 0000000..7efc8ca --- /dev/null +++ b/Platonus.API/LoggindHttpHandler.cs @@ -0,0 +1,47 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Platonus.API; + +public class LoggindHttpHandler : DelegatingHandler +{ + public LoggindHttpHandler(HttpMessageHandler innerHandler) : base(innerHandler) + { } + + void LogHttpRequest(HttpRequestMessage req) + { + Console.WriteLine($"REQUEST {req.Method} to {req.RequestUri}: " + + req.Content?.ReadAsStringAsync().GetAwaiter().GetResult()); + } + + void LogHttpResponse(HttpResponseMessage res) + { + Console.WriteLine($"RESPONSE {res.StatusCode} ({(int)res.StatusCode}) from {res.RequestMessage?.RequestUri}: " + + res.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + if (res.Headers.TryGetValues("Set-Cookie", out var cookieHeaders)) + foreach (var cookieHeader in cookieHeaders) + { + Console.WriteLine($" Set-Cookie: {cookieHeader}"); + } + } + + #if !NETSTANDARD2_0 + protected override HttpResponseMessage Send(HttpRequestMessage req, CancellationToken cancellationToken) + { + LogHttpRequest(req); + var res = base.Send(req, cancellationToken); + LogHttpResponse(res); + return res; + } + #endif + + protected override async Task SendAsync(HttpRequestMessage req, CancellationToken cancellationToken) + { + LogHttpRequest(req); + var res = await base.SendAsync(req, cancellationToken); + LogHttpResponse(res); + return res; + } +} \ No newline at end of file diff --git a/Platonus.API/LoginCredentials.cs b/Platonus.API/LoginCredentials.cs new file mode 100644 index 0000000..ee670b9 --- /dev/null +++ b/Platonus.API/LoginCredentials.cs @@ -0,0 +1,20 @@ +namespace Platonus.API; + +public struct LoginCredentials +{ + /// + /// student_id@iitu.edu.kz + /// + public readonly string Login; + + public readonly string Password; + + public readonly PlatonusLanguage Language; + + public LoginCredentials(string login, string password, PlatonusLanguage language) + { + Login = login; + Password = password; + Language = language; + } +} \ No newline at end of file diff --git a/Platonus.API/Platonus.API.csproj b/Platonus.API/Platonus.API.csproj new file mode 100644 index 0000000..6af0f03 --- /dev/null +++ b/Platonus.API/Platonus.API.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0;net6.0;net7.0 + 11 + disable + enable + Platonus.API + + + + + + + + + diff --git a/Platonus.API/PlatonusClient.cs b/Platonus.API/PlatonusClient.cs new file mode 100644 index 0000000..41b7255 --- /dev/null +++ b/Platonus.API/PlatonusClient.cs @@ -0,0 +1,103 @@ +using System; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Threading.Tasks; +using Platonus.API.DataModels; + +namespace Platonus.API; + +public class PlatonusClient +{ + private const string base_url = "https://platonus.iitu.edu.kz/"; + public bool DebugHttpMessages; + + + private LoginResponse? _loginResponse; + private PlatonusLanguage? _language; + private HttpClient _http; + private CookieContainer _cookies; + + public PlatonusClient() + { +#if DEBUG + // TODO disable http messages logging + DebugHttpMessages = true; +#endif + _cookies = new CookieContainer(); + var httpClientHandler = new HttpClientHandler + { + CookieContainer = _cookies + }; + _http = new HttpClient(new LoggindHttpHandler(httpClientHandler)) + { + BaseAddress = new Uri(base_url) + }; + } + + public async Task LoginAsync(LoginCredentials userCredentials) + { + string json = $$""" + { + "login": "{{userCredentials.Login}}", + "password": "{{userCredentials.Password}}", + "authForDeductedStudentsAndGraduates": "false" + } + """; + var reqContent = new StringContent(json); + reqContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + _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() + ?? 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); + } + } + + public async Task 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(new ScheduleRequest()); + var res = await _http.PostAsync( + $"rest/schedule/userSchedule/student/initial/{_language.LiteralCode}", + req); + // var rezult = await res.Content.ReadFromJsonAsync(); + } + catch (HttpRequestException re) + { + HandleRequestException(re); + } + + } + + private void HandleRequestException(HttpRequestException re) + { + // TODO http exception handling + throw re; + } +} \ No newline at end of file diff --git a/Platonus.API/PlatonusLanguage.cs b/Platonus.API/PlatonusLanguage.cs new file mode 100644 index 0000000..957cf8b --- /dev/null +++ b/Platonus.API/PlatonusLanguage.cs @@ -0,0 +1,17 @@ +namespace Platonus.API; + +public class PlatonusLanguage +{ + public readonly int Number; + public readonly string LiteralCode; + + private PlatonusLanguage(int num, string literalCode) + { + Number = num; + LiteralCode = literalCode; + } + + public static PlatonusLanguage English = new(0, "en"); + public static PlatonusLanguage Russian = new(1, "ru"); + public static PlatonusLanguage Kazakh = new(2, "kz"); +} \ No newline at end of file diff --git a/PlatonusSchedule.CLI/PlatonusSchedule.CLI.csproj b/PlatonusSchedule.CLI/PlatonusSchedule.CLI.csproj new file mode 100644 index 0000000..56261f7 --- /dev/null +++ b/PlatonusSchedule.CLI/PlatonusSchedule.CLI.csproj @@ -0,0 +1,15 @@ + + + + Exe + net7.0 + 10 + disable + enable + + + + + + + diff --git a/PlatonusSchedule.CLI/Program.cs b/PlatonusSchedule.CLI/Program.cs new file mode 100644 index 0000000..2ae86f5 --- /dev/null +++ b/PlatonusSchedule.CLI/Program.cs @@ -0,0 +1,20 @@ +using System; +using Platonus.API; + +var p = new PlatonusClient(); +var loginCredentials = new LoginCredentials( + ReadString("login"), + ReadString("password"), + PlatonusLanguage.English); +await p.LoginAsync(loginCredentials); +await p.GetScheduleAsync(); +return; + +string ReadString(string question) +{ + Console.Write($"{question}: "); + string? answ = Console.ReadLine(); + if (string.IsNullOrEmpty(answ)) + throw new NullReferenceException(); + return answ; +} \ No newline at end of file diff --git a/PlatonusSchedule.sln b/PlatonusSchedule.sln new file mode 100644 index 0000000..4ccbf07 --- /dev/null +++ b/PlatonusSchedule.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platonus.API", "Platonus.API\Platonus.API.csproj", "{3650802E-D79E-47FC-ADED-2D9D6AF80340}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlatonusSchedule.CLI", "PlatonusSchedule.CLI\PlatonusSchedule.CLI.csproj", "{B445963D-AB65-4138-912D-58A0A954A736}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3650802E-D79E-47FC-ADED-2D9D6AF80340}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3650802E-D79E-47FC-ADED-2D9D6AF80340}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3650802E-D79E-47FC-ADED-2D9D6AF80340}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3650802E-D79E-47FC-ADED-2D9D6AF80340}.Release|Any CPU.Build.0 = Release|Any CPU + {B445963D-AB65-4138-912D-58A0A954A736}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B445963D-AB65-4138-912D-58A0A954A736}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B445963D-AB65-4138-912D-58A0A954A736}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B445963D-AB65-4138-912D-58A0A954A736}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal