SeanutSwift/Sources/Seanut.swift

76 lines
2.6 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
import Logging
2024-02-16 14:58:42 -05:00
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
)
static var Logger: Logger? = nil
2024-02-16 14:58:42 -05:00
struct CommonArguments: ParsableArguments {
@Option(name: .shortAndLong, help: "jellyfin server domain name")
var domain: String
@Flag(name: .long, help: "prints extra information to the console")
var verbose = false
}
static func maybeSetLogger(_ opts: CommonArguments) {
Seanut.Logger = opts.verbose ? Logging.Logger(label: "garden.focks.SeanutSwift.logger") : nil
2024-02-16 14:58:42 -05:00
}
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 ☑️")
2024-02-16 14:58:42 -05:00
} catch {
print("Failed to login with provided credentials. please try again later.")
exit(withError: error)
2024-02-16 14:58:42 -05:00
}
}
static func retrieveAccessToken(for domain: URL) -> String? {
let tokenPath = FileManager.default
.homeDirectoryForCurrentUser
.appendingPathComponent(".seanut/\(domain.host!)")
return try? String(contentsOf: tokenPath)
}
}