Skip to content

Commit 3d7be94

Browse files
authored
Merge pull request #1212 from gordon-cs/s25-finalExam-schedule
s25 implementations to get final exam data by username from 25Live
2 parents 0de3b1b + 4cafa19 commit 3d7be94

File tree

12 files changed

+273
-20
lines changed

12 files changed

+273
-20
lines changed

Gordon360/Controllers/AcademicTermController.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Gordon360.Services;
33
using Microsoft.AspNetCore.Authorization;
44
using Microsoft.AspNetCore.Mvc;
5+
using System;
56
using System.Threading.Tasks;
67

78

@@ -33,5 +34,24 @@ public async Task<ActionResult<DaysLeftViewModel>> GetDaysLeft()
3334
var result = await service.GetDaysLeftAsync();
3435
return Ok(result);
3536
}
37+
38+
/// <summary>
39+
/// Gets the most recent academic term that is either Spring or Fall
40+
/// </summary>
41+
/// <returns>The current term used to fetch final exams</returns>
42+
[HttpGet]
43+
[Route("currentFinalExamTerm")]
44+
[AllowAnonymous]
45+
[Obsolete]
46+
public async Task<IActionResult> GetCurrentTermForFinalExams()
47+
{
48+
var currentFinalTerm = await service.GetCurrentTermForFinalExamsAsync();
49+
if (currentFinalTerm == null)
50+
{
51+
return NotFound();
52+
}
53+
54+
return Ok(currentFinalTerm);
55+
}
3656
}
3757
}

Gordon360/Controllers/EventsController.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
using Gordon360.Authorization;
2+
using Gordon360.Enums;
23
using Gordon360.Models.CCT.Context;
34
using Gordon360.Models.ViewModels;
45
using Gordon360.Services;
56
using Microsoft.AspNetCore.Authorization;
67
using Microsoft.AspNetCore.Mvc;
78
using Microsoft.Extensions.Caching.Memory;
9+
using Microsoft.Graph;
10+
using System;
811
using System.Collections.Generic;
912
using System.Threading.Tasks;
13+
using static System.Runtime.CompilerServices.RuntimeHelpers;
14+
using System.Linq;
15+
using Gordon360.Extensions.System;
1016

1117
namespace Gordon360.Controllers;
1218

@@ -79,5 +85,28 @@ public ActionResult<IEnumerable<EventViewModel>> GetAllPublicEvents()
7985
return Ok(result);
8086
}
8187

88+
[HttpGet]
89+
[Route("finalexams/{username}")]
90+
public async Task<ActionResult<IEnumerable<EventViewModel>>> GetFinalExamsForUserByTermAsync(
91+
string username,
92+
[FromQuery] DateTime termStart,
93+
[FromQuery] DateTime termEnd,
94+
[FromQuery] string yearCode,
95+
[FromQuery] string termCode)
96+
{
97+
var groups = AuthUtils.GetGroups(User);
98+
var authenticatedUsername = AuthUtils.GetUsername(User);
99+
100+
IEnumerable<EventViewModel> result;
101+
if (authenticatedUsername.EqualsIgnoreCase(username) || groups.Contains(AuthGroup.FacStaff))
102+
{
103+
result = await eventService.GetFinalExamsForUserByTermAsync(username, termStart, termEnd, yearCode, termCode);
104+
}
105+
else
106+
{
107+
result = await eventService.GetFinalExamsForInstructorByTermAsync(username, termStart, termEnd, yearCode, termCode);
108+
}
109+
return Ok(result);
110+
}
82111
}
83112

Gordon360/Controllers/ScheduleController.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public async Task<ActionResult<CoursesBySessionViewModel>> GetAllCourses(string
4444
/// <returns>A IEnumerable of term objects as well as the schedules</returns>
4545
[HttpGet]
4646
[Route("{username}/allcourses-by-term")]
47-
[StateYourBusiness(operation = Operation.READ_ONE, resource = Resource.STUDENT_SCHEDULE)]
4847
public async Task<ActionResult<IEnumerable<CoursesByTermViewModel>>> GetAllCoursesByTerm(string username)
4948
{
5049
var groups = AuthUtils.GetGroups(User);

Gordon360/Controllers/SessionsController.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.AspNetCore.Authorization;
44
using Microsoft.AspNetCore.Mvc;
55
using System.Collections.Generic;
6+
using System;
67

78
namespace Gordon360.Controllers;
89

@@ -61,6 +62,26 @@ public ActionResult<SessionViewModel> GetCurrentSession()
6162
return Ok(currentSession);
6263
}
6364

65+
/// <summary>
66+
/// Gets the most recent academic session that is either Spring or Fall
67+
/// </summary>
68+
/// <returns>The current session used to fetch final exams</returns>
69+
[HttpGet]
70+
[Route("currentFinals")]
71+
[AllowAnonymous]
72+
[Obsolete]
73+
public ActionResult<SessionViewModel> GetCurrentSessionForFinalExams()
74+
{
75+
var currentFinalSession = sessionService.GetCurrentSessionForFinalExams();
76+
if (currentFinalSession == null)
77+
{
78+
return NotFound();
79+
}
80+
81+
return Ok(currentFinalSession);
82+
}
83+
84+
6485
/// <summary>
6586
/// Gets the days left in the current session
6687
/// </summary>

Gordon360/Documentation/Gordon360.xml

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gordon360/Program.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,23 @@
9393
);
9494

