192 lines
5.3 KiB
Swift
192 lines
5.3 KiB
Swift
//
|
|
// LocalArticle.swift
|
|
// Evergreen
|
|
//
|
|
// Created by Brent Simmons on 4/23/16.
|
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import DataModel
|
|
import RSParser
|
|
|
|
public final class LocalArticle: Article, Hashable {
|
|
|
|
public let account: Account?
|
|
public let feedID: String
|
|
public let articleID: String
|
|
public var status: ArticleStatus!
|
|
|
|
public var guid: String?
|
|
public var title: String?
|
|
private var _body: String?
|
|
fileprivate var bodyData: Data?
|
|
|
|
public var body: String? {
|
|
get {
|
|
if _body == nil, let d = bodyData {
|
|
// print(title)
|
|
if let s = NSString(data: d, encoding: String.Encoding.utf8.rawValue) as String? {
|
|
_body = s
|
|
bodyData = nil
|
|
}
|
|
}
|
|
return _body
|
|
}
|
|
set {
|
|
_body = newValue
|
|
}
|
|
}
|
|
|
|
public var link: String?
|
|
public var permalink: String?
|
|
public var author: String?
|
|
|
|
public var datePublished: Date?
|
|
public var dateModified: Date?
|
|
|
|
private let _hash: Int
|
|
|
|
public init(account: Account, feedID: String, articleID: String) {
|
|
|
|
self.account = account
|
|
self.feedID = feedID
|
|
self.articleID = articleID
|
|
self._hash = databaseID.hashValue
|
|
}
|
|
|
|
public override func isEqual(_ object: Any?) -> Bool {
|
|
|
|
if let otherArticle = object as? LocalArticle {
|
|
return otherArticle === self
|
|
}
|
|
return false
|
|
}
|
|
|
|
// static public func ==(lhs: LocalArticle, rhs: LocalArticle) -> Bool {
|
|
//
|
|
// if lhs === rhs {
|
|
// return true
|
|
// }
|
|
//
|
|
// return lhs.hashValue == rhs.hashValue && lhs.articleID == rhs.articleID && lhs.feedID == rhs.feedID && lhs.guid == rhs.guid && lhs.title == rhs.title && lhs.body == rhs.body && lhs.link == rhs.link && lhs.permalink == rhs.permalink && lhs.author == rhs.author && lhs.datePublished == rhs.datePublished && lhs.status == rhs.status;
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
// MARK: LocalDatabase support
|
|
|
|
import RSCore
|
|
import RSDatabase
|
|
import RSParser
|
|
|
|
// Database columns *and* value keys.
|
|
|
|
let articleIDKey = "articleID"
|
|
private let articleFeedIDKey = "feedID"
|
|
private let articleGuidKey = "guid"
|
|
private let articleTitleKey = "title"
|
|
private let articleBodyKey = "body"
|
|
private let articleDatePublishedKey = "datePublished"
|
|
private let articleDateModifiedKey = "dateModified"
|
|
private let articleLinkKey = "link"
|
|
private let articlePermalinkKey = "permalink"
|
|
private let articleAuthorKey = "author"
|
|
|
|
private let mergeablePropertyNames = [articleGuidKey, articleTitleKey, articleBodyKey, articleDatePublishedKey, articleDateModifiedKey, articleLinkKey, articlePermalinkKey, articleAuthorKey]
|
|
|
|
public extension LocalArticle {
|
|
|
|
convenience init(account: Account, feedID: String, parsedItem: ParsedItem) {
|
|
|
|
self.init(account: account, feedID: feedID, articleID: parsedItem.databaseID)
|
|
|
|
self.guid = parsedItem.uniqueID
|
|
self.title = parsedItem.title
|
|
self.body = (parsedItem.contentHTML ?? parsedItem.contentText) ?? ""
|
|
self.datePublished = parsedItem.datePublished
|
|
self.dateModified = parsedItem.dateModified
|
|
self.link = parsedItem.externalURL
|
|
self.permalink = parsedItem.url
|
|
self.authors = parsedItem.authors
|
|
}
|
|
|
|
private enum ColumnIndex: Int {
|
|
case articleID = 0, feedID, guid, title, body, datePublished, dateModified, link, permalink, author
|
|
}
|
|
|
|
convenience init?(account: Account, row: FMResultSet) {
|
|
|
|
guard let articleID = row.string(forColumnIndex: Int32(ColumnIndex.articleID.rawValue)), let feedID = row.string(forColumnIndex: Int32(ColumnIndex.feedID.rawValue)) else {
|
|
return nil
|
|
}
|
|
|
|
self.init(account: account, feedID: feedID, articleID: articleID)
|
|
|
|
self.guid = row.string(forColumnIndex: Int32(ColumnIndex.guid.rawValue))
|
|
self.title = row.string(forColumnIndex: Int32(ColumnIndex.title.rawValue))
|
|
self.bodyData = row.data(forColumnIndex: Int32(ColumnIndex.body.rawValue))
|
|
self.datePublished = row.date(forColumnIndex: Int32(ColumnIndex.datePublished.rawValue))
|
|
self.dateModified = row.date(forColumnIndex: Int32(ColumnIndex.dateModified.rawValue))
|
|
self.link = row.string(forColumnIndex: Int32(ColumnIndex.link.rawValue))
|
|
self.permalink = row.string(forColumnIndex: Int32(ColumnIndex.permalink.rawValue))
|
|
self.author = row.string(forColumnIndex: Int32(ColumnIndex.author.rawValue))
|
|
}
|
|
|
|
var databaseDictionary: NSDictionary {
|
|
get {
|
|
return createDatabaseDictionary()
|
|
}
|
|
}
|
|
|
|
func updateWithParsedArticle(_ parsedArticle: ParsedItem) -> NSDictionary? {
|
|
|
|
let d: NSDictionary = rs_mergeValues(withObjectReturningChanges: parsedArticle, propertyNames: mergeablePropertyNames) as NSDictionary
|
|
if d.count < 1 {
|
|
return nil
|
|
}
|
|
|
|
let databaseDictionary: NSMutableDictionary = d.mutableCopy() as! NSMutableDictionary
|
|
databaseDictionary[articleIDKey] = articleIDKey
|
|
return databaseDictionary
|
|
}
|
|
|
|
private func createDatabaseDictionary() -> NSDictionary {
|
|
|
|
// Includes only non-nil values.
|
|
|
|
let d = NSMutableDictionary()
|
|
|
|
d[articleIDKey] = articleID
|
|
d[articleFeedIDKey] = feedID
|
|
|
|
if let guid = self.guid {
|
|
d[articleGuidKey] = guid
|
|
}
|
|
if let title = self.title {
|
|
d[articleTitleKey] = title
|
|
}
|
|
if let body = self.body {
|
|
d[articleBodyKey] = body
|
|
}
|
|
if let datePublished = self.datePublished {
|
|
d[articleDatePublishedKey] = datePublished
|
|
}
|
|
if let dateModified = self.dateModified {
|
|
d[articleDateModifiedKey] = dateModified
|
|
}
|
|
if let link = self.link {
|
|
d[articleLinkKey] = link
|
|
}
|
|
if let permalink = self.permalink {
|
|
d[articlePermalinkKey] = permalink
|
|
}
|
|
if let author = self.author {
|
|
d[articleAuthorKey] = author
|
|
}
|
|
|
|
return d
|
|
}
|
|
}
|