qBittorrent
SearchPluginManager Class Reference

#include <searchpluginmanager.h>

Inheritance diagram for SearchPluginManager:
Collaboration diagram for SearchPluginManager:

Signals

void pluginEnabled (const QString &name, bool enabled)
 
void pluginInstalled (const QString &name)
 
void pluginInstallationFailed (const QString &name, const QString &reason)
 
void pluginUninstalled (const QString &name)
 
void pluginUpdated (const QString &name)
 
void pluginUpdateFailed (const QString &name, const QString &reason)
 
void checkForUpdatesFinished (const QHash< QString, PluginVersion > &updateInfo)
 
void checkForUpdatesFailed (const QString &reason)
 

Public Member Functions

 SearchPluginManager ()
 
 ~SearchPluginManager () override
 
QStringList allPlugins () const
 
QStringList enabledPlugins () const
 
QStringList supportedCategories () const
 
QStringList getPluginCategories (const QString &pluginName) const
 
PluginInfopluginInfo (const QString &name) const
 
void enablePlugin (const QString &name, bool enabled=true)
 
void updatePlugin (const QString &name)
 
void installPlugin (const QString &source)
 
bool uninstallPlugin (const QString &name)
 
void checkForUpdates ()
 
SearchHandlerstartSearch (const QString &pattern, const QString &category, const QStringList &usedPlugins)
 
SearchDownloadHandlerdownloadTorrent (const QString &siteUrl, const QString &url)
 
QString pluginFullName (const QString &pluginName)
 

Static Public Member Functions

static SearchPluginManagerinstance ()
 
static void freeInstance ()
 
static void updateIconPath (PluginInfo *const plugin)
 
static PluginVersion getPluginVersion (const QString &filePath)
 
static QString categoryFullName (const QString &categoryName)
 
static QString pluginsLocation ()
 
static QString engineLocation ()
 

Private Member Functions

void update ()
 
void updateNova ()
 
void parseVersionInfo (const QByteArray &info)
 
void installPlugin_impl (const QString &name, const QString &path)
 
bool isUpdateNeeded (const QString &pluginName, PluginVersion newVersion) const
 
void versionInfoDownloadFinished (const Net::DownloadResult &result)
 
void pluginDownloadFinished (const Net::DownloadResult &result)
 

Static Private Member Functions

static QString pluginPath (const QString &name)
 

Private Attributes

const QString m_updateUrl
 
QHash< QString, PluginInfo * > m_plugins
 

Static Private Attributes

static QPointer< SearchPluginManagerm_instance = nullptr
 

Detailed Description

Definition at line 60 of file searchpluginmanager.h.

Constructor & Destructor Documentation

◆ SearchPluginManager()

SearchPluginManager::SearchPluginManager ( )

Definition at line 86 of file searchpluginmanager.cpp.

87  : m_updateUrl(QLatin1String("http://searchplugins.qbittorrent.org/nova3/engines/"))
88 {
89  Q_ASSERT(!m_instance); // only one instance is allowed
90  m_instance = this;
91 
92  updateNova();
93  update();
94 }
static QPointer< SearchPluginManager > m_instance

References m_instance, update(), and updateNova().

Referenced by instance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~SearchPluginManager()

SearchPluginManager::~SearchPluginManager ( )
override

Definition at line 96 of file searchpluginmanager.cpp.

97 {
98  qDeleteAll(m_plugins);
99 }
QHash< QString, PluginInfo * > m_plugins

References m_plugins.

Member Function Documentation

◆ allPlugins()

QStringList SearchPluginManager::allPlugins ( ) const

Definition at line 113 of file searchpluginmanager.cpp.

114 {
115  return m_plugins.keys();
116 }

References m_plugins.

Referenced by getPluginCategories(), PluginSelectDialog::loadSupportedSearchPlugins(), SearchWidget::on_searchButton_clicked(), SearchController::pluginsAction(), and SearchController::startAction().

Here is the caller graph for this function:

◆ categoryFullName()

QString SearchPluginManager::categoryFullName ( const QString &  categoryName)
static

Definition at line 338 of file searchpluginmanager.cpp.

