Skip to content

Commit

Permalink
🎨重构自定义图床
Browse files Browse the repository at this point in the history
🎨 Optimize

- 重构自定义图床:更好的配置参数、可配置的结果URL获取规则。具体可看:https://blog.svend.cc/upic/tutorials/custom/
- 在偏好设置打开时,Dock栏会显示uPic应用。主要为了方便在配置图床时在切换了应用后能快速点击Dock栏图标回到偏好设置界面

🐛 Fix Bugs

- 修复使用第三方软件截图后,不能通过上传已拷贝文件的bug
- 修复其他一些小问题
  • Loading branch information
gee1k committed Jul 17, 2019
1 parent 0446e93 commit bcf7f79
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 56 deletions.
8 changes: 8 additions & 0 deletions uPic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
167DDBEF22C7722200B03357 /* GithubUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167DDBEE22C7722200B03357 /* GithubUtil.swift */; };
167DDBF122C7784900B03357 /* GithubConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167DDBF022C7784900B03357 /* GithubConfigView.swift */; };
1683573C22DB0D0800985B10 /* CustomConfigSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1683573B22DB0D0800985B10 /* CustomConfigSheetController.swift */; };
1685AA3522DEC943008FBF1D /* FlippedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1685AA3422DEC943008FBF1D /* FlippedView.swift */; };
1685AA3722DEEE6C008FBF1D /* CustomHostUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1685AA3622DEEE6C008FBF1D /* CustomHostUtil.swift */; };
168A831122B606C000344E77 /* UpYunUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16995A2022B5FC7B00B1F923 /* UpYunUploader.swift */; };
1690E7E422BF111500FC81F8 /* QiniuConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1690E7E322BF111500FC81F8 /* QiniuConfigView.swift */; };
1690E7E722BF174300FC81F8 /* QiniuHostConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1690E7E622BF12D200FC81F8 /* QiniuHostConfig.swift */; };
Expand Down Expand Up @@ -167,6 +169,8 @@
167DDBEE22C7722200B03357 /* GithubUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GithubUtil.swift; sourceTree = "<group>"; };
167DDBF022C7784900B03357 /* GithubConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GithubConfigView.swift; sourceTree = "<group>"; };
1683573B22DB0D0800985B10 /* CustomConfigSheetController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomConfigSheetController.swift; sourceTree = "<group>"; };
1685AA3422DEC943008FBF1D /* FlippedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlippedView.swift; sourceTree = "<group>"; };
1685AA3622DEEE6C008FBF1D /* CustomHostUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomHostUtil.swift; sourceTree = "<group>"; };
1690E7E022BE32B100FC81F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; };
1690E7E222BE32D500FC81F8 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Preferences.strings"; sourceTree = "<group>"; };
1690E7E322BF111500FC81F8 /* QiniuConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QiniuConfigView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -252,6 +256,7 @@
161C3BE022C4831B0092114F /* CustomUploader.swift */,
161C3BE222C483560092114F /* CustomHostConfig.swift */,
161C3BE622C49BE90092114F /* RequestMethods.swift */,
1685AA3622DEEE6C008FBF1D /* CustomHostUtil.swift */,
);
path = Custom;
sourceTree = "<group>";
Expand All @@ -266,6 +271,7 @@
1647474222B66ACE00F9575D /* Data+Extension.swift */,
165D908522C333740096FF38 /* PasteboardType+Extension.swift */,
165701A022C8A6E600C57EE9 /* Regex.swift */,
1685AA3422DEC943008FBF1D /* FlippedView.swift */,
);
path = Basic;
sourceTree = "<group>";
Expand Down Expand Up @@ -685,6 +691,7 @@
165701A322C8AE0A00C57EE9 /* WeiboUtil.swift in Sources */,
16EA205C22AF8FB90006FB9C /* ConfigManager.swift in Sources */,
1675516722ACAA0600D3EB6F /* UPicUpdater.swift in Sources */,
1685AA3522DEC943008FBF1D /* FlippedView.swift in Sources */,
16068C7822AECB34004D39B7 /* PreferencesWindowController.swift in Sources */,
16995A3422B6008000B1F923 /* UpYunHostConfig.swift in Sources */,
1672762322AFF655007299C3 /* Host.swift in Sources */,
Expand Down Expand Up @@ -752,6 +759,7 @@
1660FCBC22C11C7500372950 /* TencentUtil.swift in Sources */,
1660FCBA22C11C2300372950 /* TencentHostConfig.swift in Sources */,
167DDBEF22C7722200B03357 /* GithubUtil.swift in Sources */,
1685AA3722DEEE6C008FBF1D /* CustomHostUtil.swift in Sources */,
68BBB99780D7F4586458D4F5 /* AliyunUtil.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
17 changes: 17 additions & 0 deletions uPic/Basic/FlippedView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// FlippedView.swift
// uPic
//
// Created by Svend Jin on 2019/7/17.
// Copyright © 2019 Svend Jin. All rights reserved.
//

import Cocoa

class FlippedView: NSView {
override var isFlipped:Bool {
get {
return true
}
}
}
10 changes: 5 additions & 5 deletions uPic/Models/Custom/CustomHostConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class CustomHostConfig: HostConfig {
dynamic var url: String!
dynamic var method: String! = RequestMethods.POST.rawValue
dynamic var field: String!
dynamic var extensions: String?
dynamic var bodys: String?
dynamic var headers: String?
dynamic var resultPath: String?
dynamic var domain: String?
Expand All @@ -28,8 +28,8 @@ class CustomHostConfig: HostConfig {
return NSLocalizedString("host.field.method", comment: "method")
case "field":
return NSLocalizedString("host.field.field", comment: "field")
case "extensions":
return NSLocalizedString("host.field.extensions", comment: "extensions")
case "bodys":
return NSLocalizedString("host.field.bodys", comment: "bodys")
case "headers":
return NSLocalizedString("host.field.headers", comment: "headers")
case "resultPath":
Expand All @@ -48,7 +48,7 @@ class CustomHostConfig: HostConfig {
dict["url"] = self.url
dict["method"] = self.method
dict["field"] = self.field
dict["extensions"] = self.extensions
dict["bodys"] = self.bodys
dict["headers"] = self.headers
dict["resultPath"] = self.resultPath
dict["domain"] = self.domain
Expand All @@ -67,7 +67,7 @@ class CustomHostConfig: HostConfig {
config.url = json["url"].stringValue
config.method = json["method"].stringValue
config.field = json["field"].stringValue
config.extensions = json["extensions"].stringValue
config.bodys = json["bodys"].stringValue
config.headers = json["headers"].stringValue
config.resultPath = json["resultPath"].stringValue
config.domain = json["domain"].stringValue
Expand Down
61 changes: 61 additions & 0 deletions uPic/Models/Custom/CustomHostUtil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// CustomHostUtil.swift
// uPic
//
// Created by Svend Jin on 2019/7/17.
// Copyright © 2019 Svend Jin. All rights reserved.
//

import Foundation
import SwiftyJSON

class CustomHostUtil {

/**
解析请求头或者body字符串
*/
public static func parseHeadersOrBodys(_ str: String) -> [Dictionary<String, String>] {
var arr: [Dictionary<String, String>] = []
if let json = try? JSON(data: str.data(using: String.Encoding.utf8)!) {
if let jsonArr = json.array {
for jsonItem in jsonArr {
arr.append(jsonItem.dictionaryObject as! [String: String])
}
}
}
return arr
}

