Browse Source

- Disabled file prioritizing for seeding torrents

- Added file prioritizing to Web UI
adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
aeb2c06e0f
  1. 18
      src/eventmanager.cpp
  2. 9
      src/httpconnection.cpp
  3. 13
      src/propertieswidget.cpp
  4. 2
      src/propertieswidget.h
  5. 10
      src/proplistdelegate.h
  6. 3
      src/qtorrenthandle.cpp
  7. 2
      src/torrentfilesmodel.h
  8. 39
      src/transferlistwidget.cpp
  9. 1
      src/transferlistwidget.h
  10. 61
      src/webui/prop-files.html

18
src/eventmanager.cpp

@ -111,23 +111,7 @@ QList<QVariantMap> EventManager::getPropFilesInfo(QString hash) const {
} }
file["size"] = misc::friendlyUnit((double)fi->size); file["size"] = misc::friendlyUnit((double)fi->size);
file["progress"] = fp[i]/(double)fi->size; file["progress"] = fp[i]/(double)fi->size;
switch(priorities[i]) { file["priority"] = priorities[i];
case IGNORED:
file["priority"] = tr("Ignored");
break;
case NORMAL:
file["priority"] = tr("Normal", "Normal (priority)");
break;
case HIGH:
file["priority"] = tr("High", "High (priority)");
break;
case MAXIMUM:
file["priority"] = tr("Maximum", "Maximum (priority)");
break;
default:
qDebug("Unhandled priority, setting NORMAL, priority was %d", priorities[i]);
file["priority"] = tr("Normal", "Normal (priority)");
}
files << file; files << file;
++i; ++i;
} }

9
src/httpconnection.cpp

@ -310,6 +310,15 @@ void HttpConnection::respondCommand(QString command)
emit resumeTorrent(parser.post("hash")); emit resumeTorrent(parser.post("hash"));
return; return;
} }
if(command == "setFilePrio") {
QString hash = parser.post("hash");
int file_id = parser.post("id").toInt();
int priority = parser.post("priority").toInt();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) {
h.file_priority(file_id, priority);
}
}
if(command == "pause") { if(command == "pause") {
emit pauseTorrent(parser.post("hash")); emit pauseTorrent(parser.post("hash"));
return; return;

13
src/propertieswidget.cpp

@ -74,7 +74,7 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferLi
// Set Properties list model // Set Properties list model
PropListModel = new TorrentFilesModel(); PropListModel = new TorrentFilesModel();
filesList->setModel(PropListModel); filesList->setModel(PropListModel);
PropDelegate = new PropListDelegate(0); PropDelegate = new PropListDelegate(this);
filesList->setItemDelegate(PropDelegate); filesList->setItemDelegate(PropDelegate);
// QActions // QActions
@ -229,7 +229,6 @@ void PropertiesWidget::loadTorrentInfos(QTorrentHandle &_h) {
// List files in torrent // List files in torrent
PropListModel->clear(); PropListModel->clear();
PropListModel->setupModelData(h.get_torrent_info()); PropListModel->setupModelData(h.get_torrent_info());
PropListModel->updateFilesPriorities(h.file_priorities());
// Expand first item if possible // Expand first item if possible
filesList->expand(PropListModel->index(0, 0)); filesList->expand(PropListModel->index(0, 0));
} catch(invalid_handle e) { } catch(invalid_handle e) {
@ -359,6 +358,7 @@ void PropertiesWidget::loadDynamicData() {
std::vector<size_type> fp; std::vector<size_type> fp;
h.file_progress(fp); h.file_progress(fp);
PropListModel->updateFilesProgress(fp); PropListModel->updateFilesProgress(fp);
PropListModel->updateFilesPriorities(h.file_priorities());
} }
} catch(invalid_handle e) {} } catch(invalid_handle e) {}
} }
@ -550,13 +550,17 @@ void PropertiesWidget::deleteSelectedUrlSeeds(){
} }
} }
bool PropertiesWidget::savePiecesPriorities() { bool PropertiesWidget::applyPriorities() {
qDebug("Saving pieces priorities"); qDebug("Saving pieces priorities");
std::vector<int> priorities = PropListModel->getFilesPriorities(h.get_torrent_info().num_files()); std::vector<int> priorities = PropListModel->getFilesPriorities(h.get_torrent_info().num_files());
bool first_last_piece_first = false; bool first_last_piece_first = false;
// Save first/last piece first option state
if(h.first_last_piece_first()) if(h.first_last_piece_first())
first_last_piece_first = true; first_last_piece_first = true;
// Prioritize the files
qDebug("prioritize files: %d", priorities[0]);
h.prioritize_files(priorities); h.prioritize_files(priorities);
// Restore first/last piece first option if necessary
if(first_last_piece_first) if(first_last_piece_first)
h.prioritize_first_last_piece(true); h.prioritize_first_last_piece(true);
return true; return true;
@ -592,7 +596,6 @@ void PropertiesWidget::on_changeSavePathButton_clicked() {
void PropertiesWidget::filteredFilesChanged() { void PropertiesWidget::filteredFilesChanged() {
if(h.is_valid()) { if(h.is_valid()) {
savePiecesPriorities(); applyPriorities();
transferList->updateTorrentSizeAndProgress(h.hash());
} }
} }

2
src/propertieswidget.h

@ -76,7 +76,7 @@ private:
protected: protected:
QPushButton* getButtonFromIndex(int index); QPushButton* getButtonFromIndex(int index);
bool savePiecesPriorities(); bool applyPriorities();
protected slots: protected slots:
void loadTorrentInfos(QTorrentHandle &h); void loadTorrentInfos(QTorrentHandle &h);

10
src/proplistdelegate.h

@ -41,6 +41,7 @@
#include <QProgressBar> #include <QProgressBar>
#include <QApplication> #include <QApplication>
#include "misc.h" #include "misc.h"
#include "propertieswidget.h"
// Defines for properties list columns // Defines for properties list columns
enum PropColumn {NAME, SIZE, PROGRESS, PRIORITY}; enum PropColumn {NAME, SIZE, PROGRESS, PRIORITY};
@ -49,11 +50,14 @@ enum PropPriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7};
class PropListDelegate: public QItemDelegate { class PropListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
private:
PropertiesWidget *properties;
signals: signals:
void filteredFilesChanged() const; void filteredFilesChanged() const;
public: public:
PropListDelegate(QObject *parent=0) : QItemDelegate(parent){ PropListDelegate(PropertiesWidget* properties=0, QObject *parent=0) : QItemDelegate(parent), properties(properties){
} }
~PropListDelegate(){} ~PropListDelegate(){}
@ -116,6 +120,10 @@ public:
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index) const { QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index) const {
qDebug("CreateEditor called"); qDebug("CreateEditor called");
if(index.column() != PRIORITY) return 0; if(index.column() != PRIORITY) return 0;
if(properties) {
QTorrentHandle h = properties->getCurrentTorrent();
if(!h.is_valid() || h.is_seed()) return 0;
}
QComboBox* editor = new QComboBox(parent); QComboBox* editor = new QComboBox(parent);
editor->setFocusPolicy(Qt::StrongFocus); editor->setFocusPolicy(Qt::StrongFocus);
editor->addItem(tr("Ignored")); editor->addItem(tr("Ignored"));

3
src/qtorrenthandle.cpp

@ -470,7 +470,9 @@ void QTorrentHandle::set_max_connections(int val) {
} }
void QTorrentHandle::prioritize_files(std::vector<int> v) { void QTorrentHandle::prioritize_files(std::vector<int> v) {
// Does not do anything for seeding torrents
Q_ASSERT(h.is_valid()); Q_ASSERT(h.is_valid());
Q_ASSERT(v.size() == (unsigned int)h.get_torrent_info().num_files());
h.prioritize_files(v); h.prioritize_files(v);
} }
@ -528,6 +530,7 @@ void QTorrentHandle::move_storage(QString new_path) const {
void QTorrentHandle::file_priority(int index, int priority) const { void QTorrentHandle::file_priority(int index, int priority) const {
Q_ASSERT(h.is_valid()); Q_ASSERT(h.is_valid());
if(is_seed()) return;
h.file_priority(index, priority); h.file_priority(index, priority);
} }

2
src/torrentfilesmodel.h

@ -279,6 +279,7 @@ public:
void updateFilesPriorities(std::vector<int> fprio) { void updateFilesPriorities(std::vector<int> fprio) {
for(unsigned int i=0; i<fprio.size(); ++i) { for(unsigned int i=0; i<fprio.size(); ++i) {
qDebug("Called updateFilesPriorities with %d", fprio[i]);
files_index[i]->setPriority(fprio[i]); files_index[i]->setPriority(fprio[i]);
} }
emit layoutChanged(); emit layoutChanged();
@ -287,6 +288,7 @@ public:
std::vector<int> getFilesPriorities(unsigned int nbFiles) const { std::vector<int> getFilesPriorities(unsigned int nbFiles) const {
std::vector<int> prio; std::vector<int> prio;
for(unsigned int i=0; i<nbFiles; ++i) { for(unsigned int i=0; i<nbFiles; ++i) {
qDebug("Called getFilesPriorities: %d", files_index[i]->getPriority());
prio.push_back(files_index[i]->getPriority()); prio.push_back(files_index[i]->getPriority());
} }
return prio; return prio;

39
src/transferlistwidget.cpp

@ -259,6 +259,23 @@ int TransferListWidget::updateTorrent(int row) {
return s; return s;
} }
try { try {
// Connected_seeds*100000+total_seeds*10 (if total_seeds is available)
// Connected_seeds*100000+1 (if total_seeds is unavailable)
qulonglong seeds = h.num_seeds()*1000000;
if(h.num_complete() >= h.num_seeds())
seeds += h.num_complete()*10;
else
seeds += 1;
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(seeds));
qulonglong peers = (h.num_peers()-h.num_seeds())*1000000;
if(h.num_incomplete() >= (h.num_peers()-h.num_seeds()))
peers += h.num_incomplete()*10;
else
peers += 1;
listModel->setData(listModel->index(row, TR_PEERS), QVariant(peers));
// Update torrent size. It changes when files are filtered from torrent properties
// or Web UI
listModel->setData(listModel->index(row, TR_SIZE), QVariant((qlonglong)h.actual_size()));
// Queueing code // Queueing code
if(!h.is_seed() && BTSession->isQueueingEnabled()) { if(!h.is_seed() && BTSession->isQueueingEnabled()) {
listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)h.queue_position())); listModel->setData(listModel->index(row, TR_PRIORITY), QVariant((int)h.queue_position()));
@ -293,20 +310,7 @@ int TransferListWidget::updateTorrent(int row) {
return s; return s;
} }
} }
// Connected_seeds*100000+total_seeds*10 (if total_seeds is available)
// Connected_seeds*100000+1 (if total_seeds is unavailable)
qulonglong seeds = h.num_seeds()*1000000;
if(h.num_complete() >= h.num_seeds())
seeds += h.num_complete()*10;
else
seeds += 1;
listModel->setData(listModel->index(row, TR_SEEDS), QVariant(seeds));
qulonglong peers = (h.num_peers()-h.num_seeds())*1000000;
if(h.num_incomplete() >= (h.num_peers()-h.num_seeds()))
peers += h.num_incomplete()*10;
else
peers += 1;
listModel->setData(listModel->index(row, TR_PEERS), QVariant(peers));
if(h.is_paused()) { if(h.is_paused()) {
if(h.is_seed()) if(h.is_seed())
return STATE_PAUSED_UP; return STATE_PAUSED_UP;
@ -1098,10 +1102,3 @@ void TransferListWidget::applyFilter(int f) {
selectionModel()->setCurrentIndex(proxyModel->index(0, TR_NAME), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows); selectionModel()->setCurrentIndex(proxyModel->index(0, TR_NAME), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
} }
void TransferListWidget::updateTorrentSizeAndProgress(QString hash) {
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
QTorrentHandle h = BTSession->getTorrentHandle(hash);
listModel->setData(listModel->index(row, TR_SIZE), QVariant((qlonglong)h.actual_size()));
listModel->setData(listModel->index(row, TR_PROGRESS), QVariant((double)h.progress()));
}

1
src/transferlistwidget.h

@ -108,7 +108,6 @@ public slots:
void hidePriorityColumn(bool hide); void hidePriorityColumn(bool hide);
void displayDLHoSMenu(const QPoint&); void displayDLHoSMenu(const QPoint&);
void applyFilter(int f); void applyFilter(int f);
void updateTorrentSizeAndProgress(QString hash);
signals: signals:
void currentTorrentChanged(QTorrentHandle &h); void currentTorrentChanged(QTorrentHandle &h);

61
src/webui/prop-files.html

@ -13,6 +13,49 @@
</span> </span>
<script type="text/javascript"> <script type="text/javascript">
var round1 = function(val){return Math.round(val*10)/10};
var waitingTorrentFiles=false;
var current_hash = "";
var setFilePriority = function(id, priority) {
if(current_hash == "") return;
new Request({url: '/command/setFilePrio', method: 'post', data: {'hash': current_hash, 'id': id, 'priority': priority}}).send();
}
var createPriorityCombo = function(id, selected_prio) {
var select = new Element('select');
select.set('id', 'comboPrio'+id);
select.addEvent('change', function(e){
var new_prio = $('comboPrio'+id).get('value');
setFilePriority(id, new_prio);
});
var opt = new Element("option");
opt.set('value', '0')
opt.set('html', "_(Ignored)");
if(selected_prio == 0)
opt.setAttribute('selected', '');
opt.injectInside(select);
opt = new Element("option");
opt.set('value', '1')
opt.set('html', "_(Normal)");
if(selected_prio == 1)
opt.setAttribute('selected', '');
opt.injectInside(select);
opt = new Element("option");
opt.set('value', '2')
opt.set('html', "_(High)");
if(selected_prio == 2)
opt.setAttribute('selected', '');
opt.injectInside(select);
opt = new Element("option");
opt.set('value', '7')
opt.set('html', "_(Maximum)");
if(selected_prio == 7)
opt.setAttribute('selected', '');
opt.injectInside(select);
return select;
}
var filesDynTable = new Class ({ var filesDynTable = new Class ({
initialize: function(){ initialize: function(){
@ -46,7 +89,13 @@
tds[i].set('html', ''); tds[i].set('html', '');
tds[i].adopt(new ProgressBar(row[i].toFloat(), {width:80})); tds[i].adopt(new ProgressBar(row[i].toFloat(), {width:80}));
} else { } else {
tds[i].set('html', row[i]); if(i==3) {
tds[i].getChildren('select').set('value', row[i]);
//tds[i].set('html', '');
//tds[i].adopt(createPriorityCombo(id,row[i]));
} else {
tds[i].set('html', row[i]);
}
} }
} }
return true; return true;
@ -67,17 +116,17 @@
if(i==2) { if(i==2) {
td.adopt(new ProgressBar(row[i].toFloat(), {width:80})); td.adopt(new ProgressBar(row[i].toFloat(), {width:80}));
} else { } else {
td.set('html', row[i]); if(i == 3) {
td.adopt(createPriorityCombo(id,row[i]));
} else {
td.set('html', row[i]);
}
} }
td.injectInside(tr); td.injectInside(tr);
} }
tr.injectInside(this.table); tr.injectInside(this.table);
}, },
}); });
var round1 = function(val){return Math.round(val*10)/10};
var waitingTorrentFiles=false;
var current_hash = "";
var loadTorrentFilesData = function() { var loadTorrentFilesData = function() {
if(!$defined($('filesTable'))) { if(!$defined($('filesTable'))) {

Loading…
Cancel
Save