mas/mas-cli/AppStore/PurchaseDownloadObserver.swift

109 lines
2.8 KiB
Swift
Raw Normal View History

//
2015-08-24 18:45:54 +00:00
// PurchaseDownloadObserver.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
2015-08-21 18:01:56 +00:00
let csi = "\u{001B}["
2015-09-14 08:51:09 +00:00
@objc class PurchaseDownloadObserver: NSObject, CKDownloadQueueObserver {
2015-08-24 18:45:54 +00:00
let purchase: SSPurchase
var completionHandler: (() -> ())?
var errorHandler: ((MASError) -> ())?
2015-08-21 18:01:56 +00:00
2015-08-24 18:45:54 +00:00
init(purchase: SSPurchase) {
self.purchase = purchase
}
func downloadQueue(queue: CKDownloadQueue, statusChangedForDownload download: SSDownload!) {
if download.metadata.itemIdentifier != purchase.itemIdentifier {
2015-08-21 18:01:56 +00:00
return
}
let status = download.status
if status.failed || status.cancelled {
queue.removeDownloadWithItemIdentifier(download.metadata.itemIdentifier)
}
else {
progress(status.progressState)
}
}
func downloadQueue(queue: CKDownloadQueue, changedWithAddition download: SSDownload!) {
2015-09-14 08:51:09 +00:00
print("==> Downloading " + download.metadata.title)
}
func downloadQueue(queue: CKDownloadQueue, changedWithRemoval download: SSDownload!) {
clearLine()
let status = download.status
if status.failed {
2015-09-14 08:51:09 +00:00
print("==> Download Failed")
errorHandler?(MASError(code: .DownloadFailed, sourceError: status.error))
}
else if status.cancelled {
2015-09-14 08:51:09 +00:00
print("==> Download Cancelled")
errorHandler?(MASError(code: .Cancelled))
}
else {
2015-09-14 08:51:09 +00:00
print("==> Installed " + download.metadata.title)
completionHandler?()
2015-08-24 18:45:54 +00:00
}
}
2015-08-21 18:01:56 +00:00
}
struct ProgressState {
let percentComplete: Float
let phase: String
var percentage: String {
return String(format: "%.1f%%", arguments: [floor(percentComplete * 100)])
}
}
func progress(state: ProgressState) {
// Don't display the progress bar if we're not on a terminal
if isatty(fileno(stdout)) == 0 {
return
}
2015-08-21 18:01:56 +00:00
let barLength = 60
let completeLength = Int(state.percentComplete * Float(barLength))
var bar = ""
for i in 0..<barLength {
if i < completeLength {
bar += "#"
}
else {
bar += "-"
}
}
clearLine()
2015-09-14 08:51:09 +00:00
print("\(bar) \(state.percentage) \(state.phase)", terminator: "")
fflush(stdout)
2015-08-21 18:01:56 +00:00
}
func clearLine() {
print("\(csi)2K\(csi)0G")
}
2015-08-21 18:01:56 +00:00
extension SSDownloadStatus {
var progressState: ProgressState {
let phase = activePhase?.phaseDescription ?? "Waiting"
return ProgressState(percentComplete: percentComplete, phase: phase)
}
}
extension SSDownloadPhase {
var phaseDescription: String {
switch phaseType {
case 0:
return "Downloading"
case 1:
return "Installing"
default:
return "Waiting"
}
}
}