mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-22 09:37:17 +00:00
Make a tool for collecting skins and automating screenshots
This commit is contained in:
parent
48cac8d619
commit
100795bba1
17 changed files with 260 additions and 3030 deletions
|
|
@ -1,36 +0,0 @@
|
|||
# Automated Screenshots
|
||||
|
||||
## Setup
|
||||
|
||||
Clone the Webamp repo:
|
||||
|
||||
```
|
||||
git clone git@github.com:captbaritone/webamp.git
|
||||
```
|
||||
|
||||
Start Webamp in dev mode:
|
||||
|
||||
```
|
||||
cd webamp
|
||||
yarn install
|
||||
npm start
|
||||
```
|
||||
|
||||
Webamp should now be running on your local port 8080.
|
||||
|
||||
Now, in a separate terminal:
|
||||
|
||||
```
|
||||
cd experiments/automated_screenshots
|
||||
yarn install
|
||||
```
|
||||
|
||||
Place skins in `experiments/automatedScreenshots/skins`. Subdirectories are fine, `.wsz` files will be searched for recursively.
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
Wait...
|
||||
|
||||
Find screenshots in `experiments/automatedScreenshots/screenshots`.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const Filehound = require("filehound");
|
||||
const md5File = require("md5-file");
|
||||
const Shooter = require("./shooter");
|
||||
|
||||
(async () => {
|
||||
const shooter = new Shooter();
|
||||
const passedSkin = process.argv[2];
|
||||
let files = [];
|
||||
if (passedSkin) {
|
||||
files.push(passedSkin);
|
||||
} else {
|
||||
files = await Filehound.create()
|
||||
.ext("wsz")
|
||||
.paths("skins/")
|
||||
.find();
|
||||
}
|
||||
|
||||
for (const skin of files) {
|
||||
console.log("Trying", skin);
|
||||
const skinMd5 = md5File.sync(skin);
|
||||
const screenshotPath = `screenshots/${skinMd5}.png`;
|
||||
if (fs.existsSync(screenshotPath)) {
|
||||
console.log(screenshotPath, "exists already");
|
||||
continue;
|
||||
}
|
||||
await shooter.takeScreenshot(path.join(__dirname, skin), screenshotPath, {
|
||||
minify: true
|
||||
});
|
||||
}
|
||||
|
||||
await shooter.dispose();
|
||||
})();
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
447
experiments/automatedScreenshots/package-lock.json
generated
447
experiments/automatedScreenshots/package-lock.json
generated
|
|
@ -1,447 +0,0 @@
|
|||
{
|
||||
"name": "automated_screenshots",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.1.1.tgz",
|
||||
"integrity": "sha512-yWGUUmCZD/33IRjG2It94PzixT8lX+47Uq8fjmd0cgQWITCMrJuXFaVIMnGDmDnZGGKAGdwTx8UGeU8lMR2urA==",
|
||||
"requires": {
|
||||
"es6-promisify": "5.0.0"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
|
||||
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
|
||||
"requires": {
|
||||
"balanced-match": "1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
|
||||
"integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
|
||||
"requires": {
|
||||
"inherits": "2.0.3",
|
||||
"readable-stream": "2.3.3",
|
||||
"typedarray": "0.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"safe-buffer": "5.1.1",
|
||||
"string_decoder": "1.0.3",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
|
||||
"integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"err-code": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
|
||||
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz",
|
||||
"integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y="
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"requires": {
|
||||
"es6-promise": "4.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"es6-promise": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
|
||||
"integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz",
|
||||
"integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=",
|
||||
"requires": {
|
||||
"concat-stream": "1.6.0",
|
||||
"debug": "2.2.0",
|
||||
"mkdirp": "0.5.0",
|
||||
"yauzl": "2.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
||||
"requires": {
|
||||
"ms": "0.7.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
||||
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
|
||||
}
|
||||
}
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
|
||||
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
|
||||
"requires": {
|
||||
"pend": "1.2.0"
|
||||
}
|
||||
},
|
||||
"file-js": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz",
|
||||
"integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=",
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"minimatch": "3.0.4",
|
||||
"proper-lockfile": "1.2.0"
|
||||
}
|
||||
},
|
||||
"filehound": {
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/filehound/-/filehound-1.16.2.tgz",
|
||||
"integrity": "sha1-5yrvpVh3I+LimQddFH6La1eMc9A=",
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"file-js": "0.3.0",
|
||||
"lodash": "4.17.4",
|
||||
"minimatch": "3.0.4",
|
||||
"moment": "2.18.1",
|
||||
"unit-compare": "1.0.1"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.1.0.tgz",
|
||||
"integrity": "sha512-/DTVSUCbRc6AiyOV4DBRvPDpKKCJh4qQJNaCgypX0T41quD9hp/PB5iUyx/60XobuMPQa9ce1jNV9UOUq6PnTg==",
|
||||
"requires": {
|
||||
"agent-base": "4.1.1",
|
||||
"debug": "2.6.9"
|
||||
}
|
||||
},
|
||||
"immediate": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "1.4.0",
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"jszip": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.4.tgz",
|
||||
"integrity": "sha512-z6w8iYIxZ/fcgul0j/OerkYnkomH8BZigvzbxVmr2h5HkZUrPtk2kjYtLkqR9wwQxEP6ecKNoKLsbhd18jfnGA==",
|
||||
"requires": {
|
||||
"core-js": "2.3.0",
|
||||
"es6-promise": "3.0.2",
|
||||
"lie": "3.1.1",
|
||||
"pako": "1.0.6",
|
||||
"readable-stream": "2.0.6"
|
||||
}
|
||||
},
|
||||
"lie": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
|
||||
"requires": {
|
||||
"immediate": "3.0.6"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.8"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
|
||||
"integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.18.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
|
||||
"integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
||||
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"progress": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
|
||||
"integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
|
||||
},
|
||||
"proper-lockfile": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz",
|
||||
"integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=",
|
||||
"requires": {
|
||||
"err-code": "1.1.2",
|
||||
"extend": "3.0.1",
|
||||
"graceful-fs": "4.1.11",
|
||||
"retry": "0.10.1"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
|
||||
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4="
|
||||
},
|
||||
"puppeteer": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-0.10.2.tgz",
|
||||
"integrity": "sha512-dj1MdwiYfEwTemfFeBu0inGyhcaEe3cKREvTFSA/pkGHaCwyj/FFfJHJpr9vykXvSs/PbmcApOztsUyqzd1msA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"extract-zip": "1.6.5",
|
||||
"https-proxy-agent": "2.1.0",
|
||||
"mime": "1.4.1",
|
||||
"progress": "2.0.0",
|
||||
"proxy-from-env": "1.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"ws": "3.2.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
|
||||
"integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"string_decoder": "0.10.31",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
|
||||
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"requires": {
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz",
|
||||
"integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ="
|
||||
},
|
||||
"unit-compare": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz",
|
||||
"integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=",
|
||||
"requires": {
|
||||
"moment": "2.18.1"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.2.0.tgz",
|
||||
"integrity": "sha512-hTS3mkXm/j85jTQOIcwVz3yK3up9xHgPtgEhDBOH3G18LDOZmSAG1omJeXejLKJakx+okv8vS1sopgs7rw0kVw==",
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"ultron": "1.1.0"
|
||||
}
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
|
||||
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
|
||||
"requires": {
|
||||
"fd-slicer": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"name": "automated_screenshots",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"clean": "rm screenshots/*.png",
|
||||
"sync-screenshots": "aws s3 sync --acl=public-read screenshots/ s3://webamp-uploaded-skins/screenshots/",
|
||||
"sync-skins": "aws s3 sync --acl=public-read md5Skins/ s3://webamp-uploaded-skins/skins/",
|
||||
"sync": "npm run sync-screenshots && npm run sync-skins"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"filehound": "^1.16.2",
|
||||
"imagemin": "^5.3.1",
|
||||
"imagemin-optipng": "^5.2.1",
|
||||
"imagemin-pngquant": "^5.1.0",
|
||||
"jszip": "^3.1.4",
|
||||
"md5-file": "^3.2.3",
|
||||
"puppeteer": "^0.13.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
File diff suppressed because it is too large
Load diff
1
experiments/skinArchiveTools/.gitignore
vendored
Normal file
1
experiments/skinArchiveTools/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
assets/*
|
||||
43
experiments/skinArchiveTools/README.md
Normal file
43
experiments/skinArchiveTools/README.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Skin Archive Tools
|
||||
|
||||
A collection of scripts for managing the Internet Archive's collection of Winamp Skins.
|
||||
|
||||
It works as a data pipeline. The phases are:
|
||||
|
||||
## 1. Collect Skins
|
||||
|
||||
I collect skins into a single directory on my computer. There is no real organizational strategy within this directory. It's deeply nested and there are many duplicates, as it consists of multiple collections, small and large, from multiple sources.
|
||||
|
||||
We will also extrack skins for "packs" which are zip files containing multiple skins.
|
||||
|
||||
## 2. Skins Are Deduped
|
||||
|
||||
A script creates a single flat directory that contains each skin named only by its md5 hash.
|
||||
|
||||
## 3. Screenshots Are Taken
|
||||
|
||||
Yup.
|
||||
|
||||
## 4. Skins Are Synced to the Internet Archive
|
||||
|
||||
TODO
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
Note: This will probably break the first time it's run, since it requires a directory structure that is currently not checked in due to `.gitignore`.
|
||||
|
||||
Something like:
|
||||
|
||||
```
|
||||
$ tree assets -d -L 1
|
||||
assets
|
||||
├── md5Invalids
|
||||
├── md5Packs
|
||||
├── md5Screenshots
|
||||
├── md5Skins
|
||||
└── skins
|
||||
```
|
||||
82
experiments/skinArchiveTools/lib/collectSkins.js
Normal file
82
experiments/skinArchiveTools/lib/collectSkins.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const fsPromises = require("fs").promises;
|
||||
const childProcess = require("child_process");
|
||||
const { memoize } = require("lodash");
|
||||
const md5File = require("md5-file/promise");
|
||||
const Filehound = require("filehound");
|
||||
const Utils = require("./utils");
|
||||
|
||||
const memoizedMd5File = memoize(md5File);
|
||||
|
||||
module.exports = async function collectSkins({
|
||||
inputDir,
|
||||
outputDir,
|
||||
filenamesPath
|
||||
}) {
|
||||
const files = await Filehound.create()
|
||||
.ext(["zip", "wsz"])
|
||||
.paths(inputDir)
|
||||
.find();
|
||||
|
||||
const uniqueFiles = await Utils.unique(files, memoizedMd5File);
|
||||
|
||||
const collectionInfo = await Promise.all(
|
||||
uniqueFiles.map(async filePath => {
|
||||
const md5 = await memoizedMd5File(filePath);
|
||||
const skinType = await Utils.skinType(filePath);
|
||||
const md5Path = path.join(outputDir, `${md5}.wsz`);
|
||||
const info = { filePath, md5, skinType, moved: false, md5Path };
|
||||
if (info.skinType !== "CLASSIC") {
|
||||
return info;
|
||||
}
|
||||
const exists = fs.existsSync(info.md5Path);
|
||||
if (!exists) {
|
||||
await fsPromises.link(filePath, info.md5Path);
|
||||
info.moved = true;
|
||||
}
|
||||
return info;
|
||||
})
|
||||
);
|
||||
|
||||
const pathList = collectionInfo
|
||||
.map(info => `${info.md5} ${path.relative(inputDir, info.filePath)}`)
|
||||
.join("\n");
|
||||
|
||||
fsPromises.writeFile(filenamesPath, pathList);
|
||||
collectionInfo
|
||||
.filter(info => info.skinType === "PACK")
|
||||
.forEach(pack => {
|
||||
const packPath = path.resolve(`./assets/md5Packs/${pack.md5}`);
|
||||
if (fs.existsSync(packPath)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
childProcess.execSync(`unzip "${pack.filePath}" -d "${packPath}"`);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
collectionInfo
|
||||
.filter(info => info.skinType === "INVALID")
|
||||
.forEach(async invalid => {
|
||||
const filePath = path.resolve(`./assets/md5Invalids/${invalid.md5}.wsz`);
|
||||
if (fs.existsSync(filePath)) {
|
||||
return;
|
||||
}
|
||||
await fsPromises.link(invalid.filePath, filePath, invalid.md5Path);
|
||||
});
|
||||
return {
|
||||
total: files.length,
|
||||
unique: uniqueFiles.length,
|
||||
moved: collectionInfo.filter(info => info.moved).length,
|
||||
newScreenshots: collectionInfo.filter(info => info.screenshotCreated)
|
||||
.length,
|
||||
classic: collectionInfo.filter(info => info.skinType === "CLASSIC").length,
|
||||
packs: collectionInfo.filter(info => info.skinType === "PACK").length,
|
||||
invalid: collectionInfo.filter(info => info.skinType === "INVALID").length,
|
||||
modern: collectionInfo.filter(info => info.skinType === "MODERN").length,
|
||||
// TODO: Tell modern skins from packs
|
||||
nonClassic: collectionInfo.filter(info => !info.classic).length
|
||||
};
|
||||
};
|
||||
50
experiments/skinArchiveTools/lib/index.js
Executable file
50
experiments/skinArchiveTools/lib/index.js
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
const path = require("path");
|
||||
const collectSkins = require("./collectSkins");
|
||||
const takeScreenshots = require("./takeScreenshots");
|
||||
|
||||
/**
|
||||
* Usage
|
||||
*
|
||||
* command <input_dir> <output_dir> <screenshot_dir>
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const [
|
||||
_node,
|
||||
_thisFile,
|
||||
rawInputDir,
|
||||
rawOutputDir,
|
||||
rawScreenshotDir,
|
||||
rawFilenamesPath
|
||||
] = process.argv;
|
||||
|
||||
const inputDir = path.resolve(rawInputDir);
|
||||
const outputDir = path.resolve(rawOutputDir);
|
||||
const screenshotDir = path.resolve(rawScreenshotDir);
|
||||
const filenamesPath = path.resolve(rawFilenamesPath);
|
||||
|
||||
const collect = true;
|
||||
const screenshots = true;
|
||||
|
||||
async function main() {
|
||||
if (collect) {
|
||||
const collectionInfo = await collectSkins({
|
||||
filenamesPath,
|
||||
inputDir,
|
||||
outputDir
|
||||
});
|
||||
console.log(collectionInfo);
|
||||
const packCollectionInfo = await collectSkins({
|
||||
filenamesPath,
|
||||
inputDir: path.resolve(path.join("assets", "md5Packs")),
|
||||
outputDir
|
||||
});
|
||||
console.log(packCollectionInfo);
|
||||
}
|
||||
if (screenshots) {
|
||||
await takeScreenshots(outputDir, screenshotDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Blastoff!
|
||||
main();
|
||||
|
|
@ -21,7 +21,7 @@ class Shooter {
|
|||
this._page = await this._browser.newPage();
|
||||
this._page.setViewport({ width: 275, height: 116 * 3 });
|
||||
this._page.on("console", (...args) => {
|
||||
console.log("PAGE LOG:", ...args);
|
||||
// console.log("PAGE LOG:", ...args);
|
||||
});
|
||||
const url = `http://localhost:8080/?screenshot=1`;
|
||||
await this._page.goto(url);
|
||||
|
|
@ -33,18 +33,6 @@ class Shooter {
|
|||
this._initialized = true;
|
||||
}
|
||||
|
||||
_validateZip(u) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
fs.readFile(u, (err, buffer) => {
|
||||
JSZip.loadAsync(buffer).then(resolve, reject);
|
||||
});
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async _ensureInitialized() {
|
||||
if (!this._initialized) {
|
||||
await this.init();
|
||||
|
|
@ -55,17 +43,15 @@ class Shooter {
|
|||
await this._ensureInitialized();
|
||||
console.log("Going to try", screenshotPath);
|
||||
try {
|
||||
await this._validateZip(skin);
|
||||
} catch (e) {
|
||||
console.log("Error parsing", skin, e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
console.log("geting input");
|
||||
const handle = await this._page.$("#webamp-file-input");
|
||||
console.log("uploading skin");
|
||||
await handle.uploadFile(skin);
|
||||
console.log("waiting for skin to load...");
|
||||
await this._page.evaluate(() => {
|
||||
return window.__webamp.skinIsLoaded();
|
||||
});
|
||||
console.log("waiting for screenshot");
|
||||
await this._page.screenshot({
|
||||
path: screenshotPath,
|
||||
omitBackground: true, // Make screenshot transparent
|
||||
23
experiments/skinArchiveTools/lib/takeScreenshots.js
Normal file
23
experiments/skinArchiveTools/lib/takeScreenshots.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const md5File = require("md5-file/promise");
|
||||
const Filehound = require("filehound");
|
||||
const Shooter = require("./shooter");
|
||||
|
||||
module.exports = async function takeScreenshots(skinDir, screenshotDir) {
|
||||
const files = await Filehound.create()
|
||||
.ext(["wsz"])
|
||||
.paths(skinDir)
|
||||
.find();
|
||||
const shooter = new Shooter();
|
||||
for (const filePath of files) {
|
||||
const md5 = await md5File(filePath);
|
||||
const screenshotPath = path.join(screenshotDir, `${md5}.png`);
|
||||
if (fs.existsSync(screenshotPath)) {
|
||||
continue;
|
||||
}
|
||||
await shooter.takeScreenshot(filePath, screenshotPath, {
|
||||
minify: true
|
||||
});
|
||||
}
|
||||
};
|
||||
35
experiments/skinArchiveTools/lib/utils.js
Normal file
35
experiments/skinArchiveTools/lib/utils.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
const JSZip = require("jszip");
|
||||
const fsPromises = require("fs").promises;
|
||||
|
||||
// Reduce an array down to it's unique value given an async hasher function
|
||||
async function unique(arr, hasher) {
|
||||
const seen = new Set();
|
||||
const items = [];
|
||||
await Promise.all(
|
||||
arr.map(async item => {
|
||||
const key = await hasher(item);
|
||||
if (seen.has(key)) {
|
||||
return;
|
||||
}
|
||||
seen.add(key);
|
||||
items.push(item);
|
||||
})
|
||||
);
|
||||
return items;
|
||||
}
|
||||
|
||||
async function skinType(skinPath) {
|
||||
const buffer = await fsPromises.readFile(skinPath);
|
||||
try {
|
||||
const zip = await JSZip.loadAsync(buffer);
|
||||
if (zip.file(/.*\.(wsz|wal|zip)$/i).length) {
|
||||
// This is a collection of skins
|
||||
return "PACK";
|
||||
}
|
||||
return zip.file(/^main\.bmp$/i).length === 1 ? "CLASSIC" : "MODERN";
|
||||
} catch (e) {
|
||||
return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { unique, skinType };
|
||||
21
experiments/skinArchiveTools/package.json
Normal file
21
experiments/skinArchiveTools/package.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "skinarchivetools",
|
||||
"version": "1.0.0",
|
||||
"description": "A collection of scripts for managing the Internet Archive's collection of Winamp Skins.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node lib/index.js ./assets/skins ./assets/md5Skins ./assets/md5Screenshots ./assets/filenames.txt",
|
||||
"clean": "cd md5Skins && find . -delete"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"filehound": "^1.17.0",
|
||||
"imagemin": "^6.1.0",
|
||||
"imagemin-optipng": "^6.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"md5-file": "^4.0.0",
|
||||
"puppeteer": "^1.12.2"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue