You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
9.9 KiB
279 lines
9.9 KiB
//
|
|
// MastodonDataManager.swift
|
|
// elpha-ios
|
|
//
|
|
// Created by Dwayne Harris on 10/1/18.
|
|
// Copyright © 2018 Elpha. All rights reserved.
|
|
//
|
|
|
|
import CoreData
|
|
import Foundation
|
|
import MastodonKit
|
|
|
|
public class MastodonDataManager {
|
|
static func upsertAccount(_ remoteAccount: Account) -> AccountMO? {
|
|
func saveAccount(_ account: AccountMO) -> AccountMO? {
|
|
account.id = remoteAccount.id
|
|
account.username = remoteAccount.username
|
|
account.acct = remoteAccount.acct
|
|
account.displayName = remoteAccount.displayName
|
|
account.note = remoteAccount.note
|
|
account.url = remoteAccount.url
|
|
account.avatarURL = URL(string: remoteAccount.avatar)
|
|
account.avatarStaticURL = URL(string: remoteAccount.avatarStatic)
|
|
account.headerURL = URL(string: remoteAccount.header)
|
|
account.headerStaticURL = URL(string: remoteAccount.headerStatic)
|
|
account.locked = remoteAccount.locked
|
|
account.createdAt = remoteAccount.createdAt
|
|
account.followersCount = Int32(remoteAccount.followersCount)
|
|
account.followingCount = Int32(remoteAccount.followingCount)
|
|
account.statusesCount = Int32(remoteAccount.statusesCount)
|
|
|
|
return account
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<AccountMO>(entityName: "Account")
|
|
request.predicate = NSPredicate(format: "acct == %@", remoteAccount.acct)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let account = results.first {
|
|
return saveAccount(account)
|
|
} else {
|
|
return saveAccount(AccountMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func upsertAttachment(_ remoteAttachment: Attachment) -> AttachmentMO? {
|
|
func saveAttachment(_ attachment: AttachmentMO) -> AttachmentMO? {
|
|
attachment.id = remoteAttachment.id
|
|
attachment.type = remoteAttachment.type.rawValue
|
|
attachment.url = URL(string: remoteAttachment.url)
|
|
attachment.previewURL = URL(string: remoteAttachment.previewURL)
|
|
attachment.remoteURL = remoteAttachment.remoteURL
|
|
attachment.textURL = remoteAttachment.textURL
|
|
|
|
return attachment
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<AttachmentMO>(entityName: "Attachment")
|
|
request.predicate = NSPredicate(format: "id == %@", remoteAttachment.id)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let attachment = results.first {
|
|
return saveAttachment(attachment)
|
|
} else {
|
|
return saveAttachment(AttachmentMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func upsertMention(_ remoteMention: Mention) -> MentionMO? {
|
|
func saveMention(_ mention: MentionMO) -> MentionMO? {
|
|
mention.id = remoteMention.id
|
|
mention.username = remoteMention.username
|
|
mention.acct = remoteMention.acct
|
|
mention.url = URL(string: remoteMention.url)
|
|
|
|
return mention
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<MentionMO>(entityName: "Mention")
|
|
request.predicate = NSPredicate(format: "id == %@", remoteMention.id)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let mention = results.first {
|
|
return saveMention(mention)
|
|
} else {
|
|
return saveMention(MentionMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func upsertTag(_ remoteTag: Tag) -> TagMO? {
|
|
func saveTag(_ tag: TagMO) -> TagMO? {
|
|
tag.name = remoteTag.name
|
|
tag.url = URL(string: remoteTag.url)
|
|
|
|
return tag
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<TagMO>(entityName: "Tag")
|
|
request.predicate = NSPredicate(format: "name == %@", remoteTag.name)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let tag = results.first {
|
|
return saveTag(tag)
|
|
} else {
|
|
return saveTag(TagMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func upsertApp(_ remoteApp: Application) -> AppMO? {
|
|
func saveApp(_ app: AppMO) -> AppMO? {
|
|
app.name = remoteApp.name
|
|
|
|
if let website = remoteApp.website {
|
|
app.website = URL(string: website)
|
|
}
|
|
|
|
return app
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<AppMO>(entityName: "App")
|
|
request.predicate = NSPredicate(format: "name == %@", remoteApp.name)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let tag = results.first {
|
|
return saveApp(tag)
|
|
} else {
|
|
return saveApp(AppMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func upsertStatus(_ remoteStatus: Status) -> StatusMO? {
|
|
func saveStatus(_ status: StatusMO) -> StatusMO? {
|
|
status.id = remoteStatus.id
|
|
status.uri = URL(string: remoteStatus.uri)
|
|
status.url = remoteStatus.url
|
|
status.account = MastodonDataManager.upsertAccount(remoteStatus.account)
|
|
status.inReplyToID = remoteStatus.inReplyToID
|
|
status.inReplyToAccountID = remoteStatus.inReplyToAccountID
|
|
status.content = remoteStatus.content
|
|
status.createdAt = remoteStatus.createdAt
|
|
status.reblogsCount = Int32(remoteStatus.reblogsCount)
|
|
status.favouritesCount = Int32(remoteStatus.favouritesCount)
|
|
status.reblogged = remoteStatus.reblogged ?? false
|
|
status.favourited = remoteStatus.favourited ?? false
|
|
status.sensitive = remoteStatus.sensitive ?? false
|
|
status.pinned = remoteStatus.pinned ?? false
|
|
status.spoilerText = remoteStatus.spoilerText
|
|
status.visibility = remoteStatus.visibility.rawValue
|
|
|
|
if let app = remoteStatus.application {
|
|
status.app = MastodonDataManager.upsertApp(app)
|
|
}
|
|
|
|
remoteStatus.mediaAttachments.forEach { attachment in
|
|
if let attachment = MastodonDataManager.upsertAttachment(attachment) {
|
|
status.mutableSetValue(forKey: "attachments").add(attachment)
|
|
}
|
|
}
|
|
|
|
remoteStatus.mentions.forEach { mention in
|
|
if let mention = MastodonDataManager.upsertMention(mention) {
|
|
status.mutableSetValue(forKey: "mentions").add(mention)
|
|
}
|
|
}
|
|
|
|
remoteStatus.tags.forEach { tag in
|
|
if let tag = MastodonDataManager.upsertTag(tag) {
|
|
status.mutableSetValue(forKey: "tags").add(tag)
|
|
}
|
|
}
|
|
|
|
if let reblog = remoteStatus.reblog {
|
|
let savedReblog = upsertStatus(reblog)
|
|
status.reblog = savedReblog
|
|
}
|
|
|
|
return status
|
|
}
|
|
|
|
let context = CoreDataManager.shared.getContext()
|
|
let request = NSFetchRequest<StatusMO>(entityName: "Status")
|
|
request.predicate = NSPredicate(format: "id == %@", remoteStatus.id)
|
|
|
|
do {
|
|
let results = try context.fetch(request)
|
|
if let status = results.first {
|
|
return saveStatus(status)
|
|
} else {
|
|
return saveStatus(StatusMO(context: context))
|
|
}
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func saveClient(id: String, clientID: String, clientSecret: String, url: String) -> ClientMO {
|
|
let client = ClientMO(context: CoreDataManager.shared.getContext())
|
|
client.id = id
|
|
client.clientID = clientID
|
|
client.clientSecret = clientSecret
|
|
client.url = url
|
|
|
|
CoreDataManager.shared.saveContext()
|
|
return client
|
|
}
|
|
|
|
static func getAccountByID(_ id: String) -> AccountMO? {
|
|
let request = NSFetchRequest<AccountMO>(entityName: "Account")
|
|
request.predicate = NSPredicate(format: "id == %@", id)
|
|
|
|
do {
|
|
let results = try CoreDataManager.shared.getContext().fetch(request)
|
|
guard let account = results.first else {
|
|
return nil
|
|
}
|
|
|
|
return account
|
|
} catch {
|
|
print("\(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func getRemoteAccountByID(id: String, completion: @escaping (AccountMO?, Error?) -> Void ) {
|
|
if let account = getAccountByID(id) {
|
|
completion(account, nil)
|
|
return
|
|
}
|
|
|
|
guard let client = AuthenticationManager.shared.getMKClientForSelectedSession() else {
|
|
completion(nil, NSError())
|
|
return
|
|
}
|
|
|
|
let request = Accounts.account(id: id)
|
|
|
|
client.run(request) { result in
|
|
switch result {
|
|
case .success(let account, _):
|
|
completion(upsertAccount(account), nil)
|
|
return
|
|
case .failure(let error):
|
|
completion(nil, error)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|