mirror of
https://github.com/scratchfoundation/scratch-desktop.git
synced 2024-12-23 06:02:30 -05:00
91e16c2ab5
Assets which are referenced by a sprite but not referenced by the sound, costume, or backdrop libraries were being missed by previous versions. I also removed the default parameter to several methods in order to reduce the likelihood of similar mistakes in the future.
108 lines
3.3 KiB
JavaScript
108 lines
3.3 KiB
JavaScript
const fs = require('fs');
|
|
const https = require('https');
|
|
const path = require('path');
|
|
const util = require('util');
|
|
|
|
const async = require('async');
|
|
|
|
const libraries = require('./lib/libraries');
|
|
|
|
const ASSET_HOST = 'cdn.assets.scratch.mit.edu';
|
|
const NUM_SIMULTANEOUS_DOWNLOADS = 5;
|
|
const OUT_PATH = path.resolve('static', 'assets');
|
|
|
|
|
|
const describe = function (object) {
|
|
return util.inspect(object, false, Infinity, true);
|
|
};
|
|
|
|
const collectSimple = function (library, dest, debugLabel = 'Item') {
|
|
library.forEach(item => {
|
|
let md5Count = 0;
|
|
if (item.md5) {
|
|
++md5Count;
|
|
dest.add(item.md5);
|
|
}
|
|
if (item.baseLayerMD5) {
|
|
++md5Count;
|
|
dest.add(item.baseLayerMD5);
|
|
}
|
|
if (md5Count < 1) {
|
|
console.warn(`${debugLabel} has no MD5 property:\n${describe(item)}`);
|
|
} else if (md5Count > 1) {
|
|
// is this actually bad?
|
|
console.warn(`${debugLabel} has multiple MD5 properties:\n${describe(item)}`);
|
|
}
|
|
});
|
|
return dest;
|
|
};
|
|
|
|
const collectAssets = function (dest) {
|
|
collectSimple(libraries.backdrops, dest, 'Backdrop');
|
|
collectSimple(libraries.costumes, dest, 'Costume');
|
|
collectSimple(libraries.sounds, dest, 'Sound');
|
|
libraries.sprites.forEach(sprite => {
|
|
if (sprite.md5) {
|
|
dest.add(sprite.md5);
|
|
} else {
|
|
console.warn(`Sprite has no MD5 property:\n${describe(sprite)}`);
|
|
}
|
|
if (sprite.json.costumes) {
|
|
collectSimple(sprite.json.costumes, dest, `Costume for sprite ${sprite.name}`);
|
|
}
|
|
if (sprite.json.sounds) {
|
|
collectSimple(sprite.json.sounds, dest, `Sound for sprite ${sprite.name}`);
|
|
}
|
|
});
|
|
return dest;
|
|
};
|
|
|
|
const connectionPool = [];
|
|
|
|
const fetchAsset = function (md5, callback) {
|
|
const myAgent = connectionPool.pop() || new https.Agent({keepAlive: true});
|
|
const getOptions = {
|
|
host: ASSET_HOST,
|
|
path: `/internalapi/asset/${md5}/get/`,
|
|
agent: myAgent
|
|
};
|
|
const urlHuman = `//${getOptions.host}${getOptions.path}`;
|
|
https.get(getOptions, response => {
|
|
if (response.statusCode !== 200) {
|
|
callback(new Error(`Request failed: status code ${response.statusCode} for ${urlHuman}`));
|
|
return;
|
|
}
|
|
|
|
const stream = fs.createWriteStream(path.resolve(OUT_PATH, md5), {encoding: 'binary'});
|
|
stream.on('error', callback);
|
|
response.on('data', chunk => {
|
|
stream.write(chunk);
|
|
});
|
|
response.on('end', () => {
|
|
connectionPool.push(myAgent);
|
|
stream.end();
|
|
console.log(`Fetched ${urlHuman}`);
|
|
callback();
|
|
});
|
|
});
|
|
};
|
|
|
|
const fetchAllAssets = function () {
|
|
const allAssets = collectAssets(new Set());
|
|
console.log(`Total library assets: ${allAssets.size}`);
|
|
|
|
async.forEachLimit(allAssets, NUM_SIMULTANEOUS_DOWNLOADS, fetchAsset, err => {
|
|
if (err) {
|
|
console.error(`Fetch failed:\n${describe(err)}`);
|
|
} else {
|
|
console.log('Fetch succeeded.');
|
|
}
|
|
|
|
console.log(`Shutting down ${connectionPool.length} agents.`);
|
|
while (connectionPool.length > 0) {
|
|
connectionPool.pop().destroy();
|
|
}
|
|
});
|
|
};
|
|
|
|
fetchAllAssets();
|