// // Upload.swift // CapCollector // // Created by Christoph on 26.04.20. // Copyright © 2020 CH. All rights reserved. // import Foundation import UIKit import SQLite struct Upload { let serverUrl: URL let table = Table("uploads") let rowCapId = Expression("cap") let rowCapVersion = Expression("version") init(server: URL) { self.serverUrl = server } // MARK: Paths var serverImageUrl: URL { serverUrl.appendingPathComponent("images") } private func serverImageUrl(for cap: Int, version: Int = 0) -> URL { serverImageUrl.appendingPathComponent("\(cap)/\(cap)-\(version).jpg") } private func serverImageUploadUrl(for cap: Int) -> URL { serverImageUrl.appendingPathComponent("\(cap)") } private func serverNameUploadUrl(for cap: Int) -> URL { serverUrl.appendingPathComponent("name/\(cap)") } private func serverChangeMainImageUrl(for cap: Int, to newValue: Int) -> URL { serverUrl.appendingPathComponent("switch/\(cap)/\(newValue)") } // MARK: SQLite var createQuery: String { table.create(ifNotExists: true) { t in t.column(rowCapId) t.column(rowCapVersion) } } func insertQuery(for cap: Int, version: Int) -> Insert { table.insert(rowCapId <- cap, rowCapVersion <- version) } func deleteQuery(for cap: Int, version: Int) -> Delete { table.filter(rowCapId == cap && rowCapVersion == version).delete() } // MARK: Uploading data func upload(name: String, for cap: Int, completion: @escaping (_ success: Bool) -> Void) { var request = URLRequest(url: serverNameUploadUrl(for: cap)) request.httpMethod = "POST" request.httpBody = name.data(using: .utf8) let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { self.log("Failed to upload name of cap \(cap): \(error)") completion(false) return } guard let response = response else { self.log("Failed to upload name of cap \(cap): No response") completion(false) return } guard let urlResponse = response as? HTTPURLResponse else { self.log("Failed to upload name of cap \(cap): \(response)") completion(false) return } guard urlResponse.statusCode == 200 else { self.log("Failed to upload name of cap \(cap): Response \(urlResponse.statusCode)") completion(false) return } } task.resume() } func uploadImage(for cap: Int, version: Int, completion: @escaping (_ count: Int?) -> Void) { guard let url = app.storage.existingImageUrl(for: cap, version: version) else { completion(nil) return } var request = URLRequest(url: serverImageUploadUrl(for: cap)) request.httpMethod = "POST" let task = URLSession.shared.uploadTask(with: request, fromFile: url) { data, response, error in if let error = error { self.log("Failed to upload image \(version) of cap \(cap): \(error)") completion(nil) return } guard let response = response else { self.log("Failed to upload image \(version) of cap \(cap): No response") completion(nil) return } guard let urlResponse = response as? HTTPURLResponse else { self.log("Failed to upload image \(version) of cap \(cap): \(response)") completion(nil) return } guard urlResponse.statusCode == 200 else { self.log("Failed to upload image \(version) of cap \(cap): Response \(urlResponse.statusCode)") completion(nil) return } guard let d = data, let string = String(data: d, encoding: .utf8), let int = Int(string) else { self.log("Failed to upload image \(version) of cap \(cap): Invalid response") completion(nil) return } completion(int) } task.resume() } /** Sets the main image for a cap to a different version. - Parameter cap: The id of the cap - Parameter version: The version to set as the main version. - Parameter completion: A callback with the new average color on completion. */ func setMainImage(for cap: Int, to version: Int, completion: @escaping (_ averageColor: UIColor?) -> Void) { guard let averageColor = app.storage.averageColor(for: cap, version: version) else { completion(nil) return } let url = serverChangeMainImageUrl(for: cap, to: version) var request = URLRequest(url: url) let averageRGB = averageColor.rgb request.addValue("\(averageRGB.red)", forHTTPHeaderField: "r") request.addValue("\(averageRGB.green)", forHTTPHeaderField: "g") request.addValue("\(averageRGB.blue)", forHTTPHeaderField: "b") let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { self.log("Failed to set main image of cap \(cap) to \(version): \(error)") completion(nil) return } guard let response = response else { self.log("Failed to set main image of cap \(cap) to \(version): No response") completion(nil) return } guard let urlResponse = response as? HTTPURLResponse else { self.log("Failed to set main image of cap \(cap) to \(version): \(response)") completion(nil) return } guard urlResponse.statusCode == 200 else { self.log("Failed to set main image of cap \(cap) to \(version): Response \(urlResponse.statusCode)") completion(nil) return } completion(averageColor) } task.resume() } } extension Upload: Logger { }