339 {
340  const QHash<QString, QString> categoryTable
341  {
342  {"all", tr("All categories")},
343  {"movies", tr("Movies")},
344  {"tv", tr("TV shows")},
345  {"music", tr("Music")},
346  {"games", tr("Games")},
347  {"anime", tr("Anime")},
348  {"software", tr("Software")},
349  {"pictures", tr("Pictures")},
350  {"books", tr("Books")}
351  };
352  return categoryTable.value(categoryName);
353 }

Referenced by SearchWidget::fillCatCombobox(), and anonymous_namespace{searchcontroller.cpp}::getPluginCategories().

Here is the caller graph for this function:

◆ checkForUpdates()

void SearchPluginManager::checkForUpdates ( )

Definition at line 317 of file searchpluginmanager.cpp.

318 {
319  // Download version file from update server
320  using namespace Net;
321  DownloadManager::instance()->download({m_updateUrl + "versions.txt"}
323 }
void versionInfoDownloadFinished(const Net::DownloadResult &result)
Definition: session.h:86

References m_updateUrl, and versionInfoDownloadFinished().

Referenced by PluginSelectDialog::on_updateButton_clicked(), and SearchController::updatePluginsAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkForUpdatesFailed

void SearchPluginManager::checkForUpdatesFailed ( const QString &  reason)
signal

◆ checkForUpdatesFinished

void SearchPluginManager::checkForUpdatesFinished ( const QHash< QString, PluginVersion > &  updateInfo)
signal

Referenced by parseVersionInfo(), PluginSelectDialog::PluginSelectDialog(), and SearchController::updatePluginsAction().

Here is the caller graph for this function:

◆ downloadTorrent()

SearchDownloadHandler * SearchPluginManager::downloadTorrent ( const QString &  siteUrl,
const QString &  url 
)

Definition at line 325 of file searchpluginmanager.cpp.

326 {
327  return new SearchDownloadHandler {siteUrl, url, this};
328 }

Referenced by SearchJobWidget::downloadTorrent().

Here is the caller graph for this function:

◆ enabledPlugins()

QStringList SearchPluginManager::enabledPlugins ( ) const

Definition at line 118 of file searchpluginmanager.cpp.

119 {
120  QStringList plugins;
121  for (const PluginInfo *plugin : asConst(m_plugins))
122  {
123  if (plugin->enabled)
124  plugins << plugin->name;
125  }
126 
127  return plugins;
128 }
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42

References asConst(), and m_plugins.

Referenced by getPluginCategories(), SearchWidget::on_searchButton_clicked(), and SearchController::startAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enablePlugin()

void SearchPluginManager::enablePlugin ( const QString &  name,
bool  enabled = true 
)

Definition at line 175 of file searchpluginmanager.cpp.

176 {
177  PluginInfo *plugin = m_plugins.value(name, nullptr);
178  if (plugin)
179  {
180  plugin->enabled = enabled;
181  // Save to Hard disk
182  Preferences *const pref = Preferences::instance();
183  QStringList disabledPlugins = pref->getSearchEngDisabled();
184  if (enabled)
185  disabledPlugins.removeAll(name);
186  else if (!disabledPlugins.contains(name))
187  disabledPlugins.append(name);
188  pref->setSearchEngDisabled(disabledPlugins);
189 
190  emit pluginEnabled(name, enabled);
191  }
192 }
static Preferences * instance()
QStringList getSearchEngDisabled() const
void setSearchEngDisabled(const QStringList &engines)
void pluginEnabled(const QString &name, bool enabled)

References PluginInfo::enabled, Preferences::getSearchEngDisabled(), Preferences::instance(), m_plugins, pluginEnabled(), and Preferences::setSearchEngDisabled().

Referenced by SearchController::enablePluginAction(), PluginSelectDialog::enableSelection(), PluginSelectDialog::on_actionUninstall_triggered(), and PluginSelectDialog::togglePluginState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ engineLocation()

QString SearchPluginManager::engineLocation ( )
static

Definition at line 365 of file searchpluginmanager.cpp.

366 {
367  static QString location;
368  if (location.isEmpty())
369  {
371 
372  const QDir locationDir(location);
373  locationDir.mkpath(locationDir.absolutePath());
374  }
375 
376  return location;
377 }
QString expandPathAbs(const QString &path)
Definition: fs.cpp:309
QString specialFolderLocation(const SpecialFolder folder)
Definition: profile.cpp:131

References Data, Utils::Fs::expandPathAbs(), and specialFolderLocation().

Referenced by installPlugin(), pluginsLocation(), SearchDownloadHandler::SearchDownloadHandler(), SearchHandler::SearchHandler(), uninstallPlugin(), update(), and updateNova().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ freeInstance()

void SearchPluginManager::freeInstance ( )
static

Definition at line 108 of file searchpluginmanager.cpp.

109 {
110  delete m_instance;
111 }

References m_instance.

Referenced by Application::cleanup().

Here is the caller graph for this function:

◆ getPluginCategories()

QStringList SearchPluginManager::getPluginCategories ( const QString &  pluginName) const

Definition at line 148 of file searchpluginmanager.cpp.

149 {
150  QStringList plugins;
151  if (pluginName == "all")
152  plugins = allPlugins();
153  else if ((pluginName == "enabled") || (pluginName == "multi"))
154  plugins = enabledPlugins();
155  else
156  plugins << pluginName.trimmed();
157 
158  QSet<QString> categories;
159  for (const QString &name : asConst(plugins))
160  {
161  const PluginInfo *plugin = pluginInfo(name);
162  if (!plugin) continue; // plugin wasn't found
163  for (const QString &category : plugin->supportedCategories)
164  categories << category;
165  }
166 
167  return categories.values();
168 }
PluginInfo * pluginInfo(const QString &name) const
QStringList enabledPlugins() const
QStringList allPlugins() const
QStringList supportedCategories

References allPlugins(), asConst(), enabledPlugins(), pluginInfo(), and PluginInfo::supportedCategories.

Here is the call graph for this function:

◆ getPluginVersion()

PluginVersion SearchPluginManager::getPluginVersion ( const QString &  filePath)
static

Definition at line 567 of file searchpluginmanager.cpp.

568 {
569  QFile pluginFile(filePath);
570  if (!pluginFile.open(QIODevice::ReadOnly | QIODevice::Text))
571  return {};
572 
573  while (!pluginFile.atEnd())
574  {
575  const QString line = QString(pluginFile.readLine()).remove(' ');
576  if (!line.startsWith("#VERSION:", Qt::CaseInsensitive)) continue;
577 
578  const QString versionStr = line.mid(9);
579  const PluginVersion version = PluginVersion::tryParse(versionStr, {});
580  if (version.isValid())
581  return version;
582 
583  LogMsg(tr("Search plugin '%1' contains invalid version string ('%2')")
584  .arg(Utils::Fs::fileName(filePath), versionStr), Log::MsgType::WARNING);
585  break;
586  }
587 
588  return {};
589 }
static Version tryParse(const StringClassWithSplitMethod &s, const Version &defaultVersion)
Definition: version.h:143
constexpr bool isValid() const
Definition: version.h:126
void LogMsg(const QString &message, const Log::MsgType &type)
Definition: logger.cpp:125
@ WARNING
Definition: logger.h:47
QString fileName(const QString &filePath)
Definition: fs.cpp:87

References Utils::Fs::fileName(), Utils::Version< T, N, Mandatory >::isValid(), LogMsg(), Utils::Version< unsigned short, 2 >::tryParse(), and Log::WARNING.

Referenced by installPlugin_impl(), update(), and updateNova().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ installPlugin()

void SearchPluginManager::installPlugin ( const QString &  source)

Definition at line 201 of file searchpluginmanager.cpp.

202 {
204 
206  {
207  using namespace Net;
208  DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true)
210  }
211  else
212  {
213  QString path = source;
214  if (path.startsWith("file:", Qt::CaseInsensitive))
215  path = QUrl(path).toLocalFile();
216 
217  QString pluginName = Utils::Fs::fileName(path);
218  pluginName.chop(pluginName.size() - pluginName.lastIndexOf('.'));
219 
220  if (!path.endsWith(".py", Qt::CaseInsensitive))
221  emit pluginInstallationFailed(pluginName, tr("Unknown search engine plugin file format."));
222  else
223  installPlugin_impl(pluginName, path);
224  }
225 }
static bool hasSupportedScheme(const QString &url)
void installPlugin_impl(const QString &name, const QString &path)
void pluginInstallationFailed(const QString &name, const QString &reason)
static QString engineLocation()
void pluginDownloadFinished(const Net::DownloadResult &result)
nonstd::expected< void, QString > saveToFile(const QString &path, const QByteArray &data)
Definition: io.cpp:69

