aboutsummaryrefslogtreecommitdiff
path: root/Hutch/Networking/APICacheKeys.swift
blob: d0cffa69fb04abeed9cc87d70c2d48894621f640 (plain) (blame)
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
import Foundation

enum APICacheKeys {
    static func repositories(service: SRHTService, owner: String? = nil, cursor: String? = nil, filter: String? = nil) -> String {
        make([
            service.rawValue,
            "repositories",
            owner.map { "owner:\(normalize($0))" },
            cursor.map { "cursor:\($0)" },
            filter.map { "filter:\(normalize($0))" }
        ])
    }

    static func repository(service: SRHTService, owner: String, name: String) -> String {
        make([service.rawValue, "repository", normalize(owner), normalize(name)])
    }

    static func repositoryRID(service: SRHTService, rid: String) -> String {
        make([service.rawValue, "repository", "rid:\(rid)"])
    }

    static func refs(service: SRHTService, rid: String, cursor: String? = nil) -> String {
        make([service.rawValue, "refs", "rid:\(rid)", cursor.map { "cursor:\($0)" }])
    }

    static func readme(service: SRHTService, rid: String, path: String? = nil, ref: String = "HEAD") -> String {
        make([service.rawValue, "readme", "rid:\(rid)", "ref:\(ref)", path.map { "path:\($0)" }])
    }

    static func treeRoot(service: SRHTService, rid: String, ref: String) -> String {
        make([service.rawValue, "tree", "rid:\(rid)", "ref:\(ref)", "root"])
    }

    static func treeEntries(service: SRHTService, rid: String, treeId: String, cursor: String? = nil) -> String {
        make([service.rawValue, "tree", "rid:\(rid)", "tree:\(treeId)", cursor.map { "cursor:\($0)" }])
    }

    static func blob(service: SRHTService, rid: String, blobId: String) -> String {
        make([service.rawValue, "blob", "rid:\(rid)", "blob:\(blobId)"])
    }

    static func path(service: SRHTService, rid: String, ref: String, path: String) -> String {
        make([service.rawValue, "path", "rid:\(rid)", "ref:\(ref)", "path:\(path)"])
    }

    static func ticketDetail(owner: String, trackerRid: String, ticketId: Int) -> String {
        make([SRHTService.todo.rawValue, "ticket", normalize(owner), "tracker:\(trackerRid)", "ticket:\(ticketId)"])
    }

    static func trackerLabels(trackerRid: String) -> String {
        make([SRHTService.todo.rawValue, "tracker-labels", "tracker:\(trackerRid)"])
    }

    static func trackers(cursor: String? = nil) -> String {
        make([SRHTService.todo.rawValue, "trackers", cursor.map { "cursor:\($0)" }])
    }

    static func tickets(trackerRid: String, cursor: String? = nil) -> String {
        make([SRHTService.todo.rawValue, "tickets", "tracker:\(trackerRid)", cursor.map { "cursor:\($0)" }])
    }

    static func builds(cursor: String? = nil, filter: String? = nil) -> String {
        make([SRHTService.builds.rawValue, "jobs", cursor.map { "cursor:\($0)" }, filter.map { "filter:\($0)" }])
    }

    static func buildDetail(jobId: Int) -> String {
        make([SRHTService.builds.rawValue, "job", "id:\(jobId)"])
    }

    static func buildLog(url: URL, jobId: Int? = nil, task: String? = nil) -> String {
        make([SRHTService.builds.rawValue, "log", jobId.map { "job:\($0)" }, task.map { "task:\($0)" }, url.absoluteString])
    }

    static func userRepositories(owner: String, cursor: String? = nil) -> String {
        make([SRHTService.git.rawValue, "user-repositories", normalize(owner), cursor.map { "cursor:\($0)" }])
    }

    static func userTrackers(owner: String, cursor: String? = nil) -> String {
        make([SRHTService.todo.rawValue, "user-trackers", normalize(owner), cursor.map { "cursor:\($0)" }])
    }

    static func projects(cursor: String? = nil) -> String {
        make([SRHTService.hub.rawValue, "projects", cursor.map { "cursor:\($0)" }])
    }

    static func projectDetail(rid: String, mailingListsCursor: String? = nil, sourcesCursor: String? = nil, trackersCursor: String? = nil) -> String {
        make([
            SRHTService.hub.rawValue,
            "project",
            "rid:\(rid)",
            mailingListsCursor.map { "ml:\($0)" },
            sourcesCursor.map { "src:\($0)" },
            trackersCursor.map { "trk:\($0)" }
        ])
    }

    static func homeJobs(actor: String) -> String {
        make(["home", "jobs", normalize(actor)])
    }

    static func homeTrackerTickets(owner: String, tracker: String) -> String {
        make(["home", "tickets", normalize(owner), normalize(tracker)])
    }

    static func inboxSubscriptions(cursor: String? = nil) -> String {
        make([SRHTService.lists.rawValue, "subscriptions", cursor.map { "cursor:\($0)" }])
    }

    static func inboxThreads(listRid: String, cursor: String? = nil) -> String {
        make([SRHTService.lists.rawValue, "threads", "list:\(listRid)", cursor.map { "cursor:\($0)" }])
    }

    static func pasteList(cursor: String? = nil) -> String {
        make([SRHTService.paste.rawValue, "pastes", cursor.map { "cursor:\($0)" }])
    }

    static func prefix(_ components: String...) -> String {
        make(components)
    }

    private static func make(_ parts: [String?]) -> String {
        parts.compactMap { $0?.replacingOccurrences(of: "|", with: "%7C") }
            .joined(separator: "|")
    }

    private static func normalize(_ value: String) -> String {
        value.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
    }
}

enum APICacheTTLs {
    // Active build data changes quickly; completed logs and content-addressed git data are effectively immutable.
    static let activeBuild: TimeInterval = 15
    static let completedBuildDetail: TimeInterval = 60 * 60
    static let completedBuildLog: TimeInterval = 30 * 24 * 60 * 60
    static let ticketDetail: TimeInterval = 5 * 60
    static let ticketList: TimeInterval = 2 * 60
    static let repositoryMetadata: TimeInterval = 30 * 60
    static let repositoryList: TimeInterval = 5 * 60
    static let immutableFileContent: TimeInterval = 14 * 24 * 60 * 60
    static let movingRefFileContent: TimeInterval = 10 * 60
    static let userProfile: TimeInterval = 30 * 60
    static let status: TimeInterval = 5 * 60
    static let homeDashboard: TimeInterval = 2 * 60
    static let inboxSummary: TimeInterval = 2 * 60
    static let projectList: TimeInterval = 10 * 60
    static let projectDetail: TimeInterval = 10 * 60
}