Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Watch folder #1154

Merged
merged 9 commits into from
Oct 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"auto-launch": "^4.0.1",
"bitfield": "^1.0.2",
"capture-frame": "^1.0.0",
"chokidar": "^1.6.1",
"chromecasts": "^1.8.0",
"cp-file": "^4.0.1",
"create-torrent": "^3.24.5",
Expand Down
50 changes: 50 additions & 0 deletions src/main/folder-watcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const chokidar = require('chokidar')
const log = require('./log')

class FolderWatcher {
constructor ({window, state}) {
this.window = window
this.state = state
this.torrentsFolderPath = null
this.watching = false
}

isEnabled () {
return this.state.saved.prefs.autoAddTorrents
}

start () {
// Stop watching previous folder before
// start watching a new one.
if (this.watching) this.stop()

const torrentsFolderPath = this.state.saved.prefs.torrentsFolderPath
this.torrentsFolderPath = torrentsFolderPath
if (!torrentsFolderPath) return

const glob = `${torrentsFolderPath}/**/*.torrent`
log('Folder Watcher: watching: ', glob)

const options = {
ignoreInitial: true,
awaitWriteFinish: true
}
this.watcher = chokidar.watch(glob, options)
this.watcher
.on('add', (path) => {
log('Folder Watcher: added torrent: ', path)
this.window.dispatch('addTorrent', path)
})

this.watching = true
}

stop () {
log('Folder Watcher: stop.')
if (!this.watching) return
this.watcher.close()
this.watching = false
}
}

