From bed5bc353ad30858cc174467c59084f30e1f18ce Mon Sep 17 00:00:00 2001 From: Jozen Date: Thu, 21 Nov 2019 19:09:02 +0800 Subject: [PATCH] Save grids, heroes when importing --- package-lock.json | 27 ++++--- package.json | 3 +- src/js/Components/Import/ImportList.jsx | 4 +- src/js/Import.jsx | 102 ++++++++++++++++++++---- src/js/Search.jsx | 7 +- src/js/Steam.js | 42 +++++----- 6 files changed, 131 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea6a3dc..91caeab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7260,6 +7260,11 @@ "type-check": "~0.3.2" } }, + "lnf": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/lnf/-/lnf-1.3.9.tgz", + "integrity": "sha512-XKlRuyNZcWg7jmGaYzj1bfCs/PIgVyBB13YUnOZ/QKLzWdwKGsGx7kXO1PPymm/hijuNoi9bSSv/Oz6frh8DsA==" + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -9311,19 +9316,19 @@ } }, "request-promise-core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", - "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.15" } }, "request-promise-native": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", - "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", "requires": { - "request-promise-core": "1.1.2", + "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" } @@ -9963,9 +9968,9 @@ } }, "steamgriddb": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/steamgriddb/-/steamgriddb-1.3.0.tgz", - "integrity": "sha512-i8IdqQOmA15hKXz76PKzuTdLBHxkrC9oEpURI2LBD0mqS5IBC2Jatv01dmCXWvZqkyhXODQZlmKGyDZaGZHxgg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/steamgriddb/-/steamgriddb-1.3.1.tgz", + "integrity": "sha512-+PTvAQhbK8BmamvggTrAi+Qm/L+x9m7hJv3+LWkKUI/GEqdzm4gom8nPKvg4ZH//LzrYWhoAJLqXA7mKwHGI5Q==", "requires": { "request": "^2.88.0", "request-promise-native": "^1.0.7" diff --git a/package.json b/package.json index 5cb3a80..d7c6d89 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "iconv-lite": "^0.5.0", "js-yaml": "^3.13.1", "jsonminify": "^0.4.1", + "lnf": "^1.3.9", "lodash": "^4.17.15", "metrohash": "^2.6.0", "promise-reflect": "^1.1.0", @@ -112,7 +113,7 @@ "react-uwp": "^1.2.31", "steam-categories": "^1.1.0", "steam-shortcut-editor": "^3.1.1", - "steamgriddb": "^1.3.0", + "steamgriddb": "^1.3.1", "steamid": "^1.1.3", "winreg": "^1.2.4", "xml-js": "^1.6.11" diff --git a/src/js/Components/Import/ImportList.jsx b/src/js/Components/Import/ImportList.jsx index bf1a903..28d11e8 100644 --- a/src/js/Components/Import/ImportList.jsx +++ b/src/js/Components/Import/ImportList.jsx @@ -37,8 +37,8 @@ class ImportList extends React.Component { } let thumb; - if (this.grids[i].length > 0) { - thumb = this.grids[i][0].thumb; + if (this.grids[i]) { + thumb = this.grids[i].thumb; } return ( diff --git a/src/js/Import.jsx b/src/js/Import.jsx index ef403fd..8058ff0 100644 --- a/src/js/Import.jsx +++ b/src/js/Import.jsx @@ -12,6 +12,8 @@ const Store = window.require('electron-store'); const SGDB = window.require('steamgriddb'); const { metrohash64 } = window.require('metrohash'); const log = window.require('electron-log'); +const { join, extname, dirname } = window.require('path'); +const Lnf = window.require('lnf'); class Import extends React.Component { constructor(props) { @@ -28,6 +30,8 @@ class Import extends React.Component { class: platformModules[key].default, games: [], grids: [], + posters: [], + heroes: [], installed: false, error: false, })); @@ -72,22 +76,7 @@ class Import extends React.Component { // Get grids for each platform const ids = platform.games.map((x) => encodeURIComponent(x.id)); const getGrids = this.SGDB.getGrids({ type: platform.id, id: ids.join(',') }).then((res) => { - let formatted; - // if only single id then return first grid - if (ids.length === 1) { - if (res.length > 0) { - formatted = [[res[0]]]; - } - } else { - // if multiple ids treat each object as a request - formatted = res.map((x) => { - if (x.success) { - return x.data; - } - return false; - }); - } - platform.grids = formatted; + platform.grids = this._formatResponse(ids, res); }).catch(() => { // show an error toast }); @@ -115,6 +104,26 @@ class Import extends React.Component { this.store.set('games', gamesStorage); } + // @todo this is horrible but can't be arsed right now + _formatResponse(ids, res) { + let formatted = false; + // if only single id then return first grid + if (ids.length === 1) { + if (res.length > 0) { + formatted = [res[0]]; + } + } else { + // if multiple ids treat each object as a request + formatted = res.map((x) => { + if (x.success) { + if (x.data[0]) return x.data[0]; + } + return false; + }); + } + return formatted; + } + addGames(games, platform) { this.saveImportedGames(games); @@ -142,6 +151,67 @@ class Import extends React.Component {

), }); + }).then(() => { + // Download images + PubSub.publish('toast', { + logoNode: 'Download', + title: 'Downloading Images...', + contents: (

Downloading images for imported games...

), + }); + + const ids = games.map((x) => encodeURIComponent(x.id)); + let posters = []; + let heroes = []; + + // Get posters + const getPosters = this.SGDB.getGrids({ type: platform.id, id: ids.join(','), dimensions: ['600x900'] }).then((res) => { + posters = this._formatResponse(ids, res); + }).catch(() => { + // show an error toast + }); + + // Get heroes + const getHeroes = this.SGDB.getHeroes({ type: platform.id, id: ids.join(',') }).then((res) => { + heroes = this._formatResponse(ids, res); + }).catch(() => { + // show an error toast + }); + + Promise.all([getPosters, getHeroes]).then(() => { + const downloadPromises = []; + games.forEach((game, i) => { + const appId = Steam.generateNewAppId(game.exe, game.name); + + // Take (legacy) grids from when we got them for the ImportList + const savedGrid = platform.grids[platform.games.indexOf(games[i])]; + if (platform.grids[i] && savedGrid) { + const appIdOld = Steam.generateAppId(game.exe, game.name); + const saveGrids = Steam.addAsset('horizontalGrid', appId, savedGrid.url).then((dest) => { + // Symlink to old appid so it works in BPM + Lnf.sync(dest, join(dirname(dest), `${appIdOld}${extname(dest)}`)); + }); + downloadPromises.push(saveGrids); + } + + // Download posters + if (posters[i]) { + downloadPromises.push(Steam.addAsset('verticalGrid', appId, posters[i].url)); + } + + // Download heroes + if (heroes[i]) { + downloadPromises.push(Steam.addAsset('hero', appId, heroes[i].url)); + } + }); + + Promise.all(downloadPromises).then(() => { + PubSub.publish('toast', { + logoNode: 'Download', + title: 'Downloadeds Complete', + contents: (

