Update to standard 7. Goodbye snake_case, I used to love you
[oweals/peertube.git] / server / lib / webtorrent.js
1 'use strict'
2
3 const config = require('config')
4 const ipc = require('node-ipc')
5 const pathUtils = require('path')
6 const spawn = require('electron-spawn')
7
8 const logger = require('../helpers/logger')
9
10 const electronDebug = config.get('electron.debug')
11 let host = config.get('webserver.host')
12 let port = config.get('webserver.port')
13 let nodeKey = 'webtorrentnode' + port
14 let processKey = 'webtorrentprocess' + port
15 ipc.config.silent = true
16 ipc.config.id = nodeKey
17
18 const webtorrent = {
19   add: add,
20   app: null, // Pid of the app
21   create: create,
22   remove: remove,
23   seed: seed,
24   silent: false // Useful for beautiful tests
25 }
26
27 function create (options, callback) {
28   if (typeof options === 'function') {
29     callback = options
30     options = {}
31   }
32
33   // Override options
34   if (options.host) host = options.host
35   if (options.port) {
36     port = options.port
37     nodeKey = 'webtorrentnode' + port
38     processKey = 'webtorrentprocess' + port
39     ipc.config.id = nodeKey
40   }
41
42   ipc.serve(function () {
43     if (!webtorrent.silent) logger.info('IPC server ready.')
44
45     // Run a timeout of 30s after which we exit the process
46     const timeoutWebtorrentProcess = setTimeout(function () {
47       throw new Error('Timeout : cannot run the webtorrent process. Please ensure you have electron-prebuilt npm package installed with xvfb-run.')
48     }, 30000)
49
50     ipc.server.on(processKey + '.ready', function () {
51       if (!webtorrent.silent) logger.info('Webtorrent process ready.')
52       clearTimeout(timeoutWebtorrentProcess)
53       callback()
54     })
55
56     ipc.server.on(processKey + '.exception', function (data) {
57       throw new Error('Received exception error from webtorrent process : ' + data.exception)
58     })
59
60     const webtorrentProcess = spawn(pathUtils.join(__dirname, 'webtorrentProcess.js'), host, port, { detached: true })
61
62     if (electronDebug === true) {
63       webtorrentProcess.stderr.on('data', function (data) {
64         logger.debug('Webtorrent process stderr: ', data.toString())
65       })
66
67       webtorrentProcess.stdout.on('data', function (data) {
68         logger.debug('Webtorrent process:', data.toString())
69       })
70     }
71
72     webtorrent.app = webtorrentProcess
73   })
74
75   ipc.server.start()
76 }
77
78 function seed (path, callback) {
79   const extension = pathUtils.extname(path)
80   const basename = pathUtils.basename(path, extension)
81   const data = {
82     _id: basename,
83     args: {
84       path: path
85     }
86   }
87
88   if (!webtorrent.silent) logger.debug('Node wants to seed %s.', data._id)
89
90   // Finish signal
91   const eventKey = nodeKey + '.seedDone.' + data._id
92   ipc.server.on(eventKey, function listener (received) {
93     if (!webtorrent.silent) logger.debug('Process seeded torrent %s.', received.magnetUri)
94
95     // This is a fake object, we just use the magnetUri in this project
96     const torrent = {
97       magnetURI: received.magnetUri
98     }
99
100     ipc.server.off(eventKey)
101     callback(torrent)
102   })
103
104   ipc.server.broadcast(processKey + '.seed', data)
105 }
106
107 function add (magnetUri, callback) {
108   const data = {
109     _id: magnetUri,
110     args: {
111       magnetUri: magnetUri
112     }
113   }
114
115   if (!webtorrent.silent) logger.debug('Node wants to add ' + data._id)
116
117   // Finish signal
118   const eventKey = nodeKey + '.addDone.' + data._id
119   ipc.server.on(eventKey, function (received) {
120     if (!webtorrent.silent) logger.debug('Process added torrent.')
121
122     // This is a fake object, we just use the magnetUri in this project
123     const torrent = {
124       files: received.files
125     }
126
127     ipc.server.off(eventKey)
128     callback(torrent)
129   })
130
131   ipc.server.broadcast(processKey + '.add', data)
132 }
133
134 function remove (magnetUri, callback) {
135   const data = {
136     _id: magnetUri,
137     args: {
138       magnetUri: magnetUri
139     }
140   }
141
142   if (!webtorrent.silent) logger.debug('Node wants to stop seeding %s.', data._id)
143
144   // Finish signal
145   const eventKey = nodeKey + '.removeDone.' + data._id
146   ipc.server.on(eventKey, function (received) {
147     if (!webtorrent.silent) logger.debug('Process removed torrent %s.', data._id)
148
149     let err = null
150     if (received.err) err = received.err
151
152     ipc.server.off(eventKey)
153     callback(err)
154   })
155
156   ipc.server.broadcast(processKey + '.remove', data)
157 }
158
159 // ---------------------------------------------------------------------------
160
161 module.exports = webtorrent