From e688289ae32a6804048bf178d59caa7dfa3bdcf6 Mon Sep 17 00:00:00 2001 From: toddn Date: Tue, 3 Aug 2021 14:21:39 -0500 Subject: [PATCH 01/18] adding parameter spaceBytes inside getSpace --- app/controllers/Spaces.scala | 46 +++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/app/controllers/Spaces.scala b/app/controllers/Spaces.scala index f95d5b07b..f677c964f 100644 --- a/app/controllers/Spaces.scala +++ b/app/controllers/Spaces.scala @@ -1,31 +1,22 @@ package controllers -import java.net.URL -import java.util.{ Calendar, Date } -import javax.inject.Inject - import api.Permission import api.Permission._ import models._ -import play.api.{ Logger, Play } -import play.api.data.Forms._ -import play.api.data.{ Form, Forms } -import play.api.libs.json.JsValue -import play.api.libs.json.Json -import play.api.i18n.Messages -import services._ -import securesocial.core.providers.{ Token, UsernamePasswordProvider } import org.joda.time.DateTime +import play.api.data.Forms._ +import play.api.data.{Form, Forms} import play.api.i18n.Messages -import play.api.libs.ws._ -import services.AppConfiguration -import util.{ Formatters, Mail, Publications } +import play.api.{Logger, Play} +import securesocial.core.providers.{Token, UsernamePasswordProvider} +import services.{AppConfiguration, _} +import util.{Formatters, Mail, Publications} +import java.net.URL +import java.util.{Calendar, Date} +import javax.inject.Inject import scala.collection.immutable.List -import scala.collection.mutable.{ ArrayBuffer, ListBuffer } -import scala.concurrent.{ Future, Await } -import scala.concurrent.duration._ -import org.apache.commons.lang.StringEscapeUtils.escapeJava +import scala.collection.mutable.{ArrayBuffer, ListBuffer} /** * Spaces allow users to partition the data into realms only accessible to users with the right permissions. @@ -176,6 +167,23 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS var creatorActual: User = null val collectionsInSpace = spaces.getCollectionsInSpace(Some(id.stringify), Some(size)) val datasetsInSpace = datasets.listSpace(size, id.toString(), user) + val allDatasetsInSpace = datasets.listSpace(0, id.toString(), user) + var spaceBytes: Long = 0 + for (ds <- allDatasetsInSpace){ + val ds_files = ds.files + for (ds_f <- ds_files){ + files.get(ds_f) match { + case Some(file) => { + files.getBytes(file.id) match { + case Some((stream, name, filetype, bytes)) => { + var current_bytes : Long = bytes + spaceBytes += current_bytes + } + } + } + } + } + } val publicDatasetsInSpace = datasets.listSpaceStatus(size, id.toString(), "publicAll", user) val usersInSpace = spaces.getUsersInSpace(id, None) var curationObjectsInSpace: List[CurationObject] = List() From 5e9040b79c4f7e44132fa7d1999658a8c4c895c6 Mon Sep 17 00:00:00 2001 From: toddn Date: Wed, 4 Aug 2021 14:56:41 -0500 Subject: [PATCH 02/18] add method getBytesPerSpace changing html --- app/controllers/SecuredController.scala | 7 ++--- app/controllers/Spaces.scala | 41 ++++++++++++++----------- app/views/spaces/space.scala.html | 2 +- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/app/controllers/SecuredController.scala b/app/controllers/SecuredController.scala index be5035931..700d6d0fb 100644 --- a/app/controllers/SecuredController.scala +++ b/app/controllers/SecuredController.scala @@ -2,14 +2,11 @@ package controllers import api.Permission.Permission import api.{Permission, UserRequest} -import models.{ClowderUser, RequestResource, ResourceRef, User, UserStatus} -import org.apache.commons.lang.StringEscapeUtils._ +import models.{ClowderUser, ResourceRef, User, UserStatus} import play.api.i18n.Messages import play.api.mvc._ import securesocial.core.{Authenticator, SecureSocial, UserService} import services._ -import securesocial.core.IdentityProvider -import securesocial.core.providers.utils.RoutesHelper import scala.concurrent.Future @@ -156,7 +153,7 @@ trait SecuredController extends Controller { val spaces: SpaceService = DI.injector.getInstance(classOf[SpaceService]) spaces.get(id) match { case None => Future.successful(BadRequest(views.html.notFound(spaceTitle + " does not exist.")(user))) - case Some(space) => Future.successful(Forbidden(views.html.spaces.space(space,List(),List(),List(),List(),"", Map(),List())(user))) + case Some(space) => Future.successful(Forbidden(views.html.spaces.space(space,List(),List(),List(),List(),"", Map(),List(),0)(user))) } } diff --git a/app/controllers/Spaces.scala b/app/controllers/Spaces.scala index f677c964f..cb6089195 100644 --- a/app/controllers/Spaces.scala +++ b/app/controllers/Spaces.scala @@ -167,23 +167,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS var creatorActual: User = null val collectionsInSpace = spaces.getCollectionsInSpace(Some(id.stringify), Some(size)) val datasetsInSpace = datasets.listSpace(size, id.toString(), user) - val allDatasetsInSpace = datasets.listSpace(0, id.toString(), user) - var spaceBytes: Long = 0 - for (ds <- allDatasetsInSpace){ - val ds_files = ds.files - for (ds_f <- ds_files){ - files.get(ds_f) match { - case Some(file) => { - files.getBytes(file.id) match { - case Some((stream, name, filetype, bytes)) => { - var current_bytes : Long = bytes - spaceBytes += current_bytes - } - } - } - } - } - } + var spaceBytes : Long = getBytesPerSpace(id, user.get) val publicDatasetsInSpace = datasets.listSpaceStatus(size, id.toString(), "publicAll", user) val usersInSpace = spaces.getUsersInSpace(id, None) var curationObjectsInSpace: List[CurationObject] = List() @@ -232,7 +216,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS case None => List.empty } sinkService.logSpaceViewEvent(s, user) - Ok(views.html.spaces.space(Utils.decodeSpaceElements(s), collectionsInSpace, publicDatasetsInSpace, datasetsInSpace, rs, play.Play.application().configuration().getString("SEADservices.uri"), userRoleMap, userSelections)) + Ok(views.html.spaces.space(Utils.decodeSpaceElements(s), collectionsInSpace, publicDatasetsInSpace, datasetsInSpace, rs, play.Play.application().configuration().getString("SEADservices.uri"), userRoleMap, userSelections, spaceBytes)) } case None => BadRequest(views.html.notFound(spaceTitle + " does not exist.")) } @@ -656,4 +640,25 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS } } + private def getBytesPerSpace(spaceId: UUID, user: models.User) : Long = { + val allDatasetsInSpace = datasets.listSpace(0, spaceId.toString(), Some(user)) + var spaceBytes: Long = 0 + for (ds <- allDatasetsInSpace){ + val ds_files = ds.files + for (ds_f <- ds_files){ + files.get(ds_f) match { + case Some(file) => { + files.getBytes(file.id) match { + case Some((stream, name, filetype, bytes)) => { + var current_bytes : Long = bytes + spaceBytes += current_bytes + } + } + } + } + } + } + spaceBytes + } + } diff --git a/app/views/spaces/space.scala.html b/app/views/spaces/space.scala.html index 419a443f6..0bc701bf1 100644 --- a/app/views/spaces/space.scala.html +++ b/app/views/spaces/space.scala.html @@ -1,4 +1,4 @@ -@(space: ProjectSpace, collections: List[Collection], publicDatasets: List[Dataset], datasets: List[Dataset], publishedData: List[play.api.libs.json.JsValue], servicesUrl: String, userRoleMap: Map[User, String], userSelections: List[String])(implicit user: Option[models.User]) +@(space: ProjectSpace, collections: List[Collection], publicDatasets: List[Dataset], datasets: List[Dataset], publishedData: List[play.api.libs.json.JsValue], servicesUrl: String, userRoleMap: Map[User, String], userSelections: List[String], spaceBytes: Long)(implicit user: Option[models.User]) @import play.api.libs.json._ @import play.api.Play.current From 591c11ebe24474ec3195bfbfce7ce46cf82e7808 Mon Sep 17 00:00:00 2001 From: toddn Date: Wed, 4 Aug 2021 15:06:45 -0500 Subject: [PATCH 03/18] adding to space statistics need cleanup --- app/views/spaces/space.scala.html | 3 ++- app/views/spaces/statistics.scala.html | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/spaces/space.scala.html b/app/views/spaces/space.scala.html index 0bc701bf1..c3f020f43 100644 --- a/app/views/spaces/space.scala.html +++ b/app/views/spaces/space.scala.html @@ -110,9 +110,10 @@

@Messages("collections.title")

@if(user.isDefined) { + @spaces.statistics(space, spaceBytes,"row ds-section-sm space-col-right") @spaces.otherActions(space) } else { - @spaces.statistics(space, "row ds-section-sm space-col-right") + @spaces.statistics(space, spaceBytes, "row ds-section-sm space-col-right") } @spaces.externalLinks(space.homePage, space, "row ds-section-sm break-word space-col-right") @if(play.Play.application().configuration().getBoolean("enablePublic")) { diff --git a/app/views/spaces/statistics.scala.html b/app/views/spaces/statistics.scala.html index 2175d0869..506c14197 100644 --- a/app/views/spaces/statistics.scala.html +++ b/app/views/spaces/statistics.scala.html @@ -1,11 +1,13 @@ -@(space: ProjectSpace, classes: String)(implicit user: Option[models.User]) +@(space: ProjectSpace, spaceBytes: Long, classes: String)(implicit user: Option[models.User]) @import play.api.i18n.Messages +@import _root_.util.Formatters._

Statistics

Members: @space.userCount

Collections: @space.collectionCount

Datasets: @space.datasetCount

+

@humanReadableByteCount(spaceBytes)

From befcf40b81ed415c12fd3895dd0f0afba46011b5 Mon Sep 17 00:00:00 2001 From: toddn Date: Mon, 9 Aug 2021 17:17:50 -0500 Subject: [PATCH 04/18] statistics changed - replaced with more data modeled on the index page We now see Collections, Datasets, Files, Bytes per space and Users in right column --- app/controllers/SecuredController.scala | 2 +- app/controllers/Spaces.scala | 17 +++++++++-- app/views/spaces/space.scala.html | 6 ++-- app/views/spaces/statistics.scala.html | 38 ++++++++++++++++++++----- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/app/controllers/SecuredController.scala b/app/controllers/SecuredController.scala index 700d6d0fb..0f527f3db 100644 --- a/app/controllers/SecuredController.scala +++ b/app/controllers/SecuredController.scala @@ -153,7 +153,7 @@ trait SecuredController extends Controller { val spaces: SpaceService = DI.injector.getInstance(classOf[SpaceService]) spaces.get(id) match { case None => Future.successful(BadRequest(views.html.notFound(spaceTitle + " does not exist.")(user))) - case Some(space) => Future.successful(Forbidden(views.html.spaces.space(space,List(),List(),List(),List(),"", Map(),List(),0)(user))) + case Some(space) => Future.successful(Forbidden(views.html.spaces.space(space,List(),List(),List(),List(),"", Map(),List(),0,0)(user))) } } diff --git a/app/controllers/Spaces.scala b/app/controllers/Spaces.scala index cb6089195..dff45c491 100644 --- a/app/controllers/Spaces.scala +++ b/app/controllers/Spaces.scala @@ -9,7 +9,7 @@ import play.api.data.{Form, Forms} import play.api.i18n.Messages import play.api.{Logger, Play} import securesocial.core.providers.{Token, UsernamePasswordProvider} -import services.{AppConfiguration, _} +import services._ import util.{Formatters, Mail, Publications} import java.net.URL @@ -167,7 +167,8 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS var creatorActual: User = null val collectionsInSpace = spaces.getCollectionsInSpace(Some(id.stringify), Some(size)) val datasetsInSpace = datasets.listSpace(size, id.toString(), user) - var spaceBytes : Long = getBytesPerSpace(id, user.get) + val spaceBytes : Long = getBytesPerSpace(id, user.get) + val spaceFiles : Integer = getFilesPerSpace(id, user.get) val publicDatasetsInSpace = datasets.listSpaceStatus(size, id.toString(), "publicAll", user) val usersInSpace = spaces.getUsersInSpace(id, None) var curationObjectsInSpace: List[CurationObject] = List() @@ -216,7 +217,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS case None => List.empty } sinkService.logSpaceViewEvent(s, user) - Ok(views.html.spaces.space(Utils.decodeSpaceElements(s), collectionsInSpace, publicDatasetsInSpace, datasetsInSpace, rs, play.Play.application().configuration().getString("SEADservices.uri"), userRoleMap, userSelections, spaceBytes)) + Ok(views.html.spaces.space(Utils.decodeSpaceElements(s), collectionsInSpace, publicDatasetsInSpace, datasetsInSpace, rs, play.Play.application().configuration().getString("SEADservices.uri"), userRoleMap, userSelections, spaceBytes, spaceFiles)) } case None => BadRequest(views.html.notFound(spaceTitle + " does not exist.")) } @@ -640,6 +641,16 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS } } + private def getFilesPerSpace(spaceId: UUID, user: models.User) : Integer = { + var spaceFiles: Integer = 0 + val allDatasetsInSpace = datasets.listSpace(0, spaceId.toString(), Some(user)) + for (ds <- allDatasetsInSpace) { + val files_in_ds = ds.files.length + spaceFiles += files_in_ds + } + spaceFiles + } + private def getBytesPerSpace(spaceId: UUID, user: models.User) : Long = { val allDatasetsInSpace = datasets.listSpace(0, spaceId.toString(), Some(user)) var spaceBytes: Long = 0 diff --git a/app/views/spaces/space.scala.html b/app/views/spaces/space.scala.html index c3f020f43..f4501391a 100644 --- a/app/views/spaces/space.scala.html +++ b/app/views/spaces/space.scala.html @@ -1,4 +1,4 @@ -@(space: ProjectSpace, collections: List[Collection], publicDatasets: List[Dataset], datasets: List[Dataset], publishedData: List[play.api.libs.json.JsValue], servicesUrl: String, userRoleMap: Map[User, String], userSelections: List[String], spaceBytes: Long)(implicit user: Option[models.User]) +@(space: ProjectSpace, collections: List[Collection], publicDatasets: List[Dataset], datasets: List[Dataset], publishedData: List[play.api.libs.json.JsValue], servicesUrl: String, userRoleMap: Map[User, String], userSelections: List[String], spaceBytes: Long, spaceFiles: Integer)(implicit user: Option[models.User]) @import play.api.libs.json._ @import play.api.Play.current @@ -110,10 +110,10 @@

@Messages("collections.title")

@if(user.isDefined) { - @spaces.statistics(space, spaceBytes,"row ds-section-sm space-col-right") + @spaces.statistics(space, spaceBytes,"row ds-section-sm space-col-right", None, spaceFiles ) @spaces.otherActions(space) } else { - @spaces.statistics(space, spaceBytes, "row ds-section-sm space-col-right") + @spaces.statistics(space, spaceBytes, "row ds-section-sm space-col-right",None, spaceFiles) } @spaces.externalLinks(space.homePage, space, "row ds-section-sm break-word space-col-right") @if(play.Play.application().configuration().getBoolean("enablePublic")) { diff --git a/app/views/spaces/statistics.scala.html b/app/views/spaces/statistics.scala.html index 506c14197..f9e823d30 100644 --- a/app/views/spaces/statistics.scala.html +++ b/app/views/spaces/statistics.scala.html @@ -1,13 +1,37 @@ -@(space: ProjectSpace, spaceBytes: Long, classes: String)(implicit user: Option[models.User]) +@(space: ProjectSpace, spaceBytes: Long, classes: String, isPublic: Option[Boolean], spaceFiles: Integer)(implicit user: Option[models.User]) @import play.api.i18n.Messages @import _root_.util.Formatters._
-
-

Statistics

-

Members: @space.userCount

-

Collections: @space.collectionCount

-

Datasets: @space.datasetCount

-

@humanReadableByteCount(spaceBytes)

+
+
+
+

Resources

+
+
+ +
+
From 893f418297622b193ee16c9c58de9ee9257b219f Mon Sep 17 00:00:00 2001 From: toddn Date: Mon, 9 Aug 2021 17:20:05 -0500 Subject: [PATCH 05/18] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c428d6a5b..7817f14b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Changed space page to show bytes per space. [#119](https://github.com/clowder-framework/clowder/issues/119) ### Fixed - Added index for comments, will speed up index creation From de73a6cf79ee92b69dd58ca4b4fe838bdb2786fd Mon Sep 17 00:00:00 2001 From: toddn Date: Thu, 19 Aug 2021 17:33:07 -0500 Subject: [PATCH 06/18] adding spaceBytes parameter, does not work yet --- app/api/Spaces.scala | 2 +- app/controllers/Spaces.scala | 2 +- app/models/Space.scala | 4 +++- app/services/mongodb/MongoSalatPlugin.scala | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/api/Spaces.scala b/app/api/Spaces.scala index 21931c678..859dbdfcf 100644 --- a/app/api/Spaces.scala +++ b/app/api/Spaces.scala @@ -41,7 +41,7 @@ class Spaces @Inject()(spaces: SpaceService, val userId = request.user.get.id val c = ProjectSpace(name = name, description = description, created = new Date(), creator = userId, homePage = List.empty, logoURL = None, bannerURL = None, collectionCount = 0, - datasetCount = 0, userCount = 0, metadata = List.empty) + datasetCount = 0, userCount = 0, spaceBytes = 0, metadata = List.empty) spaces.insert(c) match { case Some(id) => { appConfig.incrementCount('spaces, 1) diff --git a/app/controllers/Spaces.scala b/app/controllers/Spaces.scala index dff45c491..522a948f8 100644 --- a/app/controllers/Spaces.scala +++ b/app/controllers/Spaces.scala @@ -414,7 +414,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS val newSpace = ProjectSpace(name = formData.name, description = formData.description, created = new Date, creator = userId, homePage = formData.homePage, logoURL = formData.logoURL, bannerURL = formData.bannerURL, - collectionCount = 0, datasetCount = 0, userCount = 0, metadata = List.empty, + collectionCount = 0, datasetCount = 0, userCount = 0, spaceBytes = 0, metadata = List.empty, resourceTimeToLive = formData.resourceTimeToLive * 60 * 60 * 1000L, isTimeToLiveEnabled = formData.isTimeToLiveEnabled, status = formData.access, affiliatedSpaces = formData.affSpace) diff --git a/app/models/Space.scala b/app/models/Space.scala index 0e0df7079..6f2d545e1 100644 --- a/app/models/Space.scala +++ b/app/models/Space.scala @@ -23,6 +23,7 @@ case class ProjectSpace ( collectionCount: Integer, datasetCount: Integer, userCount: Integer, + spaceBytes: Long, metadata: List[Metadata], resourceTimeToLive: Long = SpaceConfig.getTimeToLive(), isTimeToLiveEnabled: Boolean = SpaceConfig.getIsTimeToLiveEnabled(), @@ -52,7 +53,8 @@ case class UserSpace ( bannerURL: Option[URL], collectionCount: Integer, datasetCount: Integer, - userCount: Integer) + userCount: Integer, + spaceBytes: Long) case class SpaceInvite( id: UUID = UUID.generate, diff --git a/app/services/mongodb/MongoSalatPlugin.scala b/app/services/mongodb/MongoSalatPlugin.scala index a695cb602..bf3fc06de 100644 --- a/app/services/mongodb/MongoSalatPlugin.scala +++ b/app/services/mongodb/MongoSalatPlugin.scala @@ -514,7 +514,7 @@ class MongoSalatPlugin(app: Application) extends Plugin { val spacename = java.net.InetAddress.getLocalHost.getHostName val newspace = new ProjectSpace(name = spacename, description = "", created = new Date(), creator = UUID("000000000000000000000000"), homePage = List.empty[URL], logoURL = None, bannerURL = None, metadata = List.empty[Metadata], - collectionCount = collections.toInt, datasetCount = datasets.toInt, userCount = users.toInt) + collectionCount = collections.toInt, datasetCount = datasets.toInt, userCount = users.toInt, spaceBytes = 0) ProjectSpaceDAO.save(newspace) val spaceId = new ObjectId(newspace.id.stringify) From d1235f8f75f41b08fbb5e9aad59c50cf7fbd768d Mon Sep 17 00:00:00 2001 From: toddn Date: Thu, 19 Aug 2021 17:57:20 -0500 Subject: [PATCH 07/18] new method, get bytes for dataset --- app/services/DatasetService.scala | 2 ++ app/services/mongodb/MongoDBDatasetService.scala | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/app/services/DatasetService.scala b/app/services/DatasetService.scala index d2538b4b1..071a707bf 100644 --- a/app/services/DatasetService.scala +++ b/app/services/DatasetService.scala @@ -295,6 +295,8 @@ trait DatasetService { def findMetadataChangedDatasets(): List[Dataset] + def getBytesForDataset(datasetId: UUID) : Long + /** * Check recursively whether a dataset's user-input metadata match a requested search tree. */ diff --git a/app/services/mongodb/MongoDBDatasetService.scala b/app/services/mongodb/MongoDBDatasetService.scala index f2e2616c0..ba59696bd 100644 --- a/app/services/mongodb/MongoDBDatasetService.scala +++ b/app/services/mongodb/MongoDBDatasetService.scala @@ -1068,6 +1068,17 @@ class MongoDBDatasetService @Inject() ( Dataset.find(MongoDBObject("userMetadataWasModified" -> true)).toList } + def getBytesPerDataset(datasetId: UUID) : Long = { + val dataset = Dataset.findOneById(new ObjectId(datasetId.stringify)).get + val datasetFiles = dataset.files + var datasetBytes : Long = 0 + datasetFiles.foreach{ f => { + val currentFileBytes = files.get(f).get.length + datasetBytes += currentFileBytes + }} + datasetBytes + } + def removeTag(id: UUID, tagId: UUID) { Logger.debug("Removing tag " + tagId) val result = Dataset.update(MongoDBObject("_id" -> new ObjectId(id.stringify)), $pull("tags" -> MongoDBObject("_id" -> new ObjectId(tagId.stringify))), false, false, WriteConcern.Safe) From 505474ab2747bf4ad9634d97be22dc206e36f7db Mon Sep 17 00:00:00 2001 From: toddn Date: Fri, 20 Aug 2021 16:17:00 -0500 Subject: [PATCH 08/18] methods need to match --- app/services/mongodb/MongoDBDatasetService.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/mongodb/MongoDBDatasetService.scala b/app/services/mongodb/MongoDBDatasetService.scala index ba59696bd..dac16f0c1 100644 --- a/app/services/mongodb/MongoDBDatasetService.scala +++ b/app/services/mongodb/MongoDBDatasetService.scala @@ -1068,7 +1068,7 @@ class MongoDBDatasetService @Inject() ( Dataset.find(MongoDBObject("userMetadataWasModified" -> true)).toList } - def getBytesPerDataset(datasetId: UUID) : Long = { + def getBytesForDataset(datasetId: UUID) : Long = { val dataset = Dataset.findOneById(new ObjectId(datasetId.stringify)).get val datasetFiles = dataset.files var datasetBytes : Long = 0 From 2d2b11fc5321f49f4dee72e399cdd1667576a77b Mon Sep 17 00:00:00 2001 From: toddn Date: Sat, 21 Aug 2021 15:34:11 -0500 Subject: [PATCH 09/18] adding and removing datasets from space will increment spaceBytes. --- app/services/mongodb/MongoDBSpaceService.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/services/mongodb/MongoDBSpaceService.scala b/app/services/mongodb/MongoDBSpaceService.scala index 749d46f72..db417d223 100644 --- a/app/services/mongodb/MongoDBSpaceService.scala +++ b/app/services/mongodb/MongoDBSpaceService.scala @@ -390,7 +390,9 @@ class MongoDBSpaceService @Inject() ( */ def addDataset(dataset: UUID, space: UUID): Unit = { log.debug(s"Space Service - Adding $dataset to $space") + val datasetBytes = datasets.getBytesForDataset(dataset) datasets.addToSpace(dataset, space) + ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("spaceBytes" -> datasetBytes), upsert=false, multi=false, WriteConcern.Safe) ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("datasetCount" -> 1), upsert=false, multi=false, WriteConcern.Safe) } @@ -404,6 +406,8 @@ class MongoDBSpaceService @Inject() ( def removeDataset(dataset:UUID, space:UUID): Unit = { log.debug(s"Space Service - removing $dataset from $space") datasets.removeFromSpace(dataset, space) + val datasetBytes = datasets.getBytesForDataset(dataset) + ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("spaceBytes" -> -datasetBytes), upsert=false, multi=false, WriteConcern.Safe) ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("datasetCount" -> -1), upsert=false, multi=false, WriteConcern.Safe) } From 7bd6deceac7d09ff2345ea1079ac2ec4891ada30 Mon Sep 17 00:00:00 2001 From: toddn Date: Sat, 21 Aug 2021 15:51:52 -0500 Subject: [PATCH 10/18] increment bytes when file added to dataset --- app/services/SpaceService.scala | 4 ++++ app/services/mongodb/MongoDBSpaceService.scala | 8 ++++++++ app/util/FileUtils.scala | 18 +++++++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/services/SpaceService.scala b/app/services/SpaceService.scala index a0cc4b486..3a9f1e60b 100644 --- a/app/services/SpaceService.scala +++ b/app/services/SpaceService.scala @@ -94,6 +94,10 @@ trait SpaceService { def incrementCollectionCounter(collection: UUID, space: UUID, increment: Int) + def incrementSpaceBytes(space: UUID, increment: Long) + + def decrementSpaceBytes(space: UUID, decrement: Long) + def addDataset(dataset: UUID, space: UUID) def removeDataset(dataset:UUID, space: UUID) diff --git a/app/services/mongodb/MongoDBSpaceService.scala b/app/services/mongodb/MongoDBSpaceService.scala index db417d223..6f164f8d0 100644 --- a/app/services/mongodb/MongoDBSpaceService.scala +++ b/app/services/mongodb/MongoDBSpaceService.scala @@ -378,6 +378,14 @@ class MongoDBSpaceService @Inject() ( ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("collectionCount" -> -1), upsert=false, multi=false, WriteConcern.Safe) } + def incrementSpaceBytes(space: UUID, increment: Long ): Unit = { + ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("spaceBytes" -> increment), upsert=false, multi=false, WriteConcern.Safe) + } + + def decrementSpaceBytes(space: UUID, decrement: Long): Unit = { + ProjectSpaceDAO.update(MongoDBObject("_id" -> new ObjectId(space.stringify)), $inc("spaceBytes" -> decrement), upsert=false, multi=false, WriteConcern.Safe) + } + def removeCollection(collection:UUID, space:UUID): Unit = { log.debug(s"Space Service - removing $collection from $space") collections.removeFromSpace(collection, space) diff --git a/app/util/FileUtils.scala b/app/util/FileUtils.scala index 987d2dccc..5f11aeb4e 100644 --- a/app/util/FileUtils.scala +++ b/app/util/FileUtils.scala @@ -1,15 +1,9 @@ package util -import java.io.{File => JFile} -import java.net.URL -import java.util.Date - -import collection.JavaConversions._ import api.UserRequest import controllers.Utils import fileutils.FilesUtils import models._ -import org.apache.commons.codec.digest.DigestUtils import play.api.Logger import play.api.Play._ import play.api.libs.Files @@ -18,13 +12,14 @@ import play.api.mvc.MultipartFormData import play.libs.Akka import services._ +import java.net.{URL, URLEncoder} +import java.util.Date +import javax.mail.internet.MimeUtility +import scala.collection.JavaConversions._ import scala.collection.mutable import scala.concurrent.{ExecutionContext, Future} import scala.util.Try -import javax.mail.internet.MimeUtility -import java.net.URLEncoder - object FileUtils { val appConfig: AppConfigurationService = DI.injector.getInstance(classOf[AppConfigurationService]) @@ -41,6 +36,7 @@ object FileUtils { lazy val thumbnails : ThumbnailService = DI.injector.getInstance(classOf[ThumbnailService]) lazy val routing : ExtractorRoutingService = DI.injector.getInstance(classOf[ExtractorRoutingService]) lazy val sinkService : EventSinkService = DI.injector.getInstance(classOf[EventSinkService]) + lazy val spaceService : SpaceService = DI.injector.getInstance(classOf[SpaceService]) def getContentType(filename: Option[String], contentType: Option[String]): String = { @@ -584,6 +580,10 @@ object FileUtils { events.addObjectEvent(Some(user), ds.id, ds.name, EventType.ADD_FILE.toString) } datasets.addFile(ds.id, file) + val datasetSpaces = dataset.get.spaces + for (s <- datasetSpaces){ + spaceService.incrementSpaceBytes(s, file.length) + } } } } From e656fded922898b0904cd4a2487ca4dd67ca674e Mon Sep 17 00:00:00 2001 From: toddn Date: Sat, 21 Aug 2021 15:56:53 -0500 Subject: [PATCH 11/18] decrement space bytes on remove file --- app/api/Files.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/api/Files.scala b/app/api/Files.scala index b9bae4130..0a227ac9e 100644 --- a/app/api/Files.scala +++ b/app/api/Files.scala @@ -1669,6 +1669,10 @@ class Files @Inject()( // notify rabbitmq datasets.findByFileIdAllContain(file.id).foreach { ds => routing.fileRemovedFromDataset(file, ds, Utils.baseUrl(request), request.apiKey) + val ds_spaces = ds.spaces + for (ds_s <- ds_spaces) { + spaces.decrementSpaceBytes(ds_s, file.length) + } } //this stmt has to be before files.removeFile From 27b9b628bae2a040c5527e2a7f3212f269948997 Mon Sep 17 00:00:00 2001 From: toddn Date: Wed, 25 Aug 2021 16:51:15 -0500 Subject: [PATCH 12/18] remove commented out code --- app/views/spaces/statistics.scala.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/views/spaces/statistics.scala.html b/app/views/spaces/statistics.scala.html index f9e823d30..a25ec4af1 100644 --- a/app/views/spaces/statistics.scala.html +++ b/app/views/spaces/statistics.scala.html @@ -10,11 +10,6 @@

Resources

    - -@*
  • *@ -@* @Messages("spaces.title")@humanReadableNumber(spacesCount)*@ -@*
  • *@ -
  • @Messages("collections.title") @space.collectionCount
  • From d7db4cf4c87f3b8628fa07908ac299b41705053e Mon Sep 17 00:00:00 2001 From: toddn Date: Sun, 19 Sep 2021 13:06:14 -0500 Subject: [PATCH 13/18] use cached value of bytes per space not method call --- app/controllers/Spaces.scala | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/app/controllers/Spaces.scala b/app/controllers/Spaces.scala index 522a948f8..ec0ae5d2b 100644 --- a/app/controllers/Spaces.scala +++ b/app/controllers/Spaces.scala @@ -167,7 +167,7 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS var creatorActual: User = null val collectionsInSpace = spaces.getCollectionsInSpace(Some(id.stringify), Some(size)) val datasetsInSpace = datasets.listSpace(size, id.toString(), user) - val spaceBytes : Long = getBytesPerSpace(id, user.get) + val spaceBytes : Long = s.spaceBytes val spaceFiles : Integer = getFilesPerSpace(id, user.get) val publicDatasetsInSpace = datasets.listSpaceStatus(size, id.toString(), "publicAll", user) val usersInSpace = spaces.getUsersInSpace(id, None) @@ -651,25 +651,4 @@ class Spaces @Inject() (spaces: SpaceService, users: UserService, events: EventS spaceFiles } - private def getBytesPerSpace(spaceId: UUID, user: models.User) : Long = { - val allDatasetsInSpace = datasets.listSpace(0, spaceId.toString(), Some(user)) - var spaceBytes: Long = 0 - for (ds <- allDatasetsInSpace){ - val ds_files = ds.files - for (ds_f <- ds_files){ - files.get(ds_f) match { - case Some(file) => { - files.getBytes(file.id) match { - case Some((stream, name, filetype, bytes)) => { - var current_bytes : Long = bytes - spaceBytes += current_bytes - } - } - } - } - } - } - spaceBytes - } - } From 6b5c02de97d793f76de4d13f577903ad299a626a Mon Sep 17 00:00:00 2001 From: toddn Date: Sun, 19 Sep 2021 13:35:29 -0500 Subject: [PATCH 14/18] adding update space bytes method --- app/services/mongodb/MongoSalatPlugin.scala | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/services/mongodb/MongoSalatPlugin.scala b/app/services/mongodb/MongoSalatPlugin.scala index bf3fc06de..6800c8e0b 100644 --- a/app/services/mongodb/MongoSalatPlugin.scala +++ b/app/services/mongodb/MongoSalatPlugin.scala @@ -453,6 +453,9 @@ class MongoSalatPlugin(app: Application) extends Plugin { // Updates extractors enabled and disabled in a space updateMongo("update-space-extractors-selection", updateSpaceExtractorsSelection) + + // Adds space bytes to space + updateMongo(updateKey = "update-space-bytes", updateSpaceBytes) } private def updateMongo(updateKey: String, block: () => Unit): Unit = { @@ -1690,4 +1693,22 @@ class MongoSalatPlugin(app: Application) extends Plugin { } print("DONE") } + + private def updateSpaceBytes() : Unit = { + collection("spaces.projects").foreach { space => + var spaceBytes : Long = 0 + val spaceId = space.get("_id") + val spaceDatasets = collection("datasets").find(MongoDBObject("spaces" -> spaceId)) + spaceDatasets.foreach{ spaceDataset => + val spaceDatasetFileIds = spaceDataset.get("files").asInstanceOf[List[ObjectId]] + spaceDatasetFileIds.foreach{ fileId => + collection("uploads.files").find(MongoDBObject("_id" -> fileId)).foreach{ f => + val bytes = f.get("length").asInstanceOf[Long] + spaceBytes += bytes + } + } + } + collection("spaces.projects").update(MongoDBObject("_id" -> spaceId), $set("spaceBytes" -> spaceBytes)) + } + } } From a7cb0e32fa01193536a8f24a8b683fddf459f057 Mon Sep 17 00:00:00 2001 From: toddn Date: Sun, 19 Sep 2021 15:48:36 -0500 Subject: [PATCH 15/18] added space bytes update --- app/services/mongodb/MongoSalatPlugin.scala | 30 +++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/app/services/mongodb/MongoSalatPlugin.scala b/app/services/mongodb/MongoSalatPlugin.scala index 6800c8e0b..340a26a99 100644 --- a/app/services/mongodb/MongoSalatPlugin.scala +++ b/app/services/mongodb/MongoSalatPlugin.scala @@ -2,7 +2,6 @@ package services.mongodb import java.net.URL import java.util.{Calendar, Date} - import com.mongodb.{BasicDBObject, CommandFailureException} import com.mongodb.casbah.Imports._ import com.mongodb.casbah.commons.MongoDBObject @@ -15,10 +14,7 @@ import org.bson.BSONException import play.api.libs.json._ import play.api.{Application, Logger, Play, Plugin} import play.api.Play.current -import com.mongodb.casbah.MongoURI -import com.mongodb.casbah.MongoConnection -import com.mongodb.casbah.MongoDB -import com.mongodb.casbah.MongoCollection +import com.mongodb.casbah.{MongoCollection, MongoConnection, MongoDB, MongoURI, commons} import com.mongodb.casbah.gridfs.GridFS import com.mongodb.casbah.Imports.DBObject import org.bson.types.ObjectId @@ -1694,21 +1690,27 @@ class MongoSalatPlugin(app: Application) extends Plugin { print("DONE") } - private def updateSpaceBytes() : Unit = { - collection("spaces.projects").foreach { space => - var spaceBytes : Long = 0 + private def updateSpaceBytes(): Unit = { + collection("spaces.projects").foreach{ space => + var currentSpaceBytes: Long = 0 val spaceId = space.get("_id") val spaceDatasets = collection("datasets").find(MongoDBObject("spaces" -> spaceId)) spaceDatasets.foreach{ spaceDataset => - val spaceDatasetFileIds = spaceDataset.get("files").asInstanceOf[List[ObjectId]] - spaceDatasetFileIds.foreach{ fileId => - collection("uploads.files").find(MongoDBObject("_id" -> fileId)).foreach{ f => - val bytes = f.get("length").asInstanceOf[Long] - spaceBytes += bytes + val datasetFileIds = spaceDataset.getAsOrElse[MongoDBList]("files", MongoDBList.empty) + datasetFileIds.foreach{ fileId => + print(fileId) + val currentFileUpload = collection("uploads").find(MongoDBObject("_id" -> fileId)) + currentFileUpload.foreach{ current_upload => + val curent_loader_id = current_upload.get("loader_id").toString + val file_upload_id = collection("uploads").find(MongoDBObject("_id" -> new ObjectId(curent_loader_id))) + file_upload_id.foreach{ f_upload => + val currentBytes = f_upload.get("length").asInstanceOf[Long] + currentSpaceBytes += currentBytes + } } } + collection("spaces.projects").update(MongoDBObject("_id" -> spaceId), $set("spaceBytes" -> currentSpaceBytes)) } - collection("spaces.projects").update(MongoDBObject("_id" -> spaceId), $set("spaceBytes" -> spaceBytes)) } } } From 88ec0e9458c0f5786797937ed0e0aaf22d5dacca Mon Sep 17 00:00:00 2001 From: toddn Date: Fri, 24 Sep 2021 11:10:52 -0500 Subject: [PATCH 16/18] fixig test --- test/integration/spaces/SpaceMongoDBSpec.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/spaces/SpaceMongoDBSpec.scala b/test/integration/spaces/SpaceMongoDBSpec.scala index 9c5946393..2287945ed 100644 --- a/test/integration/spaces/SpaceMongoDBSpec.scala +++ b/test/integration/spaces/SpaceMongoDBSpec.scala @@ -25,6 +25,7 @@ class SpaceMongoDBSpec extends PlaySpec with OneServerPerSuite { collectionCount = 0, datasetCount = 0, userCount = 0, + spaceBytes = 0, metadata = List.empty ) From 92b3e4c8b0cf4190825d55fca9ef9dba952836a1 Mon Sep 17 00:00:00 2001 From: Rob Kooper Date: Fri, 1 Oct 2021 16:14:12 -0500 Subject: [PATCH 17/18] fix few issues with migration - no datasets in space would result in not writing out count - very large databsae would have cursor timeout - simplified logic to count bytes --- app/services/mongodb/MongoSalatPlugin.scala | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/app/services/mongodb/MongoSalatPlugin.scala b/app/services/mongodb/MongoSalatPlugin.scala index 340a26a99..b5ede2229 100644 --- a/app/services/mongodb/MongoSalatPlugin.scala +++ b/app/services/mongodb/MongoSalatPlugin.scala @@ -1691,26 +1691,20 @@ class MongoSalatPlugin(app: Application) extends Plugin { } private def updateSpaceBytes(): Unit = { - collection("spaces.projects").foreach{ space => + val spaces = collection("spaces.projects").find().toList.foreach{ space => var currentSpaceBytes: Long = 0 val spaceId = space.get("_id") - val spaceDatasets = collection("datasets").find(MongoDBObject("spaces" -> spaceId)) + val spaceDatasets = collection("datasets").find(MongoDBObject("spaces" -> spaceId)).toList spaceDatasets.foreach{ spaceDataset => val datasetFileIds = spaceDataset.getAsOrElse[MongoDBList]("files", MongoDBList.empty) datasetFileIds.foreach{ fileId => - print(fileId) - val currentFileUpload = collection("uploads").find(MongoDBObject("_id" -> fileId)) - currentFileUpload.foreach{ current_upload => - val curent_loader_id = current_upload.get("loader_id").toString - val file_upload_id = collection("uploads").find(MongoDBObject("_id" -> new ObjectId(curent_loader_id))) - file_upload_id.foreach{ f_upload => - val currentBytes = f_upload.get("length").asInstanceOf[Long] - currentSpaceBytes += currentBytes - } + collection("uploads").findOne(MongoDBObject("_id" -> fileId)) match { + case Some(file) => currentSpaceBytes += file.get("length").asInstanceOf[Long] + case None => Logger.info(s"Could not find file ${fileId} in space ${spaceId}") } } - collection("spaces.projects").update(MongoDBObject("_id" -> spaceId), $set("spaceBytes" -> currentSpaceBytes)) } + collection("spaces.projects").update(MongoDBObject("_id" -> spaceId), $set("spaceBytes" -> currentSpaceBytes)) } } } From 56e2dabde4d96fdd02cac3a5e1b4858caf5796c2 Mon Sep 17 00:00:00 2001 From: Rob Kooper Date: Mon, 4 Oct 2021 15:12:58 -0500 Subject: [PATCH 18/18] Space layout with statistics (#283) * make space layout more like datasets/files * update changelog - undo removal - add comment + link to issue for space stats - comment about new layout * Lowered margin from 20px to 15px for button links. Co-authored-by: Luigi Marini --- CHANGELOG.md | 6 + app/views/spaces/otherActions.scala.html | 75 ++++++---- app/views/spaces/space.scala.html | 173 ++++++++++++----------- app/views/spaces/statistics.scala.html | 58 ++++---- public/stylesheets/main.css | 2 +- 5 files changed, 179 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d794e87..7370a490c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Adding mime type for geojson - Add "when" parameter in a few GET API endpoints to enable pagination [#266](https://github.com/clowder-framework/clowder/issues/266) +- Show statistics of spaces (bytes, users. etc) [#119](https://github.com/clowder-framework/clowder/issues/119) + +### Changed +- Space layout is now more inline with the layout of files and dataasets. ## 1.18.1 - 2021-08-16 @@ -69,6 +73,7 @@ If any files are returned, you should check to see if these files affected and a ### Changed - Updated Sphinx dependencies due to security and changes in required packages. +- Updated the three.js libraries for the FBX previewer ## 1.16.0 - 2021-03-31 @@ -137,6 +142,7 @@ script to fix this. ## 1.14.0 - 2021-01-07 ### Added +- Added a previewer for FBX files. - Added a new `/api/reports/metrics/extractors` report for summarizing extractor usage by user. Database administrators can use `scripts/updates/UpdateUserId.js` to assign user IDs to older extraction event records based on resource ownership in order to improve the accuracy of the report for older data. diff --git a/app/views/spaces/otherActions.scala.html b/app/views/spaces/otherActions.scala.html index 3a79be035..47f4d0c37 100644 --- a/app/views/spaces/otherActions.scala.html +++ b/app/views/spaces/otherActions.scala.html @@ -1,38 +1,61 @@ @(space: ProjectSpace)(implicit user: Option[models.User]) @import api.Permission @import play.api.i18n.Messages -
    -
    + + +
    + Extractors - - } else { -
  • + +
  • + } else { + + + +
    + Extractors - - } - @if(play.api.Play.current.plugin[services.StagingAreaPlugin].isDefined && Permission.checkPermission(Permission.EditStagingArea, ResourceRef(ResourceRef.space, space.id))) { -
  • Staging Area
  • - } -
  • @spaces.follow(space)
  • -
+ +
+ } + @if(play.api.Play.current.plugin[services.StagingAreaPlugin].isDefined && Permission.checkPermission(Permission.EditStagingArea, ResourceRef(ResourceRef.space, space.id))) { + + } +
+ @spaces.follow(space) +
diff --git a/app/views/spaces/space.scala.html b/app/views/spaces/space.scala.html index f4501391a..28ca667b2 100644 --- a/app/views/spaces/space.scala.html +++ b/app/views/spaces/space.scala.html @@ -19,111 +19,122 @@ } -
- -
-

