summaryrefslogtreecommitdiff
path: root/Hutch/Extensions/SRHTWebURL.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hutch/Extensions/SRHTWebURL.swift')
-rw-r--r--Hutch/Extensions/SRHTWebURL.swift84
1 files changed, 84 insertions, 0 deletions
diff --git a/Hutch/Extensions/SRHTWebURL.swift b/Hutch/Extensions/SRHTWebURL.swift
new file mode 100644
index 0000000..53556de
--- /dev/null
+++ b/Hutch/Extensions/SRHTWebURL.swift
@@ -0,0 +1,84 @@
+import Foundation
+
+enum SRHTWebURL {
+ static func repository(_ repository: RepositorySummary) -> URL? {
+ userScopedURL(
+ host: "\(repository.service.rawValue).sr.ht",
+ ownerCanonicalName: repository.owner.canonicalName,
+ pathComponents: [repository.name]
+ )
+ }
+
+ static func build(jobId: Int, ownerCanonicalName: String) -> URL? {
+ userScopedURL(
+ host: "builds.sr.ht",
+ ownerCanonicalName: ownerCanonicalName,
+ pathComponents: ["job", String(jobId)]
+ )
+ }
+
+ static func tracker(ownerUsername: String, trackerName: String) -> URL? {
+ userScopedURL(
+ host: "todo.sr.ht",
+ ownerUsername: ownerUsername,
+ pathComponents: [trackerName]
+ )
+ }
+
+ static func ticket(ownerUsername: String, trackerName: String, ticketId: Int) -> URL? {
+ userScopedURL(
+ host: "todo.sr.ht",
+ ownerUsername: ownerUsername,
+ pathComponents: [trackerName, String(ticketId)]
+ )
+ }
+
+ static func profile(canonicalName: String) -> URL? {
+ userScopedURL(
+ host: "meta.sr.ht",
+ ownerCanonicalName: canonicalName,
+ pathComponents: []
+ )
+ }
+
+ private static func userScopedURL(
+ host: String,
+ ownerCanonicalName: String,
+ pathComponents: [String]
+ ) -> URL? {
+ userScopedURL(
+ host: host,
+ ownerUsername: username(from: ownerCanonicalName),
+ pathComponents: pathComponents
+ )
+ }
+
+ private static func userScopedURL(
+ host: String,
+ ownerUsername: String,
+ pathComponents: [String]
+ ) -> URL? {
+ var components = URLComponents()
+ components.scheme = "https"
+ components.host = host
+
+ let encodedComponents = (["~\(ownerUsername)"] + pathComponents).map { pathComponent in
+ pathComponent.addingPercentEncoding(withAllowedCharacters: pathComponentCharacterSet) ?? pathComponent
+ }
+ components.percentEncodedPath = "/" + encodedComponents.joined(separator: "/")
+ return components.url
+ }
+
+ private static func username(from canonicalName: String) -> String {
+ if canonicalName.hasPrefix("~") {
+ return String(canonicalName.dropFirst())
+ }
+ return canonicalName
+ }
+
+ private static let pathComponentCharacterSet: CharacterSet = {
+ var characterSet = CharacterSet.urlPathAllowed
+ characterSet.remove(charactersIn: "/")
+ return characterSet
+ }()
+}