commit 29d3f021c7910bd7bca0ee33c1f8d82789a1b1af
parent 51637b33fe42135f6006b5399c2d58acafabd58e
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 9 Jul 2016 22:55:41 -0400
extract metadata (about text & links)
Diffstat:
9 files changed, 155 insertions(+), 93 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -194,7 +194,7 @@ void AboutRemote::populate()
SetWindowText(installBtn, btnLabel);
show(installBtn);
- string aboutText = m_index->aboutText();
+ string aboutText = m_index->metadata()->about();
if(m_index->name() == "ReaPack") {
boost::replace_all(aboutText, "[[REAPACK_VERSION]]", ReaPack::VERSION);
@@ -210,8 +210,8 @@ void AboutRemote::populate()
list()->onActivate(bind(&AboutRemote::aboutPackage, this));
- addLinks(IDC_WEBSITE, m_index->links(Index::WebsiteLink));
- addLinks(IDC_DONATE, m_index->links(Index::DonationLink));
+ addLinks(IDC_WEBSITE, m_index->metadata()->links(Metadata::WebsiteLink));
+ addLinks(IDC_DONATE, m_index->metadata()->links(Metadata::DonationLink));
menu()->addRow({AUTO_STR("<All Packages>")});
diff --git a/src/index.cpp b/src/index.cpp
@@ -24,8 +24,6 @@
#include "path.hpp"
#include "remote.hpp"
-#include <boost/algorithm/string/predicate.hpp>
-
#include <WDL/tinyxml/tinyxml.h>
using namespace std;
@@ -35,14 +33,6 @@ Path Index::pathFor(const string &name)
return Path::CACHE + (name + ".xml");
}
-auto Index::linkTypeFor(const char *rel) -> LinkType
-{
- if(!strcmp(rel, "donation"))
- return DonationLink;
-
- return WebsiteLink;
-}
-
IndexPtr Index::load(const string &name, const char *data)
{
TiXmlDocument doc;
@@ -152,25 +142,6 @@ const Category *Index::category(const string &name) const
return category(it->second);
}
-void Index::addLink(const LinkType type, const Link &link)
-{
- if(boost::algorithm::starts_with(link.url, "http"))
- m_links.insert({type, link});
-}
-
-auto Index::links(const LinkType type) const -> LinkList
-{
- const auto begin = m_links.lower_bound(type);
- const auto end = m_links.upper_bound(type);
-
- LinkList list(m_links.count(type));
-
- for(auto it = begin; it != end; it++)
- list[distance(begin, it)] = &it->second;
-
- return list;
-}
-
Category::Category(const string &name, const Index *ri)
: m_index(ri), m_name(name)
{
diff --git a/src/index.hpp b/src/index.hpp
@@ -24,6 +24,7 @@
#include <unordered_map>
#include <vector>
+#include "metadata.hpp"
#include "package.hpp"
#include "source.hpp"
@@ -37,18 +38,11 @@ class Remote;
class TiXmlElement;
struct NetworkOpts;
-struct Link { std::string name; std::string url; };
-
typedef std::shared_ptr<const Index> IndexPtr;
class Index : public std::enable_shared_from_this<const Index> {
public:
- enum LinkType { WebsiteLink, DonationLink };
- typedef std::multimap<LinkType, Link> LinkMap;
- typedef std::vector<const Link *> LinkList;
-
static Path pathFor(const std::string &name);
- static LinkType linkTypeFor(const char *rel);
static IndexPtr load(const std::string &name, const char *data = nullptr);
static Download *fetch(const Remote &, bool stale, const NetworkOpts &);
@@ -58,10 +52,8 @@ public:
void setName(const std::string &);
const std::string &name() const { return m_name; }
- void setAboutText(const std::string &rtf) { m_about = rtf; }
- const std::string &aboutText() const { return m_about; }
- void addLink(const LinkType, const Link &);
- LinkList links(const LinkType type) const;
+ Metadata *metadata() { return &m_metadata; }
+ const Metadata *metadata() const { return &m_metadata; }
void addCategory(const Category *cat);
const CategoryList &categories() const { return m_categories; }
@@ -74,8 +66,7 @@ private:
static void loadV1(TiXmlElement *, Index *);
std::string m_name;
- std::string m_about;
- LinkMap m_links;
+ Metadata m_metadata;
CategoryList m_categories;
PackageList m_packages;
diff --git a/src/index_v1.cpp b/src/index_v1.cpp
@@ -56,7 +56,7 @@ void LoadMetadataV1(TiXmlElement *meta, Index *ri)
if(node) {
if(const char *rtf = node->GetText())
- ri->setAboutText(rtf);
+ ri->metadata()->setAbout(rtf);
}
node = meta->FirstChildElement("link");
@@ -73,7 +73,7 @@ void LoadMetadataV1(TiXmlElement *meta, Index *ri)
}
else if(!url) url = name;
- ri->addLink(Index::linkTypeFor(rel), {name, url});
+ ri->metadata()->addLink(Metadata::getLinkType(rel), {name, url});
node = node->NextSiblingElement("link");
}
diff --git a/src/metadata.cpp b/src/metadata.cpp
@@ -0,0 +1,48 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2016 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "metadata.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+auto Metadata::getLinkType(const char *rel) -> LinkType
+{
+ if(!strcmp(rel, "donation"))
+ return DonationLink;
+
+ return WebsiteLink;
+}
+
+void Metadata::addLink(const LinkType type, const Link &link)
+{
+ if(boost::algorithm::starts_with(link.url, "http"))
+ m_links.insert({type, link});
+}
+
+auto Metadata::links(const LinkType type) const -> LinkList
+{
+ const auto begin = m_links.lower_bound(type);
+ const auto end = m_links.upper_bound(type);
+
+ LinkList list(m_links.count(type));
+
+ for(auto it = begin; it != end; it++)
+ list[distance(begin, it)] = &it->second;
+
+ return list;
+}
+
diff --git a/src/metadata.hpp b/src/metadata.hpp
@@ -0,0 +1,45 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2016 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REAPACK_METADATA_HPP
+#define REAPACK_METADATA_HPP
+
+#include <map>
+#include <string>
+#include <vector>
+
+struct Link { std::string name; std::string url; };
+
+class Metadata {
+public:
+ enum LinkType { WebsiteLink, DonationLink };
+ typedef std::multimap<LinkType, Link> LinkMap;
+ typedef std::vector<const Link *> LinkList;
+
+ static LinkType getLinkType(const char *rel);
+
+ void setAbout(const std::string &rtf) { m_about = rtf; }
+ const std::string &about() const { return m_about; }
+ void addLink(const LinkType, const Link &);
+ LinkList links(LinkType) const;
+
+private:
+ std::string m_about;
+ LinkMap m_links;
+};
+
+#endif
diff --git a/test/index.cpp b/test/index.cpp
@@ -197,49 +197,6 @@ TEST_CASE("category full name", M) {
REQUIRE(cat2.fullName() == "Remote Name/Category Name");
}
-TEST_CASE("repository description", M) {
- Index ri("Remote Name");
- CHECK(ri.aboutText().empty());
-
- ri.setAboutText("Hello World");
- REQUIRE(ri.aboutText() == "Hello World");
-}
-
-TEST_CASE("repository links", M) {
- Index ri("Remote name");
- CHECK(ri.links(Index::WebsiteLink).empty());
- CHECK(ri.links(Index::DonationLink).empty());
-
- SECTION("website links") {
- ri.addLink(Index::WebsiteLink, {"First", "http://example.com"});
- REQUIRE(ri.links(Index::WebsiteLink).size() == 1);
- ri.addLink(Index::WebsiteLink, {"Second", "http://example.com"});
-
- const auto &links = ri.links(Index::WebsiteLink);
- REQUIRE(links.size() == 2);
- REQUIRE(links[0]->name == "First");
- REQUIRE(links[1]->name == "Second");
-
- REQUIRE(ri.links(Index::DonationLink).empty());
- }
-
- SECTION("donation links") {
- ri.addLink(Index::DonationLink, {"First", "http://example.com"});
- REQUIRE(ri.links(Index::DonationLink).size() == 1);
- }
-
- SECTION("drop invalid links") {
- ri.addLink(Index::WebsiteLink, {"name", "not http(s)"});
- REQUIRE(ri.links(Index::WebsiteLink).empty());
- }
-}
-
-TEST_CASE("link type from string", M) {
- REQUIRE(Index::linkTypeFor("website") == Index::WebsiteLink);
- REQUIRE(Index::linkTypeFor("donation") == Index::DonationLink);
- REQUIRE(Index::linkTypeFor("bacon") == Index::WebsiteLink);
-}
-
TEST_CASE("set index name", M) {
SECTION("set") {
Index ri({});
diff --git a/test/index_v1.cpp b/test/index_v1.cpp
@@ -197,11 +197,11 @@ TEST_CASE("read index metadata", M) {
}
SECTION("description") {
- REQUIRE(ri->aboutText() == "Chunky\nBacon");
+ REQUIRE(ri->metadata()->about() == "Chunky\nBacon");
}
SECTION("website links") {
- const auto &links = ri->links(Index::WebsiteLink);
+ const auto &links = ri->metadata()->links(Metadata::WebsiteLink);
REQUIRE(links.size() == 4);
REQUIRE(links[0]->name == "http://cfillion.tk");
REQUIRE(links[0]->url == "http://cfillion.tk");
@@ -214,7 +214,7 @@ TEST_CASE("read index metadata", M) {
}
SECTION("donation links") {
- const auto &links = ri->links(Index::DonationLink);
+ const auto &links = ri->metadata()->links(Metadata::DonationLink);
REQUIRE(links.size() == 1);
REQUIRE(links[0]->name == "Donate");
REQUIRE(links[0]->url == "http://paypal.com");
diff --git a/test/metadata.cpp b/test/metadata.cpp
@@ -0,0 +1,50 @@
+#include <catch.hpp>
+
+#include <metadata.hpp>
+
+using namespace std;
+
+static const char *M = "[metadata]";
+
+TEST_CASE("repository links", M) {
+ Metadata md;
+ CHECK(md.links(Metadata::WebsiteLink).empty());
+ CHECK(md.links(Metadata::DonationLink).empty());
+
+ SECTION("website links") {
+ md.addLink(Metadata::WebsiteLink, {"First", "http://example.com"});
+ REQUIRE(md.links(Metadata::WebsiteLink).size() == 1);
+ md.addLink(Metadata::WebsiteLink, {"Second", "http://example.com"});
+
+ const auto &links = md.links(Metadata::WebsiteLink);
+ REQUIRE(links.size() == 2);
+ REQUIRE(links[0]->name == "First");
+ REQUIRE(links[1]->name == "Second");
+
+ REQUIRE(md.links(Metadata::DonationLink).empty());
+ }
+
+ SECTION("donation links") {
+ md.addLink(Metadata::DonationLink, {"First", "http://example.com"});
+ REQUIRE(md.links(Metadata::DonationLink).size() == 1);
+ }
+
+ SECTION("drop invalid links") {
+ md.addLink(Metadata::WebsiteLink, {"name", "not http(s)"});
+ REQUIRE(md.links(Metadata::WebsiteLink).empty());
+ }
+}
+
+TEST_CASE("link type from stmdng", M) {
+ REQUIRE(Metadata::getLinkType("website") == Metadata::WebsiteLink);
+ REQUIRE(Metadata::getLinkType("donation") == Metadata::DonationLink);
+ REQUIRE(Metadata::getLinkType("bacon") == Metadata::WebsiteLink);
+}
+
+TEST_CASE("about text", M) {
+ Metadata md;
+ CHECK(md.about().empty());
+
+ md.setAbout("Hello World");
+ REQUIRE(md.about() == "Hello World");
+}