9595
builder.Services.Add360Services();
96+
9697
builder.Services.AddHostedService<EventCacheRefreshService>();
9798
builder.Services.AddHostedService<MarketplaceCleanupService>();
9899
builder.Services.AddHostedService<PosterCleanupService>();
100+
99101
builder.Services.AddScoped<ServerUtils, ServerUtils>();
100102

101103
builder.Services.AddMemoryCache();
104+
builder.Services.AddHttpClient<IEventService, EventService>(client =>
105+
{
106+
client.Timeout = TimeSpan.FromSeconds(200);
107+
client.DefaultRequestHeaders.Add("User-Agent", "Gordon360/1.0.0");
108+
});
109+
builder.Services.AddHostedService<EventCacheRefreshService>();
102110

103111
var app = builder.Build();
104-
112+
105113
// Configure the HTTP request pipeline.
106114

107115
app.UseSwagger();

Gordon360/Services/AcademicTermService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,18 @@ public async Task<DaysLeftViewModel> GetDaysLeftAsync()
116116
TermLabel = "Break"
117117
};
118118
}
119+
120+
public async Task<YearTermTableViewModel?> GetCurrentTermForFinalExamsAsync()
121+
{
122+
var currentDate = DateTime.Now;
123+
124+
var finalExamTerm = await context.YearTermTable
125+
.Where(t =>
126+
currentDate > t.TRM_BEGIN_DTE &&
127+
(t.TRM_CDE == "SP" || t.TRM_CDE == "FA"))
128+
.OrderByDescending(t => t.TRM_BEGIN_DTE)
129+
.FirstOrDefaultAsync();
130+
131+
return finalExamTerm != null ? new YearTermTableViewModel(finalExamTerm) : null;
132+
}
119133
}

Gordon360/Services/EventCacheRefreshService.cs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
using Gordon360.Static_Classes;
1+
using Gordon360.Models.ViewModels;
2+
using Gordon360.Static_Classes;
23
using Microsoft.Extensions.Caching.Memory;
4+
using Microsoft.Extensions.DependencyInjection;
35
using Microsoft.Extensions.Hosting;
4-
using System.Threading.Tasks;
5-
using System.Threading;
66
using System;
7-
using System.Diagnostics;
8-
using Gordon360.Models.ViewModels;
97
using System.Collections.Generic;
8+
using System.Diagnostics;
9+
using System.Threading;
10+
using System.Threading.Tasks;
1011

1112
namespace Gordon360.Services;
1213

13-
public sealed class EventCacheRefreshService(IMemoryCache cache) : IHostedService, IDisposable
14+
public sealed class EventCacheRefreshService(IServiceScopeFactory scopeFactory) : IHostedService, IDisposable
1415
{
1516
private Timer? _timer = null;
17+
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
1618

1719
public Task StartAsync(CancellationToken stoppingToken)
1820
{
@@ -24,18 +26,24 @@ public Task StartAsync(CancellationToken stoppingToken)
2426

2527
private async void UpdateEventsCacheAsync(object? state)
2628
{
27-
IEnumerable<EventViewModel>? events = null;
2829
try
2930
{
30-
events = await EventService.FetchEventsAsync();
31+
using var scope = _scopeFactory.CreateScope();
32+
33+
var eventService = scope.ServiceProvider.GetRequiredService<IEventService>();
34+
var cache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
35+
36+
var events = await eventService.FetchEventsAsync();
37+
cache.Set(CacheKeys.Events, events);
38+
3139
}
3240
catch (Exception ex)
3341
{
34-
Debug.WriteLine(ex.Message);
42+
Debug.WriteLine("UpdateEventsCacheAsync error: " + ex.Message);
3543
}
36-
cache.Set(CacheKeys.Events, events);
3744
}
3845

46+
3947
public Task StopAsync(CancellationToken stoppingToken)
4048
{
4149
_timer?.Change(Timeout.Infinite, 0);

0 commit comments

Comments
 (0)