-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTorrentRequests.swift
156 lines (137 loc) · 5.46 KB
/
TorrentRequests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import Foundation
public extension Request {
// MARK: Action Requests
/// Starts torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-start`
///
/// - Parameter ids: The torrent IDs and/or hashes to start.
static func start(ids: [Any]) -> Request<Void> {
.init(method: "torrent-start", args: ["ids": ids])
}
/// Stops torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-stop`
///
/// - Parameter ids: The torrent IDs and/or hashes to stop.
static func stop(ids: [Any]) -> Request<Void> {
.init(method: "torrent-stop", args: ["ids": ids])
}
/// Verifies the data for torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-verify`
///
/// - Parameter ids: The torrent IDs and/or hashes to verify.
static func verify(ids: [Any]) -> Request<Void> {
.init(method: "torrent-verify", args: ["ids": ids])
}
/// Forces a reannounce for torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-reannounce`
///
/// - Parameter ids: The torrent IDs and/or hashes to reannounce.
static func reannounce(ids: [Any]) -> Request<Void> {
.init(method: "torrent-reannounce", args: ["ids": ids])
}
// MARK: Set Requests
/// Sets options for torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-set`
///
/// - Parameters:
/// - ids: The torrent IDs and/or hashes to update.
/// - options: The options to set on the torrents.
static func setOptions(ids: [Any], options: [TorrentOption]) -> Request<Void> {
var args = options.reduce(into: [String: Any]()) { $0[$1.key] = $1.value }
args["ids"] = ids
return .init(method: "torrent-set", args: args)
}
// MARK: Get Requests
/// Requests the list of torrents.
///
/// RPC Method: `torrent-get`
///
/// Result: The list of torrents.
///
/// - Parameter properties: The torrent properties to include.
static func torrents(properties: [Torrent.PropertyKeys]) -> Request<[Torrent]> {
.init(
method: "torrent-get",
args: ["fields": properties.map(\.rawValue)],
transform: { response in
guard let arguments = response["arguments"] as? [String: Any],
let torrents = arguments["torrents"] as? [[String: Any]]
else {
return .failure(.unexpectedResponse)
}
return .success(torrents.compactMap(Torrent.init))
}
)
}
/// Requests the list of files for a torrents.
///
/// RPC Method: `torrent-get`
///
/// Result: The list of files for the torrent.
///
/// - Parameter ids: The torrent ID or hash whose files should be requested.
static func torrentFiles(id: Any) -> Request<[TorrentFile]> {
.init(
method: "torrent-get",
args: ["ids": [id], "fields": ["files", "fileStats"]],
transform: { response -> Result<[TorrentFile], TransmissionError> in
guard let arguments = response["arguments"] as? [String: Any],
let torrents = arguments["torrents"] as? [[String: Any]],
!torrents.isEmpty,
let filesDict = torrents[0]["files"] as? [[String: Any]],
let statsDict = torrents[0]["fileStats"] as? [[String: Any]]
else {
return .failure(.unexpectedResponse)
}
return .success(zip(filesDict, statsDict).enumerated().compactMap { index, element in
TorrentFile(index: index, file: element.0, stats: element.1)
})
}
)
}
// MARK: Add Requests
/// Adds a torrent using a web URL to a torrent file or a magnet URL.
///
/// RPC Method: `torrent-add`
///
/// - Parameter url: The web or magnet URL of the torrent to add.
static func add(url: URL) -> Request<Void> {
.init(method: "torrent-add", args: ["filename": url.absoluteString])
}
/// Adds a torrent using a URL to a local torrent file.
///
/// RPC Method: `torrent-add`
///
/// - Parameter fileURL: The URL of the local torrent file to add.
static func add(fileURL: URL) -> Request<Void> {
let data = FileManager.default.contents(atPath: fileURL.path)?.base64EncodedString() ?? ""
return .init(method: "torrent-add", args: ["metainfo": data])
}
// MARK: Remove Requests
/// Removes torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-remove`
///
/// - Parameters:
/// - ids: The torrent IDs and/or hashes to remove.
/// - removeData: Whether the torrents' data should be removed.
static func remove(ids: [Any], removeData: Bool) -> Request<Void> {
.init(method: "torrent-remove", args: ["ids": ids, "delete-local-data": removeData])
}
// MARK: Set Location
/// Moves the storage for torrents with the given IDs and/or hashes.
///
/// RPC Method: `torrent-set-location`
///
/// - Parameters:
/// - ids: The torrent IDs and/or hashes whose storage should be moved.
/// - path: The new path where the torrents' data should be stored.
static func move(ids: [Any], path: String) -> Request<Void> {
.init(method: "torrent-set-location", args: ["ids": ids, "location": path, "move": true])
}
}