@space.name

- -

@Html(space.description.replace("\n","
"))

- @if(user.isDefined) { -
- @if(Permission.checkPermission(Permission.DeleteSpace, ResourceRef(ResourceRef.space, space.id))){ - - } - @if(Permission.checkPermission(Permission.CreateDataset, ResourceRef(ResourceRef.space, space.id))) { - - @Messages("create.title", Messages("dataset.title")) - } - @if(Permission.checkPermission(Permission.CreateCollection, ResourceRef(ResourceRef.space, space.id))) { - - @Messages("create.title", Messages("collections.title")) - } - - @if(Permission.checkPermission(Permission.ViewSpace, ResourceRef(ResourceRef.space, space.id)) || user.get.identityId.userId.equals(space.creator)){ - - Search - - } - @if(play.Play.application().configuration().getBoolean("enablePublic") && (Permission.checkPermission(Permission.EditSpace, ResourceRef(ResourceRef.space, space.id)) || Permission.checkPermission(Permission.DeleteSpace, ResourceRef(ResourceRef.space, space.id)))){ -
- } - } -
-
+ + @* left column, space details, datasets, collections *@
- -
- @if(user.isDefined){ -
- @spaces.datasetsBySpace(datasets, space, None, userSelections) - @spaces.collectionsBySpace(collections, space, None) -
- -
-

The @Messages("space.title") team has made the following @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase publicly available.

- @spaces.datasetsBySpace(publicDatasets, space, Some(true), userSelections) - - @if(space.isPublic) { - @spaces.collectionsBySpace(collections, space, Some(true)) - } else { -

@Messages("collections.title")

-

There are no public collections associated with this @Messages("space.title").

+ @if(Permission.checkPermission(Permission.CreateCollection, ResourceRef(ResourceRef.space, space.id))) { + + @Messages("create.title", Messages("collections.title")) + } + + @if(Permission.checkPermission(Permission.ViewSpace, ResourceRef(ResourceRef.space, space.id)) || user.get.identityId.userId.equals(space.creator)){ + + Search + + } + @if(play.Play.application().configuration().getBoolean("enablePublic") && (Permission.checkPermission(Permission.EditSpace, ResourceRef(ResourceRef.space, space.id)) || Permission.checkPermission(Permission.DeleteSpace, ResourceRef(ResourceRef.space, space.id)))){ +
}
- } else { -
-

The @Messages("space.title") team has made the following @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase publicly available. - You must be a logged-in member of the @Messages("space.title") to access all the @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase. -

- @spaces.datasetsBySpace(publicDatasets, space, Some(true), userSelections) - @if(space.isPublic) { - @spaces.collectionsBySpace(collections, space, Some(true)) + } +
+ +
+ +
+ @if(user.isDefined){ +
+ @spaces.datasetsBySpace(datasets, space, None, userSelections) + @spaces.collectionsBySpace(collections, space, None) +
+ +
+

The @Messages("space.title") team has made the following @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase publicly available.

+ @spaces.datasetsBySpace(publicDatasets, space, Some(true), userSelections) + + @if(space.isPublic) { + @spaces.collectionsBySpace(collections, space, Some(true)) + } else { +

@Messages("collections.title")

+

There are no public collections associated with this @Messages("space.title").

+ } +
+ } else { +
+

The @Messages("space.title") team has made the following @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase publicly available. + You must be a logged-in member of the @Messages("space.title") to access all the @Messages("datasets.title").toLowerCase and @Messages("collections.title").toLowerCase. +

+ @spaces.datasetsBySpace(publicDatasets, space, Some(true), userSelections) + @if(space.isPublic) { + @spaces.collectionsBySpace(collections, space, Some(true)) + } else { +

@Messages("collections.title")

+

There are no public collections associated with this @Messages("space.title").

+ } +
+ } +
+

The following @Messages("datasets.title").toLowerCase have been published through this @Messages("space.title") and any affiliated @Messages("space.title")s.

+ @curations.publishedGrid(publishedData, servicesUrl, None)
- } -
-

The following @Messages("datasets.title").toLowerCase have been published through this @Messages("space.title") and any affiliated @Messages("space.title")s.

- @curations.publishedGrid(publishedData, servicesUrl, None)
+ + @* right column, space statistics, actions *@
@if(user.isDefined) { - @spaces.statistics(space, spaceBytes,"row ds-section-sm space-col-right", None, spaceFiles ) + @spaces.statistics(space, spaceBytes, None, spaceFiles ) @spaces.otherActions(space) } else { - @spaces.statistics(space, spaceBytes, "row ds-section-sm space-col-right",None, spaceFiles) + @spaces.statistics(space, spaceBytes, None, spaceFiles) } - @spaces.externalLinks(space.homePage, space, "row ds-section-sm break-word space-col-right") + @spaces.externalLinks(space.homePage, space, "row ds-section-sm") @if(play.Play.application().configuration().getBoolean("enablePublic")) { - @spaces.access(space, userRoleMap, "row ds-section-sm break-word space-col-right") + @spaces.access(space, userRoleMap, "row ds-section-sm") } @if(play.api.Play.configuration.getBoolean("enable_expiration").getOrElse(false)) { @spaces.spaceConfiguration(space) }
+ +