------------------------------------------------------------ revno: 3276 committer: poy <p...@123gen.com> branch nick: trunk timestamp: Thu 2013-04-25 20:08:15 +0200 message: allow updating plugins rather than refusing to install modified: dcpp/PluginManager.cpp dcpp/PluginManager.h dcpp/forward.h win32/PluginInfoDlg.cpp win32/PluginInfoDlg.h win32/PluginPage.cpp win32/PluginPage.h
-- lp:dcplusplus https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk Your team Dcplusplus-team is subscribed to branch lp:dcplusplus. To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/PluginManager.cpp' --- dcpp/PluginManager.cpp 2013-04-23 17:41:14 +0000 +++ dcpp/PluginManager.cpp 2013-04-25 18:08:15 +0000 @@ -81,7 +81,7 @@ SimpleXML xml; xml.fromXML(File(info_path, File::READ, File::OPEN).read()); - DcextInfo info; + DcextInfo info { }; if(xml.findChild("dcext")) { xml.stepIn(); @@ -114,7 +114,7 @@ string version; parse("ApiVersion", version); if(Util::toInt(version) < DCAPI_CORE_VER) { - throw str(F_("%1% is too old, contact the plugin author for an update") % Util::getFileName(path)); + throw Exception(str(F_("%1% is too old, contact the plugin author for an update") % Util::getFileName(path))); } parse("UUID", info.uuid); @@ -154,26 +154,32 @@ throw Exception(str(F_("%1% is not compatible with %2%") % Util::getFileName(path) % APPNAME)); } - if(isLoaded(info.uuid)) { - throw Exception(str(F_("%1% is already installed") % Util::getFileName(path))); + { + Lock l(cs); + + auto it = findPlugin(info.uuid); + if(it != plugins.end()) { + auto& plugin = *it; + if(plugin->getInfo().version < info.version) { + info.updating = true; + } else { + throw Exception(str(F_("%1% is already installed") % plugin->getInfo().name)); + } + } } return info; } -void PluginManager::install(const string& uuid, const string& plugin, const StringList& files) { - if(uuid.empty() || plugin.empty()) { - throw Exception(); - } - +void PluginManager::install(const DcextInfo& info) { const auto source = Util::getTempPath() + "dcext" PATH_SEPARATOR_STR; - const auto target = getInstallPath(uuid); - const auto lib = target + Util::getFileName(plugin); + const auto target = getInstallPath(info.uuid); + const auto lib = target + Util::getFileName(info.plugin); File::ensureDirectory(lib); - File::renameFile(source + plugin, lib); + File::renameFile(source + info.plugin, lib); - for(auto& file: files) { + for(auto& file: info.files) { File::ensureDirectory(target + file); File::renameFile(source + file, target + file); } @@ -215,7 +221,9 @@ throw Exception(str(F_("%1% is not a valid plugin") % Util::getFileName(fileName))); } - checkPlugin(info); + if(checkPlugin(info)) { + install = true; + } if(dcMain((install ? ON_INSTALL : ON_LOAD), &dcCore, nullptr) == False) { throw Exception(str(F_("Error loading %1%") % Util::getFileName(fileName))); @@ -227,15 +235,24 @@ bool PluginManager::isLoaded(const string& guid) { Lock l(cs); - auto pluginComp = [&guid](const unique_ptr<PluginInfo>& p) -> bool { return strcmp(p->getInfo().guid, guid.c_str()) == 0; }; - auto i = std::find_if(plugins.begin(), plugins.end(), pluginComp); - return (i != plugins.end()); + return findPlugin(guid) != plugins.end(); } -void PluginManager::checkPlugin(const MetaData& info) { +bool PluginManager::checkPlugin(const MetaData& info) { + auto updating = false; + // Check if user is trying to load a duplicate - if(isLoaded(info.guid)) { - throw Exception(str(F_("%1% is already installed") % info.name)); + auto it = findPlugin(info.guid); + if(it != plugins.end()) { + auto& plugin = *it; + if(plugin->getInfo().version < info.version) { + LogManager::getInstance()->message(str(F_("Updating the %1% plugin from version %2% to version %3%") % + string(plugin->getInfo().name) % plugin->getInfo().version % info.version)); + plugins.erase(it); + updating = true; + } else { + throw Exception(str(F_("%1% is already installed") % info.name)); + } } // Check API compatibility (this should only block on absolutely wrecking api changes, which generally should not happen) @@ -251,6 +268,13 @@ } } } + + return updating; +} + +vector<unique_ptr<PluginInfo>>::iterator PluginManager::findPlugin(const string& guid) { + return std::find_if(plugins.begin(), plugins.end(), [&guid](const unique_ptr<PluginInfo>& p) { + return strcmp(p->getInfo().guid, guid.c_str()) == 0; }); } void PluginManager::unloadPlugins() { === modified file 'dcpp/PluginManager.h' --- dcpp/PluginManager.h 2013-04-23 17:41:14 +0000 +++ dcpp/PluginManager.h 2013-04-25 18:08:15 +0000 @@ -89,6 +89,7 @@ /** Information about a dcext-packaged plugin that has just been extracted. */ struct DcextInfo { + DcextInfo() : version(0), updating(false) { } string uuid; string name; double version; @@ -97,6 +98,7 @@ string website; string plugin; StringList files; + bool updating; }; class PluginManager : public Singleton<PluginManager>, private TimerManagerListener, @@ -108,7 +110,7 @@ /** Extract a dcext-packaged plugin. Throws on errors. */ DcextInfo extract(const string& path); - void install(const string& uuid, const string& plugin, const StringList& files); + void install(const DcextInfo& info); void loadPlugins(function<void (const string&)> f); void loadPlugin(const string& fileName, bool install = false); @@ -181,8 +183,10 @@ void loadSettings() noexcept; void saveSettings() noexcept; - // Check if the plugin can be loaded; throws if it can't. - void checkPlugin(const MetaData& info); + /** Check if the plugin can be loaded; throws if it can't. + @return Whether the plugin is being updated. */ + bool checkPlugin(const MetaData& info); + vector<unique_ptr<PluginInfo>>::iterator findPlugin(const string& guid); // Listeners void on(TimerManagerListener::Second, uint64_t ticks) noexcept { runHook(HOOK_TIMER_SECOND, NULL, &ticks); } === modified file 'dcpp/forward.h' --- dcpp/forward.h 2013-04-13 15:08:45 +0000 +++ dcpp/forward.h 2013-04-25 18:08:15 +0000 @@ -48,6 +48,8 @@ class CRC32Filter; +struct DcextInfo; + class Download; typedef Download* DownloadPtr; === modified file 'win32/PluginInfoDlg.cpp' --- win32/PluginInfoDlg.cpp 2013-04-23 15:34:45 +0000 +++ win32/PluginInfoDlg.cpp 2013-04-25 18:08:15 +0000 @@ -100,11 +100,12 @@ cur->column(0).align = GridInfo::BOTTOM_RIGHT; cur->setSpacing(grid->getSpacing()); WinUtil::addDlgButtons(cur, - [this, info] { handleOK(info.name, info.uuid, info.plugin, info.files); }, - [this] { endDialog(IDCANCEL); }).first->setText(T_("Install the plugin")); + [this, info] { handleOK(info); }, + [this] { endDialog(IDCANCEL); }) + .first->setText(info.updating ? T_("Update the plugin") : T_("Install the plugin")); } - setText(T_("Adding a plugin")); + setText(info.updating ? T_("Updating a plugin") : T_("Adding a plugin")); layout(); centerWindow(); @@ -112,13 +113,13 @@ return false; } -void PluginInfoDlg::handleOK(const string& name, const string& uuid, const string& plugin, const StringList& files) { +void PluginInfoDlg::handleOK(const DcextInfo& info) { try { - PluginManager::getInstance()->install(uuid, plugin, files); + PluginManager::getInstance()->install(info); endDialog(IDOK); } catch(const Exception& e) { - error(Text::toT(e.getError()), Text::toT(name)); + error(Text::toT(e.getError()), Text::toT(info.name)); endDialog(IDCANCEL); } } === modified file 'win32/PluginInfoDlg.h' --- win32/PluginInfoDlg.h 2013-04-23 15:34:45 +0000 +++ win32/PluginInfoDlg.h 2013-04-25 18:08:15 +0000 @@ -35,7 +35,7 @@ private: bool handleInitDialog(const string& path); - void handleOK(const string& name, const string& uuid, const string& plugin, const StringList& files); + void handleOK(const DcextInfo& info); void layout(); === modified file 'win32/PluginPage.cpp' --- win32/PluginPage.cpp 2013-04-23 15:34:45 +0000 +++ win32/PluginPage.cpp 2013-04-25 18:08:15 +0000 @@ -132,9 +132,7 @@ WinUtil::makeColumns(plugins, columns, 1); - for(auto& plugin: PluginManager::getInstance()->getPluginList()) { - addEntry(plugins->size(), plugin->getInfo()); - } + refreshList(); handleSelectionChanged(); @@ -255,27 +253,25 @@ .open(path_t)) { auto path = Text::fromT(path_t); - auto added = false; if(Util::getFileExt(path) == ".dcext") { - added = PluginInfoDlg(this, path).run() == IDOK; + PluginInfoDlg(this, path).run(); } else { try { PluginManager::getInstance()->loadPlugin(path, true); - added = true; } catch(const Exception& e) { dwt::MessageBox(this).show(tstring(T_("Cannot install the plugin:")) + _T("\r\n\r\n") + Text::toT(e.getError()), Text::toT(Util::getFileName(path)), dwt::MessageBox::BOX_OK, dwt::MessageBox::BOX_ICONSTOP); } } - if(added) { - auto pos = plugins->size(); - addEntry(pos, PluginManager::getInstance()->getPlugin(pos)->getInfo()); - } + refreshList(); } } void PluginPage::handleConfigurePlugin() { + if(plugins->countSelected() != 1) + return; + auto sel = plugins->getSelected(); const PluginInfo *p = PluginManager::getInstance()->getPlugin(sel); if(!p->dcMain(ON_CONFIGURE, PluginManager::getInstance()->getCore(), this->handle())) { @@ -326,6 +322,13 @@ plugins->erase(sel); } +void PluginPage::refreshList() { + plugins->clear(); + for(auto& plugin: PluginManager::getInstance()->getPluginList()) { + addEntry(plugins->size(), plugin->getInfo()); + } +} + void PluginPage::addEntry(size_t idx, const MetaData& info) { TStringList row; row.push_back(Text::toT(info.name)); === modified file 'win32/PluginPage.h' --- win32/PluginPage.h 2013-04-22 22:31:37 +0000 +++ win32/PluginPage.h 2013-04-25 18:08:15 +0000 @@ -49,6 +49,7 @@ void handleMovePluginDown(); void handleRemovePlugin(); + void refreshList(); void addEntry(size_t idx, const MetaData& info); };
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp