MediaUploader.swift (3428B)
1 // 2 // MediaUploader.swift 3 // damus 4 // 5 // Created by Daniel D’Aquino on 2023-11-24. 6 // 7 8 import Foundation 9 10 protocol MediaUploaderProtocol: Identifiable { 11 var nameParam: String { get } 12 var mediaTypeParam: String { get } 13 var supportsVideo: Bool { get } 14 var requiresNip98: Bool { get } 15 var postAPI: String { get } 16 17 func getMediaURL(from data: Data) -> String? 18 func mediaTypeValue(for mediaType: ImageUploadMediaType) -> String? 19 } 20 21 enum MediaUploader: String, CaseIterable, MediaUploaderProtocol, StringCodable { 22 var id: String { self.rawValue } 23 case nostrBuild 24 case nostrcheck 25 26 init?(from string: String) { 27 guard let mu = MediaUploader(rawValue: string) else { 28 return nil 29 } 30 31 self = mu 32 } 33 34 func to_string() -> String { 35 return rawValue 36 } 37 38 var nameParam: String { 39 switch self { 40 case .nostrBuild: 41 return "\"fileToUpload\"" 42 default: 43 return "\"file\"" 44 } 45 } 46 47 var mediaTypeParam: String { 48 return "media_type" 49 } 50 51 func mediaTypeValue(for mediaType: ImageUploadMediaType) -> String? { 52 switch mediaType { 53 case .normal: 54 return nil 55 case .profile_picture: 56 return "avatar" 57 } 58 } 59 60 var supportsVideo: Bool { 61 switch self { 62 case .nostrBuild: 63 return true 64 case .nostrcheck: 65 return true 66 } 67 } 68 69 var requiresNip98: Bool { 70 switch self { 71 case .nostrBuild: 72 return true 73 case .nostrcheck: 74 return true 75 } 76 } 77 78 struct Model: Identifiable, Hashable { 79 var id: String { self.tag } 80 var index: Int 81 var tag: String 82 var displayName : String 83 } 84 85 var model: Model { 86 switch self { 87 case .nostrBuild: 88 return .init(index: -1, tag: "nostrBuild", displayName: "nostr.build") 89 case .nostrcheck: 90 return .init(index: 0, tag: "nostrcheck", displayName: "nostrcheck.me") 91 } 92 } 93 94 var postAPI: String { 95 switch self { 96 case .nostrBuild: 97 return "https://nostr.build/api/v2/nip96/upload" 98 case .nostrcheck: 99 return "https://nostrcheck.me/api/v2/media" 100 } 101 } 102 103 func getMediaURL(from data: Data) -> String? { 104 do { 105 if let jsonObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any], 106 let status = jsonObject["status"] as? String { 107 108 if status == "success", let nip94Event = jsonObject["nip94_event"] as? [String: Any] { 109 110 if let tags = nip94Event["tags"] as? [[String]] { 111 for tagArray in tags { 112 if tagArray.count > 1, tagArray[0] == "url" { 113 return tagArray[1] 114 } 115 } 116 } 117 } else if status == "error", let message = jsonObject["message"] as? String { 118 print("Upload Error: \(message)") 119 return nil 120 } 121 } 122 } catch { 123 print("Failed JSONSerialization") 124 return nil 125 } 126 return nil 127 } 128 }