From 17e2206357f0460c98d48ab03b83ee57618eb853 Mon Sep 17 00:00:00 2001 From: Syl Date: Fri, 17 Nov 2023 15:51:11 -0600 Subject: [PATCH] change credits n stuff --- build.js | 15 +-- core/ipc/main/version/detailsStr.js | 144 +++++++++++++++++++--------- html/pagescripts/settings.js | 15 ++- html/topjs/faIconExists.js | 3 - html/util/objToDOM.js | 75 +++++++++++++++ util/build/packageDetails.js | 44 +++++++++ util/build/sourcePackage.js | 30 ++++++ 7 files changed, 268 insertions(+), 58 deletions(-) create mode 100644 html/util/objToDOM.js create mode 100644 util/build/packageDetails.js create mode 100644 util/build/sourcePackage.js diff --git a/build.js b/build.js index 838b7d7..1221439 100644 --- a/build.js +++ b/build.js @@ -1,11 +1,11 @@ const child_process = require(`child_process`); const fs = require(`fs`); -const which = require('which') +const which = require('which'); const yargs = require('yargs'); const { hideBin } = require('yargs/helpers') -const buildArgs = yargs(hideBin(process.argv)).argv +const buildArgs = yargs(hideBin(process.argv)).argv; // previous store: electron-builder -c ./package-build-store.json -p never // previous dist: electron-builder -c ./package-build.json -p always @@ -110,7 +110,8 @@ let fullMetadataDone = false; const getFullMetadata = () => new Promise(async res => { if(fullMetadataDone) return res(config); - const pkg = require(`./package.json`) + const pkg = require(`./package.json`); + const details = require(`./util/build/packageDetails.js`); const obj = { commitHash: `unk`, @@ -134,12 +135,12 @@ const getFullMetadata = () => new Promise(async res => { }, }; - for(const [name, value] of Object.keys(pkg.dependencies).sort().map(n => [n, pkg.dependencies[n]])) { - obj.buildInfo.Libraries.app[name] = value.replace(`^`, ``); + for(const name of Object.keys(pkg.dependencies).sort()) { + obj.buildInfo.Libraries.app[name] = await details(name); } - for(const [name, value] of Object.keys(pkg.devDependencies).sort().map(n => [n, pkg.devDependencies[n]])) { - obj.buildInfo.Libraries.src[name] = value.replace(`^`, ``); + for(const name of Object.keys(pkg.devDependencies).sort()) { + obj.buildInfo.Libraries.src[name] = await details(name); } const git = await which(`git`, { nothrow: true }); diff --git a/core/ipc/main/version/detailsStr.js b/core/ipc/main/version/detailsStr.js index 74ffc03..f61e2f0 100644 --- a/core/ipc/main/version/detailsStr.js +++ b/core/ipc/main/version/detailsStr.js @@ -1,7 +1,38 @@ const getPath = require(`../../../../util/getPath`); -const month = [`Jan`, `Feb`, `Mar`, `Apr`, `May`, `Jun`, `Jul`, `Aug`, `Sep`, `Oct`, `Nov`, `Dec`] -const dayOfWeek = [`Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday`, `Saturday`] +const month = [`Jan`, `Feb`, `Mar`, `Apr`, `May`, `Jun`, `Jul`, `Aug`, `Sep`, `Oct`, `Nov`, `Dec`]; +const dayOfWeek = [`Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday`, `Saturday`]; + +const iconMappings = { + lib: { + app: `hdd`, + src: `cloud` + } +}; + +const parseValue = (k, v) => { + if(k.toLowerCase() == `built`) { + const date = new Date(v); + + const time = { + h: date.getHours(), + m: date.getMinutes(), + s: date.getSeconds(), + } + + Object.entries(time).forEach(([k, v]) => v < 10 ? time[k] = `0${v}` : null) + + return `${dayOfWeek[date.getDay()]}, ${month[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()} at ${Object.values(time).join(`:`)}` + } else return v; +} + +const parseValues = (o) => { + Object.entries(o).forEach(([k, v]) => { + o[k] = parseValue(k, v); + }); + + return o; +} module.exports = { type: `handle`, @@ -17,57 +48,76 @@ module.exports = { } else if(await getPath(`./build.json`, true, false, true)) { appVersions = require(`../../../../build.json`).extraMetadata.buildInfo } - - Object.assign(appVersions, { - "Node.JS": { - "Version": `${process.versions.node} (${process.release.lts || process.release.name})`, - "V8": process.versions.v8, - "Platform": process.platform, - "Arch": process.arch, - }, - }); - - const details = []; - await require(`../../../../util/currentVersion/pybridge`)() + await require(`../../../../util/currentVersion/pybridge`)() // fetch version info const useObj = Object.assign({}, appVersions, require(`../../../../util/pythonBridge`).bridgeVersions || {}); - console.log(useObj) - - Object.keys(useObj).filter(s => !s.includes(`Libraries`)).forEach(pkg => { - details.push(``, `#### ${pkg}`); - Object.entries(useObj[pkg]).forEach(([k, v]) => { - if(k.toLowerCase() == `built`) { - const date = new Date(v); - - const time = { - h: date.getHours(), - m: date.getMinutes(), - s: date.getSeconds(), + const details = Object.entries({ + "ezytdl": { + icon: `arrow-alt-circle-down`, + }, + "ezytdl-pybridge": { + icon: `save`, + value: { + ...(useObj[`ezytdl-pybridge`] && Object.entries(useObj[`ezytdl-pybridge`]).map(([k, v]) => ({ + [`\`[bridge]\` ${k}`]: { + icon: `arrow-alt-circle-down`, + value: parseValue(k, v) + } + })).reduce((a, b) => Object.assign(a, b), {}) || {}), + ...(useObj[`yt-dlp`] && Object.entries(useObj[`yt-dlp`]).map(([k, v]) => ({ + [`\`[yt-dlp]\` ${k}`]: { + icon: `dot-circle`, + value: parseValue(k, v) + } + })).reduce((a, b) => Object.assign(a, b), {}) || {}), + } + }, + "Electron": { + icon: `atom`, + }, + "Node.JS": { + icon: `node-js`, + value: { + "Version": `${process.versions.node} (${process.release.lts || process.release.name})`, + "V8": process.versions.v8, + "Platform": process.platform, + "Arch": process.arch, + }, + }, + "Libraries": { + icon: `book`, + value: Object.keys(appVersions.Libraries).map(type => Object.entries(appVersions.Libraries[type]).map(([k, v]) => ({ + [`\`[${type}]\` ${k}`]: { + icon: iconMappings.lib[type] || `book`, + value: `[${v.version}](${v.url.version})`, + expanded: Object.entries({ + "Description": { + icon: `file-alt`, + value: v.details.description + }, + "Author": { + icon: `user`, + value: v.details.author + }, + "License": { + icon: `balance-scale-right`, + value: v.details.license + }, + "Package Info": { + icon: `caret-right`, + value: `Additional package details`, + expanded: Object.entries(v.details.package).map(([k, v]) => ({ [k]: `\`${v}\`` })).reduce((a, b) => Object.assign(a, b), {}) + }, + }).filter(([k, v]) => v.value || v.expanded).reduce((a, b) => Object.assign(a, { [b[0]]: b[1] }), {}) } - - Object.entries(time).forEach(([k, v]) => v < 10 ? time[k] = `0${v}` : null) - - v = `${dayOfWeek[date.getDay()]}, ${month[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()} at ${Object.values(time).join(`:`)}` - }; - - details.push(`- ${k}: ${v}`) - }); - }); - - details.push(``, `#### Libraries`); - - Object.keys(useObj.Libraries).forEach(pkg => { - Object.entries(useObj.Libraries[pkg]).forEach(([k, v]) => { - details.push(`- \`[${pkg}]\` [${k}](https://www.npmjs.com/package/${k}): [${v}](https://www.npmjs.com/package/${k}/v/${v})`) - }); - }); - - const returnStr = details.slice(1); + })).reduce((a, b) => Object.assign(a, b), {})).reduce((a, b) => Object.assign(a, b), {}) + }, + }).map(([k, v]) => ({ [k]: Object.assign(v, !v.value && { value: parseValues(useObj[k]) } || {}) })).reduce((a, b) => Object.assign(a, b), {}); - console.log(returnStr) + console.log(details) - return res(returnStr) + return res(details); }) } \ No newline at end of file diff --git a/html/pagescripts/settings.js b/html/pagescripts/settings.js index 21038ee..ec031d9 100644 --- a/html/pagescripts/settings.js +++ b/html/pagescripts/settings.js @@ -780,7 +780,20 @@ const parseDownloadables = () => document.body.querySelector('#downloadables').c parseDownloadables(); if(detailsStr) system.detailsStr().then(details => { - detailsStr.innerHTML = markdown.makeHtml(details.join(`\n`) + `\n`); + const arr = Object.entries(details); + + console.log(`detailsStr`, arr) + + detailsStr.innerHTML = ``; + + for(const [k, v] of arr) { + console.log(`detailsStr`, k, v) + + detailsStr.innerHTML += objToDOM(k, v).innerHTML + } + + console.log(`detailsStr`, `done`) + detailsStr.classList.remove(`d-none`) }) diff --git a/html/topjs/faIconExists.js b/html/topjs/faIconExists.js index f29da33..b307ebb 100644 --- a/html/topjs/faIconExists.js +++ b/html/topjs/faIconExists.js @@ -4,7 +4,6 @@ var faIconExists = (faType, name, returnIcon, iconStyle) => { if(exists && returnIcon) { const tempElement = document.createElement(`i`); - console.log(`objToDOM: icon2 (${faType} / ${name})`) tempElement.className = `${faType} fa-${name}`; @@ -19,8 +18,6 @@ var faIconExists = (faType, name, returnIcon, iconStyle) => { const found = fallbacks.map(f => faIconExists(f, name, returnIcon, iconStyle)); - console.log(`objToDOM: icon3 (${faType} / ${name})`, found) - return found.find(Boolean); } } \ No newline at end of file diff --git a/html/util/objToDOM.js b/html/util/objToDOM.js new file mode 100644 index 0000000..933e34b --- /dev/null +++ b/html/util/objToDOM.js @@ -0,0 +1,75 @@ +const _objToListItem = (k, v, depth=0) => { + const li = document.createElement(`li`); + + li.style.fontSize = `${1.2 - (Math.min(0.4, depth*0.2))}em`; + li.style.display = `flex`; + //li.style.alignItems = `center`; + + const kv = k && !v?.hideKey && `${k}: ` || ``; + + if(typeof v == `object`) { + li.innerHTML += objToDOM(k, v, depth+1, true).innerHTML; + } else if(typeof v == `object` && typeof v.value == `string`) { + const icon2 = v.icon && faIconExists(depth && [`far`, `fas`, `fab`], v.icon, true, { marginRight: `${5 - Math.min(0.12, depth*0.06)}px` }); + if(icon2) li.prepend(icon2); + li.innerHTML += markdown.makeHtml(kv + `${v.value}`).split(`>`).slice(1).join(`>`).split(`<`).slice(0, -1).join(`<`); + } else { + li.innerHTML += markdown.makeHtml(kv + `${v}`).split(`>`).slice(1).join(`>`).split(`<`).slice(0, -1).join(`<`); + } + + return li; +} + +const objToDOM = (name, obj, depth=0, paragraphHeading) => { + console.log(`objToDOM: ${name} (depth ${depth}) (${typeof obj})`, obj, name) + + const dom = document.createElement(`div`); + + let heading = !paragraphHeading && document.createElement(depth > 99 ? `h6` : `h${Math.min(4, (1*depth) + 2)}`); + if(heading) { + if(name) heading.innerText = name; + dom.appendChild(heading); + } + + const p = document.createElement(`p`); + p.style.marginBottom = `0px`; + if(!heading) heading = p; + + if(obj.value && typeof obj.value == `string`) { + heading.innerHTML += markdown.makeHtml((!name || !paragraphHeading ? `` : `${name}: `) + obj.value).split(`>`).slice(1).join(`>`).split(`<`).slice(0, -1).join(`<`); + //heading.innerHTML += objToDOM(null, obj.value, depth+1, true).innerHTML; + } else if(obj.value && typeof obj.value == `object`) { + const ul = document.createElement(`ul`); + Object.entries(obj.value).forEach(([k, v]) => ul.appendChild(_objToListItem(k, v, depth))) + p.appendChild(ul); + } + + const icon = obj.icon && faIconExists(depth && [`far`, `fas`, `fab`], obj.icon, true, { marginRight: `8px` }); + if(icon) (paragraphHeading && dom || name && heading || p).prepend(icon); + + if(typeof obj.expanded == `object`) { + const details = document.createElement(`details`); + + const summary = document.createElement(`summary`); + summary.style.display = `flex`; + summary.style.alignItems = `center`; + + summary.appendChild(icon); + summary.appendChild(p); + details.appendChild(summary); + + const ul = document.createElement(`ul`); + Object.entries(obj.expanded).forEach(([k, v]) => ul.appendChild(_objToListItem(k, v, depth))) + details.appendChild(ul); + + console.log(`objToDOM: details`, obj, details) + + dom.appendChild(details); + } else { + console.log(`objToDOM: p`, obj, p) + + dom.appendChild(p); + }; + + return dom; +}; \ No newline at end of file diff --git a/util/build/packageDetails.js b/util/build/packageDetails.js new file mode 100644 index 0000000..bf22116 --- /dev/null +++ b/util/build/packageDetails.js @@ -0,0 +1,44 @@ +const url = require(`url`).parse; + +const { dependencies, devDependencies } = require(`../../package.json`); +const source = require(`./sourcePackage`); + +module.exports = (name) => new Promise(async res => { + const { pkg, lock } = await source(name); + + const main = { + name, + version: `${dependencies[name] || devDependencies[name]}`.replace(`^`, ``) + }, details = {}; + + // Get package.json details + + if(pkg && typeof pkg == `object`) { + if(pkg.author) details.author = pkg.author; + if(pkg.license) details.license = pkg.license; + + if(pkg.description) details.description = pkg.description; + }; + + // Get package-lock.json details + + if(lock && typeof lock == `object`) { + if(lock.version) main.version = lock.version; + + if(lock.resolved) { + details.package = { + integrity: lock.integrity, + sourced: url(lock.resolved).host, + file: url(lock.resolved).pathname.split(`/`).pop() + } + } + } + + res({ + ...main, details, + url: { + package: `https://www.npmjs.com/package/${name}`, + version: `https://www.npmjs.com/package/${name}/v/${main.version}` + } + }); +}) \ No newline at end of file diff --git a/util/build/sourcePackage.js b/util/build/sourcePackage.js new file mode 100644 index 0000000..fc0584d --- /dev/null +++ b/util/build/sourcePackage.js @@ -0,0 +1,30 @@ +const path = require(`path`); + +const getPath = require(`../getPath`); +const pfs = require(`../promisifiedFS`); + +const lock = Object.entries(require(`../../package-lock.json`).packages) + .map(([k, v]) => ({ [k.split(`node_modules/`).pop()]: v })) + .reduce((a, b) => Object.assign(a, b), {}); + +console.log(`lock`, lock) + +module.exports = (name) => new Promise(async res => { + const resObj = {}; + + try { + const packageFilePath = await getPath(`./node_modules/${name}/package.json`, false, false, true); + const packageFile = await pfs.readFileSync(packageFilePath, `utf8`); + const package = JSON.parse(packageFile); + + resObj.pkg = package; + } catch(e) { + console.log(`Error reading package.json for ${name}: ${e}`); + } + + if(lock[name]) { + resObj.lock = lock[name]; + }; + + res(resObj); +}) \ No newline at end of file