- Merged custom-search branch. New search plugins management system

This commit is contained in:
Christophe Dumez 2007-08-31 12:06:31 +00:00
parent b7fd7d9837
commit ff4ab915a2
28 changed files with 1427 additions and 934 deletions

View file

@ -45,8 +45,6 @@
SearchEngine::SearchEngine(bittorrent *BTSession, QSystemTrayIcon *myTrayIcon, bool systrayIntegration) : QWidget(), BTSession(BTSession), myTrayIcon(myTrayIcon), systrayIntegration(systrayIntegration){
setupUi(this);
downloader = new downloadThread(this);
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(novaUpdateDownloaded(QString, QString)));
connect(downloader, SIGNAL(downloadFailure(QString, QString)), this, SLOT(handleNovaDownloadFailure(QString, QString)));
// Set Search results list model
SearchListModel = new QStandardItemModel(0,5);
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
@ -81,21 +79,8 @@ SearchEngine::SearchEngine(bittorrent *BTSession, QSystemTrayIcon *myTrayIcon, b
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput()));
connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus)));
// Set search engines names
mininova->setText("Mininova");
piratebay->setText("ThePirateBay");
// reactor->setText("TorrentReactor");
isohunt->setText("Isohunt");
// btjunkie->setText("BTJunkie");
reactor->setText("TorrentReactor");
// Check last checked search engines
loadCheckedSearchEngines();
connect(mininova, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
connect(piratebay, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
// connect(reactor, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
connect(isohunt, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
// connect(btjunkie, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
connect(reactor, SIGNAL(stateChanged(int)), this, SLOT(saveCheckedSearchEngines(int)));
// Check last enabled search engines
loadEngineSettings();
// Update nova.py search plugin if necessary
updateNova();
}
@ -183,18 +168,6 @@ void SearchEngine::sortSearchListString(int index, Qt::SortOrder sortOrder){
SearchListModel->removeRows(0, nbRows_old);
}
// Save last checked search engines to a file
void SearchEngine::saveCheckedSearchEngines(int) const{
QSettings settings("qBittorrent", "qBittorrent");
settings.beginGroup("SearchEngines");
settings.setValue("mininova", mininova->isChecked());
settings.setValue("piratebay", piratebay->isChecked());
settings.setValue("isohunt", isohunt->isChecked());
settings.setValue("reactor", reactor->isChecked());
settings.endGroup();
qDebug("Saved checked search engines");
}
// Save columns width in a file to remember them
// (download list)
void SearchEngine::saveColWidthSearchList() const{
@ -208,6 +181,11 @@ void SearchEngine::saveColWidthSearchList() const{
qDebug("Search list columns width saved");
}
void SearchEngine::on_enginesButton_clicked() {
engineSelectDlg *dlg = new engineSelectDlg(this);
connect(dlg, SIGNAL(enginesChanged()), this, SLOT(loadEngineSettings()));
}
// Load columns width in a file that were saved previously
// (search list)
bool SearchEngine::loadColWidthSearchList(){
@ -226,19 +204,6 @@ bool SearchEngine::loadColWidthSearchList(){
return true;
}
// load last checked search engines from a file
void SearchEngine::loadCheckedSearchEngines(){
qDebug("Loading checked search engines");
QSettings settings("qBittorrent", "qBittorrent");
settings.beginGroup("SearchEngines");
mininova->setChecked(settings.value("mininova", true).toBool());
piratebay->setChecked(settings.value("piratebay", false).toBool());
isohunt->setChecked(settings.value("isohunt", false).toBool());
reactor->setChecked(settings.value("reactor", false).toBool());
settings.endGroup();
qDebug("Loaded checked search engines");
}
// get the last searchs from a QSettings to a QStringList
void SearchEngine::startSearchHistory(){
QSettings settings("qBittorrent", "qBittorrent");
@ -247,6 +212,24 @@ void SearchEngine::startSearchHistory(){
settings.endGroup();
}
void SearchEngine::loadEngineSettings() {
qDebug("Loading engine settings");
enabled_engines.clear();
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QStringList known_engines = settings.value(QString::fromUtf8("SearchEngines/knownEngines"), QStringList()).toStringList();
QVariantList known_enginesEnabled = settings.value(QString::fromUtf8("SearchEngines/knownEnginesEnabled"), QList<QVariant>()).toList();
QString engine;
unsigned int i = 0;
foreach(engine, known_engines) {
if(known_enginesEnabled.at(i).toBool())
enabled_engines << engine;
++i;
}
if(enabled_engines.empty())
enabled_engines << "all";
qDebug("Engine settings loaded");
}
// Save the history list into the QSettings for the next session
void SearchEngine::saveSearchHistory()
{
@ -282,33 +265,12 @@ void SearchEngine::on_search_button_clicked(){
// Getting checked search engines
if(!mininova->isChecked() && ! piratebay->isChecked() && !reactor->isChecked() && !isohunt->isChecked()/* && !btjunkie->isChecked()*/ /*&& !meganova->isChecked()*/){
QMessageBox::critical(0, tr("No search engine selected"), tr("You must select at least one search engine."));
return;
}
Q_ASSERT(!enabled_engines.empty());
QStringList params;
QStringList engineNames;
search_stopped = false;
// Get checked search engines
if(mininova->isChecked()){
engineNames << "mininova";
}
if(piratebay->isChecked()){
engineNames << "piratebay";
}
// if(reactor->isChecked()){
// engineNames << "reactor";
// }
if(isohunt->isChecked()){
engineNames << "isohunt";
}
// if(btjunkie->isChecked()){
// engineNames << "btjunkie";
// }
if(reactor->isChecked()){
engineNames << "reactor";
}
params << engineNames.join(",");
params << enabled_engines.join(",");
params << pattern.split(" ");
// Update SearchEngine widgets
no_search_results = true;
@ -316,7 +278,7 @@ void SearchEngine::on_search_button_clicked(){
search_result_line_truncated.clear();
results_lbl->setText(tr("Results")+" <i>(0)</i>:");
// Launch search
searchProcess->start(misc::qBittorrentPath()+"nova.py", params, QIODevice::ReadOnly);
searchProcess->start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly);
}
void SearchEngine::searchStarted(){
@ -360,137 +322,105 @@ void SearchEngine::readSearchOutput(){
results_lbl->setText(tr("Results")+QString::fromUtf8(" <i>(")+misc::toQString(nb_search_results)+QString::fromUtf8(")</i>:"));
}
// Returns version of nova.py search engine
float SearchEngine::getNovaVersion(QString novaPath) const{
QFile dest_nova(novaPath);
if(!dest_nova.exists()){
return 0.0;
}
if(!dest_nova.open(QIODevice::ReadOnly | QIODevice::Text)){
return 0.0;
}
float version = 0.0;
while (!dest_nova.atEnd()){
QByteArray line = dest_nova.readLine();
if(line.startsWith("# Version: ")){
line = line.split(' ').last();
line.chop(1); // removes '\n'
version = line.toFloat();
qDebug("Search plugin version: %.2f", version);
break;
}
}
return version;
}
// Returns changelog of nova.py search engine
QByteArray SearchEngine::getNovaChangelog(QString novaPath, float my_version) const{
QFile dest_nova(novaPath);
if(!dest_nova.exists()){
return QByteArray("None");
}
if(!dest_nova.open(QIODevice::ReadOnly | QIODevice::Text)){
return QByteArray("None");
}
QByteArray changelog;
bool in_changelog = false;
while (!dest_nova.atEnd()){
QByteArray line = dest_nova.readLine();
line = line.trimmed();
if(line.startsWith("# Changelog:")){
in_changelog = true;
}else{
if(line.isEmpty()){
in_changelog = false;
}
if(line.startsWith("# End Changelog")) break;
QString end_version = "# Version: ";
char tmp[5];
snprintf(tmp, 5, "%.2f", my_version);
end_version+=QString::fromUtf8(tmp);
if(line.startsWith((const char*)end_version.toUtf8())) break;
if(in_changelog){
line.remove(0,1);
line += "\n";
changelog.append(line);
}
}
}
return changelog;
}
// Update nova.py search plugin if necessary
void SearchEngine::updateNova() const{
void SearchEngine::updateNova() {
qDebug("Updating nova");
float provided_nova_version = getNovaVersion(":/search_engine/nova.py");
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
QFile(misc::qBittorrentPath()+"nova.py").setPermissions(perm);
if(provided_nova_version > getNovaVersion(misc::qBittorrentPath()+"nova.py")){
qDebug("updating local search plugin with shipped one");
// nova.py needs update
QFile::remove(misc::qBittorrentPath()+"nova.py");
qDebug("Old nova removed");
QFile::copy(":/search_engine/nova.py", misc::qBittorrentPath()+"nova.py");
qDebug("New nova copied");
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
QFile(misc::qBittorrentPath()+"nova.py").setPermissions(perm);
qDebug("local search plugin updated");
// create search_engine directory if necessary
QDir search_dir(misc::qBittorrentPath()+"search_engine");
if(!search_dir.exists()){
search_dir.mkdir(misc::qBittorrentPath()+"search_engine");
}
}
void SearchEngine::novaUpdateDownloaded(QString url, QString filePath){
float version_on_server = getNovaVersion(filePath);
qDebug("Version on qbittorrent.org: %.2f", version_on_server);
float my_version = getNovaVersion(misc::qBittorrentPath()+"nova.py");
if(version_on_server > my_version){
if(QMessageBox::question(this,
tr("Search plugin update -- qBittorrent"),
tr("Search plugin can be updated, do you want to update it?\n\nChangelog:\n")+getNovaChangelog(filePath, my_version),
tr("&Yes"), tr("&No"),
QString(), 0, 1)){
return;
}else{
qDebug("Updating search plugin from qbittorrent.org");
QFile::remove(misc::qBittorrentPath()+"nova.py");
QFile::copy(filePath, misc::qBittorrentPath()+"nova.py");
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
QFile(misc::qBittorrentPath()+"nova.py").setPermissions(perm);
}
}else{
if(version_on_server == 0.0){
if(url == "http://www.dchris.eu/nova/nova.zip"){
qDebug("*Warning: Search plugin update download from primary server failed, trying secondary server...");
downloader->downloadUrl("http://hydr0g3n.free.fr/nova/nova.py");
}else{
QMessageBox::information(this, tr("Search plugin update")+" -- "+tr("qBittorrent"),
tr("Sorry, update server is temporarily unavailable."));
QFile package_file(search_dir.path()+QDir::separator()+"__init__.py");
package_file.open(QIODevice::WriteOnly | QIODevice::Text);
package_file.close();
if(!search_dir.exists("engines")){
search_dir.mkdir("engines");
}
QFile package_file2(search_dir.path()+QDir::separator()+"engines"+QDir::separator()+"__init__.py");
package_file2.open(QIODevice::WriteOnly | QIODevice::Text);
package_file2.close();
// Copy search plugin files (if necessary)
QString filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
if(misc::getPluginVersion(":/search_engine/nova2.py") > misc::getPluginVersion(filePath)) {
if(QFile::exists(filePath))
QFile::remove(filePath);
QFile::copy(":/search_engine/nova2.py", misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py");
}
// Set permissions
QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py").setPermissions(perm);
if(!QFile::exists(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py")){
QFile::copy(":/search_engine/novaprinter.py", misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py");
}
QString subDir = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator();
QDir search_subDir(":/search_engine/engines");
QStringList files = search_subDir.entryList();
QString file;
foreach(file, files){
filePath = search_subDir.path()+QDir::separator()+file;
// Copy python classes
if(file.endsWith(".py")) {
if(misc::getPluginVersion(filePath) > misc::getPluginVersion(subDir+file) ) {
if(QFile::exists(filePath))
QFile::remove(filePath);
QFile::copy(filePath, subDir+file);
}
} else {
// Copy icons
if(file.endsWith(".png")) {
if(!QFile::exists(subDir+file)) {
QFile::copy(filePath, subDir+file);
}
}
}else{
QMessageBox::information(this, tr("Search plugin update -- qBittorrent"),
tr("Your search plugin is already up to date."));
}
}
// Delete tmp file
QFile::remove(filePath);
}
void SearchEngine::handleNovaDownloadFailure(QString url, QString reason){
if(url == "http://www.dchris.eu/nova/nova.zip"){
qDebug("*Warning: Search plugin update download from primary server failed, trying secondary server...");
downloader->downloadUrl("http://hydr0g3n.free.fr/nova/nova.py");
}else{
// Display a message box
QMessageBox::critical(0, tr("Search plugin download error"), tr("Couldn't download search plugin update at url: %1, reason: %2.").arg(url).arg(reason));
}
}
// Download nova.py from qbittorrent.org
// Check if our nova.py is outdated and
// ask user for action.
void SearchEngine::on_update_nova_button_clicked(){
qDebug("Checking for search plugin updates on qbittorrent.org");
downloader->downloadUrl("http://www.dchris.eu/nova/nova.zip");
}
// void SearchEngine::novaUpdateDownloaded(QString url, QString filePath){
// float version_on_server = getNovaVersion(filePath);
// qDebug("Version on qbittorrent.org: %.2f", version_on_server);
// float my_version = getNovaVersion(misc::qBittorrentPath()+"nova.py");
// if(version_on_server > my_version){
// if(QMessageBox::question(this,
// tr("Search plugin update -- qBittorrent"),
// tr("Search plugin can be updated, do you want to update it?\n\nChangelog:\n")+getNovaChangelog(filePath, my_version),
// tr("&Yes"), tr("&No"),
// QString(), 0, 1)){
// return;
// }else{
// qDebug("Updating search plugin from qbittorrent.org");
// QFile::remove(misc::qBittorrentPath()+"nova.py");
// QFile::copy(filePath, misc::qBittorrentPath()+"nova.py");
// QFile::Permissions perm=QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::ReadGroup;
// QFile(misc::qBittorrentPath()+"nova.py").setPermissions(perm);
// }
// }else{
// if(version_on_server == 0.0){
// if(url == "http://www.dchris.eu/nova/nova.zip"){
// qDebug("*Warning: Search plugin update download from primary server failed, trying secondary server...");
// downloader->downloadUrl("http://hydr0g3n.free.fr/nova/nova.py");
// }else{
// QMessageBox::information(this, tr("Search plugin update")+" -- "+tr("qBittorrent"),
// tr("Sorry, update server is temporarily unavailable."));
// }
// }else{
// QMessageBox::information(this, tr("Search plugin update -- qBittorrent"),
// tr("Your search plugin is already up to date."));
// }
// }
// // Delete tmp file
// QFile::remove(filePath);
// }
//
// void SearchEngine::handleNovaDownloadFailure(QString url, QString reason){
// if(url == "http://www.dchris.eu/nova/nova.zip"){
// qDebug("*Warning: Search plugin update download from primary server failed, trying secondary server...");
// downloader->downloadUrl("http://hydr0g3n.free.fr/nova/nova.py");
// }else{
// // Display a message box
// QMessageBox::critical(0, tr("Search plugin download error"), tr("Couldn't download search plugin update at url: %1, reason: %2.").arg(url).arg(reason));
// }
// }
// Slot called when search is Finished
// Search can be finished for 3 reasons :