mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
When opening library items that were created locally, make sure they are synced
This commit is contained in:
parent
e773ea7e2b
commit
1386cc250a
3 changed files with 108 additions and 68 deletions
|
|
@ -20,28 +20,6 @@ public final class Networker: NSObject, URLSessionTaskDelegate {
|
|||
self.appEnvironment = appEnvironment
|
||||
self.urlSession = .shared
|
||||
}
|
||||
|
||||
public func createBackgroundSession() -> URLSession {
|
||||
let sessionConfig = URLSessionConfiguration.background(withIdentifier: "app.omnivoreapp.BackgroundSessionConfig-")
|
||||
sessionConfig.sharedContainerIdentifier = "group.app.omnivoreapp"
|
||||
return URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
|
||||
}
|
||||
|
||||
public func urlSession(_: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
||||
print("finished upload on original request", task.originalRequest, "error", error)
|
||||
if let httpResponse = task.response as? HTTPURLResponse {
|
||||
if 200 ... 299 ~= httpResponse.statusCode {
|
||||
// success
|
||||
if let requestId = task.originalRequest?.value(forHTTPHeaderField: "clientRequestId") {
|
||||
print("COMPLETED UPLOADED REQUEST ID", requestId)
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: NSNotification.LocallyCreatedItemSynced, object: nil, userInfo: ["objectID": requestId])
|
||||
}
|
||||
}
|
||||
}
|
||||
print("DONE")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Networker {
|
||||
|
|
|
|||
|
|
@ -35,61 +35,81 @@ public extension DataService {
|
|||
}
|
||||
}
|
||||
|
||||
// func syncPdf(item: LinkedItem, usingSession session: URLSession) async throws -> Bool {
|
||||
// try backgroundContext.performAndWait {
|
||||
// item.serverSyncStatus = Int64(ServerSyncStatus.isSyncing.rawValue)
|
||||
// try self.backgroundContext.save()
|
||||
// }
|
||||
//
|
||||
// let id = item.unwrappedID
|
||||
// let localPdfURL = item.localPdfURL
|
||||
// let url = item.unwrappedPageURLString
|
||||
// let uploadRequestUrl = try await uploadFileRequest(id: id, url: url)
|
||||
// return await try uploadFile(id: id, localPdfURL: localPdfURL, url: uploadRequestUrl, usingSession: session)
|
||||
// }
|
||||
private func updateLinkedItemStatus(id: String, status: ServerSyncStatus) async throws {
|
||||
try backgroundContext.performAndWait {
|
||||
let fetchRequest: NSFetchRequest<Models.LinkedItem> = LinkedItem.fetchRequest()
|
||||
fetchRequest.predicate = NSPredicate(format: "id == %@", id)
|
||||
|
||||
guard let linkedItem = (try? backgroundContext.fetch(fetchRequest))?.first else { return }
|
||||
linkedItem.serverSyncStatus = Int64(status.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
func syncPdf(id: String, localPdfURL: URL, url: String) async throws {
|
||||
// try backgroundContext.performAndWait {
|
||||
// item.serverSyncStatus = Int64(ServerSyncStatus.isSyncing.rawValue)
|
||||
// try self.backgroundContext.save()
|
||||
// }
|
||||
do {
|
||||
let uploadRequest = try await uploadFileRequest(id: id, url: url)
|
||||
if let urlString = uploadRequest.urlString, let uploadUrl = URL(string: urlString) {
|
||||
try await uploadFile(id: id, localPdfURL: localPdfURL, url: uploadUrl)
|
||||
// try await services.dataService.saveFilePublisher(requestId: requestId, uploadFileId: uploadFileID, url: url)
|
||||
} else {
|
||||
throw SaveArticleError.badData
|
||||
}
|
||||
|
||||
let uploadRequest = try await uploadFileRequest(id: id, url: url)
|
||||
if let urlString = uploadRequest.urlString, let uploadUrl = URL(string: urlString) {
|
||||
try await uploadFile(id: id, localPdfURL: localPdfURL, url: uploadUrl)
|
||||
// try await services.dataService.saveFilePublisher(requestId: requestId, uploadFileId: uploadFileID, url: url)
|
||||
} else {
|
||||
throw SaveArticleError.badData
|
||||
try await updateLinkedItemStatus(id: id, status: .isNSync)
|
||||
try backgroundContext.performAndWait {
|
||||
try backgroundContext.save()
|
||||
}
|
||||
} catch {
|
||||
backgroundContext.rollback()
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
func syncPage(id: String, originalHtml: String, title: String?, url: String) async throws {
|
||||
// try backgroundContext.performAndWait {
|
||||
// item.serverSyncStatus = Int64(ServerSyncStatus.isSyncing.rawValue)
|
||||
// try self.backgroundContext.save()
|
||||
// }
|
||||
try await savePage(id: id, url: url, title: title ?? url, originalHtml: originalHtml)
|
||||
do {
|
||||
try await savePage(id: id, url: url, title: title ?? url, originalHtml: originalHtml)
|
||||
try await updateLinkedItemStatus(id: id, status: .isNSync)
|
||||
try backgroundContext.performAndWait {
|
||||
try backgroundContext.save()
|
||||
}
|
||||
} catch {
|
||||
backgroundContext.performAndWait {
|
||||
backgroundContext.rollback()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
func syncUrl(id: String, url: String) async throws {
|
||||
try await saveURL(id: id, url: url)
|
||||
do {
|
||||
try await updateLinkedItemStatus(id: id, status: .isSyncing)
|
||||
try await saveURL(id: id, url: url)
|
||||
try backgroundContext.performAndWait {
|
||||
try backgroundContext.save()
|
||||
}
|
||||
} catch {
|
||||
backgroundContext.performAndWait {
|
||||
backgroundContext.rollback()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
func syncLocalCreatedLinkedItem(item: LinkedItem) {
|
||||
switch item.contentReader {
|
||||
case "PDF":
|
||||
// let id = item.unwrappedID
|
||||
// let localPdfURL = item.localPdfURL
|
||||
// let url = item.unwrappedPageURLString
|
||||
// Task {
|
||||
// let uploadRequestUrl = try await uploadFileRequest(id: id, url: url)
|
||||
// uploadFile(id: id, localPdfURL: localPdfURL, url: uploadRequestUrl)
|
||||
// try await backgroundContext.perform {
|
||||
// item.serverSyncStatus = Int64(ServerSyncStatus.isNSync.rawValue)
|
||||
// try self.backgroundContext.save()
|
||||
// }
|
||||
// }
|
||||
break
|
||||
let id = item.unwrappedID
|
||||
let localPdfURL = item.localPdfURL
|
||||
let url = item.unwrappedPageURLString
|
||||
|
||||
if let pdfUrlStr = localPdfURL, let localPdfURL = URL(string: pdfUrlStr) {
|
||||
Task {
|
||||
try await syncPdf(id: id, localPdfURL: localPdfURL, url: url)
|
||||
}
|
||||
} else {
|
||||
// TODO: This is an invalid object, we should have a way of reflecting that with an error state
|
||||
// updateLinkedItemStatus(id: id, status: .)
|
||||
}
|
||||
case "WEB":
|
||||
let id = item.unwrappedID
|
||||
let url = item.unwrappedPageURLString
|
||||
|
|
@ -98,13 +118,9 @@ public extension DataService {
|
|||
|
||||
Task {
|
||||
if let originalHtml = originalHtml {
|
||||
try await savePage(id: id, url: url, title: title, originalHtml: originalHtml)
|
||||
try await syncPage(id: id, originalHtml: originalHtml, title: title, url: url)
|
||||
} else {
|
||||
try await saveURL(id: id, url: url)
|
||||
}
|
||||
try await backgroundContext.perform {
|
||||
item.serverSyncStatus = Int64(ServerSyncStatus.isNSync.rawValue)
|
||||
try self.backgroundContext.save()
|
||||
try await syncUrl(id: id, url: url)
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ extension DataService {
|
|||
return cachedContent
|
||||
}
|
||||
|
||||
// If the page was locally created, make sure they are synced before we pull content
|
||||
await syncUnsyncedArticleContent(itemID: itemID)
|
||||
|
||||
enum QueryResult {
|
||||
case success(result: ArticleProps)
|
||||
case error(error: String)
|
||||
|
|
@ -304,6 +307,49 @@ extension DataService {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
func syncUnsyncedArticleContent(itemID: String) async {
|
||||
let linkedItemFetchRequest: NSFetchRequest<Models.LinkedItem> = LinkedItem.fetchRequest()
|
||||
linkedItemFetchRequest.predicate = NSPredicate(
|
||||
format: "id == %@", itemID
|
||||
)
|
||||
|
||||
let context = backgroundContext
|
||||
|
||||
var id: String?
|
||||
var url: String?
|
||||
var title: String?
|
||||
var originalHtml: String?
|
||||
var serverSyncStatus: Int64?
|
||||
|
||||
backgroundContext.performAndWait {
|
||||
guard let linkedItem = try? context.fetch(linkedItemFetchRequest).first else { return }
|
||||
id = linkedItem.unwrappedID
|
||||
url = linkedItem.unwrappedPageURLString
|
||||
title = linkedItem.unwrappedTitle
|
||||
originalHtml = linkedItem.originalHtml
|
||||
serverSyncStatus = linkedItem.serverSyncStatus
|
||||
}
|
||||
|
||||
if let id = id, let url = url, let title = title,
|
||||
let serverSyncStatus = serverSyncStatus,
|
||||
serverSyncStatus != ServerSyncStatus.isNSync.rawValue
|
||||
{
|
||||
do {
|
||||
if let originalHtml = originalHtml {
|
||||
try await savePage(id: id, url: url, title: title, originalHtml: originalHtml)
|
||||
} else {
|
||||
try await saveURL(id: id, url: url)
|
||||
}
|
||||
try backgroundContext.performAndWait {
|
||||
try backgroundContext.save()
|
||||
}
|
||||
} catch {
|
||||
// We don't propogate these errors, we just let it pass through so
|
||||
// the user can attempt to fetch content again.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ArticleContentStatus {
|
||||
|
|
|
|||
Loading…
Reference in a new issue