Browse Source

Use nova2dl.py script instead of DownloadManager

Closes #5026
adaptive-webui-19844
Vladimir Golovnev (Glassez) 9 years ago
parent
commit
a9e63283cc
  1. 36
      src/base/searchengine.cpp
  2. 6
      src/base/searchengine.h
  3. 3
      src/gui/search/searchtab.cpp
  4. 28
      src/gui/search/searchwidget.cpp
  5. 6
      src/gui/search/searchwidget.h
  6. 108
      src/searchengine.qrc
  7. 61
      src/searchengine/nova/nova2dl.py
  8. 61
      src/searchengine/nova3/nova2dl.py

36
src/base/searchengine.cpp

@ -266,6 +266,21 @@ void SearchEngine::cancelSearch()
} }
} }
void SearchEngine::downloadTorrent(const QString &siteUrl, const QString &url)
{
QProcess *downloadProcess = new QProcess(this);
downloadProcess->setEnvironment(QProcess::systemEnvironment());
connect(downloadProcess, SIGNAL(finished(int)), this, SLOT(torrentFileDownloadFinished(int)));
m_downloaders << downloadProcess;
QStringList params {
Utils::Fs::toNativePath(engineLocation() + "/nova2dl.py"),
siteUrl,
url
};
// Launch search
downloadProcess->start(Utils::Misc::pythonExecutable(), params, QIODevice::ReadOnly);
}
void SearchEngine::startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins) void SearchEngine::startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins)
{ {
// Search process already running or // Search process already running or
@ -357,6 +372,21 @@ void SearchEngine::pluginDownloadFailed(const QString &url, const QString &reaso
emit pluginInstallationFailed(pluginName, tr("Failed to download the plugin file. %1").arg(reason)); emit pluginInstallationFailed(pluginName, tr("Failed to download the plugin file. %1").arg(reason));
} }
void SearchEngine::torrentFileDownloadFinished(int exitcode)
{
QProcess *downloadProcess = static_cast<QProcess*>(sender());
if (exitcode == 0) {
QString line = QString::fromUtf8(downloadProcess->readAllStandardOutput()).trimmed();
QStringList parts = line.split(' ');
if (parts.size() == 2)
emit torrentFileDownloaded(parts[0]);
}
qDebug() << "Deleting downloadProcess";
m_downloaders.removeOne(downloadProcess);
downloadProcess->deleteLater();
}
// Update nova.py search plugin if necessary // Update nova.py search plugin if necessary
void SearchEngine::updateNova() void SearchEngine::updateNova()
{ {
@ -383,6 +413,12 @@ void SearchEngine::updateNova()
QFile::copy(":/" + novaFolder + "/nova2.py", filePath); QFile::copy(":/" + novaFolder + "/nova2.py", filePath);
} }
filePath = searchDir.absoluteFilePath("nova2dl.py");
if (getPluginVersion(":/" + novaFolder + "/nova2dl.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath);
QFile::copy(":/" + novaFolder + "/nova2dl.py", filePath);
}
filePath = searchDir.absoluteFilePath("fix_encoding.py"); filePath = searchDir.absoluteFilePath("fix_encoding.py");
QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath); QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath);

6
src/base/searchengine.h

@ -84,6 +84,8 @@ public:
void startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins); void startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins);
void cancelSearch(); void cancelSearch();
void downloadTorrent(const QString &siteUrl, const QString &url);
static qreal getPluginVersion(QString filePath); static qreal getPluginVersion(QString filePath);
static QString categoryFullName(const QString &categoryName); static QString categoryFullName(const QString &categoryName);
static QString pluginsLocation(); static QString pluginsLocation();
@ -102,6 +104,8 @@ signals:
void checkForUpdatesFinished(const QHash<QString, qreal> &updateInfo); void checkForUpdatesFinished(const QHash<QString, qreal> &updateInfo);
void checkForUpdatesFailed(const QString &reason); void checkForUpdatesFailed(const QString &reason);
void torrentFileDownloaded(const QString &path);
private slots: private slots:
void onTimeout(); void onTimeout();
void readSearchOutput(); void readSearchOutput();
@ -110,6 +114,7 @@ private slots:
void versionInfoDownloadFailed(const QString &url, const QString &reason); void versionInfoDownloadFailed(const QString &url, const QString &reason);
void pluginDownloaded(const QString &url, QString filePath); void pluginDownloaded(const QString &url, QString filePath);
void pluginDownloadFailed(const QString &url, const QString &reason); void pluginDownloadFailed(const QString &url, const QString &reason);
void torrentFileDownloadFinished(int exitcode);
private: private:
void update(); void update();
@ -132,6 +137,7 @@ private:
bool m_searchStopped; bool m_searchStopped;
QTimer *m_searchTimeout; QTimer *m_searchTimeout;
QByteArray m_searchResultLineTruncated; QByteArray m_searchResultLineTruncated;
QList<QProcess*> m_downloaders;
}; };
#endif // SEARCHENGINE_H #endif // SEARCHENGINE_H

3
src/gui/search/searchtab.cpp

@ -132,8 +132,9 @@ SearchTab::~SearchTab()
void SearchTab::downloadItem(const QModelIndex &index) void SearchTab::downloadItem(const QModelIndex &index)
{ {
QString torrentUrl = m_proxyModel->data(m_proxyModel->index(index.row(), SearchSortModel::DL_LINK)).toString(); QString torrentUrl = m_proxyModel->data(m_proxyModel->index(index.row(), SearchSortModel::DL_LINK)).toString();
QString siteUrl = m_proxyModel->data(m_proxyModel->index(index.row(), SearchSortModel::ENGINE_URL)).toString();
setRowColor(index.row(), "blue"); setRowColor(index.row(), "blue");
m_parent->downloadTorrent(torrentUrl); m_parent->downloadTorrent(siteUrl, torrentUrl);
} }
QHeaderView* SearchTab::header() const QHeaderView* SearchTab::header() const

28
src/gui/search/searchwidget.cpp

@ -116,6 +116,7 @@ SearchWidget::SearchWidget(MainWindow *mainWindow)
connect(m_searchEngine, SIGNAL(newSearchResults(QList<SearchResult>)), SLOT(appendSearchResults(QList<SearchResult>))); connect(m_searchEngine, SIGNAL(newSearchResults(QList<SearchResult>)), SLOT(appendSearchResults(QList<SearchResult>)));
connect(m_searchEngine, SIGNAL(searchFinished(bool)), SLOT(searchFinished(bool))); connect(m_searchEngine, SIGNAL(searchFinished(bool)), SLOT(searchFinished(bool)));
connect(m_searchEngine, SIGNAL(searchFailed()), SLOT(searchFailed())); connect(m_searchEngine, SIGNAL(searchFailed()), SLOT(searchFailed()));
connect(m_searchEngine, SIGNAL(torrentFileDownloaded(QString)), SLOT(addTorrentToSession(QString)));
// Fill in category combobox // Fill in category combobox
fillCatCombobox(); fillCatCombobox();
@ -161,6 +162,14 @@ SearchWidget::~SearchWidget()
delete m_searchEngine; delete m_searchEngine;
} }
void SearchWidget::downloadTorrent(const QString &siteUrl, const QString &url)
{
if (url.startsWith("bc://bt/", Qt::CaseInsensitive) || url.startsWith("magnet:", Qt::CaseInsensitive))
addTorrentToSession(url);
else
m_searchEngine->downloadTorrent(siteUrl, url);
}
void SearchWidget::tab_changed(int t) void SearchWidget::tab_changed(int t)
{ {
//when we switch from a tab that is not empty to another that is empty the download button //when we switch from a tab that is not empty to another that is empty the download button
@ -187,6 +196,14 @@ void SearchWidget::selectMultipleBox(const QString &text)
on_pluginsButton_clicked(); on_pluginsButton_clicked();
} }
void SearchWidget::addTorrentToSession(const QString &source)
{
if (AddNewTorrentDialog::isEnabled())
AddNewTorrentDialog::show(source, this);
else
BitTorrent::Session::instance()->addTorrent(source);
}
void SearchWidget::on_pluginsButton_clicked() void SearchWidget::on_pluginsButton_clicked()
{ {
PluginSelectDlg *dlg = new PluginSelectDlg(m_searchEngine, this); PluginSelectDlg *dlg = new PluginSelectDlg(m_searchEngine, this);
@ -281,14 +298,6 @@ void SearchWidget::saveResultsColumnsWidth()
Preferences::instance()->setSearchColsWidth(newWidthList.join(" ")); Preferences::instance()->setSearchColsWidth(newWidthList.join(" "));
} }
void SearchWidget::downloadTorrent(QString url)
{
if (AddNewTorrentDialog::isEnabled())
AddNewTorrentDialog::show(url, this);
else
BitTorrent::Session::instance()->addTorrent(url);
}
void SearchWidget::searchStarted() void SearchWidget::searchStarted()
{ {
// Update SearchEngine widgets // Update SearchEngine widgets
@ -391,9 +400,8 @@ void SearchWidget::on_downloadButton_clicked()
//QModelIndexList selectedIndexes = currentSearchTab->getCurrentTreeView()->selectionModel()->selectedIndexes(); //QModelIndexList selectedIndexes = currentSearchTab->getCurrentTreeView()->selectionModel()->selectedIndexes();
QModelIndexList selectedIndexes = m_allTabs.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = m_allTabs.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes();
foreach (const QModelIndex &index, selectedIndexes) { foreach (const QModelIndex &index, selectedIndexes) {
if (index.column() == SearchSortModel::NAME) { if (index.column() == SearchSortModel::NAME)
m_allTabs.at(tabWidget->currentIndex())->downloadItem(index); m_allTabs.at(tabWidget->currentIndex())->downloadItem(index);
}
} }
} }

