Skip to content

Commit

Permalink
Enhance the functionality for importing data. (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
biuuu authored Jan 10, 2024
1 parent 00b666d commit eb84306
Show file tree
Hide file tree
Showing 12 changed files with 354 additions and 452 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "genshin-wish-export",
"version": "0.10.1",
"version": "0.10.2",
"main": "./dist/electron/main/main.js",
"author": "biuuu <https://github.com/biuuu>",
"homepage": "https://github.com/biuuu/genshin-wish-export",
Expand Down Expand Up @@ -80,6 +80,7 @@
"@vitejs/plugin-vue": "2.1.0",
"@vue/compiler-sfc": "^3.2.29",
"adm-zip": "^0.5.9",
"ajv": "6",
"autoprefixer": "^10.4.2",
"cfonts": "^2.10.0",
"chalk": "^4.1.0",
Expand Down
210 changes: 210 additions & 0 deletions src/gachaType.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
{
"en-us": [{
"key": "200",
"name": "Permanent Wish"
}, {
"key": "100",
"name": "Novice Wishes"
}, {
"key": "301",
"name": "Character Event Wish"
}, {
"key": "302",
"name": "Weapon Event Wish"
}, {
"key": "400",
"name": "Character Event Wish-2"
}],
"fr-fr": [{
"key": "200",
"name": "Vœux permanents"
}, {
"key": "100",
"name": "Vœux des débutants"
}, {
"key": "301",
"name": "Vœux événements de personnage"
}, {
"key": "302",
"name": "Vœux événements d'arme"
}, {
"key": "400",
"name": "Vœux événements de personnage - 2"
}],
"de-de": [{
"key": "200",
"name": "Standardgebet"
}, {
"key": "100",
"name": "Neulingsgebete"
}, {
"key": "301",
"name": "Figurenaktionsgebet"
}, {
"key": "302",
"name": "Waffenaktionsgebet"
}, {
"key": "400",
"name": "Figurenaktionsgebet 2"
}],
"es-es": [{
"key": "200",
"name": "Gachapón permanente"
}, {
"key": "100",
"name": "Gachapón de principiante"
}, {
"key": "301",
"name": "Gachapón promocional de personaje"
}, {
"key": "302",
"name": "Gachapón promocional de arma"
}, {
"key": "400",
"name": "Gachapón promocional de personaje 2"
}],
"pt-pt": [{
"key": "200",
"name": "Desejo Comum"
}, {
"key": "100",
"name": "Desejos de Novato"
}, {
"key": "301",
"name": "Oração do Evento do Personagem"
}, {
"key": "302",
"name": "Oração do Evento de Arma"
}, {
"key": "400",
"name": "Oração de Evento de Personagem - 2"
}],
"ru-ru": [{
"key": "200",
"name": "Стандартная молитва"
}, {
"key": "100",
"name": "Молитва новичка"
}, {
"key": "301",
"name": "Молитва события персонажа"
}, {
"key": "302",
"name": "Молитва события оружия"
}, {
"key": "400",
"name": "Молитва события персонажа II"
}],
"ja-jp": [{
"key": "200",
"name": "通常祈願"
}, {
"key": "100",
"name": "初心者向け祈願"
}, {
"key": "301",
"name": "イベント祈願・キャラクター"
}, {
"key": "302",
"name": "イベント祈願・武器"
}, {
"key": "400",
"name": "イベント祈願・キャラクター 2"
}],
"ko-kr": [{
"key": "200",
"name": "상주 기원"
}, {
"key": "100",
"name": "초심자 기원"
}, {
"key": "301",
"name": "캐릭터 이벤트 기원"
}, {
"key": "302",
"name": "무기 이벤트 기원"
}, {
"key": "400",
"name": "캐릭터 이벤트 기원-2"
}],
"th-th": [{
"key": "200",
"name": "อธิษฐานถาวร"
}, {
"key": "100",
"name": "ผู้เริ่มอธิษฐาน"
}, {
"key": "301",
"name": "กิจกรรมอธิษฐานตัวละคร"
}, {
"key": "302",
"name": "กิจกรรมอธิษฐานอาวุธ"
}, {
"key": "400",
"name": "กิจกรรมอธิษฐานตัวละคร - 2"
}],
"vi-vn": [{
"key": "200",
"name": "Cầu Nguyện Thường"
}, {
"key": "100",
"name": "Cầu Nguyện Tân Thủ"
}, {
"key": "301",
"name": "Cầu Nguyện Nhân Vật"
}, {
"key": "302",
"name": "Cầu Nguyện Vũ Khí"
}, {
"key": "400",
"name": "Cầu Nguyện Nhân Vật-2"
}],
"id-id": [{
"key": "200",
"name": "Permohonan Standar"
}, {
"key": "100",
"name": "Permohonan Pemula"
}, {
"key": "301",
"name": "Event Permohonan Karakter"
}, {
"key": "302",
"name": "Event Permohonan Senjata"
}, {
"key": "400",
"name": "Event Permohonan Karakter - 2"
}],
"zh-cn": [{
"key": "200",
"name": "常驻祈愿"
}, {
"key": "100",
"name": "新手祈愿"
}, {
"key": "301",
"name": "角色活动祈愿"
}, {
"key": "302",
"name": "武器活动祈愿"
}, {
"key": "400",
"name": "角色活动祈愿-2"
}],
"zh-tw": [{
"key": "200",
"name": "常駐祈願"
}, {
"key": "100",
"name": "新手祈願"
}, {
"key": "301",
"name": "角色活動祈願"
}, {
"key": "302",
"name": "武器活動祈願"
}, {
"key": "400",
"name": "角色活動祈願-2"
}]
}
11 changes: 5 additions & 6 deletions src/i18n/English.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@
"ui.setting.fetchFullHistoryHint": "When this option is enabled, click the \"Update Data\" button to get all the card draw records within 6 months. When there are incorrect data within 6 months, this function can be used to repair.",
"ui.setting.closeProxy": "Disable system proxy",
"ui.setting.closeProxyHint": "When you choose proxy mode, if the program crashes it can cause unwanted results that may affect your system. You can click this button to clear the system proxy settings.",
"ui.setting.UIGFHint": "This feature is used to export data to other wish history management tools (The first export may require a longer waiting time). For a list of supported tools, refer to this link:",
"ui.setting.UIGFImportButton": "Import JSON file",
"ui.setting.UIGFImportHint": "This feature is used to import data from other wish history management tools. For a list of supported tools, refer to this link:",
"ui.setting.UIGFImportLable": "Import from other tools",
"ui.setting.UIGFHint": "This feature is used for importing/exporting data (the first export may take some time). Refer to this link for supported tools:",
"ui.setting.UIGFImportButton": "Import data",
"ui.setting.UIGFImportSuccessed": "Data has been imported",
"ui.setting.UIGFLink": "Uniformed Interchangeable GachaLog Format Standard",
"ui.setting.UIGFLable": "Export to other tools",
"ui.setting.UIGFButton": "Export JSON file",
"ui.setting.UIGFLable": "Import / Export",
"ui.setting.UIGFButton": "Export data",
"ui.setting.UIGFReadable": "Readable",
"ui.about.title": "About",
"ui.about.license": "This software is opensource using MIT license.",
Expand Down
11 changes: 5 additions & 6 deletions src/i18n/简体中文.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@
"ui.setting.fetchFullHistoryHint": "开启时点击“更新数据”按钮会完整获取6个月内所有的抽卡记录,当记录里有6个月范围以内的错误数据时可以通过这个功能修复。",
"ui.setting.closeProxy": "关闭系统代理",
"ui.setting.closeProxyHint": "如果使用过代理模式时工具非正常关闭,可能导致系统代理设置没能清除,可以通过这个按钮来清除设置过的系统代理。",
"ui.setting.UIGFHint": "该功能用于导出数据到其它抽卡记录管理工具(首次导出需要花费一点时间),支持的工具参考这个链接:",
"ui.setting.UIGFImportButton": "导入JSON文件",
"ui.setting.UIGFImportHint": "该功能用于从其它抽卡记录管理工具导入数据,支持的工具参考这个链接:",
"ui.setting.UIGFImportLable": "从其它工具导入",
"ui.setting.UIGFHint": "该功能用于导入/导出数据(首次导出需要花费一点时间),支持的工具参考这个链接:",
"ui.setting.UIGFImportButton": "导入数据",
"ui.setting.UIGFImportSuccessed": "数据已导入",
"ui.setting.UIGFLink": "统一可交换抽卡记录标准",
"ui.setting.UIGFLable": "导出到其它工具",
"ui.setting.UIGFButton": "导出JSON文件",
"ui.setting.UIGFLable": "导入/导出",
"ui.setting.UIGFButton": "导出数据",
"ui.setting.UIGFReadable": "可读",
"ui.about.title": "关于",
"ui.about.license": "本工具为开源软件,源代码使用 MIT 协议授权",
Expand Down
53 changes: 28 additions & 25 deletions src/main/UIGFJson.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
const { app, ipcMain, dialog } = require('electron')
const fs = require('fs-extra')
const path = require('path')
const getData = require('./getData').getData
const getItemTypeMap = require('./itemTypeMap').getItemTypeMap
const { getData, saveData, changeCurrent } = require('./getData')
const getItemTypeNameMap = require('./gachaTypeMap').getItemTypeNameMap
const { version } = require('../../package.json')
const config = require('./config')
const fetch = require('electron-fetch').default
const { readJSON, saveJSON, existsFile } = require('./utils')
const Ajv = require("ajv")
const { readJSON, saveJSON, existsFile, userDataPath } = require('./utils')
const Ajv = require('ajv')

// acquire uigf schema
const validateUigfJson = new Ajv().compile(require('../schema/uigf.json'));
const gachaListFileNamePattern = /^gacha-list-.*\.json$/;
const validateUigfJson = new Ajv().compile(require('../schema/uigf.json'))
const validateLocalJson = new Ajv().compile(require('../schema/local-data.json'))
const gachaListFileNamePattern = /^gacha-list-.*\.json$/

const uigfLangMap = new Map([
['zh-cn', 'chs'],
Expand Down Expand Up @@ -202,13 +203,14 @@ const start = async () => {
}
}

const readUigfJson = async (path) => {
fs.ensureFileSync(path)
const data = JSON.parse(fs.readFileSync(path, 'utf8'));
if (!validateUigfJson(data)) {
throw new Error(`UIGF Json Schema Validation Failed!`)
const saveAndBackup = async (data) => {
if (existsFile(`gacha-list-${data.uid}.json`)) {
const backupDir = path.join(userDataPath, 'backup', data.uid)
await fs.ensureDir(backupDir)
await fs.copyFile(path.join(userDataPath, `gacha-list-${data.uid}.json`), path.join(backupDir, `gacha-list-${data.uid}-${getTimeString()}.json`))
}
return data
await saveData(data)
await changeCurrent(data.uid)
}

const importJson = async () => {
Expand All @@ -220,28 +222,29 @@ const importJson = async () => {
})
if (filePathArr) {
const filePath = filePathArr[0]
const fileBaseName = path.basename(filePath)
// if the imported json file is gacha-list-*.json file
if (gachaListFileNamePattern.test(fileBaseName)){
fs.ensureFileSync(filePath)
await saveJSON(fileBaseName, JSON.parse(fs.readFileSync(filePath, 'utf8')))
}
// else just assume the file is UIGF standard complaint
else {
const importData = await readUigfJson(filePath);
const jsonStr = await fs.readFile(filePath, 'utf8')
const importData = JSON.parse(jsonStr)
if (validateLocalJson(importData)) {
await saveAndBackup(importData)
} else if (validateUigfJson(importData)) {
const gachaData = {
result: new Map(),
time: Date.now(),
typeMap: getItemTypeMap(importData.info.lang),
typeMap: getItemTypeNameMap(importData.info.lang),
uid: importData.info.uid,
lang: importData.info.lang
}
gachaData.typeMap.forEach((_, k) => gachaData.result.set(k, []))
importData.list.sort((a, b) => parseInt(BigInt(a.id) - BigInt(b.id)))
for (const item of importData.list) {
gachaData.result.get(item.uigf_gacha_type).push([item.time, item.name, item.item_type, Number(item.rank_type), item.gacha_type, item.id])
gachaData.result.get(item.uigf_gacha_type).push([item.time, item.name, item.item_type, parseInt(item.rank_type), item.gacha_type, item.id])
}
await saveJSON(`gacha-list-${importData.info.uid}.json`, gachaData)
await saveAndBackup(gachaData)
} else {
throw new Error(`JSON format error`)
}
} else {
return 'canceled'
}
}

Expand All @@ -250,7 +253,7 @@ ipcMain.handle('EXPORT_UIGF_JSON', async () => {
})

ipcMain.handle('IMPORT_UIGF_JSON', async () => {
await importJson()
return await importJson()
})

module.exports = { uigfJson }
18 changes: 18 additions & 0 deletions src/main/gachaTypeMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

const { order } = require('./getData')
const itemTypeNameMap = require('../gachaType.json')

function convertItemTypeMap(mapObject) {
const convertedItemTypeMap = new Map()
order.forEach(id => {
const itemType = mapObject.find(item => {
return item.key === id
})
convertedItemTypeMap.set(itemType.key, itemType.name)
})
return convertedItemTypeMap
}

exports.getItemTypeNameMap = function(lang) {
return convertItemTypeMap(itemTypeNameMap[lang])
}
Loading

0 comments on commit eb84306

Please sign in to comment.