References anonymous_namespace{searchpluginmanager.cpp}::clearPythonCache(), engineLocation(), Utils::Fs::fileName(), Net::DownloadManager::hasSupportedScheme(), installPlugin_impl(), pluginDownloadFinished(), pluginInstallationFailed(), Utils::IO::saveToFile(), and anonymous_namespace{misc.cpp}::source.

Referenced by PluginSelectDialog::askForLocalPlugin(), PluginSelectDialog::askForPluginUrl(), PluginSelectDialog::dropEvent(), SearchController::installPluginAction(), and updatePlugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ installPlugin_impl()

void SearchPluginManager::installPlugin_impl ( const QString &  name,
const QString &  path 
)
private

Definition at line 227 of file searchpluginmanager.cpp.

228 {
229  const PluginVersion newVersion = getPluginVersion(path);
230  const PluginInfo *plugin = pluginInfo(name);
231  if (plugin && !(plugin->version < newVersion))
232  {
233  LogMsg(tr("Plugin already at version %1, which is greater than %2").arg(plugin->version, newVersion), Log::INFO);
234  emit pluginUpdateFailed(name, tr("A more recent version of this plugin is already installed."));
235  return;
236  }
237 
238  // Process with install
239  const QString destPath = pluginPath(name);
240  bool updated = false;
241  if (QFile::exists(destPath))
242  {
243  // Backup in case install fails
244  QFile::copy(destPath, destPath + ".bak");
245  Utils::Fs::forceRemove(destPath);
246  updated = true;
247  }
248  // Copy the plugin
249  QFile::copy(path, destPath);
250  // Update supported plugins
251  update();
252  // Check if this was correctly installed
253  if (!m_plugins.contains(name))
254  {
255  // Remove broken file
256  Utils::Fs::forceRemove(destPath);
257  LogMsg(tr("Plugin %1 is not supported.").arg(name), Log::INFO);
258  if (updated)
259  {
260  // restore backup
261  QFile::copy(destPath + ".bak", destPath);
262  Utils::Fs::forceRemove(destPath + ".bak");
263  // Update supported plugins
264  update();
265  emit pluginUpdateFailed(name, tr("Plugin is not supported."));
266  }
267  else
268  {
269  emit pluginInstallationFailed(name, tr("Plugin is not supported."));
270  }
271  }
272  else
273  {
274  // Install was successful, remove backup
275  if (updated)
276  {
277  LogMsg(tr("Plugin %1 has been successfully updated.").arg(name), Log::INFO);
278  Utils::Fs::forceRemove(destPath + ".bak");
279  }
280  }
281 }
static QString pluginPath(const QString &name)
static PluginVersion getPluginVersion(const QString &filePath)
void pluginUpdateFailed(const QString &name, const QString &reason)
flag icons free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
@ INFO
Definition: logger.h:46
bool forceRemove(const QString &filePath)
Definition: fs.cpp:173
PluginVersion version