6
src/gui/search/searchwidget.h

@ -52,7 +52,7 @@ public:
explicit SearchWidget(MainWindow *mainWindow); explicit SearchWidget(MainWindow *mainWindow);
~SearchWidget(); ~SearchWidget();
void downloadTorrent(QString url); void downloadTorrent(const QString &siteUrl, const QString &url);
void giveFocusToSearchInput(); void giveFocusToSearchInput();
QTabWidget* searchTabs() const; QTabWidget* searchTabs() const;
@ -73,6 +73,8 @@ private slots:
void searchFailed(); void searchFailed();
void selectMultipleBox(const QString &text); void selectMultipleBox(const QString &text);
void addTorrentToSession(const QString &source);
void saveResultsColumnsWidth(); void saveResultsColumnsWidth();
void fillCatCombobox(); void fillCatCombobox();
void fillPluginComboBox(); void fillPluginComboBox();
@ -86,7 +88,7 @@ private:
SearchEngine *m_searchEngine; SearchEngine *m_searchEngine;
QPointer<SearchTab> m_currentSearchTab; // Selected tab QPointer<SearchTab> m_currentSearchTab; // Selected tab
QPointer<SearchTab> m_activeSearchTab; // Tab with running search QPointer<SearchTab> m_activeSearchTab; // Tab with running search
QList<QPointer<SearchTab> > m_allTabs; // To store all tabs QList<QPointer<SearchTab>> m_allTabs; // To store all tabs
MainWindow *m_mainWindow; MainWindow *m_mainWindow;
bool m_isNewQueryString; bool m_isNewQueryString;
bool m_noSearchResults; bool m_noSearchResults;

108
src/searchengine.qrc

