Created
September 18, 2024 06:17
-
-
Save xrabohrok/c74ee316bd23372f7d2327cd4b92ab30 to your computer and use it in GitHub Desktop.
deploy script for uploading to neocities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import axios from 'axios'; | |
import * as fs from 'fs'; | |
import * as fspromise from 'fs/promises' | |
import * as readline from 'readline' | |
import FormData from 'form-data' | |
import execSync from 'child_process'; | |
// current assumptions | |
const secretFile = 'secret'; | |
const localArtifactRoot = 'src/.vuepress/dist/'; | |
const batchSize = 3; | |
const excludeFiles = [ | |
'sitemap.xsl' // this is a paid feature for Neocities | |
] | |
var neocityUser = ''; | |
var neocityPW = ''; | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
var authKey = ''; | |
while(authKey === ''){ | |
if(!fs.existsSync(secretFile)){ | |
console.log('No Key found'); | |
console.log('=================='); | |
neocityUser = await new Promise( resolve => { | |
rl.question('Please enter Neocities Username:', resolve); | |
}); | |
neocityPW = await new Promise( resolve => { | |
rl.question('Please enter Neocities Password:', resolve); | |
}); | |
neocityPW = encodeURI(neocityPW); | |
await axios.get( `https://${neocityUser}:${neocityPW}@neocities.org/api/key`) | |
.then( response => { | |
if(response.data?.result === 'success'){ | |
authKey = response.data.api_key; | |
fs.writeFileSync(secretFile, authKey); | |
} | |
}); | |
} | |
else{ | |
console.log('Auth Key found'); | |
authKey = fs.readFileSync(secretFile, {encoding:'ascii'}); | |
//test the auth key because it might have expired | |
const neocities_temp = axios.create({ | |
baseURL: 'https://neocities.org/api', | |
headers: { | |
Authorization: `Bearer ${authKey}` | |
} | |
}); | |
var failed = false; | |
var result = await neocities_temp.get('/list') | |
.catch(reason => { | |
console.log(reason); | |
failed = true; | |
}); | |
if( result?.status === 401 || result?.status === 403 || failed){ | |
console.log('Nuking auth file, likely expired.') | |
fs.rmSync(secretFile); | |
authKey = ''; | |
} | |
} | |
} | |
console.log(`Auth Key: ${authKey}`); | |
const neocities = axios.create({ | |
baseURL: 'https://neocities.org/api', | |
headers: { | |
Authorization: `Bearer ${authKey}` | |
} | |
}) | |
var executing = true; | |
while(executing){ | |
console.log('What do you want to do?'); | |
console.log('\t # 1. Update Build artifact'); | |
console.log('\t # 2. Get Website Info'); | |
console.log('\t # 3. Get a list of all files') | |
console.log('\t # 4. Upload to Neocities'); | |
console.log('\t # 0. Quit'); | |
var choice = await new Promise( resolve => { | |
rl.question('Choose from above:', resolve); | |
}); | |
choice = choice.trim(); | |
if(choice === '0'){ | |
executing = false; | |
} | |
else if(choice === '1'){ | |
if(fs.existsSync(localArtifactRoot)){ | |
fs.rmSync(localArtifactRoot, {recursive: true}); | |
console.log('dist folder nuked'); | |
} | |
execSync.execSync('npm run docs:build'); | |
} | |
else if(choice === '2'){ | |
var info = await neocities.get('/info'); | |
console.log(JSON.stringify(info.data)); | |
} | |
else if(choice === '3'){ | |
var info = await neocities.get('/list'); | |
if(info.data?.result === 'success'){ | |
var files = info.data.files.map(f =>{ | |
return `${f?.size}\t | ${f?.updated_at} \t | ${f?.path} ` | |
}); | |
files.forEach(f => { | |
console.log(f); | |
}); | |
} | |
} | |
else if(choice === '4'){ | |
var distStructure = await fspromise.readdir(localArtifactRoot, {recursive: true, encoding: 'utf8', withFileTypes: true}); | |
var filesToUpload = [] | |
distStructure | |
.filter(d => !d.isDirectory()) | |
.filter(f => excludeFiles.findIndex(ex => f.name.includes(ex)) < 0) | |
.forEach(d =>{ | |
const normalizedFileName = `${d.parentPath.replace(/\/$/, '')}/${d.name}` | |
filesToUpload.push({ | |
localFile: normalizedFileName, | |
remoteFile: normalizedFileName.replace(localArtifactRoot, '') | |
}) | |
}); | |
var batchNum = 0 | |
for(let i = 0; i < filesToUpload.length; i += batchSize){ | |
var batch = filesToUpload.slice(i, i + batchSize); | |
var formData = new FormData(); | |
batch.forEach(bi => { | |
formData.append(bi.remoteFile, fs.createReadStream(bi.localFile)); | |
}); | |
await neocities.post('upload', formData, { | |
headers: { | |
...formData.getHeaders() | |
}, | |
}).then( () => { | |
batchNum += 1; | |
console.log(`batch ${batchNum} of ${Math.ceil(filesToUpload.length/batchSize)} Success`); | |
}); | |
} | |
console.log(`Number of files: ${distStructure.length}`); | |
} | |
else { | |
console.log(`Command not Recognized: ${choice}`); | |
} | |
} | |
process.exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment