<commit_before>package effechecka

import akka.event.{LoggingAdapter, Logging}
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import spray.json._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.actor.ActorSystem
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.HttpHeader
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.stream.scaladsl.Flow
import akka.http.scaladsl.server.Directive0
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.StatusCode
import akka.http.scaladsl.model.MediaTypes

trait Protocols extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val occurrenceSelector = jsonFormat3(OccurrenceSelector)

  implicit val checklistFormat = jsonFormat2(ChecklistRequest)
  implicit val itemFormat = jsonFormat2(ChecklistItem)
  implicit val checklist2Format = jsonFormat3(Checklist)

  implicit val occurrenceRequestFormat = jsonFormat2(OccurrenceCollectionRequest)
  implicit val occurrenceFormat = jsonFormat8(Occurrence)
  implicit val occurrenceCollection2Format = jsonFormat3(OccurrenceCollection)
  implicit val occurrenceMonitorFormat = jsonFormat3(OccurrenceMonitor)
}


trait Service extends Protocols with ChecklistFetcher with OccurrenceCollectionFetcher {

  private def addAccessControlHeaders: Directive0 = {
    mapResponseHeaders { headers =>
      `Access-Control-Allow-Origin`.* +: headers
    }
  }

  val echoService: Flow[Message, Message, _] = Flow[Message].map {
    case TextMessage.Strict(txt) => TextMessage("ECHO: " + txt)
    case _ => TextMessage("Message type unsupported")
  }

  val route =
    logRequestResult("checklist-service") {
      addAccessControlHeaders {
        path("checklist") {
          get {
            parameters('taxonSelector.as[String], 'wktString.as[String], 'traitSelector.as[String] ? "").as(OccurrenceSelector) { ocSelector =>
              parameters('limit.as[Int] ? 20) { limit =>
                val checklist = ChecklistRequest(ocSelector, limit)
                val statusOpt: Option[String] = statusOf(checklist)
                val (items, status) = statusOpt match {
                  case Some("ready") => (itemsFor(checklist), "ready")
                  case None => (List(), request(checklist))
                  case _ => (List(), statusOpt.get)
                }
                complete {
                  Checklist(ocSelector, status, items)
                }
              }
            }
          }
        } ~ path("occurrences") {
          get {
            parameters('taxonSelector.as[String], 'wktString.as[String], 'traitSelector.as[String] ? "").as(OccurrenceSelector) { ocSelector =>
              parameters('limit.as[Int] ? 20) { limit =>
                val ocRequest = OccurrenceCollectionRequest(ocSelector, limit)
                val statusOpt: Option[String] = statusOf(ocRequest)
                val (items, status) = statusOpt match {
                  case Some("ready") => (occurrencesFor(ocRequest), "ready")
                  case None => (List(), request(ocRequest))
                  case _ => (List(), statusOpt.get)
                }
                complete {
                  OccurrenceCollection(ocSelector, status, items)
                }
              }
            }
          }
        } ~ path("monitors") {
          get {
            complete {
              monitors()
            }
          }
        } ~ path("ws-echo") {
          get {
            handleWebsocketMessages(echoService)
          }
        } ~ path("ping") {
          complete("pong")
        } ~ get {
          getFromResource("web/index.html")
        }
      }
    }<commit_msg>introduce occurrenceSelector case class<commit_after>package effechecka

import akka.event.{LoggingAdapter, Logging}
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import spray.json._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.actor.ActorSystem
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.HttpHeader
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.stream.scaladsl.Flow
import akka.http.scaladsl.server.Directive0
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.StatusCode
import akka.http.scaladsl.model.MediaTypes

trait Protocols extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val occurrenceSelector = jsonFormat3(OccurrenceSelector)

  implicit val checklistFormat = jsonFormat2(ChecklistRequest)
  implicit val itemFormat = jsonFormat2(ChecklistItem)
  implicit val checklist2Format = jsonFormat3(Checklist)

  implicit val occurrenceRequestFormat = jsonFormat2(OccurrenceCollectionRequest)
  implicit val occurrenceFormat = jsonFormat8(Occurrence)
  implicit val occurrenceCollection2Format = jsonFormat3(OccurrenceCollection)
  implicit val occurrenceMonitorFormat = jsonFormat3(OccurrenceMonitor)
}


trait Service extends Protocols with ChecklistFetcher with OccurrenceCollectionFetcher {

  private def addAccessControlHeaders: Directive0 = {
    mapResponseHeaders { headers =>
      `Access-Control-Allow-Origin`.* +: headers
    }
  }

  val echoService: Flow[Message, Message, _] = Flow[Message].map {
    case TextMessage.Strict(txt) => TextMessage("ECHO: " + txt)
    case _ => TextMessage("Message type unsupported")
  }

  val route =
    logRequestResult("checklist-service") {
      addAccessControlHeaders {
        path("checklist") {
          get {
            extractSelector { ocSelector =>
              parameters('limit.as[Int] ? 20) { limit =>
                val checklist = ChecklistRequest(ocSelector, limit)
                val statusOpt: Option[String] = statusOf(checklist)
                val (items, status) = statusOpt match {
                  case Some("ready") => (itemsFor(checklist), "ready")
                  case None => (List(), request(checklist))
                  case _ => (List(), statusOpt.get)
                }
                complete {
                  Checklist(ocSelector, status, items)
                }
              }
            }
          }
        } ~ path("occurrences") {
          get {
            extractSelector { ocSelector =>
              parameters('limit.as[Int] ? 20) { limit =>
                val ocRequest = OccurrenceCollectionRequest(ocSelector, limit)
                val statusOpt: Option[String] = statusOf(ocRequest)
                val (items, status) = statusOpt match {
                  case Some("ready") => (occurrencesFor(ocRequest), "ready")
                  case None => (List(), request(ocRequest))
                  case _ => (List(), statusOpt.get)
                }
                complete {
                  OccurrenceCollection(ocSelector, status, items)
                }
              }
            }
          }
        } ~ path("monitors") {
          get {
            complete {
              monitors()
            }
          }
        } ~ path("ws-echo") {
          get {
            handleWebsocketMessages(echoService)
          }
        } ~ path("ping") {
          complete("pong")
        } ~ get {
          getFromResource("web/index.html")
        }
      }
    }

  def extractSelector: OccurrenceSelector = {
    parameters('taxonSelector.as[String], 'wktString.as[String], 'traitSelector.as[String] ? "").as(OccurrenceSelector)
  }
{'fraction_non_alphanumeric': 0.0995861030979556, 'fraction_numerical': 0.004013545716794181, 'mean_word_length': 2.547153024911032, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '507989', 'n_tokens_mistral': 2251, 'n_tokens_neox': 2183, 'n_words': 408}