Skip to content

Commit b1412aa

Browse files
committed
better code separation
1 parent af196c0 commit b1412aa

File tree

8 files changed

+307
-203
lines changed

8 files changed

+307
-203
lines changed

api/upload.js

Lines changed: 67 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,221 +1,96 @@
1-
const fs = require('fs');
21
const express = require('express');
32
const multer = require('multer');
4-
const bencode = require('bencode');
5-
const crypto = require('crypto');
63
const db = require('./../db');
7-
const validator = require('./validator');
84

95
const app = express.Router();
106

11-
/**
12-
* Saves torrent file to disk
13-
*
14-
* Saves torrent to the path defined in the .env file.
15-
* Also adds a path property to the torrent Object
16-
*
17-
* @param torrent - torrent object
18-
* @return {Promise<Object>} torrent object with path attached
19-
*/
20-
const saveToDisk = async (torrent) => {
21-
const now = new Date();
22-
const month = now.getMonth() + 1;
23-
const year = now.getFullYear();
24-
const path = `${process.env.TORRENT_DIR}${year}/${month}/${
25-
torrent.hash
26-
}.torrent`;
27-
28-
await fs.promises.writeFile(path, Buffer.from(torrent.buffer));
29-
torrent.path = path;
30-
return torrent;
31-
};
32-
337
const storage = multer.memoryStorage();
34-
358
const upload = multer({ storage });
369

