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

835 extend caption editing area UI #491

Merged
merged 8 commits into from
Dec 4, 2024
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
67 changes: 62 additions & 5 deletions ClassTranscribeServer/Controllers/CaptionsController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ClassTranscribeDatabase;
using ClassTranscribeDatabase.Models;
using ClassTranscribeServer.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -23,14 +24,16 @@ public class CaptionsController : BaseController
private readonly WakeDownloader _wakeDownloader;
private readonly CaptionQueries _captionQueries;
private readonly SubParser parser = new SubParser();
private readonly UserUtils _userUtils;

public CaptionsController(WakeDownloader wakeDownloader,
CTDbContext context,
CaptionQueries captionQueries,
CaptionQueries captionQueries, UserUtils userUtils,
ILogger<CaptionsController> logger) : base(context, logger)
{
_captionQueries = captionQueries;
_wakeDownloader = wakeDownloader;
_userUtils = userUtils;
}

// GET: api/Captions/ByTranscription/5
Expand Down Expand Up @@ -72,6 +75,9 @@ public async Task<ActionResult<string>> GetTranscriptionFile(string Transcriptio
[HttpGet]
public async Task<ActionResult<Caption>> GetCaption(string transcriptionId, int index)
{
// Note here that captions are effectively "stacked" on top of all other captions with the
// same transcription Id and Index.
// Then, getting a caption only returns the top caption of the stack with the newest creation date.
var captions = await _context.Captions.Where(c => c.TranscriptionId == transcriptionId && c.Index == index)
.OrderByDescending(c => c.CreatedAt).ToListAsync();
if (captions == null || captions.Count == 0)
Expand All @@ -86,32 +92,83 @@ public async Task<ActionResult<Caption>> GetCaption(string transcriptionId, int

// POST: api/Captions
[HttpPost]
[Authorize]
public async Task<ActionResult<Caption>> PostCaption(Caption modifiedCaption)
{
// This endpoint should handle deletion as well, which is represented by posting a caption
// with the empty string as text.

// This endpoint should be accessible only for people who are logged in
var user = await _userUtils.GetUser(User);
if (user == null)
{
return Unauthorized();
}

if (modifiedCaption == null || modifiedCaption.Id == null)
{
return BadRequest("modifiedCaption.Id not present");
}

Caption oldCaption = await _context.Captions.FindAsync(modifiedCaption.Id);
if (oldCaption == null)
{
return NotFound();
}
Caption newCaption = new Caption
{
Begin = oldCaption.Begin,
End = oldCaption.End,
Begin = modifiedCaption.Begin,
End = modifiedCaption.End,
Index = oldCaption.Index,
CaptionType = oldCaption.CaptionType,
Text = modifiedCaption.Text,
TranscriptionId = oldCaption.TranscriptionId
TranscriptionId = oldCaption.TranscriptionId,
LastUpdatedBy = user.Id,
CreatedBy = oldCaption.CreatedBy
};
_context.Captions.Add(newCaption);
await _context.SaveChangesAsync();
// nope _wakeDownloader.UpdateVTTFile(oldCaption.TranscriptionId);
return newCaption;
}

// POST: api/Captions/Add
[HttpPost("Add")]
[Authorize]
public async Task<ActionResult<Caption>> AddCaption(Caption newCaption)
{
// This endpoint should be accessible only for people who are logged in
var user = await _userUtils.GetUser(User);
if (user == null)
{
return Unauthorized();
}

if (newCaption == null)
{
return BadRequest("newCaption not present");
}

var allCaptions = await _context.Captions.Where(c => c.TranscriptionId == newCaption.TranscriptionId).ToListAsync();

// Every new caption must have a unique index to avoid conflicts with existing indices.
var newIndex = allCaptions.Max(c => c.Index) + 1;

Caption addedCaption = new Caption
{
Begin = newCaption.Begin,
End = newCaption.End,
Index = newIndex,
CaptionType = newCaption.CaptionType,
Text = newCaption.Text,
TranscriptionId = newCaption.TranscriptionId,
LastUpdatedBy = user.Id,
CreatedBy = user.Id
};
_context.Captions.Add(addedCaption);
await _context.SaveChangesAsync();
return addedCaption;
}

// POST: api/Captions/UpVote
[HttpPost("UpVote")]
public async Task<ActionResult<Caption>> UpVote(string id)
Expand Down
7 changes: 5 additions & 2 deletions TaskEngine.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ apt-get install -y netcat-traditional && apt-get -q update
# Microsoft 8.0 issue: https://github.com/Azure-Samples/cognitive-services-speech-sdk/issues/2204
# This will install OpenSSL 1.1.1 because it is needed by the Speech SDK.
# RUN ARCH=$(dpkg --print-architecture)
COPY ./install-speech-hack-libssl1.sh /
RUN /install-speech-hack-libssl1.sh
# COPY ./install-speech-hack-libssl1.sh /
# RUN wget /install-speech-hack-libssl1.sh

RUN wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb
RUN dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb


FROM publish_base as publish
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ public class CaptionsControllerTest : BaseControllerTest
public CaptionsControllerTest(GlobalFixture fixture) : base(fixture)
{
_controller = new CaptionsController(
(WakeDownloader) fixture._serviceProvider.GetService(typeof(WakeDownloader)),
(WakeDownloader)fixture._serviceProvider.GetService(typeof(WakeDownloader)),
_context,
new CaptionQueries(_context),
_userUtils,
null
);
)
{
ControllerContext = fixture._controllerContext
};
}

[Fact]
Expand Down Expand Up @@ -146,7 +150,7 @@ public async Task Post_Caption_Success()
Text = "foo bar",
CaptionType = CaptionType.TextCaption
};

_context.Users.Add(new ApplicationUser { Id = TestGlobals.TEST_USER_ID });
_context.Captions.Add(caption);
_context.SaveChanges();

Expand All @@ -162,6 +166,9 @@ public async Task Post_Caption_Success()
[Fact]
public async Task Post_Caption_Fail()
{
_context.Users.Add(new ApplicationUser { Id = TestGlobals.TEST_USER_ID });
_context.SaveChanges();

var result = await _controller.PostCaption(null);
Assert.IsType<BadRequestObjectResult>(result.Result);

Expand Down Expand Up @@ -320,7 +327,7 @@ public async Task Search_In_Offering_Fail()
public async Task Search_In_Offering()
{
var video = new Video { Id = "789" };

var transcriptions = new List<Transcription>()
{
new Transcription
Expand Down Expand Up @@ -359,9 +366,9 @@ public async Task Search_In_Offering()
};
var course = new Course { Id = "cid1" };
var offering = new Offering { Id = "oid8" };
var CourseOffering = new CourseOffering { Id = "2123000", CourseId = "cid1", OfferingId = "oid8"};
var playlist = new Playlist { Id = "2456" , OfferingId = offering.Id, Name = "Playlist 1"};
var media = new Media { Id = "2678", PlaylistId = playlist.Id , VideoId = video.Id, Name = "Media 1"};
var CourseOffering = new CourseOffering { Id = "2123000", CourseId = "cid1", OfferingId = "oid8" };
var playlist = new Playlist { Id = "2456", OfferingId = offering.Id, Name = "Playlist 1" };
var media = new Media { Id = "2678", PlaylistId = playlist.Id, VideoId = video.Id, Name = "Media 1" };
_context.Courses.Add(course);
_context.Offerings.Add(offering);
_context.CourseOfferings.Add(CourseOffering);
Expand All @@ -379,23 +386,24 @@ public async Task Search_In_Offering()
var onlyEnglishResults = await _controller.SearchInOffering(offering.Id, "fortran");
Assert.Single(onlyEnglishResults.Value);

var bothResults = await _controller.SearchInOffering(offering.Id, "fortran","");
var bothResults = await _controller.SearchInOffering(offering.Id, "fortran", "");

List<SearchedCaptionDTO> bothResultList = bothResults.Value.ToList();
Assert.Equal(captions.Count, bothResultList.Count());
for (int i = 0; i < captions.Count; i++) {
for (int i = 0; i < captions.Count; i++)
{
Assert.Equal(captions[i].Text, bothResultList[i].Caption.Text);
Assert.Equal(transcriptions[i].Language, bothResultList[i].Language );
Assert.Equal(transcriptions[i].Language, bothResultList[i].Language);
}

var oneFrenchResult = await _controller.SearchInOffering(offering.Id, "fortran", "fr");

Assert.Single(oneFrenchResult.Value);
var c = oneFrenchResult.Value.First();
Assert.Equal( captions[1].Text, c.Caption.Text);
var c = oneFrenchResult.Value.First();
Assert.Equal(captions[1].Text, c.Caption.Text);
Assert.Null(c.Caption.Transcription);
Assert.Equal(media.Id, c.MediaId );

Assert.Equal(media.Id, c.MediaId);
Assert.Equal(playlist.Id, c.PlaylistId);
Assert.Equal(media.Name, c.MediaName);
Assert.Equal(playlist.Name, c.PlaylistName);
Expand Down
Loading