<commit_before>package im.actor.server.file.local.http

import java.time.{ Duration, Instant }

import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.StatusCodes.OK
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ Directive0, Route }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Source
import akka.util.ByteString
import im.actor.server.api.http.HttpHandler
import im.actor.server.db.DbExtension
import im.actor.server.file.local.{ FileStorageOperations, LocalFileStorageConfig, RequestSigning }
import im.actor.util.log.AnyRefLogSource

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.{ Failure, Success }

private[local] final class FilesHttpHandler(storageConfig: LocalFileStorageConfig)(implicit val system: ActorSystem)
  extends HttpHandler
  with RequestSigning
  with FileStorageOperations
  with AnyRefLogSource {

  private val db = DbExtension(system).db
  private implicit val mat = ActorMaterializer()

  protected implicit val ec: ExecutionContext = system.dispatcher
  protected val storageLocation = storageConfig.location

  private val log = Logging(system, this)

  // format: OFF
  def routes: Route =
    extractRequest { request =>
      //      log.debug("Got file request {}", request)
      defaultVersion {
        pathPrefix("files" / Segment) { strFileId =>
          val fileId = strFileId.toLong
          options {
            log.debug("Responded OK to OPTIONS req: {}", request.uri)
            complete(HttpResponse(OK))
          } ~
          validateRequest {
            get {
              //we use `Segments` because have to match paths like:
              //v1/files/:fileId/:fileName
              //v1/files/:fileId
              path(Segments(0, 1)) { seqName =>
                val optName = seqName.headOption
                log.debug("Download file request, fileId: {}, fileName: {}", fileId, optName)
                withRangeSupport {
                  onComplete(getFile(fileId, optName)) {
                    case Success(file) =>
                      log.debug("Serving file: {} parts", fileId)
                      complete(file.loadBytes)
                    case Failure(e) =>
                      log.error(e, "Failed to get file content, fileId: {}", fileId)
                      complete(HttpResponse(500))
                  }
                }
              }
            } ~
            put {
              pathSuffix(IntNumber) { partNumber =>
                log.debug("Upload file part request, fileId: {}, partNumber: {}", fileId, partNumber)
                extractRequest { req =>
                  val writeFu = for {
                    _ <- prepareForPartWrite(fileId, partNumber)
                    _ <- req.entity.dataBytes
                      .flatMapConcat[Unit](bs => Source(writeContent(bs, fileId, partNumber)))
                      .runForeach(_ => ())
                  } yield ()
                  onComplete(writeFu) {
                    case Success(_) =><commit_msg>fix(server:files): fixed compilation error<commit_after>package im.actor.server.file.local.http

import java.time.{ Duration, Instant }

import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.StatusCodes.OK
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ Directive0, Route }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Source
import akka.util.ByteString
import im.actor.server.api.http.HttpHandler
import im.actor.server.db.DbExtension
import im.actor.server.file.local.{ FileStorageOperations, LocalFileStorageConfig, RequestSigning }
import im.actor.util.log.AnyRefLogSource

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.{ Failure, Success }

private[local] final class FilesHttpHandler(storageConfig: LocalFileStorageConfig)(implicit val system: ActorSystem)
  extends HttpHandler
  with RequestSigning
  with FileStorageOperations
  with AnyRefLogSource {

  private val db = DbExtension(system).db
  private implicit val mat = ActorMaterializer()

  protected implicit val ec: ExecutionContext = system.dispatcher
  protected val storageLocation = storageConfig.location

  private val log = Logging(system, this)

  // format: OFF
  def routes: Route =
    extractRequest { request =>
      //      log.debug("Got file request {}", request)
      defaultVersion {
        pathPrefix("files" / Segment) { strFileId =>
          val fileId = strFileId.toLong
          options {
            log.debug("Responded OK to OPTIONS req: {}", request.uri)
            complete(HttpResponse(OK))
          } ~
          validateRequest {
            get {
              //we use `Segments` because have to match paths like:
              //v1/files/:fileId/:fileName
              //v1/files/:fileId
              path(Segments(0, 1)) { seqName =>
                val optName = seqName.headOption
                log.debug("Download file request, fileId: {}, fileName: {}", fileId, optName)
                withRangeSupport {
                  onComplete(getFile(fileId, optName)) {
                    case Success(file) =>
                      log.debug("Serving file: {} parts", fileId)
                      complete(file.loadBytes)
                    case Failure(e) =>
                      log.error(e, "Failed to get file content, fileId: {}", fileId)
                      complete(HttpResponse(500))
                  }
                }
              }
            } ~
            put {
              pathSuffix(IntNumber) { partNumber =>
                log.debug("Upload file part request, fileId: {}, partNumber: {}", fileId, partNumber)
                extractRequest { req =>
                  val writeFu = for {
                    _ <- prepareForPartWrite(fileId, partNumber)
                    _ <- req.entity.dataBytes
                      .flatMapConcat(bs => Source.fromFuture(writeContent(bs, fileId, partNumber)))
                      .runForeach(_ => ())
                  } yield ()
                  onComplete(writeFu) {
                    case Success(_) =>
{'fraction_non_alphanumeric': 0.0976038338658147, 'fraction_numerical': 0.0025559105431309905, 'mean_word_length': 2.1133764296369963, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7595249', 'n_tokens_mistral': 1698, 'n_tokens_neox': 1639, 'n_words': 375}