mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-25 18:56:34 +03:00
Merge pull request #8598 from Piccirello/limit-share-ratio
WebUI Add Limit Share Ratio context menu option
This commit is contained in:
commit
a70942ed53
12 changed files with 245 additions and 8 deletions
|
@ -120,7 +120,10 @@ QVariantMap serialize(const BitTorrent::TorrentHandle &torrent)
|
|||
ret[KEY_TORRENT_AMOUNT_UPLOADED_SESSION] = torrent.totalPayloadUpload();
|
||||
ret[KEY_TORRENT_AMOUNT_LEFT] = torrent.incompletedSize();
|
||||
ret[KEY_TORRENT_AMOUNT_COMPLETED] = torrent.completedSize();
|
||||
ret[KEY_TORRENT_RATIO_LIMIT] = torrent.maxRatio();
|
||||
ret[KEY_TORRENT_MAX_RATIO] = torrent.maxRatio();
|
||||
ret[KEY_TORRENT_MAX_SEEDING_TIME] = torrent.maxSeedingTime();
|
||||
ret[KEY_TORRENT_RATIO_LIMIT] = torrent.ratioLimit();
|
||||
ret[KEY_TORRENT_SEEDING_TIME_LIMIT] = torrent.seedingTimeLimit();
|
||||
ret[KEY_TORRENT_LAST_SEEN_COMPLETE_TIME] = torrent.lastSeenComplete().toTime_t();
|
||||
ret[KEY_TORRENT_AUTO_TORRENT_MANAGEMENT] = torrent.isAutoTMMEnabled();
|
||||
ret[KEY_TORRENT_TIME_ACTIVE] = torrent.activeTime();
|
||||
|
|
|
@ -69,7 +69,10 @@ const char KEY_TORRENT_AMOUNT_DOWNLOADED_SESSION[] = "downloaded_session";
|
|||
const char KEY_TORRENT_AMOUNT_UPLOADED_SESSION[] = "uploaded_session";
|
||||
const char KEY_TORRENT_AMOUNT_LEFT[] = "amount_left";
|
||||
const char KEY_TORRENT_AMOUNT_COMPLETED[] = "completed";
|
||||
const char KEY_TORRENT_MAX_RATIO[] = "max_ratio";
|
||||
const char KEY_TORRENT_MAX_SEEDING_TIME[] = "max_seeding_time";
|
||||
const char KEY_TORRENT_RATIO_LIMIT[] = "ratio_limit";
|
||||
const char KEY_TORRENT_SEEDING_TIME_LIMIT[] = "seeding_time_limit";
|
||||
const char KEY_TORRENT_LAST_SEEN_COMPLETE_TIME[] = "seen_complete";
|
||||
const char KEY_TORRENT_LAST_ACTIVITY_TIME[] = "last_activity";
|
||||
const char KEY_TORRENT_TOTAL_SIZE[] = "total_size";
|
||||
|
|
|
@ -351,7 +351,10 @@ namespace
|
|||
// - "amount_left": Amount of data left to download
|
||||
// - "save_path": Torrent save path
|
||||
// - "completed": Amount of data completed
|
||||
// - "max_ratio": Upload max share ratio
|
||||
// - "max_seeding_time": Upload max seeding time
|
||||
// - "ratio_limit": Upload share ratio limit
|
||||
// - "seeding_time_limit": Upload seeding time limit
|
||||
// - "seen_complete": Indicates the time when the torrent was last seen complete/whole
|
||||
// - "last_activity": Last time when a chunk was downloaded/uploaded
|
||||
// - "total_size": Size including unwanted data
|
||||
|
|
|
@ -623,6 +623,21 @@ void TorrentsController::setDownloadLimitAction()
|
|||
applyToTorrents(hashes, [limit](BitTorrent::TorrentHandle *torrent) { torrent->setDownloadLimit(limit); });
|
||||
}
|
||||
|
||||
void TorrentsController::setShareLimitsAction()
|
||||
{
|
||||
checkParams({"hashes", "ratioLimit", "seedingTimeLimit"});
|
||||
|
||||
const qreal ratioLimit = params()["ratioLimit"].toDouble();
|
||||
const qlonglong seedingTimeLimit = params()["seedingTimeLimit"].toLongLong();
|
||||
const QStringList hashes = params()["hashes"].split('|');
|
||||
|
||||
applyToTorrents(hashes, [ratioLimit, seedingTimeLimit](BitTorrent::TorrentHandle *torrent)
|
||||
{
|
||||
torrent->setRatioLimit(ratioLimit);
|
||||
torrent->setSeedingTimeLimit(seedingTimeLimit);
|
||||
});
|
||||
}
|
||||
|
||||
void TorrentsController::toggleSequentialDownloadAction()
|
||||
{
|
||||
checkParams({"hashes"});
|
||||
|
|
|
@ -61,6 +61,7 @@ private slots:
|
|||
void downloadLimitAction();
|
||||
void setUploadLimitAction();
|
||||
void setDownloadLimitAction();
|
||||
void setShareLimitsAction();
|
||||
void increasePrioAction();
|
||||
void decreasePrioAction();
|
||||
void topPrioAction();
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
<file>www/private/scripts/prop-trackers.js</file>
|
||||
<file>www/private/scripts/prop-webseeds.js</file>
|
||||
<file>www/private/setlocation.html</file>
|
||||
<file>www/private/shareratio.html</file>
|
||||
<file>www/private/statistics.html</file>
|
||||
<file>www/private/transferlist.html</file>
|
||||
<file>www/private/upload.html</file>
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
</li>
|
||||
<li class="separator"><a href="#DownloadLimit"><img src="theme/kt-set-max-download-speed" alt="QBT_TR(Limit download rate...)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Limit download rate...)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
<li><a href="#UploadLimit"><img src="theme/kt-set-max-upload-speed" alt="QBT_TR(Limit upload rate...)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Limit upload rate...)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
<li><a href="#ShareRatio"><img src="images/skin/ratio.png" alt="QBT_TR(Limit share ratio...)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Limit share ratio...)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
<li><a href="#SuperSeeding"><img src="theme/checked" alt="QBT_TR(Super seeding mode)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Super seeding mode)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
<li class="separator"><a href="#SequentialDownload"><img src="theme/checked" alt="QBT_TR(Download in sequential order)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Download in sequential order)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
<li><a href="#FirstLastPiecePrio"><img src="theme/checked" alt="QBT_TR(Download first and last pieces first)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Download first and last pieces first)QBT_TR[CONTEXT=TransferListWidget]</a></li>
|
||||
|
|
|
@ -769,7 +769,7 @@ var TorrentsTable = new Class({
|
|||
this.newColumn('time_active', '', 'QBT_TR(Time Active)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('save_path', '', 'QBT_TR(Save path)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('completed', '', 'QBT_TR(Completed)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('ratio_limit', '', 'QBT_TR(Ratio Limit)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('max_ratio', '', 'QBT_TR(Ratio Limit)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('seen_complete', '', 'QBT_TR(Last Seen Complete)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
this.newColumn('last_activity', '', 'QBT_TR(Last Activity)QBT_TR[CONTEXT=TorrentModel]', 100, false);
|
||||
|
||||
|
@ -1076,8 +1076,8 @@ var TorrentsTable = new Class({
|
|||
this.columns['save_path'].updateTd = this.columns['name'].updateTd;
|
||||
this.columns['tracker'].updateTd = this.columns['name'].updateTd;
|
||||
|
||||
// ratio_limit
|
||||
this.columns['ratio_limit'].updateTd = this.columns['ratio'].updateTd;
|
||||
// max_ratio
|
||||
this.columns['max_ratio'].updateTd = this.columns['ratio'].updateTd;
|
||||
|
||||
// last_activity
|
||||
this.columns['last_activity'].updateTd = function(td, row) {
|
||||
|
|
|
@ -76,6 +76,10 @@ function friendlyPercentage(value) {
|
|||
return percentage.toFixed(1) + "%";
|
||||
}
|
||||
|
||||
function friendlyFloat(value, precision) {
|
||||
return parseFloat(value).toFixed(precision);
|
||||
}
|
||||
|
||||
/*
|
||||
* From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
*/
|
||||
|
|
|
@ -146,7 +146,6 @@ initializeWindows = function() {
|
|||
uploadLimitFN = function() {
|
||||
var hashes = torrentsTable.selectedRowsIds();
|
||||
if (hashes.length) {
|
||||
var hash = hashes[0];
|
||||
new MochaUI.Window({
|
||||
id: 'uploadLimitPage',
|
||||
title: "QBT_TR(Torrent Upload Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
|
||||
|
@ -163,6 +162,45 @@ initializeWindows = function() {
|
|||
}
|
||||
};
|
||||
|
||||
shareRatioFN = function() {
|
||||
var hashes = torrentsTable.selectedRowsIds();
|
||||
if (hashes.length) {
|
||||
var shareRatio = null;
|
||||
var torrentsHaveSameShareRatio = true;
|
||||
|
||||
// check if all selected torrents have same share ratio
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
var hash = hashes[i];
|
||||
var row = torrentsTable.rows[hash].full_data;
|
||||
var origValues = row.ratio_limit + "|" + row.seeding_time_limit + "|" + row.max_ratio + "|" + row.max_seeding_time;
|
||||
|
||||
// initialize value
|
||||
if (shareRatio === null)
|
||||
shareRatio = origValues;
|
||||
|
||||
if (origValues !== shareRatio) {
|
||||
torrentsHaveSameShareRatio = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if all torrents have same share ratio, display that share ratio. else use the default
|
||||
var orig = torrentsHaveSameShareRatio ? shareRatio : "";
|
||||
new MochaUI.Window({
|
||||
id: 'shareRatioPage',
|
||||
title: "QBT_TR(Torrent Upload/Download Ratio Limiting)QBT_TR[CONTEXT=UpDownRatioDlg]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'shareratio.html?hashes=' + hashes.join("|") + '&orig=' + orig,
|
||||
scrollbars: false,
|
||||
maximizable: false,
|
||||
paddingVertical: 0,
|
||||
paddingHorizontal: 0,
|
||||
width: 424,
|
||||
height: 175
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
toggleSequentialDownloadFN = function() {
|
||||
var hashes = torrentsTable.selectedRowsIds();
|
||||
if (hashes.length) {
|
||||
|
@ -257,7 +295,6 @@ initializeWindows = function() {
|
|||
downloadLimitFN = function() {
|
||||
var hashes = torrentsTable.selectedRowsIds();
|
||||
if (hashes.length) {
|
||||
var hash = hashes[0];
|
||||
new MochaUI.Window({
|
||||
id: 'downloadLimitPage',
|
||||
title: "QBT_TR(Torrent Download Speed Limiting)QBT_TR[CONTEXT=TransferListWidget]",
|
||||
|
@ -388,12 +425,11 @@ initializeWindows = function() {
|
|||
var hash = hashes[0];
|
||||
var row = torrentsTable.rows[hash];
|
||||
if (row) {
|
||||
var name = row.full_data.name;
|
||||
new MochaUI.Window({
|
||||
id: 'renamePage',
|
||||
title: "QBT_TR(Rename)QBT_TR[CONTEXT=TransferListWidget]",
|
||||
loadMethod: 'iframe',
|
||||
contentURL: 'rename.html?hash=' + hashes[0] + '&name=' + name,
|
||||
contentURL: 'rename.html?hash=' + hashes[0] + '&name=' + row.full_data.name,
|
||||
scrollbars: false,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
|
|
167
src/webui/www/private/shareratio.html
Normal file
167
src/webui/www/private/shareratio.html
Normal file
|
@ -0,0 +1,167 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="${LANG}">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>QBT_TR(Torrent Upload/Download Ratio Limiting)QBT_TR[CONTEXT=UpDownRatioDlg]</title>
|
||||
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
||||
<script src="scripts/lib/mootools-1.2-core-yc.js"></script>
|
||||
<script src="scripts/lib/mootools-1.2-more.js"></script>
|
||||
<script src="scripts/misc.js"></script>
|
||||
<script>
|
||||
var UseGlobalLimit = -2;
|
||||
var NoLimit = -1;
|
||||
|
||||
var keyboardEvents = new Keyboard({
|
||||
defaultEventType: 'keydown',
|
||||
events: {
|
||||
'enter': function(event) {
|
||||
$('save').click();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
keyboardEvents.activate();
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var hashesList = new URI().getData('hashes').split('|');
|
||||
var origValues = new URI().getData('orig').split('|');
|
||||
|
||||
var values = {
|
||||
ratioLimit: friendlyFloat(origValues[0], 2),
|
||||
seedingTimeLimit: parseInt(origValues[1]),
|
||||
maxRatio: friendlyFloat(origValues[2], 2),
|
||||
maxSeedingTime: parseInt(origValues[3])
|
||||
};
|
||||
|
||||
// select default when orig values not passed. using double equals to compare string and int
|
||||
if ((origValues[0] === "") || ((values.ratioLimit == UseGlobalLimit) && (values.seedingTimeLimit == UseGlobalLimit))) {
|
||||
// use default option
|
||||
setSelectedRadioValue('shareLimit', 'default');
|
||||
}
|
||||
else if ((values.maxRatio == NoLimit) && (values.maxSeedingTime == NoLimit)) {
|
||||
setSelectedRadioValue('shareLimit', 'none');
|
||||
// TODO set input boxes to *global* max ratio and seeding time
|
||||
}
|
||||
else {
|
||||
setSelectedRadioValue('shareLimit', 'custom');
|
||||
if (values.ratioLimit >= 0) {
|
||||
$('setRatio').set('checked', true);
|
||||
$('ratio').set('value', values.ratioLimit);
|
||||
}
|
||||
if (values.seedingTimeLimit >= 0) {
|
||||
$('setMinutes').set('checked', true);
|
||||
$('minutes').set('value', values.seedingTimeLimit);
|
||||
}
|
||||
}
|
||||
|
||||
shareLimitChanged();
|
||||
|
||||
$('default').focus();
|
||||
$('save').addEvent('click', function(e) {
|
||||
new Event(e).stop();
|
||||
|
||||
if (!isFormValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var shareLimit = getSelectedRadioValue('shareLimit');
|
||||
var ratioLimitValue = 0.00;
|
||||
var seedingTimeLimitValue = 0;
|
||||
|
||||
if (shareLimit === 'default') {
|
||||
ratioLimitValue = seedingTimeLimitValue = UseGlobalLimit;
|
||||
}
|
||||
else if (shareLimit === 'none') {
|
||||
ratioLimitValue = seedingTimeLimitValue = NoLimit;
|
||||
}
|
||||
else if (shareLimit === 'custom') {
|
||||
ratioLimitValue = $('setRatio').get('checked') ? $('ratio').get('value') : -1;
|
||||
seedingTimeLimitValue = $('setMinutes').get('checked') ? $('minutes').get('value') : -1;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
new Request({
|
||||
url: 'api/v2/torrents/setShareLimits',
|
||||
method: 'post',
|
||||
data: {
|
||||
hashes: hashesList.join('|'),
|
||||
ratioLimit: ratioLimitValue,
|
||||
seedingTimeLimit: seedingTimeLimitValue
|
||||
},
|
||||
onComplete: function() {
|
||||
window.parent.closeWindows();
|
||||
}
|
||||
}).send();
|
||||
});
|
||||
});
|
||||
|
||||
function getSelectedRadioValue(name) {
|
||||
var radios = document.getElementsByName(name);
|
||||
|
||||
for (var i = 0; i < radios.length; ++i) {
|
||||
var radio = radios[i];
|
||||
if (radio.checked) {
|
||||
return (radio).get('value');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setSelectedRadioValue(name, value) {
|
||||
var radios = document.getElementsByName(name);
|
||||
|
||||
for (var i = 0; i < radios.length; ++i) {
|
||||
var radio = radios[i];
|
||||
if (radio.value === value)
|
||||
radio.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
function shareLimitChanged() {
|
||||
var customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
|
||||
$('setRatio').set('disabled', !customShareLimit);
|
||||
$('setMinutes').set('disabled', !customShareLimit);
|
||||
|
||||
enableInputBoxes();
|
||||
|
||||
$('save').set('disabled', !isFormValid());
|
||||
}
|
||||
|
||||
function enableInputBoxes() {
|
||||
$('ratio').set('disabled', ($('setRatio').get('disabled') || !$('setRatio').get('checked')));
|
||||
$('minutes').set('disabled', ($('setMinutes').get('disabled') || !$('setMinutes').get('checked')));
|
||||
|
||||
$('save').set('disabled', !isFormValid());
|
||||
}
|
||||
|
||||
function isFormValid() {
|
||||
return !((getSelectedRadioValue('shareLimit') === 'custom') && !$('setRatio').get('checked') && !$('setMinutes').get('checked'));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="padding: 10px 10px 0px 10px;">
|
||||
<input type="radio" name="shareLimit" id="default" value="default" onchange="shareLimitChanged()" checked style="margin-bottom: 5px;" />QBT_TR(Use global share limit)QBT_TR[CONTEXT=UpDownRatioDlg]</br>
|
||||
<input type="radio" name="shareLimit" value="none" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />QBT_TR(Set no share limit)QBT_TR[CONTEXT=UpDownRatioDlg]</br>
|
||||
<input type="radio" name="shareLimit" value="custom" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />QBT_TR(Set share limit to)QBT_TR[CONTEXT=UpDownRatioDlg]</br>
|
||||
|
||||
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||
<input type="checkbox" id="setRatio" class="shareLimitInput" onclick="enableInputBoxes()" />
|
||||
<label for="setRatio" class="leftLabelLarge">QBT_TR(ratio)QBT_TR[CONTEXT=UpDownRatioDlg]</label>
|
||||
<input type="number" id="ratio" value="0.00" step=".01" min="0" max="9999" class="shareLimitInput" />
|
||||
</div>
|
||||
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||
<input type="checkbox" id="setMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
||||
<label for="setMinutes" class="leftLabelLarge">QBT_TR(minutes)QBT_TR[CONTEXT=UpDownRatioDlg]</label>
|
||||
<input type="number" id="minutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
|
||||
</div>
|
||||
<div style="text-align: center; padding-top: 10px;">
|
||||
<input type="button" value="QBT_TR(Save)QBT_TR[CONTEXT=HttpServer]" id="save" />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -61,6 +61,9 @@
|
|||
UploadLimit: function(element, ref) {
|
||||
uploadLimitFN();
|
||||
},
|
||||
ShareRatio : function (element, ref) {
|
||||
shareRatioFN();
|
||||
},
|
||||
|
||||
SequentialDownload: function(element, ref) {
|
||||
toggleSequentialDownloadFN();
|
||||
|
|
Loading…
Reference in a new issue