Skip to content

Commit dc10a49

Browse files
authored
Merge pull request #147 from clowder-framework/release/1.13.0
v1.13.0
2 parents 90bbe7d + c1a2d3b commit dc10a49

37 files changed

+547
-85
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

77

8+
## 1.13.0 - 2020-12-02
9+
10+
### Added
11+
- Ability to submit multiple selected files within a dataset to an extractor.
12+
- Support for Amplitude clickstream tracking. See Admin -> Customize to configure Amplitude apikey.
13+
- UpdateUserId.js to scripts/updates. This code adds user_id to each document in extractions collection in mongodb.
14+
user_id is taken from author id in uploads.files if exists, else it taken from author id in datasets collection.
15+
16+
### Fixed
17+
- An extractor with file matching set to `*/*` (all file types) would incorrectly send out dataset events.
18+
- Space Editors can now delete tags on files, datasets and sections.
19+
- GeospatialViewer previewer no longer shows if file does not contain geospatial layers.
20+
821
## 1.12.2 - 2020-11-19
922

1023
### Changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Following is a list of contributors in alphabetical order:
2121
- Mario Felarca
2222
- Max Burnette
2323
- Michal Ondrejcek
24+
- Michael Johnson
2425
- Michelle Pitcel
2526
- Mike Bobak
2627
- Mike Lambert

app/api/Admin.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class Admin @Inject() (userService: UserService,
8080
getValueString(request.body, "sensor").foreach(AppConfiguration.setSensorTitle(_))
8181
getValueString(request.body, "parameters").foreach(AppConfiguration.setParametersTitle(_))
8282
getValueString(request.body, "parameter").foreach(AppConfiguration.setParameterTitle(_))
83+
getValueString(request.body, "amplitudeApikey").foreach(AppConfiguration.setAmplitudeApiKey(_))
84+
8385
getValueString(request.body, "tosText").foreach { tos =>
8486
events.addEvent(Event(request.user.get, event_type = EventType.TOS_UPDATE.toString))
8587
AppConfiguration.setTermsOfServicesText(tos)

app/api/Datasets.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,18 +1395,16 @@ class Datasets @Inject()(
13951395

13961396
val error_str = tagCheck.error_str
13971397
val not_found = tagCheck.not_found
1398-
val userOpt = tagCheck.userOpt
1399-
val extractorOpt = tagCheck.extractorOpt
14001398
val tags = tagCheck.tags
14011399

14021400
// Now the real work: removing the tags.
14031401
if ("" == error_str) {
14041402
// Clean up leading, trailing and multiple contiguous white spaces.
14051403
val tagsCleaned = tags.get.map(_.trim().replaceAll("\\s+", " "))
14061404
(obj_type) match {
1407-
case TagCheck_File => files.removeTags(id, userOpt, extractorOpt, tagsCleaned)
1405+
case TagCheck_File => files.removeTags(id, tagsCleaned)
14081406
case TagCheck_Dataset => {
1409-
datasets.removeTags(id, userOpt, extractorOpt, tagsCleaned)
1407+
datasets.removeTags(id, tagsCleaned)
14101408
datasets.get(id) match {
14111409
case Some(dataset) => {
14121410
events.addObjectEvent(request.user, id, dataset.name, EventType.REMOVE_TAGS_DATASET.toString)
@@ -1416,7 +1414,7 @@ class Datasets @Inject()(
14161414

14171415
}
14181416

1419-
case TagCheck_Section => sections.removeTags(id, userOpt, extractorOpt, tagsCleaned)
1417+
case TagCheck_Section => sections.removeTags(id, tagsCleaned)
14201418
}
14211419
Ok(Json.obj("status" -> "success"))
14221420
} else {

app/api/Extractions.scala

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import services._
2222

2323
import scala.collection.mutable.ListBuffer
2424
import scala.concurrent.Future
25+
import scala.util.parsing.json.JSONObject
2526

2627

2728
/**
@@ -585,6 +586,81 @@ class Extractions @Inject()(
585586
}
586587
}
587588

589+
def submitFilesToExtractor(ds_id: UUID, file_ids: String)= PermissionAction(Permission.EditDataset, Some(ResourceRef(ResourceRef.dataset,
590+
ds_id)))(parse.json) { implicit request =>
591+
current.plugin[RabbitmqPlugin] match {
592+
case Some(p) => {
593+
var results = Map[String, String]()
594+
files.get(file_ids.split(",").map(fid => UUID(fid)).toList).found.foreach(fi => {
595+
createFileSubmission(request, fi) match {
596+
case Some(jobid) => results += (fi.id.stringify -> jobid.stringify)
597+
case None => Logger.error("File not submitted: "+fi.id)
598+
}
599+
})
600+
Ok(Json.obj("status" -> "success", "jobs" -> results))
601+
}
602+
case None =>
603+
Ok(Json.obj("status" -> "error", "msg"-> "RabbitmqPlugin disabled"))
604+
}
605+
}
606+
607+
private def createFileSubmission(request: UserRequest[JsValue], file: File): Option[UUID] = {
608+
current.plugin[RabbitmqPlugin] match {
609+
case Some(p) => {
610+
val id = file.id
611+
val fileType = file.contentType
612+
val idAndFlags = ""
613+
614+
// check that the file is ready for processing
615+
if (file.status.equals(models.FileStatus.PROCESSED.toString)) {
616+
// parameters for execution
617+
val parameters = (request.body \ "parameters").asOpt[JsObject].getOrElse(JsObject(Seq.empty[(String, JsValue)]))
618+
619+
// Log request
620+
val clientIP = request.remoteAddress
621+
val serverIP = request.host
622+
dtsrequests.insertRequest(serverIP, clientIP, file.filename, id, fileType, file.length, file.uploadDate)
623+
624+
val extra = Map("filename" -> file.filename,
625+
"parameters" -> parameters,
626+
"action" -> "manual-submission")
627+
val showPreviews = file.showPreviews
628+
629+
val newFlags = if (showPreviews.equals("FileLevel"))
630+
idAndFlags + "+filelevelshowpreviews"
631+
else if (showPreviews.equals("None"))
632+
idAndFlags + "+nopreviews"
633+
else
634+
idAndFlags
635+
636+
val originalId = if (!file.isIntermediate) {
637+
file.id.toString()
638+
} else {
639+
idAndFlags
640+
}
641+
642+
var datasetId: UUID = null
643+
// search datasets containning this file, either directly under dataset or indirectly.
644+
val datasetslists:List[Dataset] = datasets.findByFileIdAllContain(file.id)
645+
// Note, we assume only at most one dataset will contain a given file.
646+
if (0 != datasetslists.length) {
647+
datasetId = datasetslists.head.id
648+
}
649+
// if extractor_id is not specified default to execution of all extractors matching mime type
650+
(request.body \ "extractor").asOpt[String] match {
651+
case Some(extractorId) => p.submitFileManually(new UUID(originalId), file, Utils.baseUrl(request), extractorId, extra,
652+
datasetId, newFlags, request.apiKey, request.user)
653+
case None => p.fileCreated(file, None, Utils.baseUrl(request), request.apiKey)
654+
}
655+
} else None
656+
}
657+
case None => {
658+
Logger.error("RabbitMQ disabled.")
659+
None
660+
}
661+
}
662+
}
663+
588664
def submitDatasetToExtractor(ds_id: UUID) = PermissionAction(Permission.EditDataset, Some(ResourceRef(ResourceRef.dataset,
589665
ds_id)))(parse.json) { implicit request =>
590666
Logger.debug(s"Submitting dataset for extraction with body $request.body")

app/controllers/Admin.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class Admin @Inject() (sectionIndexInfo: SectionIndexInfoService, userService: U
2929
Ok(views.html.admin.customize(theme,
3030
AppConfiguration.getDisplayName,
3131
AppConfiguration.getWelcomeMessage,
32-
AppConfiguration.getGoogleAnalytics))
32+
AppConfiguration.getGoogleAnalytics,
33+
AppConfiguration.getAmplitudeApiKey))
3334
}
3435

3536
def tos = ServerAdminAction { implicit request =>

app/controllers/Application.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class Application @Inject() (files: FileService, collections: CollectionService,
353353
api.routes.javascript.Datasets.users,
354354
api.routes.javascript.Datasets.restoreDataset,
355355
api.routes.javascript.Datasets.emptyTrash,
356+
api.routes.javascript.Extractions.submitFilesToExtractor,
356357
api.routes.javascript.Files.download,
357358
api.routes.javascript.Files.archive,
358359
api.routes.javascript.Files.sendArchiveRequest,
@@ -528,6 +529,7 @@ class Application @Inject() (files: FileService, collections: CollectionService,
528529
controllers.routes.javascript.Extractors.selectExtractors,
529530
controllers.routes.javascript.Extractors.manageLabels,
530531
controllers.routes.javascript.Extractors.showJobHistory,
532+
controllers.routes.javascript.Extractors.submitSelectedExtractions,
531533
controllers.routes.javascript.CurationObjects.submit,
532534
controllers.routes.javascript.CurationObjects.getCurationObject,
533535
controllers.routes.javascript.CurationObjects.getUpdatedFilesAndFolders,

app/controllers/Extractors.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,26 @@ class Extractors @Inject() (extractions: ExtractionService,
350350
}
351351
}
352352

353+
def submitSelectedExtractions(ds_id: UUID) = PermissionAction(Permission.EditDataset, Some(ResourceRef(ResourceRef.dataset, ds_id))) { implicit request =>
354+
implicit val user = request.user
355+
val all_extractors = extractorService.listExtractorsInfo(List("EXTRACT", "CONVERT"))
356+
val extractors = all_extractors.filter(!_.process.file.isEmpty)
357+
datasets.get(ds_id) match {
358+
case Some(dataset) => {
359+
val allDecodedDatasets = List(dataset)
360+
val decodedSpacesContaining = ListBuffer.empty[models.ProjectSpace]
361+
dataset.spaces.map{ sp =>
362+
spaces.get(sp) match {
363+
case Some(s) => decodedSpacesContaining += Utils.decodeSpaceElements(s)
364+
case None => Logger.error("Dataset "+dataset.id.stringify+" space not found: "+sp.stringify)
365+
}
366+
}
367+
Ok(views.html.extractions.submitSelectedExtraction(extractors, dataset))
368+
}
369+
case None => InternalServerError("Dataset not found")
370+
}
371+
}
372+
353373
def submitDatasetExtraction(ds_id: UUID) = PermissionAction(Permission.EditDataset, Some(ResourceRef(ResourceRef.dataset, ds_id))) { implicit request =>
354374
implicit val user = request.user
355375
val all_extractors = extractorService.listExtractorsInfo(List("EXTRACT", "CONVERT"))

app/models/ResourceType.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import play.api.libs.json._
77
*/
88
object ResourceType extends Enumeration {
99
// type ResourceType = Value
10-
val dataset, file, collection, user, sensor, stream, folder = Value
10+
val dataset, file, collection, user, sensor, stream, folder, metadata = Value
1111

1212
def isWorkingDay(d: ResourceType.Value) = ! (d == Dataset || d == File)
1313
}

app/services/AppConfigurationService.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,23 @@ object AppConfiguration {
116116
/** Set the google analytics code */
117117
def setGoogleAnalytics(gacode: String) = appConfig.setProperty("google.analytics", gacode)
118118

119-
/** Get the welcome message */
119+
/** Get the google analytics code */
120120
def getGoogleAnalytics: String = appConfig.getProperty("google.analytics", "")
121121

122122
// ----------------------------------------------------------------------
123123

124+
/** Set the Amplitude clickstream/analytics configuration */
125+
def setAmplitudeApiKey(ampApiKey: String) = {
126+
appConfig.setProperty("amplitude.apikey", ampApiKey)
127+
}
128+
129+
/** Get the Amplitude clickstream/analytics configuration */
130+
def getAmplitudeApiKey: String = {
131+
appConfig.getProperty("amplitude.apikey", "")
132+
}
133+
134+
// ----------------------------------------------------------------------
135+
124136
/** Set the Sensors title */
125137
def setSensorsTitle(sensorsTitle: String) = appConfig.setProperty("sensors.title", sensorsTitle)
126138

0 commit comments

Comments
 (0)