module.exports = FolderWatcher
16 changes: 13 additions & 3 deletions src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,16 @@ function init () {
if (err) throw err

isReady = true
const state = results.state

windows.main.init(results.state, {hidden: hidden})
windows.main.init(state, {hidden: hidden})
windows.webtorrent.init()
menu.init()

// To keep app startup fast, some code is delayed.
setTimeout(delayedInit, config.DELAYED_INIT)
setTimeout(() => {
delayedInit(state)
}, config.DELAYED_INIT)

// Report uncaught exceptions
process.on('uncaughtException', (err) => {
Expand Down Expand Up @@ -121,17 +124,24 @@ function init () {
})
}

function delayedInit () {
function delayedInit (state) {
if (app.isQuitting) return

const announcement = require('./announcement')
const dock = require('./dock')
const updater = require('./updater')
const FolderWatcher = require('./folder-watcher')
const folderWatcher = new FolderWatcher({window: windows.main, state})

announcement.init()
dock.init()
updater.init()

ipc.setModule('folderWatcher', folderWatcher)
if (folderWatcher.isEnabled()) {
folderWatcher.start()
}

if (process.platform === 'win32') {
const userTasks = require('./user-tasks')
userTasks.init()
Expand Down
35 changes: 33 additions & 2 deletions src/main/ipc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
init
init,
setModule
}

const electron = require('electron')
Expand All @@ -13,6 +14,14 @@ const windows = require('./windows')
// Messages from the main process, to be sent once the WebTorrent process starts
const messageQueueMainToWebTorrent = []

// Will hold modules injected from the app that will be used on fired
// IPC events.
const modules = {}

function setModule (name, module) {
modules[name] = module
}

function init () {
const ipc = electron.ipcMain

Expand Down Expand Up @@ -58,7 +67,7 @@ function init () {
})

/**
* Events
* Player Events
*/

ipc.on('onPlayerOpen', function () {
Expand Down Expand Up @@ -106,6 +115,28 @@ function init () {
thumbar.onPlayerPause()
})

/**
* Folder Watcher Events
*/

ipc.on('startFolderWatcher', function () {
if (!modules['folderWatcher']) {
log('IPC ERR: folderWatcher module is not defined.')
return
}

modules['folderWatcher'].start()
})

ipc.on('stopFolderWatcher', function () {
if (!modules['folderWatcher']) {
log('IPC ERR: folderWatcher module is not defined.')
return
}

modules['folderWatcher'].stop()
})

/**
* Shell
*/
Expand Down
13 changes: 13 additions & 0 deletions src/renderer/controllers/folder-watcher-controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const {ipcRenderer} = require('electron')

module.exports = class FolderWatcherController {
start () {
console.log('-- IPC: start folder watcher')
ipcRenderer.send('startFolderWatcher')
}

stop () {
console.log('-- IPC: stop folder watcher')
ipcRenderer.send('stopFolderWatcher')
}
}
4 changes: 3 additions & 1 deletion src/renderer/lib/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ function setupStateSaved (cb) {
isFileHandler: false,
openExternalPlayer: false,
externalPlayerPath: null,
startup: false
startup: false,
autoAddTorrents: false,
torrentsFolderPath: ''
},
torrents: config.DEFAULT_TORRENTS.map(createTorrentObject),
torrentsToResume: [],
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ function onState (err, _state) {
update: createGetter(() => {
const UpdateController = require('./controllers/update-controller')
return new UpdateController(state)
}),
folderWatcher: createGetter(() => {
const FolderWatcherController = require('./controllers/folder-watcher-controller')
return new FolderWatcherController()
})
}

Expand Down Expand Up @@ -296,6 +300,8 @@ const dispatchHandlers = {
'preferences': () => controllers.prefs().show(),
'updatePreferences': (key, value) => controllers.prefs().update(key, value),
'checkDownloadPath': checkDownloadPath,
'startFolderWatcher': () => controllers.folderWatcher().start(),
'stopFolderWatcher': () => controllers.folderWatcher().stop(),

// Update (check for new versions on Linux, where there's no auto updater)
'updateAvailable': (version) => controllers.update().updateAvailable(version),
Expand Down
57 changes: 56 additions & 1 deletion src/renderer/pages/preferences-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,59 @@ class PreferencesPage extends React.Component {
dispatch('updatePreferences', 'externalPlayerPath', filePath)
}

autoAddTorrentsCheckbox () {
return (
<Preference>
<Checkbox
className='control'
checked={this.props.state.unsaved.prefs.autoAddTorrents}
label={'Watch for new .torrent files and add them immediately'}
onCheck={(e, value) => { this.handleAutoAddTorrentsChange(e, value) }}
/>
</Preference>
)
}

handleAutoAddTorrentsChange (e, isChecked) {
const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath
if (isChecked && !torrentsFolderPath) {
alert('Select a torrents folder first.') // eslint-disable-line
e.preventDefault()
return
}

dispatch('updatePreferences', 'autoAddTorrents', isChecked)

if (isChecked) {
dispatch('startFolderWatcher', null)
return
}

dispatch('stopFolderWatcher', null)
}

torrentsFolderPathSelector () {
const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath

return (
<Preference>
<PathSelector
dialog={{
title: 'Select folder to watch for new torrents',
properties: [ 'openDirectory' ]
}}
displayValue={torrentsFolderPath || ''}
onChange={this.handletorrentsFolderPathChange}
title='Folder to watch'
value={torrentsFolderPath ? path.dirname(torrentsFolderPath) : null} />
</Preference>
)
}

handletorrentsFolderPathChange (filePath) {
dispatch('updatePreferences', 'torrentsFolderPath', filePath)
}

setDefaultAppButton () {
const isFileHandler = this.props.state.unsaved.prefs.isFileHandler
if (isFileHandler) {
Expand Down Expand Up @@ -163,8 +216,10 @@ class PreferencesPage extends React.Component {
}
return (
<div style={style}>
<PreferencesSection title='Downloads'>
<PreferencesSection title='Folders'>
{this.downloadPathSelector()}
{this.autoAddTorrentsCheckbox()}
{this.torrentsFolderPathSelector()}
</PreferencesSection>
<PreferencesSection title='Playback'>
{this.openExternalPlayerCheckbox()}
Expand Down