Browse Source

- Clean up search engine plugins code

- Update plugins from sourceforge SVN/trunk now to avoid maintenance of another update server
adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
03552c9a1f
  1. 262
      src/engineselectdlg.cpp
  2. 5
      src/engineselectdlg.h
  3. 23
      src/misc.h
  4. 10
      src/searchengine.cpp
  5. 23
      src/searchengine.h

262
src/engineselectdlg.cpp

@ -32,6 +32,7 @@
#include "downloadthread.h" #include "downloadthread.h"
#include "misc.h" #include "misc.h"
#include "ico.h" #include "ico.h"
#include "searchengine.h"
#include "pluginsource.h" #include "pluginsource.h"
#include <QProcess> #include <QProcess>
#include <QHeaderView> #include <QHeaderView>
@ -44,6 +45,7 @@
#include <QTemporaryFile> #include <QTemporaryFile>
enum EngineColumns {ENGINE_NAME, ENGINE_URL, ENGINE_STATE, ENGINE_ID}; enum EngineColumns {ENGINE_NAME, ENGINE_URL, ENGINE_STATE, ENGINE_ID};
#define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/trunk/src/search_engine/engines/"
engineSelectDlg::engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines) : QDialog(parent), supported_engines(supported_engines) { engineSelectDlg::engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines) : QDialog(parent), supported_engines(supported_engines) {
setupUi(this); setupUi(this);
@ -105,8 +107,8 @@ void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) {
} }
void engineSelectDlg::on_updateButton_clicked() { void engineSelectDlg::on_updateButton_clicked() {
// Download version file from primary server // Download version file from update server on sourceforge
downloader->downloadUrl("http://www.dchris.eu/search_engine2/versions.txt"); downloader->downloadUrl(QString(UPDATE_URL)+"versions.txt");
} }
void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) { void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) {
@ -243,17 +245,17 @@ QTreeWidgetItem* engineSelectDlg::findItemWithID(QString id){
} }
bool engineSelectDlg::isUpdateNeeded(QString plugin_name, float new_version) const { bool engineSelectDlg::isUpdateNeeded(QString plugin_name, float new_version) const {
float old_version = misc::getPluginVersion(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+plugin_name+".py"); float old_version = SearchEngine::getPluginVersion(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+plugin_name+".py");
qDebug("IsUpdate needed? tobeinstalled: %.2f, alreadyinstalled: %.2f", new_version, old_version); qDebug("IsUpdate needed? tobeinstalled: %.2f, alreadyinstalled: %.2f", new_version, old_version);
return (new_version > old_version); return (new_version > old_version);
} }
void engineSelectDlg::installPlugin(QString path, QString plugin_name) { void engineSelectDlg::installPlugin(QString path, QString plugin_name) {
qDebug("Asked to install plugin at %s", path.toLocal8Bit().data()); qDebug("Asked to install plugin at %s", path.toLocal8Bit().data());
float new_version = misc::getPluginVersion(path); float new_version = SearchEngine::getPluginVersion(path);
qDebug("Version to be installed: %.2f", new_version); qDebug("Version to be installed: %.2f", new_version);
if(!isUpdateNeeded(plugin_name, new_version)) { if(!isUpdateNeeded(plugin_name, new_version)) {
qDebug("Apparently update it not needed, we have a more recent version"); qDebug("Apparently update is not needed, we have a more recent version");
QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data()));
return; return;
} }
@ -337,150 +339,134 @@ void engineSelectDlg::addNewEngine(QString engine_name) {
} }
} }
void engineSelectDlg::on_installButton_clicked() { void engineSelectDlg::on_installButton_clicked() {
pluginSourceDlg *dlg = new pluginSourceDlg(this); pluginSourceDlg *dlg = new pluginSourceDlg(this);
connect(dlg, SIGNAL(askForLocalFile()), this, SLOT(askForLocalPlugin())); connect(dlg, SIGNAL(askForLocalFile()), this, SLOT(askForLocalPlugin()));
connect(dlg, SIGNAL(askForUrl()), this, SLOT(askForPluginUrl())); connect(dlg, SIGNAL(askForUrl()), this, SLOT(askForPluginUrl()));
} }
void engineSelectDlg::askForPluginUrl() { void engineSelectDlg::askForPluginUrl() {
bool ok; bool ok;
QString url = QInputDialog::getText(this, tr("New search engine plugin URL"), QString url = QInputDialog::getText(this, tr("New search engine plugin URL"),
tr("URL:"), QLineEdit::Normal, tr("URL:"), QLineEdit::Normal,
"http://", &ok); "http://", &ok);
if (ok && !url.isEmpty()) if (ok && !url.isEmpty())
downloader->downloadUrl(url); downloader->downloadUrl(url);
} }
void engineSelectDlg::askForLocalPlugin() { void engineSelectDlg::askForLocalPlugin() {
QStringList pathsList = QFileDialog::getOpenFileNames(0, QStringList pathsList = QFileDialog::getOpenFileNames(0,
tr("Select search plugins"), QDir::homePath(), tr("Select search plugins"), QDir::homePath(),
tr("qBittorrent search plugins")+QString::fromUtf8(" (*.py)")); tr("qBittorrent search plugins")+QString::fromUtf8(" (*.py)"));
QString path; QString path;
foreach(path, pathsList) { foreach(path, pathsList) {
if(path.endsWith(".py", Qt::CaseInsensitive)) { if(path.endsWith(".py", Qt::CaseInsensitive)) {
QString plugin_name = path.split(QDir::separator()).last(); QString plugin_name = path.split(QDir::separator()).last();
plugin_name.replace(".py", "", Qt::CaseInsensitive); plugin_name.replace(".py", "", Qt::CaseInsensitive);
installPlugin(path, plugin_name); installPlugin(path, plugin_name);
}
} }
} }
}
bool engineSelectDlg::parseVersionsFile(QString versions_file, QString updateServer) { bool engineSelectDlg::parseVersionsFile(QString versions_file) {
qDebug("Checking if update is needed"); qDebug("Checking if update is needed");
bool file_correct = false; bool file_correct = false;
QFile versions(versions_file); QFile versions(versions_file);
if(!versions.open(QIODevice::ReadOnly | QIODevice::Text)){ if(!versions.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug("* Error: Could not read versions.txt file"); qDebug("* Error: Could not read versions.txt file");
return false; return false;
} }
bool updated = false; bool updated = false;
while(!versions.atEnd()) { while(!versions.atEnd()) {
QByteArray line = versions.readLine(); QByteArray line = versions.readLine();
line.replace("\n", ""); line.replace("\n", "");
line = line.trimmed(); line = line.trimmed();
if(line.isEmpty()) continue; if(line.isEmpty()) continue;
if(line.startsWith("#")) continue; if(line.startsWith("#")) continue;
QList<QByteArray> list = line.split(' '); QList<QByteArray> list = line.split(' ');
if(list.size() != 2) continue; if(list.size() != 2) continue;
QString plugin_name = QString(list.first()); QString plugin_name = QString(list.first());
if(!plugin_name.endsWith(":")) continue; if(!plugin_name.endsWith(":")) continue;
plugin_name.chop(1); // remove trailing ':' plugin_name.chop(1); // remove trailing ':'
bool ok; bool ok;
float version = list.last().toFloat(&ok); float version = list.last().toFloat(&ok);
qDebug("read line %s: %.2f", plugin_name.toLocal8Bit().data(), version); qDebug("read line %s: %.2f", plugin_name.toLocal8Bit().data(), version);
if(!ok) continue; if(!ok) continue;
file_correct = true; file_correct = true;
if(isUpdateNeeded(plugin_name, version)) { if(isUpdateNeeded(plugin_name, version)) {
qDebug("Plugin: %s is outdated", plugin_name.toLocal8Bit().data()); qDebug("Plugin: %s is outdated", plugin_name.toLocal8Bit().data());
// Downloading update // Downloading update
downloader->downloadUrl(updateServer+plugin_name+".pyqBT"); // Actually this is really a .py downloader->downloadUrl(UPDATE_URL+plugin_name+".py");
downloader->downloadUrl(updateServer+plugin_name+".png"); //downloader->downloadUrl(UPDATE_URL+plugin_name+".png");
updated = true; updated = true;
}else { }else {
qDebug("Plugin: %s is up to date", plugin_name.toLocal8Bit().data()); qDebug("Plugin: %s is up to date", plugin_name.toLocal8Bit().data());
}
}
// Close file
versions.close();
// Clean up tmp file
QFile::remove(versions_file);
if(file_correct && !updated) {
QMessageBox::information(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("All your plugins are already up to date."));
} }
return file_correct;
} }
// Close file
versions.close();
// Clean up tmp file
QFile::remove(versions_file);
if(file_correct && !updated) {
QMessageBox::information(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("All your plugins are already up to date."));
}
return file_correct;
}
void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
qDebug("engineSelectDlg received %s", url.toLocal8Bit().data()); qDebug("engineSelectDlg received %s", url.toLocal8Bit().data());
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
// Icon downloaded // Icon downloaded
QImage fileIcon; QImage fileIcon;
if(fileIcon.load(filePath)) { if(fileIcon.load(filePath)) {
QList<QTreeWidgetItem*> items = findItemsWithUrl(url); QList<QTreeWidgetItem*> items = findItemsWithUrl(url);
QTreeWidgetItem *item; QTreeWidgetItem *item;
foreach(item, items){ foreach(item, items){
QString id = item->text(ENGINE_ID); QString id = item->text(ENGINE_ID);
QString iconPath; QString iconPath;
QFile icon(filePath); QFile icon(filePath);
icon.open(QIODevice::ReadOnly); icon.open(QIODevice::ReadOnly);
if(ICOHandler::canRead(&icon)) if(ICOHandler::canRead(&icon))
iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".ico"; iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".ico";
else else
iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".png"; iconPath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"engines"+QDir::separator()+id+".png";
QFile::copy(filePath, iconPath); QFile::copy(filePath, iconPath);
item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath))); item->setData(ENGINE_NAME, Qt::DecorationRole, QVariant(QIcon(iconPath)));
}
} }
// Delete tmp file
QFile::remove(filePath);
return;
}
if(url == "http://www.dchris.eu/search_engine2/versions.txt") {
if(!parseVersionsFile(filePath, "http://www.dchris.eu/search_engine2/")) {
qDebug("Primary update server failed, try secondary");
downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine2/versions.txt");
}
QFile::remove(filePath);
return;
}
if(url == "http://hydr0g3n.free.fr/search_engine2/versions.txt") {
if(!parseVersionsFile(filePath, "http://hydr0g3n.free.fr/search_engine2/")) {
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable."));
}
QFile::remove(filePath);
return;
}
if(url.endsWith(".pyqBT", Qt::CaseInsensitive) || url.endsWith(".py", Qt::CaseInsensitive)) {
QString plugin_name = url.split('/').last();
plugin_name.replace(".pyqBT", "");
plugin_name.replace(".py", "");
installPlugin(filePath, plugin_name);
QFile::remove(filePath);
return;
} }
// Delete tmp file
QFile::remove(filePath);
return;
} }
if(url.endsWith("versions.txt")) {
void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { if(!parseVersionsFile(filePath)) {
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
qDebug("Could not download favicon: %s, reason: %s", url.toLocal8Bit().data(), reason.toLocal8Bit().data());
return;
}
if(url == "http://www.dchris.eu/search_engine2/versions.txt") {
// Primary update server failed, try secondary
qDebug("Primary update server failed, try secondary");
downloader->downloadUrl("http://hydr0g3n.free.fr/search_engine2/versions.txt");
return;
}
if(url == "http://hydr0g3n.free.fr/search_engine2/versions.txt") {
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable.")); QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable."));
return;
}
if(url.endsWith(".pyqBT", Qt::CaseInsensitive) || url.endsWith(".py", Qt::CaseInsensitive)) {
// a plugin update download has been failed
QString plugin_name = url.split('/').last();
plugin_name.replace(".pyqBT", "", Qt::CaseInsensitive);
plugin_name.replace(".py", "", Qt::CaseInsensitive);
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data()));
} }
QFile::remove(filePath);
return;
}
if(url.endsWith(".py", Qt::CaseInsensitive)) {
QString plugin_name = url.split('/').last();
plugin_name.replace(".py", "");
installPlugin(filePath, plugin_name);
QFile::remove(filePath);
return;
} }
}
void engineSelectDlg::handleDownloadFailure(QString url, QString reason) {
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
qDebug("Could not download favicon: %s, reason: %s", url.toLocal8Bit().data(), reason.toLocal8Bit().data());
return;
}
if(url.endsWith("versions.txt")) {
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, update server is temporarily unavailable."));
return;
}
if(url.endsWith(".py", Qt::CaseInsensitive)) {
// a plugin update download has been failed
QString plugin_name = url.split('/').last();
plugin_name.replace(".py", "", Qt::CaseInsensitive);
QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data()));
}
}

5
src/engineselectdlg.h

@ -51,7 +51,7 @@ class engineSelectDlg : public QDialog, public Ui::engineSelect{
QTreeWidgetItem* findItemWithID(QString id); QTreeWidgetItem* findItemWithID(QString id);
protected: protected:
bool parseVersionsFile(QString versions_file, QString updateServer); bool parseVersionsFile(QString versions_file);
bool isUpdateNeeded(QString plugin_name, float new_version) const; bool isUpdateNeeded(QString plugin_name, float new_version) const;
signals: signals:
@ -76,9 +76,6 @@ class engineSelectDlg : public QDialog, public Ui::engineSelect{
void installPlugin(QString plugin_path, QString plugin_name); void installPlugin(QString plugin_path, QString plugin_name);
void askForLocalPlugin(); void askForLocalPlugin();
void askForPluginUrl(); void askForPluginUrl();
#ifdef HAVE_ZZIP
void installZipPlugin(QString path);
#endif
}; };
#endif #endif

23
src/misc.h

@ -269,29 +269,6 @@ public:
list.insert(i, value); list.insert(i, value);
} }
static float getPluginVersion(QString filePath) {
QFile plugin(filePath);
if(!plugin.exists()){
qDebug("%s plugin does not exist, returning 0.0", filePath.toLocal8Bit().data());
return 0.0;
}
if(!plugin.open(QIODevice::ReadOnly | QIODevice::Text)){
return 0.0;
}
float version = 0.0;
while (!plugin.atEnd()){
QByteArray line = plugin.readLine();
if(line.startsWith("#VERSION: ")){
line = line.split(' ').last();
line.replace("\n", "");
version = line.toFloat();
qDebug("plugin %s version: %.2f", filePath.toLocal8Bit().data(), version);
break;
}
}
return version;
}
static QString magnetUriToHash(QString magnet_uri) { static QString magnetUriToHash(QString magnet_uri) {
QString hash = ""; QString hash = "";
QRegExp reg("urn:btih:([A-Z2-7=]+)"); QRegExp reg("urn:btih:([A-Z2-7=]+)");

10
src/searchengine.cpp

@ -362,7 +362,7 @@ void SearchEngine::updateNova() {
package_file2.close(); package_file2.close();
// Copy search plugin files (if necessary) // Copy search plugin files (if necessary)
QString filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py"; QString filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
if(misc::getPluginVersion(":/search_engine/nova2.py") > misc::getPluginVersion(filePath)) { if(getPluginVersion(":/search_engine/nova2.py") > getPluginVersion(filePath)) {
if(QFile::exists(filePath)) if(QFile::exists(filePath))
QFile::remove(filePath); QFile::remove(filePath);
QFile::copy(":/search_engine/nova2.py", filePath); QFile::copy(":/search_engine/nova2.py", filePath);
@ -372,7 +372,7 @@ void SearchEngine::updateNova() {
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py").setPermissions(perm); QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py").setPermissions(perm);
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py"; filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py";
if(misc::getPluginVersion(":/search_engine/nova2dl.py") > misc::getPluginVersion(filePath)) { if(getPluginVersion(":/search_engine/nova2dl.py") > getPluginVersion(filePath)) {
if(QFile::exists(filePath)){ if(QFile::exists(filePath)){
QFile::remove(filePath); QFile::remove(filePath);
} }
@ -380,7 +380,7 @@ void SearchEngine::updateNova() {
} }
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py").setPermissions(perm); QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2dl.py").setPermissions(perm);
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py"; filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py";
if(misc::getPluginVersion(":/search_engine/novaprinter.py") > misc::getPluginVersion(filePath)) { if(getPluginVersion(":/search_engine/novaprinter.py") > getPluginVersion(filePath)) {
if(QFile::exists(filePath)){ if(QFile::exists(filePath)){
QFile::remove(filePath); QFile::remove(filePath);
} }
@ -388,7 +388,7 @@ void SearchEngine::updateNova() {
} }
QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py").setPermissions(perm); QFile(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"novaprinter.py").setPermissions(perm);
filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py"; filePath = misc::qBittorrentPath()+"search_engine"+QDir::separator()+"helpers.py";
if(misc::getPluginVersion(":/search_engine/helpers.py") > misc::getPluginVersion(filePath)) { if(getPluginVersion(":/search_engine/helpers.py") > getPluginVersion(filePath)) {
if(QFile::exists(filePath)){ if(QFile::exists(filePath)){
QFile::remove(filePath); QFile::remove(filePath);
} }
@ -402,7 +402,7 @@ void SearchEngine::updateNova() {
QString shipped_file = shipped_subDir.path()+"/"+file; QString shipped_file = shipped_subDir.path()+"/"+file;
// Copy python classes // Copy python classes
if(file.endsWith(".py")) { if(file.endsWith(".py")) {
if(misc::getPluginVersion(shipped_file) > misc::getPluginVersion(destDir+file) ) { if(getPluginVersion(shipped_file) > getPluginVersion(destDir+file) ) {
qDebug("shippped %s is more recent then local plugin, updating", file.toLocal8Bit().data()); qDebug("shippped %s is more recent then local plugin, updating", file.toLocal8Bit().data());
if(QFile::exists(destDir+file)) { if(QFile::exists(destDir+file)) {
qDebug("Removing old %s", (destDir+file).toLocal8Bit().data()); qDebug("Removing old %s", (destDir+file).toLocal8Bit().data());

23
src/searchengine.h

@ -73,9 +73,30 @@ private:
public: public:
SearchEngine(Bittorrent *BTSession, QSystemTrayIcon *systrayIcon); SearchEngine(Bittorrent *BTSession, QSystemTrayIcon *systrayIcon);
~SearchEngine(); ~SearchEngine();
float getPluginVersion(QString filePath) const;
QString selectedCategory() const; QString selectedCategory() const;
static float getPluginVersion(QString filePath) {
QFile plugin(filePath);
if(!plugin.exists()){
qDebug("%s plugin does not exist, returning 0.0", filePath.toLocal8Bit().data());
return 0.0;
}
if(!plugin.open(QIODevice::ReadOnly | QIODevice::Text)){
return 0.0;
}
float version = 0.0;
while (!plugin.atEnd()){
QByteArray line = plugin.readLine();
if(line.startsWith("#VERSION: ")){
line = line.split(' ').last().trimmed();
version = line.toFloat();
qDebug("plugin %s version: %.2f", filePath.toLocal8Bit().data(), version);
break;
}
}
return version;
}
public slots: public slots:
void on_download_button_clicked(); void on_download_button_clicked();
void downloadTorrent(QString engine_url, QString torrent_url); void downloadTorrent(QString engine_url, QString torrent_url);

Loading…
Cancel
Save