References copy, Utils::Fs::forceRemove(), getPluginVersion(), Log::INFO, LogMsg(), m_plugins, pluginInfo(), pluginInstallationFailed(), pluginPath(), pluginUpdateFailed(), update(), and PluginInfo::version.

Referenced by installPlugin(), and pluginDownloadFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ instance()

◆ isUpdateNeeded()

bool SearchPluginManager::isUpdateNeeded ( const QString &  pluginName,
PluginVersion  newVersion 
) const
private

Definition at line 553 of file searchpluginmanager.cpp.

554 {
555  const PluginInfo *plugin = pluginInfo(pluginName);
556  if (!plugin) return true;
557 
558  PluginVersion oldVersion = plugin->version;
559  return (newVersion > oldVersion);
560 }

References pluginInfo(), and PluginInfo::version.

Referenced by parseVersionInfo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseVersionInfo()

void SearchPluginManager::parseVersionInfo ( const QByteArray &  info)
private

Definition at line 514 of file searchpluginmanager.cpp.

515 {
516  QHash<QString, PluginVersion> updateInfo;
517  int numCorrectData = 0;
518 
519  const QVector<QByteArray> lines = Utils::ByteArray::splitToViews(info, "\n", Qt::SkipEmptyParts);
520  for (QByteArray line : lines)
521  {
522  line = line.trimmed();
523  if (line.isEmpty()) continue;
524  if (line.startsWith('#')) continue;
525 
526  const QVector<QByteArray> list = Utils::ByteArray::splitToViews(line, ":", Qt::SkipEmptyParts);
527  if (list.size() != 2) continue;
528 
529  const QString pluginName = list.first().trimmed();
530  const PluginVersion version = PluginVersion::tryParse(list.last().trimmed(), {});
531 
532  if (!version.isValid()) continue;
533 
534  ++numCorrectData;
535  if (isUpdateNeeded(pluginName, version))
536  {
537  LogMsg(tr("Plugin \"%1\" is outdated, updating to version %2").arg(pluginName, version), Log::INFO);
538  updateInfo[pluginName] = version;
539  }
540  }
541 
542  if (numCorrectData < lines.size())
543  {
544  emit checkForUpdatesFailed(tr("Incorrect update info received for %1 out of %2 plugins.")
545  .arg(QString::number(lines.size() - numCorrectData), QString::number(lines.size())));
546  }
547  else
548  {
549  emit checkForUpdatesFinished(updateInfo);
550  }
551 }
bool isUpdateNeeded(const QString &pluginName, PluginVersion newVersion) const
void checkForUpdatesFinished(const QHash< QString, PluginVersion > &updateInfo)
void checkForUpdatesFailed(const QString &reason)
QVector< QByteArray > splitToViews(const QByteArray &in, const QByteArray &sep, const Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
Definition: bytearray.cpp:34

References checkForUpdatesFailed(), checkForUpdatesFinished(), Log::INFO, isUpdateNeeded(), Utils::Version< T, N, Mandatory >::isValid(), LogMsg(), Utils::ByteArray::splitToViews(), and Utils::Version< unsigned short, 2 >::tryParse().

Referenced by versionInfoDownloadFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginDownloadFinished()

void SearchPluginManager::pluginDownloadFinished ( const Net::DownloadResult result)
private

Definition at line 387 of file searchpluginmanager.cpp.

388 {
389  if (result.status == Net::DownloadStatus::Success)
390  {
391  const QString filePath = Utils::Fs::toUniformPath(result.filePath);
392 
393  QString pluginName = Utils::Fs::fileName(result.url);
394  pluginName.chop(pluginName.size() - pluginName.lastIndexOf('.')); // Remove extension
395  installPlugin_impl(pluginName, filePath);
396  Utils::Fs::forceRemove(filePath);
397  }
398  else
399  {
400  const QString url = result.url;
401  QString pluginName = url.mid(url.lastIndexOf('/') + 1);
402  pluginName.replace(".py", "", Qt::CaseInsensitive);
403 
404  if (pluginInfo(pluginName))
405  emit pluginUpdateFailed(pluginName, tr("Failed to download the plugin file. %1").arg(result.errorString));
406  else
407  emit pluginInstallationFailed(pluginName, tr("Failed to download the plugin file. %1").arg(result.errorString));
408  }
409 }
QString toUniformPath(const QString &path)
Definition: fs.cpp:69
DownloadStatus status

References Net::DownloadResult::errorString, Utils::Fs::fileName(), Net::DownloadResult::filePath, Utils::Fs::forceRemove(), installPlugin_impl(), pluginInfo(), pluginInstallationFailed(), pluginUpdateFailed(), Net::DownloadResult::status, Net::Success, Utils::Fs::toUniformPath(), and Net::DownloadResult::url.

Referenced by installPlugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginEnabled

void SearchPluginManager::pluginEnabled ( const QString &  name,
bool  enabled 
)
signal

Referenced by enablePlugin(), and SearchWidget::SearchWidget().

Here is the caller graph for this function:

◆ pluginFullName()

QString SearchPluginManager::pluginFullName ( const QString &  pluginName)

Definition at line 355 of file searchpluginmanager.cpp.

356 {
357  return pluginInfo(pluginName) ? pluginInfo(pluginName)->fullName : QString();
358 }

References PluginInfo::fullName, and pluginInfo().

Here is the call graph for this function:

◆ pluginInfo()

◆ pluginInstallationFailed

void SearchPluginManager::pluginInstallationFailed ( const QString &  name,
const QString &  reason 
)
signal

Referenced by installPlugin(), installPlugin_impl(), pluginDownloadFinished(), and PluginSelectDialog::PluginSelectDialog().

Here is the caller graph for this function:

◆ pluginInstalled

void SearchPluginManager::pluginInstalled ( const QString &  name)
signal

Referenced by PluginSelectDialog::PluginSelectDialog(), SearchWidget::SearchWidget(), and update().

Here is the caller graph for this function:

◆ pluginPath()

QString SearchPluginManager::pluginPath ( const QString &  name)
staticprivate

Definition at line 562 of file searchpluginmanager.cpp.

563 {
564  return QString::fromLatin1("%1/%2.py").arg(pluginsLocation(), name);
565 }
static QString pluginsLocation()

References pluginsLocation().

Referenced by installPlugin_impl(), and update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginsLocation()

QString SearchPluginManager::pluginsLocation ( )
static

Definition at line 360 of file searchpluginmanager.cpp.

361 {
362  return QString::fromLatin1("%1/engines").arg(engineLocation());
363 }

References engineLocation().

Referenced by PluginSelectDialog::iconDownloadFinished(), pluginPath(), uninstallPlugin(), and updateIconPath().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginUninstalled

void SearchPluginManager::pluginUninstalled ( const QString &  name)
signal

Referenced by SearchWidget::SearchWidget(), and uninstallPlugin().

Here is the caller graph for this function:

◆ pluginUpdated

void SearchPluginManager::pluginUpdated ( const QString &  name)
signal

Referenced by PluginSelectDialog::PluginSelectDialog(), SearchWidget::SearchWidget(), and update().

Here is the caller graph for this function:

◆ pluginUpdateFailed

void SearchPluginManager::pluginUpdateFailed ( const QString &  name,
const QString &  reason 
)
signal

Referenced by installPlugin_impl(), pluginDownloadFinished(), and PluginSelectDialog::PluginSelectDialog().

Here is the caller graph for this function:

◆ startSearch()

SearchHandler * SearchPluginManager::startSearch ( const QString &  pattern,
const QString &  category,
const QStringList &  usedPlugins 
)

Definition at line 330 of file searchpluginmanager.cpp.

331 {
332  // No search pattern entered
333  Q_ASSERT(!pattern.isEmpty());
334 
335  return new SearchHandler {pattern, category, usedPlugins, this};
336 }

Referenced by SearchWidget::on_searchButton_clicked(), and SearchController::startAction().

Here is the caller graph for this function:

◆ supportedCategories()

QStringList SearchPluginManager::supportedCategories ( ) const

Definition at line 130 of file searchpluginmanager.cpp.

131 {
132  QStringList result;
133  for (const PluginInfo *plugin : asConst(m_plugins))
134  {
135  if (plugin->enabled)
136  {
137  for (const QString &cat : plugin->supportedCategories)
138  {
139  if (!result.contains(cat))
140  result << cat;
141  }
142  }
143  }
144 
145  return result;
146 }

References asConst(), and m_plugins.

Here is the call graph for this function:

◆ uninstallPlugin()

bool SearchPluginManager::uninstallPlugin ( const QString &  name)

Definition at line 283 of file searchpluginmanager.cpp.

284 {
286 
287  // remove it from hard drive
288  const QDir pluginsFolder(pluginsLocation());
289  QStringList filters;
290  filters << name + ".*";
291  const QStringList files = pluginsFolder.entryList(filters, QDir::Files, QDir::Unsorted);
292  for (const QString &file : files)
293  Utils::Fs::forceRemove(pluginsFolder.absoluteFilePath(file));
294  // Remove it from supported engines
295  delete m_plugins.take(name);
296 
297  emit pluginUninstalled(name);
298  return true;
299 }
void pluginUninstalled(const QString &name)
flag icons free of to any person obtaining a copy of this software and associated documentation files(the "Software")
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts") set_source_files_properties($
Definition: CMakeLists.txt:5

References anonymous_namespace{searchpluginmanager.cpp}::clearPythonCache(), engineLocation(), file(), files(), Utils::Fs::forceRemove(), m_plugins, pluginsLocation(), and pluginUninstalled().

Referenced by PluginSelectDialog::on_actionUninstall_triggered(), and SearchController::uninstallPluginAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update()

void SearchPluginManager::update ( )
private

Definition at line 448 of file searchpluginmanager.cpp.

449 {
450  QProcess nova;
451  nova.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
452 
453  const QStringList params {Utils::Fs::toNativePath(engineLocation() + "/nova2.py"), "--capabilities"};
454  nova.start(Utils::ForeignApps::pythonInfo().executableName, params, QIODevice::ReadOnly);
455  nova.waitForFinished();
456 
457  const QString capabilities = nova.readAll();
458  QDomDocument xmlDoc;
459  if (!xmlDoc.setContent(capabilities))
460  {
461  qWarning() << "Could not parse Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data();
462  qWarning() << "Error: " << nova.readAllStandardError().constData();
463  return;
464  }
465 
466  const QDomElement root = xmlDoc.documentElement();
467  if (root.tagName() != "capabilities")
468  {
469  qWarning() << "Invalid XML file for Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data();
470  return;
471  }
472 
473  for (QDomNode engineNode = root.firstChild(); !engineNode.isNull(); engineNode = engineNode.nextSibling())
474  {
475  const QDomElement engineElem = engineNode.toElement();
476  if (!engineElem.isNull())
477  {
478  const QString pluginName = engineElem.tagName();
479 
480  auto plugin = std::make_unique<PluginInfo>();
481  plugin->name = pluginName;
482  plugin->version = getPluginVersion(pluginPath(pluginName));
483  plugin->fullName = engineElem.elementsByTagName("name").at(0).toElement().text();
484  plugin->url = engineElem.elementsByTagName("url").at(0).toElement().text();
485 
486  const QStringList categories = engineElem.elementsByTagName("categories").at(0).toElement().text().split(' ');
487  for (QString cat : categories)
488  {
489  cat = cat.trimmed();
490  if (!cat.isEmpty())
491  plugin->supportedCategories << cat;
492  }
493 
494  const QStringList disabledEngines = Preferences::instance()->getSearchEngDisabled();
495  plugin->enabled = !disabledEngines.contains(pluginName);
496 
497  updateIconPath(plugin.get());
498 
499  if (!m_plugins.contains(pluginName))
500  {
501  m_plugins[pluginName] = plugin.release();
502  emit pluginInstalled(pluginName);
503  }
504  else if (m_plugins[pluginName]->version != plugin->version)
505  {
506  delete m_plugins.take(pluginName);
507  m_plugins[pluginName] = plugin.release();
508  emit pluginUpdated(pluginName);
509  }
510  }
511  }
512 }
void pluginUpdated(const QString &name)
static void updateIconPath(PluginInfo *const plugin)
void pluginInstalled(const QString &name)
PythonInfo pythonInfo()
QString toNativePath(const QString &path)
Definition: fs.cpp:64

References engineLocation(), getPluginVersion(), Preferences::getSearchEngDisabled(), Preferences::instance(), m_plugins, pluginInstalled(), pluginPath(), pluginUpdated(), Utils::ForeignApps::pythonInfo(), Utils::Fs::toNativePath(), and updateIconPath().

Referenced by installPlugin_impl(), and SearchPluginManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateIconPath()

void SearchPluginManager::updateIconPath ( PluginInfo *const  plugin)
static

Definition at line 301 of file searchpluginmanager.cpp.

302 {
303  if (!plugin) return;
304  QString iconPath = QString::fromLatin1("%1/%2.png").arg(pluginsLocation(), plugin->name);
305  if (QFile::exists(iconPath))
306  {
307  plugin->iconPath = iconPath;
308  }
309  else
310  {
311  iconPath = QString::fromLatin1("%1/%2.ico").arg(pluginsLocation(), plugin->name);
312  if (QFile::exists(iconPath))
313  plugin->iconPath = iconPath;
314  }
315 }

References PluginInfo::iconPath, PluginInfo::name, and pluginsLocation().

Referenced by PluginSelectDialog::iconDownloadFinished(), and update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateNova()

void SearchPluginManager::updateNova ( )
private

Definition at line 412 of file searchpluginmanager.cpp.

413 {
414  // create nova directory if necessary
415  const QDir searchDir(engineLocation());
416 
417  QFile packageFile(searchDir.absoluteFilePath("__init__.py"));
418  packageFile.open(QIODevice::WriteOnly);
419  packageFile.close();
420 
421  searchDir.mkdir("engines");
422 
423  QFile packageFile2(searchDir.absolutePath() + "/engines/__init__.py");
424  packageFile2.open(QIODevice::WriteOnly);
425  packageFile2.close();
426 
427  // Copy search plugin files (if necessary)
428  const auto updateFile = [](const QString &filename, const bool compareVersion)
429  {
430  const QString filePathBundled = ":/searchengine/nova3/" + filename;
431  const QString filePathDisk = QDir(engineLocation()).absoluteFilePath(filename);
432 
433  if (compareVersion && (getPluginVersion(filePathBundled) <= getPluginVersion(filePathDisk)))
434  return;
435 
436  Utils::Fs::forceRemove(filePathDisk);
437  QFile::copy(filePathBundled, filePathDisk);
438  };
439 
440  updateFile("helpers.py", true);
441  updateFile("nova2.py", true);
442  updateFile("nova2dl.py", true);
443  updateFile("novaprinter.py", true);
444  updateFile("sgmllib3.py", false);
445  updateFile("socks.py", false);
446 }

References copy, engineLocation(), Utils::Fs::forceRemove(), and getPluginVersion().

Referenced by SearchPluginManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updatePlugin()

void SearchPluginManager::updatePlugin ( const QString &  name)

Definition at line 195 of file searchpluginmanager.cpp.

196 {
197  installPlugin(QString::fromLatin1("%1%2.py").arg(m_updateUrl, name));
198 }
void installPlugin(const QString &source)

References installPlugin(), and m_updateUrl.

Referenced by PluginSelectDialog::checkForUpdatesFinished(), and SearchController::checkForUpdatesFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ versionInfoDownloadFinished()

void SearchPluginManager::versionInfoDownloadFinished ( const Net::DownloadResult result)
private

Definition at line 379 of file searchpluginmanager.cpp.

380 {
381  if (result.status == Net::DownloadStatus::Success)
382  parseVersionInfo(result.data);
383  else
384  emit checkForUpdatesFailed(tr("Update server is temporarily unavailable. %1").arg(result.errorString));
385 }
void parseVersionInfo(const QByteArray &info)

References checkForUpdatesFailed(), Net::DownloadResult::data, Net::DownloadResult::errorString, parseVersionInfo(), Net::DownloadResult::status, and Net::Success.

Referenced by checkForUpdates().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_instance

QPointer< SearchPluginManager > SearchPluginManager::m_instance = nullptr
staticprivate

Definition at line 117 of file searchpluginmanager.h.

Referenced by freeInstance(), instance(), and SearchPluginManager().

◆ m_plugins

QHash<QString, PluginInfo*> SearchPluginManager::m_plugins
private

◆ m_updateUrl

const QString SearchPluginManager::m_updateUrl
private

Definition at line 119 of file searchpluginmanager.h.

Referenced by checkForUpdates(), and updatePlugin().


The documentation for this class was generated from the following files: