Caps-iOS/CapCollector/Data/Upload.swift
2020-05-16 11:21:55 +02:00

181 lines
6.3 KiB
Swift

//
// 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<Int>("cap")
let rowCapVersion = Expression<Int>("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 { }