diff --git a/public/shu/scenes/index.html b/public/shu/scenes/index.html
index 2bd8184e..87f9a04f 100644
--- a/public/shu/scenes/index.html
+++ b/public/shu/scenes/index.html
@@ -52,7 +52,7 @@
let scene = data[i];
let sid = scene.sid;
- let urlCover = (scene.cover)? ATON.PATH_SCENES+sid+"/cover.png" : ATON.PATH_RES+"scenecover.png";
+ let urlCover = ATON.PATH_RESTAPI2+"scenes/"+sid+"/cover"; //(scene.cover)? ATON.PATH_SCENES+sid+"/cover.png" : ATON.PATH_RES+"scenecover.png";
//let urlCover = ATON.PATH_RESTAPI+"cover/"+sid;
let shtml = "";
diff --git a/public/shu/shu.js b/public/shu/shu.js
index 8da62e2f..008c7769 100644
--- a/public/shu/shu.js
+++ b/public/shu/shu.js
@@ -149,7 +149,7 @@ SHU.createPubScenesGallery = (idcontainer, bSamples, onComplete, opts)=>{
let user = SHU.getUserFromSID(sid);
if ( bSamples || user !== "samples" ){
- let urlCover = (scene.cover)? ATON.PATH_SCENES+sid+"/cover.png" : ATON.PATH_RES+"scenecover.png";
+ let urlCover = ATON.PATH_RESTAPI2+"scenes/"+sid+"/cover"; // (scene.cover)? ATON.PATH_SCENES+sid+"/cover.png" : ATON.PATH_RES+"scenecover.png";
let title = (scene.title)? scene.title : sid;
let terms = title.trim().toLowerCase();
diff --git a/services/API/v1.js b/services/API/v1.js
index 3cf4182c..34b1437d 100644
--- a/services/API/v1.js
+++ b/services/API/v1.js
@@ -240,40 +240,8 @@ app.post("/api/cover/scene/", (req,res,next)=>{
img = img.replace(/^data:image\/png;base64,/, "");
- let scenefolder = Core.getSceneFolder(sid);
- let coverfile = path.join(scenefolder, "cover-high.png");
- let coverfileOpt = path.join(scenefolder, "cover.png");
- console.log(coverfile);
-
- fs.writeFile(coverfile, img, 'base64', (err)=>{
- //if (fs.existsSync(coverfileOpt)) fs.unlinkSync(coverfileOpt);
-
- // Optimize PNG size
- sharp(coverfile)
- //.resize({ width: 256, height: 256 })
- .withMetadata()
- .png({
- quality: 90, // 0-100
- //compression: 6, // this doesn't need to be set
- })
- .toFile(coverfileOpt, (err)=>{
- if (err) console.log(err);
- else {
- console.log('done');
- res.send(true);
- }
- });
-
-/*
- imagemin([coverfile], {
- destination: scenefolder,
- plugins: [ imageminPNGquant({ quality: [0.1, 0.1] }) ]
- }).then(()=>{
- console.log("Cover compressed");
- res.send(true);
- });
-*/
- //res.send(true);
+ Core.generateCoverForScene(sid, img, ()=>{
+ res.send(true);
});
});
@@ -287,10 +255,13 @@ app.post("/api/cover/scene/", (req,res,next)=>{
app.get(/^\/api\/cover\/(.*)$/, (req,res,next)=>{
let sid = req.params[0];
- let coverfile = path.join(Core.getSceneFolder(sid), "cover.png");
+ let coverfile = path.join(Core.getSceneFolder(sid), Core.STD_COVERFILE);
+ if (!fs.existsSync(coverfile)) coverfile = path.join(Core.getSceneFolder(sid), Core.STD_COVERFILE_HI);
+
+ console.log(coverfile)
if (!fs.existsSync(coverfile)){
- return res.sendFile(Core.DIR_RES+"scenecover.png");
+ return res.sendFile(Core.STD_COVERFILE_PATH);
}
res.sendFile(coverfile);
diff --git a/services/API/v2.js b/services/API/v2.js
index 43a5e0d8..8f24b669 100644
--- a/services/API/v2.js
+++ b/services/API/v2.js
@@ -223,6 +223,10 @@ API.init = (app)=>{
let sid = U+"/"+S;
let coverfile = path.join(Core.getSceneFolder(sid), Core.STD_COVERFILE);
+
+ // To be removed in the future (old PNGs covers)
+ if (!fs.existsSync(coverfile)) coverfile = path.join(Core.getSceneFolder(sid), Core.STD_COVERFILE_HI);
+
fs.access(coverfile, (err) => {
if (err){
res.sendFile(Core.STD_COVERFILE_PATH);
diff --git a/services/Core.js b/services/Core.js
index 5501e5a6..f83d4645 100644
--- a/services/Core.js
+++ b/services/Core.js
@@ -19,6 +19,7 @@ const fsx = require('fs-extra');
//const chokidar = require('chokidar');
const fg = require('fast-glob');
const chalk = require('chalk');
+const sharp = require("sharp");
const { networkInterfaces } = require('os');
@@ -57,7 +58,9 @@ Core.DIR_EXAMPLES = path.join(Core.DIR_PUBLIC,"examples/");
Core.DIR_FLARES = path.join(Core.DIR_CONFIG,"flares/"); //path.join(Core.DIR_PUBLIC,"custom/flares/");
Core.STD_SCENEFILE = "scene.json";
Core.STD_PUBFILE = "pub.txt"; // deprecated
-Core.STD_COVERFILE = "cover.png";
+Core.STD_COVERFILE_HI = "cover.png";
+Core.STD_COVERFILE = "cover.jpg";
+Core.STD_COVERSIZE = 256;
Core.STD_COVERFILE_PATH = path.join(Core.DIR_RES,"scenecover.png");
// Unused
@@ -924,4 +927,38 @@ Core.setupDataRoute = (app)=>{
});
};
+// IMG
+Core.generateCoverForScene = (sid, b64img, onComplete)=>{
+ if (!sid) return;
+
+ let scenefolder = Core.getSceneFolder(sid);
+ let coverfile = path.join(scenefolder, Core.STD_COVERFILE_HI);
+ let coverfileOpt = path.join(scenefolder, Core.STD_COVERFILE);
+
+ fs.writeFile(coverfile, b64img, 'base64', (err)=>{
+ //if (fs.existsSync(coverfileOpt)) fs.unlinkSync(coverfileOpt);
+
+ // Optimize PNG size
+ sharp(coverfile)
+ .resize({
+ width: Core.STD_COVERSIZE,
+ height: Core.STD_COVERSIZE
+ })
+ .withMetadata()
+/*
+ .png({
+ quality: 90, // 0-100
+ //compression: 6, // this doesn't need to be set
+ })
+*/
+ .jpeg({
+ quality: 60
+ })
+ .toFile(coverfileOpt, (err)=>{
+ if (err) console.log(err);
+ else if (onComplete) onComplete();
+ });
+ });
+};
+
module.exports = Core;
\ No newline at end of file
diff --git a/services/maat/Maat.js b/services/maat/Maat.js
index 0b6934e0..aadfae28 100644
--- a/services/maat/Maat.js
+++ b/services/maat/Maat.js
@@ -94,6 +94,15 @@ Maat.init = ()=>{
});
*/
//Maat._dUpd = setInterval(Maat.update, Maat.INTERVAL);
+
+ // First global scan
+ Maat.getUsers();
+ Maat.scanApps();
+ Maat.scanScenes();
+ for (let i in Maat.db.users){
+ let u = Maat.db.users[i].username;
+ Maat.scanCollection(u);
+ }
};
Maat.sortScenes = (entryA, entryB)=>{
@@ -125,110 +134,113 @@ Maat.addSceneKeyword = (k)=>{
Maat.scanScenes = ()=>{
if (Maat.needScan.scenes === false) return;
-
- Maat.db.scenes = []; // clear
- Maat.db.scenesByID = {};
- Maat.db.kwords = {}; // clear global keywords
- //Maat.db.users = {};
console.log("Scanning scenes...");
const confSHU = Core.config.shu;
- let files = fg.sync("**/"+Core.STD_SCENEFILE, Core.SCENES_GLOB_OPTS);
-
- for (let f in files){
- let S = {};
+ //let files = fg.sync("**/"+Core.STD_SCENEFILE, Core.SCENES_GLOB_OPTS);
+ fg("**/"+Core.STD_SCENEFILE, Core.SCENES_GLOB_OPTS).then( files => {
- let sid = path.dirname(files[f]);
- //let pubfile = Core.DIR_SCENES + sid+"/" + Core.STD_PUBFILE;
- let coverfile = Core.DIR_SCENES + sid+"/" + Core.STD_COVERFILE;
-
- //let user = sid.split("/")[0];
- //if (user) Maat.db.users[user] = 1;
+ Maat.db.scenes = []; // clear
+ Maat.db.scenesByID = {};
+ Maat.db.kwords = {}; // clear global keywords
+ //Maat.db.users = {};
- S.sid = sid;
- S.cover = fs.existsSync(coverfile)? true : false;
- //S.public = fs.existsSync(pubfile)? true : false;
+ for (let f in files){
+ let S = {};
- if (confSHU && confSHU.staffpick && confSHU.staffpick[sid]) S.staffpick = 1;
+ let sid = path.dirname(files[f]);
+ //let pubfile = Core.DIR_SCENES + sid+"/" + Core.STD_PUBFILE;
+ let coverfile = Core.DIR_SCENES + sid+"/" + Core.STD_COVERFILE;
- let sobj = Core.readSceneJSON(sid);
+ //let user = sid.split("/")[0];
+ //if (user) Maat.db.users[user] = 1;
- if (sobj){
- if (sobj.title) S.title = sobj.title;
+ S.sid = sid;
+ S.cover = fs.existsSync(coverfile)? true : false;
+ //S.public = fs.existsSync(pubfile)? true : false;
- if (sobj.kwords){
- S.kwords = sobj.kwords;
- for (let k in S.kwords) Maat.addSceneKeyword(k);
- }
+ if (confSHU && confSHU.staffpick && confSHU.staffpick[sid]) S.staffpick = 1;
+
+ let sobj = Core.readSceneJSON(sid);
- if (sobj.visibility) S.visibility = sobj.visibility;
+ if (sobj){
+ if (sobj.title) S.title = sobj.title;
- if (!sobj.creationDate){
- const sstats = fs.statSync(Core.DIR_SCENES + files[f]);
- S.creationDate = sstats.birthtime;
- }
+ if (sobj.kwords){
+ S.kwords = sobj.kwords;
+ for (let k in S.kwords) Maat.addSceneKeyword(k);
+ }
- Maat.db.scenes.push(S);
+ if (sobj.visibility) S.visibility = sobj.visibility;
- Maat.db.scenesByID[S.sid] = {
- title: S.title,
- visibility: S.visibility,
- kwords: S.kwords,
- cover: S.cover,
- creationDate: S.creationDate
- };
- }
- else {
- console.log("ERROR malformed scene: ", sid);
+ if (!sobj.creationDate){
+ const sstats = fs.statSync(Core.DIR_SCENES + files[f]);
+ S.creationDate = sstats.birthtime;
+ }
+
+ Maat.db.scenes.push(S);
+
+ Maat.db.scenesByID[S.sid] = {
+ title: S.title,
+ visibility: S.visibility,
+ kwords: S.kwords,
+ cover: S.cover,
+ creationDate: S.creationDate
+ };
+ }
+ else {
+ console.log("ERROR malformed scene: ", sid);
+ }
+
+ //Maat.db.scenes.push(S);
}
- //Maat.db.scenes.push(S);
- }
- //console.log(Maat.db.scenesByID);
- //Maat.db.scenes.sort( Maat.sortScenes );
+ //console.log(Maat.db.scenesByID);
- Maat.needScan.scenes = false;
+ //Maat.db.scenes.sort( Maat.sortScenes );
- console.log(Maat.db.kwords);
+ Maat.needScan.scenes = false;
- setTimeout(()=>{
- Maat.needScan.scenes = true;
- }, Maat.INTERVAL);
+ //console.log(Maat.db.kwords);
+
+ setTimeout(()=>{ Maat.needScan.scenes = true; }, Maat.INTERVAL);
+ });
};
Maat.scanApps = ()=>{
if (Maat.needScan.apps === false) return;
- Maat.db.apps = [];
-
let O = {};
O.cwd = Core.DIR_WAPPS;
O.follow = true;
console.log("Scanning web-apps...");
- let files = fg.sync("*/app.webmanifest", O); // index.html
- for (let f in files){
- let wid = path.dirname(files[f]);
- let appicon = path.join(Core.DIR_WAPPS+wid, "/appicon.png");
- let datadir = path.join(Core.DIR_WAPPS+wid, "/data");
-
- Maat.db.apps.push({
- wappid: wid,
- icon: fs.existsSync(appicon)? true : false,
- data: fs.existsSync(datadir)? true : false
- });
- }
+ fg("*/app.webmanifest", O).then(files => {
+ Maat.db.apps = [];
- Maat.needScan.apps = false;
+ for (let f in files){
+ let wid = path.dirname(files[f]);
+ let appicon = path.join(Core.DIR_WAPPS+wid, "/appicon.png");
+ let datadir = path.join(Core.DIR_WAPPS+wid, "/data");
- setTimeout(()=>{
- Maat.needScan.apps = true;
- }, Maat.INTERVAL);
+ Maat.db.apps.push({
+ wappid: wid,
+ icon: fs.existsSync(appicon)? true : false,
+ data: fs.existsSync(datadir)? true : false
+ });
+ }
+
+ Maat.needScan.apps = false;
+
+ setTimeout(()=>{
+ Maat.needScan.apps = true;
+ }, Maat.INTERVAL);
+ });
};
@@ -264,16 +276,17 @@ Maat.scanModels = (uid)=>{
globopts.follow = true;
*/
//let files = fg.sync("**/{*.gltf,*.glb,*.json}", globopts);
- let files = fg.sync("{"+uid+",samples}/models/**/{"+Core.mpattern+"}", Core.COLLECTIONS_GLOB_OPTS);
+ fg("{"+uid+",samples}/models/**/{"+Core.mpattern+"}", Core.COLLECTIONS_GLOB_OPTS).then( files =>{
- CC[uid].models = [];
+ CC[uid].models = [];
- if (files.length < 1) return;
+ if (files.length < 1) return;
- // TODO: improve filtering perf.
- //files = Maat.filterTSets(files);
+ // TODO: improve filtering perf.
+ //files = Maat.filterTSets(files);
- for (let f in files) CC[uid].models.push( /*relpath + */files[f] );
+ for (let f in files) CC[uid].models.push( /*relpath + */files[f] );
+ });
};
Maat.scanPanoramas = (uid)=>{
@@ -288,12 +301,13 @@ Maat.scanPanoramas = (uid)=>{
globopts.follow = true;
*/
//let files = fg.sync("**/{*.jpg,*.mp4,*.webm}", globopts);
- let files = fg.sync("{"+uid+",samples}/pano/**/{"+Core.panopattern+"}", Core.COLLECTIONS_GLOB_OPTS);
+ fg("{"+uid+",samples}/pano/**/{"+Core.panopattern+"}", Core.COLLECTIONS_GLOB_OPTS).then(files => {
- CC[uid].panos = [];
- if (files.length < 1) return;
-
- for (let f in files) CC[uid].panos.push( /*relpath +*/ files[f] );
+ CC[uid].panos = [];
+
+ if (files.length < 1) return;
+ for (let f in files) CC[uid].panos.push( /*relpath +*/ files[f] );
+ });
};
Maat.scanMedia = (uid)=>{
@@ -301,12 +315,13 @@ Maat.scanMedia = (uid)=>{
if (CC[uid] === undefined) CC[uid] = {};
- let files = fg.sync("{"+uid+",samples}/media/**/{"+Core.mediapattern+"}", Core.COLLECTIONS_GLOB_OPTS);
+ fg("{"+uid+",samples}/media/**/{"+Core.mediapattern+"}", Core.COLLECTIONS_GLOB_OPTS).then(files =>{
- CC[uid].media = [];
- if (files.length < 1) return;
+ CC[uid].media = [];
+ if (files.length < 1) return;
- for (let f in files) CC[uid].media.push( files[f] );
+ for (let f in files) CC[uid].media.push( files[f] );
+ });
};
// TODO: improve filter alg