Skip to content

Commit

Permalink
move filesutil to shared
Browse files Browse the repository at this point in the history
  • Loading branch information
steam0r committed Mar 22, 2024
1 parent 1b2dd64 commit 1be70f2
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 0 deletions.
2 changes: 2 additions & 0 deletions shared/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SharedTeamsUtil from "./utils/shared_teams_util.js";
import SharedSubPatchOpUtil from "./utils/shared_subpatchop_util.js";
import SharedLogger from "./utils/shared_logger.js";
import SharedProjectsUtil from "./utils/shared_projects_util.js";
import SharedFilesUtil from "./utils/shared_files_util.js";

export {
utilProvider,
Expand All @@ -19,5 +20,6 @@ export {
SharedProjectsUtil,
SharedTeamsUtil,
SharedSubPatchOpUtil,
SharedFilesUtil,
SharedLogger
};
39 changes: 39 additions & 0 deletions shared/api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions shared/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"type": "module",
"license": "MIT",
"dependencies": {
"image-size": "1.0.2",
"mkdirp": "2.1.3",
"marked": "1.2.9",
"moment": "2.29.4",
Expand Down
177 changes: 177 additions & 0 deletions shared/api/utils/shared_files_util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import fs from "fs";
import path from "path";
import moment from "moment";
import sizeOfImage from "image-size";
import { UtilProvider } from "./util_provider.js";
import SharedUtil from "./shared_util.js";

/**
* @abstract
*/
export default class SharedFilesUtil extends SharedUtil
{
constructor(utilProvider)
{
super(utilProvider);
this.FILETYPES =
{
"image": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".avif", ".jxl"],
"binary": [".bin"],
"audio": [".mp3", ".wav", ".ogg", ".aac", ".mid"],
"video": [".m4a", ".mp4", ".mpg", ".webm"],
"gltf": [".glb"],
"3d raw": [".obj", ".fbx", ".3ds", ".ply", ".dae", ".blend", ".md2", ".md3", ".ase"],
"JSON": [".json"],
"CSS": [".css"],
"textfile": [".txt"],
"pointcloud": [".pc.txt"],
"shader": [".frag", ".vert"],
"SVG": [".svg"],
"CSV": [".csv"],
"XML": [".xml"],
"font": [".otf", ".ttf", ".woff", ".woff2"],
"mesh sequence": [".seq.zip"],
"pointcloud json": [".pc.txt"],
"3d json": [".3d.json"],
"javascript": [".js"],
"ar markers": [".iset", ".fset", ".fset3"]
};
}

get utilName()
{
return UtilProvider.FILES_UTIL;
}

getFileAssetLocation(file)
{
let assetPath = file.projectId;
let fileName = this.getAssetFileName(file);
if (file.isLibraryFile)
{
assetPath = "library";
}
return path.join(this._cables.getAssetPath(), assetPath, fileName);
}

getFileInfo(fileDb)
{
let info = {};
const fn = this.getFileAssetLocation(fileDb);

if (fs.existsSync(fn))
{
const stats = fs.statSync(fn);
const fileSizeInBytes = stats.size;
const fileSizeInKb = fileSizeInBytes / 1024;
info.sizeKb = Math.ceil(fileSizeInKb);

info.sizeReadable = info.sizeKb + " kb";
if (info.sizeKb > 1024)info.sizeReadable = Math.round(fileSizeInKb / 1024 * 100) / 100 + " mb";

info.size = fileSizeInBytes;
info.type = this.getFileType(fn);
}

info.fileDb = fileDb;
info.fileDb.fileName = this.getAssetFileName(fileDb);
info.cachebuster = fileDb.cachebuster;
info.date = fileDb.updated;
info.readableDateSince = new moment(fileDb.updated).fromNow();
info.readableDate = new moment(fileDb.updated).format("lll");
info.converters = [];

info.converters = this.getConvertersForFile(this.getAssetFileName(fileDb) + "");

if (fileDb.suffix && (fileDb.suffix.endsWith(".png") || fileDb.suffix.endsWith(".jpg") || fileDb.suffix.endsWith(".jpeg") || fileDb.suffix.endsWith(".svg") || fileDb.suffix.endsWith(".webp") || fileDb.suffix.endsWith(".avif")))
{
info.imgPreview = this.getFileAssetUrlPath(fileDb);
info.imgPreview += "?rnd" + info.cachebuster;

const dimensions = this.imageSize(fn);
info.imgSizeWidth = dimensions.width;
info.imgSizeHeight = dimensions.height;
if (this.isPowerOfTwo(parseInt(dimensions.width)) && this.isPowerOfTwo(parseInt(dimensions.height))) info.imgSizePower = "is power of two";
else info.imgSizePower = "is NOT power of two";
}

info.icon = this.getFileIconName(fileDb);

return info;
}

getFileType(filename)
{
let type = "unknown";
for (const k in this.FILETYPES)
for (let j = 0; j < this.FILETYPES[k].length; j++)
if (filename.toLowerCase().endsWith(this.FILETYPES[k][j])) type = k;
return type;
}

getAssetFileName(fileDb)
{
if (!fileDb) return "";
return fileDb.fileName || fileDb.name;
}

getConvertersForFile(fileName)
{
const converters = [];
for (const i in this.converters)
for (const si in this.converters[i].suffix)
if ((fileName + "").toLocaleLowerCase().endsWith(this.converters[i].suffix[si]))
converters.push(this.converters[i]);
return converters;
}

getFileAssetUrlPath(file)
{
if (!file) return "";
let assetDir = file.projectId;
if (file.isLibraryFile) assetDir = "library";
return path.join("/assets/", assetDir, this.getAssetFileName(file));
}

imageSize(fn)
{
const dimensions = {
"width": 0,
"height": 0
};
try
{
const size = sizeOfImage(fn);
dimensions.height = size.height;
dimensions.width = size.width;
}
catch (e)
{
this._log.warn("failed to get image dimensions on ", fn, e.message);
}
return dimensions;
}

isPowerOfTwo(x)
{
return (x == 1 || x == 2 || x == 4 || x == 8 || x == 16 || x == 32 || x == 64 || x == 128 || x == 256 || x == 512 || x == 1024 || x == 2048 || x == 4096 || x == 8192 || x == 16384);
}

getFileIconName(fileDb)
{
let icon = "file";

if (fileDb.type === "image" || fileDb.type === "SVG") icon = "file-image";
else if (fileDb.type === "gltf" || fileDb.type === "3d json") icon = "file-box";
else if (fileDb.type === "video") icon = "file-video-2";
else if (fileDb.type === "font") icon = "file-type";
else if (fileDb.type === "JSON" || fileDb.type === "XML") icon = "file-code";
else if (fileDb.type === "javascript") icon = "file-json";
else if (fileDb.type === "shader") icon = "file-text";
else if (fileDb.type === "textfile") icon = "file-text";
else if (fileDb.type === "CSV") icon = "file-spreadsheet";
else if (fileDb.type === "audio") icon = "file-audio-2";

return icon;
}
}
11 changes: 11 additions & 0 deletions shared/api/utils/shared_ops_util.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import uuidv4 from "uuid-v4";
import mkdirp from "mkdirp";
import sanitizeFileName from "sanitize-filename";
import eslintAirbnbBase from "eslint-config-airbnb-base";
import eslintImportPlugin from "eslint-plugin-import";
import SharedUtil from "./shared_util.js";
import { UtilProvider } from "./util_provider.js";

Expand Down Expand Up @@ -1551,8 +1552,18 @@ export default class SharedOpsUtil extends SharedUtil

_getCLIConfig()
{
const importPlugin = eslintImportPlugin;
const plugins = [];
if (importPlugin)
{
importPlugin.configs.recommended.plugins.forEach((plugin) =>
{
plugins.push("eslint-plugin-" + plugin);
});
}
return {
"fix": true,
"plugins": plugins,
"baseConfig": {
"extends": eslintAirbnbBase.extends,
},
Expand Down
1 change: 1 addition & 0 deletions shared/api/utils/util_provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ UtilProvider.OPS_UTIL = "opsUtil";
UtilProvider.SUBPATCH_OP_UTIL = "subPatchOpUtil";
UtilProvider.TEAMS_UTIL = "teamsUtil";
UtilProvider.PROJECTS_UTIL = "projectsUtil";
UtilProvider.FILES_UTIL = "filesUtil";

export { UtilProvider };
export default new UtilProvider();

0 comments on commit 1be70f2

Please sign in to comment.