summaryrefslogtreecommitdiff
path: root/Sora/Data/Booru
diff options
context:
space:
mode:
Diffstat (limited to 'Sora/Data/Booru')
-rw-r--r--Sora/Data/Booru/BooruManager.swift19
-rw-r--r--Sora/Data/Booru/Tag/DanbooruTagParser.swift58
2 files changed, 75 insertions, 2 deletions
diff --git a/Sora/Data/Booru/BooruManager.swift b/Sora/Data/Booru/BooruManager.swift
index 7d11158..8f055af 100644
--- a/Sora/Data/Booru/BooruManager.swift
+++ b/Sora/Data/Booru/BooruManager.swift
@@ -308,7 +308,12 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng
guard !Task.isCancelled else { return [] }
- return BooruTagXMLParser(data: data).parse().sorted { $0.count > $1.count }
+ let parsedTags =
+ flavor == .danbooru
+ ? DanbooruTagParser(data: data).parse()
+ : BooruTagXMLParser(data: data).parse()
+
+ return parsedTags.sorted { $0.count > $1.count }
} catch {
if (error as? URLError)?.code != .cancelled {
debugPrint("BooruManager.searchTags: \(error)")
@@ -516,7 +521,17 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng
return components.url
case .danbooru:
- return nil
+ var components = URLComponents()
+
+ components.scheme = "https"
+ components.host = domain
+ components.path = "/tags.json"
+ components.queryItems = [
+ URLQueryItem(name: "search[name_matches]", value: "\(name)*"),
+ URLQueryItem(name: "limit", value: "50"),
+ ]
+
+ return components.url
}
}
diff --git a/Sora/Data/Booru/Tag/DanbooruTagParser.swift b/Sora/Data/Booru/Tag/DanbooruTagParser.swift
new file mode 100644
index 0000000..3da165a
--- /dev/null
+++ b/Sora/Data/Booru/Tag/DanbooruTagParser.swift
@@ -0,0 +1,58 @@
+import Foundation
+
+nonisolated class DanbooruTagParser {
+ private let data: Data
+
+ init(data: Data) {
+ self.data = data
+ }
+
+ func parse() -> [BooruTag] {
+ do {
+ guard let decodedTags = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] else {
+ debugPrint("DanbooruTagParser.parse: failed to decode top-level tag array.")
+
+ return []
+ }
+
+ var parsedTags: [BooruTag] = []
+ var droppedRecordCount = 0
+
+ parsedTags.reserveCapacity(decodedTags.count)
+
+ for tag in decodedTags {
+ guard let id = tag["id"] as? Int,
+ let name = tag["name"] as? String,
+ let postCount = tag["post_count"] as? Int,
+ let category = tag["category"] as? Int
+ else {
+ droppedRecordCount += 1
+
+ continue
+ }
+
+ parsedTags.append(
+ BooruTag(
+ id: String(id),
+ name: name,
+ count: postCount,
+ type: category,
+ ambiguous: false
+ )
+ )
+ }
+
+ if droppedRecordCount > 0 {
+ debugPrint(
+ "DanbooruTagParser.parse: dropped \(droppedRecordCount) malformed records while decoding tags."
+ )
+ }
+
+ return parsedTags
+ } catch {
+ debugPrint("DanbooruTagParser.parse: failed to decode response: \(error)")
+
+ return []
+ }
+ }
+}