225 lines
7.6 KiB
Swift
Executable File
225 lines
7.6 KiB
Swift
Executable File
import Foundation
|
|
|
|
@objc
|
|
class Plugin: NSObject, THOPluginProtocol {
|
|
var apikey = ""
|
|
var theClient:IRCClient? = nil
|
|
var currentAlbum = ""
|
|
var uploadQueue:[URL] = []
|
|
var isUploading = false
|
|
|
|
var task:URLSessionDataTask?
|
|
|
|
@objc
|
|
let subscribedUserInputCommands = ["arxiuskey", "upload", "cancel"]
|
|
|
|
@objc func pluginLoadedIntoMemory() {
|
|
if (apikey.count < 1) {
|
|
if let key = TPCPreferencesUserDefaults.shared().value(forKey: "arxiusAPIKey") {
|
|
apikey = key as! String
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func userInputCommandInvoked(on client: IRCClient, command commandString: String, messageString: String) {
|
|
theClient = client
|
|
|
|
performBlock(onMainThread: {
|
|
switch commandString {
|
|
case "ARXIUSKEY":
|
|
if (messageString.count == 32) {
|
|
apikey = messageString
|
|
TPCPreferencesUserDefaults.shared().setValue(apikey, forKey: "arxiusAPIKey")
|
|
debug("Your API key is set")
|
|
}
|
|
else if (messageString.count == 0 && apikey.count > 0) {
|
|
apikey = ""
|
|
TPCPreferencesUserDefaults.shared().removeObject(forKey: "arxiusAPIKey")
|
|
debug("Your API key is unset")
|
|
}
|
|
else if (messageString.count == 0) {
|
|
debug("Enter your API key like this: /arxiuskey abcd1234abcd1234abcd1234abcd1234")
|
|
}
|
|
else {
|
|
debug("That's not a valid API key")
|
|
}
|
|
|
|
case "UPLOAD":
|
|
let dialog = NSOpenPanel();
|
|
|
|
dialog.title = "Select files to upload";
|
|
dialog.showsResizeIndicator = true;
|
|
dialog.showsHiddenFiles = false;
|
|
dialog.canChooseDirectories = false;
|
|
dialog.canCreateDirectories = true;
|
|
dialog.allowsMultipleSelection = true;
|
|
|
|
if (dialog.runModal() == NSApplication.ModalResponse.OK) {
|
|
let files = dialog.urls
|
|
|
|
if (files.count > 0) {
|
|
for file in files {
|
|
let path = file.absoluteURL
|
|
uploadQueue.append(path)
|
|
}
|
|
|
|
makeAlbumIfNeeded()
|
|
}
|
|
}
|
|
|
|
case "CANCEL":
|
|
task?.cancel()
|
|
uploadQueue = []
|
|
debug("Upload cancelled")
|
|
|
|
break
|
|
|
|
default:
|
|
break
|
|
}
|
|
})
|
|
}
|
|
|
|
func debug(_ message: Any) {
|
|
self.theClient!.printDebugInformation("\u{02}[Arxius]\u{02} \(message)", in: self.theClient!.lastSelectedChannel!)
|
|
}
|
|
|
|
func startUploading() {
|
|
uploadFiles()
|
|
}
|
|
|
|
func uploadFiles() {
|
|
if (uploadQueue.count > 0) {
|
|
upload()
|
|
}
|
|
else {
|
|
currentAlbum = ""
|
|
}
|
|
}
|
|
|
|
func upload() {
|
|
let file = uploadQueue[0]
|
|
uploadQueue.remove(at: 0)
|
|
|
|
let url = URL(string: "https://arxius.io/")!
|
|
var request = URLRequest(url: url)
|
|
request.httpMethod = "POST"
|
|
var parameters: [String:String] = [:]
|
|
|
|
if (apikey.count > 0) {
|
|
parameters["apikey"] = apikey
|
|
}
|
|
|
|
if (currentAlbum.count > 0) {
|
|
parameters["album"] = currentAlbum
|
|
}
|
|
|
|
var last = false
|
|
if (uploadQueue.count < 1) {
|
|
last = true
|
|
parameters["last"] = "true"
|
|
}
|
|
|
|
let boundary = "Boundary-\(UUID().uuidString)"
|
|
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
|
|
|
do {
|
|
let fileData = try Data(contentsOf: file)
|
|
|
|
request.httpBody = createBody(parameters: parameters, boundary: boundary, data: fileData, mimeType: "application/octet-stream", filename: file.lastPathComponent)
|
|
|
|
task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
guard let data = data, let response = response as? HTTPURLResponse, error == nil else {
|
|
return
|
|
}
|
|
|
|
guard (200 ... 299) ~= response.statusCode else {
|
|
return
|
|
}
|
|
|
|
if (last) {
|
|
if let link = String(data: data, encoding: .utf8) {
|
|
self.debug("Upload complete: \(link)")
|
|
}
|
|
}
|
|
}
|
|
task!.resume()
|
|
|
|
debug("Uploading: \(file.path)")
|
|
|
|
uploadFiles()
|
|
}
|
|
catch {}
|
|
}
|
|
|
|
func makeAlbumIfNeeded() {
|
|
if (uploadQueue.count > 1) {
|
|
let url = URL(string: "https://arxius.io/api/create/album")!
|
|
var request = URLRequest(url: url)
|
|
request.httpMethod = "POST"
|
|
var parameters: [String:String] = [:]
|
|
|
|
if (apikey.count > 0) {
|
|
parameters["apikey"] = apikey
|
|
}
|
|
|
|
request.httpBody = parameters.percentEscaped().data(using: .utf8)
|
|
|
|
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
guard let data = data, let response = response as? HTTPURLResponse, error == nil else {
|
|
return
|
|
}
|
|
|
|
guard (200 ... 299) ~= response.statusCode else {
|
|
return
|
|
}
|
|
|
|
do {
|
|
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
|
|
|
|
if (json.index(forKey: "album") != nil) {
|
|
let album = json["album"] as! String
|
|
self.currentAlbum = album
|
|
self.debug("Created album: \(album)")
|
|
|
|
self.startUploading()
|
|
}
|
|
else {
|
|
self.debug("Error creating album")
|
|
}
|
|
} catch {}
|
|
}
|
|
task.resume()
|
|
}
|
|
else {
|
|
self.startUploading()
|
|
}
|
|
}
|
|
|
|
func createBody(parameters: [String: String],
|
|
boundary: String,
|
|
data: Data,
|
|
mimeType: String,
|
|
filename: String) -> Data {
|
|
let body = NSMutableData()
|
|
|
|
let boundaryPrefix = "--\(boundary)\r\n"
|
|
|
|
for (key, value) in parameters {
|
|
body.appendString(boundaryPrefix)
|
|
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
|
|
body.appendString("\(value)\r\n")
|
|
}
|
|
|
|
body.appendString(boundaryPrefix)
|
|
body.appendString("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
|
|
body.appendString("Content-Type: \(mimeType)\r\n\r\n")
|
|
body.append(data)
|
|
body.appendString("\r\n")
|
|
body.appendString("--".appending(boundary.appending("--")))
|
|
|
|
return body as Data
|
|
}
|
|
}
|