Skip to content

Commit 6f25e10

Browse files
authored
Tag models (#214)
* WIP Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com> * WIP Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com> * WIP Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com> --------- Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com>
1 parent 631abfc commit 6f25e10

4 files changed

Lines changed: 449 additions & 7 deletions

File tree

Sources/NextcloudKit/Models/NKDataFileXML.swift

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,30 @@ public class NKDataFileXML: NSObject {
8989
</d:propertyupdate>
9090
"""
9191

92+
let requestBodySystemTags =
93+
"""
94+
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
95+
<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">
96+
<d:prop>
97+
<oc:id />
98+
<oc:display-name />
99+
<nc:color />
100+
</d:prop>
101+
</d:propfind>
102+
"""
103+
104+
let requestBodySystemTagSetColor =
105+
"""
106+
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
107+
<d:propertyupdate xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">
108+
<d:set>
109+
<d:prop>
110+
<nc:color>%@</nc:color>
111+
</d:prop>
112+
</d:set>
113+
</d:propertyupdate>
114+
"""
115+
92116
func getRequestBodyFileListingFavorites(createProperties: [NKProperties]?, removeProperties: [NKProperties] = []) -> String {
93117
let request = """
94118
<?xml version=\"1.0\"?>
@@ -452,11 +476,8 @@ public class NKDataFileXML: NSObject {
452476
file.lockTimeOut = file.lockTime?.addingTimeInterval(TimeInterval(lockTimeOut))
453477
}
454478

455-
let tagsElements = propstat["d:prop", "nc:system-tags"]
456-
for element in tagsElements["nc:system-tag"] {
457-
guard let tag = element.text else { continue }
458-
file.tags.append(tag)
459-
}
479+
let tags: [NKTag] = NKTag.parse(systemTagElements: propstat["d:prop", "nc:system-tags", "nc:system-tag"])
480+
file.tags.append(contentsOf: tags)
460481

461482
// NC27 -----
462483
if let latitude = propstat["d:prop", "nc:file-metadata-gps", "latitude"].double {

Sources/NextcloudKit/Models/NKFile.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public struct NKFile: Sendable {
5656
public var shareType: [Int]
5757
public var size: Int64
5858
public var serverUrl: String
59-
public var tags: [String]
59+
public var tags: [NKTag]
6060
public var trashbinFileName: String
6161
public var trashbinOriginalLocation: String
6262
public var trashbinDeletionTime: Date
@@ -128,7 +128,7 @@ public struct NKFile: Sendable {
128128
shareType: [Int] = [],
129129
size: Int64 = 0,
130130
serverUrl: String = "",
131-
tags: [String] = [],
131+
tags: [NKTag] = [],
132132
trashbinFileName: String = "",
133133
trashbinOriginalLocation: String = "",
134134
trashbinDeletionTime: Date = Date(),
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-FileCopyrightText: Nextcloud GmbH
2+
// SPDX-FileCopyrightText: 2026 Milen Pivchev
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
import Foundation
6+
import SwiftyXMLParser
7+
8+
public struct NKTag: Sendable, Equatable, Hashable {
9+
public let id: String
10+
public let name: String
11+
public let color: String?
12+
13+
public init(id: String, name: String, color: String?) {
14+
self.id = id
15+
self.name = name
16+
self.color = color
17+
}
18+
19+
static func parse(xmlData: Data) -> [NKTag] {
20+
let xml = XML.parse(xmlData)
21+
let responses = xml["d:multistatus", "d:response"]
22+
var tags: [NKTag] = []
23+
24+
for response in responses {
25+
let propstat = response["d:propstat"][0]
26+
guard let id = propstat["d:prop", "oc:id"].text,
27+
let name = propstat["d:prop", "oc:display-name"].text else {
28+
continue
29+
}
30+
31+
let color = normalizedColor(propstat["d:prop", "nc:color"].text)
32+
33+
tags.append(NKTag(id: id, name: name, color: color))
34+
}
35+
36+
return tags
37+
}
38+
39+
static func parse(systemTagElements: XML.Accessor) -> [NKTag] {
40+
var tags: [NKTag] = []
41+
42+
for element in systemTagElements {
43+
guard let name = element.text?.trimmingCharacters(in: .whitespacesAndNewlines),
44+
!name.isEmpty else {
45+
continue
46+
}
47+
48+
let id = element.attributes["oc:id"] ?? ""
49+
let color = normalizedColor(element.attributes["nc:color"])
50+
tags.append(NKTag(id: id, name: name, color: color))
51+
}
52+
53+
return tags
54+
}
55+
56+
private static func normalizedColor(_ rawValue: String?) -> String? {
57+
guard let rawValue, !rawValue.isEmpty else {
58+
return nil
59+
}
60+
return rawValue.hasPrefix("#") ? rawValue : "#\(rawValue)"
61+
}
62+
}

0 commit comments

Comments
 (0)