// // SearchProvider.swift // App // // Created by James Magahern on 3/9/21. // import Foundation class SearchProvider { // Build a provider from a URL template. Template should contain %q or %s // which will be replaced with the sanitized query string. static func fromTemplate(_ template: String) -> SearchProvider { SearchProvider(resolver: { query in let sanitized = query.sanitized() let replaced = template .replacingOccurrences(of: "%q", with: sanitized) .replacingOccurrences(of: "%s", with: sanitized) return URL(string: replaced) ?? URL(string: "https://google.com/search?q=\(sanitized)&gbv=1")! }) } static let google = SearchProvider(resolver: { query in // gbv=1: no JS URL(string: "https://google.com/search?q=\(query.sanitized())&gbv=1")! }) static let duckduckgo = SearchProvider(resolver: { query in // html version is the one without JS URL(string: "https://html.duckduckgo.com/html/?q=\(query.sanitized())")! }) static let searxnor = SearchProvider(resolver: { query in URL(string: "http://searx.nor/search?q=\(query.sanitized())&categories=general")! }) static let whoogle = SearchProvider(resolver: { query in URL(string: "http://whoogle.nor/search?q=\(query.sanitized())")! }) func searchURLWithQuery(_ query: String) -> URL { return resolver(query) } internal let resolver: (String) -> URL internal init(resolver: @escaping (String) -> URL) { self.resolver = resolver } } fileprivate extension String { func sanitized() -> String { self .replacingOccurrences(of: " ", with: "+") .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! } }