Browse Source

Add combo box for fast search engine switch

adaptive-webui-19844
DoumanAsh 10 years ago
parent
commit
e357cf6231
  1. 3
      src/searchengine/search.ui
  2. 743
      src/searchengine/searchengine.cpp
  3. 3
      src/searchengine/searchengine.h
  4. 6
      src/searchengine/supportedengines.h

3
src/searchengine/search.ui

@ -19,6 +19,9 @@
<item> <item>
<widget class="QComboBox" name="comboCategory"/> <widget class="QComboBox" name="comboCategory"/>
</item> </item>
<item>
<widget class="QComboBox" name="selectEngine"/>
</item>
<item> <item>
<widget class="QPushButton" name="search_button"> <widget class="QPushButton" name="search_button">
<property name="maximumSize"> <property name="maximumSize">

743
src/searchengine/searchengine.cpp

@ -65,253 +65,277 @@ SearchEngine::SearchEngine(MainWindow* parent)
, search_pattern(new LineEdit) , search_pattern(new LineEdit)
, mp_mainWindow(parent) , mp_mainWindow(parent)
{ {
setupUi(this); setupUi(this);
searchBarLayout->insertWidget(0, search_pattern); searchBarLayout->insertWidget(0, search_pattern);
connect(search_pattern, SIGNAL(returnPressed()), search_button, SLOT(click())); connect(search_pattern, SIGNAL(returnPressed()), search_button, SLOT(click()));
// Icons // Icons
search_button->setIcon(IconProvider::instance()->getIcon("edit-find")); search_button->setIcon(IconProvider::instance()->getIcon("edit-find"));
download_button->setIcon(IconProvider::instance()->getIcon("download")); download_button->setIcon(IconProvider::instance()->getIcon("download"));
goToDescBtn->setIcon(IconProvider::instance()->getIcon("application-x-mswinurl")); goToDescBtn->setIcon(IconProvider::instance()->getIcon("application-x-mswinurl"));
enginesButton->setIcon(IconProvider::instance()->getIcon("preferences-system-network")); enginesButton->setIcon(IconProvider::instance()->getIcon("preferences-system-network"));
tabWidget->setTabsClosable(true); tabWidget->setTabsClosable(true);
connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
// Boolean initialization // Boolean initialization
search_stopped = false; search_stopped = false;
// Creating Search Process // Creating Search Process
searchProcess = new QProcess(this); searchProcess = new QProcess(this);
searchProcess->setEnvironment(QProcess::systemEnvironment()); searchProcess->setEnvironment(QProcess::systemEnvironment());
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted())); connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput())); connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput()));
connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus))); connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus)));
connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int))); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int)));
searchTimeout = new QTimer(this); searchTimeout = new QTimer(this);
searchTimeout->setSingleShot(true); searchTimeout->setSingleShot(true);
connect(searchTimeout, SIGNAL(timeout()), this, SLOT(on_search_button_clicked())); connect(searchTimeout, SIGNAL(timeout()), this, SLOT(on_search_button_clicked()));
// Update nova.py search plugin if necessary // Update nova.py search plugin if necessary
updateNova(); updateNova();
supported_engines = new SupportedEngines(); supported_engines = new SupportedEngines();
// Fill in category combobox // Fill in category combobox
fillCatCombobox(); fillCatCombobox();
fillEngineComboBox();
connect(search_pattern, SIGNAL(textEdited(QString)), this, SLOT(searchTextEdited(QString)));
connect(search_pattern, SIGNAL(textEdited(QString)), this, SLOT(searchTextEdited(QString)));
connect(selectEngine, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(selectMultipleBox(const QString&)));
} }
void SearchEngine::fillCatCombobox() { void SearchEngine::fillCatCombobox() {
comboCategory->clear(); comboCategory->clear();
comboCategory->addItem(full_cat_names["all"], QVariant("all")); comboCategory->addItem(full_cat_names["all"], QVariant("all"));
QStringList supported_cat = supported_engines->supportedCategories(); QStringList supported_cat = supported_engines->supportedCategories();
foreach (QString cat, supported_cat) { foreach (QString cat, supported_cat) {
qDebug("Supported category: %s", qPrintable(cat)); qDebug("Supported category: %s", qPrintable(cat));
comboCategory->addItem(full_cat_names[cat], QVariant(cat)); comboCategory->addItem(full_cat_names[cat], QVariant(cat));
} }
} }
void SearchEngine::fillEngineComboBox() {
selectEngine->clear();
selectEngine->addItem("All enabled", QVariant("enabled"));
selectEngine->addItem("All engines", QVariant("all"));
foreach (QString engi, supported_engines->enginesEnabled())
selectEngine->addItem(engi, QVariant(engi));
selectEngine->addItem("Multiple...", QVariant("multi"));
}
QString SearchEngine::selectedCategory() const { QString SearchEngine::selectedCategory() const {
return comboCategory->itemData(comboCategory->currentIndex()).toString(); return comboCategory->itemData(comboCategory->currentIndex()).toString();
}
QString SearchEngine::selectedEngine() const {
return selectEngine->itemData(selectEngine->currentIndex()).toString();
} }
SearchEngine::~SearchEngine() { SearchEngine::~SearchEngine() {
qDebug("Search destruction"); qDebug("Search destruction");
searchProcess->kill(); searchProcess->kill();
searchProcess->waitForFinished(); searchProcess->waitForFinished();
foreach (QProcess *downloader, downloaders) { foreach (QProcess *downloader, downloaders) {
// Make sure we disconnect the SIGNAL/SLOT first // Make sure we disconnect the SIGNAL/SLOT first
// To avoid qreal free // To avoid qreal free
downloader->disconnect(); downloader->disconnect();
downloader->kill(); downloader->kill();
downloader->waitForFinished(); downloader->waitForFinished();
delete downloader; delete downloader;
} }
delete search_pattern; delete search_pattern;
delete searchTimeout; delete searchTimeout;
delete searchProcess; delete searchProcess;
delete supported_engines; delete supported_engines;
} }
void SearchEngine::tab_changed(int t) void SearchEngine::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
//doesn't have to be available //doesn't have to be available
if (t>-1) if (t>-1) {//-1 = no more tab
{//-1 = no more tab if (all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel()->rowCount()) {
if (all_tab.at(tabWidget->currentIndex())->getCurrentSearchListModel()->rowCount()) { download_button->setEnabled(true);
download_button->setEnabled(true); goToDescBtn->setEnabled(true);
goToDescBtn->setEnabled(true); }
} else { else {
download_button->setEnabled(false); download_button->setEnabled(false);
goToDescBtn->setEnabled(false); goToDescBtn->setEnabled(false);
}
} }
} }
void SearchEngine::selectMultipleBox(const QString &text) {
if (text == "Multiple...") on_enginesButton_clicked();
} }
void SearchEngine::on_enginesButton_clicked() { void SearchEngine::on_enginesButton_clicked() {
engineSelectDlg *dlg = new engineSelectDlg(this, supported_engines); engineSelectDlg *dlg = new engineSelectDlg(this, supported_engines);
connect(dlg, SIGNAL(enginesChanged()), this, SLOT(fillCatCombobox())); connect(dlg, SIGNAL(enginesChanged()), this, SLOT(fillCatCombobox()));
connect(dlg, SIGNAL(enginesChanged()), this, SLOT(fillEngineComboBox()));
} }
void SearchEngine::searchTextEdited(QString) { void SearchEngine::searchTextEdited(QString) {
// Enable search button // Enable search button
search_button->setText(tr("Search")); search_button->setText(tr("Search"));
} }
void SearchEngine::giveFocusToSearchInput() { void SearchEngine::giveFocusToSearchInput() {
search_pattern->setFocus(); search_pattern->setFocus();
} }
// Function called when we click on search button // Function called when we click on search button
void SearchEngine::on_search_button_clicked() { void SearchEngine::on_search_button_clicked() {
if (searchProcess->state() != QProcess::NotRunning) { if (searchProcess->state() != QProcess::NotRunning) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
searchProcess->kill(); searchProcess->kill();
#else #else
searchProcess->terminate(); searchProcess->terminate();
#endif #endif
search_stopped = true; search_stopped = true;
if (searchTimeout->isActive()) { if (searchTimeout->isActive()) {
searchTimeout->stop(); searchTimeout->stop();
}
if (search_button->text() != tr("Search")) {
search_button->setText(tr("Search"));
return;
}
} }
if (search_button->text() != tr("Search")) { searchProcess->waitForFinished();
search_button->setText(tr("Search")); // Reload environment variables (proxy)
return; searchProcess->setEnvironment(QProcess::systemEnvironment());
const QString pattern = search_pattern->text().trimmed();
// No search pattern entered
if (pattern.isEmpty()) {
QMessageBox::critical(0, tr("Empty search pattern"), tr("Please type a search pattern first"));
return;
} }
} // Tab Addition
searchProcess->waitForFinished(); currentSearchTab = new SearchTab(this);
// Reload environment variables (proxy) connect(currentSearchTab->header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(propagateSectionResized(int,int,int)));
searchProcess->setEnvironment(QProcess::systemEnvironment()); all_tab.append(currentSearchTab);
QString tabName = pattern;
const QString pattern = search_pattern->text().trimmed(); tabName.replace(QRegExp("&{1}"), "&&");
// No search pattern entered tabWidget->addTab(currentSearchTab, tabName);
if (pattern.isEmpty()) { tabWidget->setCurrentWidget(currentSearchTab);
QMessageBox::critical(0, tr("Empty search pattern"), tr("Please type a search pattern first"));
return; // Getting checked search engines
} QStringList params;
// Tab Addition search_stopped = false;
currentSearchTab=new SearchTab(this); params << fsutils::toNativePath(fsutils::searchEngineLocation() + "/nova2.py");
connect(currentSearchTab->header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(propagateSectionResized(int,int,int))); if (selectedEngine() == "all") params << supported_engines->enginesAll().join(",");
all_tab.append(currentSearchTab); else if (selectedEngine() == "enabled") params << supported_engines->enginesEnabled().join(",");
QString tabName = pattern; else if (selectedEngine() == "multi") params << supported_engines->enginesEnabled().join(",");
tabName.replace(QRegExp("&{1}"), "&&"); else params << selectedEngine();
tabWidget->addTab(currentSearchTab, tabName); qDebug("Search with category: %s", qPrintable(selectedCategory()));
tabWidget->setCurrentWidget(currentSearchTab); params << selectedCategory();
params << pattern.split(" ");
// Getting checked search engines // Update SearchEngine widgets
QStringList params; no_search_results = true;
search_stopped = false; nb_search_results = 0;
params << fsutils::toNativePath(fsutils::searchEngineLocation() + "/nova2.py"); search_result_line_truncated.clear();
params << supported_engines->enginesEnabled().join(","); //on change le texte du label courrant
qDebug("Search with category: %s", qPrintable(selectedCategory())); currentSearchTab->getCurrentLabel()->setText(tr("Results")+" <i>(0)</i>:");
params << selectedCategory(); // Launch search
params << pattern.split(" "); searchProcess->start("python", params, QIODevice::ReadOnly);
// Update SearchEngine widgets searchTimeout->start(180000); // 3min
no_search_results = true;
nb_search_results = 0;
search_result_line_truncated.clear();
//on change le texte du label courrant
currentSearchTab->getCurrentLabel()->setText(tr("Results")+" <i>(0)</i>:");
// Launch search
searchProcess->start("python", params, QIODevice::ReadOnly);
searchTimeout->start(180000); // 3min
} }
void SearchEngine::propagateSectionResized(int index, int , int newsize) { void SearchEngine::propagateSectionResized(int index, int , int newsize) {
foreach (SearchTab * tab, all_tab) { foreach (SearchTab * tab, all_tab) {
tab->getCurrentTreeView()->setColumnWidth(index, newsize); tab->getCurrentTreeView()->setColumnWidth(index, newsize);
} }
saveResultsColumnsWidth(); saveResultsColumnsWidth();
} }
void SearchEngine::saveResultsColumnsWidth() { void SearchEngine::saveResultsColumnsWidth() {
if (all_tab.size() > 0) { if (all_tab.size() > 0) {
QTreeView* treeview = all_tab.first()->getCurrentTreeView(); QTreeView* treeview = all_tab.first()->getCurrentTreeView();
Preferences* const pref = Preferences::instance(); Preferences* const pref = Preferences::instance();
QStringList width_list; QStringList width_list;
QStringList new_width_list; QStringList new_width_list;
short nbColumns = all_tab.first()->getCurrentSearchListModel()->columnCount(); short nbColumns = all_tab.first()->getCurrentSearchListModel()->columnCount();
QString line = pref->getSearchColsWidth(); QString line = pref->getSearchColsWidth();
if (!line.isEmpty()) { if (!line.isEmpty()) {
width_list = line.split(' '); width_list = line.split(' ');
} }
for (short i=0; i<nbColumns; ++i) {
if (treeview->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) { for (short i=0; i<nbColumns; ++i) {
// load the former width if (treeview->columnWidth(i)<1 && width_list.size() == nbColumns && width_list.at(i).toInt()>=1) {
new_width_list << width_list.at(i); // load the former width
} else if (treeview->columnWidth(i)>=1) { new_width_list << width_list.at(i);
// usual case, save the current width } else if (treeview->columnWidth(i)>=1) {
new_width_list << QString::number(treeview->columnWidth(i)); // usual case, save the current width
} else { new_width_list << QString::number(treeview->columnWidth(i));
// default width } else {
treeview->resizeColumnToContents(i); // default width
new_width_list << QString::number(treeview->columnWidth(i)); treeview->resizeColumnToContents(i);
} new_width_list << QString::number(treeview->columnWidth(i));
}
}
pref->setSearchColsWidth(new_width_list.join(" "));
} }
pref->setSearchColsWidth(new_width_list.join(" "));
}
} }
void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) { void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) {
if (torrent_url.startsWith("bc://bt/", Qt::CaseInsensitive)) { if (torrent_url.startsWith("bc://bt/", Qt::CaseInsensitive)) {
qDebug("Converting bc link to magnet link"); qDebug("Converting bc link to magnet link");
torrent_url = misc::bcLinkToMagnet(torrent_url); torrent_url = misc::bcLinkToMagnet(torrent_url);
} }
qDebug() << Q_FUNC_INFO << torrent_url; qDebug() << Q_FUNC_INFO << torrent_url;
if (torrent_url.startsWith("magnet:")) { if (torrent_url.startsWith("magnet:")) {
QStringList urls; QStringList urls;
urls << torrent_url; urls << torrent_url;
mp_mainWindow->downloadFromURLList(urls); mp_mainWindow->downloadFromURLList(urls);
} else { } else {
QProcess *downloadProcess = new QProcess(this); QProcess *downloadProcess = new QProcess(this);
downloadProcess->setEnvironment(QProcess::systemEnvironment()); downloadProcess->setEnvironment(QProcess::systemEnvironment());
connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus))); connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus)));
downloaders << downloadProcess; downloaders << downloadProcess;
QStringList params; QStringList params;
params << fsutils::toNativePath(fsutils::searchEngineLocation() + "/nova2dl.py"); params << fsutils::toNativePath(fsutils::searchEngineLocation() + "/nova2dl.py");
params << engine_url; params << engine_url;
params << torrent_url; params << torrent_url;
// Launch search // Launch search
downloadProcess->start("python", params, QIODevice::ReadOnly); downloadProcess->start("python", params, QIODevice::ReadOnly);
} }
} }
void SearchEngine::searchStarted() { void SearchEngine::searchStarted() {
// Update SearchEngine widgets // Update SearchEngine widgets
search_status->setText(tr("Searching...")); search_status->setText(tr("Searching..."));
search_status->repaint(); search_status->repaint();
search_button->setText(tr("Stop")); search_button->setText(tr("Stop"));
} }
// search Qprocess return output as soon as it gets new // search Qprocess return output as soon as it gets new
// stuff to read. We split it into lines and add each // stuff to read. We split it into lines and add each
// line to search results calling appendSearchResult(). // line to search results calling appendSearchResult().
void SearchEngine::readSearchOutput() { void SearchEngine::readSearchOutput() {
QByteArray output = searchProcess->readAllStandardOutput(); QByteArray output = searchProcess->readAllStandardOutput();
output.replace("\r", ""); output.replace("\r", "");
QList<QByteArray> lines_list = output.split('\n'); QList<QByteArray> lines_list = output.split('\n');
if (!search_result_line_truncated.isEmpty()) { if (!search_result_line_truncated.isEmpty()) {
QByteArray end_of_line = lines_list.takeFirst(); QByteArray end_of_line = lines_list.takeFirst();
lines_list.prepend(search_result_line_truncated+end_of_line); lines_list.prepend(search_result_line_truncated+end_of_line);
} }
search_result_line_truncated = lines_list.takeLast().trimmed(); search_result_line_truncated = lines_list.takeLast().trimmed();
foreach (const QByteArray &line, lines_list) { foreach (const QByteArray &line, lines_list) {
appendSearchResult(QString::fromUtf8(line)); appendSearchResult(QString::fromUtf8(line));
} }
if (currentSearchTab) if (currentSearchTab)
currentSearchTab->getCurrentLabel()->setText(tr("Results")+QString::fromUtf8(" <i>(")+QString::number(nb_search_results)+QString::fromUtf8(")</i>:")); currentSearchTab->getCurrentLabel()->setText(tr("Results")+QString::fromUtf8(" <i>(")+QString::number(nb_search_results)+QString::fromUtf8(")</i>:"));
} }
void SearchEngine::downloadFinished(int exitcode, QProcess::ExitStatus) { void SearchEngine::downloadFinished(int exitcode, QProcess::ExitStatus) {
QProcess *downloadProcess = (QProcess*)sender(); QProcess *downloadProcess = (QProcess*)sender();
if (exitcode == 0) { if (exitcode == 0) {
QString line = QString::fromUtf8(downloadProcess->readAllStandardOutput()).trimmed(); QString line = QString::fromUtf8(downloadProcess->readAllStandardOutput()).trimmed();
QStringList parts = line.split(' '); QStringList parts = line.split(' ');
if (parts.size() == 2) { if (parts.size() == 2) {
QString path = parts[0]; QString path = parts[0];
QString url = parts[1]; QString url = parts[1];
QBtSession::instance()->processDownloadedFile(url, path); QBtSession::instance()->processDownloadedFile(url, path);
}
} }
} qDebug("Deleting downloadProcess");
qDebug("Deleting downloadProcess"); downloaders.removeOne(downloadProcess);
downloaders.removeOne(downloadProcess); delete downloadProcess;
delete downloadProcess;
} }
static void removePythonScriptIfExists(const QString& script_path) static void removePythonScriptIfExists(const QString& script_path)
@ -322,215 +346,216 @@ static void removePythonScriptIfExists(const QString& script_path)
// Update nova.py search plugin if necessary // Update nova.py search plugin if necessary
void SearchEngine::updateNova() { void SearchEngine::updateNova() {
qDebug("Updating nova"); qDebug("Updating nova");
// create nova directory if necessary // create nova directory if necessary
QDir search_dir(fsutils::searchEngineLocation()); QDir search_dir(fsutils::searchEngineLocation());
QString nova_folder = misc::pythonVersion() >= 3 ? "nova3" : "nova"; QString nova_folder = misc::pythonVersion() >= 3 ? "nova3" : "nova";
QFile package_file(search_dir.absoluteFilePath("__init__.py")); QFile package_file(search_dir.absoluteFilePath("__init__.py"));
package_file.open(QIODevice::WriteOnly | QIODevice::Text); package_file.open(QIODevice::WriteOnly | QIODevice::Text);
package_file.close(); package_file.close();
if (!search_dir.exists("engines")) { if (!search_dir.exists("engines")) {
search_dir.mkdir("engines"); search_dir.mkdir("engines");
} }
QFile package_file2(search_dir.absolutePath() + "/engines/__init__.py"); QFile package_file2(search_dir.absolutePath() + "/engines/__init__.py");
package_file2.open(QIODevice::WriteOnly | QIODevice::Text); package_file2.open(QIODevice::WriteOnly | QIODevice::Text);
package_file2.close(); package_file2.close();
// Copy search plugin files (if necessary) // Copy search plugin files (if necessary)
QString filePath = search_dir.absoluteFilePath("nova2.py"); QString filePath = search_dir.absoluteFilePath("nova2.py");
if (getPluginVersion(":/"+nova_folder+"/nova2.py") > getPluginVersion(filePath)) { if (getPluginVersion(":/"+nova_folder+"/nova2.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/nova2.py", filePath); QFile::copy(":/"+nova_folder+"/nova2.py", filePath);
} }
filePath = search_dir.absoluteFilePath("nova2dl.py");
if (getPluginVersion(":/"+nova_folder+"/nova2dl.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/nova2dl.py", filePath);
}
filePath = search_dir.absoluteFilePath("novaprinter.py"); filePath = search_dir.absoluteFilePath("nova2dl.py");
if (getPluginVersion(":/"+nova_folder+"/novaprinter.py") > getPluginVersion(filePath)) { if (getPluginVersion(":/"+nova_folder+"/nova2dl.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/novaprinter.py", filePath); QFile::copy(":/"+nova_folder+"/nova2dl.py", filePath);
} }
filePath = search_dir.absoluteFilePath("helpers.py"); filePath = search_dir.absoluteFilePath("novaprinter.py");
if (getPluginVersion(":/"+nova_folder+"/helpers.py") > getPluginVersion(filePath)) { if (getPluginVersion(":/"+nova_folder+"/novaprinter.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/helpers.py", filePath); QFile::copy(":/"+nova_folder+"/novaprinter.py", filePath);
} }
filePath = search_dir.absoluteFilePath("socks.py"); filePath = search_dir.absoluteFilePath("helpers.py");
removePythonScriptIfExists(filePath); if (getPluginVersion(":/"+nova_folder+"/helpers.py") > getPluginVersion(filePath)) {
QFile::copy(":/"+nova_folder+"/socks.py", filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/helpers.py", filePath);
}
if (nova_folder == "nova") { filePath = search_dir.absoluteFilePath("socks.py");
filePath = search_dir.absoluteFilePath("fix_encoding.py");
removePythonScriptIfExists(filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/fix_encoding.py", filePath); QFile::copy(":/"+nova_folder+"/socks.py", filePath);
}
if (nova_folder == "nova3") { if (nova_folder == "nova") {
filePath = search_dir.absoluteFilePath("sgmllib3.py"); filePath = search_dir.absoluteFilePath("fix_encoding.py");
removePythonScriptIfExists(filePath); removePythonScriptIfExists(filePath);
QFile::copy(":/"+nova_folder+"/sgmllib3.py", filePath); QFile::copy(":/"+nova_folder+"/fix_encoding.py", filePath);
} }
QDir destDir(QDir(fsutils::searchEngineLocation()).absoluteFilePath("engines"));
QDir shipped_subDir(":/"+nova_folder+"/engines/"); if (nova_folder == "nova3") {
QStringList files = shipped_subDir.entryList(); filePath = search_dir.absoluteFilePath("sgmllib3.py");
foreach (const QString &file, files) { removePythonScriptIfExists(filePath);
QString shipped_file = shipped_subDir.absoluteFilePath(file); QFile::copy(":/"+nova_folder+"/sgmllib3.py", filePath);
// Copy python classes }
if (file.endsWith(".py")) { QDir destDir(QDir(fsutils::searchEngineLocation()).absoluteFilePath("engines"));
const QString dest_file = destDir.absoluteFilePath(file); QDir shipped_subDir(":/"+nova_folder+"/engines/");
if (getPluginVersion(shipped_file) > getPluginVersion(dest_file) ) { QStringList files = shipped_subDir.entryList();
qDebug("shipped %s is more recent then local plugin, updating...", qPrintable(file)); foreach (const QString &file, files) {
removePythonScriptIfExists(dest_file); QString shipped_file = shipped_subDir.absoluteFilePath(file);
qDebug("%s copied to %s", qPrintable(shipped_file), qPrintable(dest_file)); // Copy python classes
QFile::copy(shipped_file, dest_file); if (file.endsWith(".py")) {
} const QString dest_file = destDir.absoluteFilePath(file);
} else { if (getPluginVersion(shipped_file) > getPluginVersion(dest_file) ) {
// Copy icons qDebug("shipped %s is more recent then local plugin, updating...", qPrintable(file));
if (file.endsWith(".png")) { removePythonScriptIfExists(dest_file);
if (!QFile::exists(destDir.absoluteFilePath(file))) { qDebug("%s copied to %s", qPrintable(shipped_file), qPrintable(dest_file));
QFile::copy(shipped_file, destDir.absoluteFilePath(file)); QFile::copy(shipped_file, dest_file);
}
} else {
// Copy icons
if (file.endsWith(".png")) {
if (!QFile::exists(destDir.absoluteFilePath(file))) {
QFile::copy(shipped_file, destDir.absoluteFilePath(file));
}
}
} }
}
} }
}
} }
// Slot called when search is Finished // Slot called when search is Finished
// Search can be finished for 3 reasons : // Search can be finished for 3 reasons :
// Error | Stopped by user | Finished normally // Error | Stopped by user | Finished normally
void SearchEngine::searchFinished(int exitcode,QProcess::ExitStatus) { void SearchEngine::searchFinished(int exitcode,QProcess::ExitStatus) {
if (searchTimeout->isActive()) { if (searchTimeout->isActive()) {
searchTimeout->stop(); searchTimeout->stop();
} }
bool useNotificationBalloons = Preferences::instance()->useProgramNotification(); bool useNotificationBalloons = Preferences::instance()->useProgramNotification();
if (useNotificationBalloons && mp_mainWindow->getCurrentTabWidget() != this) { if (useNotificationBalloons && mp_mainWindow->getCurrentTabWidget() != this) {
mp_mainWindow->showNotificationBaloon(tr("Search Engine"), tr("Search has finished")); mp_mainWindow->showNotificationBaloon(tr("Search Engine"), tr("Search has finished"));
} }
if (exitcode) { if (exitcode) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
search_status->setText(tr("Search aborted")); search_status->setText(tr("Search aborted"));
#else #else
search_status->setText(tr("An error occurred during search...")); search_status->setText(tr("An error occurred during search..."));
#endif #endif
}else{
if (search_stopped) {
search_status->setText(tr("Search aborted"));
}else{ }else{
if (no_search_results) { if (search_stopped) {
search_status->setText(tr("Search returned no results")); search_status->setText(tr("Search aborted"));
}else{ }else{
search_status->setText(tr("Search has finished")); if (no_search_results) {
} search_status->setText(tr("Search returned no results"));
}else{
search_status->setText(tr("Search has finished"));
}
}
} }
}
if (currentSearchTab) if (currentSearchTab)
currentSearchTab->getCurrentLabel()->setText(tr("Results", "i.e: Search results")+QString::fromUtf8(" <i>(")+QString::number(nb_search_results)+QString::fromUtf8(")</i>:")); currentSearchTab->getCurrentLabel()->setText(tr("Results", "i.e: Search results")+QString::fromUtf8(" <i>(")+QString::number(nb_search_results)+QString::fromUtf8(")</i>:"));
search_button->setText(tr("Search")); search_button->setText(tr("Search"));
} }
// SLOT to append one line to search results list // SLOT to append one line to search results list
// Line is in the following form : // Line is in the following form :
// file url | file name | file size | nb seeds | nb leechers | Search engine url // file url | file name | file size | nb seeds | nb leechers | Search engine url
void SearchEngine::appendSearchResult(const QString &line) { void SearchEngine::appendSearchResult(const QString &line) {
if (!currentSearchTab) { if (!currentSearchTab) {
if (searchProcess->state() != QProcess::NotRunning) { if (searchProcess->state() != QProcess::NotRunning) {
searchProcess->terminate(); searchProcess->terminate();
}
if (searchTimeout->isActive()) {
searchTimeout->stop();
}
search_stopped = true;
return;
} }
if (searchTimeout->isActive()) { const QStringList parts = line.split("|");
searchTimeout->stop(); const int nb_fields = parts.size();
if (nb_fields < NB_PLUGIN_COLUMNS-1) { //-1 because desc_link is optional
return;
} }
search_stopped = true; Q_ASSERT(currentSearchTab);
return; // Add item to search result list
} QStandardItemModel* cur_model = currentSearchTab->getCurrentSearchListModel();
const QStringList parts = line.split("|"); Q_ASSERT(cur_model);
const int nb_fields = parts.size(); int row = cur_model->rowCount();
if (nb_fields < NB_PLUGIN_COLUMNS-1) { //-1 because desc_link is optional cur_model->insertRow(row);
return;
} cur_model->setData(cur_model->index(row, SearchSortModel::DL_LINK), parts.at(PL_DL_LINK).trimmed()); // download URL
Q_ASSERT(currentSearchTab); cur_model->setData(cur_model->index(row, SearchSortModel::NAME), parts.at(PL_NAME).trimmed()); // Name
// Add item to search result list cur_model->setData(cur_model->index(row, SearchSortModel::SIZE), parts.at(PL_SIZE).trimmed().toLongLong()); // Size
QStandardItemModel* cur_model = currentSearchTab->getCurrentSearchListModel(); bool ok = false;
Q_ASSERT(cur_model); qlonglong nb_seeders = parts.at(PL_SEEDS).trimmed().toLongLong(&ok);
int row = cur_model->rowCount(); if (!ok || nb_seeders < 0) {
cur_model->insertRow(row); cur_model->setData(cur_model->index(row, SearchSortModel::SEEDS), tr("Unknown")); // Seeders
} else {
cur_model->setData(cur_model->index(row, SearchSortModel::DL_LINK), parts.at(PL_DL_LINK).trimmed()); // download URL cur_model->setData(cur_model->index(row, SearchSortModel::SEEDS), nb_seeders); // Seeders
cur_model->setData(cur_model->index(row, SearchSortModel::NAME), parts.at(PL_NAME).trimmed()); // Name }
cur_model->setData(cur_model->index(row, SearchSortModel::SIZE), parts.at(PL_SIZE).trimmed().toLongLong()); // Size qlonglong nb_leechers = parts.at(PL_LEECHS).trimmed().toLongLong(&ok);
bool ok = false; if (!ok || nb_leechers < 0) {
qlonglong nb_seeders = parts.at(PL_SEEDS).trimmed().toLongLong(&ok); cur_model->setData(cur_model->index(row, SearchSortModel::LEECHS), tr("Unknown")); // Leechers
if (!ok || nb_seeders < 0) { } else {
cur_model->setData(cur_model->index(row, SearchSortModel::SEEDS), tr("Unknown")); // Seeders cur_model->setData(cur_model->index(row, SearchSortModel::LEECHS), nb_leechers); // Leechers
} else { }
cur_model->setData(cur_model->index(row, SearchSortModel::SEEDS), nb_seeders); // Seeders cur_model->setData(cur_model->index(row, SearchSortModel::ENGINE_URL), parts.at(PL_ENGINE_URL).trimmed()); // Engine URL
} // Description Link
qlonglong nb_leechers = parts.at(PL_LEECHS).trimmed().toLongLong(&ok); if (nb_fields == NB_PLUGIN_COLUMNS)
if (!ok || nb_leechers < 0) { cur_model->setData(cur_model->index(row, SearchSortModel::DESC_LINK), parts.at(PL_DESC_LINK).trimmed());
cur_model->setData(cur_model->index(row, SearchSortModel::LEECHS), tr("Unknown")); // Leechers
} else { no_search_results = false;
cur_model->setData(cur_model->index(row, SearchSortModel::LEECHS), nb_leechers); // Leechers ++nb_search_results;
} // Enable clear & download buttons
cur_model->setData(cur_model->index(row, SearchSortModel::ENGINE_URL), parts.at(PL_ENGINE_URL).trimmed()); // Engine URL download_button->setEnabled(true);
// Description Link goToDescBtn->setEnabled(true);
if (nb_fields == NB_PLUGIN_COLUMNS)
cur_model->setData(cur_model->index(row, SearchSortModel::DESC_LINK), parts.at(PL_DESC_LINK).trimmed());
no_search_results = false;
++nb_search_results;
// Enable clear & download buttons
download_button->setEnabled(true);
goToDescBtn->setEnabled(true);
} }
void SearchEngine::closeTab(int index) { void SearchEngine::closeTab(int index) {
if (index == tabWidget->indexOf(currentSearchTab)) { if (index == tabWidget->indexOf(currentSearchTab)) {
qDebug("Deleted current search Tab"); qDebug("Deleted current search Tab");
if (searchProcess->state() != QProcess::NotRunning) { if (searchProcess->state() != QProcess::NotRunning) {
searchProcess->terminate(); searchProcess->terminate();
}
if (searchTimeout->isActive()) {
searchTimeout->stop();
}
search_stopped = true;
currentSearchTab = 0;
} }
if (searchTimeout->isActive()) { delete all_tab.takeAt(index);
searchTimeout->stop(); if (!all_tab.size()) {
download_button->setEnabled(false);
goToDescBtn->setEnabled(false);
} }
search_stopped = true;
currentSearchTab = 0;
}
delete all_tab.takeAt(index);
if (!all_tab.size()) {
download_button->setEnabled(false);
goToDescBtn->setEnabled(false);
}
} }
// Download selected items in search results list // Download selected items in search results list
void SearchEngine::on_download_button_clicked() { void SearchEngine::on_download_button_clicked() {
//QModelIndexList selectedIndexes = currentSearchTab->getCurrentTreeView()->selectionModel()->selectedIndexes(); //QModelIndexList selectedIndexes = currentSearchTab->getCurrentTreeView()->selectionModel()->selectedIndexes();
QModelIndexList selectedIndexes = all_tab.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = all_tab.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) {
// Get Item url // Get Item url
QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy(); QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy();
QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString(); QString torrent_url = model->data(model->index(index.row(), URL_COLUMN)).toString();
QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString(); QString engine_url = model->data(model->index(index.row(), ENGINE_URL_COLUMN)).toString();
downloadTorrent(engine_url, torrent_url); downloadTorrent(engine_url, torrent_url);
all_tab.at(tabWidget->currentIndex())->setRowColor(index.row(), "red"); all_tab.at(tabWidget->currentIndex())->setRowColor(index.row(), "red");
}
} }
}
} }
void SearchEngine::on_goToDescBtn_clicked() void SearchEngine::on_goToDescBtn_clicked()
{ {
QModelIndexList selectedIndexes = all_tab.at(tabWidget->currentIndex())->getCurrentTreeView()->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = all_tab.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) {
QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy(); QSortFilterProxyModel* model = all_tab.at(tabWidget->currentIndex())->getCurrentSearchListProxy();
const QString desc_url = model->data(model->index(index.row(), SearchSortModel::DESC_LINK)).toString(); const QString desc_url = model->data(model->index(index.row(), SearchSortModel::DESC_LINK)).toString();
if (!desc_url.isEmpty()) if (!desc_url.isEmpty())
QDesktopServices::openUrl(QUrl::fromEncoded(desc_url.toUtf8())); QDesktopServices::openUrl(QUrl::fromEncoded(desc_url.toUtf8()));
}
} }
}
} }

