Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new API endpoints for file manager/consume page #63

Merged
merged 3 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/Aquifer.API/Modules/Bibles/BibleResponse.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
namespace Aquifer.API.Modules.Bibles;

public class BibleBookResponse
public class BibleResponse
{
public int LanguageId { get; set; }
public string Name { get; set; } = null!;
public int Id { get; set; }
public required string Name { get; set; }
public required string Abbreviation { get; set; }

public IEnumerable<BibleBookResponseContent> Contents { get; set; } =
new List<BibleBookResponseContent>();
public required IEnumerable<BibleResponseBook> Books { get; set; }
}

public class BibleBookResponseContent
public class BibleResponseBook
{
public int BookId { get; set; }
public string DisplayName { get; set; } = null!;
public string TextUrl { get; set; } = null!;
public object? AudioUrls { get; set; }
public required string BookCode { get; set; }
public required string DisplayName { get; set; }
public int TextSize { get; set; }
public int AudioSize { get; set; }
public int ChapterCount { get; set; }
}

public class BibleBookDetailsResponse : BibleResponseBook
{
public string TextUrl { get; set; } = null!;
public object? AudioUrls { get; set; }
}
68 changes: 52 additions & 16 deletions src/Aquifer.API/Modules/Bibles/BiblesModule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Aquifer.API.Utilities;
using Aquifer.Data;
using Aquifer.Data;
using Aquifer.Data.Enums;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;

Expand All @@ -10,31 +10,67 @@ public class BiblesModule : IModule
public IEndpointRouteBuilder MapEndpoints(IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("bibles");
group.MapGet("language/{languageId:int}", GetBibleContentsByLanguage);
group.MapGet("language/{languageId:int}", GetBibleByLanguage);
group.MapGet("{bibleId:int}/book/{bookCode}", GetBibleBookDetails);

return endpoints;
}

private async Task<Ok<List<BibleBookResponse>>> GetBibleContentsByLanguage(int languageId,
private async Task<Ok<List<BibleResponse>>> GetBibleByLanguage(int languageId,
AquiferDbContext dbContext,
CancellationToken cancellationToken)
{
var bibles = await dbContext.Bibles.Where(x => x.LanguageId == languageId)
.Select(x => new BibleBookResponse
.Select(bible => new BibleResponse
{
LanguageId = x.LanguageId,
Name = x.Name,
Contents = x.BibleBookContents.Select(y => new BibleBookResponseContent
{
BookId = y.BookId,
DisplayName = y.DisplayName,
TextUrl = y.TextUrl,
TextSize = y.TextSize,
AudioUrls = JsonUtilities.DefaultSerialize(y.AudioUrls),
AudioSize = y.AudioSize
})
Name = bible.Name,
Abbreviation = bible.Abbreviation,
Id = bible.Id,
Books = bible.BibleBookContents.OrderBy(book => book.BookId).Select(book =>
new BibleResponseBook
{
BookCode = book.BookId.ToCode(),
DisplayName = book.DisplayName,
TextSize = book.TextSize,
AudioSize = book.AudioSize,
ChapterCount = book.ChapterCount
})
}).ToListAsync(cancellationToken);

return TypedResults.Ok(bibles);
}

private async Task<Results<Ok<BibleBookDetailsResponse>, NotFound>> GetBibleBookDetails(
int bibleId,
string bookCode,
AquiferDbContext dbContext,
CancellationToken cancellationToken)
{
var bookId = BookIdSerializer.FromCode(bookCode);
if (bookId == null)
{
return TypedResults.NotFound();
}

var book = await dbContext.BibleBookContents
.SingleOrDefaultAsync(b => b.BibleId == bibleId && b.BookId == bookId, cancellationToken);

if (book == null)
{
return TypedResults.NotFound();
}

var response = new BibleBookDetailsResponse
{
AudioSize = book.AudioSize,
AudioUrls = book.AudioUrls,
BookCode = book.BookId.ToCode(),
ChapterCount = book.ChapterCount,
DisplayName = book.DisplayName,
TextSize = book.TextSize,
TextUrl = book.TextUrl
};

return TypedResults.Ok(response);
}
}
4 changes: 2 additions & 2 deletions src/Aquifer.API/Modules/Languages/LanguageResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class LanguageResponse
{
public int Id { get; set; }
public string Iso6393Code { get; set; } = null!;
public string EnglishDisplay { get; set; } = null!;
public required string Iso6393Code { get; set; }
public required string EnglishDisplay { get; set; }
}
2 changes: 1 addition & 1 deletion src/Aquifer.API/Modules/Languages/LanguagesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public IEndpointRouteBuilder MapEndpoints(IEndpointRouteBuilder endpoints)
return endpoints;
}

