vapor 实践

vapor 安装包上传入库

2018-10-08  本文已影响15人  搞好关系

以用户的邮箱作为依据上传安装包,并使用task对安装包进行解压然后抽取信息
1 先上上传文件代码然后分析

 public func upload( req: Request) -> EventLoopFuture<String>{
  
        do{
          return try req.content.decode(Upload.self).flatMap { (u) -> EventLoopFuture<String> in
            let upload: Upload = u
            //            let upload: Upload = try req.query.decode(Upload.self)
            
            return SKUser.query(on: req).filter(\.email
                , .equal
                , upload.email).first().flatMap({ (skUser) -> EventLoopFuture<String> in
                    
                    if let skUser = skUser {

                        let path =  try! req.sharedContainer.make(DirectoryConfig.self).workDir + "Public/"
                        let userFolder = u.email
                        do{
                            let fileManager = FileManager.default
                            if !fileManager.fileExists(atPath: path+userFolder) {
                                try fileManager.createDirectory(atPath: path+userFolder
                                    , withIntermediateDirectories: true
                                    , attributes: [:])
                            }
                            let userFileRelativePath = userFolder + "/\(Date().timeIntervalSince1970)" +  u.kind.type
                            let  filePath = path + userFileRelativePath
                            
                            try upload.file.write(to: URL(fileURLWithPath: filePath))
                            return  try ipaTool(req: req, ipaPath: filePath).flatMap({ (info) -> EventLoopFuture<String> in
                                let identifer =  (info["info"] as! Dictionary<String, Any>)["CFBundleIdentifier"] as! String
                             return   SKPackage.query(on: req).filter(\.identifer, .equal, identifer).first().flatMap({ (package) -> EventLoopFuture<String> in
                                    if let package = package {
                                        //存在package 则installpackage直接入库
                                        let relaticePath = userFileRelativePath
                                        let skInstallpackage: SKInstallPackage =  SKInstallPackage.init(id: nil, userId: skUser.id!, packageId: package.id!, addDate: Date().timeIntervalSince1970, relativePath: relaticePath)
                                        
                                        return  skInstallpackage.create(on: req).flatMap({ (innInstallPackage) -> EventLoopFuture<String> in
                                            let result = req.eventLoop.newPromise(String.self)
                                            
                                            result.succeed(result:  "\(innInstallPackage.owner) \(innInstallPackage.package.child.owner) \(innInstallPackage)" )
                                            return result.futureResult
                                        })
                                        
                                    }else{//不存在 则先package信息入库,然后installpackage入库
                                       return SKPackage(userId: skUser.id!, identifer: identifer, type: upload.kind).create(on: req).flatMap({ (p) -> EventLoopFuture<String> in
                                            
                                        let skInstallpackage: SKInstallPackage =  SKInstallPackage.init(id: nil, userId: skUser.id!, packageId: p.id!, addDate: Date().timeIntervalSince1970, relativePath: path)
                                      return  skInstallpackage.create(on: req).flatMap({ (sInstallPackage) -> EventLoopFuture<String> in
                                        let result = req.eventLoop.newPromise(String.self)
                                        
                                            result.succeed(result:  "\(skInstallpackage.owner) \(skInstallpackage.package)")
                                        return result.futureResult
                                        })
                                        })
                                        
                                    }
                                })
                                //文件解析信息
//                                print(info)
//                                result.succeed(result: "\(info)")
//                                return result.futureResult
                            })
                        } catch{
                            let result = req.eventLoop.newPromise(String.self)

                            result.fail(error: error)
                        }
                        
                    }else{
                        let result = req.eventLoop.newPromise(String.self)
                        result.succeed(result: "用户" + upload.email + "不存在")
                        return result.futureResult
                    }
                    let result = req.eventLoop.newPromise(String.self)
                    result.succeed(result: "这里是不走的地方")
return result.futureResult
                    
                })
            }
        }catch{
                    let result = req.eventLoop.newPromise(String.self)
                    result.fail(error: error)
                    return result.futureResult
        }
    }

2.大致流程分析
.检测用户是否存在
.接受上传文件并存储本地
.调用shell解压安装包并分析安装Info.plist
.包信息入库 安装资源包信息入库
3.使用task调用shell分析

public func ipaTool(req: Request, ipaPath path: String)throws -> EventLoopFuture<Dictionary<String, Any>>{
    //let path =  try req.sharedContainer.make(DirectoryConfig.self).workDir + "Public/s1538917708.271797.ipa"
    let currentTempDirFolder = NSTemporaryDirectory().appending(UUID.init().uuidString)
    
    
    let result = req.eventLoop.newPromise(Dictionary<String, Any>.self)
    
    let process: Process = Process.launchedProcess(launchPath: "/usr/bin/unzip"
        , arguments: ["-u", "-j", "-d", currentTempDirFolder, path, "Payload/*.app/embedded.mobileprovision", "Payload/*.app/Info.plist","*","-x", "*/*/*/*"])
    
    
    process.terminationHandler = {p in
        let status = p.terminationStatus
        
        if status == 0 {
            
            var provisionPath: String  = "\(currentTempDirFolder)".appending("/embedded.mobileprovision")
            
            let plistPath: String = "\(currentTempDirFolder)".appending("/Info.plist")
            do{
                let appPlist = try! Data.init(contentsOf: URL(fileURLWithPath: plistPath))
                let  appPropertyList: Dictionary<String,Any> = try PropertyListSerialization.propertyList(from: appPlist
                    , options: PropertyListSerialization.ReadOptions.mutableContainers
                    , format: nil) as! Dictionary
                
                let bundleExecutable = appPropertyList["CFBundleExecutable"] as! String
                
                let binaryPath = "\(currentTempDirFolder)/\(bundleExecutable)"
                if process.terminationReason == .exit{
                    print("结束🔚")
                }
                
                result.succeed(result: ["path":"\(currentTempDirFolder)".appending(bundleExecutable)+"\(appPropertyList)", "info": appPropertyList])
                
            }catch{
                result.fail(error: error)
            }
            
            
            //        result.succeed(result: "process succeeded\(currentTempDirFolder)")
            //        print("Task succeeded.\(currentTempDirFolder)")
        } else {
            result.succeed(result: [:])
            print("Task failed.")
        }
        
    }
    
    return result.futureResult
}

4.数据库入库结果


安装包入库结果
包信息入库结果
上一篇下一篇

猜你喜欢

热点阅读