Files
archy-demo/neode-ui/scripts/download-app-icons.js
2026-03-17 02:14:04 +00:00

174 lines
4.6 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Script to download app icons from GitHub repositories
* Downloads icons for all dummy apps from Start9Labs/{app-id}-startos repos
*/
import fs from 'fs'
import path from 'path'
import https from 'https'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const appIds = [
'bitcoin',
'btcpay-server',
'homeassistant',
'grafana',
'endurain',
'fedimint',
'morphos-server',
'lightning-stack',
'mempool',
'ollama',
'searxng',
'onlyoffice',
'penpot'
]
// Map app IDs to their Start9 repo names (some might differ)
const repoMap = {
'bitcoin': 'bitcoind-startos',
'btcpay-server': 'btcpayserver-startos',
'homeassistant': 'home-assistant-startos',
'grafana': 'grafana-startos',
'lightning-stack': 'lnd-startos',
'mempool': 'mempool-startos',
'searxng': 'searxng-startos',
'onlyoffice': 'onlyoffice-startos',
'penpot': 'penpot-startos',
}
// Custom icon URLs for apps without Start9 repos
const customIconUrls = {
'fedimint': [
'https://raw.githubusercontent.com/fedibtc/fedimint-ui/master/apps/router/public/favicon.svg',
],
}
const iconDir = path.join(__dirname, '../public/assets/img/app-icons')
// Ensure directory exists
if (!fs.existsSync(iconDir)) {
fs.mkdirSync(iconDir, { recursive: true })
}
function downloadFile(url, filepath) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(filepath)
https.get(url, (response) => {
if (response.statusCode === 200) {
response.pipe(file)
file.on('finish', () => {
file.close()
console.log(`✅ Downloaded: ${path.basename(filepath)}`)
resolve()
})
} else if (response.statusCode === 404) {
file.close()
fs.unlinkSync(filepath) // Delete empty file
console.log(`⚠️ Not found: ${url}`)
reject(new Error(`404: ${url}`))
} else {
file.close()
fs.unlinkSync(filepath)
reject(new Error(`HTTP ${response.statusCode}: ${url}`))
}
}).on('error', (err) => {
file.close()
if (fs.existsSync(filepath)) {
fs.unlinkSync(filepath)
}
reject(err)
})
})
}
async function downloadIcon(appId) {
const targetExt = 'webp' // Prefer webp for consistency with mempool, etc.
const fallbackExts = ['webp', 'png', 'svg']
const filepath = path.join(iconDir, `${appId}.webp`)
// Skip if file already exists
if (appId === 'fedimint' && fs.existsSync(path.join(iconDir, 'fedimint.png'))) {
console.log(`⏭️ Skipping ${appId} (fedimint.png exists)`)
return true
}
for (const ext of fallbackExts) {
const fp = path.join(iconDir, `${appId}.${ext}`)
if (fs.existsSync(fp)) {
console.log(`⏭️ Skipping ${appId} (already exists)`)
return true
}
}
// Try custom URLs first (e.g. fedimint from fedimint-ui)
if (customIconUrls[appId]) {
for (const url of customIconUrls[appId]) {
try {
const ext = url.endsWith('.svg') ? 'svg' : (url.endsWith('.png') ? 'png' : 'webp')
const fp = path.join(iconDir, `${appId}.${ext}`)
await downloadFile(url, fp)
return true
} catch (err) {
continue
}
}
}
const repoName = repoMap[appId] || `${appId}-startos`
const iconPaths = ['icon.png', 'icon.svg', 'assets/icon.png', 'assets/icon.svg']
for (const iconPath of iconPaths) {
const url = `https://raw.githubusercontent.com/Start9Labs/${repoName}/main/${iconPath}`
const extension = iconPath.endsWith('.svg') ? 'svg' : 'png'
const fp = path.join(iconDir, `${appId}.${extension}`)
try {
await downloadFile(url, fp)
return true
} catch (err) {
continue
}
}
console.log(`❌ Failed to download icon for ${appId}`)
return false
}
async function main() {
console.log('Downloading app icons from GitHub...\n')
const results = {
success: [],
failed: []
}
for (const appId of appIds) {
try {
const success = await downloadIcon(appId)
if (success) {
results.success.push(appId)
} else {
results.failed.push(appId)
}
// Small delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 500))
} catch (err) {
console.error(`Error downloading ${appId}:`, err.message)
results.failed.push(appId)
}
}
console.log(`\n✅ Successfully downloaded ${results.success.length} icons`)
if (results.failed.length > 0) {
console.log(`❌ Failed to download ${results.failed.length} icons:`, results.failed.join(', '))
}
}
main().catch(console.error)