@ -1,54 +1,56 @@
<!DOCTYPE RCC><RCC version="1.0"> <RCC>
<qresource> <qresource prefix="/">
<file>searchengine/nova/fix_encoding.py</file> <file>searchengine/nova/fix_encoding.py</file>
<file>searchengine/nova/helpers.py</file> <file>searchengine/nova/helpers.py</file>
<file>searchengine/nova/nova2.py</file> <file>searchengine/nova/nova2.py</file>
<file>searchengine/nova/novaprinter.py</file> <file>searchengine/nova/novaprinter.py</file>
<file>searchengine/nova/socks.py</file> <file>searchengine/nova/socks.py</file>
<file>searchengine/nova/engines/btdigg.png</file> <file>searchengine/nova/engines/btdigg.png</file>
<file>searchengine/nova/engines/btdigg.py</file> <file>searchengine/nova/engines/btdigg.py</file>
<file>searchengine/nova/engines/demonoid.png</file> <file>searchengine/nova/engines/demonoid.png</file>
<file>searchengine/nova/engines/demonoid.py</file> <file>searchengine/nova/engines/demonoid.py</file>
<file>searchengine/nova/engines/extratorrent.png</file> <file>searchengine/nova/engines/extratorrent.png</file>
<file>searchengine/nova/engines/extratorrent.py</file> <file>searchengine/nova/engines/extratorrent.py</file>
<file>searchengine/nova/engines/kickasstorrents.png</file> <file>searchengine/nova/engines/kickasstorrents.png</file>
<file>searchengine/nova/engines/kickasstorrents.py</file> <file>searchengine/nova/engines/kickasstorrents.py</file>
<file>searchengine/nova/engines/legittorrents.png</file> <file>searchengine/nova/engines/legittorrents.png</file>
<file>searchengine/nova/engines/legittorrents.py</file> <file>searchengine/nova/engines/legittorrents.py</file>
<file>searchengine/nova/engines/mininova.png</file> <file>searchengine/nova/engines/mininova.png</file>
<file>searchengine/nova/engines/mininova.py</file> <file>searchengine/nova/engines/mininova.py</file>
<file>searchengine/nova/engines/piratebay.png</file> <file>searchengine/nova/engines/piratebay.png</file>
<file>searchengine/nova/engines/piratebay.py</file> <file>searchengine/nova/engines/piratebay.py</file>
<file>searchengine/nova/engines/torlock.png</file> <file>searchengine/nova/engines/torlock.png</file>
<file>searchengine/nova/engines/torlock.py</file> <file>searchengine/nova/engines/torlock.py</file>
<file>searchengine/nova/engines/torrentreactor.png</file> <file>searchengine/nova/engines/torrentreactor.png</file>
<file>searchengine/nova/engines/torrentreactor.py</file> <file>searchengine/nova/engines/torrentreactor.py</file>
<file>searchengine/nova/engines/torrentz.png</file> <file>searchengine/nova/engines/torrentz.png</file>
<file>searchengine/nova/engines/torrentz.py</file> <file>searchengine/nova/engines/torrentz.py</file>
<file>searchengine/nova3/helpers.py</file> <file>searchengine/nova3/helpers.py</file>
<file>searchengine/nova3/nova2.py</file> <file>searchengine/nova3/nova2.py</file>
<file>searchengine/nova3/novaprinter.py</file> <file>searchengine/nova3/novaprinter.py</file>
<file>searchengine/nova3/sgmllib3.py</file> <file>searchengine/nova3/sgmllib3.py</file>
<file>searchengine/nova3/socks.py</file> <file>searchengine/nova3/socks.py</file>
<file>searchengine/nova3/engines/btdigg.png</file> <file>searchengine/nova3/engines/btdigg.png</file>
<file>searchengine/nova3/engines/btdigg.py</file> <file>searchengine/nova3/engines/btdigg.py</file>
<file>searchengine/nova3/engines/demonoid.png</file> <file>searchengine/nova3/engines/demonoid.png</file>
<file>searchengine/nova3/engines/demonoid.py</file> <file>searchengine/nova3/engines/demonoid.py</file>
<file>searchengine/nova3/engines/extratorrent.png</file> <file>searchengine/nova3/engines/extratorrent.png</file>
<file>searchengine/nova3/engines/extratorrent.py</file> <file>searchengine/nova3/engines/extratorrent.py</file>
<file>searchengine/nova3/engines/kickasstorrents.png</file> <file>searchengine/nova3/engines/kickasstorrents.png</file>
<file>searchengine/nova3/engines/kickasstorrents.py</file> <file>searchengine/nova3/engines/kickasstorrents.py</file>
<file>searchengine/nova3/engines/legittorrents.png</file> <file>searchengine/nova3/engines/legittorrents.png</file>
<file>searchengine/nova3/engines/legittorrents.py</file> <file>searchengine/nova3/engines/legittorrents.py</file>
<file>searchengine/nova3/engines/mininova.png</file> <file>searchengine/nova3/engines/mininova.png</file>
<file>searchengine/nova3/engines/mininova.py</file> <file>searchengine/nova3/engines/mininova.py</file>
<file>searchengine/nova3/engines/piratebay.png</file> <file>searchengine/nova3/engines/piratebay.png</file>
<file>searchengine/nova3/engines/piratebay.py</file> <file>searchengine/nova3/engines/piratebay.py</file>
<file>searchengine/nova3/engines/torlock.png</file> <file>searchengine/nova3/engines/torlock.png</file>
<file>searchengine/nova3/engines/torlock.py</file> <file>searchengine/nova3/engines/torlock.py</file>
<file>searchengine/nova3/engines/torrentreactor.png</file> <file>searchengine/nova3/engines/torrentreactor.png</file>
<file>searchengine/nova3/engines/torrentreactor.py</file> <file>searchengine/nova3/engines/torrentreactor.py</file>
<file>searchengine/nova3/engines/torrentz.png</file> <file>searchengine/nova3/engines/torrentz.png</file>
<file>searchengine/nova3/engines/torrentz.py</file> <file>searchengine/nova3/engines/torrentz.py</file>
</qresource> <file>searchengine/nova/nova2dl.py</file>
<file>searchengine/nova3/nova2dl.py</file>
</qresource>
</RCC> </RCC>

