Tusker/Tusker/API/InstanceFeatures.swift

157 lines
4.6 KiB
Swift

//
// InstanceFeatures.swift
// Tusker
//
// Created by Shadowfacts on 1/23/22.
// Copyright © 2022 Shadowfacts. All rights reserved.
//
import Foundation
import Pachyderm
struct InstanceFeatures {
private static let pleromaVersionRegex = try! NSRegularExpression(pattern: "\\(compatible; Pleroma (.*)\\)")
private(set) var instanceType = InstanceType.mastodon
private(set) var version: Version?
private(set) var pleromaVersion: Version?
private(set) var maxStatusChars = 500
var localOnlyPosts: Bool {
instanceType == .hometown || instanceType == .glitch
}
var mastodonAttachmentRestrictions: Bool {
instanceType.isMastodon
}
var pollsAndAttachments: Bool {
instanceType == .pleroma
}
var boostToOriginalAudience: Bool {
instanceType == .pleroma
}
var profilePinnedStatuses: Bool {
instanceType != .pixelfed
}
var trends: Bool {
instanceType == .mastodon
}
var trendingStatusesAndLinks: Bool {
instanceType == .mastodon && hasVersion(3, 5, 0)
}
var reblogVisibility: Bool {
(instanceType == .mastodon && hasVersion(2, 8, 0))
|| (instanceType == .pleroma && hasVersion(2, 0, 0))
}
mutating func update(instance: Instance, nodeInfo: NodeInfo?) {
let ver = instance.version.lowercased()
if ver.contains("glitch") {
instanceType = .glitch
} else if nodeInfo?.software.name == "hometown" {
instanceType = .hometown
} else if ver.contains("pleroma") {
instanceType = .pleroma
} else if ver.contains("pixelfed") {
instanceType = .pixelfed
} else {
instanceType = .mastodon
}
version = Version(string: ver)
if let match = InstanceFeatures.pleromaVersionRegex.firstMatch(in: ver, range: NSRange(location: 0, length: ver.utf16.count)) {
pleromaVersion = Version(string: (ver as NSString).substring(with: match.range(at: 1)))
}
maxStatusChars = instance.maxStatusCharacters ?? 500
}
func hasVersion(_ major: Int, _ minor: Int, _ patch: Int) -> Bool {
if let version {
return version >= Version(major, minor, patch)
} else {
return false
}
}
}
extension InstanceFeatures {
enum InstanceType: Equatable {
case mastodon // vanilla
case pleroma
case hometown
case glitch
case pixelfed
var isMastodon: Bool {
switch self {
case .mastodon, .hometown, .glitch:
return true
default:
return false
}
}
}
}
extension InstanceFeatures {
struct Version: Equatable, Comparable {
private static let regex = try! NSRegularExpression(pattern: "^(\\d+)\\.(\\d+)\\.(\\d+).*$")
let major: Int
let minor: Int
let patch: Int
init(_ major: Int, _ minor: Int, _ patch: Int) {
self.major = major
self.minor = minor
self.patch = patch
}
init?(string: String) {
guard let match = Version.regex.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)),
match.numberOfRanges == 4 else {
return nil
}
let majorStr = (string as NSString).substring(with: match.range(at: 1))
let minorStr = (string as NSString).substring(with: match.range(at: 2))
let patchStr = (string as NSString).substring(with: match.range(at: 3))
guard let major = Int(majorStr),
let minor = Int(minorStr),
let patch = Int(patchStr) else {
return nil
}
self.major = major
self.minor = minor
self.patch = patch
}
static func ==(lhs: Version, rhs: Version) -> Bool {
return lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch == rhs.patch
}
static func < (lhs: InstanceFeatures.Version, rhs: InstanceFeatures.Version) -> Bool {
if lhs.major < rhs.major {
return true
} else if lhs.major > rhs.major {
return false
} else if lhs.minor < rhs.minor {
return true
} else if lhs.minor > rhs.minor {
return false
} else if lhs.patch < rhs.patch {
return true
} else {
return false
}
}
}
}