Skip to content

Commit

Permalink
Merge pull request #80 from AtlasOfLivingAustralia/1.2.4
Browse files Browse the repository at this point in the history
1.2.4
  • Loading branch information
chrisala committed Jun 19, 2015
2 parents cec977a + 24898f7 commit bcb1616
Show file tree
Hide file tree
Showing 35 changed files with 5,286 additions and 3,509 deletions.
2 changes: 1 addition & 1 deletion application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
#Mon Nov 03 17:25:26 EST 2014
app.grails.version=2.4.4
app.name=ecodata
app.version=1.2.3-SNAPSHOT
app.version=1.2.4-SNAPSHOT
10 changes: 0 additions & 10 deletions grails-app/conf/BuildConfig.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ grails.project.dependency.resolution = {
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.

test "org.gebish:geb-spock:0.9.3"
test("org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion") {
exclude "xml-apis"
}
test("org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion")
test("org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion")
test "org.spockframework:spock-grails-support:0.7-groovy-2.0"

// ElasticSearch
compile "org.elasticsearch:elasticsearch:1.5.2"

Expand Down Expand Up @@ -95,8 +87,6 @@ grails.project.dependency.resolution = {
build ":release:3.0.1"
compile ':cache:1.1.8'
compile ":cache-ehcache:1.0.5"

test ":geb:0.9.3"

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver
class AdminController {

def outputService, activityService, siteService, projectService, authService,
organisationService,
collectoryService,
commonService, cacheService, metadataService, elasticSearchService, documentService
def beforeInterceptor = [action:this.&auth, only:['index','tools','settings','audit']]

Expand Down Expand Up @@ -37,7 +37,7 @@ class AdminController {

@RequireApiKey
def syncCollectoryOrgs() {
def errors = organisationService.collectorySync()
def errors = collectoryService.syncOrganisations()
if (errors)
render (status: 503, text: errors)
else
Expand Down
32 changes: 21 additions & 11 deletions grails-app/controllers/au/org/ala/ecodata/DocumentController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,50 @@ class DocumentController {
}

def index() {
log.debug "Total documents = ${Document.count()}"
log.debug "Total documents (including links) = ${Document.count()}"
render "${Document.count()} documents"
}

def get(String id) {
def detail = []
if (!id) {
def list = documentService.getAll(params.includeDeleted as boolean, params.view)
list.sort {it.name}
//log.debug list
asJson([list: list])
} else {
if (id) {
def doc = documentService.get(id, detail)
if (doc) {
asJson doc
} else {
render status:404, text: 'No such id'
}
} else if (params.links as boolean) {
def list = documentService.getAllLinks(params.view)
//log.debug list
asJson([list: list])
} else {
def list = documentService.getAll(params.includeDeleted as boolean, params.view)
list.sort {it.name}
//log.debug list
asJson([list: list])
}
}

def find(String entity, String id) {
def result = documentService.findAllByOwner(entity+'Id', id)
asJson([documents:result])
if (params.links as boolean) {
def result = documentService.findAllLinksByOwner(entity+'Id', id)
asJson([documents:result])
} else {
def result = documentService.findAllByOwner(entity+'Id', id)
asJson([documents:result])
}
}

@RequireApiKey
def delete(String id) {
def a = Document.findByDocumentId(id)
if (a) {
if (params.destroy) {
if (a.type == documentService.LINKTYPE) {
a.delete()
} else if (params.destroy) {
documentService.deleteFile(a)
a.delete()

} else {
a.status = 'deleted'
a.save(flush: true)
Expand Down
4 changes: 4 additions & 0 deletions grails-app/domain/au/org/ala/ecodata/Document.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Document {
String siteId
String activityId
String outputId
String externalUrl

boolean thirdPartyConsentDeclarationMade = false
String thirdPartyConsentDeclarationText
Expand All @@ -49,6 +50,8 @@ class Document {
}

def getUrl() {
if (externalUrl) return externalUrl

return urlFor(filepath, filename)
}

Expand Down Expand Up @@ -108,5 +111,6 @@ class Document {
isPrimaryProjectImage nullable: true
thirdPartyConsentDeclarationMade nullable: true
thirdPartyConsentDeclarationText nullable: true
externalUrl nullable: true
}
}
14 changes: 11 additions & 3 deletions grails-app/domain/au/org/ala/ecodata/Project.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class Project {
}

ObjectId id
String projectId // same as collectory dataProvider id
String projectId
String dataProviderId // collectory dataProvider id
String dataResourceId // one collectory dataResource stores all sightings
String status = 'active'
String externalId
Expand Down Expand Up @@ -63,8 +64,11 @@ class Project {
List activities

boolean isCitizenScience, isDataSharing
boolean hasParticipantCost, hasTeachingMaterials, isDIY, isSuitableForChildren
String difficulty, gear, task
String projectPrivacy, dataSharingLicense
String projectType // survey, works
// TODO urlAndroid and urlITunes need to be phased out; replaced by link-type documente
String aim, keywords, urlAndroid, urlITunes, urlWeb
String getInvolved, scienceType, projectSiteId
double funding
Expand Down Expand Up @@ -147,11 +151,12 @@ class Project {
promoteOnHomepage nullable:true
organisationId nullable:true
projectType nullable:true // nullable for backward compatibility; survey, works
dataProviderId nullable:true // nullable for backward compatibility
dataResourceId nullable:true // nullable for backward compatibility
aim nullable:true
keywords nullable:true
urlAndroid nullable:true, url:true
urlITunes nullable:true, url:true
urlAndroid nullable:true, url:true // TODO phased out
urlITunes nullable:true, url:true // TODO phased out
urlWeb nullable:true, url:true
getInvolved nullable:true
scienceType nullable:true
Expand All @@ -160,6 +165,9 @@ class Project {
orgIdSvcProvider nullable:true
projectSiteId nullable:true // nullable for backward compatibility
projectPrivacy nullable:true, inList: ['Open','Closed']
difficulty nullable:true, inList: ['Easy','Medium','Hard']
gear nullable:true
task nullable:true
dataSharingLicense nullable:true, inList: collectoryLicenseTypes
userCreated nullable:true
userLastModified nullable:true
Expand Down
116 changes: 114 additions & 2 deletions grails-app/services/au/org/ala/ecodata/CollectoryService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CollectoryService {

def institutionId = null
try {
def collectoryProps = mapAttributesToCollectory(props)
def collectoryProps = mapOrganisationAttributesToCollectory(props)
def result = webService.doPost(grailsApplication.config.collectory.baseURL + 'ws/institution/', collectoryProps)
institutionId = webService.extractCollectoryIdFromResult(result)
}
Expand All @@ -25,7 +25,7 @@ class CollectoryService {
return institutionId
}

private def mapAttributesToCollectory(props) {
private def mapOrganisationAttributesToCollectory(props) {
def mapKeyOrganisationDataToCollectory = [
orgType: 'institutionType',
description: 'pubDescription',
Expand All @@ -44,4 +44,116 @@ class CollectoryService {
}
collectoryProps
}

// create ecodata organisations for any institutions in collectory which are not yet in ecodata
// return null if sucessful, or errors
def syncOrganisations() {
def errors
def url = "${grailsApplication.config.collectory.baseURL}ws/institution/"
def institutions = webService.getJson(url)
if (institutions instanceof List) {
def orgs = Organisation.findAllByCollectoryInstitutionIdIsNotNull()
def map = orgs.collectEntries {
[it.collectoryInstitutionId, it]
}
institutions.each({it ->
if (!map[it.uid]) {
def inst = webService.getJson(url + it.uid)
def result = create([collectoryInstitutionId: inst.uid,
name: inst.name,
description: inst.pubDescription?:"",
url: inst.websiteUrl?:""])
if (result.errors) errors = result.errors
}
})
}
errors
}

/**
* Creates a new Data Provider (=~ ecodata project) and Data Resource (=~ ecodata outputs)
* in the collectory using the supplied properties as input. Much of project meta data is
* stored in a 'hiddenJSON' field in collectory.
* @param id the project id in ecodata.
* @param props the properties for the new data provider and resource.
* @return a map containing the created data provider id and data resource id, or null.
*/
Map createDataProviderAndResource(id, props) {

Map ids = [:]

try {
def collectoryProps = mapProjectAttributesToCollectory(props)
def result = webService.doPost(grailsApplication.config.collectory.baseURL + 'ws/dataProvider/', collectoryProps)
ids.dataProviderId = webService.extractCollectoryIdFromResult(result)
if (ids.dataProviderId) {
// create a dataResource in collectory to hold project outputs
collectoryProps.remove('hiddenJSON')
collectoryProps.dataProvider = [uid: ids.dataProviderId]
if (props.collectoryInstitutionId) collectoryProps.institution = [uid: props.collectoryInstitutionId]
collectoryProps.licenseType = props.dataSharingLicense
result = webService.doPost(grailsApplication.config.collectory.baseURL + 'ws/dataResource/', collectoryProps)
ids.dataResourceId = webService.extractCollectoryIdFromResult(result)
}
} catch (Exception e) {
def error = "Error creating collectory info for project ${id} - ${e.message}"
log.error error
}

return ids
}

/**
* Updates the Data Provider (=~ ecodata project) and Data Resource (=~ ecodata outputs)
* in the collectory using the supplied properties as input. The 'hiddenJSON' field in
* collectory is recreated to reflect the latest project properties.
* @param project the UPDATED project in ecodata.
* @return void.
*/
def updateDataProviderAndResource(project) {

def projectId = project.projectId
try {
project = ['id', 'dateCreated', 'documents', 'lastUpdated', 'organisationName', 'projectId', 'sites'].each {
project.remove(it)
}
webService.doPost(grailsApplication.config.collectory.baseURL + 'ws/dataProvider/' + project.dataProviderId,
mapProjectAttributesToCollectory(project))
if (project.dataResourceId)
webService.doPost(grailsApplication.config.collectory.baseURL + 'ws/dataResource/' + project.dataResourceId,
[licenseType: project.dataSharingLicense])
} catch (Exception e ) {
def error = "Error updating collectory info for project ${projectId} - ${e.message}"
log.error error
}

}

private def mapProjectAttributesToCollectory(props) {
def mapKeyProjectDataToCollectory = [
description: 'pubDescription',
manager: 'email',
name: 'name',
dataSharingLicense: '', // ignore this property (mapped to dataResource)
organisation: '', // ignore this property
projectId: 'uid',
urlWeb: 'websiteUrl'
]
def collectoryProps = [
api_key: grailsApplication.config.api_key
]
def hiddenJSON = [:]
props.each { k, v ->
if (v != null) {
def keyCollectory = mapKeyProjectDataToCollectory[k]
if (keyCollectory == null) // not mapped to first class collectory property
hiddenJSON[k] = v
else if (keyCollectory != '') // not to be ignored
collectoryProps[keyCollectory] = v
}
}
collectoryProps.hiddenJSON = hiddenJSON
collectoryProps
}

}
31 changes: 26 additions & 5 deletions grails-app/services/au/org/ala/ecodata/DocumentService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import java.text.SimpleDateFormat
class DocumentService {

static final ACTIVE = "active"
static final LINKTYPE = "link"
static final FILE_LOCK = new Object()

static final DIRECTORY_PARTITION_FORMAT = 'yyyy-MM'
Expand Down Expand Up @@ -53,15 +54,23 @@ class DocumentService {

def getAll(boolean includeDeleted = false, levelOfDetail = []) {
includeDeleted ?
Document.list().collect { toMap(it, levelOfDetail) } :
Document.findAllByStatus(ACTIVE).collect { toMap(it, levelOfDetail) }
Document.findAllByTypeNotEqual(LINKTYPE).collect { toMap(it, levelOfDetail) } :
Document.findAllByStatusAndTypeNotEqual(ACTIVE, LINKTYPE).collect { toMap(it, levelOfDetail) }
}

def getAllLinks(levelOfDetail = []) {
Document.findAllByType(LINKTYPE).collect { toMap(it, levelOfDetail) }
}

def findAllForProjectId(id, levelOfDetail = []) {
Document.findAllByProjectIdAndStatus(id, ACTIVE).collect { toMap(it, levelOfDetail) }
Document.findAllByProjectIdAndStatusAndTypeNotEqual(id, ACTIVE, LINKTYPE).collect { toMap(it, levelOfDetail) }
}

def findAllLinksForProjectId(id, levelOfDetail = []) {
Document.findAllByProjectIdAndType(id, LINKTYPE).collect { toMap(it, levelOfDetail) }
}
def findAllForProjectIdAndIsPrimaryProjectImage(id, levelOfDetail = []) {

def findAllForProjectIdAndIsPrimaryProjectImage(id, levelOfDetail = []) {
Document.findAllByProjectIdAndStatusAndIsPrimaryProjectImage(id, ACTIVE,true).collect { toMap(it, levelOfDetail) }
}

Expand Down Expand Up @@ -285,6 +294,7 @@ class DocumentService {
def query = Document.createCriteria()

def results = query {
ne('type', LINKTYPE)
eq(ownerType, owner)
if (!includeDeleted) {
ne('status', 'deleted')
Expand All @@ -293,4 +303,15 @@ class DocumentService {

results.collect{toMap(it, 'flat')}
}

def findAllLinksByOwner(ownerType, owner) {
def query = Document.createCriteria()

def results = query {
eq('type', LINKTYPE)
eq(ownerType, owner)
}

results.collect{toMap(it, 'flat')}
}
}
Loading

0 comments on commit bcb1616

Please sign in to comment.