diff options
| author | Pitu <[email protected]> | 2018-09-18 03:34:00 -0300 |
|---|---|---|
| committer | Pitu <[email protected]> | 2018-09-18 03:34:00 -0300 |
| commit | 4b2b02110b457d8ebeee78e1bdf99eb0660d0626 (patch) | |
| tree | a6e30208b61e3927c1681c7006241cd0d837de89 /src/api | |
| parent | Stupid hash was working, the size changes for some reason when uploading (diff) | |
| download | host.fuwn.me-4b2b02110b457d8ebeee78e1bdf99eb0660d0626.tar.xz host.fuwn.me-4b2b02110b457d8ebeee78e1bdf99eb0660d0626.zip | |
We can now download albums yayyyy
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/routes/albums/albumZipGET.js | 78 | ||||
| -rw-r--r-- | src/api/routes/albums/link/linkPOST.js | 3 | ||||
| -rw-r--r-- | src/api/structures/Database.js | 2 | ||||
| -rw-r--r-- | src/api/structures/Server.js | 4 | ||||
| -rw-r--r-- | src/api/utils/Util.js | 13 |
5 files changed, 99 insertions, 1 deletions
diff --git a/src/api/routes/albums/albumZipGET.js b/src/api/routes/albums/albumZipGET.js new file mode 100644 index 0000000..7a853cd --- /dev/null +++ b/src/api/routes/albums/albumZipGET.js @@ -0,0 +1,78 @@ +const Route = require('../../structures/Route'); +const config = require('../../../../config'); +const db = require('knex')(config.server.database); +const Util = require('../../utils/Util'); +const log = require('../../utils/Log'); +const path = require('path'); +const jetpack = require('fs-jetpack'); + +class albumGET extends Route { + constructor() { + super('/album/:identifier/zip', 'get', { bypassAuth: true }); + } + + async run(req, res) { + const { identifier } = req.params; + if (!identifier) return res.status(400).json({ message: 'Invalid identifier supplied' }); + + /* + Make sure it exists and it's enabled + */ + const link = await db.table('links').where({ identifier, enabled: true }).first(); + if (!link) return res.status(400).json({ message: 'The identifier supplied could not be found' }); + + /* + Same with the album, just to make sure is not a deleted album and a leftover link + */ + const album = await db.table('albums').where('id', link.albumId).first(); + if (!album) return res.status(400).json({ message: 'Album not found' }); + + /* + If the date when the album was zipped is greater than the album's last edit, we just send the zip to the user + */ + if (album.zippedAt > album.editedAt) { + const filePath = path.join(__dirname, '..', '..', '..', '..', config.uploads.uploadFolder, 'zips', `${album.userId}-${album.id}.zip`); + const exists = await jetpack.existsAsync(filePath); + /* + Make sure the file exists just in case, and if not, continue to it's generation. + */ + if (exists) { + const fileName = `lolisafe-${identifier}.zip`; + return res.download(filePath, fileName); + } + } + + /* + Grab the files in a very unoptimized way. (This should be a join between both tables) + */ + const fileList = await db.table('albumsFiles').where('albumId', link.albumId).select('fileId'); + + /* + If there are no files, stop here + */ + if (!fileList) return res.status(400).json({ message: 'Can\'t download an empty album' }); + + /* + Get the actual files + */ + const fileIds = fileList.map(el => el.fileId); + const files = await db.table('files') + .whereIn('id', fileIds) + .select('name'); + const filesToZip = files.map(el => el.name); + + try { + Util.createZip(filesToZip, album); + await db.table('albums').where('id', link.albumId).update('zippedAt', db.fn.now()); + + const filePath = path.join(__dirname, '..', '..', '..', '..', config.uploads.uploadFolder, 'zips', `${album.userId}-${album.id}.zip`); + const fileName = `lolisafe-${identifier}.zip`; + return res.download(filePath, fileName); + } catch (error) { + log.error(error); + return res.status(500).json({ message: 'There was a problem downloading the album' }); + } + } +} + +module.exports = albumGET; diff --git a/src/api/routes/albums/link/linkPOST.js b/src/api/routes/albums/link/linkPOST.js index 4b24eae..1edf891 100644 --- a/src/api/routes/albums/link/linkPOST.js +++ b/src/api/routes/albums/link/linkPOST.js @@ -9,7 +9,7 @@ class linkPOST extends Route { super('/album/link/new', 'post'); } - async run(req, res) { + async run(req, res, user) { if (!req.body) return res.status(400).json({ message: 'No body provided' }); const { albumId } = req.body; if (!albumId) return res.status(400).json({ message: 'No album provided' }); @@ -35,6 +35,7 @@ class linkPOST extends Route { try { await db.table('links').insert({ identifier, + userId: user.id, albumId, enabled: true, enableDownload: true, diff --git a/src/api/structures/Database.js b/src/api/structures/Database.js index dc26afe..76ea006 100644 --- a/src/api/structures/Database.js +++ b/src/api/structures/Database.js @@ -34,6 +34,7 @@ class Database { // table.string('identifier'); // table.boolean('enabled'); // table.boolean('enableDownload').defaultTo(true); + table.timestamp('zippedAt'); table.timestamp('createdAt'); table.timestamp('editedAt'); }); @@ -57,6 +58,7 @@ class Database { if (!await db.schema.hasTable('links')) { await db.schema.createTable('links', table => { table.increments(); + table.integer('userId'); table.integer('albumId'); table.string('identifier'); table.integer('views').defaultTo(0); diff --git a/src/api/structures/Server.js b/src/api/structures/Server.js index ae4b678..0b05570 100644 --- a/src/api/structures/Server.js +++ b/src/api/structures/Server.js @@ -24,6 +24,10 @@ class Server { this.server.use(helmet()); this.server.use(cors({ allowedHeaders: ['Accept', 'Authorization', 'Cache-Control', 'X-Requested-With', 'Content-Type', 'albumId'] })); this.server.use((req, res, next) => { + /* + This bypasses the headers.accept for album download, since it's accesed directly through the browser. + */ + if (req.url.includes('/api/album/') && req.url.includes('/zip') && req.method === 'GET') return next(); if (req.headers.accept === 'application/vnd.lolisafe.json') return next(); return res.status(405).json({ message: 'Incorrect `Accept` header provided' }); }); diff --git a/src/api/utils/Util.js b/src/api/utils/Util.js index 617b38f..52cfb03 100644 --- a/src/api/utils/Util.js +++ b/src/api/utils/Util.js @@ -9,6 +9,7 @@ const log = require('../utils/Log'); const crypto = require('crypto'); const sharp = require('sharp'); const ffmpeg = require('fluent-ffmpeg'); +const Zip = require('adm-zip'); const imageExtensions = ['.jpg', '.jpeg', '.bmp', '.gif', '.png', '.webp']; const videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov']; @@ -183,6 +184,18 @@ class Util { return user; }); } + + static createZip(files, album) { + try { + const zip = new Zip(); + for (const file of files) { + zip.addLocalFile(path.join(__dirname, '..', '..', '..', config.uploads.uploadFolder, file)); + } + zip.writeZip(path.join(__dirname, '..', '..', '..', config.uploads.uploadFolder, 'zips', `${album.userId}-${album.id}.zip`)); + } catch (error) { + log.error(error); + } + } } module.exports = Util; |