From c943f39f6bdbcfa06d4a3d7263399fd9541773a6 Mon Sep 17 00:00:00 2001 From: Subin Siby Date: Thu, 12 May 2022 05:13:54 +0530 Subject: [PATCH] feat: add preference to customize global trackers (#1836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add preference to customize global trackers. Requires restart to apply * Use IPC to pass global trackers list, torrent pause and resume will now update trackers * Make the default tracker list an array from array of arrays * Use globalThis instead of just global Co-authored-by: Diego Rodríguez Baquero --- .../controllers/torrent-list-controller.js | 4 ++ src/renderer/lib/state.js | 13 +++++- src/renderer/main.js | 8 ++++ src/renderer/pages/preferences-page.js | 46 +++++++++++++++++++ src/renderer/webtorrent.js | 13 +++--- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/renderer/controllers/torrent-list-controller.js b/src/renderer/controllers/torrent-list-controller.js index 158841a5..af4051a8 100644 --- a/src/renderer/controllers/torrent-list-controller.js +++ b/src/renderer/controllers/torrent-list-controller.js @@ -113,6 +113,10 @@ module.exports = class TorrentListController { } } + setGlobalTrackers (globalTrackers) { + ipcRenderer.send('wt-set-global-trackers', globalTrackers) + } + // TODO: use torrentKey, not infoHash toggleTorrent (infoHash) { const torrentSummary = TorrentSummary.getByKey(this.state, infoHash) diff --git a/src/renderer/lib/state.js b/src/renderer/lib/state.js index 098869ab..97ad46fa 100644 --- a/src/renderer/lib/state.js +++ b/src/renderer/lib/state.js @@ -3,6 +3,7 @@ const path = require('path') const { EventEmitter } = require('events') const config = require('../../config') +const defaultAnnounceList = require('create-torrent').announceList.map((arr) => arr[0]) const SAVE_DEBOUNCE_INTERVAL = 1000 @@ -79,6 +80,7 @@ function getDefaultState () { getPlayingTorrentSummary, getPlayingFileSummary, getExternalPlayerName, + getGlobalTrackers, shouldHidePlayerControls } } @@ -129,7 +131,8 @@ function setupStateSaved () { soundNotifications: true, autoAddTorrents: false, torrentsFolderPath: '', - highestPlaybackPriority: true + highestPlaybackPriority: true, + globalTrackers: defaultAnnounceList }, torrents: config.DEFAULT_TORRENTS.map(createTorrentObject), torrentsToResume: [], @@ -201,6 +204,14 @@ function shouldHidePlayerControls () { this.playing.location === 'local' } +function getGlobalTrackers () { + const trackers = this.saved.prefs.globalTrackers + if (!trackers) { + return defaultAnnounceList + } + return trackers +} + async function load (cb) { let saved = await appConfig.read() diff --git a/src/renderer/main.js b/src/renderer/main.js index 945842ea..8e8ebbb2 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -124,6 +124,9 @@ function onState (err, _state) { } }) + // Give global trackers + setGlobalTrackers() + // Restart everything we were torrenting last time the app ran resumeTorrents() @@ -314,6 +317,7 @@ const dispatchHandlers = { preferences: () => controllers.prefs().show(), updatePreferences: (key, value) => controllers.prefs().update(key, value), checkDownloadPath, + updateGlobalTrackers: (trackers) => setGlobalTrackers(trackers), startFolderWatcher: () => controllers.folderWatcher().start(), stopFolderWatcher: () => controllers.folderWatcher().stop(), @@ -416,6 +420,10 @@ function escapeBack () { } } +function setGlobalTrackers () { + controllers.torrentList().setGlobalTrackers(state.getGlobalTrackers()) +} + // Starts all torrents that aren't paused on program startup function resumeTorrents () { state.saved.torrents diff --git a/src/renderer/pages/preferences-page.js b/src/renderer/pages/preferences-page.js index 359b6786..8bfe4000 100644 --- a/src/renderer/pages/preferences-page.js +++ b/src/renderer/pages/preferences-page.js @@ -4,6 +4,7 @@ const PropTypes = require('prop-types') const colors = require('material-ui/styles/colors') const Checkbox = require('material-ui/Checkbox').default const RaisedButton = require('material-ui/RaisedButton').default +const TextField = require('material-ui/TextField').default const Heading = require('../components/heading') const PathSelector = require('../components/path-selector') @@ -28,6 +29,15 @@ class PreferencesPage extends React.Component { this.handleSoundNotificationsChange = this.handleSoundNotificationsChange.bind(this) + + this.handleSetGlobalTrackers = + this.handleSetGlobalTrackers.bind(this) + + const globalTrackers = this.props.state.getGlobalTrackers().join('\n') + + this.state = { + globalTrackers + } } downloadPathSelector () { @@ -229,6 +239,39 @@ class PreferencesPage extends React.Component { dispatch('updatePreferences', 'isFileHandler', true) } + setGlobalTrackers () { + // Align the text fields + const textFieldStyle = { width: '100%' } + const textareaStyle = { margin: 0 } + + return ( + + + + ) + } + + handleSetGlobalTrackers (e, globalTrackers) { + this.setState({ globalTrackers }) + + const announceList = globalTrackers + .split('\n') + .map((s) => s.trim()) + .filter((s) => s !== '') + + dispatch('updatePreferences', 'globalTrackers', announceList) + dispatch('updateGlobalTrackers', announceList) + } + render () { const style = { color: colors.grey400, @@ -254,6 +297,9 @@ class PreferencesPage extends React.Component { {this.setStartupCheckbox()} {this.soundNotificationsCheckbox()} + + {this.setGlobalTrackers()} + ) } diff --git a/src/renderer/webtorrent.js b/src/renderer/webtorrent.js index ff888d36..6550aa70 100644 --- a/src/renderer/webtorrent.js +++ b/src/renderer/webtorrent.js @@ -4,7 +4,6 @@ console.time('init') const crypto = require('crypto') const util = require('util') -const defaultAnnounceList = require('create-torrent').announceList const { ipcRenderer } = require('electron') const fs = require('fs') const mm = require('music-metadata') @@ -16,11 +15,6 @@ const config = require('../config') const { TorrentKeyNotFoundError } = require('./lib/errors') const torrentPoster = require('./lib/torrent-poster') -// Force use of webtorrent trackers on all torrents -globalThis.WEBTORRENT_ANNOUNCE = defaultAnnounceList - .map((arr) => arr[0]) - .filter((url) => url.indexOf('wss://') === 0 || url.indexOf('ws://') === 0) - /** * WebTorrent version. */ @@ -65,6 +59,8 @@ init() function init () { listenToClientEvents() + ipcRenderer.on('wt-set-global-trackers', (e, globalTrackers) => + setGlobalTrackers(globalTrackers)) ipcRenderer.on('wt-start-torrenting', (e, torrentKey, torrentID, path, fileModtimes, selections) => startTorrenting(torrentKey, torrentID, path, fileModtimes, selections)) ipcRenderer.on('wt-stop-torrenting', (e, infoHash) => @@ -99,6 +95,11 @@ function listenToClientEvents () { client.on('error', (err) => ipcRenderer.send('wt-error', null, err.message)) } +// Sets the default trackers +function setGlobalTrackers (globalTrackers) { + globalThis.WEBTORRENT_ANNOUNCE = globalTrackers +} + // Starts a given TorrentID, which can be an infohash, magnet URI, etc. // Returns a WebTorrent object. See https://git.io/vik9M function startTorrenting (torrentKey, torrentID, path, fileModtimes, selections) {