public async Task<Ok<List<LanguageResponse>>> GetLanguages(AquiferDbContext dbContext)
private async Task<Ok<List<LanguageResponse>>> GetLanguages(AquiferDbContext dbContext)
{
var languages = await dbContext.Languages.Select(x => new LanguageResponse
{
Expand Down
43 changes: 0 additions & 43 deletions src/Aquifer.API/Modules/Passages/PassageResourcesResponse.cs

This file was deleted.

14 changes: 0 additions & 14 deletions src/Aquifer.API/Modules/Passages/PassageResponse.cs

This file was deleted.

144 changes: 93 additions & 51 deletions src/Aquifer.API/Modules/Passages/PassagesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,109 @@ namespace Aquifer.API.Modules.Passages;

public class PassagesModule : IModule
{
private static readonly ResourceEntityType[] AllowedResourceTypes = { ResourceEntityType.CBBTER };

public IEndpointRouteBuilder MapEndpoints(IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("passages");
group.MapGet("/resources/language/{languageId:int}", GetPassageResourcesByLanguage);
group.MapGet("language/{languageId:int}/resource/{resourceType}", GetPassagesByLanguageAndResource);
group.MapGet("{passageId:int}/language/{languageId:int}", GetPassageDetailsForLanguage);
return endpoints;
}

public async Task<Ok<List<PassageResourcesResponse>>> GetPassageResourcesByLanguage(int languageId,
private async Task<Results<Ok<List<PassagesBookResponse>>, NotFound>> GetPassagesByLanguageAndResource(
int languageId,
ResourceEntityType resourceType,
AquiferDbContext dbContext,
CancellationToken cancellationToken)
{
if (!AllowedResourceTypes.Contains(resourceType))
{
return TypedResults.NotFound();
}

var passagesByBook = (await dbContext.Passages
.Where(p => p.PassageResources.Any(pr =>
pr.Resource.Type == resourceType &&
pr.Resource.ResourceContents.Any(rc => rc.LanguageId == languageId)))
.Select(passage =>
new PassagesResponsePassage
{
Id = passage.Id,
PassageStartDetails = BibleUtilities.TranslateVerseId(passage.StartVerseId),
PassageEndDetails = BibleUtilities.TranslateVerseId(passage.EndVerseId)
}
).ToListAsync(cancellationToken))
.GroupBy(passage => passage.BookId)
.Select(grouped => new PassagesBookResponse
{
BookId = grouped.Key, Passages = grouped.OrderBy(p => p.StartChapter).ThenBy(p => p.StartVerse)
})
.OrderBy(book => book.BookId).ToList();

return TypedResults.Ok(passagesByBook);
}

private async Task<Results<Ok<PassageDetailsResponse>, NotFound>> GetPassageDetailsForLanguage(
int passageId,
int languageId,
AquiferDbContext dbContext,
CancellationToken cancellationToken)
{
var passageContent = (await dbContext.Passages.Select(passage =>
new PassageResourcesResponse
var passage = await dbContext.Passages.FindAsync(passageId, cancellationToken);
if (passage == null)
{
return TypedResults.NotFound();
}

var passageResourceContent = await dbContext.PassageResources
// find all passages that overlap with the current passage
.Where(pr => (pr.Passage.StartVerseId >= passage.StartVerseId &&
pr.Passage.StartVerseId <= passage.EndVerseId) ||
(pr.Passage.EndVerseId >= passage.StartVerseId &&
pr.Passage.EndVerseId <= passage.EndVerseId))
.SelectMany(pr => pr.Resource.ResourceContents.Where(rc => rc.LanguageId == languageId).Select(rc =>
new PassageDetailsResponseContent
{
PassageStartDetails = BibleUtilities.TranslateVerseId(passage.StartVerseId),
PassageEndDetails = BibleUtilities.TranslateVerseId(passage.EndVerseId),
Resources = passage.PassageResources
.Where(pr => pr.Resource.Type != ResourceEntityType.TyndaleBibleDictionary)
.Select(passageResource =>
new PassageResourcesResponseResource
{
Type = (int)passageResource.Resource.Type,
MediaType = (int)passageResource.Resource.MediaType,
EnglishLabel = passageResource.Resource.EnglishLabel,
Tag = passageResource.Resource.Tag,
Content =
passageResource.Resource.ResourceContents
.Select(resourceContent =>
new PassageResourcesResponseResourceContent
{
LanguageId = resourceContent.LanguageId,
DisplayName = resourceContent.DisplayName,
Summary = resourceContent.Summary,
Content = JsonUtilities.DefaultSerialize(resourceContent.Content),
ContentSize = resourceContent.ContentSize
}).FirstOrDefault(content => content.LanguageId == languageId),
SupportingResources = passageResource.Resource.SupportingResources
.Where(sr => sr.Type != ResourceEntityType.TyndaleBibleDictionary)
.Select(
supportingResource => new PassageResourcesResponseResource
{
Type = (int)supportingResource.Type,
MediaType = (int)supportingResource.MediaType,
EnglishLabel = supportingResource.EnglishLabel,
Tag = supportingResource.Tag,
Content = supportingResource.ResourceContents.Select(resourceContent =>
new PassageResourcesResponseResourceContent
{
LanguageId = resourceContent.LanguageId,
DisplayName = resourceContent.DisplayName,
Summary = resourceContent.Summary,
Content =
JsonUtilities.DefaultSerialize(resourceContent.Content),
ContentSize = resourceContent.ContentSize
}).FirstOrDefault(content => content.LanguageId == languageId)
})
})
}).ToListAsync(cancellationToken))
.OrderBy(passage => passage.BookId)
.ThenBy(passage => passage.StartChapter).ThenBy(passage => passage.StartVerse).ToList();
ContentId = rc.Id,
ContentSize = rc.ContentSize,
MediaTypeName = rc.MediaType,
TypeName = pr.Resource.Type
}))
.ToListAsync(cancellationToken);

var verseResourceContent = await dbContext.VerseResources
// find all verses contained within the current passage
.Where(vr => vr.VerseId >= passage.StartVerseId && vr.VerseId <= passage.EndVerseId)
.SelectMany(vr => vr.Resource.ResourceContents.Where(rc => rc.LanguageId == languageId).Select(rc =>
new PassageDetailsResponseContent
{
ContentId = rc.Id,
ContentSize = rc.ContentSize,
MediaTypeName = rc.MediaType,
TypeName = vr.Resource.Type
}))
.ToListAsync(cancellationToken);

var supportingResourceContent = await dbContext.PassageResources.Where(pr => pr.PassageId == passageId)
.SelectMany(pr => pr.Resource.SupportingResources
.SelectMany(sr => sr.ResourceContents.Where(rc => rc.LanguageId == languageId)
.Select(rc => new PassageDetailsResponseContent
{
ContentId = rc.Id,
ContentSize = rc.ContentSize,
MediaTypeName = rc.MediaType,
TypeName = sr.Type
})))
.ToListAsync(cancellationToken);

return TypedResults.Ok(passageContent);
return TypedResults.Ok(new PassageDetailsResponse
{
Id = passage.Id,
PassageStartDetails = BibleUtilities.TranslateVerseId(passage.StartVerseId),
PassageEndDetails = BibleUtilities.TranslateVerseId(passage.EndVerseId),
Contents = passageResourceContent.Concat(verseResourceContent).Concat(supportingResourceContent)
.DistinctBy(rc => rc.ContentId)
});
MrGrinst marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading