From 4010b4cb2ac4b2dbf2891208de540ce78b3ff473 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 16 Sep 2018 12:42:46 -0700 Subject: [PATCH] On startup, import from AccountData.plist one last time, then rename it to AccountData-old.plist. On subsequent startups, import using Subscriptions.opml. --- Frameworks/Account/Account.swift | 114 ++++++++++++++++++++++--------- Frameworks/Account/Feed.swift | 38 +++++------ Frameworks/Account/Folder.swift | 58 ++++++++-------- 3 files changed, 129 insertions(+), 81 deletions(-) diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 8b8c7f277..6ee00990a 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -574,54 +574,102 @@ private extension Account { func pullObjectsFromDisk() { - let settingsFileURL = URL(fileURLWithPath: settingsFile) - guard let d = NSDictionary(contentsOf: settingsFileURL) as? [String: Any] else { + // 9/16/2018: Turning a corner — we used to store data in a plist file, + // but now we’re switching over to OPML. Read the plist file one last time, + // then rename it so we never read from it again. + + if FileManager.default.fileExists(atPath: settingsFile) { + // Old code for reading in plist file. + let settingsFileURL = URL(fileURLWithPath: settingsFile) + guard let d = NSDictionary(contentsOf: settingsFileURL) as? [String: Any] else { + return + } + guard let childrenArray = d[Key.children] as? [[String: Any]] else { + return + } + children = objects(with: childrenArray) + rebuildFeedDictionaries() + + let userInfo = d[Key.userInfo] as? NSDictionary + delegate.update(account: self, withUserInfo: userInfo) + + // Rename plist file so we don’t see it next time. + let renamedFilePath = (dataFolder as NSString).appendingPathComponent("AccountData-old.plist") + do { + try FileManager.default.moveItem(atPath: settingsFile, toPath: renamedFilePath) + } + catch {} + + dirty = true // Ensure OPML file will be written soon. return } - guard let childrenArray = d[Key.children] as? [[String: Any]] else { + + importOPMLFile(path: opmlFilePath) + } + + func importOPMLFile(path: String) { + let opmlFileURL = URL(fileURLWithPath: path) + var fileData: Data? + do { + fileData = try Data(contentsOf: opmlFileURL) + } catch { + NSApplication.shared.presentError(error) return } - children = objects(with: childrenArray) - rebuildFeedDictionaries() - - let userInfo = d[Key.userInfo] as? NSDictionary - delegate.update(account: self, withUserInfo: userInfo) - } - - func diskDictionary() -> NSDictionary { - - let diskObjects = children.compactMap { (object) -> [String: Any]? in - - if let folder = object as? Folder { - return folder.dictionary - } - else if let feed = object as? Feed { - return feed.dictionary - } - return nil + guard let opmlData = fileData else { + return } - var d = [String: Any]() - d[Key.children] = diskObjects as NSArray + let parserData = ParserData(url: opmlFileURL.absoluteString, data: opmlData) + var opmlDocument: RSOPMLDocument? - if let userInfo = delegate.userInfo(for: self) { - d[Key.userInfo] = userInfo + do { + opmlDocument = try RSOPMLParser.parseOPML(with: parserData) + } catch { + NSApplication.shared.presentError(error) + return + } + guard let parsedOPML = opmlDocument else { + return } - return d as NSDictionary + importOPML(parsedOPML) } +// func diskDictionary() -> NSDictionary { +// +// let diskObjects = children.compactMap { (object) -> [String: Any]? in +// +// if let folder = object as? Folder { +// return folder.dictionary +// } +// else if let feed = object as? Feed { +// return feed.dictionary +// } +// return nil +// } +// +// var d = [String: Any]() +// d[Key.children] = diskObjects as NSArray +// +// if let userInfo = delegate.userInfo(for: self) { +// d[Key.userInfo] = userInfo +// } +// +// return d as NSDictionary +// } + func saveToDisk() { dirty = false - let d = diskDictionary() - do { - try RSPlist.write(d, filePath: settingsFile) - } - catch let error as NSError { - NSApplication.shared.presentError(error) - } +// let d = diskDictionary() +// do { +// try RSPlist.write(d, filePath: settingsFile) +// } +// catch let error as NSError { +// NSApplication.shared.presentError(error) +// } let opmlDocumentString = opmlDocument() do { diff --git a/Frameworks/Account/Feed.swift b/Frameworks/Account/Feed.swift index 1bea926c9..2ec6d81fa 100644 --- a/Frameworks/Account/Feed.swift +++ b/Frameworks/Account/Feed.swift @@ -188,25 +188,25 @@ public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { return d[Key.url] != nil } - public var dictionary: [String: Any] { - var d = [String: Any]() - - d[Key.url] = url - - // feedID is not repeated when it’s the same as url - if (feedID != url) { - d[Key.feedID] = feedID - } - - if let name = name { - d[Key.name] = name - } - if let editedName = editedName { - d[Key.editedName] = editedName - } - - return d - } +// public var dictionary: [String: Any] { +// var d = [String: Any]() +// +// d[Key.url] = url +// +// // feedID is not repeated when it’s the same as url +// if (feedID != url) { +// d[Key.feedID] = feedID +// } +// +// if let name = name { +// d[Key.name] = name +// } +// if let editedName = editedName { +// d[Key.editedName] = editedName +// } +// +// return d +// } // MARK: - Debug diff --git a/Frameworks/Account/Folder.swift b/Frameworks/Account/Folder.swift index 5e0e940b6..acd72b241 100644 --- a/Frameworks/Account/Folder.swift +++ b/Frameworks/Account/Folder.swift @@ -73,36 +73,36 @@ public final class Folder: DisplayNameProvider, Container, UnreadCountProvider, } } - var dictionary: [String: Any] { - - var d = [String: Any]() - guard let account = account else { - return d - } - - if let name = name { - d[Key.name] = name - } +// var dictionary: [String: Any] { +// +// var d = [String: Any]() +// guard let account = account else { +// return d +// } +// +// if let name = name { +// d[Key.name] = name +// } +// +// let childObjects = children.compactMap { (child) -> [String: Any]? in +// +// if let feed = child as? Feed { +// return feed.dictionary +// } +// if let folder = child as? Folder, account.supportsSubFolders { +// return folder.dictionary +// } +// assertionFailure("Expected a feed or a folder."); +// return nil +// } +// +// if !childObjects.isEmpty { +// d[Key.children] = childObjects +// } +// +// return d +// } - let childObjects = children.compactMap { (child) -> [String: Any]? in - - if let feed = child as? Feed { - return feed.dictionary - } - if let folder = child as? Folder, account.supportsSubFolders { - return folder.dictionary - } - assertionFailure("Expected a feed or a folder."); - return nil - } - - if !childObjects.isEmpty { - d[Key.children] = childObjects - } - - return d - } - // MARK: Feeds func addFeed(_ feed: Feed) -> Bool {