mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-10 05:44:25 +00:00
- Allow to download torrents from a local file (Web UI)
This commit is contained in:
parent
a4318cc060
commit
b9c4a434c9
@ -30,6 +30,7 @@
|
|||||||
#include <QHttpResponseHeader>
|
#include <QHttpResponseHeader>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
|
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
|
||||||
: QObject(parent), socket(socket), parent(parent)
|
: QObject(parent), socket(socket), parent(parent)
|
||||||
@ -45,11 +46,17 @@ HttpConnection::~HttpConnection()
|
|||||||
|
|
||||||
void HttpConnection::read()
|
void HttpConnection::read()
|
||||||
{
|
{
|
||||||
QString input = socket->readAll();
|
QByteArray input = socket->readAll();
|
||||||
qDebug(" -------");
|
qDebug(" -------");
|
||||||
qDebug("|REQUEST|");
|
qDebug("|REQUEST|");
|
||||||
qDebug(" -------");
|
qDebug(" -------");
|
||||||
qDebug("%s", input.toAscii().constData());
|
//qDebug("%s", input.toAscii().constData());
|
||||||
|
if(input.size() > 100000) {
|
||||||
|
qDebug("Request too big");
|
||||||
|
generator.setStatusLine(400, "Bad Request");
|
||||||
|
write();
|
||||||
|
return;
|
||||||
|
}
|
||||||
parser.write(input);
|
parser.write(input);
|
||||||
if(parser.isError())
|
if(parser.isError())
|
||||||
{
|
{
|
||||||
@ -74,6 +81,7 @@ void HttpConnection::write()
|
|||||||
|
|
||||||
void HttpConnection::respond()
|
void HttpConnection::respond()
|
||||||
{
|
{
|
||||||
|
qDebug("Respond called");
|
||||||
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
|
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
|
||||||
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
|
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
|
||||||
{
|
{
|
||||||
@ -176,6 +184,25 @@ void HttpConnection::respondCommand(QString command)
|
|||||||
emit urlsReadyToBeDownloaded(url_list_cleaned);
|
emit urlsReadyToBeDownloaded(url_list_cleaned);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(command == "upload")
|
||||||
|
{
|
||||||
|
QByteArray torrentfile = parser.torrent();
|
||||||
|
// XXX: Trick to get a unique filename
|
||||||
|
QString filePath;
|
||||||
|
QTemporaryFile *tmpfile = new QTemporaryFile();
|
||||||
|
if (tmpfile->open()) {
|
||||||
|
filePath = tmpfile->fileName();
|
||||||
|
}
|
||||||
|
delete tmpfile;
|
||||||
|
// write it to HD
|
||||||
|
QFile torrent(filePath);
|
||||||
|
if(torrent.open(QIODevice::WriteOnly)) {
|
||||||
|
torrent.write(torrentfile);
|
||||||
|
torrent.close();
|
||||||
|
}
|
||||||
|
emit torrentReadyToBeDownloaded(filePath, false, QString(), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(command == "resumeall")
|
if(command == "resumeall")
|
||||||
{
|
{
|
||||||
emit resumeAllTorrents();
|
emit resumeAllTorrents();
|
||||||
|
@ -57,6 +57,7 @@ class HttpConnection : public QObject
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void urlsReadyToBeDownloaded(const QStringList&);
|
void urlsReadyToBeDownloaded(const QStringList&);
|
||||||
|
void torrentReadyToBeDownloaded(QString, bool, QString, bool);
|
||||||
void deleteTorrent(QString hash);
|
void deleteTorrent(QString hash);
|
||||||
void resumeTorrent(QString hash);
|
void resumeTorrent(QString hash);
|
||||||
void pauseTorrent(QString hash);
|
void pauseTorrent(QString hash);
|
||||||
|
@ -49,11 +49,11 @@ QString HttpRequestParser::url() const
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HttpRequestParser::message() const
|
QByteArray HttpRequestParser::message() const
|
||||||
{
|
{
|
||||||
if(isParsable())
|
if(isParsable())
|
||||||
return data;
|
return data;
|
||||||
return QString();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HttpRequestParser::get(const QString key) const
|
QString HttpRequestParser::get(const QString key) const
|
||||||
@ -66,7 +66,12 @@ QString HttpRequestParser::post(const QString key) const
|
|||||||
return postMap[key];
|
return postMap[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpRequestParser::write(QString str)
|
QByteArray HttpRequestParser::torrent() const
|
||||||
|
{
|
||||||
|
return torrent_content;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpRequestParser::write(QByteArray str)
|
||||||
{
|
{
|
||||||
while (!headerDone && str.size()>0)
|
while (!headerDone && str.size()>0)
|
||||||
{
|
{
|
||||||
@ -111,7 +116,7 @@ void HttpRequestParser::write(QString str)
|
|||||||
if(contentType() == "application/x-www-form-urlencoded")
|
if(contentType() == "application/x-www-form-urlencoded")
|
||||||
{
|
{
|
||||||
QUrl url;
|
QUrl url;
|
||||||
url.setEncodedQuery(data.toAscii());
|
url.setEncodedQuery(data);
|
||||||
QListIterator<QPair<QString, QString> > i(url.queryItems());
|
QListIterator<QPair<QString, QString> > i(url.queryItems());
|
||||||
while (i.hasNext())
|
while (i.hasNext())
|
||||||
{
|
{
|
||||||
@ -120,9 +125,15 @@ void HttpRequestParser::write(QString str)
|
|||||||
qDebug() << pair.first << "=" << post(pair.first);
|
qDebug() << pair.first << "=" << post(pair.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(contentType() == "multipart/form-data")
|
||||||
|
{
|
||||||
|
//qDebug() << data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
|
||||||
|
torrent_content = data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
qDebug() << "isError: " << isError();
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,11 @@ class HttpRequestParser : public QHttpRequestHeader
|
|||||||
bool headerDone;
|
bool headerDone;
|
||||||
bool messageDone;
|
bool messageDone;
|
||||||
bool error;
|
bool error;
|
||||||
QString data;
|
QByteArray data;
|
||||||
QString path;
|
QString path;
|
||||||
QMap<QString, QString> postMap;
|
QMap<QString, QString> postMap;
|
||||||
QMap<QString, QString> getMap;
|
QMap<QString, QString> getMap;
|
||||||
|
QByteArray torrent_content;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HttpRequestParser();
|
HttpRequestParser();
|
||||||
@ -41,10 +42,11 @@ class HttpRequestParser : public QHttpRequestHeader
|
|||||||
bool isParsable() const;
|
bool isParsable() const;
|
||||||
bool isError() const;
|
bool isError() const;
|
||||||
QString url() const;
|
QString url() const;
|
||||||
QString message() const;
|
QByteArray message() const;
|
||||||
QString get(const QString key) const;
|
QString get(const QString key) const;
|
||||||
QString post(const QString key) const;
|
QString post(const QString key) const;
|
||||||
void write(QString str);
|
QByteArray torrent() const;
|
||||||
|
void write(QByteArray str);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,6 +62,7 @@ void HttpServer::newHttpConnection()
|
|||||||
HttpConnection *connection = new HttpConnection(socket, this);
|
HttpConnection *connection = new HttpConnection(socket, this);
|
||||||
//connect connection to BTSession
|
//connect connection to BTSession
|
||||||
connect(connection, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
|
connect(connection, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
|
||||||
|
connect(connection, SIGNAL(torrentReadyToBeDownloaded(QString, bool, QString, bool)), BTSession, SLOT(addTorrent(QString, bool, QString, bool)));
|
||||||
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
|
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
|
||||||
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
|
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
|
||||||
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
|
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<qresource>
|
<qresource>
|
||||||
<file>webui/index.html</file>
|
<file>webui/index.html</file>
|
||||||
<file>webui/download.html</file>
|
<file>webui/download.html</file>
|
||||||
|
<file>webui/upload.html</file>
|
||||||
<file>webui/about.html</file>
|
<file>webui/about.html</file>
|
||||||
<file>webui/css/mocha.css</file>
|
<file>webui/css/mocha.css</file>
|
||||||
<file>webui/css/dynamicTable.css</file>
|
<file>webui/css/dynamicTable.css</file>
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
<a class="returnFalse">File</a>
|
<a class="returnFalse">File</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a id="downloadLink">Download from URL</a></li>
|
<li><a id="downloadLink">Download from URL</a></li>
|
||||||
|
<li><a id="uploadLink">Download local torrent</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -52,6 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="mochaToolbar">
|
<div id="mochaToolbar">
|
||||||
<a id="downloadButton"><img class="mochaToolButton" title="Download from URL" src="images/skin/url.png"/></a>
|
<a id="downloadButton"><img class="mochaToolButton" title="Download from URL" src="images/skin/url.png"/></a>
|
||||||
|
<a id="uploadButton"><img class="mochaToolButton" title="Download local torrent" src="images/skin/open.png"/></a>
|
||||||
<a id="deleteButton"><img class="mochaToolButton" title="Delete" src="images/skin/delete.png"/></a>
|
<a id="deleteButton"><img class="mochaToolButton" title="Delete" src="images/skin/delete.png"/></a>
|
||||||
<a id="resumeButton"><img class="mochaToolButton" title="Resume" src="images/skin/play.png"/></a>
|
<a id="resumeButton"><img class="mochaToolButton" title="Resume" src="images/skin/play.png"/></a>
|
||||||
<a id="pauseButton"><img class="mochaToolButton" title="Pause" src="images/skin/pause.png"/></a>
|
<a id="pauseButton"><img class="mochaToolButton" title="Pause" src="images/skin/pause.png"/></a>
|
||||||
|
@ -35,6 +35,23 @@ function attachMochaLinkEvents(){
|
|||||||
height: 270
|
height: 270
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addClickEvent('upload', function(e){
|
||||||
|
new Event(e).stop();
|
||||||
|
document.mochaUI.newWindow({
|
||||||
|
id: 'uploadPage',
|
||||||
|
title: 'Upload torrent file',
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL:'upload.html',
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
paddingVertical: 0,
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
width: 500,
|
||||||
|
height: 120
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
addClickEvent('delete', function(e){
|
addClickEvent('delete', function(e){
|
||||||
new Event(e).stop();
|
new Event(e).stop();
|
||||||
|
21
src/webui/upload.html
Normal file
21
src/webui/upload.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Upload local torrent file</title>
|
||||||
|
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="css/mocha.css" type="text/css" />
|
||||||
|
<script type="text/javascript" src="scripts/mootools-trunk-1475.js" charset="utf-8"></script>
|
||||||
|
<!-- <script type="text/javascript" src="scripts/upload.js" charset="utf-8"></script> -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<center>
|
||||||
|
<h1 class="vcenter"><img class="vcenter" title="Download local torrent" src="images/skin/open.png"/>Download local torrent</h1>
|
||||||
|
<form action="/command/upload" enctype="multipart/form-data" method="post" name="uploadForm">
|
||||||
|
|
||||||
|
<input type="file" name="torrentfile" id="torrentfile" size="40"/><p>Point to torrent file</p><!--<input type="submit" value="Download"/> -->
|
||||||
|
<a id="upButton" onclick="document.uploadForm.submit();window.parent.document.getElementById('uploadPage').parentNode.removeChild(window.parent.document.getElementById('uploadPage'));">Download</a>
|
||||||
|
</form>
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user