- SearchPlugin checks for Content-type -header, so now it is able to download
authorlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Mon, 23 Nov 2009 12:33:07 +0000 (12:33 +0000)
committerlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Mon, 23 Nov 2009 12:33:07 +0000 (12:33 +0000)
through links that dont have suffix .torrent
- TODO: File renaming. Some filenames are not valid to be copied (contain brackets etc.)

git-svn-id: file:///svnroot/qtrapids/trunk@46 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda

src/gui/MainWindow.cpp
src/gui/MainWindow.h
src/plugins/PluginInterface.h
src/plugins/searchplugin/SearchPlugin.cpp
src/plugins/searchplugin/SearchPlugin.h

index 9a6770c..e233aee 100644 (file)
@@ -166,12 +166,12 @@ void MainWindow::addMenuItem(QWidget* widget, PluginWidgetType type)
 bool MainWindow::eventRequest(QVariant param, PluginRequest req)
 {
        if (req == qtrapids::PluginHostInterface::OPEN_FILE) {
-                       QString sourceFile = param.toString();
-                       
+               QString sourceFile = param.toString();
+               
                // Get the source files name from the full path:
                QFileInfo fInfo(sourceFile);
                QString targetFile = fInfo.fileName();
-               targetFile = settings_.value("download/directory").toString() + targetFile;
+               targetFile = settings_.value("download/directory").toString() + "/" + targetFile;
                
                // Copy temoporary file to Downloads directory...
                if (!QFile::copy(sourceFile, targetFile)) {
@@ -181,9 +181,14 @@ bool MainWindow::eventRequest(QVariant param, PluginRequest req)
                        // If copying was successful, remove the original temporary file.
                        QFile::remove(sourceFile);
                }
-                       
+               
+               /// @todo Torrent bencoding validity should be checked before starting(?)
                // ...and start the torrent:
                on_torrentFileSelected(targetFile);
+       
+       } else if (req == qtrapids::PluginHostInterface::READ_BUFFER) {
+               // Create torrent information from char* buffer and start.
+               StartTorrentFromBufferData(param.toByteArray().constData(), param.toByteArray().size());
        }
        
        return true;
@@ -252,6 +257,28 @@ void MainWindow::LoadPlugins()
        }
 }
 
+
+
+// Opens torrent information from buffer data and adds torrent to session 
+void MainWindow::StartTorrentFromBufferData(char const* data, int size)
+{
+       // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent
+       /// @todo Should typedef libtorrent::torrent_info to something
+       AddTorrentParams addParams;
+       boost::intrusive_ptr<libtorrent::torrent_info> tiTmp =
+           new libtorrent::torrent_info(data, size);
+       addParams.ti = tiTmp;
+       // save_path is the only mandatory parameter, rest are optional.
+       addParams.save_path = boost::filesystem::path(settings_.value("download/directory").toString().toStdString());
+       //addParams.storage_mode = libtorrent::storage_mode_allocate;
+       qtrapids::QTorrentHandle handle = btSession_.addTorrent(addParams);
+       dlView_->newItem(handle);
+//     torrentHandles_.push_back(handlePtr);
+#ifdef QTRAPIDS_DEBUG
+       qDebug() << "Is valid: " << handle.isValid();
+#endif
+}
+
 // =========================== SLOTS =================================
 void MainWindow::on_openAction_clicked()
 {
@@ -339,6 +366,7 @@ void MainWindow::on_torrentFileSelected(const QString& file)
 
        // Otherwise add torrent
        // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent
+       /// @todo Should typedef libtorrent::torrent_info to something
        AddTorrentParams addParams;
        boost::intrusive_ptr<libtorrent::torrent_info> tiTmp =
            new libtorrent::torrent_info(boost::filesystem::path(file.toStdString()));
@@ -354,7 +382,6 @@ void MainWindow::on_torrentFileSelected(const QString& file)
 #endif
 }
 