37-
const hashTorrent = (torrentBuffer) => {
38-
const hash = crypto.createHash('sha256');
39-
const code = `${process.env.SECRET}${torrentBuffer.toString(
40-
'utf8'
41-
)}${Math.floor(new Date().getTime() / 1000).toString()}`;
42-
hash.update(code);
43-
return hash.digest('hex');
44-
};
45-
46-
/**
47-
* Processes a torrent
48-
*
49-
* Removes trackers from torrent
50-
* Adds fileList and hash fields to the torrent
51-
*
52-
* @param torrent - torrent object
53-
* @return {Object} torrent object with buffer and hash attached
54-
*/
55-
const processTorrent = (torrent) => {
56-
const decodedTorrent = bencode.decode(torrent.buffer);
57-
delete decodedTorrent.announce;
58-
59-
torrent.fileList = [];
60-
torrent.totalFileSize = decodedTorrent.info.files.reduce((total, file) => {
61-
torrent.fileList.push({ fileName: file.path, fileSize: file.length });
62-
total += file.length;
63-
return total;
64-
}, 0);
65-
66-
torrent.buffer = bencode.encode(decodedTorrent);
67-
torrent.hash = hashTorrent(torrent.buffer);
68-
69-
return torrent;
70-
};
71-
7210
const torrentUpload = upload.fields([{ name: 'torrent', maxCount: 1 }]);
73-
7411
app.post('/upload', torrentUpload, async (req, res) => {
7512
const release = JSON.parse(req.body.release);
76-
const client = await db.pool.connect();
77-
78-
if (release.torrentType === 'music') {
79-
const musicReleaseTypes = (await db.getMusicReleaseTypes()).rows;
80-
const musicQualities = (await db.getMusicQualities()).rows;
81-
try {
82-
await validator.validateMusic({
83-
release,
84-
musicReleaseTypes,
85-
musicQualities
13+
const torrentFile = req.files.torrent[0];
14+
15+
try {
16+
if (release.torrentType === 'music') {
17+
const {
18+
torrentId,
19+
musicId,
20+
musicReleaseId
21+
} = await db.createMusicRelease(release, torrentFile);
22+
return res.json({
23+
torrentId,
24+
musicId,
25+
musicReleaseId
8626
});
87-
88-
// valid if doesn't throw
89-
await Promise.all(release.artists.map(validator.validateArtist));
90-
91-
await db.beginTransaction(client);
92-
93-
let musicId = release.music;
94-
// insert music if necessary
95-
if (release.music instanceof Object) {
96-
// music comes with at least 1 associated artist
97-
// insert the artist(s) if they are not ids
98-
const artistsToInsert = release.artists.filter((artist) =>
99-
Object.prototype.hasOwnProperty.call(artist, 'name')
100-
);
101-
const artistIds = release.artists.filter((artist) =>
102-
Object.prototype.hasOwnProperty.call(artist, 'id')
103-
);
104-
const insertedArtists = await db.insertArtists(artistsToInsert, client);
105-
const artistsToLink = [...artistIds, ...insertedArtists];
106-
107-
// insert music and assign it to musicId to be used to create the music_release
108-
const insertMusicRes = await db.insertMusic(
109-
{
110-
music: release.music,
111-
artistsToLink
112-
},
113-
client
114-
);
115-
musicId = insertMusicRes.rows[0].id;
116-
}
117-
118-
const processedTorrent = processTorrent(req.files.torrent[0]);
119-
120-
// insert torrent
121-
const torrentRes = await db.insertTorrent(
122-
{
123-
fileSize: processedTorrent.totalFileSize,
124-
originalFileName: processedTorrent.originalname,
125-
filePath: '/',
126-
files: processedTorrent.fileList,
127-
uploaderId: '01D91F1JSSW4X5DNKSVPD2J3EM'
128-
},
129-
client
130-
);
131-
132-
const torrentId = torrentRes.rows[0].id;
133-
134-
// insert music release
135-
await db.insertMusicRelease(
136-
{ musicId, releaseInfo: release.info, torrentId },
137-
client
27+
}
28+
if (release.torrentType === 'movie') {
29+
const {
30+
torrentId,
31+
movieId,
32+
videoReleaseId
33+
} = await db.createMovieRelease(release, torrentFile);
34+
35+
return res.json({
36+
torrentId,
37+
movieId,
38+
videoReleaseId
39+
});
40+
}
41+
if (release.torrentType === 'tv') {
42+
const { torrentId, tvId, videoReleaseId } = await db.createTVRelease(
43+
release,
44+
torrentFile
13845
);
13946

140-
await db.commitTransaction(client);
141-
} catch (e) {
142-
await db.rollbackTransaction(client);
143-
console.log(e);
144-
return res.status(400).json({
145-
error: e
47+
return res.json({
48+
torrentId,
49+
tvId,
50+
videoReleaseId
14651
});
147-
} finally {
148-
client.release();
14952
}
150-
} else if (release.torrentType === 'movie') {
151-
try {
152-
await validator.validateMovie({
153-
release
53+
if (release.torrentType === 'anime') {
54+
const {
55+
torrentId,
56+
animeId,
57+
videoReleaseId
58+
} = await db.createAnimeRelease(release, torrentFile);
59+
60+
return res.json({
61+
torrentId,
62+
animeId,
63+
videoReleaseId
15464
});
155-
156-
await db.beginTransaction(client);
157-
158-
let movieId = release.movie;
159-
if (release.movie instanceof Object) {
160-
const movieRes = await db.insertMovie(
161-
{
162-
name: release.movie.name,
163-
description: release.movie.description,
164-
year: release.movie.year
165-
},
166-
client
167-
);
168-
169-
movieId = movieRes.rows[0].id;
170-
}
171-
172-
const processedTorrent = processTorrent(req.files.torrent[0]);
173-
174-
// insert torrent
175-
const torrentRes = await db.insertTorrent(
176-
{
177-
fileSize: processedTorrent.totalFileSize,
178-
originalFileName: processedTorrent.originalname,
179-
filePath: '/',
180-
files: processedTorrent.fileList,
181-
uploaderId: '01D91F1JSSW4X5DNKSVPD2J3EM'
182-
},
183-
client
65+
}
66+
if (release.torrentType === 'software') {
67+
const { torrentId, softwareId } = await db.createSoftwareRelease(
68+
release,
69+
torrentFile
18470
);
18571

186-
const torrentId = torrentRes.rows[0].id;
187-
188-
await db.insertVideoRelease(
189-
{
190-
videoId: movieId,
191-
quality: release.info.quality,
192-
title: release.info.title,
193-
description: release.info.description,
194-
torrentId
195-
},
196-
client
72+
return res.json({
73+
torrentId,
74+
softwareId
75+
});
76+
}
77+
if (release.torrentType === 'video-game') {
78+
const { torrentId, videoGameId } = await db.createVideoGameRelease(
79+
release,
80+
torrentFile
19781
);
19882

199-
await db.commitTransaction(client);
200-
} catch (e) {
201-
await db.rollbackTransaction(client);
202-
console.log(e);
203-
return res.status(400).json({
204-
error: e
83+
return res.json({
84+
torrentId,
85+
videoGameId
20586
});
206-
} finally {
207-
client.release();
20887
}
209-
} else if (release.torrentType === 'tv') {
210-
} else if (release.torrentType === 'anime') {
211-
} else if (
212-
release.torrentType === 'software' ||
213-
release.torrentType === 'video-game'
214-
) {
215-
} else {
21688
return res.sendStatus(400);
89+
} catch (e) {
90+
return res.status(500).json({
91+
error: e
92+
});
21793
}
218-
res.sendStatus(200);
21994
});
22095

22196
module.exports = app;

db/createMovieRelease.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const db = require('./index');
2+
const { processTorrent, validator } = require('./../util');
3+
4+
const createMovieRelease = async (release, torrentFile) => {
5+
await validator.validateMovie({
6+
release
7+
});
8+
9+
const client = await db.pool.connect();
10+
11+
await db.beginTransaction(client);
12+
13+
let movieId = release.movie;
14+
if (release.movie instanceof Object) {
15+
const movieRes = await db.insertMovie(
16+
{
17+
name: release.movie.name,
18+
description: release.movie.description,
19+
year: release.movie.year
20+
},
21+
client
22+
);
23+
24+
movieId = movieRes.rows[0].id;
25+
}
26+
27+
const processedTorrent = processTorrent(torrentFile);
28+
29+
// insert torrent
30+
const torrentRes = await db.insertTorrent(
31+
{
32+
fileSize: processedTorrent.totalFileSize,
33+
originalFileName: processedTorrent.originalname,
34+
filePath: '/',
35+
files: processedTorrent.fileList,
36+
uploaderId: '01D91F1JSSW4X5DNKSVPD2J3EM'
37+
},
38+
client
39+
);
40+
41+
const torrentId = torrentRes.rows[0].id;
42+
43+
const videoReleaseRes = await db.insertVideoRelease(
44+
{
45+
videoId: movieId,
46+
quality: release.info.quality,
47+
title: release.info.title,
48+
description: release.info.description,
49+
torrentId
50+
},
51+
client
52+
);
53+
54+
await db.commitTransaction(client);
55+
56+
return {
57+
torrentId,
58+
movieId,
59+
videoReleaseId: videoReleaseRes.rows[0].id
60+
};
61+
};
62+
63+
module.exports = createMovieRelease;

0 commit comments

Comments
 (0)