import Foundation struct DanbooruPost: Decodable { let id: Int let createdAt: Date let uploaderId: Int let score: Int let source: String let md5: String let rating: String let imageWidth: Int let imageHeight: Int let tagString: String let parentId: Int? let mediaAsset: DanbooruMediaAsset let fileURL: String let largeFileURL: String let previewFileURL: String let isDeleted: Bool enum CodingKeys: String, CodingKey { case id = "id" case createdAt = "created_at" case uploaderId = "uploader_id" case score = "score" case source = "source" case md5 = "md5" case rating = "rating" case imageWidth = "image_width" case imageHeight = "image_height" case tagString = "tag_string" case parentId = "parent_id" case mediaAsset = "media_asset" case fileURL = "file_url" case largeFileURL = "large_file_url" case previewFileURL = "preview_file_url" case isDeleted = "is_deleted" } func toBooruPost() -> BooruPost? { guard let fileURL = URL(string: fileURL), let sampleURL = URL(string: largeFileURL), let previewURL = URL(string: previewFileURL) else { return nil } let previewVariant = mediaAsset.variants.first { $0.type == "180x180" } let sampleVariant = mediaAsset.variants.first { $0.type == "sample" } ?? mediaAsset.variants.first { $0.type == "original" } return BooruPost( id: String(id), height: imageHeight, score: String(score), fileURL: fileURL, parentID: parentId != nil ? String(parentId!) : "", sampleURL: sampleURL, sampleWidth: sampleVariant?.width ?? imageWidth, sampleHeight: sampleVariant?.height ?? imageHeight, previewURL: previewURL, rating: BooruRating(rating), tags: tagString.components(separatedBy: " ").filter { !$0.isEmpty }, width: imageWidth, change: nil, md5: md5, creatorID: String(uploaderId), authorID: nil, createdAt: createdAt, status: isDeleted ? "deleted" : "active", source: source, previewWidth: previewVariant?.width ?? 180, previewHeight: previewVariant?.height ?? 180 ) } }