diff --git a/server/src/main/scala/ch.epfl.scala.index.server/routes/api/SearchApi.scala b/server/src/main/scala/ch.epfl.scala.index.server/routes/api/SearchApi.scala index 1dd37f72b..503752ace 100644 --- a/server/src/main/scala/ch.epfl.scala.index.server/routes/api/SearchApi.scala +++ b/server/src/main/scala/ch.epfl.scala.index.server/routes/api/SearchApi.scala @@ -28,11 +28,24 @@ object SearchApi { implicit val formatReleaseOptions: OFormat[ReleaseOptions] = Json.format[ReleaseOptions] + implicit val formatResult: OFormat[Result] = + Json.format[Result] + + case class Result(currentPage: Int, pageTotal: Int, items: Seq[Project]) case class Project( organization: String, repository: String, - logo: Option[String] = None, - artifacts: List[String] = Nil + logo: Option[String], + stars: Option[Int], + forks: Option[Int], + contributorCount: Option[Int], + topics: Set[String], + defaultArtifact: Option[String], + artifacts: List[String], + scalaVersion: List[String], + scalaJsVersion: List[String], + scalaNativeVersion: List[String], + sbtVersion: List[String] ) case class ReleaseOptions( @@ -91,7 +104,8 @@ class SearchApi( val routes: Route = pathPrefix("api") { cors() { - path("search") { + // deprecated endpoint replaced by api/search endpoint + path("search-old") { get { parameters( ( @@ -125,17 +139,6 @@ class SearchApi( sbtVersion ) - def convert(project: Project): SearchApi.Project = { - import project._ - val artifacts0 = if (cli) cliArtifacts.toList else artifacts - SearchApi.Project( - organization, - repository, - project.github.flatMap(_.logo.map(_.target)), - artifacts0 - ) - } - scalaTarget match { case Some(_) => val searchParams = SearchParams( @@ -147,7 +150,7 @@ class SearchApi( ) val result = dataRepository .findProjects(searchParams) - .map(page => page.items.map(p => convert(p))) + .map(page => page.items.map(convertProject(cli))) complete(OK, result) case None => @@ -158,6 +161,25 @@ class SearchApi( } } } ~ + path("search") { + get { + optionalSession(refreshable, usingCookies) { userId => + val user = session.getUser(userId) + searchParams(user) { params => + val result = dataRepository + .findProjects(params) + .map { page => + SearchApi.Result( + currentPage = page.pagination.current, + pageTotal = page.pagination.pageCount, + items = page.items.map(convertProject(params.cli)) + ) + } + complete(result) + } + } + } + } ~ path("project") { get { parameters( @@ -201,9 +223,8 @@ class SearchApi( optionalSession(refreshable, usingCookies) { userId => val user = session.getUser(userId) searchParams(user) { params => - complete { - autocomplete(params) - } + val autoCompletion = autocomplete(params) + complete(autoCompletion) } } } @@ -211,6 +232,28 @@ class SearchApi( } } + private def convertProject( + cli: Boolean + )(project: Project): SearchApi.Project = { + val artifacts = if (cli) project.cliArtifacts.toList else project.artifacts + val defaultArtifact = project.defaultArtifact.filter(artifacts.contains) + SearchApi.Project( + project.organization, + project.repository, + project.github.flatMap(_.logo.map(_.target)), + project.github.flatMap(_.stars), + project.github.flatMap(_.forks), + project.github.map(_.contributorCount), + project.github.map(_.topics).getOrElse(Set.empty), + defaultArtifact, + artifacts, + project.scalaVersion, + project.sbtVersion, + project.scalaJsVersion, + project.scalaNativeVersion + ) + } + private def getReleaseOptions( projectRef: Project.Reference, scalaTarget: Option[ScalaTarget], diff --git a/server/src/main/scala/ch.epfl.scala.index.server/routes/package.scala b/server/src/main/scala/ch.epfl.scala.index.server/routes/package.scala index 7e75f1049..32aebfc9f 100644 --- a/server/src/main/scala/ch.epfl.scala.index.server/routes/package.scala +++ b/server/src/main/scala/ch.epfl.scala.index.server/routes/package.scala @@ -10,6 +10,7 @@ package object routes { ( "q" ? "*", "page".as[Int] ? 1, + "total".as[Int] ? SearchParams.resultsPerPage, "sort".?, "topics".as[String].*, "targetTypes".as[String].*, @@ -17,13 +18,15 @@ package object routes { "scalaJsVersions".as[String].*, "scalaNativeVersions".as[String].*, "sbtVersions".as[String].*, - "you".?, - "contributingSearch".as[Boolean] ? false + "contributingSearch".as[Boolean] ? false, + "cli".as[Boolean] ? false, + "you".? ) ).tmap { case ( q, page, + total, sort, topics, targetTypes, @@ -31,8 +34,9 @@ package object routes { scalaJsVersions, scalaNativeVersions, sbtVersions, - you, - contributingSearch + contributingSearch, + cli, + you ) => val userRepos = you .flatMap(_ => user.map(_.repos)) @@ -42,8 +46,10 @@ package object routes { page, sort, userRepos, + total = total, topics = topics.toList, targetTypes = targetTypes.toList, + cli = cli, scalaVersions = scalaVersions.toList, scalaJsVersions = scalaJsVersions.toList, scalaNativeVersions = scalaNativeVersions.toList,