Skip to content

Commit

Permalink
More changes, slowly building out event creation
Browse files Browse the repository at this point in the history
  • Loading branch information
evanlihou committed Jun 21, 2024
1 parent be249ae commit 0e8878f
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 32 deletions.
5 changes: 5 additions & 0 deletions FiMAdminApi.Data/DataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ public class DataContext(DbContextOptions<DataContext> options) : DbContext(opti
public DbSet<Season> Seasons { get; init; }
public DbSet<Event> Events { get; init; }
public DbSet<TruckRoute> TruckRoutes { get; init; }

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Properties(typeof(Enum)).HaveConversion<string>();
}
}
10 changes: 6 additions & 4 deletions FiMAdminApi.Data/Models/Event.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using FiMAdminApi.Data.Enums;

namespace FiMAdminApi.Data.Models;

Expand All @@ -9,16 +10,17 @@ public class Event
public required string Key { get; set; }
public string? Code { get; set; }
public required string Name { get; set; }
public string? SyncSource { get; set; }
public DataSources? SyncSource { get; set; }
public required bool IsOfficial { get; set; }
public int? TruckRouteId { get; set; }
public TruckRoute? TruckRoute { get; set; }
public required DateTimeOffset StartTime { get; set; }
public required DateTimeOffset EndTime { get; set; }
public required DateTime StartTime { get; set; }
public required DateTime EndTime { get; set; }
public required string TimeZone { get; set; }
public DateTimeOffset? SyncAsOf { get; set; }
public required string Status { get; set; } = "NotStarted";

// Relations
[Description("Note: This object may not be populated in some endpoints.")]
public Season? Season { get; set; }
}
}
5 changes: 4 additions & 1 deletion FiMAdminApi.Data/Models/TruckRoute.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.ComponentModel.DataAnnotations;

namespace FiMAdminApi.Data.Models;

public class TruckRoute
{

[Key]
public int Id { get; set; }
}
26 changes: 9 additions & 17 deletions FiMAdminApi/Clients/FrcEventsDataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Text;
using System.Text.Json;
using FiMAdminApi.Data.Models;
using FiMAdminApi.Extensions;
using Event = FiMAdminApi.Clients.Models.Event;

namespace FiMAdminApi.Clients;
Expand All @@ -18,11 +19,13 @@ public FrcEventsDataClient(IServiceProvider sp)
var configSection = sp.GetRequiredService<IConfiguration>().GetRequiredSection("Clients:FrcEvents");

var apiKey = configSection["ApiKey"];
if (string.IsNullOrWhiteSpace(apiKey)) throw new ArgumentNullException(nameof(apiKey));
if (string.IsNullOrWhiteSpace(apiKey))
throw new ApplicationException("FrcEvents ApiKey was null but is required");
_apiKey = apiKey;

var baseUrl = configSection["BaseUrl"];
if (string.IsNullOrWhiteSpace(baseUrl)) throw new ArgumentNullException(nameof(baseUrl));
if (string.IsNullOrWhiteSpace(baseUrl))
throw new ApplicationException("FrcEvents BaseUrl was null but is required");
_baseUrl = new Uri(baseUrl);

_httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("FrcEvents");
Expand Down Expand Up @@ -51,7 +54,8 @@ public FrcEventsDataClient(IServiceProvider sp)
DistrictCode = evt.GetProperty("districtCode").GetString(),
City = evt.GetProperty("city").GetString() ?? "(No city)",
StartTime = new DateTimeOffset(startTime, timeZone.GetUtcOffset(startTime)),
EndTime = new DateTimeOffset(endTime, timeZone.GetUtcOffset(endTime))
EndTime = new DateTimeOffset(endTime, timeZone.GetUtcOffset(endTime)),
TimeZone = timeZone
};
}).SingleOrDefault((Event?)null);
}
Expand All @@ -61,7 +65,7 @@ public Task<List<Event>> GetDistrictEventsAsync(Season season, string districtCo
throw new NotImplementedException();
}

private string GetSeason(Season season)
private static string GetSeason(Season season)
{
return season.StartTime.Year.ToString();
}
Expand All @@ -77,7 +81,7 @@ private HttpRequestMessage BuildGetRequest(FormattableString endpoint, Dictionar
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(_apiKey)));

var relativeUri =
$"{EncodeString(endpoint, Uri.EscapeDataString)}{(queryParams is not null && queryParams.Count > 0 ? QueryString.Create(queryParams!) : "")}";
$"{endpoint.EncodeString(Uri.EscapeDataString)}{(queryParams is not null && queryParams.Count > 0 ? QueryString.Create(queryParams!) : "")}";