/**
格式化请求头或者body为字符串
*/
public static func formatHeadersOrBodys(_ arr: [Dictionary<String, String>]) -> String {
return JSON(arr).rawString() ?? ""
}

/**
获取json结果中的url
*/
public static func parseResultUrl(_ json: JSON, _ resultPath: String) -> String {
var retUrl = ""
var retJson = json

if !resultPath.isEmpty {
if let pathJSON = try? JSON(data: resultPath.data(using: String.Encoding.utf8)!) {
if let pathArr = pathJSON.arrayObject {
var path: [JSONSubscriptType] = []
for p in pathArr {
if (p is Int) {
path.append(p as! Int)
} else if (p is String) {
path.append(p as! String)
}
}
retUrl = retJson[path].rawString() ?? ""
}
}
}

return retUrl
}
}
75 changes: 35 additions & 40 deletions uPic/Models/Custom/CustomUploader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Cocoa
import Alamofire
import SwiftyXMLParser
import SwiftyJSON

class CustomUploader: BaseUploader {

Expand All @@ -30,10 +30,10 @@ class CustomUploader: BaseUploader {
let field = config.field!
let hostSaveKey = HostSaveKey(rawValue: config.saveKey!)!
let domain = config.domain!

let httpMethod = HTTPMethod(rawValue: method) ?? HTTPMethod.post


if url.isEmpty {
super.faild(errorMsg: NSLocalizedString("bad-host-config", comment: "bad host config"))
return
Expand All @@ -52,47 +52,37 @@ class CustomUploader: BaseUploader {

var headers = HTTPHeaders()
headers.add(HTTPHeader.contentType("application/x-www-form-urlencoded;charset=utf-8"))

if let headersStr = config.headers {
let headersArr = headersStr.split(separator: Character("&"))
for headerSr in headersArr {
let headerArr = headerSr.split(separator: Character("="))
if headerArr.count < 2 {
continue
}
var value = String(headerArr[1])
switch value {
case "{filename}":
value = fileName
break
default:
break
let headersArr = CustomHostUtil.parseHeadersOrBodys(headersStr)
for header in headersArr {
if let key = header["key"] {
var value = header["value"] ?? ""
if value == "{filename}" {
value = fileName
}

headers.add(HTTPHeader(name: key, value: value))
}
headers.add(HTTPHeader(name: String(headerArr[0]), value: value))
}
}



func multipartFormDataGen(multipartFormData: MultipartFormData) {

if let extensionsStr = config.extensions {
let extensionsArr = extensionsStr.split(separator: Character("&"))
for extensions in extensionsArr {
let extensionArr = extensions.split(separator: Character("="))
if extensionArr.count < 2 {
continue
}

var value = String(extensionArr[1])
switch value {
case "{filename}":
value = fileName
break
default:
break
if let bodysStr = config.bodys {
let bodysArr = CustomHostUtil.parseHeadersOrBodys(bodysStr)
for body in bodysArr {
if let key = body["key"] {
var value = body["value"] ?? ""
if value == "{filename}" {
value = fileName
}

multipartFormData.append(String(value).data(using: .utf8)!, withName: key)
}
multipartFormData.append(String(value).data(using: .utf8)!, withName: String(extensionArr[0]))
}
}

if fileUrl != nil {
multipartFormData.append(fileUrl!, withName: field, fileName: fileName, mimeType: mimeType)
} else {
Expand All @@ -103,10 +93,15 @@ class CustomUploader: BaseUploader {

AF.upload(multipartFormData: multipartFormDataGen, to: url, method: httpMethod, headers: headers).validate().uploadProgress { progress in
super.progress(percent: progress.fractionCompleted)
}.response(completionHandler: { response -> Void in
}.responseJSON(completionHandler: { response -> Void in
switch response.result {
case .success(_):
super.completed(url: "\(domain)/\(fileName)")
case .success(let value):
let json = JSON(value)
var retUrl = CustomHostUtil.parseResultUrl(json, config.resultPath ?? "")
if !domain.isEmpty {
retUrl = "\(domain)/\(retUrl)"
}
super.completed(url: retUrl)
case .failure(let error):
super.faild(errorMsg: error.localizedDescription)
}
Expand Down
1 change: 1 addition & 0 deletions uPic/Notifier/PreferencesNotifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class PreferencesNotifier: Notifier {
public enum Notification: String {
case openConfigSheet
case saveHostSettings
case saveCustomExtensionSettings
case hostConfigChanged
}

Expand Down
4 changes: 2 additions & 2 deletions uPic/PreferencesWindow/Base.lproj/Preferences.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@
<rect key="frame" x="20" y="20" width="340" height="160"/>
<subviews>
<stackView distribution="fill" orientation="horizontal" alignment="top" spacing="12" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="216" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yY2-Uz-6lI">
<rect key="frame" x="0.0" y="128" width="94" height="32"/>
<rect key="frame" x="0.0" y="128" width="96" height="32"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PJu-EB-sSS">
<rect key="frame" x="-2" y="8" width="44" height="24"/>
Expand All @@ -311,7 +311,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GS4-or-3hj">
<rect key="frame" x="50" y="8" width="46" height="24"/>
<rect key="frame" x="50" y="8" width="48" height="24"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="0.1.0" id="Jnf-AX-bIr">
<font key="font" metaFont="system" size="20"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
Expand Down
2 changes: 1 addition & 1 deletion uPic/PreferencesWindow/ConfigView/ConfigView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ class ConfigView: NSView {

func removeObserver() {
PreferencesNotifier.removeObserver(observer: self, notification: .saveHostSettings)
PreferencesNotifier.addObserver(observer: self, selector: #selector(saveHostSettings), notification: .saveHostSettings)
}

@objc func openConfigSheet(_ sender: NSButton) {
Expand All @@ -132,6 +131,7 @@ class ConfigView: NSView {
}

@objc func saveHostSettings(notification: Notification) {
self.removeObserver()
guard let userInfo = notification.userInfo else {
print("No userInfo found in notification")
return
Expand Down
Loading

0 comments on commit bcf7f79

Please sign in to comment.