reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/about.cpp | 6+++---
Msrc/index.cpp | 29-----------------------------
Msrc/index.hpp | 17++++-------------
Msrc/index_v1.cpp | 4++--
Asrc/metadata.cpp | 48++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/metadata.hpp | 45+++++++++++++++++++++++++++++++++++++++++++++
Mtest/index.cpp | 43-------------------------------------------
Mtest/index_v1.cpp | 6+++---
Atest/metadata.cpp | 50++++++++++++++++++++++++++++++++++++++++++++++++++
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"); +}