linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06803
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3276: allow updating plugins rather than refusing to install
------------------------------------------------------------
revno: 3276
committer: poy <poy@xxxxxxxxxx>
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);
};