// // OPMLFile.swift // Account // // Created by Maurice Parker on 9/12/19. // Copyright © 2019 Ranchero Software, LLC. All rights reserved. // import Foundation import os.log import RSCore import RSParser final class OPMLFile: NSObject, NSFilePresenter { private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "account") private let filename: String private let account: Account private let operationQueue: OperationQueue var presentedItemURL: URL? { return URL(string: filename) } var presentedItemOperationQueue: OperationQueue { return operationQueue } init(filename: String, account: Account) { self.filename = filename self.account = account operationQueue = OperationQueue() operationQueue.maxConcurrentOperationCount = 1 } func load() { let opmlFileURL = URL(fileURLWithPath: filename) var fileData: Data? do { fileData = try Data(contentsOf: opmlFileURL) } catch { // Commented out because it’s not an error on first run. // TODO: make it so we know if it’s first run or not. //NSApplication.shared.presentError(error) return } guard let opmlData = fileData else { return } let parserData = ParserData(url: opmlFileURL.absoluteString, data: opmlData) var opmlDocument: RSOPMLDocument? do { opmlDocument = try RSOPMLParser.parseOPML(with: parserData) } catch { os_log(.error, log: log, "OPML Import failed: %@.", error.localizedDescription) return } guard let parsedOPML = opmlDocument, let children = parsedOPML.children else { return } BatchUpdate.shared.perform { account.loadOPMLItems(children, parentFolder: nil) } } func save() { let opmlDocumentString = opmlDocument() do { let url = URL(fileURLWithPath: filename) try opmlDocumentString.write(to: url, atomically: true, encoding: .utf8) } catch let error as NSError { os_log(.error, log: log, "Save to disk failed: %@.", error.localizedDescription) } } } private extension OPMLFile { func opmlDocument() -> String { let escapedTitle = account.nameForDisplay.rs_stringByEscapingSpecialXMLCharacters() let openingText = """ \(escapedTitle) """ let middleText = account.OPMLString(indentLevel: 0) let closingText = """ """ let opml = openingText + middleText + closingText return opml } }