2020-10-24 01:04:25 +00:00
|
|
|
/**
|
2020-10-25 21:13:48 +00:00
|
|
|
* @license
|
|
|
|
*
|
2020-10-24 01:04:25 +00:00
|
|
|
* Copyright © Charles Kerr, Dave Perrett, Malcolm Jarvis and Bruno Bierbaumer
|
|
|
|
*
|
|
|
|
* This file is licensed under the GPLv2.
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { AlertDialog } from './alert-dialog.js';
|
|
|
|
|
|
|
|
export const RPC = {
|
|
|
|
_DaemonVersion: 'version',
|
|
|
|
_DownSpeedLimit: 'speed-limit-down',
|
|
|
|
_DownSpeedLimited: 'speed-limit-down-enabled',
|
|
|
|
_QueueMoveBottom: 'queue-move-bottom',
|
|
|
|
_QueueMoveDown: 'queue-move-down',
|
|
|
|
_QueueMoveTop: 'queue-move-top',
|
|
|
|
_QueueMoveUp: 'queue-move-up',
|
|
|
|
_Root: '../rpc',
|
|
|
|
_TurtleDownSpeedLimit: 'alt-speed-down',
|
|
|
|
_TurtleState: 'alt-speed-enabled',
|
|
|
|
_TurtleUpSpeedLimit: 'alt-speed-up',
|
|
|
|
_UpSpeedLimit: 'speed-limit-up',
|
|
|
|
_UpSpeedLimited: 'speed-limit-up-enabled',
|
|
|
|
};
|
|
|
|
|
|
|
|
export class Remote {
|
|
|
|
// TODO: decouple from controller
|
|
|
|
constructor(controller) {
|
|
|
|
this._controller = controller;
|
|
|
|
this._error = '';
|
|
|
|
this._session_id = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
sendRequest(data, callback, context) {
|
|
|
|
const headers = new Headers();
|
|
|
|
headers.append('cache-control', 'no-cache');
|
|
|
|
headers.append('content-type', 'application/json');
|
|
|
|
headers.append('pragma', 'no-cache');
|
|
|
|
if (this._session_id) {
|
|
|
|
headers.append(Remote._SessionHeader, this._session_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
let response_argument = null;
|
|
|
|
fetch(RPC._Root, {
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
headers,
|
|
|
|
method: 'POST',
|
|
|
|
})
|
|
|
|
.then((response) => {
|
|
|
|
response_argument = response;
|
|
|
|
if (response.status === 409) {
|
|
|
|
const error = new Error(Remote._SessionHeader);
|
|
|
|
error.header = response.headers.get(Remote._SessionHeader);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
return response.json();
|
|
|
|
})
|
|
|
|
.then((payload) => {
|
|
|
|
if (callback) {
|
|
|
|
callback.call(context, payload, response_argument);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
if (error.message === Remote._SessionHeader) {
|
|
|
|
// copy the session header and try again
|
|
|
|
this._session_id = error.header;
|
|
|
|
this.sendRequest(data, callback, context);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
console.trace(error);
|
|
|
|
this._controller.togglePeriodicSessionRefresh(false);
|
|
|
|
this._controller.setCurrentPopup(
|
|
|
|
new AlertDialog({
|
|
|
|
heading: 'Connection failed',
|
|
|
|
message:
|
|
|
|
'Could not connect to the server. You may need to reload the page to reconnect.',
|
|
|
|
})
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: return a Promise
|
|
|
|
loadDaemonPrefs(callback, context) {
|
|
|
|
const o = {
|
|
|
|
method: 'session-get',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
checkPort(callback, context) {
|
|
|
|
const o = {
|
|
|
|
method: 'port-test',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
renameTorrent(torrentIds, oldpath, newname, callback, context) {
|
|
|
|
const o = {
|
|
|
|
arguments: {
|
|
|
|
ids: torrentIds,
|
|
|
|
name: newname,
|
|
|
|
path: oldpath,
|
|
|
|
},
|
|
|
|
method: 'torrent-rename-path',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
loadDaemonStats(callback, context) {
|
|
|
|
const o = {
|
|
|
|
method: 'session-stats',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
updateTorrents(torrentIds, fields, callback, context) {
|
|
|
|
const o = {
|
|
|
|
arguments: {
|
|
|
|
fields,
|
|
|
|
format: 'table',
|
|
|
|
},
|
|
|
|
method: 'torrent-get',
|
|
|
|
};
|
|
|
|
if (torrentIds) {
|
|
|
|
o.arguments.ids = torrentIds;
|
|
|
|
}
|
|
|
|
this.sendRequest(o, (response) => {
|
|
|
|
const arguments_ = response['arguments'];
|
|
|
|
callback.call(context, arguments_.torrents, arguments_.removed);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
getFreeSpace(dir, callback, context) {
|
|
|
|
const o = {
|
|
|
|
arguments: {
|
|
|
|
path: dir,
|
|
|
|
},
|
|
|
|
method: 'free-space',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, (response) => {
|
|
|
|
const arguments_ = response['arguments'];
|
|
|
|
callback.call(context, arguments_.path, arguments_['size-bytes']);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
changeFileCommand(torrentId, fileIndices, command) {
|
|
|
|
const arguments_ = {
|
|
|
|
ids: [torrentId],
|
|
|
|
};
|
|
|
|
arguments_[command] = fileIndices;
|
|
|
|
this.sendRequest(
|
|
|
|
{
|
|
|
|
arguments: arguments_,
|
|
|
|
method: 'torrent-set',
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
this._controller.refreshTorrents([torrentId]);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendTorrentSetRequests(method, torrent_ids, arguments_, callback, context) {
|
|
|
|
if (!arguments_) {
|
|
|
|
arguments_ = {};
|
|
|
|
}
|
|
|
|
arguments_['ids'] = torrent_ids;
|
|
|
|
const o = {
|
|
|
|
arguments: arguments_,
|
|
|
|
method,
|
|
|
|
};
|
|
|
|
this.sendRequest(o, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
sendTorrentActionRequests(method, torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentSetRequests(method, torrent_ids, null, callback, context);
|
|
|
|
}
|
|
|
|
|
|
|
|
startTorrents(torrent_ids, noqueue, callback, context) {
|
|
|
|
const name = noqueue ? 'torrent-start-now' : 'torrent-start';
|
|
|
|
this.sendTorrentActionRequests(name, torrent_ids, callback, context);
|
|
|
|
}
|
|
|
|
stopTorrents(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
'torrent-stop',
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
moveTorrents(torrent_ids, new_location, callback, context) {
|
|
|
|
this.sendTorrentSetRequests(
|
|
|
|
'torrent-set-location',
|
|
|
|
torrent_ids,
|
|
|
|
{
|
|
|
|
location: new_location,
|
|
|
|
move: true,
|
|
|
|
},
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
removeTorrents(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
'torrent-remove',
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
removeTorrentsAndData(torrents) {
|
|
|
|
const o = {
|
|
|
|
arguments: {
|
|
|
|
'delete-local-data': true,
|
|
|
|
ids: [],
|
|
|
|
},
|
|
|
|
method: 'torrent-remove',
|
|
|
|
};
|
|
|
|
|
|
|
|
if (torrents) {
|
|
|
|
for (let index = 0, length_ = torrents.length; index < length_; ++index) {
|
|
|
|
o.arguments.ids.push(torrents[index].getId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.sendRequest(o, () => {
|
|
|
|
this._controller.refreshTorrents();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
verifyTorrents(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
'torrent-verify',
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
reannounceTorrents(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
'torrent-reannounce',
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
addTorrentByUrl(url, options) {
|
|
|
|
if (url.match(/^[\da-f]{40}$/i)) {
|
|
|
|
url = `magnet:?xt=urn:btih:${url}`;
|
|
|
|
}
|
|
|
|
const o = {
|
|
|
|
arguments: {
|
|
|
|
filename: url,
|
|
|
|
paused: options.paused,
|
|
|
|
},
|
|
|
|
method: 'torrent-add',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, () => {
|
|
|
|
this._controller.refreshTorrents();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
savePrefs(arguments_) {
|
|
|
|
const o = {
|
|
|
|
arguments: arguments_,
|
|
|
|
method: 'session-set',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, () => {
|
|
|
|
this._controller.loadDaemonPrefs();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
updateBlocklist() {
|
|
|
|
const o = {
|
|
|
|
method: 'blocklist-update',
|
|
|
|
};
|
|
|
|
this.sendRequest(o, () => {
|
|
|
|
this._controller.loadDaemonPrefs();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Added queue calls
|
|
|
|
moveTorrentsToTop(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
RPC._QueueMoveTop,
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
moveTorrentsToBottom(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
RPC._QueueMoveBottom,
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
moveTorrentsUp(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
RPC._QueueMoveUp,
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
moveTorrentsDown(torrent_ids, callback, context) {
|
|
|
|
this.sendTorrentActionRequests(
|
|
|
|
RPC._QueueMoveDown,
|
|
|
|
torrent_ids,
|
|
|
|
callback,
|
|
|
|
context
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Remote._SessionHeader = 'X-Transmission-Session-Id';
|