Changeset 635


Ignore:
Timestamp:
Jul 26, 2010, 1:33:50 PM (14 years ago)
Author:
gav
Message:

Add feature to import inventory item pictures from zip file.

Location:
trunk/grails-app
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/conf/Config.groovy

    r633 r635  
    6464globalDirs.logDirectory = globalDirs.catalinaBase ? "${globalDirs.catalinaBase}${fs}logs${fs}" : globalDirs.targetDir
    6565globalDirs.workDirectory = globalDirs.catalinaBase ? "${globalDirs.catalinaBase}${fs}work${fs}" : globalDirs.targetDir
     66globalDirs.tempDirectory = globalDirs.catalinaBase ? "${globalDirs.catalinaBase}${fs}temp${fs}${appName}${fs}" : globalDirs.targetDir
    6667globalDirs.searchableIndexDirectory = "${globalDirs.workDirectory}SearchableIndex${fs}${appName}${fs}"
     68globalDirs.tempInventoryItemPicturesDirectory = "${globalDirs.tempDirectory}InventoryItemPictures${fs}"
    6769
    6870/**
  • trunk/grails-app/controllers/InventoryItemDetailedController.groovy

    r634 r635  
    3434        }
    3535        forward(action: 'search', params: params)
     36    }
     37
     38    /**
     39    * Display the import view.
     40    */
     41    def importInventoryItemPictures = {
     42    }
     43
     44    /**
     45    * Handle the import save.
     46    */
     47    def importInventoryItemPicturesSave = {
     48        def result = inventoryItemService.importInventoryItemPictures(request)
     49
     50        if(!result.error) {
     51            def logFileLink = g.link(controller: "appCore", action: "appLog") {"log"}
     52            flash.message = g.message(code: "inventoryItemPictures.import.success", args: [logFileLink])
     53            redirect(action:search)
     54            return
     55        }
     56
     57        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
     58        redirect(action: importInventoryItemPictures)
    3659    }
    3760
  • trunk/grails-app/i18n/messages.properties

    r633 r635  
    1111inventory.import.success=Inventory imported.
    1212inventory.import.failure=Could not create inventory from supplied file, failed on line {0}, see {1}.
     13
     14inventoryItemPictures.import.success=Inventory item pictures imported, see {0}.
     15inventoryItemPictures.import.failure.no.directory=Import directory on server not found.
     16inventoryItemPictures.import.failure.to.unzip=Failed to unzip supplied file.
    1317
    1418inventoryItemPurchase.import.success=Inventory item purchases imported.
  • trunk/grails-app/services/InventoryItemService.groovy

    r549 r635  
     1import org.codehaus.groovy.grails.commons.ConfigurationHolder
     2
    13/**
    24* Provides a service class for the InventoryItem domain class.
     
    228230    /**
    229231    * Save an inventory item picture.
     232    * @param params An object or map containing at least the inventoryItem ID.
    230233    * @param pictureSource A supported source to get the picture image from.
    231234    * Supported sources:
    232235    * HttpServletRequest e.g: 'request' var from controller to run getFile('file') against.
    233236    * ServletContextResource e.g: grailsApplication.mainContext.getResource('images/logo.png')
     237    * File e.g: new File('picture.jpg')
    234238    */
    235239    def savePicture(params, pictureSource) {
     
    294298                pictureInputStream = pictureSource.inputStream
    295299            }
     300            else if(pictureSource instanceof File) {
     301                pictureFile = pictureSource
     302                pictureFileName = pictureFile.name
     303
     304                if ( !pictureFile.isFile() || (pictureFile.length() == 0) )
     305                    return fail(code:"default.file.not.supplied")
     306
     307                if (pictureFile.length() > Image.MAX_SIZE)
     308                    return fail(code:"default.file.over.max.size", args: [Image.MAX_SIZE/kByteMultiplier, "kB"])
     309
     310                pictureInputStream = new FileInputStream(pictureSource)
     311            }
    296312            else {
    297313                    return fail(code:"inventory.item.picture.source.not.supported")
     
    329345            return result
    330346
    331         } //end withTransaction
    332     }
     347        } // end withTransaction
     348    } // savePicture
     349
     350    /**
     351    * Import inventory pictures from an uploaded zip file.
     352    * @param request The http request to run getFile against.
     353    * Get file should return a zip format file containing the inventory item pictures.
     354    */
     355    def importInventoryItemPictures(request) {
     356            def result = [:]
     357
     358            def kByteMultiplier = 1000
     359            def mByteMultiplier = 1000 * kByteMultiplier
     360            def fileMaxSize = 500 * mByteMultiplier
     361
     362            def fail = { Map m ->
     363                result.error = [ code: m.code, args: m.args ]
     364                return result
     365            }
     366
     367            // Get file from request.
     368            def multiPartFile = request.getFile('file')
     369            def zipFileName = multiPartFile.originalFilename
     370
     371            if(!multiPartFile || multiPartFile.isEmpty())
     372                return fail(code: "default.file.not.supplied")
     373
     374            if (multiPartFile.getSize() > fileMaxSize)
     375                return fail(code: "default.file.over.max.size", args: [fileMaxSize/mByteMultiplier, "MB"])
     376
     377            // Check create import dir.
     378            def dir = new File(ConfigurationHolder.config.globalDirs.tempInventoryItemPicturesDirectory)
     379            def imageFiles = []
     380
     381            if(!dir.exists())
     382                dir.mkdirs()
     383
     384            if(!dir.isDirectory()) {
     385                return fail(code:'inventoryItemPictures.import.failure.no.directory')
     386            }
     387
     388            // Write zip file to disk.
     389            def zipOutputFile = new File(dir.absolutePath + File.separator + zipFileName)
     390            multiPartFile.transferTo(zipOutputFile)
     391
     392            // Use ant to unzip.
     393            def ant = new AntBuilder()
     394            try {
     395                ant.unzip(  src: zipOutputFile.absolutePath,
     396                                    dest: dir.absolutePath,
     397                                    overwrite:"true" )
     398            }
     399            catch(e) {
     400                log.error e
     401                return fail(code:'inventoryItemPictures.import.failure.to.unzip')
     402            }
     403
     404            // Recurse through dir building list of imageFiles.
     405            def imageFilePattern = ~/[^\s].+(\.(?i)(jpg|png|gif|bmp))$/
     406
     407            dir.eachFileMatch(imageFilePattern) {
     408                imageFiles << it
     409            }
     410
     411            dir.eachDirRecurse { subDir ->
     412                subDir.eachFileMatch(imageFilePattern) {
     413                    imageFiles << it
     414                }
     415            }
     416
     417            // Find inventoryItems by name of picture and call savePicture.
     418            def inventoryItemInstance
     419            def itemName
     420            def savePictureResult
     421
     422            for(imageFile in imageFiles) {
     423                itemName = imageFile.name[0..-5]
     424                inventoryItemInstance = InventoryItem.findByName(itemName)
     425                if(!inventoryItemInstance) {
     426                    log.warn 'InventoryItem not found with name: ' + itemName
     427                    continue
     428                }
     429                if(inventoryItemInstance.picture) {
     430                    log.warn 'InventoryItem already has picture: ' + itemName
     431                    continue
     432                }
     433                savePictureResult = savePicture(inventoryItemInstance, imageFile)
     434                if(savePictureResult.error)
     435                    log.error savePictureResult.error
     436                else
     437                    log.info 'InventoryItem picture saved: ' + itemName
     438            }
     439
     440            // Success.
     441            return result
     442
     443    } // importInventoryItemPictures
    333444
    334445} // end class
  • trunk/grails-app/views/inventoryItemDetailed/search.gsp

    r629 r635  
    147147                                            Import Purchases
    148148                                        </g:link>
     149                                        /
     150                                        <g:link action="importInventoryItemPictures">
     151                                            Import Pictures
     152                                        </g:link>
    149153                                    </td>
    150154                                </tr>
Note: See TracChangeset for help on using the changeset viewer.