diff --git a/app/binders/QueryBinders.scala b/app/binders/QueryBinders.scala index 9493aca..eb5d10f 100644 --- a/app/binders/QueryBinders.scala +++ b/app/binders/QueryBinders.scala @@ -23,12 +23,15 @@ object QueryBinders { } implicit val hashedBindable = QueryStringBindable.bindableString.transform[Hashes]( - str => str.split('-') match { - case Array(sha1, md5) => Hashes(sha1 = sha1, md5 = md5) - }, + str => Hashes.unserialize(str), hashes => hashes.serialized ) + implicit val hashesPathBinder = new PathBindable[Hashes] { + override def bind(key: String, value: String): Either[String, Hashes] = Right(Hashes.unserialize(value)) + override def unbind(key: String, value: Hashes): String = value.serialized + } + implicit object MapStringIntJavascriptLiteral extends JavascriptLiteral[Map[String, Int]] { override def to(value: Map[String, Int]): String = formats.writes(value).toString() } diff --git a/app/com/ysoft/odc/OdcParser.scala b/app/com/ysoft/odc/OdcParser.scala index 0999934..dc8618f 100644 --- a/app/com/ysoft/odc/OdcParser.scala +++ b/app/com/ysoft/odc/OdcParser.scala @@ -33,6 +33,12 @@ final case class Hashes(sha1: String, md5: String){ def serialized = s"$sha1-$md5" } +object Hashes { + def unserialize(str: String): com.ysoft.odc.Hashes = str.split('-') match { + case Array(sha1, md5) => Hashes(sha1 = sha1, md5 = md5) + } +} + final case class Exclusion(sha1: String) extends AnyVal { def matches(dependency: Dependency): Boolean = dependency.sha1 == sha1 def matches(group: GroupedDependency): Boolean = group.sha1 == sha1 diff --git a/app/controllers/Statistics.scala b/app/controllers/Statistics.scala index eab4fae..33891c3 100644 --- a/app/controllers/Statistics.scala +++ b/app/controllers/Statistics.scala @@ -312,6 +312,18 @@ class Statistics @Inject()( } } + def library(selectorOption: Option[String], depId: Hashes) = ReadAction.async { implicit req => + val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions) + resultsFuture flatMap { allResults => + select(allResults, selectorOption).fold(Future.successful(notFound())) { selection => + Future.successful(Ok(views.html.library( + dep = selection.result.groupedDependenciesByHashes(depId), + selectorOption = selectorOption + ))) + } + } + } + def affectedProjects(depId: Hashes) = ReadAction.async { implicit req => val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions) resultsFuture flatMap { case (successfulResults, failedResults) => diff --git a/app/views/library.scala.html b/app/views/library.scala.html new file mode 100644 index 0000000..0c93947 --- /dev/null +++ b/app/views/library.scala.html @@ -0,0 +1,5 @@ +@(dep: GroupedDependency, selectorOption: Option[String])(implicit req: DefaultRequest, messages: Messages) +@main("Library details"){ + @libraryIdentificationList(dep, None, addLink = false, addButtons = false) + @dependencyDetailsInner(depPrefix = "library-single-", dep = dep, selectorOption = selectorOption) +} \ No newline at end of file diff --git a/conf/routes b/conf/routes index 72806b5..6f2e73b 100644 --- a/conf/routes +++ b/conf/routes @@ -22,6 +22,7 @@ POST /unsnooze/:snoozeId controllers.Application.unsnooze(s GET /https-test/with-redirect controllers.Application.testHttps(allowRedirect: Boolean = true) GET /https-test controllers.Application.testHttps(allowRedirect: Boolean = false) +GET /library/:depId controllers.Statistics.library(selectorOption: Option[String], depId: com.ysoft.odc.Hashes) GET /stats/dependency-details.htmlf controllers.Statistics.dependencyDetails(selectorOption: Option[String], depPrefix: String, depId: com.ysoft.odc.Hashes) GET /stats/affected-projects.htmlf controllers.Statistics.affectedProjects(depId: com.ysoft.odc.Hashes) GET /stats/basic controllers.Statistics.basic(selector: Option[String] = None)