Skip to content

Commit

Permalink
Merge pull request #331 from Planetable/fixes-export-planet
Browse files Browse the repository at this point in the history
Improved planet data package importing.
  • Loading branch information
livid authored Mar 24, 2024
2 parents 68070aa + 51e6f30 commit 66568f0
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 81 deletions.
7 changes: 4 additions & 3 deletions Planet/Entities/MyArticleModel+ImportExport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ import SwiftUI
extension MyArticleModel {
@MainActor
static func importArticles(fromURLs urls: [URL]) async throws {
guard urls.filter({ $0.lastPathComponent.hasSuffix(".article") }).count > 0 else {
let articleURLs: [URL] = urls.filter({ $0.lastPathComponent.hasSuffix(".article") })
guard articleURLs.count > 0 else {
throw PlanetError.InternalError
}
let planets = PlanetStore.shared.myPlanets
if planets.count > 1 {
PlanetStore.shared.importingArticleURLs = urls
PlanetStore.shared.importingArticleURLs = articleURLs
PlanetStore.shared.isShowingPlanetPicker = true
} else if planets.count == 1, let planet = planets.first {
try await importArticles(urls, toPlanet: planet)
try await importArticles(articleURLs, toPlanet: planet)
} else {
throw PlanetError.PlanetNotExistsError
}
Expand Down
3 changes: 3 additions & 0 deletions Planet/Entities/MyPlanetModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@ class MyPlanetModel: Equatable, Hashable, Identifiable, ObservableObject, Codabl
}

@MainActor static func importBackup(from path: URL) throws -> MyPlanetModel {
guard path.lastPathComponent.hasSuffix(".planet") else {
throw PlanetError.InternalError
}
Self.logger.info("Importing backup from \(path)")
let backupInfoPath = path.appendingPathComponent("planet.json", isDirectory: false)
let backupAssetsPath = path.appendingPathComponent("assets", isDirectory: true)
Expand Down
79 changes: 34 additions & 45 deletions Planet/Helper/KeyboardShortcutHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,38 +247,7 @@ class KeyboardShortcutHelper: ObservableObject {

Group {
Button {
let panel = NSOpenPanel()
panel.message = "Choose Planet Articles to Import"
panel.prompt = "Import"
panel.allowsMultipleSelection = true
let planetDataIdentifier = {
if let name = Bundle.main.object(forInfoDictionaryKey: "ORGANIZATION_IDENTIFIER_PREFIX") as? String {
return name + ".planet.article.data"
} else {
return "xyz.planetable.planet.article.data"
}
}()
panel.allowedContentTypes = [UTType(planetDataIdentifier)!]
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.canCreateDirectories = false
let response = panel.runModal()
guard response == .OK, panel.urls.count > 0 else { return }
Task { @MainActor in
do {
try await MyArticleModel.importArticles(fromURLs: panel.urls)
} catch {
debugPrint("failed to import articles: \(error)")
PlanetStore.shared.isShowingAlert = true
PlanetStore.shared.alertTitle = "Failed to Import Articles"
switch error {
case PlanetError.ImportPlanetArticlePublishingError:
PlanetStore.shared.alertMessage = "Planet is publishing progress, please try again later."
default:
PlanetStore.shared.alertMessage = error.localizedDescription
}
}
}
self.importArticleAction()
} label: {
Text("Import Article")
}
Expand All @@ -294,19 +263,41 @@ class KeyboardShortcutHelper: ObservableObject {
}
}

func importPlanetAction() {
// MARK: -

private func importArticleAction() {
let panel = NSOpenPanel()
panel.message = "Choose Planet Data"
panel.message = "Choose Planet Articles to Import"
panel.prompt = "Import"
panel.allowsMultipleSelection = false
let planetDataIdentifier = {
if let name = Bundle.main.object(forInfoDictionaryKey: "ORGANIZATION_IDENTIFIER_PREFIX") as? String {
return name + ".planet.data"
} else {
return "xyz.planetable.planet.data"
panel.allowsMultipleSelection = true
panel.allowedContentTypes = [.package]
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.canCreateDirectories = false
let response = panel.runModal()
guard response == .OK, panel.urls.count > 0 else { return }
Task { @MainActor in
do {
try await MyArticleModel.importArticles(fromURLs: panel.urls)
} catch {
PlanetStore.shared.isShowingAlert = true
PlanetStore.shared.alertTitle = "Failed to Import Articles"
switch error {
case PlanetError.ImportPlanetArticlePublishingError:
PlanetStore.shared.alertMessage = "Planet is publishing progress, please try again later."
default:
PlanetStore.shared.alertMessage = error.localizedDescription
}
}
}()
panel.allowedContentTypes = [UTType(planetDataIdentifier)!]
}
}

private func importPlanetAction() {
let panel = NSOpenPanel()
panel.message = "Choose Planet Data to Import"
panel.prompt = "Import"
panel.allowsMultipleSelection = false
panel.allowedContentTypes = [.package]
panel.canChooseDirectories = false
panel.canChooseFiles = true
panel.canCreateDirectories = false
Expand All @@ -318,13 +309,11 @@ class KeyboardShortcutHelper: ObservableObject {
PlanetStore.shared.myPlanets.insert(planet, at: 0)
PlanetStore.shared.selectedView = .myPlanet(planet)
} catch {
PlanetStore.shared.alert(title: "Failed to import planet")
PlanetStore.shared.alert(title: "Failed to Import Planet", message: error.localizedDescription)
}
}
}

// MARK: -

@ViewBuilder
private func publishedFoldersMenus() -> some View {
Menu("Published Folders") {
Expand Down
12 changes: 9 additions & 3 deletions Planet/PlanetAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ class PlanetAppDelegate: NSObject, NSApplicationDelegate {
}
} else if url.lastPathComponent.hasSuffix(".planet") {
Task { @MainActor in
let planet = try MyPlanetModel.importBackup(from: url)
PlanetStore.shared.myPlanets.insert(planet, at: 0)
PlanetStore.shared.selectedView = .myPlanet(planet)
do {
let planet = try MyPlanetModel.importBackup(from: url)
PlanetStore.shared.myPlanets.insert(planet, at: 0)
PlanetStore.shared.selectedView = .myPlanet(planet)
} catch {
PlanetStore.shared.isShowingAlert = true
PlanetStore.shared.alertTitle = "Failed to Import Planet"
PlanetStore.shared.alertMessage = error.localizedDescription
}
}
} else if url.lastPathComponent.hasSuffix(".article") {
Task { @MainActor in
Expand Down
2 changes: 1 addition & 1 deletion Planet/PlanetError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ enum PlanetError: Error {


extension PlanetError: LocalizedError {
public var errorDescription: String? {
public var localizedDescription: String? {
switch self {
case .PersistenceError:
return NSLocalizedString("Persistence Error", comment: "")
Expand Down
86 changes: 58 additions & 28 deletions Planet/Views/Sidebar/MyPlanetSidebarItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ struct MyPlanetSidebarItem: View {
@ObservedObject var planet: MyPlanetModel
@State var isShowingArchiveConfirmation = false
@State var isShowingDeleteConfirmation = false
@State var isExportingPlanet = false

var body: some View {
HStack(spacing: 4) {
Expand Down Expand Up @@ -151,7 +150,25 @@ struct MyPlanetSidebarItem: View {
Group {
Menu("Export Planet") {
Button {
isExportingPlanet = true
do {
try exportPlanet()
} catch PlanetError.FileExistsError {
Task { @MainActor in
self.planetStore.isShowingAlert = true
self.planetStore.alertTitle = "Failed to Share Planet Data"
self.planetStore.alertMessage = """
There is already an exported Planet in the destination.
We do not recommend override your backup.
Please choose another destination, or rename your previous backup.
"""
}
} catch {
Task { @MainActor in
self.planetStore.isShowingAlert = true
self.planetStore.alertTitle = "Failed to Share Planet Data"
self.planetStore.alertMessage = error.localizedDescription
}
}
} label: {
Text("Save as Planet Data File")
}
Expand Down Expand Up @@ -220,32 +237,32 @@ struct MyPlanetSidebarItem: View {
Text("Delete")
}
}
.fileImporter(
isPresented: $isExportingPlanet,
allowedContentTypes: [.directory]
) { result in
if let url = try? result.get() {
do {
try planet.exportBackup(to: url)
return
}
catch PlanetError.FileExistsError {
PlanetStore.shared.alert(
title: "Failed to Export Planet",
message: """
There is already an exported Planet in the destination. \
We do not recommend override your backup. \
Please choose another destination, or rename your previous backup.
"""
)
return
}
catch {
// use general alert
}
}
PlanetStore.shared.alert(title: "Failed to Export Planet", message: "Please try again.")
}
// .fileImporter(
// isPresented: $isExportingPlanet,
// allowedContentTypes: [.directory]
// ) { result in
// if let url = try? result.get() {
// do {
// try planet.exportBackup(to: url)
// return
// }
// catch PlanetError.FileExistsError {
// PlanetStore.shared.alert(
// title: "Failed to Export Planet",
// message: """
// There is already an exported Planet in the destination. \
// We do not recommend override your backup. \
// Please choose another destination, or rename your previous backup.
// """
// )
// return
// }
// catch {
// // use general alert
// }
// }
// PlanetStore.shared.alert(title: "Failed to Export Planet", message: "Please try again.")
// }
}

private func hasWorldWideWeb() -> Bool {
Expand Down Expand Up @@ -277,6 +294,19 @@ struct MyPlanetSidebarItem: View {
return conf
}

private func exportPlanet() throws {
let panel = NSOpenPanel()
panel.message = "Choose Directory to Export Planet"
panel.prompt = "Export"
panel.allowsMultipleSelection = false
panel.allowedContentTypes = [.folder]
panel.canChooseDirectories = true
panel.canChooseFiles = false
let response = panel.runModal()
guard response == .OK, let url = panel.url else { return }
try planet.exportBackup(to: url)
}

private func airDropPlanet() throws {
guard let service: NSSharingService = NSSharingService(named: .sendViaAirDrop) else {
throw PlanetError.ServiceAirDropNotExistsError
Expand Down
2 changes: 1 addition & 1 deletion Planet/versioning.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
CURRENT_PROJECT_VERSION = 1933
CURRENT_PROJECT_VERSION = 1934

0 comments on commit 66568f0

Please sign in to comment.