From 6d8cec17de60538ec735aaeacb92441bb4719ac7 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 2 Jun 2016 19:40:12 -0700 Subject: [PATCH 1/4] npm run open-config -- open folder --- bin/open-config.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/open-config.js b/bin/open-config.js index b005a1d8..3c9a5990 100755 --- a/bin/open-config.js +++ b/bin/open-config.js @@ -2,7 +2,5 @@ var config = require('../config') var open = require('open') -var path = require('path') -var configPath = path.join(config.CONFIG_PATH, 'config.json') -open(configPath) +open(config.CONFIG_PATH) From e86bd268004111f81c2cca3d846e99fbc957b6fc Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 2 Jun 2016 19:46:29 -0700 Subject: [PATCH 2/4] Refactor state save/load - Fix bug where new install was relying on the migration to run on startup to fix up the default config - Moved save/load functions into state.js - Removed exported getInitialState, getDefaultSavedState since that's leaky. The state module should take care of that. --- config.js | 46 ++- main/windows/about.js | 2 +- package.json | 1 + renderer/lib/migrations.js | 18 +- renderer/lib/state.js | 305 +++++++------------ renderer/lib/torrent-summary.js | 4 +- renderer/main.js | 87 ++---- renderer/views/home.js | 3 +- renderer/webtorrent.js | 8 +- static/{wired-cd.jpg => wiredCd.jpg} | Bin static/{wired-cd.torrent => wiredCd.torrent} | Bin 11 files changed, 201 insertions(+), 273 deletions(-) rename static/{wired-cd.jpg => wiredCd.jpg} (100%) rename static/{wired-cd.torrent => wiredCd.torrent} (100%) diff --git a/config.js b/config.js index fa123f73..67713721 100644 --- a/config.js +++ b/config.js @@ -24,11 +24,39 @@ module.exports = { CRASH_REPORT_URL: 'https://webtorrent.io/desktop/crash-report', CONFIG_PATH: getConfigPath(), - CONFIG_POSTER_PATH: path.join(getConfigPath(), 'Posters'), - CONFIG_TORRENT_PATH: path.join(getConfigPath(), 'Torrents'), + + DEFAULT_TORRENTS: [ + { + name: 'Big Buck Bunny', + posterFileName: 'bigBuckBunny.jpg', + torrentFileName: 'bigBuckBunny.torrent' + }, + { + name: 'Cosmos Laundromat (Preview)', + posterFileName: 'cosmosLaundromat.jpg', + torrentFileName: 'cosmosLaundromat.torrent' + }, + { + name: 'Sintel', + posterFileName: 'sintel.jpg', + torrentFileName: 'sintel.torrent' + }, + { + name: 'Tears of Steel', + posterFileName: 'tearsOfSteel.jpg', + torrentFileName: 'tearsOfSteel.torrent' + }, + { + name: 'The WIRED CD - Rip. Sample. Mash. Share.', + posterFileName: 'wiredCd.jpg', + torrentFileName: 'wiredCd.torrent' + } + ], DELAYED_INIT: 3000 /* 3 seconds */, + DEFAULT_DOWNLOAD_PATH: getDefaultDownloadPath(), + GITHUB_URL: 'https://github.com/feross/webtorrent-desktop', GITHUB_URL_ISSUES: 'https://github.com/feross/webtorrent-desktop/issues', GITHUB_URL_RAW: 'https://raw.githubusercontent.com/feross/webtorrent-desktop/master', @@ -38,8 +66,10 @@ module.exports = { IS_PORTABLE: isPortable(), IS_PRODUCTION: isProduction(), + POSTER_PATH: path.join(getConfigPath(), 'Posters'), ROOT_PATH: __dirname, STATIC_PATH: path.join(__dirname, 'static'), + TORRENT_PATH: path.join(getConfigPath(), 'Torrents'), WINDOW_ABOUT: 'file://' + path.join(__dirname, 'renderer', 'about.html'), WINDOW_MAIN: 'file://' + path.join(__dirname, 'renderer', 'main.html'), @@ -57,6 +87,18 @@ function getConfigPath () { } } +function getDefaultDownloadPath () { + if (!process || !process.type) { + return '' + } + + var electron = require('electron') + + return process.type === 'renderer' + ? electron.remote.app.getPath('downloads') + : electron.app.getPath('downloads') +} + function isPortable () { try { return process.platform === 'win32' && isProduction() && !!fs.statSync(PORTABLE_PATH) diff --git a/main/windows/about.js b/main/windows/about.js index 0a29d51d..c21dfc4d 100644 --- a/main/windows/about.js +++ b/main/windows/about.js @@ -31,7 +31,7 @@ function init () { // No menu on the About window win.setMenu(null) - win.webContents.on('did-finish-load', function () { + win.webContents.once('did-finish-load', function () { win.show() }) diff --git a/package.json b/package.json index 131520f2..971060a8 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "main-loop": "^3.2.0", "musicmetadata": "^2.0.2", "network-address": "^1.1.0", + "parse-torrent": "^5.7.3", "prettier-bytes": "^1.0.1", "run-parallel": "^1.1.6", "semver": "^5.1.0", diff --git a/renderer/lib/migrations.js b/renderer/lib/migrations.js index 011374f6..15b11526 100644 --- a/renderer/lib/migrations.js +++ b/renderer/lib/migrations.js @@ -40,22 +40,20 @@ function migrate_0_7_0 (state) { var infoHash = ts.infoHash // Replace torrentPath with torrentFileName + // There are a number of cases to handle here: + // * Originally we used absolute paths + // * Then, relative paths for the default torrents, eg '../static/sintel.torrent' + // * Then, paths computed at runtime for default torrents, eg 'sintel.torrent' + // * Finally, now we're getting rid of torrentPath altogether var src, dst if (ts.torrentPath) { - // There are a number of cases to handle here: - // * Originally we used absolute paths - // * Then, relative paths for the default torrents, eg '../static/sintel.torrent' - // * Then, paths computed at runtime for default torrents, eg 'sintel.torrent' - // * Finally, now we're getting rid of torrentPath altogether console.log('replacing torrentPath %s', ts.torrentPath) - if (path.isAbsolute(ts.torrentPath)) { - src = ts.torrentPath - } else if (ts.torrentPath.startsWith('..')) { + if (path.isAbsolute(ts.torrentPath) || ts.torrentPath.startsWith('..')) { src = ts.torrentPath } else { src = path.join(config.STATIC_PATH, ts.torrentPath) } - dst = path.join(config.CONFIG_TORRENT_PATH, infoHash + '.torrent') + dst = path.join(config.TORRENT_PATH, infoHash + '.torrent') // Synchronous FS calls aren't ideal, but probably OK in a migration // that only runs once if (src !== dst) fs.copySync(src, dst) @@ -71,7 +69,7 @@ function migrate_0_7_0 (state) { src = path.isAbsolute(ts.posterURL) ? ts.posterURL : path.join(config.STATIC_PATH, ts.posterURL) - dst = path.join(config.CONFIG_POSTER_PATH, infoHash + extension) + dst = path.join(config.POSTER_PATH, infoHash + extension) // Synchronous FS calls aren't ideal, but probably OK in a migration // that only runs once if (src !== dst) fs.copySync(src, dst) diff --git a/renderer/lib/state.js b/renderer/lib/state.js index 88c7b229..e782b826 100644 --- a/renderer/lib/state.js +++ b/renderer/lib/state.js @@ -1,18 +1,20 @@ -var electron = require('electron') -var path = require('path') - -var remote = electron.remote - -var config = require('../../config') -var LocationHistory = require('./location-history') - module.exports = { - getInitialState, getDefaultPlayState, - getDefaultSavedState + load, + save } -function getInitialState () { +var appConfig = require('application-config')('WebTorrent') +var path = require('path') + +var config = require('../../config') +var migrations = require('./migrations') + +appConfig.filePath = path.join(config.CONFIG_PATH, 'config.json') + +function getDefaultState () { + var LocationHistory = require('./location-history') + return { /* * Temporary state disappears once the program exits. @@ -91,185 +93,59 @@ function getDefaultPlayState () { } /* If the saved state file doesn't exist yet, here's what we use instead */ -function getDefaultSavedState () { - return { - version: config.APP_VERSION, /* make sure we can upgrade gracefully later */ - torrents: [ - { - status: 'paused', - infoHash: '88594aaacbde40ef3e2510c47374ec0aa396c08e', - magnetURI: 'magnet:?xt=urn:btih:88594aaacbde40ef3e2510c47374ec0aa396c08e&dn=bbb_sunflower_1080p_30fps_normal.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80%2Fannounce&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=wss%3A%2F%2Ftracker.webtorrent.io&ws=http%3A%2F%2Fdistribution.bbb3d.renderfarming.net%2Fvideo%2Fmp4%2Fbbb_sunflower_1080p_30fps_normal.mp4', - displayName: 'Big Buck Bunny', - posterURL: 'bigBuckBunny.jpg', - torrentPath: 'bigBuckBunny.torrent', - files: [ - { - length: 276134947, - name: 'bbb_sunflower_1080p_30fps_normal.mp4' - } - ] - }, - { - status: 'paused', - infoHash: '6a9759bffd5c0af65319979fb7832189f4f3c35d', - magnetURI: 'magnet:?xt=urn:btih:6a9759bffd5c0af65319979fb7832189f4f3c35d&dn=sintel.mp4&tr=udp%3A%2F%2Fexodus.desync.com%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=wss%3A%2F%2Ftracker.webtorrent.io&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel-1024-surround.mp4', - displayName: 'Sintel', - posterURL: 'sintel.jpg', - torrentPath: 'sintel.torrent', - files: [ - { - length: 129241752, - name: 'sintel.mp4' - } - ] - }, - { - status: 'paused', - infoHash: '02767050e0be2fd4db9a2ad6c12416ac806ed6ed', - magnetURI: 'magnet:?xt=urn:btih:02767050e0be2fd4db9a2ad6c12416ac806ed6ed&dn=tears_of_steel_1080p.webm&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=wss%3A%2F%2Ftracker.webtorrent.io', - displayName: 'Tears of Steel', - posterURL: 'tearsOfSteel.jpg', - torrentPath: 'tearsOfSteel.torrent', - files: [ - { - length: 571346576, - name: 'tears_of_steel_1080p.webm' - } - ] - }, - { - status: 'paused', - infoHash: '6a02592d2bbc069628cd5ed8a54f88ee06ac0ba5', - magnetURI: 'magnet:?xt=urn:btih:6a02592d2bbc069628cd5ed8a54f88ee06ac0ba5&dn=CosmosLaundromatFirstCycle&tr=http%3A%2F%2Fbt1.archive.org%3A6969%2Fannounce&tr=http%3A%2F%2Fbt2.archive.org%3A6969%2Fannounce&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=wss%3A%2F%2Ftracker.webtorrent.io&ws=http%3A%2F%2Fia601508.us.archive.org%2F14%2Fitems%2F&ws=http%3A%2F%2Fia801508.us.archive.org%2F14%2Fitems%2F&ws=https%3A%2F%2Farchive.org%2Fdownload%2F', - displayName: 'Cosmos Laundromat (Preview)', - posterURL: 'cosmosLaundromat.jpg', - torrentPath: 'cosmosLaundromat.torrent', - files: [ - { - length: 223580, - name: 'Cosmos Laundromat - First Cycle (1080p).gif' - }, - { - length: 220087570, - name: 'Cosmos Laundromat - First Cycle (1080p).mp4' - }, - { - length: 56832560, - name: 'Cosmos Laundromat - First Cycle (1080p).ogv' - }, - { - length: 3949, - name: 'CosmosLaundromat-FirstCycle1080p.en.srt' - }, - { - length: 3907, - name: 'CosmosLaundromat-FirstCycle1080p.es.srt' - }, - { - length: 4119, - name: 'CosmosLaundromat-FirstCycle1080p.fr.srt' - }, - { - length: 3941, - name: 'CosmosLaundromat-FirstCycle1080p.it.srt' - }, - { - length: 11264, - name: 'CosmosLaundromatFirstCycle_meta.sqlite' - }, - { - length: 1204, - name: 'CosmosLaundromatFirstCycle_meta.xml' - } - ] - }, - { - status: 'paused', - infoHash: '3ba219a8634bf7bae3d848192b2da75ae995589d', - magnetURI: 'magnet:?xt=urn:btih:3ba219a8634bf7bae3d848192b2da75ae995589d&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share.&tr=udp%3A%2F%2Fexodus.desync.com%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.internetwarriors.net%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=wss%3A%2F%2Ftracker.webtorrent.io&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F', - displayName: 'The WIRED CD - Rip. Sample. Mash. Share.', - posterURL: 'wired-cd.jpg', - torrentPath: 'wired-cd.torrent', - files: [ - { - length: 1964275, - name: '01 - Beastie Boys - Now Get Busy.mp3' - }, - { - length: 3610523, - name: '02 - David Byrne - My Fair Lady.mp3' - }, - { - length: 2759377, - name: '03 - Zap Mama - Wadidyusay.mp3' - }, - { - length: 5816537, - name: '04 - My Morning Jacket - One Big Holiday.mp3' - }, - { - length: 2106421, - name: '05 - Spoon - Revenge!.mp3' - }, - { - length: 3347550, - name: '06 - Gilberto Gil - Oslodum.mp3' - }, - { - length: 2107577, - name: '07 - Dan The Automator - Relaxation Spa Treatment.mp3' - }, - { - length: 3108130, - name: '08 - Thievery Corporation - Dc 3000.mp3' - }, - { - length: 3051528, - name: '09 - Le Tigre - Fake French.mp3' - }, - { - length: 3270259, - name: '10 - Paul Westerberg - Looking Up In Heaven.mp3' - }, - { - length: 3263528, - name: '11 - Chuck D - No Meaning No (feat. Fine Arts Militia).mp3' - }, - { - length: 6380952, - name: '12 - The Rapture - Sister Saviour (Blackstrobe Remix).mp3' - }, - { - length: 6550396, - name: '13 - Cornelius - Wataridori 2.mp3' - }, - { - length: 3034692, - name: '14 - DJ Danger Mouse - What U Sittin\' On (feat. Jemini, Cee Lo And Tha Alkaholiks).mp3' - }, - { - length: 3854611, - name: '15 - DJ Dolores - Oslodum 2004.mp3' - }, - { - length: 1762120, - name: '16 - Matmos - Action At A Distance.mp3' - }, - { - length: 4071, - name: 'README.md' - }, - { - length: 78163, - name: 'poster.jpg' - } - ] - } - ], +function setupSavedState (cb) { + var fs = require('fs-extra') + var parseTorrent = require('parse-torrent') + var parallel = require('run-parallel') + + var saved = { prefs: { downloadPath: config.IS_PORTABLE ? path.join(config.CONFIG_PATH, 'Downloads') - : remote.app.getPath('downloads') + : config.DEFAULT_DOWNLOAD_PATH + }, + torrents: config.DEFAULT_TORRENTS.map(createTorrentObject), + version: config.APP_VERSION /* make sure we can upgrade gracefully later */ + } + + var tasks = [] + + config.DEFAULT_TORRENTS.map(function (t, i) { + var infoHash = saved.torrents[i].infoHash + tasks.push(function (cb) { + fs.copy( + path.join(config.STATIC_PATH, t.posterFileName), + path.join(config.POSTER_PATH, infoHash + path.extname(t.posterFileName)), + cb + ) + }) + tasks.push(function (cb) { + fs.copy( + path.join(config.STATIC_PATH, t.torrentFileName), + path.join(config.TORRENT_PATH, infoHash + '.torrent'), + cb + ) + }) + }) + + parallel(tasks, function (err) { + if (err) return cb(err) + cb(null, saved) + }) + + function createTorrentObject (t) { + var torrent = fs.readFileSync(path.join(config.STATIC_PATH, t.torrentFileName)) + var parsedTorrent = parseTorrent(torrent) + + return { + status: 'paused', + infoHash: parsedTorrent.infoHash, + name: t.name, + displayName: t.name, + posterFileName: parsedTorrent.infoHash + path.extname(t.posterFileName), + torrentFileName: parsedTorrent.infoHash + '.torrent', + magnetURI: parseTorrent.toMagnetURI(parsedTorrent), + files: parsedTorrent.files } } } @@ -284,3 +160,58 @@ function getPlayingFileSummary () { if (!torrentSummary) return null return torrentSummary.files[this.playing.fileIndex] } + +function load (cb) { + var state = getDefaultState() + + appConfig.read(function (err, saved) { + if (err || !saved.version) { + console.log('Missing config file: Creating new one') + setupSavedState(onSaved) + } else { + onSaved(null, saved) + } + }) + + function onSaved (err, saved) { + if (err) return cb(err) + console.log('onSaved', err, saved) + state.saved = saved + migrations.run(state) + cb(null, state) + } +} + +// Write state.saved to the JSON state file +function save (state, cb) { + console.log('saving state to ' + appConfig.filePath) + + var electron = require('electron') + + // Clean up, so that we're not saving any pending state + var copy = Object.assign({}, state.saved) + // Remove torrents pending addition to the list, where we haven't finished + // reading the torrent file or file(s) to seed & don't have an infohash + copy.torrents = copy.torrents + .filter((x) => x.infoHash) + .map(function (x) { + var torrent = {} + for (var key in x) { + if (key === 'progress' || key === 'torrentKey') { + continue // Don't save progress info or key for the webtorrent process + } + if (key === 'playStatus') { + continue // Don't save whether a torrent is playing / pending + } + torrent[key] = x[key] + } + return torrent + }) + + appConfig.write(copy, function (err) { + if (err) console.error(err) + + // TODO: this doesn't belong here + electron.ipcRenderer.send('savedState') + }) +} diff --git a/renderer/lib/torrent-summary.js b/renderer/lib/torrent-summary.js index 23eb5932..9587777c 100644 --- a/renderer/lib/torrent-summary.js +++ b/renderer/lib/torrent-summary.js @@ -10,14 +10,14 @@ var config = require('../../config') // Returns an absolute path to the torrent file, or null if unavailable function getTorrentPath (torrentSummary) { if (!torrentSummary || !torrentSummary.torrentFileName) return null - return path.join(config.CONFIG_TORRENT_PATH, torrentSummary.torrentFileName) + return path.join(config.TORRENT_PATH, torrentSummary.torrentFileName) } // Expects a torrentSummary // Returns an absolute path to the poster image, or null if unavailable function getPosterPath (torrentSummary) { if (!torrentSummary || !torrentSummary.posterFileName) return null - var posterPath = path.join(config.CONFIG_POSTER_PATH, torrentSummary.posterFileName) + var posterPath = path.join(config.POSTER_PATH, torrentSummary.posterFileName) // Work around a Chrome bug (reproduced in vanilla Chrome, not just Electron): // Backslashes in URLS in CSS cause bizarre string encoding issues return posterPath.replace(/\\/g, '/') diff --git a/renderer/main.js b/renderer/main.js index 4a782bd9..04ce25bc 100644 --- a/renderer/main.js +++ b/renderer/main.js @@ -3,7 +3,6 @@ console.time('init') var crashReporter = require('../crash-reporter') crashReporter.init() -var appConfig = require('application-config')('WebTorrent') var dragDrop = require('drag-drop') var electron = require('electron') var fs = require('fs-extra') @@ -18,46 +17,30 @@ var patch = require('virtual-dom/patch') var App = require('./views/app') var config = require('../config') var errors = require('./lib/errors') -var migrations = require('./lib/migrations') var sound = require('./lib/sound') var State = require('./lib/state') var TorrentPlayer = require('./lib/torrent-player') var TorrentSummary = require('./lib/torrent-summary') - var {setDispatch} = require('./lib/dispatcher') -setDispatch(dispatch) - -appConfig.filePath = path.join(config.CONFIG_PATH, 'config.json') - -// This dependency is the slowest-loading, so we lazy load it -var Cast = null - -var vdomLoop - -var state = State.getInitialState() -state.location.go({ url: 'home' }) // Add first page to location history // Electron apps have two processes: a main process (node) runs first and starts // a renderer process (essentially a Chrome window). We're in the renderer process, // and this IPC channel receives from and sends messages to the main process var ipcRenderer = electron.ipcRenderer -// All state lives in state.js. `state.saved` is read from and written to a file. -// All other state is ephemeral. First we load state.saved then initialize the app. -loadState(init) +var state, vdomLoop -function loadState (cb) { - appConfig.read(function (err, data) { - if (err) console.error(err) +// This dependency is the slowest-loading, so we lazy load it +var Cast = null - // populate defaults if they're not there - state.saved = Object.assign({}, State.getDefaultSavedState(), data) - state.saved.torrents.forEach(function (torrentSummary) { - if (torrentSummary.displayName) torrentSummary.name = torrentSummary.displayName - }) +init() - if (cb) cb() - }) +function init () { + // All state lives in state.js. `state.saved` is read from and written to a file. + // All other state is ephemeral. First we load state.saved then initialize the app. + State.load(onState) + + setDispatch(dispatch) } /** @@ -65,9 +48,12 @@ function loadState (cb) { * Connects to the torrent networks, sets up the UI and OS integrations like * the dock icon and drag+drop. */ -function init () { - // Clean up the freshly-loaded config file, which may be from an older version - migrations.run(state) +function onState (err, _state) { + if (err) return onError(err) + state = _state + + // Add first page to location history + state.location.go({ url: 'home' }) // Restart everything we were torrenting last time the app ran resumeTorrents() @@ -328,7 +314,7 @@ function dispatch (action, ...args) { saveStateThrottled() } if (action === 'saveState') { - saveState() + State.save(state) } if (action === 'setTitle') { state.window.title = args[0] /* title */ @@ -512,7 +498,8 @@ function updatePreferences (property, value) { // All unsaved prefs take effect atomically, and are saved to config.json function savePreferences () { state.saved.prefs = Object.assign(state.saved.prefs || {}, state.unsaved.prefs) - saveState() + State.save(state) + update() } // Don't write state.saved to file more than once a second @@ -520,43 +507,11 @@ function saveStateThrottled () { if (state.saveStateTimeout) return state.saveStateTimeout = setTimeout(function () { delete state.saveStateTimeout - saveState() + State.save(state) + update() }, 1000) } -// Write state.saved to the JSON state file -function saveState () { - console.log('saving state to ' + appConfig.filePath) - - // Clean up, so that we're not saving any pending state - var copy = Object.assign({}, state.saved) - // Remove torrents pending addition to the list, where we haven't finished - // reading the torrent file or file(s) to seed & don't have an infohash - copy.torrents = copy.torrents - .filter((x) => x.infoHash) - .map(function (x) { - var torrent = {} - for (var key in x) { - if (key === 'progress' || key === 'torrentKey') { - continue // Don't save progress info or key for the webtorrent process - } - if (key === 'playStatus') { - continue // Don't save whether a torrent is playing / pending - } - torrent[key] = x[key] - } - return torrent - }) - - appConfig.write(copy, function (err) { - if (err) console.error(err) - ipcRenderer.send('savedState') - }) - - // Update right away, don't wait for the state to save - update() -} - // Called when the user adds files (.torrent, files to seed, subtitles) to the app // via any method (drag-drop, drag to app icon, command line) function onOpen (files) { diff --git a/renderer/views/home.js b/renderer/views/home.js index 2d405424..4c9ebbff 100644 --- a/renderer/views/home.js +++ b/renderer/views/home.js @@ -218,7 +218,8 @@ function TorrentList (state) { // Show a single torrentSummary file in the details view for a single torrent function renderFileRow (torrentSummary, file, index) { // First, find out how much of the file we've downloaded - var isSelected = torrentSummary.selections[index] // Are we even torrenting it? + // Are we even torrenting it? + var isSelected = torrentSummary.selections && torrentSummary.selections[index] var isDone = false // Are we finished torrenting it? var progress = '' if (torrentSummary.progress && torrentSummary.progress.files) { diff --git a/renderer/webtorrent.js b/renderer/webtorrent.js index 3dd5ec2c..e2ccbd3c 100644 --- a/renderer/webtorrent.js +++ b/renderer/webtorrent.js @@ -173,7 +173,7 @@ function saveTorrentFile (torrentKey) { } // Otherwise, save the .torrent file, under the app config folder - fs.mkdir(config.CONFIG_TORRENT_PATH, function (_) { + fs.mkdir(config.TORRENT_PATH, function (_) { fs.writeFile(torrentPath, torrent.torrentFile, function (err) { if (err) return console.log('error saving torrent file %s: %o', torrentPath, err) console.log('saved torrent file %s', torrentPath) @@ -186,7 +186,7 @@ function saveTorrentFile (torrentKey) { // Checks whether we've already resolved a given infohash to a torrent file // Calls back with (torrentPath, exists). Logs, does not call back on error function checkIfTorrentFileExists (infoHash, cb) { - var torrentPath = path.join(config.CONFIG_TORRENT_PATH, infoHash + '.torrent') + var torrentPath = path.join(config.TORRENT_PATH, infoHash + '.torrent') fs.exists(torrentPath, function (exists) { cb(torrentPath, exists) }) @@ -199,10 +199,10 @@ function generateTorrentPoster (torrentKey) { torrentPoster(torrent, function (err, buf, extension) { if (err) return console.log('error generating poster: %o', err) // save it for next time - fs.mkdirp(config.CONFIG_POSTER_PATH, function (err) { + fs.mkdirp(config.POSTER_PATH, function (err) { if (err) return console.log('error creating poster dir: %o', err) var posterFileName = torrent.infoHash + extension - var posterFilePath = path.join(config.CONFIG_POSTER_PATH, posterFileName) + var posterFilePath = path.join(config.POSTER_PATH, posterFileName) fs.writeFile(posterFilePath, buf, function (err) { if (err) return console.log('error saving poster: %o', err) // show the poster diff --git a/static/wired-cd.jpg b/static/wiredCd.jpg similarity index 100% rename from static/wired-cd.jpg rename to static/wiredCd.jpg diff --git a/static/wired-cd.torrent b/static/wiredCd.torrent similarity index 100% rename from static/wired-cd.torrent rename to static/wiredCd.torrent From d9aa3822eee2414ef951c66267378b6053a2e754 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 2 Jun 2016 19:52:35 -0700 Subject: [PATCH 3/4] Set selections by default In case the user tries to change a file selection state before enabling the torrent. --- renderer/lib/state.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/renderer/lib/state.js b/renderer/lib/state.js index e782b826..243f4657 100644 --- a/renderer/lib/state.js +++ b/renderer/lib/state.js @@ -145,7 +145,8 @@ function setupSavedState (cb) { posterFileName: parsedTorrent.infoHash + path.extname(t.posterFileName), torrentFileName: parsedTorrent.infoHash + '.torrent', magnetURI: parseTorrent.toMagnetURI(parsedTorrent), - files: parsedTorrent.files + files: parsedTorrent.files, + selections: parsedTorrent.files.map((x) => true) } } } From 9348c61a844450b1f74491ea8a2cc2237470f843 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Thu, 2 Jun 2016 19:53:37 -0700 Subject: [PATCH 4/4] stray console.log --- renderer/lib/state.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/renderer/lib/state.js b/renderer/lib/state.js index 243f4657..81fbacea 100644 --- a/renderer/lib/state.js +++ b/renderer/lib/state.js @@ -176,7 +176,6 @@ function load (cb) { function onSaved (err, saved) { if (err) return cb(err) - console.log('onSaved', err, saved) state.saved = saved migrations.run(state) cb(null, state) @@ -185,7 +184,7 @@ function load (cb) { // Write state.saved to the JSON state file function save (state, cb) { - console.log('saving state to ' + appConfig.filePath) + console.log('Saving state to ' + appConfig.filePath) var electron = require('electron')