Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d3e26f15a | ||
|
|
8a95895254 | ||
|
|
5d71f9e9c6 | ||
|
|
5d410457ce | ||
|
|
c6cd21b8ff | ||
|
|
2235b2fa82 | ||
|
|
65e0b5d6e7 | ||
|
|
ea64411570 | ||
|
|
9348c61a84 | ||
|
|
d9aa3822ee | ||
|
|
e86bd26800 | ||
|
|
6d8cec17de | ||
|
|
572f084570 | ||
|
|
4a3ca5459d |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,5 +1,16 @@
|
||||
# WebTorrent Desktop Version History
|
||||
|
||||
## v0.7.1 - 2016-06-02
|
||||
|
||||
### Changed
|
||||
|
||||
- Change "Step Forward" keyboard shortcut to `Alt+Left`
|
||||
- Change "Step Backward" keyboard shortcut to to `Alt+Right`
|
||||
|
||||
### Fixed
|
||||
|
||||
- First time startup bug -- invalid torrent/poster paths
|
||||
|
||||
## v0.7.0 - 2016-06-02
|
||||
|
||||
### Added
|
||||
|
||||
@@ -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)
|
||||
|
||||
50
config.js
50
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,22 @@ function getConfigPath () {
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultDownloadPath () {
|
||||
if (!process || !process.type) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (isPortable()) {
|
||||
return path.join(getConfigPath(), 'Downloads')
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -217,13 +217,17 @@ function getMenuTemplate () {
|
||||
},
|
||||
{
|
||||
label: 'Step Forward',
|
||||
accelerator: 'CmdOrCtrl+Alt+Right',
|
||||
accelerator: process.platform === 'darwin'
|
||||
? 'CmdOrCtrl+Alt+Right'
|
||||
: 'Alt+Right',
|
||||
click: () => windows.main.dispatch('skip', 1),
|
||||
enabled: false
|
||||
},
|
||||
{
|
||||
label: 'Step Backward',
|
||||
accelerator: 'CmdOrCtrl+Alt+Left',
|
||||
accelerator: process.platform === 'darwin'
|
||||
? 'CmdOrCtrl+Alt+Left'
|
||||
: 'Alt+Left',
|
||||
click: () => windows.main.dispatch('skip', -1),
|
||||
enabled: false
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ function init () {
|
||||
resizable: false,
|
||||
show: false,
|
||||
skipTaskbar: true,
|
||||
title: 'About ' + config.APP_WINDOW_TITLE,
|
||||
useContentSize: true,
|
||||
width: 300
|
||||
})
|
||||
@@ -31,7 +32,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()
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "webtorrent-desktop",
|
||||
"description": "WebTorrent, the streaming torrent client. For OS X, Windows, and Linux.",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.2",
|
||||
"author": {
|
||||
"name": "WebTorrent, LLC",
|
||||
"email": "feross@feross.org",
|
||||
@@ -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",
|
||||
|
||||
@@ -18,44 +18,41 @@ function run (state) {
|
||||
var version = state.saved.version
|
||||
|
||||
if (semver.lt(version, '0.7.0')) {
|
||||
migrate_0_7_0(state)
|
||||
migrate_0_7_0(state.saved)
|
||||
}
|
||||
|
||||
// Future migrations...
|
||||
// if (semver.lt(version, '0.8.0')) {
|
||||
// migrate_0_8_0(state)
|
||||
// }
|
||||
if (semver.lt(version, '0.7.2')) {
|
||||
migrate_0_7_2(state.saved)
|
||||
}
|
||||
|
||||
// Config is now on the new version
|
||||
state.saved.version = config.APP_VERSION
|
||||
}
|
||||
|
||||
function migrate_0_7_0 (state) {
|
||||
function migrate_0_7_0 (saved) {
|
||||
console.log('migrate to 0.7.0')
|
||||
|
||||
var fs = require('fs-extra')
|
||||
var path = require('path')
|
||||
|
||||
state.saved.torrents.forEach(function (ts) {
|
||||
saved.torrents.forEach(function (ts) {
|
||||
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 +68,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)
|
||||
@@ -88,3 +85,11 @@ function migrate_0_7_0 (state) {
|
||||
delete ts.fileModtimes
|
||||
})
|
||||
}
|
||||
|
||||
function migrate_0_7_2 (saved) {
|
||||
if (!saved.prefs) {
|
||||
saved.prefs = {
|
||||
downloadPath: config.DEFAULT_DOWNLOAD_PATH
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,58 @@ 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')
|
||||
downloadPath: 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,
|
||||
selections: parsedTorrent.files.map((x) => true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,3 +159,57 @@ 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)
|
||||
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')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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, '/')
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Reference in New Issue
Block a user