271 lines
9.4 KiB
Swift
271 lines
9.4 KiB
Swift
//
|
|
// LibraryImport.swift
|
|
// Zockerhoehle
|
|
//
|
|
// Created by Julian-Steffen Müller on 20.11.19.
|
|
// Copyright © 2019 Julian-Steffen Müller. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import CoreData
|
|
|
|
// MARK: - Library Import
|
|
|
|
class LibraryImport {
|
|
let CDContext : NSManagedObjectContext
|
|
|
|
init(context CDContext: NSManagedObjectContext = CDManager.shared.viewContext) {
|
|
self.CDContext = CDContext
|
|
}
|
|
|
|
static func backupName(from filename : String) -> String? {
|
|
if filename.hasPrefix("libExp_") && filename.hasSuffix(".json") {
|
|
var backupName = filename
|
|
backupName.removeFirst("libExp_".count)
|
|
backupName.removeLast(".json".count)
|
|
return backupName
|
|
}else{
|
|
return .none
|
|
}
|
|
}
|
|
|
|
func backupFiles() -> [String] {
|
|
do {
|
|
guard let documentDirectory = ICloudManager.backup_folder else { return [] }
|
|
|
|
let filesInDocumentsDir = try FileManager.default.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: .none, options: [])
|
|
|
|
let backupFiles = filesInDocumentsDir.filter{
|
|
$0.isFileURL
|
|
}.map {
|
|
$0.lastPathComponent
|
|
}.filter {
|
|
$0.hasPrefix("libExp_") && $0.hasSuffix(".json")
|
|
}.sorted(by: { $0 > $1 })
|
|
|
|
return backupFiles
|
|
|
|
}catch let error {
|
|
print(error)
|
|
print("LibraryImport::backupFiles - Error reading files from Document directory!")
|
|
}
|
|
|
|
return []
|
|
}
|
|
|
|
func resetDatabase(games : [Game], accessories : [Accessory], consoles : [Console], gameSeries: [GameSeries]) {
|
|
self.CDContext.performAndWait {
|
|
// let gamesFR = NSFetchRequest<Game>(entityName: "Game")
|
|
// let accessoriesFR = NSFetchRequest<Accessory>(entityName: "Accessory")
|
|
// let consoleFR = NSFetchRequest<Console>(entityName: "Console")
|
|
// let gameSeriesFR = NSFetchRequest<GameSeries>(entityName: "GameSeries")
|
|
//
|
|
// let games = try CDManager.shared.viewContext.fetch(gamesFR) as [NSManagedObject]
|
|
// let accessories = try CDManager.shared.viewContext.fetch(accessoriesFR) as [NSManagedObject]
|
|
// let consoles = try CDManager.shared.viewContext.fetch(consoleFR) as [NSManagedObject]
|
|
// let gameSeries = try CDManager.shared.viewContext.fetch(gameSeriesFR) as [NSManagedObject]
|
|
//
|
|
var core_data_objects : [NSManagedObject] = []
|
|
core_data_objects.append(contentsOf: games)
|
|
core_data_objects.append(contentsOf: accessories)
|
|
core_data_objects.append(contentsOf: consoles)
|
|
core_data_objects.append(contentsOf: gameSeries)
|
|
|
|
for cdObject in core_data_objects {
|
|
CDManager.shared.viewContext.delete(cdObject)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func noneIfEmpty(_ str : String?) -> String? {
|
|
if str == "" { return .none }
|
|
return str
|
|
}
|
|
|
|
private func makeCDGame(from game: BHLGame, _ gameDict: inout [UUID : Game], _ cdConsole: Console) {
|
|
let cdGame = Game(context: self.CDContext)
|
|
gameDict[game.uuid] = cdGame
|
|
cdGame.name = game.name ?? "n/a"
|
|
cdGame.uuid = game.uuid
|
|
cdGame.inWishlist = game.inWishlist
|
|
cdGame.isFinished = game.isFinished
|
|
cdGame.finishedDate = game.finishedDate
|
|
cdGame.lentTo = game.lentTo
|
|
cdGame.cover_icloud_path = game.cover_icloud_path
|
|
cdGame.notes = noneIfEmpty(game.notes)
|
|
cdGame.pickupDescription = noneIfEmpty(game.pickupDescription)
|
|
cdGame.isDigital = game.isDigital
|
|
cdGame.playtime_h = game.playtime_h ?? 0
|
|
cdGame.playtime_min = game.playtime_min ?? 0
|
|
|
|
if let pickupDate = game.pickupDate, let date = Date.from(string: pickupDate) {
|
|
cdGame.pickupDate = date
|
|
}else{
|
|
print("Could not decode date '\(game.pickupDate)' for game '\(cdGame.name)'")
|
|
}
|
|
|
|
if let date = Date.from(string: game.releaseDate) {
|
|
cdGame.releaseDate = date
|
|
|
|
}else{
|
|
print("Could not decode date '\(game.releaseDate)' for game '\(cdGame.name)'")
|
|
}
|
|
|
|
cdConsole.addToGames(cdGame)
|
|
cdGame.console = cdConsole
|
|
print("Imported: \(cdGame.name) for \(cdConsole.name)")
|
|
}
|
|
|
|
private func makeCDAccessory(from accessory: BHLAccessory, _ accessoryDict: inout [UUID : Accessory], _ cdConsole: Console) {
|
|
let cdAccessory = Accessory(context: self.CDContext)
|
|
accessoryDict[accessory.uuid] = cdAccessory
|
|
cdAccessory.name = accessory.name
|
|
cdAccessory.uuid = accessory.uuid
|
|
cdAccessory.lentTo = accessory.lentTo
|
|
cdAccessory.color = accessory.color
|
|
cdAccessory.manufacturer = accessory.manufacturer
|
|
cdAccessory.inWishlist = accessory.inWishlist
|
|
|
|
cdConsole.addToAccessories(cdAccessory)
|
|
cdAccessory.console = cdConsole
|
|
}
|
|
|
|
private func makeCDConsole(from console : BHLConsole) -> Console {
|
|
let cdConsole = Console(context: self.CDContext)
|
|
cdConsole.name = console.name ?? "n/a"
|
|
cdConsole.uuid = console.uuid
|
|
cdConsole.manufacturer = console.manufacturer
|
|
cdConsole.shortName = console.shortName
|
|
cdConsole.logo_icloud_path = console.logo_icloud_path
|
|
cdConsole.releaseDate = console.releaseDate
|
|
|
|
return cdConsole
|
|
}
|
|
|
|
private func makeCDGameSeries(from gameSeries: BHLGameSeries, _ gameDict: inout [UUID : Game]) {
|
|
let cdGameSeries = GameSeries(context: self.CDContext)
|
|
cdGameSeries.name = gameSeries.name
|
|
cdGameSeries.cover_icloud_path = gameSeries.cover_icloud_path
|
|
|
|
for uuid in gameSeries.games {
|
|
if let game = gameDict[uuid] {
|
|
cdGameSeries.addToGames(game)
|
|
game.series = cdGameSeries
|
|
}
|
|
}
|
|
}
|
|
|
|
func importLIB(from filename: String) {
|
|
guard let file = ICloudManager.backup_folder?.appendingPathComponent(filename) else {
|
|
print("LibraryImport:importLIB Could not get icloud backup folder")
|
|
return
|
|
}
|
|
|
|
if file.isFileURL {
|
|
do {
|
|
let data = try Data(contentsOf: file)
|
|
importLIB(data: data)
|
|
}catch let error {
|
|
print("LibraryImport::importLIB::String - Cannot create data from file '\(error)'")
|
|
}
|
|
}
|
|
}
|
|
|
|
func importLIB(data : Data) {
|
|
do {
|
|
let library = try JSONDecoder().decode(BHLibrary.self, from: data)
|
|
|
|
var gameDict = [UUID:Game]()
|
|
var accessoryDict = [UUID:Accessory]()
|
|
|
|
for console in library.consoles {
|
|
let cdConsole = makeCDConsole(from: console)
|
|
|
|
print("CONSOLE: \(cdConsole.name) with \(console.games.count) games")
|
|
for uuid in console.games {
|
|
|
|
if let game = library.games.first(where: {$0.uuid == uuid}) {
|
|
makeCDGame(from: game, &gameDict, cdConsole)
|
|
}else{
|
|
print("LibraryImport::importLIB - Game with UUID '\(uuid)' not found")
|
|
}
|
|
}
|
|
|
|
for uuid in console.accessories {
|
|
if let accessory = library.accessories.first(where: {$0.uuid == uuid}) {
|
|
makeCDAccessory(from: accessory, &accessoryDict, cdConsole)
|
|
}else{
|
|
print("LibraryImport::importLIB - Accessory with UUID '\(uuid)' not found")
|
|
}
|
|
}
|
|
}
|
|
|
|
for gameSeries in library.gameSeries {
|
|
makeCDGameSeries(from: gameSeries, &gameDict)
|
|
}
|
|
}catch let error {
|
|
print("LibraryImport::importLIB::DATA - Error while importing! '\(error)'")
|
|
}
|
|
|
|
print("Import Successfull")
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - BHLLibrary Classes
|
|
|
|
struct BHLibrary : Decodable {
|
|
let games : [BHLGame]
|
|
let consoles : [BHLConsole]
|
|
let gameSeries : [BHLGameSeries]
|
|
let accessories : [BHLAccessory]
|
|
}
|
|
|
|
struct BHLGame : Decodable {
|
|
let uuid : UUID
|
|
let name : String?
|
|
let lentTo : String?
|
|
let isDigital : Bool
|
|
let inWishlist : Bool
|
|
let isFinished : Bool
|
|
let finishedDate : Date?
|
|
let notes : String?
|
|
let releaseDate : String
|
|
let pickupDate : String?
|
|
let pickupDescription : String?
|
|
let publisher : String?
|
|
let console : UUID
|
|
let cover_icloud_path : String?
|
|
let playtime_h : Int?
|
|
let playtime_min : Int?
|
|
}
|
|
|
|
struct BHLAccessory : Decodable {
|
|
let uuid : UUID
|
|
let name : String
|
|
let color : String?
|
|
let manufacturer : String?
|
|
let inWishlist : Bool
|
|
let lentTo : String?
|
|
let console : UUID?
|
|
}
|
|
|
|
struct BHLGameSeries : Decodable {
|
|
let uuid : UUID
|
|
let name : String
|
|
let games : [UUID]
|
|
let cover_icloud_path : String?
|
|
}
|
|
|
|
struct BHLConsole : Decodable {
|
|
let uuid : UUID
|
|
let name : String?
|
|
let logo_icloud_path : String?
|
|
let manufacturer : String?
|
|
let releaseDate : Date
|
|
let shortName : String?
|
|
let accessories : [UUID]
|
|
let games : [UUID]
|
|
}
|