All Images Downloaded!

), + }); + }); + }); }).catch((err) => { if (err.type === 'OpenError') { PubSub.publish('toast', { diff --git a/src/js/Search.jsx b/src/js/Search.jsx index e20beef..033c96c 100644 --- a/src/js/Search.jsx +++ b/src/js/Search.jsx @@ -77,12 +77,7 @@ class Search extends React.Component { } this.setIsDownloading(true); - const itemsClone = { ...this.state.items }; - Steam.addGrid(props.appid, props.image, (progress) => { - this.setState({ downloadProgress: progress }); - itemsClone[props.index].progress = progress; - this.setState({ itemsClone }); - }).then((dest) => { + Steam.addAsset('horizontalGrid', props.appid, props.image).then((dest) => { this.setImageDownloaded(props.appid, props.name, dest); }).catch(() => { this.setIsDownloading(false); diff --git a/src/js/Steam.js b/src/js/Steam.js index 7fb5cd1..a3fe6f2 100644 --- a/src/js/Steam.js +++ b/src/js/Steam.js @@ -4,7 +4,7 @@ import { crc32 } from 'crc'; const Registry = window.require('winreg'); const Store = window.require('electron-store'); const fs = window.require('fs'); -const { join } = window.require('path'); +const { join, extname } = window.require('path'); const VDF = window.require('@node-steam/vdf'); const shortcut = window.require('steam-shortcut-editor'); const https = window.require('https'); @@ -265,13 +265,6 @@ class Steam { return image; } - static deleteCustomGridImage(userdataGridPath, appid) { - const imagePath = this.getCustomGridImage(userdataGridPath, appid); - if (imagePath) { - fs.unlinkSync(imagePath); - } - } - static getShortcutFile() { return new Promise((resolve) => { this.getSteamPath().then((steamPath) => { @@ -284,12 +277,27 @@ class Steam { }); } - static addGrid(appId, url, onProgress = () => {}) { + static addAsset(type, appId, url) { return new Promise((resolve, reject) => { this.getCurrentUserGridPath().then((userGridPath) => { const imageUrl = url; - const imageExt = imageUrl.substr(imageUrl.lastIndexOf('.') + 1); - const dest = join(userGridPath, `${appId}.${imageExt}`); + const imageExt = extname(imageUrl); + + let dest; + + switch (type) { + case 'horizontalGrid': + dest = join(userGridPath, `${appId}${imageExt}`); + break; + case 'verticalGrid': + dest = join(userGridPath, `${appId}p${imageExt}`); + break; + case 'hero': + dest = join(userGridPath, `${appId}_hero${imageExt}`); + break; + default: + reject(); + } let cur = 0; const data = new Stream(); @@ -298,21 +306,19 @@ class Steam { https.get(url, (response) => { const len = parseInt(response.headers['content-length'], 10); - response.on('end', () => { - this.deleteCustomGridImage(userGridPath, appId); - fs.writeFileSync(dest, data.read()); - resolve(dest); - }); - response.on('data', (chunk) => { cur += chunk.length; data.push(chunk); progress = Math.round((cur / len) * 10) / 10; if (progress !== lastProgress) { lastProgress = progress; - onProgress(progress); } }); + + response.on('end', () => { + fs.writeFileSync(dest, data.read()); + resolve(dest); + }); }).on('error', (err) => { fs.unlink(dest); reject(err);