// // FervorController.swift // Reader // // Created by Shadowfacts on 11/25/21. // import Foundation import Fervor import OSLog class FervorController { static let oauthRedirectURI = URL(string: "frenzy://oauth-callback")! let instanceURL: URL private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "FervorController") let client: FervorClient private(set) var account: LocalData.Account? private(set) var clientID: String? private(set) var clientSecret: String? private(set) var accessToken: String? private(set) var persistentContainer: PersistentContainer! init(instanceURL: URL) { self.instanceURL = instanceURL self.client = FervorClient(instanceURL: instanceURL, accessToken: nil) } convenience init(account: LocalData.Account) { self.init(instanceURL: account.instanceURL) self.account = account self.clientID = account.clientID self.clientSecret = account.clientSecret self.accessToken = account.accessToken self.client.accessToken = account.accessToken self.persistentContainer = PersistentContainer(account: account, fervorController: self) } func register() async throws -> ClientRegistration { let registration = try await client.register(clientName: "Frenzy iOS", website: nil, redirectURI: FervorController.oauthRedirectURI) clientID = registration.clientID clientSecret = registration.clientSecret return registration } func getToken(authCode: String) async throws { let token = try await client.token(authCode: authCode, redirectURI: FervorController.oauthRedirectURI, clientID: clientID!, clientSecret: clientSecret!) client.accessToken = token.accessToken accessToken = token.accessToken } func syncAll() async { logger.info("Syncing groups and feeds") async let groups = try! client.groups() async let feeds = try! client.feeds() try! await persistentContainer.sync(serverGroups: groups, serverFeeds: feeds) let lastSync = try! await persistentContainer.lastSyncDate() logger.info("Syncing items with last sync date: \(String(describing: lastSync), privacy: .public)") let update = try! await client.syncItems(lastSync: lastSync) try! await persistentContainer.syncItems(update) try! await persistentContainer.updateLastSyncDate(update.syncTimestamp) } @MainActor func syncReadToServer() async throws { var count = 0 for case let item as Item in self.persistentContainer.viewContext.updatedObjects { count += 1 let f = item.read ? client.read(item:) : client.unread(item:) let _ = try await f(item.id!) } logger.info("Synced \(count, privacy: .public) read/unread to server") try self.persistentContainer.viewContext.save() } }