mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-14 16:57:55 +00:00
- Web UI: Display generation information in torrent properties
This commit is contained in:
parent
ce6f665a7b
commit
e35d100769
@ -32,6 +32,7 @@
|
|||||||
#include "eventmanager.h"
|
#include "eventmanager.h"
|
||||||
#include "bittorrent.h"
|
#include "bittorrent.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "torrentpersistentdata.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
EventManager::EventManager(QObject *parent, Bittorrent *BTSession)
|
EventManager::EventManager(QObject *parent, Bittorrent *BTSession)
|
||||||
@ -43,6 +44,51 @@ QList<QVariantMap> EventManager::getEventList() const {
|
|||||||
return event_list.values();
|
return event_list.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap EventManager::getPropGeneralInfo(QString hash) const {
|
||||||
|
QVariantMap data;
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
if(h.is_valid()) {
|
||||||
|
// Save path
|
||||||
|
data["save_path"] = TorrentPersistentData::getSavePath(hash);
|
||||||
|
// Creation date
|
||||||
|
data["creation_date"] = h.creation_date();
|
||||||
|
// Comment
|
||||||
|
data["comment"] = h.comment();
|
||||||
|
data["total_wasted"] = misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes());
|
||||||
|
data["total_uploaded"] = misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")";
|
||||||
|
data["total_downloaded"] = misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")";
|
||||||
|
if(h.upload_limit() <= 0)
|
||||||
|
data["up_limit"] = QString::fromUtf8("∞");
|
||||||
|
else
|
||||||
|
data["up_limit"] = misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)");
|
||||||
|
if(h.download_limit() <= 0)
|
||||||
|
data["dl_limit"] = QString::fromUtf8("∞");
|
||||||
|
else
|
||||||
|
data["dl_limit"] = misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)");
|
||||||
|
QString elapsed_txt = misc::userFriendlyDuration(h.active_time());
|
||||||
|
if(h.is_seed()) {
|
||||||
|
elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")";
|
||||||
|
}
|
||||||
|
data["time_elapsed"] = elapsed_txt;
|
||||||
|
data["nb_connections"] = QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")";
|
||||||
|
// Update ratio info
|
||||||
|
float ratio;
|
||||||
|
if(h.total_payload_download() == 0){
|
||||||
|
if(h.total_payload_upload() == 0)
|
||||||
|
ratio = 1.;
|
||||||
|
else
|
||||||
|
ratio = 10.; // Max ratio
|
||||||
|
}else{
|
||||||
|
ratio = (double)h.total_payload_upload()/(double)h.total_payload_download();
|
||||||
|
if(ratio > 10.){
|
||||||
|
ratio = 10.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data["share_ratio"] = QString(QByteArray::number(ratio, 'f', 1));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
void EventManager::addedTorrent(QTorrentHandle& h)
|
void EventManager::addedTorrent(QTorrentHandle& h)
|
||||||
{
|
{
|
||||||
modifiedTorrent(h);
|
modifiedTorrent(h);
|
||||||
|
@ -51,6 +51,7 @@ class EventManager : public QObject
|
|||||||
public:
|
public:
|
||||||
EventManager(QObject *parent, Bittorrent* BTSession);
|
EventManager(QObject *parent, Bittorrent* BTSession);
|
||||||
QList<QVariantMap> getEventList() const;
|
QList<QVariantMap> getEventList() const;
|
||||||
|
QVariantMap getPropGeneralInfo(QString hash) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addedTorrent(QTorrentHandle& h);
|
void addedTorrent(QTorrentHandle& h);
|
||||||
|
@ -147,7 +147,7 @@ void HttpConnection::respond()
|
|||||||
}
|
}
|
||||||
if (list.size() == 0)
|
if (list.size() == 0)
|
||||||
list.append("index.html");
|
list.append("index.html");
|
||||||
if (list.size() == 2)
|
if (list.size() >= 2)
|
||||||
{
|
{
|
||||||
if (list[0] == "json")
|
if (list[0] == "json")
|
||||||
{
|
{
|
||||||
@ -156,6 +156,14 @@ void HttpConnection::respond()
|
|||||||
respondJson();
|
respondJson();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(list.size() > 2) {
|
||||||
|
if(list[1] == "propertiesGeneral") {
|
||||||
|
qDebug("Web UI Asked for general properties data");
|
||||||
|
QString hash = list[2];
|
||||||
|
respondGenPropertiesJson(hash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (list[0] == "command")
|
if (list[0] == "command")
|
||||||
{
|
{
|
||||||
@ -210,6 +218,17 @@ void HttpConnection::respondJson()
|
|||||||
write();
|
write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpConnection::respondGenPropertiesJson(QString hash) {
|
||||||
|
qDebug("Torrent hash is %s", hash.toLocal8Bit().data());
|
||||||
|
EventManager* manager = parent->eventManager();
|
||||||
|
QString string = json::toJson(manager->getPropGeneralInfo(hash));
|
||||||
|
qDebug("GenProperties JSON is %s", string.toLocal8Bit().data());
|
||||||
|
generator.setStatusLine(200, "OK");
|
||||||
|
generator.setContentTypeByExt("js");
|
||||||
|
generator.setMessage(string);
|
||||||
|
write();
|
||||||
|
}
|
||||||
|
|
||||||
void HttpConnection::respondCommand(QString command)
|
void HttpConnection::respondCommand(QString command)
|
||||||
{
|
{
|
||||||
if(command == "download")
|
if(command == "download")
|
||||||
|
@ -56,6 +56,7 @@ class HttpConnection : public QObject
|
|||||||
void write();
|
void write();
|
||||||
virtual void respond();
|
virtual void respond();
|
||||||
void respondJson();
|
void respondJson();
|
||||||
|
void respondGenPropertiesJson(QString hash);
|
||||||
void respondCommand(QString command);
|
void respondCommand(QString command);
|
||||||
void respondNotFound();
|
void respondNotFound();
|
||||||
void processDownloadedFile(QString, QString);
|
void processDownloadedFile(QString, QString);
|
||||||
|
94
src/json.h
94
src/json.h
@ -36,71 +36,79 @@
|
|||||||
|
|
||||||
namespace json {
|
namespace json {
|
||||||
|
|
||||||
QString toJson(QVariant v) {
|
QString toJson(QVariant v) {
|
||||||
if (v.isNull())
|
if (v.isNull())
|
||||||
return "null";
|
return "null";
|
||||||
switch(v.type())
|
switch(v.type())
|
||||||
{
|
{
|
||||||
case QVariant::Bool:
|
case QVariant::Bool:
|
||||||
case QVariant::Double:
|
case QVariant::Double:
|
||||||
case QVariant::Int:
|
case QVariant::Int:
|
||||||
case QVariant::LongLong:
|
case QVariant::LongLong:
|
||||||
case QVariant::UInt:
|
case QVariant::UInt:
|
||||||
case QVariant::ULongLong:
|
case QVariant::ULongLong:
|
||||||
return v.value<QString>();
|
return v.value<QString>();
|
||||||
case QVariant::String:
|
case QVariant::String:
|
||||||
{
|
{
|
||||||
QString s = v.value<QString>();
|
QString s = v.value<QString>();
|
||||||
QString result = "\"";
|
QString result = "\"";
|
||||||
for(int i=0; i<s.size(); i++)
|
for(int i=0; i<s.size(); i++)
|
||||||
{
|
{
|
||||||
QChar ch = s[i];
|
QChar ch = s[i];
|
||||||
switch(ch.toAscii())
|
switch(ch.toAscii())
|
||||||
{
|
{
|
||||||
case '\b':
|
case '\b':
|
||||||
result += "\\b";
|
result += "\\b";
|
||||||
break;
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
result += "\\f";
|
result += "\\f";
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
result += "\\n";
|
result += "\\n";
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
result += "\\r";
|
result += "\\r";
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
result += "\\t";
|
result += "\\t";
|
||||||
break;
|
break;
|
||||||
case '\"':
|
case '\"':
|
||||||
case '\'':
|
case '\'':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '&':
|
case '&':
|
||||||
result += '\\';
|
result += '\\';
|
||||||
case '\0':
|
case '\0':
|
||||||
default:
|
default:
|
||||||
result += ch;
|
result += ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += "\"";
|
result += "\"";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return "undefined";
|
return "undefined";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString toJson(QList<QVariantMap> v) {
|
QString toJson(QVariantMap m) {
|
||||||
QStringList res;
|
QStringList vlist;
|
||||||
foreach(QVariantMap m, v) {
|
foreach(QString key, m.keys()) {
|
||||||
QStringList vlist;
|
vlist << toJson(key)+":"+toJson(m[key]);
|
||||||
foreach(QString key, m.keys()) {
|
|
||||||
vlist << toJson(key)+":"+toJson(m[key]);
|
|
||||||
}
|
|
||||||
res << "{"+vlist.join(",")+"}";
|
|
||||||
}
|
|
||||||
return "["+res.join(",")+"]";
|
|
||||||
}
|
}
|
||||||
|
return "{"+vlist.join(",")+"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString toJson(QList<QVariantMap> v) {
|
||||||
|
QStringList res;
|
||||||
|
foreach(QVariantMap m, v) {
|
||||||
|
QStringList vlist;
|
||||||
|
foreach(QString key, m.keys()) {
|
||||||
|
vlist << toJson(key)+":"+toJson(m[key]);
|
||||||
|
}
|
||||||
|
res << "{"+vlist.join(",")+"}";
|
||||||
|
}
|
||||||
|
return "["+res.join(",")+"]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,26 +1,100 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><b>_(Transfer)</b></legend>
|
<legend><b>_(Transfer)</b></legend>
|
||||||
<table>
|
<table>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Uploaded:)</td><td>0 Kb</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Uploaded:)</td><td style="padding-right: 20px;" id="total_uploaded">0 Kb</td><td style="text-align:right; padding: 4px;">_(UP limit:)</td><td style="padding-right: 20px;" id="up_limit">xx</td><td style="text-align:right; padding: 4px;">_(Share ratio:)</td><td id="share_ratio">xx</td></tr>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Downloaded:)</td><td>0 Kb</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Downloaded:)</td><td style="padding-right: 20px;" id="total_downloaded">0 Kb</td><td style="text-align:right; padding: 4px;">_(DL limit:)</td><td style="padding-right: 20px;" id="dl_limit">xx</td><td style="text-align:right; padding: 4px;">_(Connections:)</td><td id="nb_connections">xx</td></tr>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Wasted:)</td><td>0 Kb</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Wasted:)</td><td style="padding-right: 20px;" id="total_wasted">0 Kb</td><td style="text-align:right; padding: 4px;">_(Time elapsed:)</td><td style="padding-right: 20px;" id="time_elapsed">xx</td><td></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><b>_(Information)</b></legend>
|
<legend><b>_(Information)</b></legend>
|
||||||
<table>
|
<table>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Save path:)</td><td>xxx</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Save path:)</td><td id="save_path">xxx</td></tr>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Created on:)</td><td>xxx</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Created on:)</td><td id="creation_date">xxx</td></tr>
|
||||||
<tr><td style="text-align:right; padding: 4px;">_(Torrent hash:)</td><td>xxx</td></tr>
|
<tr><td style="text-align:right; padding: 4px;">_(Torrent hash:)</td><td id="torrent_hash">xxx</td></tr>
|
||||||
<tr><td style="vertical-align: top; padding: 4px; text-align:right;">
|
<tr><td style="vertical-align: top; padding: 4px; text-align:right;">
|
||||||
<br/>
|
<br/>
|
||||||
_(Comment:)
|
_(Comment:)
|
||||||
</td><td>
|
</td><td>
|
||||||
<textarea name="comments" id="comments" rows="15" cols="80">
|
<textarea name="comment" id="comment" rows="15" cols="80">
|
||||||
xxx
|
xxx
|
||||||
</textarea>
|
</textarea>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
static information: save_path, creation_date, torrent_hash, comment
|
||||||
|
|
||||||
|
dynamic information: total_downloaded, total_uploaded, total_wasted, up_limit, dl_limit, time_elapsed, share_ratio, nb_connections
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var waiting=false;
|
||||||
|
|
||||||
|
var clearData = function() {
|
||||||
|
$('torrent_hash').set('html', '');
|
||||||
|
$('save_path').set('html', '');
|
||||||
|
$('creation_date').set('html', '');
|
||||||
|
$('comment').set('html', '');
|
||||||
|
$('total_uploaded').set('html', '');
|
||||||
|
$('total_downloaded').set('html', '');
|
||||||
|
$('total_wasted').set('html', '');
|
||||||
|
$('up_limit').set('html', '');
|
||||||
|
$('dl_limit').set('html', '');
|
||||||
|
$('time_elapsed').set('html', '');
|
||||||
|
$('nb_connections').set('html', '');
|
||||||
|
$('share_ratio').set('html', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadData = function() {
|
||||||
|
var current_hash = myTable.getCurrentTorrentHash();
|
||||||
|
if(current_hash == "") {
|
||||||
|
clearData();
|
||||||
|
loadData.delay(2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Display hash
|
||||||
|
$('torrent_hash').set('html', current_hash);
|
||||||
|
var url = 'json/propertiesGeneral/'+current_hash;
|
||||||
|
if (!waiting) {
|
||||||
|
waiting=true;
|
||||||
|
var request = new Request.JSON({
|
||||||
|
url: url,
|
||||||
|
method: 'get',
|
||||||
|
onFailure: function() {
|
||||||
|
$('error_div').set('html', 'qBittorrent client is not reachable');
|
||||||
|
waiting=false;
|
||||||
|
loadData.delay(2000);
|
||||||
|
},
|
||||||
|
onSuccess: function(data) {
|
||||||
|
$('error_div').set('html', '');
|
||||||
|
if(data){
|
||||||
|
// Update Torrent data
|
||||||
|
$('save_path').set('html', data.save_path);
|
||||||
|
$('creation_date').set('html', data.creation_date);
|
||||||
|
$('comment').set('html', data.comment);
|
||||||
|
$('total_uploaded').set('html', data.total_uploaded);
|
||||||
|
$('total_downloaded').set('html', data.total_downloaded);
|
||||||
|
$('total_wasted').set('html', data.total_wasted);
|
||||||
|
$('up_limit').set('html', data.up_limit);
|
||||||
|
$('dl_limit').set('html', data.dl_limit);
|
||||||
|
$('time_elapsed').set('html', data.time_elapsed);
|
||||||
|
$('nb_connections').set('html', data.nb_connections);
|
||||||
|
$('share_ratio').set('html', data.share_ratio);
|
||||||
|
} else {
|
||||||
|
clearData();
|
||||||
|
}
|
||||||
|
waiting=false;
|
||||||
|
loadData.delay(2000);
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Initial loading
|
||||||
|
loadData();
|
||||||
|
</script>
|
@ -160,7 +160,7 @@ window.addEvent('domready', function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
waiting=false;
|
waiting=false;
|
||||||
ajaxfn.delay(1000);
|
ajaxfn.delay(1500);
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,13 @@ var dynamicTable = new Class ({
|
|||||||
this.priority_hidden = false;
|
this.priority_hidden = false;
|
||||||
this.progressIndex = progressIndex;
|
this.progressIndex = progressIndex;
|
||||||
this.filter = 'all';
|
this.filter = 'all';
|
||||||
|
this.current_hash = '';
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentTorrentHash: function() {
|
||||||
|
if(this.cur.length > 0)
|
||||||
|
return this.cur[0];
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
altRow: function()
|
altRow: function()
|
||||||
@ -200,6 +207,7 @@ var dynamicTable = new Class ({
|
|||||||
temptr.addClass('selected');
|
temptr.addClass('selected');
|
||||||
}
|
}
|
||||||
this.cur[0] = id;
|
this.cur[0] = id;
|
||||||
|
// TODO: Warn Properties panel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user