-
 void MainWindow::on_alert(std::auto_ptr<Alert> al)
 {
        if (al.get() != NULL) {
index 6f104d2..fcea41d 100644 (file)
@@ -72,6 +72,7 @@ class MainWindow : public QMainWindow, public qtrapids::PluginHostInterface {
        
        private:
                void LoadPlugins();
+               void StartTorrentFromBufferData(char const* data, int size);
                
        private:
                QTabWidget *tabWidget_;
index a5ea554..1048efd 100644 (file)
@@ -56,6 +56,7 @@ namespace qtrapids
                        /// @todo Additional functionality request constants.
                        enum PluginRequest {
                                OPEN_FILE,
+                               READ_BUFFER,
                                UNKNOWN_REQUEST
                        };
                        
index add01e0..fbc406f 100644 (file)
@@ -30,6 +30,7 @@
 #include <QFileInfo>
 #include <QWebView>
 #include <QWebPage>
+#include <QNetworkReply>
 #include <QDomDocument>
 
 #include "SearchPlugin.h"
@@ -47,13 +48,10 @@ namespace qtrapids
                searchButton_(NULL), result_(NULL), 
                dlManager_(NULL), host_(NULL)
        {
-               // TODO: Parse search engine XML(?) descriptions.
-               // -Add search engines to model
-               // -Show model in comboBox
-               // Add back/forward/refresh -buttons to widget to allow some browsing
-       
+               // TODO: Add back/forward/refresh -buttons to widget to allow some browsing functionality
        }
        
+       
        void SearchPlugin::initialize(PluginHostInterface* host, Info info)
        {
                host_ = host;
@@ -94,11 +92,12 @@ namespace qtrapids
 
        void SearchPlugin::on_searchButton_clicked()
        {
-               
                int i = comboBox_->currentIndex();
                QString tmp = engineTemplates_.at(i);
+               
                i = tmp.indexOf(SEARCH_TERMS_STRING);
                tmp.replace(i, SEARCH_TERMS_STRING.length(), searchLine_->text());
+               
                QUrl searchUrl(tmp);
                qDebug() << searchUrl;
                result_ = new QWebView;
@@ -107,9 +106,13 @@ namespace qtrapids
                QWebPage *resultPage = result_->page();
                resultPage->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
                
+               // Get the network access manager for examining HTTP replies.
+               QNetworkAccessManager *netwAccessManager_ = resultPage->networkAccessManager();
+               
                connect(resultPage, SIGNAL(linkClicked(const QUrl&)), this, SLOT(on_linkClicked(const QUrl&)));
                connect(result_, SIGNAL(loadFinished(bool)), this, SLOT(on_loadFinished(bool)));
-       
+               connect(netwAccessManager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_networkReplyFinished(QNetworkReply*)));
+               
                result_->load(searchUrl);
                
                on_searchResult((QWidget*)result_);
@@ -126,54 +129,79 @@ namespace qtrapids
        }
        
        
-       void SearchPlugin::on_searchResult(QWidget* resultWidget)
+       void SearchPlugin::on_networkReplyFinished(QNetworkReply* reply)
        {
-#ifdef QTRAPIDS_DEBUG
-               qDebug() << "on_searchResult()";
-#endif
-               if (host_) {
-                       host_->addPluginWidget(resultWidget, qtrapids::PluginHostInterface::TAB_PAGE);
-               }
-       }
-
-       void SearchPlugin::on_linkClicked(const QUrl& url)
-       {
-               // Get the path part of URL (the part after the host part) 
-               QString path = url.path();
-               QFileInfo fInfo(path);
                
-               // Check path suffix. If it is .torrent, we should download:
-               /// @todo We should actually check for MIME-type application/x-bittorrent in HTTP response, 
-               /// instead of relying on file suffix.
-               /// e.g. link 
-               ///http://www.bitenova.org/download.php?id=c84375141231eef49fc6c55e6347ba4f4a623a05&name=Nero_Linux_3.5.1.0__(Debian)_deutsch
-               /// will not work.
-               /// @todo Also, after downloading, the torrent bencoding validity should be checked at plugin host..
-               if (fInfo.suffix() == "torrent") {
-#ifdef QTRAPIDS_DEBUG
-                       qDebug() << "IS TORRENT";
-#endif
-                       QString filename = fInfo.fileName();
+               qDebug() << "on_networkReplyFinished()";
+               QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
+               QString filename;
+               QByteArray replyData;
+               QUrl url = reply->url();
+               
+               qDebug() << "on_networkReplyFinished():" << url;
+               
+               // If content type is torrent data, read reply data:
+               if (contentType == "application/x-bittorrent") {
+                       
+                       // If HTTP-response has Content-Disposition: -header, then we must use that as filename.
+                       if (reply->hasRawHeader("Content-Disposition")) { // NOTE this code block taken from kwebpage.cpp
+                               const QString value = QLatin1String(reply->rawHeader("Content-Disposition"));
+                               const int pos = value.indexOf(QLatin1String("filename="));
+                               if (pos != -1) {
+                                       QString name = value.mid(pos + 9);
+                                       if (name.startsWith(QLatin1Char('"')) && name.endsWith(QLatin1Char('"')))
+                                               name = name.mid(1, name.size() - 2);
+                                       filename = name;
+                               }
+                       // No content-disposition header, use last part (the filename) of URL as filename:
+                       } else {
+                               QString path = url.path();
+                               QFileInfo fInfo(path);
+                               filename = fInfo.fileName();
+                       }
                        
                        // Destroy ongoing download, if any.
                        if (dlManager_) {
                                delete dlManager_;
                                dlManager_ = NULL;
                        }
-                       
+               
+                       /// @todo Is this a bit of a hack now; we get the reply and check Content-Type,
+                       /// The download is then started afterwards, so we get unecessarily one extra
+                       /// HTTP-response here.  
+                       /// @todo Could this whole content-type checking be logically moved to DownloadManager?
                        // Start downloading Torrent file.
                        dlManager_ = new DownloadManager(url, "/tmp/" + filename);
                        connect(dlManager_, SIGNAL(finished(QString)), this, SLOT(on_downloadFinished(QString)));
                        dlManager_->start();
                        
-               } else {
-                       // If was not .torrent -file, check URL validity and load the page as usual.
-                       if (url.isValid()) {
-                               result_->load(url);
-                       }
                }
        }
        
+       
+       void SearchPlugin::on_searchResult(QWidget* resultWidget)
+       {
+#ifdef QTRAPIDS_DEBUG
+               qDebug() << "on_searchResult()";
+#endif
+               if (host_) {
+                       host_->addPluginWidget(resultWidget, qtrapids::PluginHostInterface::TAB_PAGE);
+               }
+       }
+
+
+       /// @todo It may be that we don't actually need link delegation, because we check response Content-Type header
+       /// on_linkClicked() in that case unnecessary function
+       void SearchPlugin::on_linkClicked(const QUrl& url)
+       {
+               qDebug() << "on_linkClicked():" << url;
+               
+               if (url.isValid()) {
+                       result_->load(url);
+               }
+       }
+       
+       
        void SearchPlugin::on_downloadFinished(QString filepath)
        {
 #ifdef QTRAPIDS_DEBUG
@@ -181,7 +209,9 @@ namespace qtrapids
 #endif
                delete dlManager_;
                dlManager_ = NULL;
-               host_->eventRequest(QVariant(filepath), qtrapids::PluginHostInterface::OPEN_FILE);
+               if (host_) {
+                       host_->eventRequest(QVariant(filepath), qtrapids::PluginHostInterface::OPEN_FILE);
+               }
        }
 
 
@@ -189,55 +219,41 @@ namespace qtrapids
        {
                foreach (QString dirName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
                
-                               QFile file(dir.path() + "/" + dirName + "/" + DESCRIPTION_FILENAME);
+                       QFile file(dir.path() + "/" + dirName + "/" + DESCRIPTION_FILENAME);
+                       
+                       if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                               qWarning() << "Unable to open " << DESCRIPTION_FILENAME << " for reading in " << dir.path();
+                               continue;
+                       }
+                       
+                       // Parse the XML file to DOM document.
+                       QDomDocument document;
+                       
+                       // Second parameter: nameSpaceProcessing = false
+                       if (!document.setContent(&file, false)) {
+                               qWarning() << "Unable to parse " << DESCRIPTION_FILENAME << " in " << dirName;
+                       } else {
+                               QDomNodeList urlElements = document.elementsByTagName("Url");
+                               QDomNodeList shortNameElements = document.elementsByTagName("ShortName");
                                
-                               if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-                                       qWarning() << "Unable to open " << DESCRIPTION_FILENAME << " for reading in " << dir.path();
-                                       continue;
+                               QDomNode n = urlElements.item(0);
+                               QDomNode m;
+                               QDomNamedNodeMap attribMap;
+                               if (n.hasAttributes()) {
+                                       attribMap = n.attributes();
+                                       m = attribMap.namedItem("template");
+                                       engineTemplates_.push_back(m.nodeValue());
                                }
                                
-                               // Parse the XML file to DOM document.
-                               QDomDocument document;
-                               
-                               // Second parameter: nameSpaceProcessing = false
-                               if (!document.setContent(&file, false)) {
-                                       qWarning() << "Unable to parse " << DESCRIPTION_FILENAME << " in " << dirName;
-                               } else {
-                                       QDomNodeList urlElements = document.elementsByTagName("Url");
-                                       QDomNodeList shortNameElements = document.elementsByTagName("ShortName");
-                                       
-                                       QDomNode n = urlElements.item(0);
-                                       QDomNode m;
-                                       QDomNamedNodeMap attribMap;
-                                       if (n.hasAttributes()) {
-                                               attribMap = n.attributes();
-                                               m = attribMap.namedItem("template");
-                                               engineTemplates_.push_back(m.nodeValue());
-                                       }
-                                       
-                                       n = shortNameElements.item(0);
-                                       if (n.hasChildNodes()) {
-                                               m = n.firstChild();
-                                               comboBox_->addItem(m.nodeValue());
-                                       }
+                               n = shortNameElements.item(0);
+                               if (n.hasChildNodes()) {
+                                       m = n.firstChild();
+                                       comboBox_->addItem(m.nodeValue());
                                }
                        }
-                       
-                       
-                       /// @todo save parsed xml elements <Shortname> and <Url template="<foo>"> to a model which is displayed in combobox.
                }
-               
-                                               /*
-               QDomElement docElem = document.documentElement();
-               QDomNode n = docElem.firstChild();
-               while(!n.isNull()) {
-                       QDomElement e = n.toElement(); // try to convert the node to an element.
-                       if(!e.isNull()) {
-                               qDebug() << qPrintable(e.tagName()); // the node really is an element.
-                       }
-                       n = n.nextSibling();
-               }
-               */
+               /// @todo save parsed xml elements <Shortname> and <Url template="<foo>"> to a model which is displayed in combobox.
+       }
 
 } // namespace qtrapids
 
index 1b16330..eecabd3 100644 (file)
@@ -30,6 +30,7 @@ class QComboBox;
 class QPushButton;
 class QLineEdit;
 class QWebView;
+class QNetworkReply;
 class DownloadManager;
 class QDir;
 
@@ -56,6 +57,7 @@ class SearchPlugin : public PluginInterface
                void on_searchButton_clicked();
                void on_searchResult(QWidget* resultWidget);
                void on_loadFinished(bool ok);
+               void on_networkReplyFinished(QNetworkReply* reply);
                void on_linkClicked(const QUrl& url);
                void on_downloadFinished(QString filepath);