commit 18f546204686f3e5c9f1af76eac6bcd802971042
parent 829875e621575e493b0a46ff3166221d7182bbd1
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 5 Dec 2015 00:26:03 -0500
implement the "import remote repository" feature
Diffstat:
8 files changed, 116 insertions(+), 60 deletions(-)
diff --git a/src/config.cpp b/src/config.cpp
@@ -18,7 +18,7 @@ static const char *VER_KEY = "version";
static string ArrayKey(const string &key, const size_t i)
{
- return key + to_string(i);
+ return to_string(i) + key;
}
static const int BUFFER_SIZE = 2083;
@@ -40,7 +40,7 @@ void Config::setString(const char *group,
void Config::fillDefaults()
{
- m_remotes.push_back({"ReaScripts",
+ addRemote({"ReaScripts",
"https://github.com/ReaTeam/ReaScripts/raw/master/index.xml"});
}
@@ -64,6 +64,11 @@ void Config::write() const
writeRegistry();
}
+void Config::addRemote(Remote remote)
+{
+ m_remotes[remote.first] = remote.second;
+}
+
void Config::readRemotes()
{
size_t i = 0;
@@ -75,19 +80,17 @@ void Config::readRemotes()
if(name.empty() || url.empty())
break;
- m_remotes.push_back({name, url});
+ addRemote({name, url});
} while(++i);
}
void Config::writeRemotes() const
{
- const size_t size = m_remotes.size();
-
- for(size_t i = 0; i < size; i++) {
- const Remote &remote = m_remotes[i];
+ size_t i = 0;
- setString(REMOTES_GRP, ArrayKey(NAME_KEY, i), remote.name());
- setString(REMOTES_GRP, ArrayKey(URL_KEY, i), remote.url());
+ for(auto it = m_remotes.begin(); it != m_remotes.end(); it++, i++) {
+ setString(REMOTES_GRP, ArrayKey(NAME_KEY, i), it->first);
+ setString(REMOTES_GRP, ArrayKey(URL_KEY, i), it->second);
}
}
diff --git a/src/config.hpp b/src/config.hpp
@@ -13,7 +13,8 @@ public:
void read(const Path &);
void write() const;
- const RemoteList &remotes() const { return m_remotes; }
+ void addRemote(Remote);
+ const RemoteMap &remotes() const { return m_remotes; }
Registry *registry() { return &m_registry; }
private:
@@ -26,7 +27,7 @@ private:
void readRemotes();
void writeRemotes() const;
- RemoteList m_remotes;
+ RemoteMap m_remotes;
void readRegistry();
void writeRegistry() const;
diff --git a/src/main.cpp b/src/main.cpp
@@ -42,7 +42,10 @@ extern "C" REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(
reapack.init(instance, rec);
reapack.setupAction("REAPACK_SYNC", "ReaPack: Synchronize Packages",
- &reapack.action, std::bind(&ReaPack::synchronize, reapack));
+ &reapack.syncAction, std::bind(&ReaPack::synchronize, reapack));
+
+ reapack.setupAction("REAPACK_IMPORT",
+ std::bind(&ReaPack::importRemote, reapack));
rec->Register("hookcommand", (void *)commandHook);
rec->Register("hookcustommenu", (void *)menuHook);
diff --git a/src/reapack.cpp b/src/reapack.cpp
@@ -4,6 +4,8 @@
#include <reaper_plugin_functions.h>
+#include <fstream>
+
using namespace std;
ReaPack::ReaPack()
@@ -18,24 +20,39 @@ void ReaPack::init(REAPER_PLUGIN_HINSTANCE instance, reaper_plugin_info_t *rec)
m_mainHandle = GetMainHwnd();
m_resourcePath.append(GetResourcePath());
- m_config.read(m_resourcePath + "reapack.ini");
+ // wtf? If m_config is a member object different instances will be used
+ // in importRemote(), synchronize() and cleanup()
+ m_config = new Config;
+ m_config->read(m_resourcePath + "reapack.ini");
}
void ReaPack::cleanup()
{
// for some reasons ~ReaPack() is called many times during startup
// and two times during shutdown on osx... cleanup() is called only once
- m_config.write();
+ m_config->write();
+ delete m_config;
+}
+
+int ReaPack::setupAction(const char *name, const ActionCallback &callback)
+{
+ const int id = m_rec->Register("command_id", (void *)name);
+ m_actions[id] = callback;
+
+ return id;
}
-void ReaPack::setupAction(const char *name, const char *desc,
- gaccel_register_t *action, ActionCallback callback)
+int ReaPack::setupAction(const char *name, const char *desc,
+ gaccel_register_t *action, const ActionCallback &callback)
{
+ const int id = setupAction(name, callback);
+
action->desc = desc;
- action->accel.cmd = m_rec->Register("command_id", (void *)name);
+ action->accel.cmd = id;
m_rec->Register("gaccel", action);
- m_actions[action->accel.cmd] = callback;
+
+ return id;
}
bool ReaPack::execActions(const int id, const int)
@@ -48,12 +65,34 @@ bool ReaPack::execActions(const int id, const int)
return true;
}
+Transaction *ReaPack::createTransaction()
+{
+ if(m_transaction)
+ return 0;
+
+ m_transaction = new Transaction(m_config->registry(), m_resourcePath);
+
+ m_transaction->onReady([=] {
+ // TODO: display the package list with the changelogs
+ m_transaction->run();
+ });
+
+ m_transaction->onFinish([=] {
+ delete m_transaction;
+ m_transaction = 0;
+
+ m_config->write();
+ });
+
+ return m_transaction;
+}
+
void ReaPack::synchronize()
{
if(m_transaction)
return;
- RemoteList remotes = m_config.remotes();
+ RemoteMap remotes = m_config->remotes();
if(remotes.empty()) {
ShowMessageBox("No remote repository configured, nothing to do!",
@@ -62,19 +101,41 @@ void ReaPack::synchronize()
return;
}
- m_transaction = new Transaction(m_config.registry(), m_resourcePath);
+ m_transaction->fetch(remotes);
+}
- m_transaction->onReady([=] {
- // TODO: display the package list with the changelogs
- m_transaction->run();
- });
+void ReaPack::importRemote()
+{
+ char path[4096];
- m_transaction->onFinish([=] {
- delete m_transaction;
- m_transaction = 0;
+ const char *title = "ReaPack: Import remote repository";
+ if(!GetUserFileNameForRead(path, title, "ReaPackRemote"))
+ return;
- m_config.write();
- });
+ ifstream file(path);
+ if(!file.good()) {
+ ShowMessageBox(strerror(errno), title, 0);
+ return;
+ }
- m_transaction->fetch(remotes);
+ string name;
+ file >> name;
+
+ string url;
+ file >> url;
+
+ file.close();
+
+ if(m_config->remotes().count({name})) {
+ ShowMessageBox("This remote is already configured.", title, 0);
+ return;
+ }
+
+ const Remote remote{name, url};
+ m_config->addRemote(remote);
+ m_config->write();
+
+ Transaction *t = createTransaction();
+ if(t)
+ t->fetch(remote);
}
diff --git a/src/reapack.hpp b/src/reapack.hpp
@@ -15,23 +15,27 @@ class Transaction;
class ReaPack {
public:
- gaccel_register_t action;
+ gaccel_register_t syncAction;
ReaPack();
void init(REAPER_PLUGIN_HINSTANCE, reaper_plugin_info_t *);
void cleanup();
- void setupAction(const char *name, const char *desc,
- gaccel_register_t *action, ActionCallback callback);
+ int setupAction(const char *name, const ActionCallback &);
+ int setupAction(const char *name, const char *desc,
+ gaccel_register_t *action, const ActionCallback &);
bool execActions(const int id, const int);
void synchronize();
+ void importRemote();
private:
+ Transaction *createTransaction();
+
std::map<int, ActionCallback> m_actions;
- Config m_config;
+ Config *m_config;
Transaction *m_transaction;
REAPER_PLUGIN_HINSTANCE m_instance;
diff --git a/src/remote.hpp b/src/remote.hpp
@@ -1,24 +1,10 @@
#ifndef REAPACK_REMOTE_HPP
#define REAPACK_REMOTE_HPP
+#include <map>
#include <string>
-#include <vector>
-class Remote;
-typedef std::vector<Remote> RemoteList;
-
-class Remote {
-public:
- Remote(const std::string &name, const std::string &url)
- : m_name(name), m_url(url)
- {}
-
- const std::string &name() const { return m_name; }
- const std::string &url() const { return m_url; }
-
-private:
- std::string m_name;
- std::string m_url;
-};
+typedef std::map<std::string, std::string> RemoteMap;
+typedef RemoteMap::value_type Remote;
#endif
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -21,7 +21,7 @@ Transaction::~Transaction()
delete db;
}
-void Transaction::fetch(const RemoteList &remotes)
+void Transaction::fetch(const RemoteMap &remotes)
{
for(const Remote &remote : remotes)
fetch(remote);
@@ -29,18 +29,18 @@ void Transaction::fetch(const RemoteList &remotes)
void Transaction::fetch(const Remote &remote)
{
- Download *dl = new Download(remote.name(), remote.url());
+ Download *dl = new Download(remote.first, remote.second);
dl->addCallback([=]() {
if(dl->status() != 200) {
- addError(dl->contents(), remote.name());
+ addError(dl->contents(), dl->name());
return;
}
- const Path path = m_dbPath + ("remote_" + remote.name() + ".xml");
+ const Path path = m_dbPath + ("remote_" + dl->name() + ".xml");
ofstream file(path.join());
if(file.bad()) {
- addError(strerror(errno), remote.name());
+ addError(strerror(errno), dl->name());
return;
}
@@ -48,7 +48,7 @@ void Transaction::fetch(const Remote &remote)
file.close();
Database *db = Database::load(path.join().c_str());
- db->setName(remote.name());
+ db->setName(dl->name());
m_databases.push_back(db);
});
diff --git a/src/transaction.hpp b/src/transaction.hpp
@@ -9,8 +9,6 @@
#include <boost/signals2.hpp>
-class Remote;
-
class Transaction {
public:
typedef boost::signals2::signal<void ()> Signal;
@@ -22,7 +20,7 @@ public:
void onReady(const Callback &callback) { m_onReady.connect(callback); }
void onFinish(const Callback &callback) { m_onFinish.connect(callback); }
- void fetch(const RemoteList &);
+ void fetch(const RemoteMap &);
void fetch(const Remote &);
void prepare();