This commit is contained in:
nielsandriesse 2020-06-02 12:02:54 +10:00
parent 6d3ca84f48
commit fe4aeddd27
6 changed files with 75 additions and 36 deletions

View File

@ -634,7 +634,8 @@
C35E8AA32485C72300ACB629 /* SwiftCSV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C35E8AA22485C72300ACB629 /* SwiftCSV.framework */; };
C35E8AA82485C85800ACB629 /* GeoLite2-Country-Locations-English.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */; };
C35E8AA92485C85800ACB629 /* GeoLite2-Country-Blocks-IPv4.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */; };
C35E8AAC2485D1FE00ACB629 /* CSVUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAB2485D1FE00ACB629 /* CSVUtilities.swift */; };
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; };
C35E8AB02485E86A00ACB629 /* GeneralUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */; };
C36B8707243C50C60049991D /* SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 453518921FC63DBF00210559 /* SignalMessaging.framework */; };
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; };
C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; };
@ -1517,7 +1518,8 @@
C35E8AA22485C72300ACB629 /* SwiftCSV.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCSV.framework; path = ThirdParty/Carthage/Build/iOS/SwiftCSV.framework; sourceTree = "<group>"; };
C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Locations-English.csv"; sourceTree = "<group>"; };
C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Blocks-IPv4.csv"; sourceTree = "<group>"; };
C35E8AAB2485D1FE00ACB629 /* CSVUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSVUtilities.swift; sourceTree = "<group>"; };
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IP2Country.swift; sourceTree = "<group>"; };
C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralUtilities.swift; sourceTree = "<group>"; };
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; };
C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionSheet.swift; sourceTree = "<group>"; };
@ -2908,7 +2910,8 @@
children = (
B8544E3223D50E4900299F14 /* AppearanceUtilities.swift */,
C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */,
C35E8AAB2485D1FE00ACB629 /* CSVUtilities.swift */,
C35E8AAF2485E86A00ACB629 /* GeneralUtilities.swift */,
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */,
B84664F4235022F30083A1CD /* MentionUtilities.swift */,
B886B4A82398BA1500211ABE /* QRCode.swift */,
B8783E9D23EB948D00404FB8 /* UILabel+Interaction.swift */,
@ -4211,7 +4214,6 @@
45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */,
4539B5861F79348F007141FF /* PushRegistrationManager.swift in Sources */,
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */,
C35E8AAC2485D1FE00ACB629 /* CSVUtilities.swift in Sources */,
B8B26C91234D8CBD004ED98C /* MentionCandidateSelectionViewDelegate.swift in Sources */,
340FC8BB204DAC8D007AEB0F /* OWSAddToContactViewController.m in Sources */,
45F32C232057297A00A300D5 /* MediaPageViewController.swift in Sources */,
@ -4249,6 +4251,7 @@
34D1F0831F8678AA0066283D /* ConversationInputTextView.m in Sources */,
340FC8B6204DAC8D007AEB0F /* OWSQRCodeScanningViewController.m in Sources */,
4CB5F26920F7D060004D1B42 /* MessageActions.swift in Sources */,
C35E8AB02485E86A00ACB629 /* GeneralUtilities.swift in Sources */,
340FC8B5204DAC8D007AEB0F /* AboutTableViewController.m in Sources */,
34BECE2B1F74C12700D7438D /* DebugUIStress.m in Sources */,
340FC8B9204DAC8D007AEB0F /* UpdateGroupViewController.m in Sources */,
@ -4263,6 +4266,7 @@
B85357BF23A1AE0800AAF6CD /* SeedReminderView.swift in Sources */,
B85357C723A1FB5100AAF6CD /* LinkDeviceVCDelegate.swift in Sources */,
340FC8C5204DE223007AEB0F /* DebugUIBackup.m in Sources */,
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */,
4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */,
340FC8AE204DAC8D007AEB0F /* OWSSoundSettingsViewController.m in Sources */,
4579431E1E7C8CE9008ED0C0 /* Pastelog.m in Sources */,

View File

@ -1,4 +0,0 @@
import SwiftCSV
@inline(never)
public func preload(_ x: CSV) { }

View File

@ -0,0 +1,3 @@
@inline(never)
public func touch(_ x: Any?) { }

View File

@ -0,0 +1,61 @@
import SwiftCSV
final class IP2Country {
private static let ipv4Table = try! CSV(name: "GeoLite2-Country-Blocks-IPv4", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)!
private static let countryNamesTable = try! CSV(name: "GeoLite2-Country-Locations-English", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)!
private static var countryNamesCache: [String:String] = [:]
// MARK: Lifecycle
static let shared = IP2Country()
private init() {
preloadCountriesIfNeeded()
NotificationCenter.default.addObserver(self, selector: #selector(preloadCountriesIfNeeded), name: .pathsBuilt, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
// MARK: Implementation
static func getCountry(_ ip: String) -> String {
var truncatedIP = ip
func getCountryInternal() -> String {
if let country = countryNamesCache[ip] { return country }
if let ipv4TableIndex = ipv4Table.namedColumns["network"]!.firstIndex(where: { $0.starts(with: truncatedIP) }) {
let countryID = ipv4Table.namedColumns["registered_country_geoname_id"]![ipv4TableIndex]
if let countryNamesTableIndex = countryNamesTable.namedColumns["geoname_id"]!.firstIndex(of: countryID) {
let country = countryNamesTable.namedColumns["country_name"]![countryNamesTableIndex]
countryNamesCache[ip] = country
return country
}
}
if truncatedIP.contains(".") && !truncatedIP.hasSuffix(".") { // The fuzziest we want to go is xxx.x
truncatedIP.removeLast()
if truncatedIP.hasSuffix(".") { truncatedIP.removeLast() }
return getCountryInternal()
} else {
return "Unknown Country"
}
}
return getCountryInternal()
}
@objc private func preloadCountriesIfNeeded() {
DispatchQueue.global(qos: .userInitiated).async {
if OnionRequestAPI.paths.count < OnionRequestAPI.pathCount {
let storage = OWSPrimaryStorage.shared()
storage.dbReadConnection.read { transaction in
OnionRequestAPI.paths = storage.getOnionRequestPaths(in: transaction)
}
}
guard OnionRequestAPI.paths.count >= OnionRequestAPI.pathCount else { return }
let pathToDisplay = OnionRequestAPI.paths.first!
pathToDisplay.forEach { snode in
let _ = IP2Country.getCountry(snode.ip) // Preload if needed
}
print("[Loki] Finished preloading onion request path countries.")
}
}
}

View File

@ -84,10 +84,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
// MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global(qos: .userInitiated).async {
preload(PathVC.ipv4Table)
preload(PathVC.countryNamesTable)
}
touch(IP2Country.shared)
SignalApp.shared().homeViewController = self
setUpGradientBackground()
if navigationController?.navigationBar != nil {

View File

@ -3,10 +3,6 @@ import SwiftCSV
final class PathVC : BaseVC {
static let ipv4Table = try! CSV(name: "GeoLite2-Country-Blocks-IPv4", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)!
static let countryNamesTable = try! CSV(name: "GeoLite2-Country-Locations-English", extension: "csv", bundle: .main, delimiter: ",", encoding: .utf8, loadColumns: true)!
static var countryNamesCache: [String:String] = [:]
// MARK: Components
private lazy var pathStackView: UIStackView = {
let result = UIStackView()
@ -159,27 +155,9 @@ final class PathVC : BaseVC {
}
private func getPathRow(snode: LokiAPITarget, location: LineView.Location, dotAnimationStartDelay: Double, dotAnimationRepeatInterval: Double, isGuardSnode: Bool) -> UIStackView {
var snodeIP = snode.ip
func getCountry() -> String {
if let country = PathVC.countryNamesCache[snode.address] { return country }
if let ipv4TableIndex = PathVC.ipv4Table.namedColumns["network"]!.firstIndex(where: { $0.starts(with: snodeIP) }) {
let countryID = PathVC.ipv4Table.namedColumns["registered_country_geoname_id"]![ipv4TableIndex]
if let countryNamesTableIndex = PathVC.countryNamesTable.namedColumns["geoname_id"]!.firstIndex(of: countryID) {
let country = PathVC.countryNamesTable.namedColumns["country_name"]![countryNamesTableIndex]
PathVC.countryNamesCache[snode.address] = country
return country
}
}
if snodeIP.contains(".") && !snodeIP.hasSuffix(".") { // The fuzziest we want to go is xxx.x
snodeIP.removeLast()
if snodeIP.hasSuffix(".") { snodeIP.removeLast() }
return getCountry()
} else {
return "Unknown Country"
}
}
let country = IP2Country.getCountry(snode.ip)
let title = isGuardSnode ? NSLocalizedString("Guard Node", comment: "") : NSLocalizedString("Service Node", comment: "")
return getPathRow(title: title, subtitle: getCountry(), location: location, dotAnimationStartDelay: dotAnimationStartDelay, dotAnimationRepeatInterval: dotAnimationRepeatInterval)
return getPathRow(title: title, subtitle: country, location: location, dotAnimationStartDelay: dotAnimationStartDelay, dotAnimationRepeatInterval: dotAnimationRepeatInterval)
}
// MARK: Interaction