aboutsummaryrefslogtreecommitdiff
path: root/src/api/utils
diff options
context:
space:
mode:
authorZephyrrus <[email protected]>2020-07-02 03:11:51 +0300
committerZephyrrus <[email protected]>2020-07-02 03:12:12 +0300
commit42f1a1003a299ca4e571d503d7200b76ff41e752 (patch)
treeaf4b2010772f17a058a3515d0203c9eb5e595ef3 /src/api/utils
parentfeat: start refactoring the code to actually use vuex (diff)
downloadhost.fuwn.me-42f1a1003a299ca4e571d503d7200b76ff41e752.tar.xz
host.fuwn.me-42f1a1003a299ca4e571d503d7200b76ff41e752.zip
feat: externalize thumb generation function for easier testing
Diffstat (limited to 'src/api/utils')
-rw-r--r--src/api/utils/ThumbUtil.js60
-rw-r--r--src/api/utils/Util.js118
2 files changed, 111 insertions, 67 deletions
diff --git a/src/api/utils/ThumbUtil.js b/src/api/utils/ThumbUtil.js
new file mode 100644
index 0000000..5c96b5c
--- /dev/null
+++ b/src/api/utils/ThumbUtil.js
@@ -0,0 +1,60 @@
+const jetpack = require('fs-jetpack');
+const path = require('path');
+const sharp = require('sharp');
+const ffmpeg = require('fluent-ffmpeg');
+
+const imageExtensions = ['.jpg', '.jpeg', '.gif', '.png', '.webp'];
+const videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
+
+class ThumbUtil {
+ static generateThumbnails(filename) {
+ const ext = path.extname(filename).toLowerCase();
+ const output = `${filename.slice(0, -ext.length)}.png`;
+ if (imageExtensions.includes(ext)) return this.generateThumbnailForImage(filename, output);
+ if (videoExtensions.includes(ext)) return this.generateThumbnailForVideo(filename);
+ return null;
+ }
+
+ static async generateThumbnailForImage(filename, output) {
+ const file = await jetpack.readAsync(
+ path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename),
+ 'buffer'
+ );
+ await sharp(file)
+ .resize(64, 64)
+ .toFormat('png')
+ .toFile(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square', output));
+ await sharp(file)
+ .resize(225, null)
+ .toFormat('png')
+ .toFile(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', output));
+ }
+
+ static generateThumbnailForVideo(filename) {
+ ffmpeg(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename))
+ .thumbnail({
+ timestamps: [0],
+ filename: '%b.png',
+ folder: path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square'),
+ size: '64x64'
+ })
+ .on('error', error => log.error(error.message));
+ ffmpeg(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename))
+ .thumbnail({
+ timestamps: [0],
+ filename: '%b.png',
+ folder: path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs'),
+ size: '150x?'
+ })
+ .on('error', error => log.error(error.message));
+ }
+
+ static getFileThumbnail(filename) {
+ if (!filename) return null;
+ const ext = path.extname(filename).toLowerCase();
+ if (!imageExtensions.includes(ext) && !videoExtensions.includes(ext)) return null;
+ return `${filename.slice(0, -ext.length)}.png`;
+ }
+}
+
+module.exports = ThumbUtil;
diff --git a/src/api/utils/Util.js b/src/api/utils/Util.js
index 07c295d..8c9428d 100644
--- a/src/api/utils/Util.js
+++ b/src/api/utils/Util.js
@@ -14,15 +14,13 @@ const db = require('knex')({
useNullAsDefault: process.env.DB_CLIENT === 'sqlite' ? true : false
});
const moment = require('moment');
-const log = require('../utils/Log');
const crypto = require('crypto');
-const sharp = require('sharp');
-const ffmpeg = require('fluent-ffmpeg');
const Zip = require('adm-zip');
const uuidv4 = require('uuid/v4');
-const imageExtensions = ['.jpg', '.jpeg', '.gif', '.png', '.webp'];
-const videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov'];
+const log = require('./Log');
+const ThumbUtil = require('./ThumbUtil');
+
const blockedExtensions = process.env.BLOCKED_EXTENSIONS.split(',');
class Util {
@@ -34,59 +32,13 @@ class Util {
return blockedExtensions.includes(extension);
}
- static generateThumbnails(filename) {
- const ext = path.extname(filename).toLowerCase();
- const output = `${filename.slice(0, -ext.length)}.png`;
- if (imageExtensions.includes(ext)) return this.generateThumbnailForImage(filename, output);
- if (videoExtensions.includes(ext)) return this.generateThumbnailForVideo(filename);
- return null;
- }
-
- static async generateThumbnailForImage(filename, output) {
- const file = await jetpack.readAsync(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename), 'buffer');
- await sharp(file)
- .resize(64, 64)
- .toFormat('png')
- .toFile(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square', output));
- await sharp(file)
- .resize(225, null)
- .toFormat('png')
- .toFile(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', output));
- }
-
- static generateThumbnailForVideo(filename) {
- ffmpeg(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename))
- .thumbnail({
- timestamps: [0],
- filename: '%b.png',
- folder: path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square'),
- size: '64x64'
- })
- .on('error', error => log.error(error.message));
- ffmpeg(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename))
- .thumbnail({
- timestamps: [0],
- filename: '%b.png',
- folder: path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs'),
- size: '150x?'
- })
- .on('error', error => log.error(error.message));
- }
-
- static getFileThumbnail(filename) {
- if (!filename) return null;
- const ext = path.extname(filename).toLowerCase();
- if (!imageExtensions.includes(ext) && !videoExtensions.includes(ext)) return null;
- return `${filename.slice(0, -ext.length)}.png`;
- }
-
static constructFilePublicLink(file) {
/*
TODO: This wont work without a reverse proxy serving both
the site and the API under the same domain. Pls fix.
*/
file.url = `${process.env.DOMAIN}/${file.name}`;
- const thumb = this.getFileThumbnail(file.name);
+ const thumb = ThumbUtil.getFileThumbnail(file.name);
if (thumb) {
file.thumb = `${process.env.DOMAIN}/thumbs/${thumb}`;
file.thumbSquare = `${process.env.DOMAIN}/thumbs/square/${thumb}`;
@@ -96,10 +48,11 @@ class Util {
static getUniqueFilename(name) {
const retry = (i = 0) => {
- const filename = randomstring.generate({
- length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
- capitalization: 'lowercase'
- }) + path.extname(name).toLowerCase();
+ const filename =
+ randomstring.generate({
+ length: parseInt(process.env.GENERATED_FILENAME_LENGTH, 10),
+ capitalization: 'lowercase'
+ }) + path.extname(name).toLowerCase();
// TODO: Change this to look for the file in the db instead of in the filesystem
const exists = jetpack.exists(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename));
@@ -117,7 +70,10 @@ class Util {
length: parseInt(process.env.GENERATED_ALBUM_LENGTH, 10),
capitalization: 'lowercase'
});
- const exists = await db.table('links').where({ identifier }).first();
+ const exists = await db
+ .table('links')
+ .where({ identifier })
+ .first();
if (!exists) return identifier;
/*
It's funny but if you do i++ the asignment never gets done resulting in an infinite loop
@@ -130,7 +86,10 @@ class Util {
}
static async getFileHash(filename) {
- const file = await jetpack.readAsync(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename), 'buffer');
+ const file = await jetpack.readAsync(
+ path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename),
+ 'buffer'
+ );
if (!file) {
log.error(`There was an error reading the file < ${filename} > for hashing`);
return null;
@@ -142,7 +101,10 @@ class Util {
}
static generateFileHash(data) {
- const hash = crypto.createHash('md5').update(data).digest('hex');
+ const hash = crypto
+ .createHash('md5')
+ .update(data)
+ .digest('hex');
return hash;
}
@@ -151,13 +113,20 @@ class Util {
}
static async deleteFile(filename, deleteFromDB = false) {
- const thumbName = this.getFileThumbnail(filename);
+ const thumbName = ThumbUtil.getFileThumbnail(filename);
try {
await jetpack.removeAsync(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, filename));
- await jetpack.removeAsync(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', thumbName));
- await jetpack.removeAsync(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square', thumbName));
+ await jetpack.removeAsync(
+ path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', thumbName)
+ );
+ await jetpack.removeAsync(
+ path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'thumbs', 'square', thumbName)
+ );
if (deleteFromDB) {
- await db.table('files').where('name', filename).delete();
+ await db
+ .table('files')
+ .where('name', filename)
+ .delete();
}
} catch (error) {
log.error(`There was an error removing the file < ${filename} >`);
@@ -169,7 +138,8 @@ class Util {
try {
const fileAlbums = await db.table('albumsFiles').where({ albumId: id });
for (const fileAlbum of fileAlbums) {
- const file = await db.table('files')
+ const file = await db
+ .table('files')
.where({ id: fileAlbum.fileId })
.first();
if (!file) continue;
@@ -195,7 +165,8 @@ class Util {
try {
const fileTags = await db.table('fileTags').where({ tagId: id });
for (const fileTag of fileTags) {
- const file = await db.table('files')
+ const file = await db
+ .table('files')
.where({ id: fileTag.fileId })
.first();
if (!file) continue;
@@ -219,7 +190,10 @@ class Util {
const id = decoded ? decoded.sub : '';
const iat = decoded ? decoded.iat : '';
- const user = await db.table('users').where({ id }).first();
+ const user = await db
+ .table('users')
+ .where({ id })
+ .first();
if (!user || !user.enabled) return false;
if (iat && iat < moment(user.passwordEditedAt).format('x')) return false;
@@ -233,7 +207,17 @@ class Util {
for (const file of files) {
zip.addLocalFile(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, file));
}
- zip.writeZip(path.join(__dirname, '..', '..', '..', process.env.UPLOAD_FOLDER, 'zips', `${album.userId}-${album.id}.zip`));
+ zip.writeZip(
+ path.join(
+ __dirname,
+ '..',
+ '..',
+ '..',
+ process.env.UPLOAD_FOLDER,
+ 'zips',
+ `${album.userId}-${album.id}.zip`
+ )
+ );
} catch (error) {
log.error(error);
}