181 lines
6.3 KiB
Swift
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 { }
|