61
src/searchengine/nova/nova2dl.py

@ -0,0 +1,61 @@
#VERSION: 1.20
# Author:
# Christophe DUMEZ (chris@qbittorrent.org)
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import sys
import os
import glob
from helpers import download_file
supported_engines = dict()
engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py'))
for engine in engines:
e = engine.split(os.sep)[-1][:-3]
if len(e.strip()) == 0: continue
if e.startswith('_'): continue
try:
exec("from engines.%s import %s"%(e,e))
exec("engine_url = %s.url"%e)
supported_engines[engine_url] = e
except:
pass
if __name__ == '__main__':
if len(sys.argv) < 3:
raise SystemExit('./nova2dl.py engine_url download_parameter')
engine_url = sys.argv[1].strip()
download_param = sys.argv[2].strip()
if engine_url not in list(supported_engines.keys()):
raise SystemExit('./nova2dl.py: this engine_url was not recognized')
exec("engine = %s()"%supported_engines[engine_url])
if hasattr(engine, 'download_torrent'):
engine.download_torrent(download_param)
else:
print(download_file(download_param))
sys.exit(0)

61
src/searchengine/nova3/nova2dl.py

@ -0,0 +1,61 @@
#VERSION: 1.20
# Author:
# Christophe DUMEZ (chris@qbittorrent.org)
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import sys
import os
import glob
from helpers import download_file
supported_engines = dict()
engines = glob.glob(os.path.join(os.path.dirname(__file__), 'engines','*.py'))
for engine in engines:
e = engine.split(os.sep)[-1][:-3]
if len(e.strip()) == 0: continue
if e.startswith('_'): continue
try:
exec("from engines.%s import %s"%(e,e))
exec("engine_url = %s.url"%e)
supported_engines[engine_url] = e
except:
pass
if __name__ == '__main__':
if len(sys.argv) < 3:
raise SystemExit('./nova2dl.py engine_url download_parameter')
engine_url = sys.argv[1].strip()
download_param = sys.argv[2].strip()
if engine_url not in list(supported_engines.keys()):
raise SystemExit('./nova2dl.py: this engine_url was not recognized')
exec("engine = %s()"%supported_engines[engine_url])
if hasattr(engine, 'download_torrent'):
engine.download_torrent(download_param)
else:
print(download_file(download_param))
sys.exit(0)
Loading…
Cancel
Save