Skip to content
This repository has been archived by the owner on Nov 13, 2020. It is now read-only.

Commit

Permalink
Fix previews of ZIP archives with 0 or 1 file entries
Browse files Browse the repository at this point in the history
Fixes #10
  • Loading branch information
samuelmeuli committed May 18, 2020
1 parent 968eeca commit a9b2db6
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 13 deletions.
Binary file not shown.
Binary file added GlanceTests/TestFiles/archives/example-no-files.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
41 changes: 28 additions & 13 deletions QLPlugin/Views/Previews/ZIPPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SwiftExec
class ZIPPreview: Preview {
let filesRegex =
#"(.{10}) +.+ +.+ +(\d+) +.+ +.+ +(\d{2}-\w{3}-\d{2} +\d{2}:\d{2}) +(.+)"#
let sizeRegex = #"\d+ files, (\d+) bytes uncompressed, \d+ bytes compressed: +([\d.]+)%"#
let sizeRegex = #"\d+ files?, (\d+) bytes? uncompressed, \d+ bytes? compressed: +([\d.]+)%"#

let byteCountFormatter = ByteCountFormatter()
let dateFormatter = DateFormatter()
Expand All @@ -15,11 +15,21 @@ class ZIPPreview: Preview {
}

private func runZIPInfoCommand(filePath: String) throws -> String {
let result = try exec(
program: "/usr/bin/zipinfo",
arguments: [filePath]
)
return result.stdout ?? ""
do {
let result = try exec(
program: "/usr/bin/zipinfo",
arguments: [filePath]
)
return result.stdout ?? ""
} catch {
// Empty ZIP files are allowed, but return exit code 1
let error = error as! ExecError
let stdout = error.execResult.stdout ?? ""
if error.execResult.exitCode == 1, stdout.hasSuffix("Empty zipfile.") {
return stdout
}
throw error
}
}

/// Parses the output of the `zipinfo` command.
Expand All @@ -34,7 +44,7 @@ class ZIPPreview: Preview {
// Content lines: "drwxr-xr-x 2.0 unx 0 bx stor 20-Jan-13 19:38 my-zip/dir/"
// - "-" as first character indicates a file, "d" a directory
// - "0 bx" indicates the number of bytes
let filesString = linesSplit[2 ... linesSplit.count - 2].joined(separator: "\n")
let filesString = linesSplit[2 ..< linesSplit.count - 1].joined(separator: "\n")
let fileMatches = filesString.matchRegex(regex: filesRegex)
for fileMatch in fileMatches {
let permissions = fileMatch[1]
Expand All @@ -57,12 +67,17 @@ class ZIPPreview: Preview {
}
}

// Last line: "152 files, 192919 bytes uncompressed, 65061 bytes compressed: 66.3%"
let sizeMatches = String(linesSplit.last ?? "").matchRegex(regex: sizeRegex)
let sizeUncompressed = Int(sizeMatches[0][1])
let compressionRatio = Double(sizeMatches[0][2])

return (fileTree, sizeUncompressed, compressionRatio)
// Last line:
// - If not empty: "152 files, 192919 bytes uncompressed, 65061 bytes compressed: 66.3%"
// - If empty: "Empty zipfile."
if let lastLine = linesSplit.last, lastLine != "Empty zipfile." {
let sizeMatches = String(lastLine).matchRegex(regex: sizeRegex)
let sizeUncompressed = Int(sizeMatches[0][1])
let compressionRatio = Double(sizeMatches[0][2])
return (fileTree, sizeUncompressed, compressionRatio)
} else {
return (fileTree, 0, 0)
}
}

func createPreviewVC(file: File) throws -> PreviewVC {
Expand Down

0 comments on commit a9b2db6

Please sign in to comment.