@@ -4,24 +4,28 @@ const bencode = require('bencode');
4
4
const crypto = require ( 'crypto' ) ;
5
5
const db = require ( './../db.js' ) ;
6
6
const fs = require ( 'fs' ) ;
7
+ const _ = require ( 'lodash' ) ;
7
8
8
9
const app = express . Router ( ) ;
9
10
10
11
const util = require ( 'util' ) ;
11
12
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
+ }
20
20
} ,
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
+ }
23
27
}
24
- });*/
28
+ } ;
25
29
26
30
const saveToDisk = torrent => {
27
31
const now = new Date ( ) ;
@@ -44,10 +48,22 @@ const storage = multer.memoryStorage();
44
48
45
49
const upload = multer ( { storage } ) ;
46
50
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 ) ;
51
67
} ;
52
68
53
69
const hashTorrent = torrentBuffer => {
@@ -57,28 +73,28 @@ const hashTorrent = torrentBuffer => {
57
73
return hash . digest ( 'hex' ) ;
58
74
} ;
59
75
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.' ;
63
80
64
- const verifiedGroup = new Map ( ) ;
65
-
66
- Object . entries ( group ) . forEach ( entry => {
81
+ const verified = new Map ( ) ;
82
+ Object . entries ( input ) . forEach ( entry => {
67
83
let key = entry [ 0 ] ;
68
84
let value = entry [ 1 ] ;
69
85
70
- if ( allowedFields . includes ( key ) ) {
71
- verifiedGroup . set ( key , value ) ;
86
+ if ( allowed . includes ( key ) ) {
87
+ verified . set ( key , value ) ;
72
88
}
73
89
} ) ;
74
90
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 ) ) ;
78
94
}
79
- } )
95
+ } ) ;
80
96
81
- return Promise . resolve ( verifiedGroup ) ;
97
+ return Promise . resolve ( verified ) ;
82
98
} ;
83
99
84
100
const upTo = to => {
@@ -89,46 +105,56 @@ const upTo = to => {
89
105
return upToArray . toString ( ) ;
90
106
} ;
91
107
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 => {
94
111
const keys = verifiedGroup . keys ( ) ;
95
112
const values = verifiedGroup . values ( ) ;
96
113
const length = verifiedGroup . size ;
97
114
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
+ } ) ;
99
120
} ) ;
100
121
} ;
101
122
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
+ } )
104
138
} ;
105
139
106
140
const torrentUpload = upload . fields ( [ { name : 'torrent' , maxCount : 1 } ] ) ;
107
141
108
142
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 ] ;
111
144
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
+ } ) ;
129
156
} ) . catch ( err => {
130
157
console . log ( err ) ;
131
- res . sendStatus ( 500 ) ;
132
158
} ) ;
133
159
} ) ;
134
160
0 commit comments