简体   繁体   中英

Updating multiples files with Vapor properly

I'm working on a project with vapor and I'm trying to make a function who edit an item with multiples pictures and I don't know how to make it properly for making update the pictures.

Currently, my func is really really lengthy (200 lines:o and I want to add others pictures) and I didn't how to do more properly.

Thanks you for any help:)

''''

func editItemPostHandler(_ req: Request) throws
-> EventLoopFuture<Response> {
    
    
    let updateData =
    try req.content.decode(CreateItemFormData.self)
    
    return Item
        .find(req.parameters.get("itemID"), on: req.db)
        .unwrap(or: Abort(.notFound)).flatMap { item in
            // 3
            item.title = updateData.title
            item.price = updateData.price
            item.description = updateData.description
            item.condition = updateData.condition
            item.weight = updateData.weight
            
            item.$category.id = updateData.categoryID
            item.$size.id = updateData.sizeID
            item.$genderCollection.id = updateData.collectionGenderID
            item.$brand.id = updateData.brandID
            
            if !updateData.picture.isEmpty && !updateData.frontPicture.isEmpty {
                
                let imageName = "\(UUID()).jpg"
                let NewPath =
                req.application.directory.workingDirectory +
                imageFolder + imageName
                
                let frontPictureImageName = "\(UUID()).jpg"
                let frontPictureNewPath =
                req.application.directory.workingDirectory +
                imageFolder + frontPictureImageName
                
                return req.fileio
                    .writeFile(.init(data: updateData.picture), at: NewPath)
                    .flatMap {
                        
                        return req.fileio
                            .writeFile(.init(data: updateData.frontPicture), at: frontPictureNewPath)
                            .flatMap {
                                
                                
                                return Item
                                    .find(req.parameters.get("itemID"), on: req.db)
                                    .unwrap(or: Abort(.notFound)).flatMapThrowing
                                { item in
                                    
                                    
                                    let filename = item.pictures
                                    // 3 3. Construct the path of the picture.
                                    let oldPicturePath = req.application.directory
                                        .workingDirectory + imageFolder + filename
                                    
                                    
                                    let frontPicturefilename = item.frontPicture
                                    // 3 3. Construct the path of the picture.
                                    let oldFrontPicturePath = req.application.directory
                                        .workingDirectory + imageFolder + frontPicturefilename
                                    
                                    
                                    do {
                                        try FileManager.default.removeItem(atPath: oldPicturePath)
                                        try FileManager.default.removeItem(atPath: oldFrontPicturePath)
                                        
                                    }
                                    
                                    item.pictures = imageName
                                    item.frontPicture = frontPictureImageName
                                    
                                    return item
                                }
                                .flatMap {
                                    
                                    (item: Item) -> EventLoopFuture<Response> in
                                    
                                    guard let id = item.id else {
                                        let error = Abort(.internalServerError)
                                        return req.eventLoop.future(error: error)
                                    }
                                    
                                    
                                    // 5
                                    let redirect = req.redirect(to: "/items/\(id)")
                                    return item.save(on: req.db).transform(to: redirect)
                                }
                            }
                    }
            }
            
            else if !updateData.picture.isEmpty {
                
                let imageName = "\(UUID()).jpg"
                let NewPath =
                req.application.directory.workingDirectory +
                imageFolder + imageName
                
                return req.fileio
                    .writeFile(.init(data: updateData.picture), at: NewPath)
                    .flatMap {
                        
                        
                        return Item
                            .find(req.parameters.get("itemID"), on: req.db)
                            .unwrap(or: Abort(.notFound)).flatMapThrowing
                        { item in
                            
                            
                            let filename = item.pictures

                            let oldPicturePath = req.application.directory
                                .workingDirectory + imageFolder + filename
                            
                            do {
                                try FileManager.default.removeItem(atPath: oldPicturePath)
                            }
                            
                            item.pictures = imageName
                            
                            return item
                        }
                        .flatMap {
                            
                            (item: Item) -> EventLoopFuture<Response> in
                            
                            guard let id = item.id else {
                                let error = Abort(.internalServerError)
                                return req.eventLoop.future(error: error)
                            }
                            
                            
                            // 5
                            let redirect = req.redirect(to: "/items/\(id)")
                            return item.save(on: req.db).transform(to: redirect)
                        }
                    }
                
                
                
            }
            
            else if !updateData.frontPicture.isEmpty {
                
                let frontPictureImageName = "\(UUID()).jpg"
                let frontPictureNewPath =
                req.application.directory.workingDirectory +
                imageFolder + frontPictureImageName
                
                return req.fileio
                    .writeFile(.init(data: updateData.frontPicture), at: frontPictureNewPath)
                    .flatMap {
                        
                        
                        return Item
                            .find(req.parameters.get("itemID"), on: req.db)
                            .unwrap(or: Abort(.notFound)).flatMapThrowing
                        { item in
                            
                            
                            let frontPicturefilename = item.frontPicture
                            // 3 3. Construct the path of the picture.
                            let oldFrontPicturePath = req.application.directory
                                .workingDirectory + imageFolder + frontPicturefilename
                            
                            do {
                                try FileManager.default.removeItem(atPath: oldFrontPicturePath)
                            }
                            
                            item.frontPicture = frontPictureImageName
                            
                            return item
                        }
                        .flatMap {
                            
                            (item: Item) -> EventLoopFuture<Response> in
                            
                            guard let id = item.id else {
                                let error = Abort(.internalServerError)
                                return req.eventLoop.future(error: error)
                            }
                            
                            
                            let redirect = req.redirect(to: "/items/\(id)")
                            return item.save(on: req.db).transform(to: redirect)
                        }
                    }
            }
            
            else {
                
                guard let id = item.id else {
                    let error = Abort(.internalServerError)
                    return req.eventLoop.future(error: error)
                }

                let redirect = req.redirect(to: "/items/\(id)")
                return item.save(on: req.db).transform(to: redirect)
            }
        }
}

'''

Thanks you for your help.

Emmanuel

Update,

I found a tricky strategy but it's allow me to have a less longer code:

When I edit an item, firstly I give the name of the former image path to the new image path. If there is a new image (so the data of the image is not empty) I'll change the name of this path. After that, I'll try to push the data with fileIO.writeFile. If there is not data, nothing is write and the path of the image stay the same. If there is data, it will write the data, and after it will delete the old picture with: try FileManager.default.removeItem(atPath: oldPicturePath)

'''

 func editItemPostHandler(_ req: Request) throws
-> EventLoopFuture<Response> {
    
    
    let updateData =
    try req.content.decode(CreateItemFormData.self)
    
    return Item
        .find(req.parameters.get("itemID"), on: req.db)
        .unwrap(or: Abort(.notFound)).flatMap { item in

            item.title = updateData.title
            item.price = updateData.price
            item.description = updateData.description
            item.condition = updateData.condition
            item.weight = updateData.weight
            
            item.$category.id = updateData.categoryID
            item.$size.id = updateData.sizeID
            item.$genderCollection.id = updateData.collectionGenderID
            item.$brand.id = updateData.brandID
            
                
            // 1. give the former name of itemPicture to imageName

                var imageName = item.pictures

            // 2. if updateData.picture isn't empty, give a new name the image name       
                if !updateData.picture.isEmpty {
                imageName = "\(UUID()).jpg"
                }

            // create a path with the name of the image 
                let NewPath =
                req.application.directory.workingDirectory +
                imageFolder + imageName
                
                 // same logic for the second picture                    
                var frontPictureImageName = item.frontPicture
                    
                if !updateData.frontPicture.isEmpty {
                frontPictureImageName = "\(UUID()).jpg"
                }
                
                let frontPictureNewPath =
                req.application.directory.workingDirectory +
                imageFolder + frontPictureImageName
                // try to write the file with the data (if it's empty, nothing is write but the logic continue. 
                return req.fileio
                    .writeFile(.init(data: updateData.picture), at: NewPath)
                    .flatMap {
                // same for the second picture 
                        return req.fileio
                            .writeFile(.init(data: updateData.frontPicture), at: frontPictureNewPath)
                            .flatMap {
                                
                                
                                return Item
                                    .find(req.parameters.get("itemID"), on: req.db)
                                    .unwrap(or: Abort(.notFound)).flatMapThrowing
                                { item in
                                    
                                    
                                    let filename = item.pictures
                     // Construct the path with the old picture name.
                                    let oldPicturePath = req.application.directory
                                        .workingDirectory + imageFolder + filename
                                    
                                    
                                    let frontPicturefilename = item.frontPicture
                                    // 3 3. Construct the path of the picture.
                                    let oldFrontPicturePath = req.application.directory
                                        .workingDirectory + imageFolder + frontPicturefilename
                                    
                                    
                                    do {
                     // if the data isn't empty delete the former picture file 

                                        if !updateData.picture.isEmpty {

                                        try FileManager.default.removeItem(atPath: oldPicturePath)
                                        }
                     // same for the second picture
                                        if !updateData.frontPicture.isEmpty {

                                            try FileManager.default.removeItem(atPath: oldFrontPicturePath)
                                        }

                                        
                                    }
                                    
                                    item.pictures = imageName
                                    item.frontPicture = frontPictureImageName
                                    
                                    return item
                                }
                                .flatMap {
                                    
                                    (item: Item) -> EventLoopFuture<Response> in
                                    
                                    guard let id = item.id else {
                                        let error = Abort(.internalServerError)
                                        return req.eventLoop.future(error: error)
                                    }
                                    
                                    
                                    // save the new item
                                    let redirect = req.redirect(to: "/items/\(id)")
                                    return item.save(on: req.db).transform(to: redirect)
                                }
                            }
                    }
            }
}

'''

It's tricky but it allow to have less code than before and be able to add more picture to my item struct

Here's my item struct:

'''

 struct CreateItemFormData: Content {

let collectionGenderID: UUID
let categoryID: UUID
let sizeID : UUID
let brandID : UUID
let title: String
let price: String
let description: String
let condition: String
let weight: String
var picture: Data
var frontPicture: Data

 }

'''

Thanks you, and if you have better solution, it's always welcome. :)

Have a good day, Emmanuel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM