Commit 33b40d53 authored by Björn Eyselein's avatar Björn Eyselein
Browse files

Small Updates Importer

parent c37e8d35
......@@ -86,6 +86,8 @@ class AdminController @Inject()(cc: ControllerComponents, protected val tableDef
FormMappings.newCollectionForm.bindFromRequest.fold(onError, onRead)
}
// Flashcards
def uploadCardsFile(courseId: Int, collId: Int): EssentialAction = futureWithUserAndCollection(courseId, collId) { (admin, collection) =>
implicit request =>
......@@ -97,9 +99,7 @@ class AdminController @Inject()(cc: ControllerComponents, protected val tableDef
failureStrings.foreach(println)
val futureImportedFlashcardsSaved = Future.sequence(importedFlashcards.map(
tableDefs.futureInsertCompleteFlashcard
))
val futureImportedFlashcardsSaved = Future.sequence(importedFlashcards.map(tableDefs.futureInsertCompleteFlashcard))
futureImportedFlashcardsSaved map { importedFlashcardsSaved =>
Ok(views.html.cardPreview(admin, courseId, collection, importedFlashcards, failureStrings))
......
......@@ -34,10 +34,10 @@ object Importer {
val sheet = workbook.getSheetAt(workbook.getActiveSheetIndex)
val firstRowWithoutHeaderInex = sheet.getFirstRowNum + 1
val firstRowWithoutHeaderIndex = sheet.getFirstRowNum + 1
// Ignore header ExcelRow
val readFlashcards = (firstRowWithoutHeaderInex to sheet.getLastRowNum) flatMap { rowIndex =>
val readFlashcards = (firstRowWithoutHeaderIndex to sheet.getLastRowNum) flatMap { rowIndex =>
Option(sheet.getRow(rowIndex)) match {
case None => None
case Some(row) => Some(readRow(row, courseId, collId))
......@@ -68,19 +68,13 @@ object Importer {
}
})
Right(Flashcard(cardId, collId, courseId, CardType.Choice, question, meaning = "", choiceAnswers = answers))
Right(Flashcard(cardId, collId, courseId, CardType.Choice, question, choiceAnswers = answers))
}
private def readWordRow(row: ExcelRow, courseId: Int, collId: Int, question: String): Either[String, Flashcard] =
readStringCell(row, meaningCellIndex) map { meaning =>
Flashcard(row.getRowNum, collId, courseId, CardType.Vocable, question, meaning)
}
private def readTextRow(row: ExcelRow, courseId: Int, collId: Int, question: String): Either[String, Flashcard] =
private def readTextualRow(row: ExcelRow, courseId: Int, collId: Int, cardType: CardType, question: String): Either[String, Flashcard] =
readStringCell(row, meaningCellIndex) map { meaning =>
Flashcard(row.getRowNum, collId, courseId, CardType.Text, question, meaning)
Flashcard(row.getRowNum, collId, courseId, cardType, question, meaning)
}
private def readBlankRow(row: ExcelRow, courseId: Int, collId: Int, question: String): Either[String, Flashcard] = {
......@@ -88,35 +82,24 @@ object Importer {
val (_, answers): (Seq[String], Seq[BlanksAnswer]) = partitionEitherSeq((meaningCellIndex to row.getLastCellNum).map { cellIndex =>
readStringCell(row, cellIndex) map {
answer =>
val id = cellIndex - meaningCellIndex
BlanksAnswer(id, cardId, collId, courseId, answer)
answer => BlanksAnswer(cellIndex - meaningCellIndex, cardId, collId, courseId, answer)
}
})
Right(Flashcard(cardId, collId, courseId, CardType.Blank, question, meaning = "", answers))
}
private def readRow(row: ExcelRow, courseId: Int, collId: Int): Either[String, Flashcard] =
readStringCell(row, cardTypeCellIndex) flatMap { cardTypeString: String =>
cardTypeFromString(cardTypeString) flatMap { cardType: CardType =>
readStringCell(row, questionCellIndex) flatMap { question: String =>
cardType match {
case CardType.Vocable => readWordRow(row, courseId, collId, question)
case CardType.Text => readTextRow(row, courseId, collId, question)
case CardType.Blank => readBlankRow(row, courseId, collId, question)
case CardType.Choice => readChoiceRow(row, courseId, collId, question)
}
}
}
private def readRow(row: ExcelRow, courseId: Int, collId: Int): Either[String, Flashcard] = for {
cardTypeString <- readStringCell(row, cardTypeCellIndex)
cardType <- cardTypeFromString(cardTypeString)
question <- readStringCell(row, questionCellIndex)
flashcard <- cardType match {
case CardType.Vocable | CardType.Text => readTextualRow(row, courseId, collId, cardType, question)
case CardType.Blank => readBlankRow(row, courseId, collId, question)
case CardType.Choice => readChoiceRow(row, courseId, collId, question)
}
} yield flashcard
private def readStringCell(row: ExcelRow, index: Int): Either[String, String] = {
val cell = row.getCell(index, MissingCellPolicy.CREATE_NULL_AS_BLANK)
......
......@@ -90,41 +90,30 @@ trait CoursesCollectionsFlashcardsTableQueries {
// Saving
def futureInsertCompleteFlashcard(completeFlashcard: Flashcard): Future[Boolean] = {
val dbCompleteFlashcard = PersistenceModels.flashcardToDbFlashcard(completeFlashcard)
futureInsertFlashcard(dbCompleteFlashcard.flashcard) flatMap { dbFlashcard =>
val futureSavedChoiceAnswers = Future.sequence(dbCompleteFlashcard.choiceAnswers.map { dbChoiceAnswer =>
futureInsertChoiceAnswer(dbChoiceAnswer.copy(cardId = dbFlashcard.cardId))
})
val futureSavedBlanksAnswers = Future.sequence(dbCompleteFlashcard.blanksAnswers.map { dbBlanksAnswer =>
futureInsertBlanksAnswer(dbBlanksAnswer.copy(cardId = dbFlashcard.cardId))
})
futureSavedChoiceAnswers.map {
savedAnswers => true
}
def futureInsertCompleteFlashcard(completeFlashcard: Flashcard): Future[Boolean] =
PersistenceModels.flashcardToDbFlashcard(completeFlashcard) match {
case DBCompleteFlashcard(flashcard, choiceAnswers, blanksAnswers) =>
futureInsertFlashcard(flashcard) flatMap {
case false => Future.successful(false)
case true =>
for {
futureSavedChoiceAnswers <- Future.sequence(choiceAnswers.map(futureInsertChoiceAnswer))
futureSavedBlanksAnswers <- Future.sequence(blanksAnswers.map(futureInsertBlanksAnswer))
} yield futureSavedChoiceAnswers.forall(identity) && futureSavedBlanksAnswers.forall(identity)
}
}
}
def futureInsertFlashcard(flashcard: DBFlashcard): Future[DBFlashcard] = {
val query = flashcardsTQ returning flashcardsTQ.map(_.id) into ((fc, newId) => fc.copy(cardId = newId))
db.run(query += flashcard)
}
private def futureInsertChoiceAnswer(choiceAnswer: ChoiceAnswer): Future[ChoiceAnswer] = {
val query = choiceAnswersTQ returning choiceAnswersTQ.map(_.id) into ((ca, newId) => ca.copy(answerId = newId))
db.run(query += choiceAnswer)
}
def futureInsertFlashcard(flashcard: DBFlashcard): Future[Boolean] =
db.run(flashcardsTQ insertOrUpdate flashcard).transform(_ == 1, identity)
private def futureInsertBlanksAnswer(blanksAnswer: BlanksAnswer): Future[BlanksAnswer] = {
val query = blanksAnswersTQ returning blanksAnswersTQ.map(_.id) into ((ca, newId) => ca.copy(answerId = newId))
private def futureInsertChoiceAnswer(choiceAnswer: ChoiceAnswer): Future[Boolean] =
db.run(choiceAnswersTQ insertOrUpdate choiceAnswer).transform(_ == 1, identity)
db.run(query += blanksAnswer)
}
private def futureInsertBlanksAnswer(blanksAnswer: BlanksAnswer): Future[Boolean] =
db.run(blanksAnswersTQ insertOrUpdate blanksAnswer).transform(_ == 1, identity)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment