Skip to content

Commit 7237d05

Browse files
committed
Merge branch 'release/6.1.7'
2 parents 058bfdf + 8ab644d commit 7237d05

File tree

26 files changed

+677
-91
lines changed

26 files changed

+677
-91
lines changed

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ branches:
77
only:
88
- master
99
- develop
10-
- feature/dg-101
10+
- /^feature\/.*$/
11+
- /^hotfix\/.*$/
1112
services:
1213
- postgresql
1314
addons:

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ plugins {
2424
id "com.dorongold.task-tree" version "2.1.1"
2525
}
2626

27-
version "6.1.6"
27+
version "6.1.7"
2828
group "au.org.ala"
2929
description "Digivol application"
3030

grails-app/assets/javascripts/admin-stats.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -400,13 +400,19 @@ function adminStats(config) {
400400
self.getTranscriptionTimeByProjectType();
401401
};
402402

403+
self.toISODate = function(dateObj) {
404+
return dateObj.getFullYear() + '-' +
405+
('0'+ (dateObj.getMonth()+1)).slice(-2) + '-' +
406+
('0'+ dateObj.getDate()).slice(-2) + 'T00:00:00';
407+
}
408+
403409
self.exportToCSV = function (data, reportType) {
404410
// var dt = new google.visualization.DataTable(data);
405411
// var csv = dt.toCSV();
406412
// if (downloadCSV(csv, reportType) == "failed") {
407413
//request browser to trigger server api to download
408-
var startParam = self.startDate != null ? self.startDate.toISOString() : '';
409-
var endParam = self.endDate != null ? self.endDate.toISOString() : '';
414+
var startParam = self.startDate != null ? self.toISODate(self.startDate) : '';
415+
var endParam = self.endDate != null ? self.toISODate(self.endDate) : '';
410416
var institutionParam = self.institutionId;
411417
var url = config.exportCSVReport + "?reportType=" + reportType + "&startDate=" + encodeURIComponent(startParam) +
412418
"&endDate=" + encodeURIComponent(endParam) + "&institutionId=" + encodeURIComponent(institutionParam);

grails-app/conf/application.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ spring:
120120
enabled: true
121121
baselineOnMigrate: true
122122
baselineVersion: 1
123-
outOfOrder: true
123+
outOfOrder: false
124+
default-schema: 'public'
125+
table: 'schema_version'
124126

125127
server:
126128
tomcat:

grails-app/conf/spring/resources.groovy

+19-20
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,48 @@ import au.org.ala.volunteer.BVPServletFilter
33
import au.org.ala.volunteer.DigivolServletContextConfig
44
import au.org.ala.volunteer.collectory.CollectoryClientFactoryBean
55
import org.flywaydb.core.Flyway
6-
import org.flywaydb.core.api.MigrationVersion
6+
import org.flywaydb.core.api.configuration.ClassicConfiguration
77
import org.springframework.beans.factory.config.BeanDefinition
88
import org.springframework.boot.web.servlet.FilterRegistrationBean
99

1010
// Place your Spring DSL code here
1111
beans = {
12-
// customPageRenderer(CustomPageRenderer, ref("groovyPagesTemplateEngine")) {
13-
// groovyPageLocator = ref("groovyPageLocator")
14-
// }
15-
1612
collectoryClient(CollectoryClientFactoryBean) {
1713
endpoint = 'http://collections.ala.org.au/ws/'
1814
}
1915

20-
// bvpSecurePluginFilter(BVPSecurePluginFilter) {
21-
// securityPrimitives = ref("securityPrimitives")
22-
// }
23-
2416
applicationContextHolder(ApplicationContextHolder) { bean ->
2517
bean.factoryMethod = 'getInstance'
2618
}
2719

2820
digivolServletContextConfig(DigivolServletContextConfig)
2921

30-
bvpServletFilter(FilterRegistrationBean) {
22+
bvpServletFilterBean(BVPServletFilter) {
23+
authService = ref("authService")
24+
}
25+
bvpServletFilterRegistrationBean(FilterRegistrationBean) {
3126
name = 'BVPServletFilter'
32-
filter = bean(BVPServletFilter)
27+
filter = ref("bvpServletFilterBean")
3328
urlPatterns = [ '/*' ]
3429
asyncSupported = true
3530
}
3631

37-
if (application.config.getProperty('flyway.enabled', Boolean)) {
32+
if (application.config.getProperty('spring.flyway.enabled', Boolean)) {
3833

39-
flyway(Flyway) { bean ->
40-
bean.initMethod = 'migrate'
34+
flywayConfiguration(ClassicConfiguration) { bean ->
4135
dataSource = ref('dataSource')
42-
baselineOnMigrate = application.config.getProperty('flyway.baselineOnMigrate', Boolean, false)
43-
def outOfOrderProp = application.config.getProperty('flyway.outOfOrder', Boolean, false)
36+
defaultSchema = application.config.getProperty('spring.flyway.default-schema')
37+
table = application.config.getProperty('spring.flyway.table')
38+
baselineOnMigrate = application.config.getProperty('spring.flyway.baselineOnMigrate', Boolean, true)
39+
def outOfOrderProp = application.config.getProperty('spring.flyway.outOfOrder', Boolean, false)
4440
outOfOrder = outOfOrderProp
45-
//locations = application.config.flyway.locations ?: 'classpath:db/migration'
46-
locations = ['classpath:db/migration']
47-
if (application.config.getProperty('flyway.baselineVersion', Integer))
48-
baselineVersionAsString = application.config.getProperty('flyway.baselineVersion', Integer).toString()
41+
locationsAsStrings = application.config.getProperty('spring.flyway.locations', List<String>, ['classpath:db/migration'])
42+
if (application.config.getProperty('spring.flyway.baselineVersion', Integer))
43+
baselineVersionAsString = application.config.getProperty('spring.flyway.baselineVersion', Integer).toString()
44+
}
45+
46+
flyway(Flyway, ref('flywayConfiguration')) { bean ->
47+
bean.initMethod = 'migrate'
4948
}
5049

5150
BeanDefinition sessionFactoryBeanDef = getBeanDefinition('sessionFactory')

grails-app/controllers/au/org/ala/volunteer/DigivolActivityInterceptor.groovy

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package au.org.ala.volunteer
22

3-
import au.org.ala.cas.util.AuthenticationCookieUtils
3+
import au.org.ala.web.AuthService
44
import groovy.transform.CompileStatic
55
import groovy.util.logging.Slf4j
66

@@ -9,6 +9,7 @@ import groovy.util.logging.Slf4j
99
class DigivolActivityInterceptor {
1010

1111
UserService userService
12+
AuthService authService
1213
SettingsService settingsService
1314

1415
DigivolActivityInterceptor() {
@@ -25,7 +26,7 @@ class DigivolActivityInterceptor {
2526
return true
2627
}
2728

28-
def userId = AuthenticationCookieUtils.getUserName(request)
29+
def userId = authService.userName
2930
if (userId) {
3031
userService.recordUserActivity(userId, request, params)
3132
}

grails-app/controllers/au/org/ala/volunteer/ProjectController.groovy

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package au.org.ala.volunteer
22

3-
import au.org.ala.cas.util.AuthenticationCookieUtils
43
import com.google.common.base.Stopwatch
54
import com.google.common.base.Strings
65
import grails.converters.JSON
76
import grails.gorm.transactions.Transactional
87
import grails.web.servlet.mvc.GrailsParameterMap
9-
import org.apache.commons.io.FileUtils
108
import org.jooq.DSLContext
119
import org.springframework.dao.DataIntegrityViolationException
1210
import org.springframework.web.multipart.MultipartFile
@@ -56,7 +54,7 @@ class ProjectController {
5654

5755
String currentUserId = null
5856

59-
def username = AuthenticationCookieUtils.getUserName(request)
57+
def username = authService.userName
6058
if (username) currentUserId = authService.getUserForEmailAddress(username)?.userId
6159

6260
if (!projectInstance) {

grails-app/controllers/au/org/ala/volunteer/SettingController.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class SettingController {
6363
SettingDefinition settingDefinition = getSettingDefByKey(key)
6464
if (settingDefinition && value) {
6565
settingsService.setSetting(key, value)
66-
flash.message= "Setting '${key}' set to '${value}'"
66+
flash.message= "Updated setting '${key}'."
6767
} else {
6868
flash.message= "Save setting failed! Either the setting key or value was missing/null"
6969
}

grails-app/controllers/au/org/ala/volunteer/TranscribeController.groovy

+20-3
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,15 @@ class TranscribeController {
309309
def skipNextAction = params.getBoolean('skipNextAction', false)
310310
WebUtils.cleanRecordValues(params.recordValues as Map)
311311

312-
fieldSyncService.syncFields(taskInstance, params.recordValues as Map, currentUser, markTranscribed,
313-
false, null, fieldSyncService.truncateFieldsForProject(taskInstance.project),
314-
request.remoteAddr, transcription)
312+
fieldSyncService.syncFields(taskInstance,
313+
params.recordValues as Map,
314+
currentUser,
315+
markTranscribed as boolean,
316+
false,
317+
null,
318+
fieldSyncService.truncateFieldsForProject(taskInstance.project),
319+
request.remoteAddr,
320+
transcription)
315321

316322
if (!taskInstance.hasErrors()) {
317323
updatePicklists(taskInstance)
@@ -321,6 +327,7 @@ class TranscribeController {
321327
render([success: true] as JSON)
322328
} else {
323329
log.debug("Save successful, skip to next task.")
330+
welcomeUser(currentUserObj)
324331
redirect(action: 'showNextFromProject', id: taskInstance.project.id,
325332
params: [prevId: taskInstance.id, prevUserId: currentUser, complete: params.id, mode: params.mode ?: ''])
326333
}
@@ -330,6 +337,7 @@ class TranscribeController {
330337
render([success: true] as JSON)
331338
} else {
332339
log.debug("Save successful. Redirecting to show next action view")
340+
welcomeUser(currentUserObj)
333341
redirect(action: 'showNextAction', id: params.id, params: [mode: params.mode ?: ''])
334342
}
335343
}
@@ -352,6 +360,15 @@ class TranscribeController {
352360
}
353361
}
354362

363+
private void welcomeUser(User user) {
364+
// Welcome email? Send if this was their first transcription and haven't been welcomed yet
365+
User updatedUser = User.get(user.id)
366+
if (!updatedUser.hasBeenWelcomed()) {
367+
log.debug("User being sent welcome email after transcribing first task.")
368+
userService.sendWelcomeEmail(updatedUser, UserService.WELCOME_EMAIL_TRANSCRIPTION)
369+
}
370+
}
371+
355372
/**
356373
* Show the next task for the supplied project.
357374
*/

grails-app/domain/au/org/ala/volunteer/User.groovy

+15-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ class User implements AsyncEntity<User> {
99
String firstName
1010
String lastName
1111
String organisation
12-
Integer transcribedCount = 0 //the number of tasks completed by the user
13-
Integer validatedCount = 0 // the number of task completed by this user and then validated by a validator
14-
Date created //set to the date when the user first contributed
12+
Integer transcribedCount = 0 // the number of tasks completed by the user
13+
Integer validatedCount = 0 // the number of task completed by this user and then validated by a validator
14+
Date created // set to the date when the user first contributed
15+
Date welcomeEmailSent // Datetime user is sent the 'welcome' email.
1516

1617
String displayName // computed
1718

@@ -23,6 +24,7 @@ class User implements AsyncEntity<User> {
2324
table 'vp_user'
2425
displayName formula: '''FIRST_NAME || ' ' || LAST_NAME'''
2526
version false
27+
welcomeEmailSent column: 'welcome_date'
2628
}
2729

2830
static constraints = {
@@ -34,6 +36,7 @@ class User implements AsyncEntity<User> {
3436
displayName nullable: true // nullable for unit tests
3537
userId maxSize: 200
3638
email maxSize: 200
39+
welcomeEmailSent nullable: true
3740
}
3841

3942
@Override
@@ -74,4 +77,13 @@ class User implements AsyncEntity<User> {
7477
public String toString() {
7578
"User (id: $id, userId: ${userId}, displayName: ${displayName})"
7679
}
80+
81+
/**
82+
* Returns true or false if a given user has been sent a welcome email yet.
83+
* @return
84+
*/
85+
def hasBeenWelcomed() {
86+
log.debug("User.hasBeenWelcomed: ${!(welcomeEmailSent == null)}")
87+
return !(welcomeEmailSent == null)
88+
}
7789
}

grails-app/i18n/messages.properties

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ default.button.dont.validate.label=Save partial validation
5454

5555
default.leaderboard.describeBadges.label=Badges
5656

57+
default.user.welcome.subject=Welcome to DigiVol!
58+
default.user.welcome.preview=A welcome to DigiVol from the Australian Museum and Atlas of Living Australia.
59+
5760
# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
5861
typeMismatch.java.net.URL=Property {0} must be a valid URL
5962
typeMismatch.java.net.URI=Property {0} must be a valid URI

grails-app/jobs/au/org/ala/volunteer/NewUserDigestNotifierJob.groovy

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import javax.sql.DataSource
1111
@Slf4j
1212
class NewUserDigestNotifierJob {
1313
def mailService
14+
def userService
1415
DataSource dataSource
1516
static concurrent = false
1617

@@ -89,6 +90,15 @@ class NewUserDigestNotifierJob {
8990
sql.close()
9091
}
9192
}
93+
94+
// Welcome emails
95+
def userList = User.findAllByWelcomeEmailSent(null)
96+
if (userList.size() > 0) {
97+
userList.each {user ->
98+
userService.sendWelcomeEmail(user, UserService.WELCOME_EMAIL_SYNC)
99+
}
100+
}
101+
92102
log.info("New User Digest Notifier job finishing at ${new Date()}")
93103
}
94104
}

grails-app/services/au/org/ala/volunteer/InstitutionMessageService.groovy

+3-2
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ class InstitutionMessageService {
293293
// Render the message, if errors, set the status and move on.
294294
String message
295295
try {
296-
message = groovyPageRenderer.render(view: '/institutionMessage/messageTemplate',
297-
model: [subject : iMessage.subject,
296+
message = groovyPageRenderer.render(view: '/mail/messageTemplate',
297+
model: [messageTemplate : 'institutionMsg',
298+
subject : iMessage.subject,
298299
inboxPreview : "A message from ${iMessage.institution.name}",
299300
serverUrl : serverUrl,
300301
institutionName : iMessage.institution.name,

0 commit comments

Comments
 (0)