diff options
| -rw-r--r-- | Sora/Data/Moebooru/MoebooruManager.swift | 2 | ||||
| -rw-r--r-- | Sora/Data/Moebooru/MoebooruPost.swift | 46 | ||||
| -rw-r--r-- | Sora/Data/Moebooru/MoebooruPostXMLParser.swift | 153 |
3 files changed, 168 insertions, 33 deletions
diff --git a/Sora/Data/Moebooru/MoebooruManager.swift b/Sora/Data/Moebooru/MoebooruManager.swift index fd8d337..286a187 100644 --- a/Sora/Data/Moebooru/MoebooruManager.swift +++ b/Sora/Data/Moebooru/MoebooruManager.swift @@ -50,7 +50,7 @@ class MoebooruManager: ObservableObject { if Task.isCancelled { return } DispatchQueue.main.async { - let newPosts = Array(Set(MoebooruPostXMLParser().parse(data: data))).sorted { $0.id > $1.id } + let newPosts = Array(Set(MoebooruPostXMLParser(data: data).parse())).sorted { $0.id > $1.id } if newPosts == [] { self.endOfData = true diff --git a/Sora/Data/Moebooru/MoebooruPost.swift b/Sora/Data/Moebooru/MoebooruPost.swift index df332ec..215da5e 100644 --- a/Sora/Data/Moebooru/MoebooruPost.swift +++ b/Sora/Data/Moebooru/MoebooruPost.swift @@ -1,16 +1,46 @@ import Foundation struct MoebooruPost: Identifiable, Hashable { - let id: Int + let id: String let tags: [String] - let createdAt: Date + let createdAt: Int + let updatedAt: Int + let creatorID: String + let approverID: String let author: String - let source: URL? - let score: Int - let fileURL: URL? - let previewURL: URL? - let sampleURL: URL? - let jpegURL: URL? + let change: String + let source: String + let score: String + let md5: String + let fileSize: Int + let fileExtension: String + let fileURL: URL + let isShownInIndex: Bool + let previewURL: URL + let previewWidth: Int + let previewHeight: Int + let actualPreviewWidth: Int + let actualPreviewHeight: Int + let sampleURL: URL + let sampleWidth: Int + let sampleHeight: Int + let sampleFileSize: Int + let jpegURL: URL + let jpegWidth: Int + let jpegHeight: Int + let jpegFileSize: Int + let rating: String + let isRatingLocked: Bool + let hasChildren: Bool + let parentId: String + let status: String + let isPending: Bool let width: Int let height: Int + let isHeld: Bool + let framesPendingString: String + let framesString: String + let isNoteLocked: Bool + let lastNotedAt: Int + let lastCommentedAt: Int } diff --git a/Sora/Data/Moebooru/MoebooruPostXMLParser.swift b/Sora/Data/Moebooru/MoebooruPostXMLParser.swift index 418a9c6..e5a73e9 100644 --- a/Sora/Data/Moebooru/MoebooruPostXMLParser.swift +++ b/Sora/Data/Moebooru/MoebooruPostXMLParser.swift @@ -2,41 +2,146 @@ import Foundation class MoebooruPostXMLParser: NSObject, XMLParserDelegate { private var posts: [MoebooruPost] = [] + private var currentPost: MoebooruPost? + private var parser: XMLParser - func parse(data: Data) -> [MoebooruPost] { - let parser = XMLParser(data: data) + init(data: Data) { + parser = XMLParser(data: data) + + super.init() parser.delegate = self + } + + func parse() -> [MoebooruPost] { parser.parse() return posts } - func parser(_: XMLParser, didStartElement elementName: String, - namespaceURI _: String?, qualifiedName _: String?, - attributes attributeDict: [String: String]) - { - if elementName == "post", - let id = Int(attributeDict["id"] ?? ""), - let createdAtTimestamp = TimeInterval(attributeDict["created_at"] ?? ""), - let score = Int(attributeDict["score"] ?? ""), - let width = Int(attributeDict["width"] ?? ""), - let height = Int(attributeDict["height"] ?? "") - { - posts.append(MoebooruPost( + func parser(_: XMLParser, didStartElement elementName: String, namespaceURI _: String?, qualifiedName _: String?, attributes attributeDict: [String: String] = [:]) { + if elementName == "post" { + guard let id = attributeDict["id"], + let tags = attributeDict["tags"], + let createdAtStr = attributeDict["created_at"], + let createdAt = Int(createdAtStr), + let updatedAtStr = attributeDict["updated_at"], + let updatedAt = Int(updatedAtStr), + let creatorId = attributeDict["creator_id"], + let approverId = attributeDict["approver_id"], + let author = attributeDict["author"], + let change = attributeDict["change"], + let source = attributeDict["source"], + let score = attributeDict["score"], + let md5 = attributeDict["md5"], + let fileSizeStr = attributeDict["file_size"], + let fileSize = Int(fileSizeStr), + let fileExt = attributeDict["file_ext"], + let fileUrl = attributeDict["file_url"], + let isShownStr = attributeDict["is_shown_in_index"], + let previewUrl = attributeDict["preview_url"], + let previewWidthStr = attributeDict["preview_width"], + let previewWidth = Int(previewWidthStr), + let previewHeightStr = attributeDict["preview_height"], + let previewHeight = Int(previewHeightStr), + let actualPreviewWidthStr = attributeDict["actual_preview_width"], + let actualPreviewWidth = Int(actualPreviewWidthStr), + let actualPreviewHeightStr = attributeDict["actual_preview_height"], + let actualPreviewHeight = Int(actualPreviewHeightStr), + let sampleUrl = attributeDict["sample_url"], + let sampleWidthStr = attributeDict["sample_width"], + let sampleWidth = Int(sampleWidthStr), + let sampleHeightStr = attributeDict["sample_height"], + let sampleHeight = Int(sampleHeightStr), + let sampleFileSizeStr = attributeDict["sample_file_size"], + let sampleFileSize = Int(sampleFileSizeStr), + let jpegUrl = attributeDict["jpeg_url"], + let jpegWidthStr = attributeDict["jpeg_width"], + let jpegWidth = Int(jpegWidthStr), + let jpegHeightStr = attributeDict["jpeg_height"], + let jpegHeight = Int(jpegHeightStr), + let jpegFileSizeStr = attributeDict["jpeg_file_size"], + let jpegFileSize = Int(jpegFileSizeStr), + let rating = attributeDict["rating"], + let isRatingLockedStr = attributeDict["is_rating_locked"], + let hasChildrenStr = attributeDict["has_children"], + let parentId = attributeDict["parent_id"], + let status = attributeDict["status"], + let isPendingStr = attributeDict["is_pending"], + let widthStr = attributeDict["width"], + let width = Int(widthStr), + let heightStr = attributeDict["height"], + let height = Int(heightStr), + let isHeldStr = attributeDict["is_held"], + let framesPendingString = attributeDict["frames_pending_string"], + let framesString = attributeDict["frames_string"], + let isNoteLockedStr = attributeDict["is_note_locked"], + let lastNotedAtStr = attributeDict["last_noted_at"], + let lastNotedAt = Int(lastNotedAtStr), + let lastCommentedAtStr = attributeDict["last_commented_at"], + let lastCommentedAt = Int(lastCommentedAtStr) + else { + return + } + + currentPost = MoebooruPost( id: id, - tags: attributeDict["tags"]?.components(separatedBy: " ") ?? [], - createdAt: Date(timeIntervalSince1970: createdAtTimestamp), - author: attributeDict["author"] ?? "", - source: URL(string: attributeDict["source"] ?? ""), + tags: tags.components(separatedBy: " "), + createdAt: createdAt, + updatedAt: updatedAt, + creatorID: creatorId, + approverID: approverId, + author: author, + change: change, + source: source, score: score, - fileURL: URL(string: attributeDict["file_url"] ?? ""), - previewURL: URL(string: attributeDict["preview_url"] ?? ""), - sampleURL: URL(string: attributeDict["sample_url"] ?? ""), - jpegURL: URL(string: attributeDict["jpeg_url"] ?? ""), + md5: md5, + fileSize: fileSize, + fileExtension: fileExt, + fileURL: URL(string: fileUrl)!, + isShownInIndex: isShownStr == "true", + previewURL: URL(string: previewUrl)!, + previewWidth: previewWidth, + previewHeight: previewHeight, + actualPreviewWidth: actualPreviewWidth, + actualPreviewHeight: actualPreviewHeight, + sampleURL: URL(string: sampleUrl)!, + sampleWidth: sampleWidth, + sampleHeight: sampleHeight, + sampleFileSize: sampleFileSize, + jpegURL: URL(string: jpegUrl)!, + jpegWidth: jpegWidth, + jpegHeight: jpegHeight, + jpegFileSize: jpegFileSize, + rating: rating, + isRatingLocked: isRatingLockedStr == "true", + hasChildren: hasChildrenStr == "true", + parentId: parentId, + status: status, + isPending: isPendingStr == "true", width: width, - height: height - )) + height: height, + isHeld: isHeldStr == "true", + framesPendingString: framesPendingString, + framesString: framesString, + isNoteLocked: isNoteLockedStr == "true", + lastNotedAt: lastNotedAt, + lastCommentedAt: lastCommentedAt + ) + } + } + + func parser(_: XMLParser, didEndElement elementName: String, namespaceURI _: String?, qualifiedName _: String?) { + if elementName == "post", let post = currentPost { + posts.append(post) + + currentPost = nil } } + + #if DEBUG + func parser(_: XMLParser, parseErrorOccurred parseError: any Error) { + print(parseError) + } + #endif } |