Skip to content

Commit 59df854

Browse files
committed
Finished basic upload handling code
1 parent 8cdb8e5 commit 59df854

File tree

1 file changed

+79
-53
lines changed

1 file changed

+79
-53
lines changed

api/upload.js

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,28 @@ const bencode = require('bencode');
44
const crypto = require('crypto');
55
const db = require('./../db.js');
66
const fs = require('fs');
7+
const _ = require('lodash');
78

89
const app = express.Router();
910

1011
const util = require('util');
1112

12-
/*const storage = multer.diskStorage({
13-
destination: (req, file, cb) => {
14-
const now = new Date();
15-
const month = now.getMonth() + 1;
16-
const year = now.getFullYear();
17-
console.log(util.inspect(file));
18-
19-
cb(null, `${process.env.TORRENT_DIR}${year}/${month}/`);
13+
const verificationTypes = {
14+
group: {
15+
album: {
16+
required: ['artist', 'album', 'original_release_year'],
17+
allowed: ['artist', 'album', 'original_release_year'],
18+
errorMessage: 'Album group is missing information.'
19+
}
2020
},
21-
filename: (req, file, cb) => {
22-
cb(null, `${file.hash}.torrent`);
21+
release: {
22+
album: {
23+
required: ['release_type', 'format', 'bitrate', 'media'],
24+
allowed: ['release_type', 'format', 'bitrate', 'media'],
25+
errorMessage: 'Album is missing information.'
26+
}
2327
}
24-
});*/
28+
};
2529

2630
const saveToDisk = torrent => {
2731
const now = new Date();
@@ -44,10 +48,22 @@ const storage = multer.memoryStorage();
4448

4549
const upload = multer({ storage });
4650

47-
const stripTrackers = torrentBuffer => {
48-
const torrent = bencode.decode(torrentBuffer);
49-
delete torrent['announce'];
50-
return bencode.encode(torrent);
51+
const processTorrent = torrent => {
52+
const decodedTorrent = bencode.decode(torrent.buffer);
53+
const processedTorrent = _.cloneDeep(torrent);
54+
55+
delete decodedTorrent['announce'];
56+
57+
processedTorrent.fileList = [];
58+
processedTorrent.totalFileSize = decodedTorrent.info.files.reduce((total, file) => {
59+
processedTorrent.fileList.push({ fileName: file.path, fileSize: file.length });
60+
return total += file.length;
61+
}, 0);
62+
63+
processedTorrent.buffer = bencode.encode(decodedTorrent);
64+
processedTorrent.hash = hashTorrent(processedTorrent.buffer);
65+
66+
return Promise.resolve(processedTorrent);
5167
};
5268

5369
const hashTorrent = torrentBuffer => {
@@ -57,28 +73,28 @@ const hashTorrent = torrentBuffer => {
5773
return hash.digest('hex');
5874
};
5975

60-
const verifyAlbum = group => {
61-
const requiredFields = ['artist', 'album', 'year', 'release_type', 'format', 'bitrate', 'media'];
62-
const allowedFields = ['artist', 'album', 'year', 'release_type', 'format', 'bitrate', 'media'];
76+
const verify = (input, type) => {
77+
const required = type.required;
78+
const allowed = type.allowed;
79+
const errMsg = type.errorMessage || 'Missing required fields.';
6380

64-
const verifiedGroup = new Map();
65-
66-
Object.entries(group).forEach(entry => {
81+
const verified = new Map();
82+
Object.entries(input).forEach(entry => {
6783
let key = entry[0];
6884
let value = entry[1];
6985

70-
if (allowedFields.includes(key)) {
71-
verifiedGroup.set(key, value);
86+
if (allowed.includes(key)) {
87+
verified.set(key, value);
7288
}
7389
});
7490

75-
requiredFields.forEach(field => {
76-
if (!verifiedGroup.has(field)) {
77-
return Promise.reject(new Error('Missing required fields.'));
91+
required.forEach(field => {
92+
if (!verified.has(field)) {
93+
return Promise.reject(new Error(errMsg));
7894
}
79-
})
95+
});
8096

81-
return Promise.resolve(verifiedGroup);
97+
return Promise.resolve(verified);
8298
};
8399

84100
const upTo = to => {
@@ -89,46 +105,56 @@ const upTo = to => {
89105
return upToArray.toString();
90106
};
91107

92-
const createGroup = group => {
93-
return verifyAlbum(group).then(verifiedGroup => {
108+
const getGroup = group => {
109+
if (typeof (group) === 'number') return Promise.resolve(group);
110+
return verify(group, verificationTypes.group.album).then(verifiedGroup => {
94111
const keys = verifiedGroup.keys();
95112
const values = verifiedGroup.values();
96113
const length = verifiedGroup.size;
97114

98-
return db.query(`insert into tracker.groups (${keys.toString()}) values (${upTo(length)}) return id`, values);
115+
return db.query(`insert into tracker.groups (${[...keys].toString()}) values (${upTo(length)}) returning id`, [...values])
116+
.then(result => {
117+
group = result.rows[0].id;
118+
return group;
119+
});
99120
});
100121
};
101122

102-
const store = (torrent, group) => {
103-
return db.query('insert into tracker.torrents (hash, path, group) values ($1, $2, $3)', [torrent.hash, torrent.path, group]);
123+
const store = (torrent, group, releaseInfo) => {
124+
return verify(releaseInfo, verificationTypes.release.album).then(verifiedRelease => {
125+
// Add more information to the verified user input
126+
verifiedRelease.set('group_id', group);
127+
verifiedRelease.set('file_size', torrent.totalFileSize);
128+
verifiedRelease.set('original_file_name', torrent.originalname);
129+
verifiedRelease.set('file_path', torrent.path);
130+
verifiedRelease.set('files', JSON.stringify(torrent.fileList));
131+
132+
const keys = verifiedRelease.keys();
133+
const values = verifiedRelease.values();
134+
const length = verifiedRelease.size;
135+
136+
return db.query(`insert into tracker.torrents (${[...keys].toString()}) values (${upTo(length)}) returning id, group_id`, [...values]);
137+
})
104138
};
105139

106140
const torrentUpload = upload.fields([{ name: 'torrent', maxCount: 1 }]);
107141

108142
app.post('/upload', torrentUpload, (req, res) => {
109-
//app.post('/upload', upload.single('torrent'), (req, res) => {
110-
const torrent = stripTrackers(req.files.torrent[0].buffer);
143+
const torrent = req.files.torrent[0];
111144
const group = JSON.parse(req.body.group);
112-
113-
torrent.hash = hashTorrent(torrent.buffer);
114-
115-
saveToDisk(torrent).then(torrent => {
116-
if (typeof (group) !== 'Number') {
117-
return createGroup(group).then(result => {
118-
group = result.rows[0].id;
119-
return group
120-
}).then(group => {
121-
return store(torrent, group).then(result => {
122-
const torrentId = result.rows[0].id;
123-
if (torrentId) {
124-
res.send(200, { id: torrentId });
125-
}
126-
});
127-
})
128-
}
145+
const releaseInfo = JSON.parse(req.body.info);
146+
147+
processTorrent(torrent).then(saveToDisk).then(torrent => {
148+
return getGroup(group).then(group => {
149+
return store(torrent, group, releaseInfo).then(result => {
150+
const torrentId = result.rows[0].id;
151+
if (torrentId) {
152+
res.send(200, { id: result.rows[0].group_id });
153+
}
154+
});
155+
});
129156
}).catch(err => {
130157
console.log(err);
131-
res.sendStatus(500);
132158
});
133159
});
134160

0 commit comments

Comments
 (0)