Files
omnivore/apple/OmnivoreKit/Sources/Services/InternalModels/InternalLibraryItem.swift
Jackson Harper e63b4f9b2c Abstract out fetching from view model so we can better handle multiple fetch folders
Rename LinkedItem to LibraryItem

More on following

Add new fetcher

Tab bar
2023-12-07 17:15:52 +08:00

174 lines
4.9 KiB
Swift

import CoreData
import Foundation
import Models
struct InternalLibraryItem {
let id: String
let title: String
let createdAt: Date
let savedAt: Date
let readAt: Date?
let updatedAt: Date
let folder: String
let state: ArticleContentStatus
var readingProgress: Double
var readingProgressAnchor: Int
let imageURLString: String?
let onDeviceImageURLString: String?
let documentDirectoryPath: String?
let pageURLString: String
let descriptionText: String?
let publisherURLString: String?
let siteName: String?
let author: String?
let publishDate: Date?
let slug: String
let isArchived: Bool
let contentReader: String?
let originalHtml: String?
let language: String?
let wordsCount: Int?
let downloadURL: String
let recommendations: [InternalRecommendation]
var labels: [InternalLinkedItemLabel]
var isPDF: Bool {
if let contentReader = contentReader {
return contentReader == "PDF"
}
return pageURLString.hasSuffix("pdf")
}
func asManagedObject(inContext context: NSManagedObjectContext) -> LibraryItem {
let existingItem = LibraryItem.lookup(byID: id, inContext: context)
let linkedItem = existingItem ?? LibraryItem(entity: LibraryItem.entity(), insertInto: context)
linkedItem.id = id
linkedItem.title = title
linkedItem.createdAt = createdAt
linkedItem.savedAt = savedAt
linkedItem.updatedAt = updatedAt
linkedItem.readAt = readAt
linkedItem.folder = folder
linkedItem.state = state.rawValue
linkedItem.readingProgress = readingProgress
linkedItem.readingProgressAnchor = Int64(readingProgressAnchor)
linkedItem.imageURLString = imageURLString
linkedItem.onDeviceImageURLString = onDeviceImageURLString
linkedItem.pageURLString = pageURLString
linkedItem.descriptionText = descriptionText
linkedItem.publisherURLString = publisherURLString
linkedItem.siteName = siteName
linkedItem.author = author
linkedItem.publishDate = publishDate
linkedItem.readAt = readAt
linkedItem.slug = slug
linkedItem.isArchived = isArchived
linkedItem.contentReader = contentReader
linkedItem.originalHtml = originalHtml
linkedItem.language = language
linkedItem.wordsCount = Int64(wordsCount ?? 0)
linkedItem.downloadURL = downloadURL
// Remove existing labels in case a label had been deleted
if let existingLabels = linkedItem.labels {
linkedItem.removeFromLabels(existingLabels)
}
for label in labels {
linkedItem.addToLabels(label.asManagedObject(inContext: context))
}
if let existingRecommendation = linkedItem.recommendations {
linkedItem.removeFromRecommendations(existingRecommendation)
}
for recommendation in recommendations {
linkedItem.addToRecommendations(recommendation.asManagedObject(inContext: context))
}
return linkedItem
}
}
extension Sequence where Element == InternalLibraryItem {
func persist(context: NSManagedObjectContext) -> [NSManagedObjectID]? {
var linkedItems: [LibraryItem]?
context.performAndWait {
linkedItems = map { $0.asManagedObject(inContext: context) }
do {
try context.save()
print("LinkedItems saved succesfully")
} catch {
context.rollback()
print(error)
print("Failed to save LinkedItems: \(error.localizedDescription)")
}
}
if let linkedItems = linkedItems {
return linkedItems.map(\.objectID)
} else {
return nil
}
}
}
public extension DataService {
func persist(jsonArticle: JSONArticle) -> NSManagedObjectID? {
jsonArticle.persistAsLinkedItem(context: backgroundContext)
}
}
extension JSONArticle {
func persistAsLinkedItem(context: NSManagedObjectContext) -> NSManagedObjectID? {
var objectID: NSManagedObjectID?
let internalLinkedItem = InternalLibraryItem(
id: id,
title: title,
createdAt: createdAt,
savedAt: savedAt,
readAt: readAt,
updatedAt: updatedAt,
folder: folder,
state: .succeeded,
readingProgress: readingProgressPercent,
readingProgressAnchor: readingProgressAnchorIndex,
imageURLString: image,
onDeviceImageURLString: nil,
documentDirectoryPath: nil,
pageURLString: url,
descriptionText: title,
publisherURLString: nil,
siteName: nil,
author: nil,
publishDate: nil,
slug: slug,
isArchived: isArchived,
contentReader: contentReader,
originalHtml: nil,
language: language,
wordsCount: wordsCount,
downloadURL: downloadURL,
recommendations: [],
labels: []
)
context.performAndWait {
objectID = internalLinkedItem.asManagedObject(inContext: context).objectID
do {
try context.save()
logger.debug("LinkedItem saved succesfully")
} catch {
context.rollback()
logger.debug("Failed to save LinkedItem: \(error.localizedDescription)")
}
}
return objectID
}
}