def updateContent()

in app/controllers/Files.scala [158:235]


  def updateContent(requestedId: Int) = IsAuthenticatedAsync(parse.multipartFormData) { uid => { request =>
    implicit val db = dbConfig.db
    logger.debug(s"updateContent called with requestedId: $requestedId")

    val sha256Option = request.body.dataParts.get("sha256").flatMap(_.headOption)
    logger.debug(s"SHA256 option received: $sha256Option")
    def calculateSha256(fileInputStream: FileInputStream): Future[String] = Future {
      val md = MessageDigest.getInstance("SHA-256")
      val stream = new BufferedInputStream(fileInputStream)

      try {
        val buffer = new Array[Byte](8192)
        Stream.continually(stream.read(buffer)).takeWhile(_ != -1).foreach { bytesRead =>
          md.update(buffer, 0, bytesRead)
        }
        val sha256 = md.digest().map("%02x".format(_)).mkString
        logger.debug(s"Calculated SHA256: $sha256")
        sha256
      } catch {
        case e: Exception =>
          println(s"updateContent error: ${e.toString}")
          logger.error("Error calculating SHA256", e)
          throw e
      }
      finally {
        stream.close()
      }
    }

    request.body.file("file") match {
      case Some(filePart) =>
        logger.info(s"File found: ${filePart.filename}, size: ${filePart.fileSize}")
        println(s"File found: ${filePart.filename}, size: ${filePart.fileSize}")
        val fileInputStream = new FileInputStream(filePart.ref.path.toFile)
        calculateSha256(fileInputStream).flatMap { calculatedSha =>
          logger.debug(s"SHA256 comparison: received $sha256Option, calculated $calculatedSha")
          println(s"SHA256 comparison: received $sha256Option, calculated $calculatedSha")
          if (sha256Option.contains(calculatedSha)) {
            db.run(
              TableQuery[FileEntryRow].filter(_.id === requestedId).result.headOption.asTry
            ).flatMap {
              case Success(Some(fileEntry: FileEntry)) =>
                logger.info(s"File entry found: $fileEntry")
                backupFile(fileEntry).flatMap { backupPath =>
                  logger.info(s"Backup successful: $backupPath")
                  // Now that the backup has succeeded, proceed with the update
                  logger.info("About to update file...")
                  fileEntryDAO.writeStreamToFile(fileEntry, new FileInputStream(filePart.ref.path.toFile)).map { _ =>
                    logger.info("File content update successful")
                    Ok(Json.obj("status" -> "ok", "detail" -> "File content has been updated."))
                  }
                }.recover { case error: Throwable =>
                  logger.error(s"Backup failed: ${error}")
                  println(s"Backup failed: ${error.toString}")
                  InternalServerError(Json.obj("status" -> "error", "detail" -> s"Backup failed: ${error.toString}"))
                }
              case Success(None) =>
                logger.warn(s"No file entry found for ID $requestedId")
                println((s"No file entry found for ID $requestedId"))
                Future.successful(NotFound(Json.obj("status" -> "error", "detail" -> s"File with ID $requestedId not found")))
              case Failure(error) =>
                logger.error("Database query failed", error)
                println("Database query failed", error.toString)
                Future.successful(InternalServerError(Json.obj("status" -> "error", "detail" -> error.toString)))
            }
          } else {
            logger.warn("SHA256 checksum does not match")
            println("SHA256 checksum does not match")
            Future.successful(BadRequest(Json.obj("status" -> "error", "detail" -> s"SHA256 checksum does not match - $sha256Option - $calculatedSha")))
          }
        }
      case None =>
        logger.warn("No file provided in the request")
        println("No file provided in the request")
        Future.successful(BadRequest(Json.obj("status" -> "error", "detail" -> "No file provided")))
    }
  }
  }