support api for proxy provider [beta] [appcenter] [notarize]
This commit is contained in:
parent
e1ce6b35db
commit
969124d9e7
@ -64,6 +64,8 @@
|
||||
F935B2F42307CD32009E4D33 /* ProxyConfigHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F935B2F32307CD32009E4D33 /* ProxyConfigHelper.m */; };
|
||||
F935B2FA23083EE6009E4D33 /* ProxySettingTool.m in Sources */ = {isa = PBXBuildFile; fileRef = F935B2F923083EE6009E4D33 /* ProxySettingTool.m */; };
|
||||
F935B2FC23085515009E4D33 /* SystemProxyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F935B2FB23085515009E4D33 /* SystemProxyManager.swift */; };
|
||||
F939724C23A4B33500FE5A3F /* ClashProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F939724B23A4B33500FE5A3F /* ClashProvider.swift */; };
|
||||
F939724E23A4DB0600FE5A3F /* DateFormatter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = F939724D23A4DB0600FE5A3F /* DateFormatter+.swift */; };
|
||||
F976275C23634DF8000EDEFE /* LoginServiceKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F976275B23634DF8000EDEFE /* LoginServiceKit.swift */; };
|
||||
F977FAAC2366790500C17F1F /* AutoUpgardeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F977FAAB2366790500C17F1F /* AutoUpgardeManager.swift */; };
|
||||
F977FAAE23669D6400C17F1F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F977FAAD23669D6400C17F1F /* ConnectionManager.swift */; };
|
||||
@ -181,6 +183,8 @@
|
||||
F935B2F823083EE6009E4D33 /* ProxySettingTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProxySettingTool.h; sourceTree = "<group>"; };
|
||||
F935B2F923083EE6009E4D33 /* ProxySettingTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ProxySettingTool.m; sourceTree = "<group>"; };
|
||||
F935B2FB23085515009E4D33 /* SystemProxyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemProxyManager.swift; sourceTree = "<group>"; };
|
||||
F939724B23A4B33500FE5A3F /* ClashProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClashProvider.swift; sourceTree = "<group>"; };
|
||||
F939724D23A4DB0600FE5A3F /* DateFormatter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+.swift"; sourceTree = "<group>"; };
|
||||
F976275B23634DF8000EDEFE /* LoginServiceKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginServiceKit.swift; sourceTree = "<group>"; };
|
||||
F977FAAB2366790500C17F1F /* AutoUpgardeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoUpgardeManager.swift; sourceTree = "<group>"; };
|
||||
F977FAAD23669D6400C17F1F /* ConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionManager.swift; sourceTree = "<group>"; };
|
||||
@ -232,6 +236,7 @@
|
||||
F92D0B29236C759100575E15 /* NSTextField+Vibrancy.swift */,
|
||||
F9E754D1239CC28D00CEE7CC /* NSAlert+Extension.swift */,
|
||||
F9E8F34523A12B89002DE5E8 /* String+Encode.swift */,
|
||||
F939724D23A4DB0600FE5A3F /* DateFormatter+.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@ -281,6 +286,7 @@
|
||||
499A485722ED715200F6C675 /* RemoteConfigModel.swift */,
|
||||
F915A4612366ADEF004840BE /* ClashConnection.swift */,
|
||||
F92D0B23236BC12000575E15 /* SavedProxyModel.swift */,
|
||||
F939724B23A4B33500FE5A3F /* ClashProvider.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@ -620,6 +626,7 @@
|
||||
4952C3D02117027C004A4FA8 /* ConfigFileManager.swift in Sources */,
|
||||
49BC061C212931F4005A0FE7 /* AboutViewController.swift in Sources */,
|
||||
4949D154213242F600EF85E6 /* Paths.swift in Sources */,
|
||||
F939724E23A4DB0600FE5A3F /* DateFormatter+.swift in Sources */,
|
||||
F915A4622366ADEF004840BE /* ClashConnection.swift in Sources */,
|
||||
F977FAAE23669D6400C17F1F /* ConnectionManager.swift in Sources */,
|
||||
495340B320DE68C300B0D3FF /* StatusItemView.swift in Sources */,
|
||||
@ -660,6 +667,7 @@
|
||||
4960A6DB2136529200B940C9 /* JSBridgeHandler.swift in Sources */,
|
||||
493AEAE5221AE7230016FE98 /* ProxyMenuItem.swift in Sources */,
|
||||
499A485E22ED9B7C00F6C675 /* NSTableView+Reload.swift in Sources */,
|
||||
F939724C23A4B33500FE5A3F /* ClashProvider.swift in Sources */,
|
||||
49862FA0218418C600A1D5EC /* ClashRule.swift in Sources */,
|
||||
49C9EF64223E78F5005D8B6A /* ClashProxy.swift in Sources */,
|
||||
F9E8F34623A12B89002DE5E8 /* String+Encode.swift in Sources */,
|
||||
|
@ -546,10 +546,16 @@ extension AppDelegate {
|
||||
|
||||
extension AppDelegate {
|
||||
func registCrashLogger() {
|
||||
#if DEBUG
|
||||
return
|
||||
#endif
|
||||
Fabric.with([Crashlytics.self])
|
||||
}
|
||||
|
||||
func failLaunchProtect() {
|
||||
#if DEBUG
|
||||
return
|
||||
#endif
|
||||
let x = UserDefaults.standard
|
||||
var launch_fail_times: Int = 0
|
||||
if let xx = x.object(forKey: "launch_fail_times") as? Int { launch_fail_times = xx }
|
||||
|
18
ClashX/Extensions/DateFormatter+.swift
Normal file
18
ClashX/Extensions/DateFormatter+.swift
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// DateFormatter+.swift
|
||||
// ClashX
|
||||
//
|
||||
// Created by Etan Chen on 2019/12/14.
|
||||
// Copyright © 2019 west2online. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
extension DateFormatter {
|
||||
static var js: DateFormatter {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale(identifier: NSCalendar.Identifier.ISO8601.rawValue)
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SZ"
|
||||
return dateFormatter
|
||||
}
|
||||
}
|
@ -166,6 +166,13 @@ class ApiRequest {
|
||||
ApiRequest.shared.proxyRespCache = proxies
|
||||
}
|
||||
|
||||
static func requestProxyProviderList(completeHandler: ((ClashProviderResp) -> Void)? = nil) {
|
||||
req("/providers/proxies").responseData { res in
|
||||
let provider = ClashProviderResp.create(try? res.result.get())
|
||||
completeHandler?(provider)
|
||||
}
|
||||
}
|
||||
|
||||
static func updateAllowLan(allow: Bool, completeHandler: (() -> Void)? = nil) {
|
||||
req("/configs",
|
||||
method: .patch,
|
||||
|
@ -17,26 +17,31 @@ class MenuItemFactory {
|
||||
return
|
||||
}
|
||||
|
||||
ApiRequest.requestProxyGroupList() {
|
||||
proxyInfo in
|
||||
var menuItems = [NSMenuItem]()
|
||||
ApiRequest.requestProxyProviderList() {
|
||||
proxyprovider in
|
||||
|
||||
for proxy in proxyInfo.proxyGroups {
|
||||
var menu: NSMenuItem?
|
||||
switch proxy.type {
|
||||
case .select: menu = self.generateSelectorMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
case .urltest, .fallback: menu = generateUrlTestFallBackMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
case .loadBalance:
|
||||
menu = generateLoadBalanceMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
default: continue
|
||||
}
|
||||
ApiRequest.requestProxyGroupList() {
|
||||
proxyInfo in
|
||||
proxyInfo.updateProvider(proxyprovider)
|
||||
|
||||
if let menu = menu {
|
||||
menuItems.append(menu)
|
||||
menu.isEnabled = true
|
||||
var menuItems = [NSMenuItem]()
|
||||
for proxy in proxyInfo.proxyGroups {
|
||||
var menu: NSMenuItem?
|
||||
switch proxy.type {
|
||||
case .select: menu = self.generateSelectorMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
case .urltest, .fallback: menu = generateUrlTestFallBackMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
case .loadBalance:
|
||||
menu = generateLoadBalanceMenuItem(proxyGroup: proxy, proxyInfo: proxyInfo)
|
||||
default: continue
|
||||
}
|
||||
|
||||
if let menu = menu {
|
||||
menuItems.append(menu)
|
||||
menu.isEnabled = true
|
||||
}
|
||||
}
|
||||
completionHandler(menuItems.reversed())
|
||||
}
|
||||
completionHandler(menuItems.reversed())
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +157,21 @@ class MenuItemFactory {
|
||||
return menu
|
||||
}
|
||||
|
||||
static func generateProviderMenuItems(_ provider: ClashProvider) -> NSMenuItem? {
|
||||
let menu = NSMenuItem(title: provider.name, action: nil, keyEquivalent: "")
|
||||
let submenu = NSMenu(title: provider.name)
|
||||
|
||||
for proxy in provider.proxies {
|
||||
let proxyMenuItem = NSMenuItem(title: proxy.name, action: #selector(empty), keyEquivalent: "")
|
||||
proxyMenuItem.target = MenuItemFactory.self
|
||||
proxyMenuItem.submenu = generateHistoryMenu(proxy)
|
||||
submenu.addItem(proxyMenuItem)
|
||||
}
|
||||
|
||||
menu.submenu = submenu
|
||||
return menu
|
||||
}
|
||||
|
||||
static func generateSwitchConfigMenuItems() -> [NSMenuItem] {
|
||||
var items = [NSMenuItem]()
|
||||
for config in ConfigManager.getConfigFilesList() {
|
||||
|
50
ClashX/Models/ClashProvider.swift
Normal file
50
ClashX/Models/ClashProvider.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// ClashProvider.swift
|
||||
// ClashX
|
||||
//
|
||||
// Created by yichengchen on 2019/12/14.
|
||||
// Copyright © 2019 west2online. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class ClashProviderResp: Codable {
|
||||
let allProviders: [ClashProxyName: ClashProvider]
|
||||
lazy var providers: [ClashProxyName: ClashProvider] = {
|
||||
return allProviders.filter({ $0.value.vehicleType != .Compatible })
|
||||
}()
|
||||
|
||||
private init() {
|
||||
allProviders = [:]
|
||||
}
|
||||
|
||||
static func create(_ data: Data?) -> ClashProviderResp {
|
||||
guard let data = data else { return ClashProviderResp() }
|
||||
let decoder = JSONDecoder()
|
||||
decoder.dateDecodingStrategy = .formatted(DateFormatter.js)
|
||||
return (try? decoder.decode(ClashProviderResp.self, from: data)) ?? ClashProviderResp()
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case allProviders = "providers"
|
||||
}
|
||||
}
|
||||
|
||||
class ClashProvider: Codable {
|
||||
enum ProviderType: String, Codable {
|
||||
case Proxy
|
||||
case String
|
||||
}
|
||||
|
||||
enum ProviderVehicleType: String, Codable {
|
||||
case HTTP
|
||||
case File
|
||||
case Compatible
|
||||
case Unknown
|
||||
}
|
||||
|
||||
let name: String
|
||||
let proxies: [ClashProxy]
|
||||
let type: ProviderType
|
||||
let vehicleType: ProviderVehicleType
|
||||
}
|
@ -67,11 +67,12 @@ class ClashProxySpeedHistory: Codable {
|
||||
}
|
||||
|
||||
class ClashProxy: Codable {
|
||||
var name: ClashProxyName = ""
|
||||
let name: ClashProxyName
|
||||
let type: ClashProxyType
|
||||
let all: [ClashProxyName]?
|
||||
let history: [ClashProxySpeedHistory]
|
||||
let now: ClashProxyName?
|
||||
var providerProxy = false
|
||||
weak var enclosingResp: ClashProxyResp? = nil
|
||||
|
||||
lazy var speedtestAble: [ClashProxyName] = {
|
||||
@ -79,14 +80,16 @@ class ClashProxy: Codable {
|
||||
var proxys = [ClashProxyName]()
|
||||
for proxy in allProxys {
|
||||
if let p = resp.proxiesMap[proxy], !ClashProxyType.isProxyGroup(p) {
|
||||
proxys.append(proxy)
|
||||
if !p.providerProxy {
|
||||
proxys.append(proxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
return proxys
|
||||
}()
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type, all, history, now
|
||||
case type, all, history, now, name
|
||||
}
|
||||
|
||||
lazy var maxProxyName: String = {
|
||||
@ -105,7 +108,7 @@ class ClashProxy: Codable {
|
||||
|
||||
class ClashProxyResp {
|
||||
let proxies: [ClashProxy]
|
||||
let proxiesMap: [ClashProxyName: ClashProxy]
|
||||
var proxiesMap: [ClashProxyName: ClashProxy]
|
||||
|
||||
init(_ data: Any?) {
|
||||
guard
|
||||
@ -122,18 +125,14 @@ class ClashProxyResp {
|
||||
var proxiesMap = [ClashProxyName: ClashProxy]()
|
||||
|
||||
let decoder = JSONDecoder()
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.locale = Locale(identifier: NSCalendar.Identifier.ISO8601.rawValue)
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SZ"
|
||||
decoder.dateDecodingStrategy = .formatted(dateFormatter)
|
||||
for (key, value) in proxies {
|
||||
decoder.dateDecodingStrategy = .formatted(DateFormatter.js)
|
||||
for value in proxies.values {
|
||||
guard let data = try? JSONSerialization.data(withJSONObject: value, options: .prettyPrinted) else {
|
||||
continue
|
||||
}
|
||||
guard let proxy = try? decoder.decode(ClashProxy.self, from: data) else {
|
||||
continue
|
||||
}
|
||||
proxy.name = key
|
||||
proxiesModel.append(proxy)
|
||||
proxiesMap[proxy.name] = proxy
|
||||
}
|
||||
@ -145,6 +144,15 @@ class ClashProxyResp {
|
||||
}
|
||||
}
|
||||
|
||||
func updateProvider(_ providerResp: ClashProviderResp) {
|
||||
for provider in providerResp.providers.values {
|
||||
for proxy in provider.proxies {
|
||||
proxy.providerProxy = true
|
||||
proxiesMap[proxy.name] = proxy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy var proxiesSortMap: [ClashProxyName: Int] = {
|
||||
var map = [ClashProxyName: Int]()
|
||||
for (idx, proxy) in (self.proxiesMap["GLOBAL"]?.all ?? []).enumerated() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
module github.com/yichengchen/clashX/ClashX
|
||||
|
||||
require (
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191212162924-0822b526d5d8
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191214101333-eae06a4a7d3e
|
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
|
||||
)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191212162924-0822b526d5d8 h1:GeVCWlqa0YfzWDFAzTRKfhGqL8WolYmY5fHDY1xwUfI=
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191212162924-0822b526d5d8/go.mod h1:3AN6ikXSGG+ZHpQQMirTGu8t3tokzyLU/NUXb5QYZ9Q=
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191214101333-eae06a4a7d3e h1:W3sFYmxO8s77tkcLnHQTrVmhWZXohOrEU1Bvxb+HgoE=
|
||||
github.com/Dreamacro/clash v0.16.1-0.20191214101333-eae06a4a7d3e/go.mod h1:3AN6ikXSGG+ZHpQQMirTGu8t3tokzyLU/NUXb5QYZ9Q=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.5 h1:BizWSjmwzAyQoslz6YhJYMiAGT99j9cnm9zlxVr+kyI=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.5/go.mod h1:LSXCjyHesPY3pLjhwff1mQX72ItcBT/N2xNC685cYeU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
Loading…
Reference in New Issue
Block a user