Prevent more than one OPML import from being run at the same time.
This commit is contained in:
parent
b89f088917
commit
0a9bf2aef0
|
@ -36,9 +36,25 @@ public enum AccountType: Int {
|
|||
// TODO: more
|
||||
}
|
||||
|
||||
public enum AccountError: Error {
|
||||
public enum AccountError: LocalizedError {
|
||||
|
||||
case createErrorNotFound
|
||||
case createErrorAlreadySubscribed
|
||||
case opmlImportInProgress
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .opmlImportInProgress:
|
||||
return NSLocalizedString("An OPML import for this account is already running.", comment: "Import running")
|
||||
default:
|
||||
return NSLocalizedString("An unknown error occurred.", comment: "Unknown error")
|
||||
}
|
||||
}
|
||||
|
||||
public var recoverySuggestion: String? {
|
||||
return NSLocalizedString("Please try again later.", comment: "Try later")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final class Account: DisplayNameProvider, UnreadCountProvider, Container, Hashable {
|
||||
|
@ -299,6 +315,12 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
}
|
||||
|
||||
public func importOPML(_ opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
guard !delegate.opmlImportInProgress else {
|
||||
completion(.failure(AccountError.opmlImportInProgress))
|
||||
return
|
||||
}
|
||||
|
||||
delegate.importOPML(for: self, opmlFile: opmlFile) { [weak self] result in
|
||||
switch result {
|
||||
case .success:
|
||||
|
@ -312,6 +334,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public func markArticles(_ articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<Article>? {
|
||||
|
|
|
@ -14,6 +14,8 @@ protocol AccountDelegate {
|
|||
|
||||
// Local account does not; some synced accounts might.
|
||||
var supportsSubFolders: Bool { get }
|
||||
var opmlImportInProgress: Bool { get }
|
||||
|
||||
var server: String? { get }
|
||||
var credentials: Credentials? { get set }
|
||||
var accountMetadata: AccountMetadata? { get set }
|
||||
|
|
|
@ -32,6 +32,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
|
||||
let supportsSubFolders = false
|
||||
let server: String? = "api.feedbin.com"
|
||||
var opmlImportInProgress = false
|
||||
|
||||
var credentials: Credentials? {
|
||||
didSet {
|
||||
|
@ -185,7 +186,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
}
|
||||
|
||||
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
|
||||
var fileData: Data?
|
||||
|
||||
do {
|
||||
|
@ -201,13 +202,15 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
}
|
||||
|
||||
os_log(.debug, log: log, "Begin importing OPML...")
|
||||
|
||||
opmlImportInProgress = true
|
||||
|
||||
caller.importOPML(opmlData: opmlData) { [weak self] result in
|
||||
switch result {
|
||||
case .success(let importResult):
|
||||
if importResult.complete {
|
||||
guard let self = self else { return }
|
||||
os_log(.debug, log: self.log, "Import OPML done.")
|
||||
self.opmlImportInProgress = false
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(()))
|
||||
}
|
||||
|
@ -217,6 +220,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
case .failure(let error):
|
||||
guard let self = self else { return }
|
||||
os_log(.debug, log: self.log, "Import OPML failed.")
|
||||
self.opmlImportInProgress = false
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(error))
|
||||
}
|
||||
|
@ -225,41 +229,6 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
|
||||
}
|
||||
|
||||
private func checkImportResult(opmlImportResultID: Int, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
Timer.scheduledTimer(withTimeInterval: 15, repeats: true) { [weak self] timer in
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
os_log(.debug, log: self.log, "Checking status of OPML import...")
|
||||
|
||||
self.caller.retrieveOPMLImportResult(importID: opmlImportResultID) { result in
|
||||
switch result {
|
||||
case .success(let importResult):
|
||||
if let result = importResult, result.complete {
|
||||
os_log(.debug, log: self.log, "Checking status of OPML import successfully completed.")
|
||||
timer.invalidate()
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
case .failure(let error):
|
||||
os_log(.debug, log: self.log, "Import OPML check failed.")
|
||||
timer.invalidate()
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
caller.renameTag(oldName: folder.name ?? "", newName: name) { result in
|
||||
|
@ -546,6 +515,43 @@ private extension FeedbinAccountDelegate {
|
|||
|
||||
}
|
||||
|
||||
func checkImportResult(opmlImportResultID: Int, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
Timer.scheduledTimer(withTimeInterval: 15, repeats: true) { [weak self] timer in
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
os_log(.debug, log: self.log, "Checking status of OPML import...")
|
||||
|
||||
self.caller.retrieveOPMLImportResult(importID: opmlImportResultID) { result in
|
||||
switch result {
|
||||
case .success(let importResult):
|
||||
if let result = importResult, result.complete {
|
||||
os_log(.debug, log: self.log, "Checking status of OPML import successfully completed.")
|
||||
timer.invalidate()
|
||||
self.opmlImportInProgress = false
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
case .failure(let error):
|
||||
os_log(.debug, log: self.log, "Import OPML check failed.")
|
||||
timer.invalidate()
|
||||
self.opmlImportInProgress = false
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func syncFolders(_ account: Account, _ tags: [FeedbinTag]?) {
|
||||
|
||||
guard let tags = tags else { return }
|
||||
|
|
|
@ -18,6 +18,8 @@ public enum LocalAccountDelegateError: String, Error {
|
|||
final class LocalAccountDelegate: AccountDelegate {
|
||||
|
||||
let supportsSubFolders = false
|
||||
let opmlImportInProgress = false
|
||||
|
||||
let server: String? = nil
|
||||
var credentials: Credentials?
|
||||
var accountMetadata: AccountMetadata?
|
||||
|
|
Loading…
Reference in New Issue