if (relativeUri.StartsWith('/'))
throw new ArgumentException("Endpoint must be a relative path", nameof(endpoint));
Expand All @@ -86,16 +90,4 @@ private HttpRequestMessage BuildGetRequest(FormattableString endpoint, Dictionar

return request;
}

private string EncodeString(FormattableString str, Func<string, string> func)
{
var invariantParameters = str.GetArguments()
.Select(a => FormattableString.Invariant($"{a}"));
var escapedParameters = invariantParameters
.Select(func)
.Cast<object>()
.ToArray();

return string.Format(str.Format, escapedParameters);
}
}
1 change: 1 addition & 0 deletions FiMAdminApi/Clients/Models/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public class Event
public string City { get; set; }
public DateTimeOffset StartTime { get; set; }
public DateTimeOffset EndTime { get; set; }
public TimeZoneInfo TimeZone { get; set; }
}
16 changes: 16 additions & 0 deletions FiMAdminApi/Extensions/FormattableStringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace FiMAdminApi.Extensions;

public static class FormattableStringExtensions
{
public static string EncodeString(this FormattableString str, Func<string, string> func)
{
var invariantParameters = str.GetArguments()
.Select(a => FormattableString.Invariant($"{a}"));
var escapedParameters = invariantParameters
.Select(func)
.Cast<object>()
.ToArray();

return string.Format(str.Format, escapedParameters);
}
}
54 changes: 44 additions & 10 deletions FiMAdminApi/Services/UpsertEventsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public async Task<UpsertEventsResponse> UpsertFromDataSource(UpsertFromDataSourc
var season = await GetAndValidateSeason(request.SeasonId, response);
if (season is null)
{
response.Errors.Add("Season not found");
return response;
}

Expand All @@ -51,11 +50,8 @@ public async Task<UpsertEventsResponse> UpsertFromDataSource(UpsertFromDataSourc
.Select(async code =>
{
var resp = await dataClient.GetEventAsync(season, code.Trim());
if (resp is not null) return resp;
response.Errors.Add($"Event with code {code} not found");
return null;
if (resp is null) response.Errors.Add($"Event with code {code} not found");
return resp;
}))).Where(e => e is not null).Select(e => e!).ToList();
}

Expand All @@ -64,9 +60,47 @@ public async Task<UpsertEventsResponse> UpsertFromDataSource(UpsertFromDataSourc
response.Warnings.Add("No events to create");
return response;
}



foreach (var apiEvent in apiEvents)
{
var dbEvent = dbEvents.FirstOrDefault(e => e.Code == apiEvent.EventCode);
if (dbEvent is not null)
{
if (!request.OverrideExisting)
{
response.Warnings.Add($"Found existing event {apiEvent.EventCode}, skipping");
continue;
}

dbEvent.Name = apiEvent.Name;
dbEvent.StartTime = apiEvent.StartTime.UtcDateTime;
dbEvent.EndTime = apiEvent.EndTime.UtcDateTime;
context.Events.Update(dbEvent);
response.UpsertedEvents.Add(dbEvent);
}
else
{
var newEvent = new Event
{
Id = new Guid(),
SeasonId = season.Id,
Key = GenerateEventKey(),
Code = apiEvent.EventCode,
Name = apiEvent.Name,
IsOfficial = false,
StartTime = apiEvent.StartTime.UtcDateTime,
EndTime = apiEvent.EndTime.UtcDateTime,
TimeZone = apiEvent.TimeZone.Id,
Status = "NotStarted",
SyncSource = request.DataSource
};

context.Events.Add(newEvent);
response.UpsertedEvents.Add(newEvent);
}
}

await context.SaveChangesAsync();
return response;
}

Expand All @@ -88,7 +122,7 @@ public async Task<UpsertEventsResponse> UpsertFromDataSource(UpsertFromDataSourc
return season;
}

private string GenerateEventKey()
private static string GenerateEventKey()
{
// Removes any ambiguous characters
const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
Expand All @@ -109,7 +143,7 @@ public class UpsertFromDataSourceRequest

public DataSources DataSource { get; set; }
public string? DistrictCode { get; set; }
public IEnumerable<string> EventCodes { get; set; } = Array.Empty<string>();
public IEnumerable<string> EventCodes { get; set; } = [];
}

public class UpsertEventsResponse
Expand Down

0 comments on commit 0e8878f

Please sign in to comment.