SeanutSwift/Sources/Seanut.swift

65 lines
2.3 KiB
Swift
Raw Normal View History

2024-02-16 14:58:42 -05:00
// The Swift Programming Language
// https://docs.swift.org/swift-book
import Foundation
import ArgumentParser
import JellyfinAPI
import CryptoKit
let SeanutVersion = "0.0.1"
@main
struct Seanut: AsyncParsableCommand {
static var configuration = CommandConfiguration(
abstract: "A utility to download media from jellyfin servers",
subcommands: [SearchCommand.self, DownloadCommand.self, LoginCommand.self],
defaultSubcommand: SearchCommand.self
)
struct CommonArguments: ParsableArguments {
@Option(name: .shortAndLong, help: "jellyfin server domain name")
var domain: String
}
static func generateJellyfinConfiguration(url: URL) -> JellyfinClient.Configuration {
let hostname = Host.current().localizedName ?? "Seanut-Device"
let digest = SHA256.hash(data: hostname.data(using: .utf8)!)
return JellyfinClient.Configuration(
url: url,
client: "SeanutSwift",
deviceName: hostname,
deviceID: digest.compactMap({ String(format: "%02x", $0) }).joined(),
version: SeanutVersion
)
}
static func getAccessToken(client: JellyfinClient, username: String, password: String?) async {
let pass: String? = password ?? {
print("password>", terminator: " ")
return readLine(strippingNewline: true)
}()
let domain = client.configuration.url.host!
do {
let auth = try await client.signIn(username: username,
password: pass ?? "")
let fileName = FileManager.default
.homeDirectoryForCurrentUser
.appendingPathComponent(".seanut/\(domain)")
try auth.accessToken!.write(to: fileName, atomically: false, encoding: .utf8)
print("Access token retrieved and saved to ~/.seanut/\(domain)")
} catch {
fatalError("failed to login with provided credentials. please try again.")
}
}
static func retrieveAccessToken(for domain: URL) -> String? {
let tokenPath = FileManager.default
.homeDirectoryForCurrentUser
.appendingPathComponent(".seanut/\(domain.host!)")
return try? String(contentsOf: tokenPath)
}
}