Skip to content

Commit

Permalink
Fixed service: Fastly
Browse files Browse the repository at this point in the history
also removed StatusCast and refactored CampaignMonitor
  • Loading branch information
inket committed Feb 9, 2023
1 parent 8e758ad commit 677709a
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 52 deletions.
16 changes: 2 additions & 14 deletions stts.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@
B277BC9822B4C16A000B55C3 /* AzureDevOpsServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = B277BC9722B4C16A000B55C3 /* AzureDevOpsServices.swift */; };
B28285E12405E44100B11A08 /* Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28285E02405E44100B11A08 /* Zoom.swift */; };
B2841CEB20BA6207004AFDB7 /* SorryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2841CEA20BA6207004AFDB7 /* SorryService.swift */; };
B286ECA5285E39D700E9CCE6 /* StatusCastService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B286ECA4285E39D700E9CCE6 /* StatusCastService.swift */; };
B2894CE420EEE2780009CCA3 /* Buildkite.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2894CE320EEE2780009CCA3 /* Buildkite.swift */; };
B2898FD01DC7441D0005F58F /* StatusIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2898FCF1DC7441D0005F58F /* StatusIndicator.swift */; };
B28C1D441E607D8600F9D0DC /* Mapbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = B28C1D431E607D8600F9D0DC /* Mapbox.swift */; };
Expand Down Expand Up @@ -520,7 +519,6 @@
B277BC9722B4C16A000B55C3 /* AzureDevOpsServices.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureDevOpsServices.swift; sourceTree = "<group>"; };
B28285E02405E44100B11A08 /* Zoom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zoom.swift; sourceTree = "<group>"; };
B2841CEA20BA6207004AFDB7 /* SorryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SorryService.swift; sourceTree = "<group>"; };
B286ECA4285E39D700E9CCE6 /* StatusCastService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusCastService.swift; sourceTree = "<group>"; };
B2894CE320EEE2780009CCA3 /* Buildkite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buildkite.swift; sourceTree = "<group>"; };
B2898FCF1DC7441D0005F58F /* StatusIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusIndicator.swift; sourceTree = "<group>"; };
B28C1D431E607D8600F9D0DC /* Mapbox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mapbox.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -798,14 +796,6 @@
path = Sorry;
sourceTree = "<group>";
};
B286ECA3285E39C300E9CCE6 /* StatusCast */ = {
isa = PBXGroup;
children = (
B22BB39E223B33AE00B43BED /* CampaignMonitor.swift */,
);
path = StatusCast;
sourceTree = "<group>";
};
B299C8561DD051710024D2E9 /* StatusPage */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -874,7 +864,6 @@
0FDDACCC23CD7EBF00FE96CD /* ElasticCloud.swift */,
B299C8541DD051210024D2E9 /* EngineYard.swift */,
9BF74DC57A426C3EBFCC2E90 /* EquinixMetal.swift */,
A125C59D20F7909500C513B3 /* Fastly.swift */,
B269FCBA1E261BDF0016041D /* Figma.swift */,
B20396371EE6A06C008CCA21 /* Filestack.swift */,
E96A56CCE8D1459FB0B09DB6 /* FirefoxRelay.swift */,
Expand Down Expand Up @@ -1102,7 +1091,6 @@
B2841CEC20BA6423004AFDB7 /* Sorry */,
B26CB5711E13448900116A33 /* Status.ioV1 */,
B2163B0120BA5AE600B14A85 /* StatusCake */,
B286ECA3285E39C300E9CCE6 /* StatusCast */,
B25425032935958D0093AC83 /* StatusHub */,
B299C8561DD051710024D2E9 /* StatusPage */,
B2FDC9201D67071500F0B728 /* Super */,
Expand All @@ -1111,7 +1099,9 @@
B2A4D7E6247E72B50089EA77 /* AzureAll.swift */,
B2A4D7E8247E73BC0089EA77 /* AzureDevOpsAll.swift */,
B23038F01E0DF3CC00B29095 /* Beanstalk.swift */,
B22BB39E223B33AE00B43BED /* CampaignMonitor.swift */,
B290315B1E4B0CA7005B58CC /* Evernote.swift */,
A125C59D20F7909500C513B3 /* Fastly.swift */,
B2253A6E209F42430039F574 /* Firebase.swift */,
B2E70FDA22B07DBC000BCAD2 /* GoogleCloudPlatformAll.swift */,
B2FDC9191D67029900F0B728 /* Heroku.swift */,
Expand Down Expand Up @@ -1156,7 +1146,6 @@
B205A9171D49D67700EA178D /* Service.swift */,
B2841CEA20BA6207004AFDB7 /* SorryService.swift */,
B2163AFF20BA56EF00B14A85 /* StatusCakeService.swift */,
B286ECA4285E39D700E9CCE6 /* StatusCastService.swift */,
B2542501293591610093AC83 /* StatusHubService.swift */,
B2FDC91B1D67062200F0B728 /* StatusPageService.swift */,
B2A0635D1E1341C900EEA762 /* StatusioV1Service.swift */,
Expand Down Expand Up @@ -1411,7 +1400,6 @@
B2894CE420EEE2780009CCA3 /* Buildkite.swift in Sources */,
B20396361EE6A060008CCA21 /* Trello.swift in Sources */,
B227D31225D7671600951917 /* Poka.swift in Sources */,
B286ECA5285E39D700E9CCE6 /* StatusCastService.swift in Sources */,
B231DD59257B431900647312 /* Xandr.swift in Sources */,
B2ABB6171F59770800DF8EC2 /* Imgix.swift in Sources */,
B213D1F6269AD941005EBDDA /* Tableau.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
//
// StatusCastService.swift
// CampaignMonitor.swift
// stts
//

import Foundation
import Kanna

typealias StatusCastService = BaseStatusCastService & RequiredServiceProperties & RequiredStatusCastProperties

protocol RequiredStatusCastProperties {}

class BaseStatusCastService: BaseService {
private enum StatusCastStatus: String, CaseIterable {
class CampaignMonitor: Service {
private enum Status: String, CaseIterable {
case available
case unavailable
case informational
Expand All @@ -37,14 +33,11 @@ class BaseStatusCastService: BaseService {
}
}

override func updateStatus(callback: @escaping (BaseService) -> Void) {
guard let realSelf = self as? StatusCastService else {
fatalError("BaseStatusCastService should not be used directly.")
}

let statusURL = realSelf.url
let name = "Campaign Monitor"
let url = URL(string: "https://status.campaignmonitor.com")!

loadData(with: statusURL) { [weak self] data, _, error in
override func updateStatus(callback: @escaping (BaseService) -> Void) {
loadData(with: url) { [weak self] data, _, error in
guard let strongSelf = self else { return }
defer { callback(strongSelf) }
guard let data = data else { return strongSelf._fail(error) }
Expand All @@ -53,9 +46,8 @@ class BaseStatusCastService: BaseService {
return strongSelf._fail("Couldn't parse response")
}

// Not all StatusCast services support this format or this method of looking for status…
let statuses: [(ServiceStatus, String?)] = doc.css(".status-list-component-status-text").map { element in
for status in StatusCastStatus.allCases {
for status in Status.allCases {
if element.className?.contains("component-\(status.rawValue)") == true {
return (
status.serviceStatus,
Expand Down
94 changes: 94 additions & 0 deletions stts/Services/Fastly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Fastly.swift
// stts
//

import Foundation
import Kanna

class Fastly: Service {
let url = URL(string: "https://status.fastly.com")!

private enum Status: String, CaseIterable {
case normal
case informational
case maintenance
case degraded
case unavailable

case investigating
case identified
case monitoring

var serviceStatus: ServiceStatus {
switch self {
case .normal:
return .good
case .informational:
return .notice
case .maintenance:
return .maintenance
case .degraded:
return .minor
case .unavailable:
return .major
case .investigating, .identified, .monitoring:
// Statuses for incidents, but in case they show up...
return .notice
}
}
}

override func updateStatus(callback: @escaping (BaseService) -> Void) {
loadData(with: url) { [weak self] data, _, error in
guard let strongSelf = self else { return }
defer { callback(strongSelf) }
guard let data = data else { return strongSelf._fail(error) }

guard let doc = try? HTML(html: data, encoding: .utf8) else {
return strongSelf._fail("Couldn't parse response")
}

// The page has a table that displays the statuses, their names and their image URLs. We map URLs to names
// so that we can identify the status from its URL.
var statusHeaders: [Status] = []
doc.css("#widget-000301 table tr th").forEach { element in
if element["colspan"] == nil,
let headerText = element.text?.lowercased(),
let status = Status(rawValue: headerText) {
statusHeaders.append(status)
}
}
var statusImageURLs: [String] = []
doc.css("#widget-000301 table tr td img").forEach { element in
if let statusImageURL = element["src"]?.lowercased() {
statusImageURLs.append(statusImageURL)
}
}

guard statusHeaders.count == statusImageURLs.count, statusImageURLs.count != 0 else {
return strongSelf._fail("Unexpected response")
}

var urlToStatusMap: [String: Status] = [:]
statusImageURLs.enumerated().forEach { index, url in
urlToStatusMap[url] = statusHeaders[index]
}

guard
let blockQuote = doc.css("blockquote").first,
let statusImageURL = blockQuote.css("img").first?["src"]?.lowercased(),
let status = urlToStatusMap[statusImageURL],
let statusText = blockQuote.text?
.trimmingCharacters(in: .whitespacesAndNewlines)
.trimmingCharacters(in: CharacterSet(charactersIn: "|"))
.trimmingCharacters(in: .whitespacesAndNewlines)
else {
return strongSelf._fail("Unexpected response")
}

strongSelf.status = status.serviceStatus
strongSelf.message = statusText
}
}
}
11 changes: 0 additions & 11 deletions stts/Services/StatusCast/CampaignMonitor.swift

This file was deleted.

11 changes: 0 additions & 11 deletions stts/Services/StatusPage/Fastly.swift

This file was deleted.

0 comments on commit 677709a

Please sign in to comment.