Changeset 14
- Timestamp:
- Feb 16, 2011, 2:24:56 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/conf/BaseFilters.groovy
r12 r14 184 184 log.info "User is not authenticated during synchronizatino. Redirecting to GSCF." 185 185 redirect( url: gscfService.urlAuthRemote(params, session.sessionToken) ) 186 return false; 186 187 } catch( Exception e ) { 187 188 // Synchronization fails. Log error and continue; don't bother the user with it -
trunk/grails-app/conf/UrlMappings.groovy
r2 r14 8 8 } 9 9 10 "/"(controller: " study")10 "/"(controller: "run") 11 11 "500"(view:'/error') 12 12 } -
trunk/grails-app/controllers/nl/tno/metagenomics/AssayController.groovy
r13 r14 1 1 package nl.tno.metagenomics 2 3 import java.util.List; 2 4 3 5 import org.codehaus.groovy.grails.commons.ConfigurationHolder … … 19 21 gscfAddUrl: gscfService.urlAddStudy() ] 20 22 } 21 23 22 24 def show = { 23 25 def assay = getAssay( params.id ); … … 65 67 } 66 68 69 if (!assay.study.canRead( session.user ) ) { 70 flash.error = "You don't have the right authorizaton to access assay " + assay.name 71 redirect(action: 'index') 72 return null 73 } 74 67 75 redirect( action: "show", id: assay.id ); 68 76 } … … 95 103 */ 96 104 def parseTagExcel = { 97 def assay = getAssay( params.id );105 def assay = getAssay( params.id, true ); 98 106 if( !assay ) 99 107 return … … 129 137 } 130 138 session.possibleFields = excelData.possibleFields 131 139 132 140 [assay: assay, headers: excelData.headers, exampleData: excelData.exampleData, filename: filename, possibleFields: [ "Don't import" ] + excelData.possibleFields, bestMatches: excelData.bestMatches] 133 141 } … … 137 145 */ 138 146 def updateTagsByExcel = { 139 def assay = getAssay( params.id );147 def assay = getAssay( params.id, true ); 140 148 if( !assay ) { 141 149 // Now delete the file, since we don't need it anymore … … 158 166 // Now loop through the excel sheet and update all samples with the specified data 159 167 File file = new File( fileService.getUploadDir(), session.filename ); 160 168 161 169 if( !file.exists() || !file.canRead() ) { 162 170 flash.error = "Excel file has been removed since previous step. Please try again." … … 164 172 return 165 173 } 166 174 167 175 def excelData = sampleExcelService.updateTagsByExcel( matchColumns, session.possibleFields, file, assay.assaySamples ); 168 176 … … 178 186 flash.message += excelData.failedRows.size() + " row(s) could not be imported, because the sample names could not be found in the database." 179 187 } 188 189 // Now delete the file, since we don't need it anymore 190 _deleteUploadedFileFromSession() 191 180 192 redirect( action: 'show', id: params.id ) 181 193 } … … 185 197 */ 186 198 def updateTagsManually = { 187 def assay = getAssay( params.id );199 def assay = getAssay( params.id, true ); 188 200 if( !assay ) 189 201 return … … 224 236 */ 225 237 def addExistingRuns = { 226 def assay = getAssay( params.id );238 def assay = getAssay( params.id, true ); 227 239 if( !assay ) 228 240 return … … 250 262 251 263 /** 252 * Adds existing runs tothis assay264 * Removes a run from this assay 253 265 */ 254 266 def removeRun = { 255 def assay = getAssay( params.id );267 def assay = getAssay( params.id, true ); 256 268 if( !assay ) 257 269 return … … 300 312 session.filename = '' 301 313 } 302 303 protected Assay getAssay(def assayId) { 304 // load study with id specified by param.id 305 def assay 306 try { 307 assay = Assay.get(assayId as Long) 308 } catch( Exception e ) { 309 flash.error = "Incorrect id given: " + assayId 310 redirect(controller: 'study') 311 return null 312 } 313 314 if (!assay) { 315 flash.error = "No assay found with id: " + assayId 316 redirect(controller: 'study') 317 return null 318 } 319 320 if (!assay.study.canRead( session.user ) ) { 321 flash.error = "You don't have the right authorizaton to access assay " + assay.name 322 redirect(controller: 'study') 323 return null 324 } 325 326 return assay 327 } 328 314 329 315 /** 330 316 * Exports data about one or more assays in fasta format 331 317 */ 332 318 def exportAsFasta = { 333 def tokens = params.list( 'tokens' ); 334 def ids = params.list( 'ids' ); 335 def name; 336 337 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 338 339 if( !tokens && !ids ) { 340 def message = "No assay tokens or ids given" 341 response.setStatus( 400, message) 342 render message; 343 return; 344 } 345 346 def assaySamples = []; 347 348 // Determine which assaySamples to export 349 def assay; 350 tokens.each { token -> 351 assay = Assay.findByAssayToken( token ); 352 if( assay ) 353 assaySamples += assay.assaySamples 354 } 355 ids.each { id -> 356 assay = Assay.get( id ); 357 if( assay ) 358 assaySamples += assay.assaySamples 359 } 360 361 if( ( ids.size() + tokens.size() ) == 1 && assay ) 362 name = "Assay_" + assay?.name?.replace( ' ', '_' ); 363 else 319 def assaySamples = getAssaySamples( params ); 320 def name 321 322 if( assaySamples == null ) { 323 return 324 } else if( assaySamples*.assay.unique().size() == 1 ) { 325 name = "Assay_" + assaySamples[0].assay?.name?.replace( ' ', '_' ); 326 } else { 364 327 name = "assays"; 365 328 } 329 366 330 // Export the sequences and quality scores 367 331 response.setHeader "Content-disposition", "attachment; filename=" + name.trim() + ".zip" … … 373 337 } 374 338 } 339 340 /** 341 * Export metadata of selected samples in excel format 342 */ 343 def exportMetaData = { 344 def assaySamples = getAssaySamples( params ); 345 def name 346 347 if( assaySamples == null ) { 348 return 349 } else if( assaySamples*.assay.unique().size() == 1 ) { 350 name = "Assay_" + assaySamples[0].assay?.name?.replace( ' ', '_' ); 351 } else { 352 name = "assays"; 353 } 354 355 // Export the metadata 356 response.setHeader "Content-disposition", "attachment; filename=${name}.xls" 357 try { 358 // The export functionality needs a assaySample-tag list, but it 359 // should be empty when only exporting metadata 360 def tags = []; 361 assaySamples.unique().each { assaySample -> 362 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"] 363 } 364 sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.getOutputStream() ); 365 response.outputStream.flush(); 366 } catch( Exception e ) { 367 log.error( "Exception occurred during export of metadata. Probably the user has cancelled the download." ); 368 } 369 } 370 371 372 /** 373 * Retrieves an assay from the database, based on the assay ID given 374 * @param assayId ID of the assay 375 * @param writeAccess True if you require write access to this assay. The system will check for sufficient privileges 376 * @return 377 */ 378 protected Assay getAssay(def assayId, boolean writeAccess = false ) { 379 // load study with id specified by param.id 380 def assay 381 try { 382 assay = Assay.get(assayId as Long) 383 } catch( Exception e ) { 384 flash.error = "Incorrect id given: " + assayId 385 redirect(action: 'index') 386 return null 387 } 388 389 if (!assay) { 390 flash.error = "No assay found with id: " + assayId 391 redirect(action: 'index') 392 return null 393 } 394 395 if ( !assay.study.canRead( session.user ) || ( writeAccess && !assay.study.canWrite( session.user ) ) ) { 396 flash.error = "You don't have the right authorizaton to access assay " + assay.name 397 redirect(action: 'index') 398 return null 399 } 400 401 return assay 402 } 403 404 405 protected List getAssaySamples( params ) { 406 def tokens = params.list( 'tokens' ); 407 def ids = params.list( 'ids' ); 408 def name; 409 410 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 411 412 if( !tokens && !ids ) { 413 def message = "No assay tokens or ids given" 414 flash.error = message 415 redirect( action: "index" ); 416 return; 417 } 418 419 def assaySamples = []; 420 421 // Determine which assaySamples to export 422 def assay; 423 tokens.each { token -> 424 assay = Assay.findByAssayToken( token ); 425 if( assay && assay.study.canRead( session.user ) ) 426 assaySamples += assay.assaySamples 427 } 428 ids.each { id -> 429 assay = Assay.get( id ); 430 if( assay && assay.study.canRead( session.user ) ) 431 assaySamples += assay.assaySamples 432 } 433 434 return assaySamples; 435 } 436 437 375 438 } -
trunk/grails-app/controllers/nl/tno/metagenomics/FastaController.groovy
r12 r14 69 69 case "run": 70 70 entity = getRun( params.id ); 71 assaySamples = entity.assaySamples ;71 assaySamples = entity.assaySamples.findAll { it.assay.study.canRead( session.user ) }; 72 72 break; 73 73 case "assay": -
trunk/grails-app/controllers/nl/tno/metagenomics/RunController.groovy
r13 r14 35 35 36 36 // Determine runs not used in this assay 37 def otherAssays = Assay.list( sort: "name" ).findAll { !it.runs.contains( run ) }37 def otherAssays = Assay.list( sort: "name" ).findAll { !it.runs.contains( run ) && it.study.canRead( session.user ) } 38 38 39 39 // Send the assay information to the view … … 67 67 68 68 def create = { 69 // Retrieve the assay from the database, but don't exit with an error if no assay is found 69 70 Assay a = getAssay(params.id); 70 71 flash.error = ""; … … 133 134 } 134 135 136 // Check whether the user has sufficient privileges to remove the run from all assays 137 def hasPrivileges = true; 138 run.assay.each { 139 if( !it.study.canWrite( session.user ) ) 140 hasPrivileges = false 141 } 142 143 if( !hasPrivileges ) { 144 flash.message = "Run could not be deleted because you don't have sufficient privileges to remove the run from all assays."; 145 redirect( controller: "assay", action: "show", id: params.assayId ) 146 } 147 135 148 // Remove all associations 136 149 run.assays.each { … … 257 270 def assaySamples = run.assaySamples.findAll { it.assay.study.canWrite( session.user ) } 258 271 272 println "Matchcolumns: " + matchColumns 273 println "Possible fields: " + session.possibleFields 274 println "Assay samples: " + assaySamples.sample.name 275 259 276 def excelData = sampleExcelService.updateTagsByExcel( matchColumns, session.possibleFields, file, assaySamples ); 260 277 278 println excelData 279 261 280 // Return a message to the user 262 281 if( !excelData.success ) { … … 270 289 flash.message += excelData.failedRows.size() + " row(s) could not be imported, because the sample names could not be found in the database or you don't have the proper permissions to change them." 271 290 } 291 292 // Now delete the file, since we don't need it anymore 293 _deleteUploadedFileFromSession() 294 272 295 redirect( action: 'show', id: params.id ) 273 296 } … … 289 312 290 313 if( sampleParams ) { 291 run.assaySamples. each { assaySample ->314 run.assaySamples.findAll { it.assay.study.canWrite( session.user ) }.each { assaySample -> 292 315 def assaySampleParams = sampleParams.get( assaySample.id as String ); 293 316 if( assaySampleParams ) { … … 318 341 319 342 if( !run ) { 320 redirect(controller: ' study')343 redirect(controller: 'run', action: 'index') 321 344 return 322 345 } … … 332 355 try { 333 356 def assaySample = AssaySample.findById( assaySampleId as Long ) 334 if( run.assaySamples == null || !run.assaySamples.contains( assaySample ) ) { 335 run.addToAssaySamples( assaySample ); 336 numAdded++; 357 if( assaySample.assay.study.canWrite( session.user ) ) { 358 if( run.assaySamples == null || !run.assaySamples.contains( assaySample ) ) { 359 run.addToAssaySamples( assaySample ); 360 numAdded++; 361 } 337 362 } 338 363 } catch( Exception e ) {} … … 355 380 356 381 if( !params.assaySampleId ) { 357 flash. message= "No sample id given"382 flash.error = "No sample id given" 358 383 redirect(action: 'show', id: params.id) 359 384 return … … 366 391 } catch( Exception e ) { 367 392 log.error e 368 flash. message= "Incorrect assaysample id given: " + params.assaySampleId393 flash.error = "Incorrect assaysample id given: " + params.assaySampleId 369 394 redirect(action: 'show', id: params.id) 370 395 return 371 396 } 372 397 398 if( !assaySample.assay.study.canWrite( session.user ) ) { 399 flash.error = "You don't have sufficient privileges to remove the specified sample from this run." 400 redirect(action: 'show', id: params.id) 401 return 402 } 403 373 404 if( run.assaySamples.contains( assaySample ) ) { 374 405 run.removeFromAssaySamples( assaySample ); … … 403 434 try { 404 435 def assay = Assay.findById( assay_id as Long ) 405 if( run.assays == null || !run.assays.contains( assay ) ) { 406 run.addToAssays( assay ); 407 numAdded++; 436 if( assay.study.canWrite( session.user ) ) { 437 if( run.assays == null || !run.assays.contains( assay ) ) { 438 run.addToAssays( assay ); 439 numAdded++; 440 } 408 441 } 409 442 } catch( Exception e ) {} … … 442 475 } 443 476 477 if( !assay.study.canWrite( session.user ) ) { 478 flash.error = "You don't have sufficient privileges to remove the specified assay from this run." 479 redirect(action: 'show', id: params.id) 480 return 481 } 482 444 483 if( run.assays.contains( assay ) ) { 445 484 run.removeFromAssays( assay ); … … 456 495 */ 457 496 def exportAsFasta = { 458 def ids = params.list( 'ids' ); 459 460 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 461 462 if( !ids ) { 463 def message = "No run ids given" 464 response.setStatus( 400, message) 465 render message; 497 def assaySamples = getAssaySamples( params ); 498 499 if( assaySamples == null ) 466 500 return; 467 } 468 469 def assaySamples = []; 501 470 502 def name 471 503 472 if( ids.size() == 1 ) 473 name = "Run_" + Run.get( ids[ 0 ] )?.name?.replace( ' ', '_' ); 504 if( assaySamples.size() == 0 ) { 505 flash.error = "No samples found for selected runs"; 506 redirect( action: "list" ); 507 return; 508 } else if( assaySamples*.run.unique().size() == 1 ) 509 name = "Run_" + assaySamples[0].run?.name?.replace( ' ', '_' ); 474 510 else 475 511 name = "runs"; 476 477 // Determine which assaySamples to export478 ids.each { id ->479 def run = Run.get( id );480 if( run )481 assaySamples += run.assaySamples482 }483 512 484 513 // Export the sequences and quality scores … … 491 520 } 492 521 } 493 522 523 /** 524 * Export metadata of selected samples in excel format 525 */ 526 def exportMetaData = { 527 def assaySamples = getAssaySamples( params ); 528 def name 529 530 if( assaySamples == null ) 531 return; 532 533 if( assaySamples.size() == 0 ) { 534 flash.error = "No samples found for selected runs"; 535 redirect( action: "list" ); 536 return; 537 } else if( assaySamples*.run.unique().size() == 1 ) { 538 name = "Run_" + assaySamples[0].run?.name?.replace( ' ', '_' ); 539 } else { 540 name = "runs"; 541 } 542 543 // Export the metadata 544 response.setHeader "Content-disposition", "attachment; filename=${name}.xls" 545 try { 546 // The export functionality needs a assaysSample-tag list, but it 547 // should be empty when only exporting metadata 548 def tags = []; 549 assaySamples.unique().each { assaySample -> 550 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"] 551 } 552 sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.getOutputStream() ); 553 response.outputStream.flush(); 554 } catch( Exception e ) { 555 log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." ); 556 } 557 } 558 559 protected List getAssaySamples( params ) { 560 def ids = params.list( 'ids' ); 561 562 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 563 564 if( !ids ) { 565 def message = "No run ids given" 566 flash.error = message 567 redirect( action: "index" ); 568 return; 569 } 570 571 def assaySamples = []; 572 573 // Determine which assaySamples to export 574 ids.each { id -> 575 def run = Run.get( id ); 576 if( run ) 577 assaySamples += run.assaySamples.findAll { it.assay.study.canRead( session.user ) } 578 } 579 580 return assaySamples; 581 } 494 582 495 583 /** -
trunk/grails-app/controllers/nl/tno/metagenomics/SampleController.groovy
r13 r14 1 1 package nl.tno.metagenomics 2 3 import java.util.List; 2 4 3 5 import org.codehaus.groovy.grails.commons.ConfigurationHolder … … 5 7 class SampleController { 6 8 def fastaService 9 def sampleExcelService 7 10 8 11 def index = { 9 12 redirect( controller: 'study' ); 10 13 } 14 15 /** 16 * Exports data about one or more studies in fasta format 17 */ 18 def exportAsFasta = { 19 def assaySamples = getAssaySamples( params ); 20 def name 21 22 if( assaySamples == null ) { 23 return 24 } else if( assaySamples*.sample.unique().size() == 1 ) { 25 name = "Sample_" + assaySamples[0].sample.name?.replace( ' ', '_' ); 26 } else { 27 name = "samples"; 28 } 29 30 // Export the sequences and quality scores 31 response.setHeader "Content-disposition", "attachment; filename=" + name.trim() + ".zip" 32 try { 33 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 34 response.outputStream.flush(); 35 } catch( Exception e ) { 36 log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." ); 37 } 38 } 39 40 /** 41 * Export metadata of one or more studies in excel format 42 */ 43 def exportMetaData = { 44 def assaySamples = getAssaySamples( params ); 45 def name 46 47 if( assaySamples == null ) { 48 return 49 } else if( assaySamples*.sample.unique().size() == 1 ) { 50 name = "Sample_" + assaySamples[0].sample.name?.replace( ' ', '_' ); 51 } else { 52 name = "samples"; 53 } 54 55 // Export the metadata 56 response.setHeader "Content-disposition", "attachment; filename=${name}.xls" 57 try { 58 // The export functionality needs a assaySample-tag list, but it 59 // should be empty when only exporting metadata 60 def tags = []; 61 assaySamples.unique().each { assaySample -> 62 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"] 63 } 64 sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.getOutputStream() ); 65 response.outputStream.flush(); 66 } catch( Exception e ) { 67 log.error( "Exception occurred during export of metadata. Probably the user has cancelled the download." ); 68 e.printStackTrace(); 69 } 70 } 71 11 72 73 74 12 75 /** 13 * Exports data about one or more samples in fasta format 76 * Parse the given parameters and try to extract assaysamples using ids and tokens of samples 77 * @param params 78 * @return 14 79 */ 15 def exportAsFasta ={80 protected List getAssaySamples( params ) { 16 81 def tokens = params.list( 'tokens' ); 17 82 def ids = params.list( 'ids' ); 18 83 def name; 84 19 85 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 20 86 21 87 if( !tokens && !ids ) { 22 88 def message = "No sample tokens or ids given" 23 response.setStatus( 400, message)24 re nder message;89 flash.error = message 90 redirect( action: "index" ); 25 91 return; 26 92 } 27 93 28 94 def assaySamples = []; 29 def name = "samples"; 30 95 31 96 // Determine which assaySamples to export 97 def sample; 32 98 tokens.each { token -> 33 def sample = Sample.findBySampleToken( token ); 34 if( sample ) 35 assaySamples += sample.assaySamples 99 sample = Sample.findBySampleToken( token ); 100 if( sample.study.canRead( session.user ) ) { 101 if( sample && sample.assaySamples ) 102 assaySamples += sample.assaySamples; 103 } 36 104 } 37 105 ids.each { id -> 38 def sample = Sample.get( id ); 39 if( sample ) 40 assaySamples += sample.assaySamples 106 sample = Sample.get( id ); 107 if( sample.study.canRead( session.user ) ) { 108 if( sample && sample.assaySamples ) 109 assaySamples += sample.assaySamples; 110 } 41 111 } 42 43 // Export the sequences and quality scores 44 response.setHeader "Content-disposition", "attachment; filename=${name}.zip" 45 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 46 response.outputStream.flush(); 112 113 return assaySamples; 47 114 } 115 116 48 117 } -
trunk/grails-app/controllers/nl/tno/metagenomics/StudyController.groovy
r13 r14 1 1 package nl.tno.metagenomics 2 3 import java.util.List; 2 4 3 5 class StudyController { … … 6 8 def fileService 7 9 def trashService 10 def fastaService 11 def sampleExcelService 8 12 9 13 def index = { … … 21 25 } 22 26 23 def exportAsExcel = { 24 render "To be implemented" 27 28 /** 29 * Exports data about one or more studies in fasta format 30 */ 31 def exportAsFasta = { 32 def assaySamples = getAssaySamples( params ); 33 def name 34 35 if( assaySamples == null ) { 36 return 37 } else if( assaySamples*.assay*.study.unique().size() == 1 ) { 38 name = "Study_" + assaySamples[0].assay.study.name?.replace( ' ', '_' ); 39 } else { 40 name = "studies"; 41 } 42 43 // Export the sequences and quality scores 44 response.setHeader "Content-disposition", "attachment; filename=" + name.trim() + ".zip" 45 try { 46 fastaService.export( assaySamples.unique(), response.getOutputStream(), name ); 47 response.outputStream.flush(); 48 } catch( Exception e ) { 49 log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." ); 50 } 51 } 52 53 /** 54 * Export metadata of one or more studies in excel format 55 */ 56 def exportMetaData = { 57 def assaySamples = getAssaySamples( params ); 58 def name 59 60 if( assaySamples == null ) { 61 return 62 } else if( assaySamples*.assay*.study.unique().size() == 1 ) { 63 name = "Study_" + assaySamples[0].assay.study.name?.replace( ' ', '_' ); 64 } else { 65 name = "studies"; 66 } 67 68 // Export the metadata 69 response.setHeader "Content-disposition", "attachment; filename=${name}.xls" 70 try { 71 // The export functionality needs a assaySample-tag list, but it 72 // should be empty when only exporting metadata 73 def tags = []; 74 assaySamples.unique().each { assaySample -> 75 tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"] 76 } 77 sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.getOutputStream() ); 78 response.outputStream.flush(); 79 } catch( Exception e ) { 80 log.error( "Exception occurred during export of metadata. Probably the user has cancelled the download." ); 81 e.printStackTrace(); 82 } 83 } 84 85 /** 86 * Parse the given parameters and try to extract studies using ids and tokens 87 * @param params 88 * @return 89 */ 90 protected List getAssaySamples( params ) { 91 def tokens = params.list( 'tokens' ); 92 def ids = params.list( 'ids' ); 93 def name; 94 95 ids = ids.findAll { it.isLong() }.collect { Long.parseLong( it ) } 96 97 if( !tokens && !ids ) { 98 def message = "No assay tokens or ids given" 99 flash.error = message 100 redirect( action: "index" ); 101 return; 102 } 103 104 def assaySamples = []; 105 106 // Determine which assaySamples to export 107 def study; 108 tokens.each { token -> 109 study = Study.findByStudyToken( token ); 110 if( study && study.canRead( session.user ) ) 111 assaySamples += study.assays*.assaySamples.flatten(); 112 } 113 ids.each { id -> 114 study = Study.get( id ); 115 if( study && study.canRead( session.user ) ) 116 assaySamples += study.assays*.assaySamples.flatten(); 117 } 118 119 return assaySamples; 25 120 } 26 121 -
trunk/grails-app/controllers/nl/tno/metagenomics/integration/RestController.groovy
r13 r14 233 233 log.error "Data was requested for " + entity.toLowerCase() + " " + object.name + " but the user " + session.user.username + " doesn't have the right privileges." 234 234 continue; 235 } else {236 log.error "Data was requested for " + entity.toLowerCase() + " " + object.name + ": " + session.user.username + " - " + study.canRead( session.user )237 235 } 238 236 … … 373 371 switch( entity ) { 374 372 case "Study": 375 actions[ entity ] = [ [ name: "excel", description: "Export as excel", url: createLink( controller: "study", action: "exportAsExcel", absolute: true ) ] ] 373 actions[ entity ] = [ 374 [ name: "excel", description: "Export metadata", url: createLink( controller: "study", action: "exportMetaData", absolute: true ) ], 375 [ name: "fasta", description: "Export as fasta", url: createLink( controller: "study", action: "exportAsFasta", absolute: true ) ] 376 ] 376 377 break; 377 378 case "Assay": 378 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta", url: createLink( controller: "assay", action: "exportAsFasta", absolute: true ) ] ] 379 actions[ entity ] = [ 380 [ name: "fasta", description: "Export as fasta", url: createLink( controller: "assay", action: "exportAsFasta", absolute: true ) ], 381 [ name: "excel", description: "Export metadata", url: createLink( controller: "assay", action: "exportMetaData", absolute: true ) ] 382 ] 379 383 break; 380 384 case "Sample": 381 actions[ entity ] = [ [ name: "fasta", description: "Export as fasta", url: createLink( controller: "sample", action: "exportAsFasta", absolute: true ) ] ] 385 actions[ entity ] = [ 386 [ name: "fasta", description: "Export as fasta", url: createLink( controller: "sample", action: "exportAsFasta", absolute: true ) ], 387 [ name: "excel", description: "Export metadata", url: createLink( controller: "sample", action: "exportMetaData", absolute: true ) ] 388 ] 382 389 break; 383 390 default: -
trunk/grails-app/services/nl/tno/metagenomics/SampleExcelService.groovy
r13 r14 87 87 88 88 headers.eachWithIndex { header, idx -> 89 // Do matching using fuzzy search. The 0. 1treshold makes sure that no match if chosen if89 // Do matching using fuzzy search. The 0.8 treshold makes sure that no match if chosen if 90 90 // there is actually no match at all. 91 bestMatches[idx] = fuzzySearchService.mostSimilar( header, possibleFields, 0.1 ); 91 if( !header || header.toString().trim() == "" ) 92 bestMatches[idx] = null 93 else 94 bestMatches[idx] = fuzzySearchService.mostSimilar( header, possibleFields, 0.8 ); 92 95 } 93 96 … … 119 122 def dataMatches = false; 120 123 possibleFields.each { columnName -> 121 columns[ columnName ] = matchColumns.findIndexOf { it.value == columnName } 124 def foundColumn = matchColumns.find { it.value == columnName }; 125 126 columns[ columnName ] = ( foundColumn && foundColumn.key.toString().isInteger() ) ? Integer.valueOf( foundColumn.key.toString() ) : -1; 122 127 123 128 if( columnName != sampleNameName && columns[ columnName ] != -1 ) … … 125 130 } 126 131 132 println columns 133 127 134 // A column to match the sample name must be present 128 135 if( columns[ sampleNameName ] == -1 ) { 129 // Now delete the file, since we don't need it anymore130 _deleteUploadedFileFromSession()131 132 136 return [ success: false, message: "There must be a column present in the excel file that matches the sample name. Please try again." ] 133 137 } … … 135 139 // A column with data should also be present 136 140 if( !dataMatches ) { 137 // Now delete the file, since we don't need it anymore138 _deleteUploadedFileFromSession()139 140 141 return [ success: false, message: "There are no data columns present in the excel file. No samples are updated." ] 141 142 } … … 166 167 String sampleName = rowData[ columns[ sampleNameName ] ] as String 167 168 169 // If no sample name is found, the row is either empty or contains no sample name 170 if( !sampleName ) { 171 failedRows << [ row: rowData, sampleName: "" ]; 172 continue; 173 } 174 168 175 // Find assay by sample name. Since sample names are unique within an assay (enforced by GSCF), 169 176 // this will always work when only using one assay. When multiple assays are used, this might pose 170 177 // a problem 178 // TODO: Fix problem with multiple assays 171 179 AssaySample assaySample = assaySamples.find { it.sample.id == Sample.findByName( sampleName )?.id }; 180 println "Row: " + i + " - Sample name: " + sampleName + " - " + assaySample 172 181 173 182 // If no assaysample is found, add this row to the failed-row list -
trunk/grails-app/services/nl/tno/metagenomics/integration/GscfService.groovy
r13 r14 24 24 */ 25 25 public String urlAuthRemote( def params, def token ) { 26 def redirectURL = "${config.gscf.baseURL}/login/auth_remote?moduleURL=${this.moduleURL()}&consumer=${this.consumerID()}&token=${token}&returnUrl=${config.grails.serverURL}" 27 26 def redirectURL = "${config.gscf.baseURL}/login/auth_remote?moduleURL=${this.moduleURL()}&consumer=${this.consumerID()}&token=${token}&" 27 28 def returnUrl = config.grails.serverURL 28 29 if (params.controller != null){ 29 re directURL+= "/${params.controller}"30 returnUrl += "/${params.controller}" 30 31 if (params.action != null){ 31 re directURL+= "/${params.action}"32 returnUrl += "/${params.action}" 32 33 if (params.id != null){ 33 re directURL+= "/${params.id}"34 returnUrl += "/${params.id}" 34 35 } 35 36 } 36 37 } 37 38 38 return redirectURL 39 // Append other parameters 40 returnUrl += "?" + params.collect { 41 if( it.key != "controller" && it.key != "action" && it.key != "id" ) 42 return it.key.toString().encodeAsURL() + "=" + it.value.toString().encodeAsURL(); 43 else 44 return "" 45 }.findAll { it }.join( "&" ); 46 47 return redirectURL + "returnUrl=" + returnUrl.encodeAsURL(); 39 48 } 40 49 … … 65 74 * @return Map 66 75 */ 67 public Map getUser(String sessionToken) {76 public Map getUser(String sessionToken) throws Exception { 68 77 def user = [:] 69 this.callGSCF(sessionToken, "getUser").each { 70 user[ it.key ] = it.value; 71 } 72 return user 78 try { 79 this.callGSCF(sessionToken, "getUser").each { 80 user[ it.key ] = it.value; 81 } 82 return user 83 } catch( Exception e ) { 84 throw new Exception( "Retrieving user details from GSCF failed", e ); 85 } 73 86 } 74 87 … … 80 93 * @return ArrayList 81 94 */ 82 public ArrayList getStudies(String sessionToken) {95 public ArrayList getStudies(String sessionToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 83 96 return this.callGSCF(sessionToken, "getStudies") 84 97 } … … 92 105 * @return ArrayList 93 106 */ 94 public ArrayList getStudies(String sessionToken, ArrayList studyTokens ) {107 public ArrayList getStudies(String sessionToken, ArrayList studyTokens ) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 95 108 return this.callGSCF(sessionToken, "getStudies", [ "studyToken": studyTokens ] ); 96 109 } … … 104 117 * @return ArrayList 105 118 */ 106 public def getStudy(String sessionToken, String studyToken) throws NotAuthorizedException, ResourceNotFoundException{119 public def getStudy(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 107 120 def list 108 121 … … 131 144 * @return ArrayList 132 145 */ 133 public ArrayList getAssays(String sessionToken, String studyToken) throws NotAuthorizedException, ResourceNotFoundException{146 public ArrayList getAssays(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 134 147 try { 135 148 return this.callGSCF(sessionToken, "getAssays", ["studyToken": studyToken]) … … 150 163 * @return ArrayList 151 164 */ 152 public def getAssay(String sessionToken, String studyToken, String assayToken ) throws NotAuthorizedException, ResourceNotFoundException{165 public def getAssay(String sessionToken, String studyToken, String assayToken )throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 153 166 def list 154 167 try { … … 178 191 * @return ArrayList 179 192 */ 180 public def getSample(String sessionToken, String assayToken, String sampleToken) throws NotAuthorizedException, ResourceNotFoundException{193 public def getSample(String sessionToken, String assayToken, String sampleToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 181 194 def list 182 195 … … 205 218 * @return ArrayList 206 219 */ 207 public ArrayList getSamples(String sessionToken, String assayToken) throws NotAuthorizedException, ResourceNotFoundException{220 public ArrayList getSamples(String sessionToken, String assayToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 208 221 // Samples of a Study limited to a single Assay 209 222 try { … … 225 238 * @return ArrayList 226 239 */ 227 public def getSamples(String sessionToken, List sampleTokens) throws NotAuthorizedException, ResourceNotFoundException{240 public def getSamples(String sessionToken, List sampleTokens) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 228 241 def list 229 242 … … 249 262 * @return ArrayList 250 263 */ 251 public HashMap getAuthorizationLevel(String sessionToken, String studyToken) throws ResourceNotFoundException{264 public HashMap getAuthorizationLevel(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 252 265 ArrayList list 253 266 -
trunk/grails-app/services/nl/tno/metagenomics/integration/SynchronizationService.groovy
r13 r14 67 67 } 68 68 } 69 70 // Append other parameters 71 returnUrl += "?" + params.collect { 72 if( it.key != "controller" && it.key != "action" && it.key != "id" ) 73 return it.key.toString().encodeAsURL() + "=" + it.value.toString().encodeAsURL(); 74 else 75 return "" 76 }.findAll { it }.join( "&" ); 77 69 78 if( timeForFullSynchronization() ) { 70 79 return ConfigurationHolder.config.grails.serverURL + "/synchronize/full?redirect=" + returnUrl.encodeAsURL() … … 91 100 * @return ArrayList List of studies or null if the synchronization has failed 92 101 */ 93 public ArrayList<Study> synchronizeStudies() throws NotAuthenticatedException, Exception {102 public ArrayList<Study> synchronizeStudies() throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception { 94 103 if( !performSynchronization() ) 95 104 return Study.findAllWhereTrashcan(false) … … 140 149 // synchronizing and return null 141 150 log.error( "Exception occurred when fetching studies: " + e.getMessage() ) 142 throw new Exception( "Error while fetching studies", e)151 throw e 143 152 } 144 153 -
trunk/grails-app/views/assay/index.gsp
r13 r14 17 17 <thead> 18 18 <tr> 19 <th class="nonsortable">< /th>19 <th class="nonsortable"><input type="checkbox" id="checkAll" onClick="checkAllPaginated(this);" /></th> 20 20 <th>Assay</th> 21 21 <th>Study</th> … … 29 29 <g:each in="${study.assays}" var="assay"> 30 30 <tr> 31 <td><g:checkBox name="ids" value="${assay.id}" checked="${false}" /></td>31 <td><g:checkBox name="ids" value="${assay.id}" checked="${false}" onClick="updateCheckAll(this);" /></td> 32 32 33 33 <td><g:link controller="assay" action="show" id="${assay.id}">${assay.name}</g:link></td> … … 50 50 <p class="options"> 51 51 <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#assayForm' ), '<g:createLink action="exportAsFasta" />', '#assays', 'Please select an assay to export' ); return false;">Export as fasta</a> 52 <a class="excel" href="#" onClick="submitPaginatedForm( $( '#assayForm' ), '<g:createLink action="exportMetaData" />', '#assays', 'Please select an assay to export' ); return false;">Export metadata</a> 52 53 </p> 53 54 -
trunk/grails-app/views/common/_topnav.gsp
r9 r14 1 1 <!-- TOPNAV //--> 2 2 <ul class="topnav"> 3 <li><g:link controller=" study">Home</g:link></li>3 <li><g:link controller="run">Home</g:link></li> 4 4 <li> 5 5 <a href="#" onClick="return false;">View</a> … … 7 7 <li><g:link controller="run">Runs</g:link></li> 8 8 <li><g:link controller="assay">Assays</g:link></li> 9 <li><g:link controller="study">Studies</g:link></li> 9 10 </ul> 10 11 </li> -
trunk/grails-app/views/layouts/main.gsp
r13 r14 37 37 <div id="content"> 38 38 <g:if test="${lastSynchronized}"> 39 < p>Last full synchronization: ${lastSynchronized}</p>39 <!-- Last full synchronization: ${lastSynchronized} --> 40 40 </g:if> 41 41 <g:if test="${flash.error}"> -
trunk/grails-app/views/run/index.gsp
r13 r14 30 30 <thead> 31 31 <tr> 32 <th class="nonsortable">< /th>32 <th class="nonsortable"><input type="checkbox" id="checkAll" onClick="checkAllPaginated(this);" /></th> 33 33 <th>Run</th> 34 34 <th># samples</th> … … 39 39 <g:each in="${runs}" var="run"> 40 40 <tr> 41 <td><g:checkBox name="ids" value="${run.id}" checked="${false}" /></td>41 <td><g:checkBox name="ids" value="${run.id}" checked="${false}" onClick="updateCheckAll(this);" /></td> 42 42 <td><g:link controller="run" action="show" id="${run.id}">${run.name}</g:link></td> 43 43 <td>${run.assaySamples?.size()}</td> … … 50 50 <a class="add" href="#" onClick="showAddRunDialog(); return false;">Add run</a> 51 51 <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#runForm' ), '<g:createLink action="exportAsFasta" />', '#runs', 'Please select a run to export' ); return false;">Export as fasta</a> 52 <a class="excel" href="#" onClick="submitPaginatedForm( $( '#runForm' ), '<g:createLink action="exportMetaData" />', '#runs', 'Please select a run to export' ); return false;">Export metadata</a> 52 53 </p> 53 54 </g:else> -
trunk/grails-app/views/study/index.gsp
r7 r14 12 12 </g:if> 13 13 <g:else> 14 <table class="paginate"> 14 <form id="assayForm"> 15 </form> 16 17 <table id="studies" class="paginate"> 15 18 <thead> 16 19 <tr> 17 20 <th class="nonsortable"><input type="checkbox" id="checkAll" onClick="checkAllPaginated(this);" /></th> 21 <th>Study</th> 18 22 <th>Assay</th> 19 <th>Study</th>20 23 <th># samples</th> 21 24 </tr> … … 34 37 <g:each in="${study.assays}" var="assay"> 35 38 <tr> 39 <td><g:checkBox name="ids" value="${assay.id}" checked="${false}" onClick="updateCheckAll(this);" /></td> 40 <td><a href="${study.viewUrl()}">${study.name}</a></td> 36 41 <td><g:link controller="assay" action="show" id="${assay.id}">${assay.name}</g:link></td> 37 <td><a href="${study.viewUrl()}">${study.name}</a></td>38 42 <td>${assay.assaySamples?.size()}</td> 39 43 </tr> … … 43 47 </tbody> 44 48 </table> 49 <p class="options"> 50 <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#assayForm' ), '<g:createLink controller="assay" action="exportAsFasta" />', '#studies', 'Please select one or more studies to export' ); return false;">Export as fasta</a> 51 <a class="excel" href="#" onClick="submitPaginatedForm( $( '#assayForm' ), '<g:createLink controller="assay" action="exportMetaData" />', '#studies', 'Please select one or more studies to export' ); return false;">Export metadata</a> 52 </p> 45 53 </g:else> 46 54 </body> -
trunk/web-app/css/buttons.css
r13 r14 6 6 padding-bottom: 2px; 7 7 line-height: 20px; 8 padding-left: 28px; 8 padding-left: 26px; 9 10 background-image: transparent; 11 background-repeat: no-repeat; 12 background-position: 3px 50%; 9 13 } 10 14 … … 12 16 13 17 .options a.fasta { 14 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/brick_go.png) 5px 50% no-repeat;18 background-image: url(../plugins/famfamfam-1.0.1/images/icons/brick_go.png); 15 19 } 16 20 .options a.excel { … … 18 22 } 19 23 .options a.edit { 20 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/pencil.png) 5px 50% no-repeat;24 background-image: url(../plugins/famfamfam-1.0.1/images/icons/pencil.png); 21 25 } 22 26 .options a.add { 23 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/add.png) 5px 50% no-repeat;27 background-image: url(../plugins/famfamfam-1.0.1/images/icons/add.png); 24 28 } 25 29 .options a.addSequences { 26 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/page_attach.png) 5px 50% no-repeat;30 background-image: url(../plugins/famfamfam-1.0.1/images/icons/page_attach.png); 27 31 } 28 32 29 33 .options a.addAssociation { 30 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/application_add.png) 5px 50% no-repeat;34 background-image: url(../plugins/famfamfam-1.0.1/images/icons/application_add.png); 31 35 } 32 36 .options a.editAssociation { 33 background : transparent url(../plugins/famfamfam-1.0.1/images/icons/application_edit.png) 5px 50% no-repeat;37 background-image: url(../plugins/famfamfam-1.0.1/images/icons/application_edit.png); 34 38 } -
trunk/web-app/css/datatables/demo_table_jui.css
r11 r14 78 78 .dataTables_wrapper { font-size: 10px; } 79 79 80 /* Check all checkbox */ 81 input.transparent { 82 -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; 83 filter: alpha(opacity=30); 84 opacity: 0.3; 85 -moz-opacity: 0.3; 86 -khtml-opacity: 0.3; 87 } 88 80 89 /* 81 90 * Sort arrow icon positioning -
trunk/web-app/js/paginate.js
r4 r14 49 49 } 50 50 }); 51 } 52 53 function checkAllPaginated( input ) { 54 var paginatedTable = $(input).closest( '.paginate' ); 55 var dataTable = paginatedTable.closest( '.dataTables_wrapper' ); 56 var checkAll = $( '#checkAll', paginatedTable ); 51 57 58 var oTable = paginatedTable.dataTable(); 59 var inputs = $('input', oTable.fnGetNodes()) 60 61 // If any of the inputs is checked, uncheck all. Otherwise, check all 62 var check = false; 63 64 for(var i = 0; i < inputs.length; i++ ) { 65 if( !$(inputs[i]).attr( 'checked' ) ) { 66 check = true; 67 break; 68 } 69 } 70 71 inputs.each( function( idx, el ) { 72 $(el).attr( 'checked', check ); 73 }) 74 75 updateCheckAll( checkAll ); 76 } 77 78 function updateCheckAll( input ) { 79 var paginatedTable = $(input).closest( '.paginate' ); 80 var dataTable = paginatedTable.closest( '.dataTables_wrapper' ); 81 82 var checkAll = $( '#checkAll', paginatedTable ); 83 84 var oTable = paginatedTable.dataTable(); 85 var inputs = $('input', oTable.fnGetNodes()) 86 87 // Is none checked, are all checked or are some checked 88 var numChecked = 0 89 for(var i = 0; i < inputs.length; i++ ) { 90 if( $(inputs[i]).attr( 'checked' ) ) { 91 numChecked++; 92 } 93 } 94 95 checkAll.attr( 'checked', numChecked > 0 ); 96 97 if( numChecked > 0 && numChecked < inputs.length - 1 ) { 98 checkAll.addClass( 'transparent' ); 99 } else { 100 checkAll.removeClass( 'transparent' ); 101 } 52 102 } 53 103
Note: See TracChangeset
for help on using the changeset viewer.