New Baseline -- Added basic Cloudkit support and changed to julian.steffen@me.com Apple Developer Account
This commit is contained in:
328
Zockerhoehle/Utils/LibraryImport.swift
Normal file
328
Zockerhoehle/Utils/LibraryImport.swift
Normal file
@@ -0,0 +1,328 @@
|
||||
//
|
||||
// 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 {
|
||||
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 {
|
||||
let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
|
||||
|
||||
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 []
|
||||
}
|
||||
|
||||
private func resetDatabase() {
|
||||
print(GameSeriesStore().gameSeries)
|
||||
CDManager.shared.viewContext.reset()
|
||||
CDManager.shared.viewContext.performAndWait {
|
||||
let deleteRequests =
|
||||
[NSBatchDeleteRequest(fetchRequest: Game.fetchRequest()),
|
||||
NSBatchDeleteRequest(fetchRequest: Accessory.fetchRequest()),
|
||||
NSBatchDeleteRequest(fetchRequest: Console.fetchRequest()),
|
||||
NSBatchDeleteRequest(fetchRequest: GameSeries.fetchRequest()),
|
||||
NSBatchDeleteRequest(fetchRequest: Logo.fetchRequest()),
|
||||
NSBatchDeleteRequest(fetchRequest: Cover.fetchRequest())]
|
||||
|
||||
let storeCoordinator = CDManager.shared.persistentContainer.persistentStoreCoordinator
|
||||
do {
|
||||
for deleteRequest in deleteRequests {
|
||||
try storeCoordinator.execute(deleteRequest, with: CDManager.shared.viewContext)
|
||||
}
|
||||
}catch let error {
|
||||
print(error)
|
||||
print("LibraryImport::resetDatabase - Reset of Database failes!")
|
||||
}
|
||||
}
|
||||
print(GameSeriesStore().gameSeries)
|
||||
}
|
||||
|
||||
private func makeCDGame(from game: BHLGame, _ gameDict: inout [UUID : Game], _ cdConsole: Console) {
|
||||
let cdGame = Game(context: CDManager.shared.viewContext)
|
||||
gameDict[game.uuid] = cdGame
|
||||
cdGame.name = game.name
|
||||
cdGame.uuid = game.uuid
|
||||
cdGame.inWishlist = game.inWishlist
|
||||
cdGame.isFinished = game.isFinished
|
||||
cdGame.lentTo = game.lentTo
|
||||
//TODO: cdGame.createdAt = game.createdAt.
|
||||
|
||||
let cdCover = Cover(context: CDManager.shared.viewContext)
|
||||
cdCover.image = game.cover
|
||||
cdCover.game = cdGame
|
||||
cdGame.cover = cdCover
|
||||
|
||||
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: CDManager.shared.viewContext)
|
||||
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: CDManager.shared.viewContext)
|
||||
cdConsole.name = console.name
|
||||
cdConsole.uuid = console.uuid
|
||||
cdConsole.manufacturer = console.manufacturer
|
||||
cdConsole.shortName = console.shortName
|
||||
cdConsole.generation = Int64(console.generation)
|
||||
|
||||
let cdLogo = Logo(context: CDManager.shared.viewContext)
|
||||
cdLogo.image = console.logo
|
||||
cdLogo.console = cdConsole
|
||||
cdConsole.logo = cdLogo
|
||||
|
||||
return cdConsole
|
||||
}
|
||||
|
||||
private func makeCDGameSeries(from gameSeries: BHLGameSeries, _ gameDict: inout [UUID : Game]) {
|
||||
let cdGameSeries = GameSeries(context: CDManager.shared.viewContext)
|
||||
cdGameSeries.name = gameSeries.name
|
||||
|
||||
let cdCover = GameSeriesCover(context: CDManager.shared.viewContext)
|
||||
cdCover.image = gameSeries.cover
|
||||
cdCover.gameSeries = cdGameSeries
|
||||
cdGameSeries.cover = cdCover
|
||||
|
||||
for uuid in gameSeries.games {
|
||||
if let game = gameDict[uuid] {
|
||||
cdGameSeries.addToGames(game)
|
||||
game.series = cdGameSeries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func importLIB(from filename: String) {
|
||||
do {
|
||||
let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
|
||||
|
||||
let file = documentDirectory.appendingPathComponent(filename)
|
||||
|
||||
if file.isFileURL {
|
||||
let library = try JSONDecoder().decode(BHLibrary.self, from: Data(contentsOf: file))
|
||||
|
||||
resetDatabase()
|
||||
|
||||
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(error)
|
||||
print("LibraryImport::importLIB - Error while importing!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 notes : String?
|
||||
let createdAt : String?
|
||||
let publisher : String?
|
||||
let console : UUID?
|
||||
let series : UUID?
|
||||
let cover : UIImage?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case uuid
|
||||
case name
|
||||
case lentTo
|
||||
case isDigital
|
||||
case inWishlist
|
||||
case isFinished
|
||||
case notes
|
||||
case createdAt
|
||||
case publisher
|
||||
case console
|
||||
case series
|
||||
case cover
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
uuid = try container.decode(UUID.self, forKey: .uuid)
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
lentTo = try container.decode(String?.self, forKey: .lentTo)
|
||||
isDigital = try container.decode(Bool.self, forKey: .isDigital)
|
||||
inWishlist = try container.decode(Bool.self, forKey: .inWishlist)
|
||||
isFinished = try container.decode(Bool.self, forKey: .isFinished)
|
||||
notes = try container.decode(String?.self, forKey: .notes)
|
||||
createdAt = try container.decode(String?.self, forKey: .notes)
|
||||
publisher = try container.decode(String?.self, forKey: .publisher)
|
||||
console = try container.decode(UUID?.self, forKey: .console)
|
||||
series = try container.decode(UUID?.self, forKey: .console)
|
||||
|
||||
|
||||
if let coverBase64 = try container.decode(String?.self, forKey: .cover),
|
||||
let coverData = Data(base64Encoded: coverBase64) {
|
||||
cover = UIImage(data: coverData)
|
||||
}else {
|
||||
cover = .none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 cover : UIImage?
|
||||
let games : [UUID]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case uuid
|
||||
case name
|
||||
case cover
|
||||
case games
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
uuid = try container.decode(UUID.self, forKey: .uuid)
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
games = try container.decode([UUID].self, forKey: .games)
|
||||
|
||||
if let coverBase64 = try container.decode(String?.self, forKey: .cover),
|
||||
let coverData = Data(base64Encoded: coverBase64) {
|
||||
cover = UIImage(data: coverData)
|
||||
}else {
|
||||
cover = .none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BHLConsole : Decodable {
|
||||
let uuid : UUID
|
||||
let name : String
|
||||
let logo : UIImage?
|
||||
let generation : Int
|
||||
let manufacturer : String?
|
||||
let shortName : String?
|
||||
let accessories : [UUID]
|
||||
let games : [UUID]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case uuid
|
||||
case name
|
||||
case logo
|
||||
case generation
|
||||
case manufacturer
|
||||
case shortName
|
||||
case accessories
|
||||
case games
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
uuid = try container.decode(UUID.self, forKey: .uuid)
|
||||
name = try container.decode(String.self, forKey: .name)
|
||||
generation = try container.decode(Int.self, forKey: .generation)
|
||||
manufacturer = try container.decode(String?.self, forKey: .manufacturer)
|
||||
shortName = try container.decode(String?.self, forKey: .shortName)
|
||||
accessories = try container.decode([UUID].self, forKey: .accessories)
|
||||
games = try container.decode([UUID].self, forKey: .games)
|
||||
|
||||
if let coverBase64 = try container.decode(String?.self, forKey: .logo),
|
||||
let coverData = Data(base64Encoded: coverBase64) {
|
||||
logo = UIImage(data: coverData)
|
||||
}else {
|
||||
logo = .none
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user