Skip to content

Commit d2bb604

Browse files
committed
Added content from the completion of the Twitch hosted workshop on April 3, 2020
1 parent 14870c9 commit d2bb604

File tree

123 files changed

+43643
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+43643
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<PropertyGroup>
8+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
9+
<NoWarn>$(NoWarn);1591</NoWarn>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
14+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
15+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
16+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
<PrivateAssets>all</PrivateAssets>
19+
</PackageReference>
20+
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="3.1.3" />
21+
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
22+
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.0" />
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\ConferenceDTO\ConferenceDTO.csproj" />
27+
</ItemGroup>
28+
29+
<ItemGroup>
30+
<Protobuf Include="Protos\Sessions.proto" />
31+
</ItemGroup>
32+
33+
34+
</Project>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.AspNetCore.Http;
7+
using BackEnd.Data;
8+
using ConferenceDTO;
9+
10+
namespace BackEnd.Controllers
11+
{
12+
[Route("/api/[controller]")]
13+
[ApiController]
14+
public class AttendeesController : ControllerBase
15+
{
16+
private readonly ApplicationDbContext _db;
17+
18+
public AttendeesController(ApplicationDbContext db)
19+
{
20+
_db = db;
21+
}
22+
23+
[HttpGet("{username}")]
24+
[ProducesResponseType(StatusCodes.Status200OK)]
25+
[ProducesResponseType(StatusCodes.Status404NotFound)]
26+
[ProducesDefaultResponseType]
27+
public async Task<ActionResult<AttendeeResponse>> Get(string username)
28+
{
29+
var attendee = await _db.Attendees.Include(a => a.SessionsAttendees)
30+
.ThenInclude(sa => sa.Session)
31+
.SingleOrDefaultAsync(a => a.UserName == username);
32+
33+
if (attendee == null)
34+
{
35+
return NotFound();
36+
}
37+
38+
var result = attendee.MapAttendeeResponse();
39+
40+
return result;
41+
}
42+
43+
[HttpGet("{username}/sessions")]
44+
public async Task<ActionResult<List<SessionResponse>>> GetSessions(string username)
45+
{
46+
var sessions = await _db.Sessions.AsNoTracking()
47+
.Include(s => s.Track)
48+
.Include(s => s.SessionSpeakers)
49+
.ThenInclude(ss => ss.Speaker)
50+
.Where(s => s.SessionAttendees.Any(sa => sa.Attendee.UserName == username))
51+
.Select(m => m.MapSessionResponse())
52+
.ToListAsync();
53+
54+
return sessions;
55+
}
56+
57+
[HttpPost]
58+
[ProducesResponseType(StatusCodes.Status201Created)]
59+
[ProducesResponseType(StatusCodes.Status409Conflict)]
60+
public async Task<ActionResult<AttendeeResponse>> Post(ConferenceDTO.Attendee input)
61+
{
62+
// Check if the attendee already exists
63+
var existingAttendee = await _db.Attendees
64+
.Where(a => a.UserName == input.UserName)
65+
.FirstOrDefaultAsync();
66+
67+
if (existingAttendee != null)
68+
{
69+
return Conflict(input);
70+
}
71+
72+
var attendee = new Data.Attendee
73+
{
74+
FirstName = input.FirstName,
75+
LastName = input.LastName,
76+
UserName = input.UserName,
77+
EmailAddress = input.EmailAddress
78+
};
79+
80+
_db.Attendees.Add(attendee);
81+
await _db.SaveChangesAsync();
82+
83+
var result = attendee.MapAttendeeResponse();
84+
85+
return CreatedAtAction(nameof(Get), new { username = result.UserName }, result);
86+
}
87+
88+
[HttpPost("{username}/session/{sessionId}")]
89+
[ProducesResponseType(StatusCodes.Status200OK)]
90+
[ProducesResponseType(StatusCodes.Status400BadRequest)]
91+
[ProducesResponseType(StatusCodes.Status404NotFound)]
92+
[ProducesDefaultResponseType]
93+
public async Task<ActionResult<AttendeeResponse>> AddSession(string username, int sessionId)
94+
{
95+
var attendee = await _db.Attendees.Include(a => a.SessionsAttendees)
96+
.ThenInclude(sa => sa.Session)
97+
.SingleOrDefaultAsync(a => a.UserName == username);
98+
99+
if (attendee == null)
100+
{
101+
return NotFound();
102+
}
103+
104+
var session = await _db.Sessions.FindAsync(sessionId);
105+
106+
if (session == null)
107+
{
108+
return BadRequest();
109+
}
110+
111+
attendee.SessionsAttendees.Add(new SessionAttendee
112+
{
113+
AttendeeId = attendee.Id,
114+
SessionId = sessionId
115+
});
116+
117+
await _db.SaveChangesAsync();
118+
119+
var result = attendee.MapAttendeeResponse();
120+
121+
return result;
122+
}
123+
124+
[HttpDelete("{username}/session/{sessionId}")]
125+
[ProducesResponseType(StatusCodes.Status204NoContent)]
126+
[ProducesResponseType(StatusCodes.Status400BadRequest)]
127+
[ProducesResponseType(StatusCodes.Status404NotFound)]
128+
[ProducesDefaultResponseType]
129+
public async Task<IActionResult> RemoveSession(string username, int sessionId)
130+
{
131+
var attendee = await _db.Attendees.Include(a => a.SessionsAttendees)
132+
.SingleOrDefaultAsync(a => a.UserName == username);
133+
134+
if (attendee == null)
135+
{
136+
return NotFound();
137+
}
138+
139+
var session = await _db.Sessions.FindAsync(sessionId);
140+
141+
if (session == null)
142+
{
143+
return BadRequest();
144+
}
145+
146+
var sessionAttendee = attendee.SessionsAttendees.FirstOrDefault(sa => sa.SessionId == sessionId);
147+
attendee.SessionsAttendees.Remove(sessionAttendee);
148+
149+
await _db.SaveChangesAsync();
150+
151+
return NoContent();
152+
}
153+
}
154+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using BackEnd.Data;
2+
using BackEnd.Protos;
3+
using Grpc.Core;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
namespace BackEnd.Controllers
11+
{
12+
public class GrpcSessionController : Sessions.SessionsBase
13+
{
14+
15+
private readonly ApplicationDbContext _DbContext;
16+
17+
public GrpcSessionController(ApplicationDbContext dbContext)
18+
{
19+
_DbContext = dbContext;
20+
}
21+
22+
public override Task<SessionResponse> GetSessions(SessionRequest request, ServerCallContext context)
23+
{
24+
25+
var outResponse = new SessionResponse();
26+
outResponse.Sessions.AddRange(_DbContext.Sessions.Select<Data.Session, BackEnd.Protos.Session>(s => new BackEnd.Protos.Session
27+
{
28+
Id = s.Id,
29+
Abstract = s.Abstract,
30+
EndTime = s.EndTime.ToString(),
31+
StartTime = s.StartTime.ToString(),
32+
Title = s.Title
33+
}));
34+
35+
return Task.FromResult(outResponse);
36+
37+
}
38+
}
39+
40+
}
41+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.EntityFrameworkCore;
6+
using BackEnd.Data;
7+
using ConferenceDTO;
8+
9+
namespace BackEnd.Controllers
10+
{
11+
[Route("api/[controller]")]
12+
[ApiController]
13+
public class SearchController : ControllerBase
14+
{
15+
private readonly ApplicationDbContext _db;
16+
17+
public SearchController(ApplicationDbContext db)
18+
{
19+
_db = db;
20+
}
21+
22+
[HttpPost]
23+
public async Task<ActionResult<List<SearchResult>>> Search(SearchTerm term)
24+
{
25+
var query = term.Query.ToLowerInvariant();
26+
var sessionResults = (await _db.Sessions.Include(s => s.Track)
27+
.Include(s => s.SessionSpeakers)
28+
.ThenInclude(ss => ss.Speaker)
29+
.ToListAsync())
30+
.Where(s =>
31+
s.Title.ToLowerInvariant().Contains(query) ||
32+
s.Track.Name.ToLowerInvariant().Contains(query)
33+
)
34+
.ToList();
35+
36+
var speakerResults = (await _db.Speakers.Include(s => s.SessionSpeakers)
37+
.ThenInclude(ss => ss.Session)
38+
.ToListAsync())
39+
.Where(s =>
40+
(s.Name?.ToLowerInvariant().Contains(query) ?? false) ||
41+
(s.Bio?.ToLowerInvariant().Contains(query) ?? false) ||
42+
(s.WebSite?.ToLowerInvariant().Contains(query) ?? false)
43+
)
44+
.ToList();
45+
46+
var results = sessionResults.Select(session => new SearchResult
47+
{
48+
Type = SearchResultType.Session,
49+
Session = session.MapSessionResponse()
50+
})
51+
.Concat(speakerResults.Select(speaker => new SearchResult
52+
{
53+
Type = SearchResultType.Speaker,
54+
Speaker = speaker.MapSpeakerResponse()
55+
}));
56+
57+
return results.ToList();
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)