@@ -75,14 +75,15 @@ class BiosecurityCSVService {
75
75
76
76
def tempFilePath = Files . createTempFile(outputFile, " .csv" )
77
77
def tempFile = tempFilePath. toFile()
78
- String rawHeader = " recordID:uuid, recordLink:occurrenceLink, scientificName,taxonConceptID,decimalLatitude,decimalLongitude,eventDate,occurrenceStatus,dataResourceName,multimedia,media_id:image," +
78
+ // example of rawHeader
79
+ // recordID:uuid recordID is the header name, uuid is the property in the record
80
+ String rawHeader = " recordID:uuid, recordLink:occurrenceLink, scientificName,taxonConceptID,decimalLatitude,decimalLongitude,eventDate,occurrenceStatus,dataResourceName,multimedia,mediaId:image," +
79
81
" vernacularName,taxonConceptID_new,kingdom,phylum,class:classs,order,family,genus,species,subspecies," +
80
82
" firstLoadedDate:firstLoaded,basisOfRecord,match," +
81
- " search_term,correct_name:scientificName,provided_name:providedName,common_name:vernacularName,state:stateProvince,lga,shape,list_id:listId,list_name:listName,cw_state,shape_feature,creator:collector," +
82
- " license,mimetype,width,height," +
83
- " image_url:smallImageUrl," + // TBC , multiple image urls
84
- " date_sent:dateSent," +
85
- " cl"
83
+ " searchTerm:search_term,correct name:scientificName,provided name:providedName,common name:vernacularName,state:stateProvince,lga layer,lga,fq,list id:listId,list name:listName, listLink:listLink, cw_state,shape feature:shape_feature,creator:collector," +
84
+ " license,mimetype," +
85
+ " image url:smallImageUrl," + // TBC , multiple image urls
86
+ " date sent:dateSent"
86
87
// "fq, kvs"
87
88
if (grailsApplication. config. biosecurity. csv. headers) {
88
89
rawHeader = grailsApplication. config. biosecurity. csv. headers
@@ -92,7 +93,6 @@ class BiosecurityCSVService {
92
93
def fields = []
93
94
def headersAndFields = rawHeader. split(' ,' )
94
95
headersAndFields. each { entry ->
95
-
96
96
def parts = entry. trim(). split(' :' , 2 ) // Split on ':' with a limit of 2 parts
97
97
headers << parts[0 ] // Add the part before ':' to the first array
98
98
if (parts. size() > 1 ) {
@@ -107,36 +107,14 @@ class BiosecurityCSVService {
107
107
writer. write(headers. join(" ," )+ " \n " )
108
108
records. each { record ->
109
109
def values = fields. collect { field ->
110
- def value = " "
111
- if (record. containsKey(field)) {
112
- value = record[field]
113
- // if value is a list, convert it to a string. e.g. collectors, images
114
- if (value instanceof List ) {
115
- value = " \" ${ value.join(";")} \" " // Join the list with ';' and wrap it in double quotes
116
- } else {
117
- value = value. toString()
118
- switch (field) {
119
- case " eventDate" :
120
- if (value) {
121
- value = new SimpleDateFormat (" dd/MM/yyyy hh:mm:ss" ). format(value. toLong())
122
- }
123
- break
124
- default :
125
- if (value instanceof List ) {
126
- value = " \" ${ value.join(";")} \" " // Join the list with ';' and wrap it in double quotes
127
- } else {
128
- value = value. toString()
129
- }
130
- break
131
- }
132
- }
133
- } else {
134
- // special cases
135
- if (field == " lga" ) {
110
+ def value = record[field]
111
+
112
+ switch (field) {
113
+ case " lga" :
136
114
// read from cl (context layer)
137
115
def cls = record[" cl" ]
138
- // LGA2023
139
- def layerId= grailsApplication. config. biosecurity. csv. lga ?: " LGA2023"
116
+ // LGA2023 is the default layer id
117
+ def layerId = grailsApplication. config. getProperty( ' biosecurity.csv.lga' , ' LGA2023' )
140
118
if (cls) {
141
119
String matched = cls. find {
142
120
def (k, v) = it. split(' :' ) // Split the string into key and value
@@ -145,8 +123,30 @@ class BiosecurityCSVService {
145
123
// assure return "" if matched is null
146
124
value = matched?. split(' :' )?. with { it. size() > 1 ? it[1 ] : " " } ?: " "
147
125
}
148
- }
126
+ break
127
+ case " lga layer" :
128
+ value = grailsApplication. config. biosecurity. csv. lga ?: " LGA2023"
129
+ break
130
+ case " eventDate" :
131
+ if (value) {
132
+ value = new SimpleDateFormat (" dd/MM/yyyy hh:mm:ss" ). format(value. toLong())
133
+ } else {
134
+ value = " "
135
+ }
136
+ break
137
+ default :
138
+ if (record. containsKey(field)) {
139
+ if (value instanceof List ) {
140
+ value = " \" ${ value.join(";")} \" " // Join the list with ';' and wrap it in double quotes
141
+ } else {
142
+ value = value. toString()
143
+ }
144
+ } else {
145
+ value = " "
146
+ }
147
+ break
149
148
}
149
+
150
150
return value
151
151
}
152
152
writer. write(values. join(" ," ))
@@ -165,9 +165,10 @@ class BiosecurityCSVService {
165
165
String aggregateCSVFiles (String folderName ) {
166
166
def BASE_DIRECTORY = grailsApplication. config. biosecurity. csv. local. directory
167
167
def folder = new File (BASE_DIRECTORY , folderName)
168
- Collection<File > csvFiles = folder. listFiles(). findAll { it. isFile() && it. name. endsWith(' .csv' ) }
168
+ Collection<File > csvFiles = []
169
+ collectCsvFiles(folder, csvFiles)
169
170
170
- log. info(" Aggregate CSV files into one file" )
171
+ log. info(" Aggregate ${ csvFiles.size() } CSV files under ${ folder } into one file" )
171
172
def tempFilePath = Files . createTempFile(" merged_" , " .csv" )
172
173
def tempFile = tempFilePath. toFile()
173
174
tempFile. withWriter { writer ->
@@ -189,6 +190,21 @@ class BiosecurityCSVService {
189
190
return tempFile. absolutePath
190
191
}
191
192
193
+ /**
194
+ * Collect CSV files from the folder and its subfolders
195
+ * @param folder
196
+ * @param collectedFiles
197
+ */
198
+ private void collectCsvFiles (File folder , Collection<File > collectedFiles ) {
199
+ folder. listFiles(). each { file ->
200
+ if (file. isDirectory()) {
201
+ collectCsvFiles(file, collectedFiles) // Recursively collect CSV files from subfolders
202
+ } else if (file. isFile() && file. name. endsWith(' .csv' )) {
203
+ collectedFiles. add(file)
204
+ }
205
+ }
206
+ }
207
+
192
208
/**
193
209
* Move file from source to destination
194
210
* @param source
@@ -219,13 +235,14 @@ class BiosecurityCSVService {
219
235
* @param dir
220
236
* @return Key value pair of folder and files
221
237
* */
238
+
222
239
private List<Map > listFilesRecursively (File dir ) {
223
240
def BASE_DIRECTORY = grailsApplication. config. biosecurity. csv. local. directory
224
241
def rootDir = new File (BASE_DIRECTORY )
225
242
def foldersAndFiles = rootDir. listFiles(). findAll { it. isDirectory() }. collect { folder ->
226
243
[
227
244
name : folder. name,
228
- files : folder. listFiles(). findAll { it. isFile() }. collect { file -> file. name }
245
+ files : folder. listFiles(). findAll { it. isFile() && it . name . endsWith( ' .csv ' ) }. collect { file -> file. name }
229
246
]
230
247
}
231
248
return foldersAndFiles
0 commit comments