-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApiClient.cs
More file actions
137 lines (119 loc) · 5.06 KB
/
ApiClient.cs
File metadata and controls
137 lines (119 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ReSchedule.Entities;
namespace ReSchedule;
public static class CacheOptions
{
private const int HoursGetGroupsExpiration = 12;
private const int HoursGetScheduleExpiration = 6;
public static MemoryCacheEntryOptions GroupsExpEntryOptions => new()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(HoursGetGroupsExpiration)
};
public static MemoryCacheEntryOptions ScheduleExpEntryOptions => new()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(HoursGetScheduleExpiration)
};
}
public class ApiClient
{
private readonly HttpClient _httpClient;
private readonly IMemoryCache _cache;
private readonly ILogger _logger;
private readonly string _getGroupsUri = "schedule/groups";
private readonly Func<string, string> _getScheduleUri = (groupId) => $"schedule/lessons?groupId={groupId}";
public ApiClient(IHttpClientFactory httpClientFactory, IMemoryCache cache, ILogger<ApiClient> logger)
{
_logger = logger;
_logger.LogInformation("Creating ApiClient instance");
string apiUri = "https://schedule.kpi.ua/api/";
_httpClient = httpClientFactory.CreateClient();
if (apiUri.Last() != '/') apiUri += '/';
_httpClient.BaseAddress = new Uri(apiUri);
_cache = cache;
}
private void LogCachingProcess(string key)
{
var stats = _cache.GetCurrentStatistics();
_logger.LogInformation("Caching {Key}\n\tCurrent MemoryConsumption {}\n\tEntries {}",
key,
stats?.CurrentEstimatedSize?.ToString() ?? "none",
stats?.CurrentEntryCount.ToString() ?? "none");
}
private async Task<HttpResponseMessage> RequestGroups()
{
var response = await _httpClient.GetAsync(_getGroupsUri);
if (response.IsSuccessStatusCode)
{
LogCachingProcess(_getGroupsUri);
_cache.Set(_getGroupsUri, response, CacheOptions.GroupsExpEntryOptions);
}
return response;
}
private async Task<HttpResponseMessage> RequestSchedule(string groupId)
{
var uri = _getScheduleUri(groupId);
var response = await _httpClient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
LogCachingProcess(uri);
_cache.Set(uri, response, CacheOptions.ScheduleExpEntryOptions);
}
return response;
}
public async Task<Response<List<Group>>> GetGroups()
{
var response = _cache.TryGetValue(_getGroupsUri, out HttpResponseMessage? cacheResponse) switch
{
true => cacheResponse!,
false => await RequestGroups()
};
if (!response.IsSuccessStatusCode)
{
_logger.LogError("Get groups request was not successfull. Status Code {}",response.StatusCode);
return new Response<List<Group>>() {StatusCode = response.StatusCode};
}
var content = await response.Content.ReadAsStringAsync();
var jGroups = JObject.Parse(content)["data"]!.Children();
var groups = jGroups.Select(jGroup => jGroup.ToObject<Group>()!).ToList();
return new Response<List<Group>>() {StatusCode = response.StatusCode, Data = groups};
}
public async Task<Response<Schedule>> GetSchedule(string groupId)
{
var response = _cache.TryGetValue(_getScheduleUri(groupId), out HttpResponseMessage? cacheResponse) switch
{
true => cacheResponse!,
false => await RequestSchedule(groupId)
};
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning("GetSchedule request was not successful.\nStatus Code:{}",
response.StatusCode);
return new Response<Schedule>() {StatusCode = response.StatusCode};
}
var content = await response.Content.ReadAsStringAsync();
var data = JObject.Parse(content)["data"]!;
var firstWeek = data["scheduleFirstWeek"]!.Children();
var secondWeek = data["scheduleSecondWeek"]!.Children();
var schedule = new Schedule
{
ScheduleFirstWeek = firstWeek.Select(jDay => jDay.ToObject<WeekDay>()!).ToList(),
ScheduleSecondWeek = secondWeek.Select(jDay => jDay.ToObject<WeekDay>()!).ToList()
};
return new Response<Schedule>() {StatusCode = response.StatusCode, Data = schedule};
}
public async Task<Response<ScheduleTime>> GetCurrentTime()
{
var response = await _httpClient.GetAsync($"time/current");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var data = JObject.Parse(content)["data"]!;
var time = data.ToObject<ScheduleTime>();
return new Response<ScheduleTime>() {StatusCode = response.StatusCode, Data = time};
}
_logger.LogError("Time request was not successfull. Status Code {}",response.StatusCode);
return new Response<ScheduleTime>() {StatusCode = response.StatusCode};
}
}