#!/usr/bin/node --expose-gc const fetch = require("node-fetch"); const request = require("request"); const fs = require("fs"); const ncp = require("ncp"); const asar = require("asar"); const archiver = require("archiver"); const exec = require("child_process").exec; const branches = ["canary", "ptb", "stable"]; const platforms = ["win", "linux", "osx"]; console.log("loading config..."); var config = fs.existsSync("config.json") ? JSON.parse(fs.readFileSync("config.json").toString()) : {}; var lastver = {}; function patch(target, resolve) { console.log("extracting zip..."); if (!fs.existsSync(target)) fs.mkdirSync(target); console.log(`unzip -o ${target}.orig.zip -d ${target}`); var child = exec(`unzip -o ${target}.orig.zip -d ${target}`); child.stdout.pipe(process.stdout); child.on("exit", () => { path = target + "/core"; console.log("extracting asar..."); asar.extractAll(path + ".asar", path); console.log("patching mainScreen.js..."); var mainScreen = fs .readFileSync(path + "/app/mainScreen.js") .toString(); mainScreen = mainScreen .replace(/nodeIntegration: false,/, "nodeIntegration: true,") .replace( /mainWindow\.loadURL\(URL_TO_LOAD\);/, "mainWindow.loadURL(_url.format({ pathname: _path2.default.join(__dirname, 'bspwn/updater.html'), protocol: 'file:', slashes: true }));" ); fs.writeFileSync(path + "/app/mainScreen.js", mainScreen); console.log("patching mainScreenPreload.js..."); var mainScreenPreload = fs .readFileSync(path + "/app/mainScreenPreload.js") .toString(); mainScreenPreload = mainScreenPreload.replace( /var electron = require\('electron'\);/, "var bspwn = require('./bspwn');\nbspwn.go();\nvar electron = require('electron');" ); fs.writeFileSync(path + "/app/mainScreenPreload.js", mainScreenPreload); console.log("copying bspwn files..."); ncp.ncp(__dirname + "/bspwn", path + "/app/bspwn", () => { console.log("zipping it all up..."); var archive = archiver("zip"); var output = fs.createWriteStream( (config.target || "./") + target + ".zip" ); archive.pipe(output); archive.directory(path, "core"); archive.file(__dirname + "/files/index.js", { name: "index.js" }); archive.file(target + "/package.json", { name: "package.json" }); archive.finalize(); //output.close(resolve); resolve(); }); }); } async function scrape() { console.log("scraping..."); try { for (b in branches) { var branch = branches[b]; for (p in platforms) { await new Promise(async (resolve, reject) => { var platform = platforms[p]; var ident = `${branch}-${platform}`; var currentver = await fetch( `https://discordapp.com/api/updates/${branch}?platform=${platform}` ); currentver = await currentver.json(); currentver = currentver.name; var modules = await fetch( `https://discordapp.com/api/modules/${branch}/versions.json?platform=${platform}&host_version=${currentver}` ); modules = await modules.json(); var verstring = `${currentver}-${ modules.discord_desktop_core }`; console.log(`${ident} ${verstring}`); if (!lastver[ident] || verstring > lastver[ident]) { console.log("update available, fetching..."); lastver[ident] = verstring; var target = `https://discordapp.com/api/modules/${branch}/discord_desktop_core/${ modules.discord_desktop_core }?platform=${platform}&host_version=${currentver}`; console.log(target); request( { followAllRedirects: true, url: target, encoding: null }, (err, response, body) => { fs.writeFile( "./" + ident + ".orig.zip", body, () => { console.log("done downloading"); patch(ident, resolve); } ); } ); } else resolve(); }); } } } catch (ex) { console.log(ex); } console.log("scraping again in 15 minutes"); global.gc(); } setInterval(scrape, 15 * 60 * 1000); //setInterval(scrape, 60*1000); scrape();