Skip to content

Commit 52d45bd

Browse files
authored
Merge pull request #94 from AtlasOfLivingAustralia/develop
prepare 1.5.1 release
2 parents eb36523 + 47aeadb commit 52d45bd

32 files changed

+1118
-242
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ branches:
66
only:
77
- master
88
- hotfix
9+
- develop
910
before_cache:
1011
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
1112
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is a small app responsible for sending email alerts when there are changes
44

55
# Build status
66

7-
[![Build Status](https://travis-ci.org/AtlasOfLivingAustralia/alerts.svg?branch=master)](https://travis-ci.org/AtlasOfLivingAustralia/alerts)
7+
[![Build Status](https://travis-ci.com/AtlasOfLivingAustralia/alerts.svg?branch=master)](https://travis-ci.com/AtlasOfLivingAustralia/alerts)
88

99
# Dev environment set up
1010

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ dependencies {
9898
testCompile "org.grails:grails-test-mixins:3.3.0"
9999

100100
// Grails plugin dependencies
101-
runtime "org.grails.plugins:ala-bootstrap3:3.2.0", noCache
101+
runtime "org.grails.plugins:ala-bootstrap3:3.2.3", noCache
102102
compile "org.grails.plugins:ala-ws-security-plugin:2.0", noCache
103103
compile "org.grails.plugins:ala-ws-plugin:2.0", noCache
104104
compile "org.grails.plugins:ala-auth:3.1.0", noCache

grails-app/conf/application.yml

+7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ endpoints:
102102
unique-names: true
103103
enabled: true
104104
---
105+
headerAndFooter:
106+
baseURL: "https://www.ala.org.au/commonui-bs3-2019"
107+
version: "2"
108+
105109
skin:
106110
layout: "ala-main"
107111
orgNameLong: "Atlas of Living Australia"
@@ -239,3 +243,6 @@ environments:
239243
production:
240244
dataSource:
241245
dbCreate: none
246+
247+
myannotation:
248+
enabled: false

grails-app/conf/logback.groovy

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ switch (Environment.current) {
6969
[
7070
(DEBUG): [ // DEBUG and TRACE should only be enabled for non-production environments
7171
// 'grails.app',
72+
'au.org.ala.alerts',
7273
'au.org.ala.cas',
7374
'au.org.ala.hub',
7475
'au.org.ala.bootstrap3',
+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
// Place your Spring DSL code here
1+
import grails.util.Holders
2+
import org.springframework.web.servlet.i18n.SessionLocaleResolver
3+
24
beans = {
5+
localeResolver(SessionLocaleResolver) {
6+
defaultLocale= new java.util.Locale(Holders.config.siteDefaultLanguage as String)
7+
}
38
}

grails-app/controllers/au/org/ala/alerts/AdminController.groovy

+4-18
Original file line numberDiff line numberDiff line change
@@ -173,24 +173,10 @@ class AdminController {
173173
def showUsersAlerts() {
174174
User user = User.findByUserId(params.userId)
175175
if (user) {
176-
def notificationInstanceList = Notification.findAllByUser(user)
177-
//split into custom and non-custom...
178-
def enabledQueries = notificationInstanceList.collect { it.query }
179-
def enabledIds = enabledQueries.collect { it.id }
180-
181-
//all types
182-
def allAlertTypes = Query.findAllByCustom(false)
183-
184-
allAlertTypes.removeAll { enabledIds.contains(it.id) }
185-
def customQueries = enabledQueries.findAll { it.custom }
186-
def standardQueries = enabledQueries.findAll { !it.custom }
187-
188-
render(view: "../notification/myAlerts", model: [disabledQueries: allAlertTypes,
189-
enabledQueries : standardQueries, customQueries: customQueries,
190-
frequencies : Frequency.listOrderByPeriodInSeconds(),
191-
user : user,
192-
adminUser : authService.userDetails()
193-
])
176+
def userConfig = userService.getUserAlertsConfig(user)
177+
userConfig.put('adminUser', authService.userDetails())
178+
179+
render(view: "../notification/myAlerts", model: userConfig)
194180
} else {
195181
log.info "user with id " + params.userId + " not found."
196182
response.sendError(404)

grails-app/controllers/au/org/ala/alerts/NotificationController.groovy

+34-42
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package au.org.ala.alerts
22

3-
import au.org.ala.web.AlaSecured
43
import grails.converters.JSON
54
import org.apache.http.HttpStatus
65

@@ -22,66 +21,51 @@ class NotificationController {
2221
}
2322

2423
def addMyAlert = {
25-
def user
26-
if (authService.userInRole("ROLE_ADMIN")) {
27-
user = userService.getUserById(params.userId)
28-
} else {
29-
user = userService.getUser()
30-
}
24+
def user = getUser()
3125

3226
if (!user) {
3327
response.status = HttpStatus.SC_NOT_FOUND
3428
response.sendError(HttpStatus.SC_NOT_FOUND, "Unrecognised user")
3529
} else {
36-
log.debug('add my alert ' + params.id)
37-
def notificationInstance = new Notification()
38-
notificationInstance.query = Query.findById(params.id)
39-
notificationInstance.user = user
40-
//does this already exist?
41-
def exists = Notification.findByQueryAndUser(notificationInstance.query, notificationInstance.user)
42-
if (!exists) {
43-
log.info("Adding alert for user: " + notificationInstance.user + ", query id: " + params.id)
44-
notificationInstance.save(flush: true)
45-
} else {
46-
log.info("NOT Adding alert for user: " + notificationInstance.user + ", query id: " + params.id + ", already exists...")
47-
}
30+
notificationService.addAlertForUser(user, Long.valueOf(params.id))
4831
return null
4932
}
5033
}
5134

5235
def deleteMyAlert = {
53-
def user
54-
if (authService.userInRole("ROLE_ADMIN")) {
55-
user = userService.getUserById(params.userId)
56-
} else {
57-
user = userService.getUser()
58-
}
36+
def user = getUser()
5937

6038
if (!user) {
6139
response.status = HttpStatus.SC_NOT_FOUND
6240
response.sendError(HttpStatus.SC_NOT_FOUND, "Unrecognised user")
6341
} else {
64-
def query = Query.get(params.id)
65-
log.debug('Deleting my alert : ' + params.id + ' for user : ' + authService.getDisplayName())
66-
67-
def notificationInstance = Notification.findByUserAndQuery(user, query)
68-
if (notificationInstance) {
69-
log.debug('Deleting my notification : ' + params.id)
70-
notificationInstance.each { it.delete(flush: true) }
71-
} else {
72-
log.error('*** Unable to find my notification - no delete : ' + params.id)
73-
}
74-
return null
42+
notificationService.deleteAlertForUser(user, Long.valueOf(params.id))
7543
}
7644
}
7745

78-
def deleteMyAlertWR = {
79-
def user
80-
if (authService.userInRole("ROLE_ADMIN")) {
81-
user = userService.getUserById(params.userId)
82-
} else {
83-
user = userService.getUser()
46+
def addMyAnnotation = {
47+
def user = getUser()
48+
try {
49+
notificationService.addMyAnnotation(user)
50+
render ([success: true] as JSON)
51+
} catch (ignored) {
52+
response.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, "failed to add 'my annotation' alert for user " + user?.getUserId())
53+
}
54+
55+
}
56+
57+
def deleteMyAnnotation = {
58+
def user = getUser()
59+
try {
60+
notificationService.deleteMyAnnotation(user)
61+
render ([success: true] as JSON)
62+
} catch (ignored) {
63+
response.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, "failed to delete 'my annotation' alert for user " + user?.getUserId())
8464
}
65+
}
66+
67+
def deleteMyAlertWR = {
68+
def user = getUser()
8569

8670
//this is a hack to get around a CAS issue
8771
if (user == null) {
@@ -101,6 +85,14 @@ class NotificationController {
10185
redirect(action: 'myAlerts')
10286
}
10387

88+
private User getUser() {
89+
if (authService.userInRole("ROLE_ADMIN")) {
90+
return userService.getUserById(params.userId)
91+
} else {
92+
return userService.getUser()
93+
}
94+
}
95+
10496
def changeFrequency = {
10597
def user = userService.getUser()
10698
log.debug("Changing frequency to: " + params.frequency + " for user ${user}")

grails-app/controllers/au/org/ala/alerts/QueryController.groovy

+9-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class QueryController {
88

99
static allowedMethods = [save: "POST", update: "POST", update: "PUT", delete: "POST"]
1010
def authService
11+
def queryService
1112

1213
def index() {
1314
redirect(action: "list", params: params)
@@ -148,9 +149,14 @@ class QueryController {
148149
}
149150

150151
try {
151-
queryInstance.delete(flush: true)
152-
flash.message = message(code: 'default.deleted.message', args: [message(code: 'query.label', default: 'Query'), params.id])
153-
redirect(action: "list")
152+
if (queryInstance.notifications?.size() == 0){
153+
queryService.deleteQuery(queryInstance)
154+
flash.message = message(code: 'default.deleted.message', args: [message(code: 'query.label', default: 'Query'), params.id])
155+
redirect(action: "list")
156+
} else {
157+
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'query.label', default: 'Query'), params.id])
158+
redirect(action: "show", id: params.id)
159+
}
154160
}
155161
catch (DataIntegrityViolationException e) {
156162
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'query.label', default: 'Query'), params.id])

grails-app/controllers/au/org/ala/alerts/UrlMappings.groovy

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ class UrlMappings {
4343
// /api/* will not be protected by CAS, but all operations should be protected with @RequireApiKey
4444
"/api/alerts/user/$userId/unsubscribe"(controller: 'webservice', action: [POST: 'deleteAllAlertsForUser'])
4545
"/api/alerts/user/createAlerts"(controller: 'webservice', action: [POST: 'createUserAlerts'])
46+
47+
"/api/alerts/user/$userId"(controller: 'webservice', action: [GET: 'getUserAlertsWS'])
48+
4649
"/robots.txt"(view:'/notFound')
4750
"400"(view:'/error')
4851
"403"(view:'/error')

grails-app/controllers/au/org/ala/alerts/WebserviceController.groovy

+44
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class WebserviceController {
2222

2323
def queryService
2424
def userService
25+
def notificationService
2526

2627
def index = {}
2728
def test = {}
@@ -395,4 +396,47 @@ class WebserviceController {
395396
}
396397
user
397398
}
399+
400+
@RequireApiKey
401+
def getUserAlertsWS() {
402+
User user = userService.getUserById(params.userId)
403+
if (user == null) {
404+
response.status = 404
405+
render ([error : "can't find a user with userId " + params.userId] as JSON)
406+
} else {
407+
render (userService.getUserAlertsConfig(user) as JSON)
408+
}
409+
}
410+
411+
@RequireApiKey
412+
def addMyAnnotationAlertWS() {
413+
User user = userService.getUserById(params.userId)
414+
if (user == null) {
415+
response.status = 404
416+
render ([error : "can't find a user with userId " + params.userId] as JSON)
417+
} else {
418+
try {
419+
notificationService.addMyAnnotation(user)
420+
render([success: true] as JSON)
421+
} catch (ignored) {
422+
render "failed to add my annotation for user " + params.userId, contentType: 'text/plain', status: 500
423+
}
424+
}
425+
}
426+
427+
@RequireApiKey
428+
def deleteMyAnnotationAlertWS() {
429+
User user = userService.getUserById(params.userId)
430+
if (user == null) {
431+
response.status = 404
432+
render ([error : "can't find a user with userId " + params.userId] as JSON)
433+
} else {
434+
try {
435+
notificationService.deleteMyAnnotation(user)
436+
render([success: true] as JSON)
437+
} catch (ignored) {
438+
render "failed to delete my annotation for user " + params.userId, contentType: 'text/plain', status: 500
439+
}
440+
}
441+
}
398442
}

grails-app/domain/au/org/ala/alerts/Query.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Query {
2121
String idJsonPath //the json path for producing a list of IDs for change detection
2222
String recordJsonPath
2323

24-
static hasMany = [ notifications : Notification, queryResults:QueryResult, propertyPaths:PropertyPath ]
24+
static hasMany = [notifications: Notification, queryResults: QueryResult, propertyPaths: PropertyPath]
2525

2626
static constraints = {
2727
description nullable: true, maxSize: 400, widget:'textarea'

grails-app/i18n/messages.properties

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
annotations.update.message={0} occurrence records have been annotated.
2+
myannotations.update.message={0} occurrence records have been reviewed and updated by the custodian.
23
more.records.update.message={0} more occurrence records have been added.
34
more.images.update.message={0} more occurrence records with images have been added.
45
more.cs.update.message={0} more citizen science records have been added.
@@ -100,6 +101,7 @@ admin.view.my.alerts=View my email subscriptions
100101
admin.view.list=View list of alert types
101102
admin.run.hourly=Run hourly checks now
102103
admin.run.daily=Run daily checks now
104+
admin.run.weekly=Run weekly checks now
103105
admin.run.monthly=Run monthly checks now
104106
my.alerts.breadcrumbs=My email subscriptions
105107
my.alerts.breadcrumb.parent=My profile
@@ -141,6 +143,8 @@ not.found.title=Page Not Found
141143
not.found.path=Path:
142144
query.annotations.title=Annotations
143145
query.annotations.descr=Notify me when annotations are made on any record.
146+
query.myannotations.title=My Annotations
147+
query.myannotations.descr=Notify me when records I have flagged are updated.
144148
query.new.records.title=New records
145149
query.new.records.descr=Notify me when new records are added.
146150
query.new.images.title=New images
@@ -151,6 +155,8 @@ query.citizen.records.imgs.title=Citizen science records with images
151155
query.citizen.records.imgs.descr=Notify me when new citizen science records with images are added.
152156
query.spatial.layers.title=Spatial layers
153157
query.spatial.layers.descr=Notify me when new spatial layers are added.
158+
query.occurrence.datasets.title=New occurrence datasets
159+
query.occurrence.datasets.descr=Notify me when new occurrence datasets are added.
154160
query.datasets.title=Datasets
155161
query.datasets.descr=Notify me when new datasets are added.
156162
query.species.lists.title=Species lists
@@ -160,4 +166,17 @@ query.ala.blog.descr=Notify me when ALA Blog items are added.
160166
frequency.hourly=hourly
161167
frequency.daily=daily
162168
frequency.weekly=weekly
163-
frequency.monthly=monthly
169+
frequency.monthly=monthly
170+
emailservice.update.subject=Update - {0}
171+
query.service.occurrences.name=New records for {0}
172+
query.service.occurrences.update.msg=More occurrence records have been added for {0}
173+
query.service.occurrences.desc=Notify me when new records are added for {0}
174+
query.service.annotations.name=New annotations on records for {0}
175+
query.service.annotations.update.msg=Annotations have been added for {0}
176+
query.service.annotations.desc=Notify me when new annotations are added for {0}
177+
query.service.occurrences.resource.update.msg=More occurrence records have been added for {0} - {1}
178+
query.service.occurrences.resource.desc=Notify me when new records are added for {0} - {1}
179+
query.service.occurrences.recorded.name=New records for {0} recorded in {1}
180+
query.service.occurrences.recorded.update.msg=More occurrence records have been added for {0} recorded in {1}
181+
query.service.occurrences.recorded.desc=Notify me when new recoCitizen science records with images'rds are added for {0} recorded in {1}
182+
biocache.no.image=No image

0 commit comments

Comments
 (0)