Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit a2f39c8

Browse files
authored
Add AtomicSiteServiceRemote (#704)
2 parents 5fba5e8 + 2140306 commit a2f39c8

File tree

5 files changed

+157
-1
lines changed

5 files changed

+157
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ _None._
3838

3939
### New Features
4040

41-
_None._
41+
- Add `AtomicSiteServiceRemote`
4242

4343
### Bug Fixes
4444

WordPressKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
0CB1905E2A2A5E83004D3E80 /* BlazeCampaign.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB1905D2A2A5E83004D3E80 /* BlazeCampaign.swift */; };
1414
0CB190612A2A6A13004D3E80 /* blaze-campaigns-search.json in Resources */ = {isa = PBXBuildFile; fileRef = 0CB1905F2A2A6943004D3E80 /* blaze-campaigns-search.json */; };
1515
0CB190652A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB190642A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift */; };
16+
0CED1FE82B617CF300E6DD52 /* AtomicSiteServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CED1FE72B617CF300E6DD52 /* AtomicSiteServiceRemote.swift */; };
17+
0CED1FEB2B617D7D00E6DD52 /* AtomicLogs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CED1FEA2B617D7D00E6DD52 /* AtomicLogs.swift */; };
1618
1769DEAA24729AFF00F42EFC /* HomepageSettingsServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1769DEA924729AFF00F42EFC /* HomepageSettingsServiceRemote.swift */; };
1719
17BF9A6C20C7DC3300BF57D2 /* reader-site-search-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 17BF9A6B20C7DC3300BF57D2 /* reader-site-search-success.json */; };
1820
17BF9A7220C7E18200BF57D2 /* reader-site-search-success-hasmore.json in Resources */ = {isa = PBXBuildFile; fileRef = 17BF9A6D20C7E18100BF57D2 /* reader-site-search-success-hasmore.json */; };
@@ -728,6 +730,8 @@
728730
0CB1905D2A2A5E83004D3E80 /* BlazeCampaign.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlazeCampaign.swift; sourceTree = "<group>"; };
729731
0CB1905F2A2A6943004D3E80 /* blaze-campaigns-search.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "blaze-campaigns-search.json"; sourceTree = "<group>"; };
730732
0CB190642A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlazeCampaignsSearchResponse.swift; sourceTree = "<group>"; };
733+
0CED1FE72B617CF300E6DD52 /* AtomicSiteServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicSiteServiceRemote.swift; sourceTree = "<group>"; };
734+
0CED1FEA2B617D7D00E6DD52 /* AtomicLogs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicLogs.swift; sourceTree = "<group>"; };
731735
1769DEA924729AFF00F42EFC /* HomepageSettingsServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomepageSettingsServiceRemote.swift; sourceTree = "<group>"; };
732736
17BF9A6B20C7DC3300BF57D2 /* reader-site-search-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "reader-site-search-success.json"; sourceTree = "<group>"; };
733737
17BF9A6D20C7E18100BF57D2 /* reader-site-search-success-hasmore.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "reader-site-search-success-hasmore.json"; sourceTree = "<group>"; };
@@ -1476,6 +1480,14 @@
14761480
name = Blaze;
14771481
sourceTree = "<group>";
14781482
};
1483+
0CED1FE92B617D6700E6DD52 /* Atomic */ = {
1484+
isa = PBXGroup;
1485+
children = (
1486+
0CED1FEA2B617D7D00E6DD52 /* AtomicLogs.swift */,
1487+
);
1488+
name = Atomic;
1489+
sourceTree = "<group>";
1490+
};
14791491
3297E1DC2564649D00287D21 /* Scan */ = {
14801492
isa = PBXGroup;
14811493
children = (
@@ -2036,6 +2048,7 @@
20362048
9309994C1F1657C600F006A1 /* ThemeServiceRemote.m */,
20372049
E1D6B557200E473A00325669 /* TimeZoneServiceRemote.swift */,
20382050
436D56322118D7AA00CEAA33 /* TransactionsServiceRemote.swift */,
2051+
0CED1FE72B617CF300E6DD52 /* AtomicSiteServiceRemote.swift */,
20392052
93F50A3E1F227C8900B5BEBA /* UsersServiceRemoteXMLRPC.swift */,
20402053
93F50A351F226B9300B5BEBA /* WordPressComServiceRemote.h */,
20412054
93F50A361F226B9300B5BEBA /* WordPressComServiceRemote.m */,
@@ -2051,6 +2064,7 @@
20512064
9368C79C1EC62EBD0092CE8E /* Models */ = {
20522065
isa = PBXGroup;
20532066
children = (
2067+
0CED1FE92B617D6700E6DD52 /* Atomic */,
20542068
0CB1905C2A2A5E7B004D3E80 /* Blaze */,
20552069
7E3E7A4620E443100075D159 /* Extensions */,
20562070
E1EF5D5E1F9F3CA700B6D53E /* Plugins */,
@@ -3310,6 +3324,7 @@
33103324
4A05E7962B2FCB6400C25E3B /* NonceRetrieval.swift in Sources */,
33113325
93BD27701EE737A8002BB00B /* ServiceRemoteWordPressComREST.m in Sources */,
33123326
E61A51A621B172A900A5F902 /* RemoteWpcomPlan.swift in Sources */,
3327+
0CED1FE82B617CF300E6DD52 /* AtomicSiteServiceRemote.swift in Sources */,
33133328
93BD277F1EE73944002BB00B /* WordPressComOAuthClient.swift in Sources */,
33143329
740B23B91F17EC7300067A2A /* PostServiceRemoteREST.m in Sources */,
33153330
93BD27801EE73944002BB00B /* WordPressComRestApi.swift in Sources */,
@@ -3364,6 +3379,7 @@
33643379
C785325625B5F46C006CEAFB /* JetpackThreatFixStatus.swift in Sources */,
33653380
0CB190652A2A7569004D3E80 /* BlazeCampaignsSearchResponse.swift in Sources */,
33663381
93F50A381F226B9300B5BEBA /* WordPressComServiceRemote.m in Sources */,
3382+
0CED1FEB2B617D7D00E6DD52 /* AtomicLogs.swift in Sources */,
33673383
9F4E52002088E38200424676 /* ObjectValidation.swift in Sources */,
33683384
7EC60EC022DC5D7C00FB0336 /* EditorSettings.swift in Sources */,
33693385
7403A3021EF0726E00DED7DC /* AccountSettings.swift in Sources */,

WordPressKit/AtomicLogs.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import Foundation
2+
3+
public final class AtomicErrorLogEntry: Decodable {
4+
public let message: String?
5+
public let severity: String?
6+
public let kind: String?
7+
public let name: String?
8+
public let file: String?
9+
public let line: Int?
10+
public let timestamp: Date?
11+
12+
public enum Severity: String {
13+
case user = "User"
14+
case warning = "Warning"
15+
case deprecated = "Deprecated"
16+
case fatalError = "Fatal error"
17+
}
18+
}
19+
20+
public final class AtomicErrorLogsResponse: Decodable {
21+
public let totalResults: Int
22+
public let logs: [AtomicErrorLogEntry]
23+
public let scrollId: String?
24+
}
25+
26+
public class AtomicWebServerLogEntry: Decodable {
27+
public let bodyBytesSent: Int?
28+
/// The possible values are `"true"` or `"false"`.
29+
public let cached: String?
30+
public let date: Date?
31+
public let httpHost: String?
32+
public let httpReferer: String?
33+
public let httpUserAgent: String?
34+
public let requestTime: Double?
35+
public let requestType: String?
36+
public let requestURL: String?
37+
public let scheme: String?
38+
public let status: Int?
39+
public let timestamp: Int?
40+
public let type: String?
41+
public let userIP: String?
42+
}
43+
44+
public final class AtomicWebServerLogsResponse: Decodable {
45+
public let totalResults: Int
46+
public let logs: [AtomicWebServerLogEntry]
47+
public let scrollId: String?
48+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import Foundation
2+
3+
public final class AtomicSiteServiceRemote: ServiceRemoteWordPressComREST {
4+
/// - parameter scrollID: Pass the scroll ID from the previous response to
5+
/// fetch the next page.
6+
public func getErrorLogs(siteID: Int,
7+
range: Range<Date>,
8+
severity: AtomicErrorLogEntry.Severity? = nil,
9+
scrollID: String? = nil,
10+
pageSize: Int = 50,
11+
success: @escaping (AtomicErrorLogsResponse) -> Void,
12+
failure: @escaping (Error) -> Void) {
13+
let path = self.path(forEndpoint: "sites/\(siteID)/hosting/error-logs/", withVersion: ._2_0)
14+
var parameters = [
15+
"start": "\(Int(range.lowerBound.timeIntervalSince1970))",
16+
"end": "\(Int(range.upperBound.timeIntervalSince1970))",
17+
"sort_order": "desc",
18+
"page_size": "\(pageSize)"
19+
] as [String: String]
20+
if let severity {
21+
parameters["filter[severity][]"] = severity.rawValue
22+
}
23+
if let scrollID {
24+
parameters["scroll_id"] = scrollID
25+
}
26+
wordPressComRestApi.GET(path, parameters: parameters as [String: AnyObject]) { responseObject, httpResponse in
27+
guard (200..<300).contains(httpResponse?.statusCode ?? 0),
28+
let data = (responseObject as? [String: AnyObject])?["data"],
29+
JSONSerialization.isValidJSONObject(data) else {
30+
failure(URLError(.unknown))
31+
return
32+
}
33+
do {
34+
let data = try JSONSerialization.data(withJSONObject: data)
35+
let response = try JSONDecoder.apiDecoder.decode(AtomicErrorLogsResponse.self, from: data)
36+
success(response)
37+
} catch {
38+
WPKitLogError("Error parsing campaigns response: \(error), \(responseObject)")
39+
failure(error)
40+
}
41+
} failure: { error, _ in
42+
failure(error)
43+
}
44+
}
45+
46+
public func getWebServerLogs(siteID: Int,
47+
range: Range<Date>,
48+
httpMethod: String? = nil,
49+
statusCode: Int? = nil,
50+
scrollID: String? = nil,
51+
pageSize: Int = 50,
52+
success: @escaping (AtomicWebServerLogsResponse) -> Void,
53+
failure: @escaping (Error) -> Void) {
54+
let path = self.path(forEndpoint: "sites/\(siteID)/hosting/logs/", withVersion: ._2_0)
55+
var parameters = [
56+
"start": "\(Int(range.lowerBound.timeIntervalSince1970))",
57+
"end": "\(Int(range.upperBound.timeIntervalSince1970))",
58+
"sort_order": "desc",
59+
"page_size": "\(pageSize)"
60+
] as [String: String]
61+
if let httpMethod {
62+
parameters["filter[request_type][]"] = httpMethod.uppercased()
63+
}
64+
if let statusCode {
65+
parameters["filter[status][]"] = "\(statusCode)"
66+
}
67+
if let scrollID {
68+
parameters["scroll_id"] = scrollID
69+
}
70+
wordPressComRestApi.GET(path, parameters: parameters as [String: AnyObject]) { responseObject, httpResponse in
71+
guard (200..<300).contains(httpResponse?.statusCode ?? 0),
72+
let data = (responseObject as? [String: AnyObject])?["data"],
73+
JSONSerialization.isValidJSONObject(data) else {
74+
failure(URLError(.unknown))
75+
return
76+
}
77+
do {
78+
let data = try JSONSerialization.data(withJSONObject: data)
79+
let response = try JSONDecoder.apiDecoder.decode(AtomicWebServerLogsResponse.self, from: data)
80+
success(response)
81+
} catch {
82+
WPKitLogError("Error parsing campaigns response: \(error), \(responseObject)")
83+
failure(error)
84+
}
85+
} failure: { error, _ in
86+
failure(error)
87+
}
88+
}
89+
}

WordPressKit/WordPressComRestApi.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import Alamofire
44

55
// MARK: - WordPressComRestApiError
66

7+
@available(*, deprecated, renamed: "WordPressComRestApiErrorCode", message: "`WordPressComRestApiError` is renamed to `WordPressRestApiErrorCode`, and no longer conforms to `Swift.Error`")
8+
public typealias WordPressComRestApiError = WordPressComRestApiErrorCode
9+
710
/**
811
Error constants for the WordPress.com REST API
912

0 commit comments

Comments
 (0)