3
src/searchengine/searchengine.h

@ -60,6 +60,7 @@ public:
SearchEngine(MainWindow *mp_mainWindow); SearchEngine(MainWindow *mp_mainWindow);
~SearchEngine(); ~SearchEngine();
QString selectedCategory() const; QString selectedCategory() const;
QString selectedEngine() const;
static qreal getPluginVersion(QString filePath) { static qreal getPluginVersion(QString filePath) {
QFile plugin(filePath); QFile plugin(filePath);
@ -98,11 +99,13 @@ protected slots:
void readSearchOutput(); void readSearchOutput();
void searchStarted(); void searchStarted();
void updateNova(); void updateNova();
void selectMultipleBox(const QString &text);
void on_enginesButton_clicked(); void on_enginesButton_clicked();
void propagateSectionResized(int index, int oldsize , int newsize); void propagateSectionResized(int index, int oldsize , int newsize);
void saveResultsColumnsWidth(); void saveResultsColumnsWidth();
void downloadFinished(int exitcode, QProcess::ExitStatus); void downloadFinished(int exitcode, QProcess::ExitStatus);
void fillCatCombobox(); void fillCatCombobox();
void fillEngineComboBox();
void searchTextEdited(QString); void searchTextEdited(QString);
private slots: private slots:

6
src/searchengine/supportedengines.h

@ -113,6 +113,12 @@ public:
qDeleteAll(this->values()); qDeleteAll(this->values());
} }
QStringList enginesAll() const {
QStringList engines;
foreach (const SupportedEngine *engine, values()) engines << engine->getName();
return engines;
}
QStringList enginesEnabled() const { QStringList enginesEnabled() const {
QStringList engines; QStringList engines;
foreach (const SupportedEngine *engine, values()) { foreach (const SupportedEngine *engine, values()) {

Loading…
Cancel
Save