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.数据库入库结果
安装包入库结果
包信息入库结果