diff --git a/README.md b/README.md index f2fe4c0..10200be 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This is a client of [TinyPNG](https://tinypng.com) for Mac, with which you can c [Release Page](https://github.com/kyleduo/TinyPNG4Mac/releases) -[CDN](https://static.kyleduo.com/project/release/tinypng4mac/tinypng4mac_1_0_1.app.zip) +[CDN](https://static.kyleduo.com/project/release/tinypng4mac/tinypng4mac_1_0_3.zip) Check "Anywhere" in `Preferences -> Security & privacy` if you can not open this app. Just for the first time, and I suggest you uncheck it after you open this app for security. @@ -30,6 +30,12 @@ Check "Anywhere" in `Preferences -> Security & privacy` if you can not open this ### Release Notes +**Version 1.0.3** + +1. Support compress folder recursively. [#14](https://github.com/kyleduo/TinyPNG4Mac/issues/14) [#33](https://github.com/kyleduo/TinyPNG4Mac/issues/33) + +---- + **Version 1.0.2** 1. Fixed [#29](https://github.com/kyleduo/TinyPNG4Mac/issues/29) diff --git a/README_ZH.md b/README_ZH.md index 8a95c38..e270617 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -20,7 +20,7 @@ [Release Page](https://github.com/kyleduo/TinyPNG4Mac/releases) -[CDN下载](https://static.kyleduo.com/project/release/tinypng4mac/tinypng4mac_1_0_1.app.zip) +[CDN下载](https://static.kyleduo.com/project/release/tinypng4mac/tinypng4mac_1_0_3.zip) 第一次打开可能出现“无法打开”的提示,请到`设置 -> 安全性与隐私`里面勾选`所有来源`。出于安全考虑,建议打开之后关闭这个选项。 @@ -30,6 +30,12 @@ ### 更新信息 +**Version 1.0.3** + +1. 支持压缩目录下的所有图片 [#14](https://github.com/kyleduo/TinyPNG4Mac/issues/14) [#33](https://github.com/kyleduo/TinyPNG4Mac/issues/33) + +---- + **Version 1.0.2** 1. 修复 [#29](https://github.com/kyleduo/TinyPNG4Mac/issues/29) diff --git a/archive/TinyPNG4Mac_1_0_2.zip b/archive/TinyPNG4Mac_1_0_3.zip similarity index 81% rename from archive/TinyPNG4Mac_1_0_2.zip rename to archive/TinyPNG4Mac_1_0_3.zip index 4e6d496..ea931d3 100644 Binary files a/archive/TinyPNG4Mac_1_0_2.zip and b/archive/TinyPNG4Mac_1_0_3.zip differ diff --git a/source/Podfile.lock b/source/Podfile.lock index 3c3ee46..546051d 100644 --- a/source/Podfile.lock +++ b/source/Podfile.lock @@ -7,7 +7,7 @@ DEPENDENCIES: - SwiftyJSON (~> 5.0) SPEC REPOS: - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - Alamofire - SwiftyJSON @@ -17,4 +17,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 1e14da6108c97041b7daef307aaa48a8f180f7a4 -COCOAPODS: 1.7.5 +COCOAPODS: 1.8.0 diff --git a/source/tinypng4mac.xcodeproj/project.pbxproj b/source/tinypng4mac.xcodeproj/project.pbxproj index 88391d0..2489306 100644 --- a/source/tinypng4mac.xcodeproj/project.pbxproj +++ b/source/tinypng4mac.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 27C12A171D35411800F0FD81 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 27C12A151D35411800F0FD81 /* Localizable.strings */; }; 27F5BA4B206B7021008529C9 /* TPWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F5BA4A206B7021008529C9 /* TPWindow.swift */; }; 27F5BA4E206B7373008529C9 /* PasteboardTypeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F5BA4D206B7373008529C9 /* PasteboardTypeExtension.swift */; }; + BCFA8CDD233BC9BC0082F4C4 /* FileInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCFA8CDC233BC9BC0082F4C4 /* FileInfo.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -60,6 +61,7 @@ 3EC4E906FA6863DD0D5839DA /* Pods-TinyPNG4Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TinyPNG4Mac.release.xcconfig"; path = "Pods/Target Support Files/Pods-TinyPNG4Mac/Pods-TinyPNG4Mac.release.xcconfig"; sourceTree = ""; }; 811CF203124A83759CC63BFF /* Pods_TinyPNG4Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TinyPNG4Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B8A32DFEB3E5214A1AADE38D /* Pods-TinyPNG4Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TinyPNG4Mac.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TinyPNG4Mac/Pods-TinyPNG4Mac.debug.xcconfig"; sourceTree = ""; }; + BCFA8CDC233BC9BC0082F4C4 /* FileInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileInfo.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -126,6 +128,7 @@ isa = PBXGroup; children = ( 277AAF691D254D4F00788F37 /* TPTaskInfo.swift */, + BCFA8CDC233BC9BC0082F4C4 /* FileInfo.swift */, ); path = model; sourceTree = ""; @@ -310,6 +313,7 @@ 277AAF6A1D254D4F00788F37 /* TPTaskInfo.swift in Sources */, 277AAF6C1D25517E00788F37 /* TPStore.swift in Sources */, 277AAF621D250DD100788F37 /* DragContainer.swift in Sources */, + BCFA8CDD233BC9BC0082F4C4 /* FileInfo.swift in Sources */, 277AAF781D269D7C00788F37 /* IOHelper.swift in Sources */, 277AAF761D2698B600788F37 /* TPConfig.swift in Sources */, ); @@ -451,8 +455,10 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 10; INFOPLIST_FILE = tinypng4mac/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.kyleduo.tinypngmac; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -466,8 +472,10 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 10; INFOPLIST_FILE = tinypng4mac/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.kyleduo.tinypngmac; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/source/tinypng4mac/Info.plist b/source/tinypng4mac/Info.plist index 397d7c4..1ece798 100644 --- a/source/tinypng4mac/Info.plist +++ b/source/tinypng4mac/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.2 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 9 + $(CURRENT_PROJECT_VERSION) LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright diff --git a/source/tinypng4mac/MainViewController.swift b/source/tinypng4mac/MainViewController.swift index 6fc0326..31f4fc1 100644 --- a/source/tinypng4mac/MainViewController.swift +++ b/source/tinypng4mac/MainViewController.swift @@ -212,7 +212,7 @@ class MainViewController: NSViewController, NSOpenSavePanelDelegate, NSTableView func draggingExit() { } - func draggingFileAccept(_ files:Array) { + func draggingFileAccept(_ files:Array) { if TPClient.sApiKey == "" { showInputPanel() return; @@ -220,9 +220,11 @@ class MainViewController: NSViewController, NSOpenSavePanelDelegate, NSTableView var tasks = [TPTaskInfo]() let manager = FileManager.default for file in files { - let attributes = try? manager.attributesOfItem(atPath: file.path) + print(file.filePath.path) + print(file.filePath.relativePath) + let attributes = try? manager.attributesOfItem(atPath: file.filePath.path) let size = attributes![FileAttributeKey.size]! - let task = TPTaskInfo(originFile: file, fileName:file.lastPathComponent, originSize: (size as AnyObject).doubleValue!) + let task = TPTaskInfo(file, originSize: (size as AnyObject).doubleValue!) tasks.append(task) } TPClient.sharedClient.add(tasks) diff --git a/source/tinypng4mac/model/FileInfo.swift b/source/tinypng4mac/model/FileInfo.swift new file mode 100644 index 0000000..cd3897e --- /dev/null +++ b/source/tinypng4mac/model/FileInfo.swift @@ -0,0 +1,19 @@ +// +// FileInfo.swift +// TinyPNG4Mac +// +// Created by kyleduo on 2019/9/26. +// Copyright © 2019 kyleduo. All rights reserved. +// + +import Foundation + +class FileInfo { + var filePath: URL + var relativePath: String + + init(_ filePath: URL, relativePath: String) { + self.filePath = filePath + self.relativePath = relativePath + } +} diff --git a/source/tinypng4mac/model/TPTaskInfo.swift b/source/tinypng4mac/model/TPTaskInfo.swift index c88b5ac..5b2ade4 100644 --- a/source/tinypng4mac/model/TPTaskInfo.swift +++ b/source/tinypng4mac/model/TPTaskInfo.swift @@ -12,7 +12,7 @@ class TPTaskInfo: NSObject { var originFile: URL var outputFile: URL? var resultUrl: String - var fileName: String + var fileInfo: FileInfo var originSize: Double var status: TPTaskStatus var progress: Progress // progress for uploading and downloading @@ -22,9 +22,9 @@ class TPTaskInfo: NSObject { var errorMessage: String? var index: Int - init(originFile: URL, fileName: String, originSize: Double) { - self.originFile = originFile - self.fileName = fileName + init(_ fileInfo: FileInfo, originSize: Double) { + self.originFile = fileInfo.filePath + self.fileInfo = fileInfo self.originSize = originSize self.status = .initial @@ -40,7 +40,7 @@ class TPTaskInfo: NSObject { } override var description: String { - return String(format: "Task {}", self.fileName) + return String(format: "Task {}", self.fileInfo.relativePath) } } diff --git a/source/tinypng4mac/tpclient/TPClient.swift b/source/tinypng4mac/tpclient/TPClient.swift index 1f1ce50..dd522da 100644 --- a/source/tinypng4mac/tpclient/TPClient.swift +++ b/source/tinypng4mac/tpclient/TPClient.swift @@ -49,7 +49,7 @@ class TPClient { if let t = task { self.updateStatus(t, newStatus: .prepare) runningTasks += 1 - debugPrint("prepare to upload: " + t.fileName + " tasks: " + String(self.runningTasks)) + debugPrint("prepare to upload: " + t.fileInfo.relativePath + " tasks: " + String(self.runningTasks)) executeTask(t) } else { break; @@ -69,7 +69,7 @@ class TPClient { let authorizationHeader = "Basic " + authData! self.updateStatus(task, newStatus: .uploading) - debugPrint("uploading: " + task.fileName) + debugPrint("uploading: " + task.fileInfo.relativePath) let headers: HTTPHeaders = [ "Authorization": authorizationHeader, @@ -79,7 +79,7 @@ class TPClient { .uploadProgress(closure: { (progress) in if progress.fractionCompleted == 1 { self.updateStatus(task, newStatus: .processing) - debugPrint("processing: " + task.fileName) + debugPrint("processing: " + task.fileInfo.relativePath) } else { self.updateStatus(task, newStatus: .uploading, progress: progress) } @@ -89,7 +89,7 @@ class TPClient { let json = JSON(jsonstr) if json != JSON.null { if let error = json["error"].string { - debugPrint("error: " + task.fileName + error) + debugPrint("error: " + task.fileInfo.relativePath + error) self.markError(task, errorMessage: json["message"].string) return } @@ -116,13 +116,13 @@ class TPClient { } fileprivate func onUploadFinish(_ task: TPTaskInfo) { - debugPrint("downloading: " + task.fileName) + debugPrint("downloading: " + task.fileInfo.relativePath) self.updateStatus(task, newStatus: .downloading) if TPConfig.shouldReplace() { task.outputFile = task.originFile; } else { let folder = IOHeler.getOutputPath() - task.outputFile = folder.appendingPathComponent(task.fileName) + task.outputFile = folder.appendingPathComponent(task.fileInfo.relativePath) } downloadCompressImage(task) } @@ -142,7 +142,7 @@ class TPClient { self.markError(task, errorMessage: "download error") } else { self.updateStatus(task, newStatus: .finish) - debugPrint("finish: " + task.fileName + " tasks: " + String(self.runningTasks)) + debugPrint("finish: " + task.fileInfo.relativePath + " tasks: " + String(self.runningTasks)) } self.checkExecution() diff --git a/source/tinypng4mac/utils/IOHelper.swift b/source/tinypng4mac/utils/IOHelper.swift index 416a2db..c47d658 100644 --- a/source/tinypng4mac/utils/IOHelper.swift +++ b/source/tinypng4mac/utils/IOHelper.swift @@ -41,4 +41,11 @@ class IOHeler { try! fileManager.removeItem(at: file) } } + + static func isDirectory(_ path: String) -> Bool { + let fileManager = FileManager.default + var isDirectory = ObjCBool(false) + let fileExists = fileManager.fileExists(atPath: path, isDirectory: &isDirectory) + return fileExists && isDirectory.boolValue + } } diff --git a/source/tinypng4mac/views/DragContainer.swift b/source/tinypng4mac/views/DragContainer.swift index 3cfa2fc..b0066a2 100644 --- a/source/tinypng4mac/views/DragContainer.swift +++ b/source/tinypng4mac/views/DragContainer.swift @@ -11,7 +11,7 @@ import Cocoa protocol DragContainerDelegate { func draggingEntered(); func draggingExit(); - func draggingFileAccept(_ files:Array); + func draggingFileAccept(_ files:Array); } class DragContainer: NSView { @@ -38,14 +38,10 @@ class DragContainer: NSView { override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { self.layer?.backgroundColor = NSColor(white: 1, alpha: highlightAlpha).cgColor; - let res = checkExtension(sender) if let delegate = self.delegate { delegate.draggingEntered(); } - if res { - return NSDragOperation.generic - } - return NSDragOperation() + return NSDragOperation.generic } override func draggingExited(_ sender: NSDraggingInfo?) { @@ -61,14 +57,10 @@ class DragContainer: NSView { } override func performDragOperation(_ sender: NSDraggingInfo) -> Bool { - var files = Array() + var files = Array() if let board = sender.draggingPasteboard.propertyList(forType: NSFilenamesPboardType) as? NSArray { for path in board { - let url = URL(fileURLWithPath: path as! String) - let fileExtension = url.pathExtension.lowercased() - if acceptTypes.contains(fileExtension) { - files.append(url) - } + files.append(contentsOf: collectFiles(path as! String)) } } @@ -78,17 +70,30 @@ class DragContainer: NSView { return true } - - func checkExtension(_ draggingInfo: NSDraggingInfo) -> Bool { - if let board = draggingInfo.draggingPasteboard.propertyList(forType: NSFilenamesPboardType) as? NSArray { - for path in board { - let url = URL(fileURLWithPath: path as! String) - let fileExtension = url.pathExtension.lowercased() - if acceptTypes.contains(fileExtension) { - return true - } - } - } - return false - } + + func collectFiles(_ filePath: String) -> Array { + var files = Array() + let isDirectory = IOHeler.isDirectory(filePath) + if isDirectory { + let fileManager = FileManager.default + let enumerator = fileManager.enumerator(atPath: filePath) + while let relativePath = enumerator?.nextObject() as? String { + let fullFilePath = filePath.appending("/\(relativePath)") + if (fileIsAcceptable(fullFilePath)) { + let parent = URL(fileURLWithPath: filePath).lastPathComponent + files.append(FileInfo(URL(fileURLWithPath: fullFilePath), relativePath:"\(parent)/\(relativePath)")) + } + } + } else if (fileIsAcceptable(filePath)) { + let url = URL(fileURLWithPath: filePath) + files.append(FileInfo(url, relativePath:url.lastPathComponent)) + } + return files + } + + func fileIsAcceptable(_ path: String) -> Bool { + let url = URL(fileURLWithPath: path) + let fileExtension = url.pathExtension.lowercased() + return acceptTypes.contains(fileExtension) + } } diff --git a/source/tinypng4mac/views/TaskTableCell.swift b/source/tinypng4mac/views/TaskTableCell.swift index 48824e0..69e60a4 100644 --- a/source/tinypng4mac/views/TaskTableCell.swift +++ b/source/tinypng4mac/views/TaskTableCell.swift @@ -21,7 +21,7 @@ class TaskTableCell: NSTableCellView { var task: TPTaskInfo? { didSet { - self.name.stringValue = (task?.fileName)! + self.name.stringValue = (task?.fileInfo.relativePath)! self.preview.image = NSImage.init(contentsOf: (task?.originFile)! as URL) let taskStatus = (task?.status)! var statusText = "" @@ -52,7 +52,13 @@ class TaskTableCell: NSTableCellView { } if taskStatus == .finish { - let text = "-\(Formator.formatSize(task!.originSize - task!.resultSize)) (\(Formator.formatRate(1 - task!.compressRate)))" + let sizeChange = task!.originSize - task!.resultSize + var text: String = "" + if sizeChange == 0 { + text = "0.00B" + } else { + text = "-\(Formator.formatSize(sizeChange)) (\(Formator.formatRate(1 - task!.compressRate)))" + } self.status.stringValue = text self.status.textColor = NSColor(deviceRed:0.41, green:0.95, blue:0.78, alpha:1.00) self.name.textColor = NSColor(deviceRed:1, green:1, blue:1, alpha:0.9)