Skip to content
Snippets Groups Projects
Verified Commit 84d64754 authored by Spotlight Deveaux's avatar Spotlight Deveaux :fox:
Browse files

Use Alamofire

parent 1502bff4
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ target 'Screenshottr' do
# Pods for Screenshottr
pod 'UTIKit'
pod 'SKQueue', :git => 'https://owo.codes/Screenshottr/SKQueue'
pod 'Alamofire', '~> 4.7'
target 'ScreenshottrTests' do
inherit! :search_paths
......
......@@ -334,11 +334,13 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Screenshottr/Pods-Screenshottr-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
"${BUILT_PRODUCTS_DIR}/SKQueue/SKQueue.framework",
"${BUILT_PRODUCTS_DIR}/UTIKit/UTIKit.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SKQueue.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UTIKit.framework",
);
......
......@@ -16,10 +16,13 @@ class AppDelegate: NSObject, NSApplicationDelegate {
let popover = NSPopover()
let viewController = PopoverMenu(nibName: "PopoverMenu",
bundle: Bundle.main)
let statusIcon = NSImage(named: "status_icon")
var spinnerView = NSView()
let spinner = NSProgressIndicator()
func applicationDidFinishLaunching(_ aNotification: Notification) {
statusItem.image = NSImage(named: "status_icon")
statusItem.action = #selector(togglePopover)
statusItem.button!.image = statusIcon
statusItem.button!.action = #selector(togglePopover)
popover.contentViewController = viewController
popover.behavior = .transient
......@@ -27,6 +30,28 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// Set up file watching
let queue = SKQueue(delegate: UploadReceiver())
queue?.addPath(NSSearchPathForDirectoriesInDomains(.desktopDirectory, .userDomainMask, true)[0], notifyingAbout: .Write)
// Create spinner view for progress purposes
spinnerView = NSView(frame: statusItem.button!.frame)
spinner.isIndeterminate = false
spinner.style = .bar
spinnerView.addSubview(spinner)
spinner.sizeToFit()
}
func setProgress(progress: Double) {
spinner.doubleValue = progress
print("Currently at \(progress)")
// Take a faux image in order to set as a status bar item.
// https://stackoverflow.com/a/30147199/3874884
let dataOfView = spinnerView.dataWithPDF(inside: spinnerView.bounds)
let imageOfView = NSImage(data: dataOfView)
statusItem.button!.image = imageOfView
}
func resetIndicator() {
spinner.doubleValue = 0.0
statusItem.image = statusIcon
}
@objc func quitApplication() {
......
......@@ -9,125 +9,73 @@
import Foundation
import UTIKit
import Alamofire
class PomfManager {
func uploadFile(path: String, completionHandler: @escaping (_ : NSError?, _ : String) -> Void) {
func uploadFile(pathToFile: String, completionHandler: @escaping (_ : Error?, _ : String) -> Void) {
let defaults = UserDefaults.standard
let uploadPath = defaults.string(forKey: "pomfUploadPath")
if uploadPath == nil {
// Gotta alert the user
// Alert the user they're not configured.
let userInfo: [AnyHashable : Any] = [
NSLocalizedDescriptionKey : NSLocalizedString("Unsuccessful", value: "Go to Settings and enter a Pomf upload url.", comment: "") ,
NSLocalizedFailureReasonErrorKey : NSLocalizedString("Unsuccessful", value: "Go to Settings and enter a Pomf upload url.", comment: "")
]
completionHandler(NSError(domain: "pomf.error.ufukdup.yourcodesucks.nopermission.getatoken.slideinto.deans.dms", code: 666420, userInfo: userInfo as? [String : Any]), "https://google.com")
]
completionHandler(NSError(domain: "PomfErrorDomain", code: 1, userInfo: userInfo as? [String : Any]), "https://google.com")
return
}
let request = NSMutableURLRequest(url: URL(string: uploadPath!)!)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
let bodyData : Data?
do {
bodyData = try createBody(path: path, boundary: boundary)
} catch let error as NSError {
completionHandler(error, "https://google.com/")
return
}
request.httpBody = bodyData ?? "".data(using: .utf8)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request as URLRequest) {
data,response,error in
if error != nil{
print(error?.localizedDescription ?? "topkek")
return
}
do {
let parsedData = try JSONSerialization.jsonObject(with: data!) as! NSDictionary
let status : Bool = parsedData["success"] as! Bool
if (status == false) {
let description : String = parsedData["description"] as! String
let userInfo: [AnyHashable : Any] = [
NSLocalizedDescriptionKey : NSLocalizedString("Unsuccessful", value: description, comment: "") ,
NSLocalizedFailureReasonErrorKey : NSLocalizedString("Unsuccessful", value: description, comment: "")
]
let errorCode : Int = parsedData["errorcode"] as! Int
completionHandler(NSError(domain: "PomfErrorDomain", code: errorCode, userInfo: userInfo as? [String : Any]), "https://google.com")
return
// Create a POST request
let fileToUpload = URL(fileURLWithPath: pathToFile)
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(fileToUpload, withName: "files[]")
},
to: uploadPath!,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
DispatchQueue.global().async(execute: {
DispatchQueue.main.sync{
AppDelegate().setProgress(progress: progress.fractionCompleted)
}
})
}
upload.responseJSON { response in
// Parse JSON from the server.
// However, before parsing, set the original image
DispatchQueue.main.async {
AppDelegate().resetIndicator()
}
if let parsedData : NSDictionary = response.result.value as? NSDictionary {
let status : Bool = parsedData["success"] as! Bool
if (status == false) {
let description : String = parsedData["description"] as! String
let userInfo: [AnyHashable : Any] = [
NSLocalizedDescriptionKey : NSLocalizedString("Unsuccessful", value: description, comment: "") ,
NSLocalizedFailureReasonErrorKey : NSLocalizedString("Unsuccessful", value: description, comment: "")
]
let errorCode : Int = parsedData["errorcode"] as! Int
completionHandler(NSError(domain: "PomfErrorDomain", code: errorCode, userInfo: userInfo as? [String : Any]), "https://google.com")
return
}
// Attempt to get information returned over the uploaded file.
let test : [NSDictionary] = parsedData["files"] as! [NSDictionary]
let furtherTest : NSDictionary = test[0]
// https://discord.coffee/c58cec.png
let fileName = furtherTest.object(forKey: "url") as! String? ?? "c58cec.png"
completionHandler(nil, "\(defaults.string(forKey: "pomfBaseDomain")!)/\(fileName)" )
}
}
case .failure(let encodingError):
print(encodingError)
completionHandler(encodingError, "https://google.com/")
}
let test : [NSDictionary] = parsedData["files"] as! [NSDictionary]
let furtherTest : NSDictionary = test[0]
// https://spotlight-thinks-awoo.should-be.legal/c58cec.png
let fileName = furtherTest.object(forKey: "url") as! String? ?? "c58cec.png"
completionHandler(nil, "\(defaults.string(forKey: "pomfBaseDomain")!)/\(fileName)" )
} catch let error as NSError {
print(error)
completionHandler(error, "https://google.com/")
return
}
}.resume()
}
func createBody(path: String, boundary: String) throws -> Data {
let url = URL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
let mimetype = UTI(filenameExtension: url.pathExtension)?.mimeType ?? "application/octet-stream"
let boundaryStart = "--\(boundary)\r\n"
let boundaryEnd = "--\(boundary)--\r\n"
let contentDispositionString = "Content-Disposition: form-data; name=\"files[]\"; filename=\"\(filename)\"\r\n"
let contentTypeString = "Content-Type: \(mimetype)\r\n\r\n"
// Prepare the HTTPBody for the request.
let requestBodyData : NSMutableData = NSMutableData()
requestBodyData.append(boundaryStart.data(using: String.Encoding.utf8)!)
requestBodyData.append(contentDispositionString.data(using: String.Encoding.utf8)!)
requestBodyData.append(contentTypeString.data(using: String.Encoding.utf8)!)
requestBodyData.append(data)
requestBodyData.append("\r\n".data(using: String.Encoding.utf8)!)
requestBodyData.append(boundaryEnd.data(using: String.Encoding.utf8)!)
return requestBodyData as Data
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
}
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
extension Data {
/// Append string to NSMutableData
///
/// Rather than littering my code with calls to `dataUsingEncoding` to convert strings to NSData, and then add that data to the NSMutableData, this wraps it in a nice convenient little extension to NSMutableData. This converts using UTF-8.
///
/// - parameter string: The string to be added to the `NSMutableData`.
mutating func append(_ string: String) {
if let data = string.data(using: .utf8) {
append(data)
}
}
/// Create hexadecimal string representation of `Data` object.
///
/// - returns: `String` representation of this `Data` object.
func hexadecimal() -> String {
return map { String(format: "%02x", $0) }
.joined(separator: "")
)
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="15G19009" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.13.2"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
......
......@@ -51,8 +51,7 @@ class UploadManager : NSObject {
uploadFrom(path: screenshot.path, shouldDelete: true)
}
defaults.set(false, forKey: uploadingKey)
} catch let error as NSError {
print("Ooops! Something went wrong: \(error.localizedDescription)")
} catch let error {
showFailureNotification(errorText: error.localizedDescription)
defaults.set(false, forKey: uploadingKey)
}
......@@ -63,12 +62,12 @@ class UploadManager : NSObject {
}
func uploadFrom(path: String, shouldDelete: Bool) {
PomfManager().uploadFile(path: path) { (error, url) in
PomfManager().uploadFile(pathToFile: path) { (error, url) in
self.finalizeUpload(path: path, error: error, url: url, shouldDelete: shouldDelete) {}
}
}
func finalizeUpload(path: String, error: NSError?, url: String, shouldDelete: Bool, handler: () -> Void) {
func finalizeUpload(path: String, error: Error?, url: String, shouldDelete: Bool, handler: () -> Void) {
if (error != nil) {
self.showFailureNotification(errorText: error!.localizedDescription)
handler()
......@@ -99,6 +98,8 @@ class UploadManager : NSObject {
// We leave this as its own function for usage in failures in other areas.
func showFailureNotification(errorText: String) {
print(errorText)
let notification = NSUserNotification()
notification.title = "Screenshot machine 🅱roke."
notification.informativeText = errorText
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment