summaryrefslogtreecommitdiff
path: root/gentoobrowse/src
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-12-21 15:02:57 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2017-01-16 21:47:53 +0000
commit1f675b4dea063c5272b9b0421dafcb23f55ad959 (patch)
treeb1a483a44bb3a4d319853cffc71865b022c75b2b /gentoobrowse/src
parentSet cxxflags specifically, not cflags (diff)
downloadgentoobrowse-1f675b4dea063c5272b9b0421dafcb23f55ad959.tar.bz2
gentoobrowse-1f675b4dea063c5272b9b0421dafcb23f55ad959.tar.xz
gentoobrowse-1f675b4dea063c5272b9b0421dafcb23f55ad959.zip
Line in the sand, all basic functionality is working
Diffstat (limited to 'gentoobrowse/src')
-rw-r--r--gentoobrowse/src/Jamfile.jam59
-rw-r--r--gentoobrowse/src/base.cpp67
-rw-r--r--gentoobrowse/src/base.json21
-rw-r--r--gentoobrowse/src/mash.ice107
-rw-r--r--gentoobrowse/src/news.ice14
-rw-r--r--gentoobrowse/src/news.json52
-rw-r--r--gentoobrowse/src/packages.cpp323
-rw-r--r--gentoobrowse/src/packages.json52
-rw-r--r--gentoobrowse/src/pagebase.ice26
-rw-r--r--gentoobrowse/src/search.cpp67
-rw-r--r--gentoobrowse/src/search.json45
-rw-r--r--gentoobrowse/src/use.json50
-rw-r--r--gentoobrowse/src/user.cpp236
13 files changed, 1119 insertions, 0 deletions
diff --git a/gentoobrowse/src/Jamfile.jam b/gentoobrowse/src/Jamfile.jam
new file mode 100644
index 0000000..96b77e5
--- /dev/null
+++ b/gentoobrowse/src/Jamfile.jam
@@ -0,0 +1,59 @@
+import icespider ;
+
+lib icespider-common ;
+lib icespider-xslt : : : : <library>../..//libxmlpp ;
+lib icespider-fcgi ;
+lib icespider-filesessions ;
+lib adhocutil ;
+lib Ice ;
+lib IceUtil ;
+lib pthread ;
+lib boost_system ;
+lib slicer ;
+lib slicer-json ;
+lib slicer-xml ;
+lib slicer-db ;
+lib gentoobrowse-domain ;
+lib gentoobrowse : :
+ <name>gentoobrowse-api
+ : :
+ <include>/usr/share/gentoobrowse-api
+ <include>/usr/share/slicer/ice
+ <include>/usr/include/gentoobrowse-api
+ <include>/usr/include/slicer/db
+ <include>/usr/include/slicer/slicer
+ <library>gentoobrowse-domain
+ <library>slicer-db
+ ;
+lib icespider : :
+ <name>icespider-core
+ : :
+ <include>/usr/include/icespider
+ <include>/usr/include/slicer
+ <include>/usr/include/adhocutil
+ <include>/usr/share/icespider/ice
+ <library>icespider-common
+ <library>icespider-xslt
+ <library>icespider-fcgi
+ <library>icespider-filesessions
+ <library>adhocutil
+ <library>Ice
+ <library>IceUtil
+ <library>pthread
+ <library>slicer
+ <library>boost_system
+ <allow-ice>yes
+ ;
+
+exe gentoobrowse-cgi :
+ [ glob *.cpp *.ice *.json ]
+ :
+ <variant>release:<cxxflags>-flto=3
+ <variant>release:<linkflags>-flto=3
+ <slicer>yes
+ <include>.
+ <library>icespider
+ <library>gentoobrowse
+ <library>slicer-json
+ <library>slicer-xml
+ ;
diff --git a/gentoobrowse/src/base.cpp b/gentoobrowse/src/base.cpp
new file mode 100644
index 0000000..9656a1f
--- /dev/null
+++ b/gentoobrowse/src/base.cpp
@@ -0,0 +1,67 @@
+#ifndef GENTOOBROWSE_BASE_H
+#define GENTOOBROWSE_BASE_H
+
+#include <icespider-routes-base.h>
+#include <mash.h>
+#include <algorithm>
+
+namespace GentooBrowse {
+ ::Gentoo::UserPtr
+ common::currentUser(const IceSpider::IHttpRequest * request) const
+ {
+ if (auto sid = request->getCookieParam("sessionId")) {
+ if (auto s = prx0->getSession(*sid)) {
+ auto uid = s->variables.find("userId");
+ if (uid != s->variables.end()) {
+ return prx1->get(boost::lexical_cast<Ice::Int>(uid->second));
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ void
+ common::addUser(const IceSpider::IHttpRequest * request, const PageBasePtr & model) const
+ {
+ model->user = currentUser(request);
+ }
+
+ void
+ common::trimCategories(Gentoo::Categories & categories, const Gentoo::Packages & packages) const
+ {
+ std::set<Ice::Int> ids;
+ std::transform(packages.begin(), packages.end(), std::inserter(ids, ids.begin()), [](auto p) {
+ return p->categoryid;
+ });
+ categories.erase(std::remove_if(categories.begin(), categories.end(), [&ids](auto category) {
+ return ids.find(category->categoryid) == ids.end();
+ }), categories.end());
+ }
+
+ void
+ common::trimCategories(Gentoo::Categories & categories, const Gentoo::SearchResultPackages & packages) const
+ {
+ std::set<Ice::Int> ids;
+ std::transform(packages.begin(), packages.end(), std::inserter(ids, ids.begin()), [](auto p) {
+ return p->categoryid;
+ });
+ categories.erase(std::remove_if(categories.begin(), categories.end(), [&ids](auto category) {
+ return ids.find(category->categoryid) == ids.end();
+ }), categories.end());
+ }
+
+ void
+ common::trimPackages(Gentoo::Packages & packages, const Gentoo::Ebuilds & ebuilds) const
+ {
+ std::set<Ice::Int> ids;
+ std::transform(ebuilds.begin(), ebuilds.end(), std::inserter(ids, ids.begin()), [](auto e) {
+ return e->packageid;
+ });
+ packages.erase(std::remove_if(packages.begin(), packages.end(), [&ids](auto package) {
+ return ids.find(package->packageid) == ids.end();
+ }), packages.end());
+ }
+}
+
+#endif
+
diff --git a/gentoobrowse/src/base.json b/gentoobrowse/src/base.json
new file mode 100644
index 0000000..c1164ee
--- /dev/null
+++ b/gentoobrowse/src/base.json
@@ -0,0 +1,21 @@
+{
+ "name": "GentooBrowse",
+ "routeBases": {
+ "common": {
+ "proxies": [ "IceSpider.SessionManager", "Gentoo.Users" ],
+ "functions": [
+ "::Gentoo::UserPtr currentUser(const IceSpider::IHttpRequest *) const",
+ "void trimCategories(Gentoo::Categories &, const Gentoo::Packages &) const",
+ "void trimCategories(Gentoo::Categories &, const Gentoo::SearchResultPackages &) const",
+ "void trimPackages(Gentoo::Packages &, const Gentoo::Ebuilds &) const",
+ "template<typename T> void trimCategories(const IceSpider::IHttpRequest *, const IceInternal::Handle<T> & p) const { trimCategories(p->categories, p->packages); }",
+ "void addUser(const IceSpider::IHttpRequest *, const PageBasePtr &) const"
+ ]
+ }
+ },
+ "slices": [
+ "mash.ice",
+ "session.ice",
+ "users.ice"
+ ]
+}
diff --git a/gentoobrowse/src/mash.ice b/gentoobrowse/src/mash.ice
new file mode 100644
index 0000000..98d4cc1
--- /dev/null
+++ b/gentoobrowse/src/mash.ice
@@ -0,0 +1,107 @@
+#include <portage.ice>
+#include <users.ice>
+#include <pagebase.ice>
+
+module GentooBrowse {
+ module Wrappers {
+ struct PK {
+ ["slicer:xml:attribute"]
+ bool tracked;
+ ["slicer:xml:text"]
+ string name;
+ };
+
+ struct Package {
+ Gentoo::Package detail;
+ Gentoo::Ebuilds ebuilds;
+ };
+
+ ["slicer:key:id","slicer:value:package","slicer:item:package"]
+ dictionary<PK, Package> Packages;
+
+ ["slicer:key:id","slicer:value:packages","slicer:item:category"]
+ dictionary<PK, Packages> Categories;
+
+ ["slicer:key:timestamp","slicer:value:categories","slicer:item:sync"]
+ dictionary<string, Categories> Syncs;
+
+ struct SiteMapCategory {
+ ["slicer:name:detail"]
+ Gentoo::OverviewCategory category;
+ Gentoo::Packages packages;
+ };
+
+ ["slicer:element:category"]
+ sequence<SiteMapCategory> SiteMapCategories;
+ };
+
+ ["slicer:root:gentoo"]
+ class Index extends PageBase {
+ Wrappers::Syncs syncs;
+ };
+
+ ["slicer:root:gentoo"]
+ class Browse extends PageBase {
+ Gentoo::OverviewCategoriesBySuper categories;
+ };
+
+ ["slicer:root:gentoo"]
+ class Popular extends PageBase {
+ Gentoo::Categories categories;
+ Gentoo::Packages packages;
+ };
+
+ ["slicer:root:gentoo"]
+ class UserTracked extends Popular {
+ Gentoo::Ebuilds versions;
+ };
+
+ ["slicer:root:gentoo"]
+ class Sitemap extends PageBase {
+ Wrappers::SiteMapCategories categories;
+ };
+
+ ["slicer:root:gentoo"]
+ class Search extends PageBase {
+ Gentoo::Categories categories;
+ Gentoo::SearchResultPackages packages;
+ Gentoo::SearchResultBugs bugs;
+ Gentoo::News news;
+ Gentoo::Uses uses;
+ string query;
+ };
+
+ ["slicer:root:gentoo"]
+ class Category extends PageBase {
+ Gentoo::Category category;
+ Gentoo::Packages packages;
+ };
+
+ ["slicer:root:gentoo"]
+ class Package extends PageBase {
+ Gentoo::Categories categories;
+ Gentoo::Package package;
+ Gentoo::ChangeLog changelog;
+ Gentoo::EbuildDetails ebuilds;
+ Gentoo::PackageDependencyPackages dependencies;
+ Gentoo::PackageDependencyPackages rdependencies;
+ Gentoo::PackageDependencyPackages depending;
+ Gentoo::PackageMasks masks;
+ Gentoo::Uses uses;
+ Gentoo::Bugs bugs;
+ Gentoo::Repositories repos;
+ bool tracked = false;
+ };
+
+ ["slicer:root:gentoo"]
+ class Use extends PageBase {
+ Gentoo::Categories categories;
+ Gentoo::Uses usage;
+ Gentoo::Packages packages;
+ };
+
+ ["slicer:root:gentoo"]
+ class UseIndex extends PageBase {
+ Gentoo::Uses uses;
+ };
+};
diff --git a/gentoobrowse/src/news.ice b/gentoobrowse/src/news.ice
new file mode 100644
index 0000000..18af2a9
--- /dev/null
+++ b/gentoobrowse/src/news.ice
@@ -0,0 +1,14 @@
+#include <portage.ice>
+#include <pagebase.ice>
+
+module GentooBrowse {
+ class NewsRecent extends PageBase {
+ ["slicer:root:gentoo"]
+ Gentoo::News articles;
+ };
+ class NewsArticle extends PageBase {
+ ["slicer:root:gentoo"]
+ Gentoo::NewsItem article;
+ };
+};
+
diff --git a/gentoobrowse/src/news.json b/gentoobrowse/src/news.json
new file mode 100644
index 0000000..ce05e2a
--- /dev/null
+++ b/gentoobrowse/src/news.json
@@ -0,0 +1,52 @@
+{
+ "name": "GentooBrowse",
+ "headers": [ "xsltStreamSerializer.h", "icespider-routes-base.h" ],
+ "routes": {
+ "news": {
+ "path": "/news",
+ "bases": [ "common" ],
+ "mutators": [ "addUser" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/news.xslt\"" ]
+ },
+ "application/atom+xml": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/news-atom.xslt\"" ]
+ }
+ },
+ "operations": {
+ "articles": {
+ "operation": "Gentoo.Portage.getNewsRecent"
+ }
+ },
+ "type": "GentooBrowse.NewsRecent",
+ "params": {
+ "items": {
+ "default": "10"
+ }
+ }
+ },
+ "newsitem": {
+ "path": "/news/{newsid}",
+ "bases": [ "common" ],
+ "mutators": [ "addUser" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/newsitem.xslt\"" ]
+ }
+ },
+ "operations": {
+ "article": {
+ "operation": "Gentoo.Portage.getNewsItem"
+ }
+ },
+ "type": "GentooBrowse.NewsArticle"
+ }
+ },
+ "slices": [
+ "news.ice"
+ ]
+}
diff --git a/gentoobrowse/src/packages.cpp b/gentoobrowse/src/packages.cpp
new file mode 100644
index 0000000..f652900
--- /dev/null
+++ b/gentoobrowse/src/packages.cpp
@@ -0,0 +1,323 @@
+// Standard headers.
+#include <irouteHandler.h>
+#include <core.h>
+#include <util.h>
+#include <slicer/serializer.h>
+
+// Interface headers.
+#include <mash.h>
+#include <portage.h>
+
+// Extra headers.
+#include <xsltStreamSerializer.h>
+#include <icespider-routes-base.h>
+#include <safeMapFind.h>
+
+namespace GentooBrowse {
+ template<typename I, typename T> std::map<I, T> makeMap(const std::vector<T> & items, const boost::function<I(const T &)> & id)
+ {
+ std::map<I, T> rtn;
+ for (const auto & item : items) {
+ rtn.insert({ id(item), item });
+ }
+ return rtn;
+ }
+
+ // Implementation classes.
+
+ // Route name: index
+ // path: /
+ class index : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ index(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pd_syncs(3)
+ {
+ addRouteSerializer({ "application", "atom+xml" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/home-atom.xslt"));
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/home.xslt"));
+ }
+
+ ~index()
+ {
+ removeRouteSerializer({ "application", "atom+xml" });
+ removeRouteSerializer({ "text", "html" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ ::GentooBrowse::IndexPtr _responseModel = new ::GentooBrowse::Index();
+ auto _ar_categories = prx0->begin_getCategoriesWithRecentAdditions(_pd_syncs, request->getContext());
+ auto _ar_ebuilds = prx0->begin_getRecentAdditions(_pd_syncs, request->getContext());
+ auto _ar_packages = prx0->begin_getPackagesWithRecentAdditions(_pd_syncs, request->getContext());
+ addUser(request, _responseModel);
+ Ice::AsyncResultPtr _ar_t;
+ if (_responseModel->user) {
+ _ar_t = prx1->begin_tracked(_responseModel->user->userid);
+ }
+ auto ebuilds = prx0->end_getRecentAdditions(_ar_ebuilds);
+ auto packages = GentooBrowse::makeMap<Ice::Int, Gentoo::PackagePtr>(prx0->end_getPackagesWithRecentAdditions(_ar_packages), [](auto p){ return p->packageid; });
+ auto categories = GentooBrowse::makeMap<Ice::Int, Gentoo::CategoryPtr>(prx0->end_getCategoriesWithRecentAdditions(_ar_categories), [](auto c){ return c->categoryid; });
+ decltype(prx1->end_tracked(_ar_t)) tracked;
+ if (_ar_t) {
+ tracked = prx1->end_tracked(_ar_t);
+ }
+ for(const auto & ebuild : ebuilds) {
+ auto & p = packages[ebuild->packageid];
+ auto & c = categories[p->categoryid];
+ auto & s = _responseModel->syncs[ebuild->moddate.substr(0, 10)];
+ bool isTracked = std::find(tracked.begin(), tracked.end(), p->packageid) != tracked.end();
+ auto & pw = s[{ isTracked, c->name }][{ isTracked, p->name }];
+ if (!pw.detail) pw.detail = p;
+ pw.ebuilds.push_back(ebuild);
+ }
+ request->response(this, _responseModel);
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const ::Ice::Int _pd_syncs;
+ };
+
+ // Route name: category
+ // path: /packages/{category}
+ class category : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ category(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/packages/{category}"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ _pi_category(1)
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/category.xslt"));
+ }
+
+ ~category()
+ {
+ removeRouteSerializer({ "text", "html" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _p_category(request->getURLParam<::std::string>(_pi_category));
+ auto cat = prx0->findCategory(_p_category, request->getContext());
+ auto _ar_pkgs = prx0->begin_getPackagesInCategory(cat->categoryid, request->getContext());
+ ::GentooBrowse::CategoryPtr model = new ::GentooBrowse::Category();
+ model->category = cat;
+ model->packages = prx0->end_getPackagesInCategory(_ar_pkgs);
+ addUser(request, model);
+ request->response(this, model);
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ const ::Ice::Int _pi_category;
+ };
+
+ // Route name: package
+ // path: /packages/{category}/{package}
+ class package : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ package(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/packages/{category}/{package}"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pi_category(1),
+ _pi_package(2)
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/package.xslt"));
+ }
+
+ ~package()
+ {
+ removeRouteSerializer({ "text", "html" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _p_category(request->getURLParam<::std::string>(_pi_category));
+ auto _p_package(request->getURLParam<::std::string>(_pi_package));
+ auto _ar_p = prx0->begin_findPackage(_p_category, _p_package, request->getContext());
+ auto _ar_r = prx0->begin_getRepositories(request->getContext());
+ auto _ar_cats = prx0->begin_getAllCategories(request->getContext());
+ ::GentooBrowse::PackagePtr model = new ::GentooBrowse::Package();
+ model->package = prx0->end_findPackage(_ar_p);
+ Ice::AsyncResultPtr _ar_t;
+ auto _ar_cl = prx0->begin_getPackageChangeLog(model->package->packageid, request->getContext());
+ auto _ar_ebuilds = prx0->begin_getPackageVersionDetails(model->package->packageid, request->getContext());
+ auto _ar_bugs = prx0->begin_getPackageBugs(model->package->packageid, request->getContext());
+ auto _ar_d = prx0->begin_getPackageDependencies(model->package->packageid, request->getContext());
+ auto _ar_rd = prx0->begin_getPackageRuntimeDependencies(model->package->packageid, request->getContext());
+ auto _ar_dp = prx0->begin_getPackagesDepending(model->package->packageid, request->getContext());
+ auto _ar_m = prx0->begin_getPackageMasks(model->package->packageid, request->getContext());
+ auto _ar_u = prx0->begin_getPackageUses(model->package->packageid, request->getContext());
+ addUser(request, model);
+ if (model->user) {
+ _ar_t = prx1->begin_tracked(model->user->userid);
+ }
+ model->categories = prx0->end_getAllCategories(_ar_cats);
+ model->changelog = prx0->end_getPackageChangeLog(_ar_cl);
+ model->ebuilds = prx0->end_getPackageVersionDetails(_ar_ebuilds);
+ model->bugs = prx0->end_getPackageBugs(_ar_bugs);
+ model->dependencies = prx0->end_getPackageDependencies(_ar_d);
+ model->rdependencies = prx0->end_getPackageRuntimeDependencies(_ar_rd);
+ model->depending = prx0->end_getPackagesDepending(_ar_dp);
+ model->masks = prx0->end_getPackageMasks(_ar_m);
+ model->uses = prx0->end_getPackageUses(_ar_u);
+ model->repos = prx0->end_getRepositories(_ar_r);
+ std::set<Ice::Int> ids({ model->package->categoryid });
+ collateCategoryIds(ids, model->dependencies);
+ collateCategoryIds(ids, model->depending);
+ collateCategoryIds(ids, model->rdependencies);
+ model->categories.erase(std::remove_if(model->categories.begin(), model->categories.end(), [&ids](auto category) {
+ return ids.find(category->categoryid) == ids.end();
+ }), model->categories.end());
+ if (_ar_t) {
+ model->tracked = AdHoc::containerContains(prx1->end_tracked(_ar_t), model->package->packageid);
+ }
+ request->response(this, model);
+ }
+
+ private:
+ template<typename T>
+ static void collateCategoryIds(std::set<Ice::Int> & ids, const std::vector<T> & packages)
+ {
+ std::transform(packages.begin(), packages.end(), std::inserter(ids, ids.begin()), [](auto p) {
+ return p->categoryid;
+ });
+ }
+ const Gentoo::PortagePrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const ::Ice::Int _pi_category;
+ const ::Ice::Int _pi_package;
+ };
+
+
+ // Route name: track package
+ // path: /packages/{category}/{package}/tracked
+ class packageTrack : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ packageTrack(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::PUT, "/packages/{category}/{package}/tracked"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pi_category(1),
+ _pi_package(2)
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _p_category(request->getURLParam<::std::string>(_pi_category));
+ auto _p_package(request->getURLParam<::std::string>(_pi_package));
+ auto p = prx0->findPackage(_p_category, _p_package, request->getContext());
+ auto u = this->currentUser(request);
+ prx1->track(u->userid, p->packageid);
+ request->response(204, "Tracked");
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const ::Ice::Int _pi_category;
+ const ::Ice::Int _pi_package;
+ };
+
+
+ // Route name: untrack package
+ // path: /packages/{category}/{package}/tracked
+ class packageUntrack : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ packageUntrack(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::DELETE, "/packages/{category}/{package}/tracked"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pi_category(1),
+ _pi_package(2)
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _p_category(request->getURLParam<::std::string>(_pi_category));
+ auto _p_package(request->getURLParam<::std::string>(_pi_package));
+ auto p = prx0->findPackage(_p_category, _p_package, request->getContext());
+ auto u = this->currentUser(request);
+ prx1->untrack(u->userid, p->packageid);
+ request->response(204, "Untracked");
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const ::Ice::Int _pi_category;
+ const ::Ice::Int _pi_package;
+ };
+
+
+ // Route name: userAtom
+ // path: /atom/{username}
+ class userAtom : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ userAtom(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/atom/{username}"),
+ common(core),
+ prx0(core->getProxy<Gentoo::Portage>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pi_username(1)
+ {
+ addRouteSerializer({ "application", "atom+xml" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/user-atom.xslt"));
+ removeRouteSerializer({ "application", "xml" });
+ removeRouteSerializer({ "application", "json" });
+ }
+
+ ~userAtom()
+ {
+ removeRouteSerializer({ "application", "atom+xml" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _p_username(request->getURLParam<::std::string>(_pi_username));
+ auto user = prx1->find(_p_username);
+ auto _ar_cs = prx0->begin_getAllCategories(request->getContext());
+ auto _ar_ps = prx0->begin_getUserTrackedPackages(user->userid, request->getContext());
+ auto _ar_vs = prx0->begin_getUserTrackedRecentVersions(user->userid, 50, request->getContext());
+ GentooBrowse::UserTrackedPtr ut = new GentooBrowse::UserTracked();
+ ut->categories = prx0->end_getAllCategories(_ar_cs);
+ ut->packages = prx0->end_getUserTrackedPackages(_ar_ps);
+ ut->versions = prx0->end_getUserTrackedRecentVersions(_ar_vs);
+ common::trimPackages(ut->packages, ut->versions);
+ common::trimCategories(ut->categories, ut->packages);
+ request->response(this, ut);
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const ::Ice::Int _pi_username;
+ };
+
+
+} // namespace gentoobrowse
+
+// Register route handlers.
+FACTORY(GentooBrowse::index, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::category, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::package, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::packageTrack, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::packageUntrack, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::userAtom, IceSpider::RouteHandlerFactory);
+
diff --git a/gentoobrowse/src/packages.json b/gentoobrowse/src/packages.json
new file mode 100644
index 0000000..aa65b0b
--- /dev/null
+++ b/gentoobrowse/src/packages.json
@@ -0,0 +1,52 @@
+{
+ "name": "GentooBrowse",
+ "headers": [ "xsltStreamSerializer.h", "icespider-routes-base.h" ],
+ "routes": {
+ "browse": {
+ "path": "/packages",
+ "bases": [ "common" ],
+ "mutators": [ "addUser" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/categories.xslt\"" ]
+ }
+ },
+ "operations": {
+ "categories": {
+ "operation": "Gentoo.Portage.getAllOverviewCategories"
+ }
+ },
+ "type": "GentooBrowse.Browse"
+ },
+ "popular": {
+ "path": "/packages/popular",
+ "bases": [ "common" ],
+ "mutators": [ "addUser", "trimCategories" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/popular.xslt\"" ]
+ }
+ },
+ "operations": {
+ "categories": {
+ "operation": "Gentoo.Portage.getAllCategories"
+ },
+ "packages": {
+ "operation": "Gentoo.Portage.getTopTrackedPackages"
+ }
+ },
+ "type": "GentooBrowse.Popular",
+ "params": {
+ "n": {
+ "default": "50"
+ }
+ }
+ }
+ },
+ "slices": [
+ "mash.ice",
+ "portage.ice"
+ ]
+}
diff --git a/gentoobrowse/src/pagebase.ice b/gentoobrowse/src/pagebase.ice
new file mode 100644
index 0000000..7fbb953
--- /dev/null
+++ b/gentoobrowse/src/pagebase.ice
@@ -0,0 +1,26 @@
+#ifndef GENTOOBRWOSE_PAGEBASE_ICE
+#define GENTOOBRWOSE_PAGEBASE_ICE
+
+#include <user-models.ice>
+
+module GentooBrowse {
+ const string USERID = "userId";
+ const string SESSIONID = "sessionId";
+
+ class PageBase {
+ Gentoo::User user;
+ };
+
+ class Credentials {
+ string username;
+ string password;
+ };
+
+ class SignUp extends Credentials {
+ string realname;
+ string email;
+ };
+};
+
+#endif
+
diff --git a/gentoobrowse/src/search.cpp b/gentoobrowse/src/search.cpp
new file mode 100644
index 0000000..c435df1
--- /dev/null
+++ b/gentoobrowse/src/search.cpp
@@ -0,0 +1,67 @@
+// Standard headers.
+#include <irouteHandler.h>
+#include <core.h>
+#include <util.h>
+#include <slicer/serializer.h>
+
+// Interface headers.
+#include <mash.h>
+#include <portage.h>
+
+// Extra headers.
+#include <xsltStreamSerializer.h>
+#include <icespider-routes-base.h>
+#include <safeMapFind.h>
+
+namespace GentooBrowse {
+ // Base classes.
+
+} // namespace GentooBrowse
+
+
+namespace GentooBrowse {
+ // Route name: sitemap
+ // path: /sitemap.xml
+ class sitemap : public IceSpider::IRouteHandler {
+ public:
+ sitemap(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/sitemap.xml"),
+ prx0(core->getProxy<Gentoo::Portage>())
+ {
+ addRouteSerializer({ "application", "xml" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/sitemap.xslt"));
+ }
+
+ ~sitemap()
+ {
+ removeRouteSerializer({ "application", "xml" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _ar_categories = prx0->begin_getAllOverviewCategories(request->getContext());
+ auto _ar_packages = prx0->begin_getAllPackages(request->getContext());
+ ::GentooBrowse::SitemapPtr _responseModel = new ::GentooBrowse::Sitemap();
+ auto categories = prx0->end_getAllOverviewCategories(_ar_categories);
+ auto packages = prx0->end_getAllPackages(_ar_packages);
+ for (const auto & super : categories) {
+ std::transform(super.second.begin(), super.second.end(),
+ std::inserter(_responseModel->categories, _responseModel->categories.begin()), [&packages](auto c) {
+ Gentoo::Packages ps;
+ std::copy_if(packages.begin(), packages.end(), std::inserter(ps, ps.begin()), [&c](auto p) {
+ return p->categoryid == c->categoryid;
+ });
+ return GentooBrowse::Wrappers::SiteMapCategory({ c, ps });
+ });
+ }
+ request->response(this, _responseModel);
+ }
+
+ private:
+ const Gentoo::PortagePrx prx0;
+ };
+
+} // namespace GentooBrowse
+
+// Register route handlers.
+FACTORY(GentooBrowse::sitemap, IceSpider::RouteHandlerFactory);
+
diff --git a/gentoobrowse/src/search.json b/gentoobrowse/src/search.json
new file mode 100644
index 0000000..aea47c3
--- /dev/null
+++ b/gentoobrowse/src/search.json
@@ -0,0 +1,45 @@
+{
+ "name": "GentooBrowse",
+ "headers": [ "xsltStreamSerializer.h", "icespider-routes-base.h" ],
+ "routes": {
+ "search": {
+ "path": "/search",
+ "bases": [ "common" ],
+ "mutators": [ "addUser", "trimCategories" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/search.xslt\"" ]
+ }
+ },
+ "operations": {
+ "categories": {
+ "operation": "Gentoo.Portage.getAllCategories"
+ },
+ "packages": {
+ "operation": "Gentoo.Portage.getPackagesSearch"
+ },
+ "bugs": {
+ "operation": "Gentoo.Portage.getBugsSearch"
+ },
+ "uses": {
+ "operation": "Gentoo.Portage.getUsesSearch"
+ },
+ "news": {
+ "operation": "Gentoo.Portage.getNewsSearch"
+ }
+ },
+ "type": "GentooBrowse.Search",
+ "params": {
+ "query": {
+ "source": "QueryString",
+ "key": "criteria"
+ }
+ }
+ }
+ },
+ "slices": [
+ "mash.ice",
+ "portage.ice"
+ ]
+}
diff --git a/gentoobrowse/src/use.json b/gentoobrowse/src/use.json
new file mode 100644
index 0000000..63a9161
--- /dev/null
+++ b/gentoobrowse/src/use.json
@@ -0,0 +1,50 @@
+{
+ "name": "GentooBrowse",
+ "headers": [ "xsltStreamSerializer.h", "icespider-routes-base.h" ],
+ "routes": {
+ "useIndex": {
+ "path": "/use",
+ "bases": [ "common" ],
+ "mutators": [ "addUser" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/use.xslt\"" ]
+ }
+ },
+ "operations": {
+ "uses": {
+ "operation": "Gentoo.Portage.getGlobalUses"
+ }
+ },
+ "type": "GentooBrowse.UseIndex"
+ },
+ "useDetail": {
+ "path": "/use/{flag}",
+ "bases": [ "common" ],
+ "mutators": [ "addUser", "trimCategories" ],
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/use-detail.xslt\"" ]
+ }
+ },
+ "operations": {
+ "categories": {
+ "operation": "Gentoo.Portage.getAllCategories"
+ },
+ "packages": {
+ "operation": "Gentoo.Portage.getUsePackages"
+ },
+ "usage": {
+ "operation": "Gentoo.Portage.getUseUsage"
+ }
+ },
+ "type": "GentooBrowse.Use"
+ }
+ },
+ "slices": [
+ "mash.ice",
+ "portage.ice"
+ ]
+}
diff --git a/gentoobrowse/src/user.cpp b/gentoobrowse/src/user.cpp
new file mode 100644
index 0000000..1bd5b88
--- /dev/null
+++ b/gentoobrowse/src/user.cpp
@@ -0,0 +1,236 @@
+// Standard headers.
+#include <irouteHandler.h>
+#include <core.h>
+#include <slicer/serializer.h>
+
+// Interface headers.
+#include <mash.h>
+#include <users.h>
+#include <session.h>
+
+// Extra headers.
+#include <xsltStreamSerializer.h>
+#include <icespider-routes-base.h>
+
+namespace GentooBrowse {
+ // Implementation classes.
+
+ // Route name: login
+ // path: /user/login
+ class login : public IceSpider::IRouteHandler {
+ public:
+ login(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::POST, "/user/login"),
+ prx0(core->getProxy<IceSpider::SessionManager>()),
+ prx1(core->getProxy<Gentoo::Users>())
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto credentials = *request->getBody<GentooBrowse::CredentialsPtr>();
+ auto user = prx1->authenticate(credentials->username, credentials->password);
+ auto s = prx0->createSession();
+ s->variables[USERID] = boost::lexical_cast<std::string>(user->userid);
+ prx0->updateSession(s);
+ request->setCookie(SESSIONID, s->id, IceUtil::None, "/");
+ request->responseRedirect("/user/home", "Authenticated");
+ }
+
+ private:
+ const IceSpider::SessionManagerPrx prx0;
+ const Gentoo::UsersPrx prx1;
+ };
+
+ // Route name: signup
+ // path: /user/signup
+ class signup : public IceSpider::IRouteHandler {
+ public:
+ signup(const IceSpider::Core *) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/user/signup")
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/user-signup.xslt"));
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ PageBasePtr p = new PageBase();
+ request->response(this, p);
+ }
+ };
+
+ // Route name: signup post
+ // path: /user/signup
+ class signupPost : public IceSpider::IRouteHandler {
+ public:
+ signupPost(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::POST, "/user/signup"),
+ prx1(core->getProxy<Gentoo::Users>())
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto signup = *request->getBody<GentooBrowse::SignUpPtr>();
+ auto user = prx1->create(signup->username, signup->password, signup->realname, signup->email);
+ request->responseRedirect("/user/verification", "Pending verification");
+ }
+
+ private:
+ const Gentoo::UsersPrx prx1;
+ };
+
+ // Route name: verification
+ // path: /user/verification
+ class verification : public IceSpider::IRouteHandler {
+ public:
+ verification(const IceSpider::Core *) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/user/verification")
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/user-verification.xslt"));
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ PageBasePtr p = new PageBase();
+ request->response(this, p);
+ }
+ };
+
+ // Route name: verification post
+ // path: /user/verification
+ class verificationPost : public IceSpider::IRouteHandler {
+ public:
+ verificationPost(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::POST, "/user/verification"),
+ prx0(core->getProxy<IceSpider::SessionManager>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ _pn_username("username"),
+ _pn_guid("guid")
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ auto _pbody(request->getBody<IceSpider::StringMap>());
+ auto _p_username(request->getBodyParam<::std::string>(_pbody, _pn_username) /
+ [this]() { return requiredParameterNotFound<::std::string>("Body", _pn_username); });
+ auto _p_guid(request->getBodyParam<::std::string>(_pbody, _pn_guid) /
+ [this]() { return requiredParameterNotFound<::std::string>("Body", _pn_guid); });
+ auto user = prx1->verify(_p_username, _p_guid, request->getContext());
+ auto s = prx0->createSession();
+ s->variables[USERID] = boost::lexical_cast<std::string>(user->userid);
+ prx0->updateSession(s);
+ request->setCookie(SESSIONID, s->id, IceUtil::None, "/");
+ request->responseRedirect("/user/home", "Verified, welcome!");
+ }
+
+ private:
+ const IceSpider::SessionManagerPrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const std::string _pn_username;
+ const std::string _pn_guid;
+ };
+
+ // Route name: home
+ // path: /user/home
+ class home : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ home(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/user/home"),
+ common(core),
+ prx0(core->getProxy<IceSpider::SessionManager>()),
+ prx1(core->getProxy<Gentoo::Users>())
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/user-home.xslt"));
+ }
+
+ ~home()
+ {
+ removeRouteSerializer({ "text", "html" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ PageBasePtr p = new PageBase();
+ addUser(request, p);
+ request->response(this, p);
+ }
+
+ private:
+ const IceSpider::SessionManagerPrx prx0;
+ const Gentoo::UsersPrx prx1;
+ };
+
+ // Route name: tracked
+ // path: /user/tracked
+ class tracked : public IceSpider::IRouteHandler,
+ public common {
+ public:
+ tracked(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/user/tracked"),
+ common(core),
+ prx0(core->getProxy<IceSpider::SessionManager>()),
+ prx1(core->getProxy<Gentoo::Users>()),
+ prx2(core->getProxy<Gentoo::Portage>())
+ {
+ addRouteSerializer({ "text", "html" }, new IceSpider::XsltStreamSerializer::IceSpiderFactory("xslt/user-tracked.xslt"));
+ }
+
+ ~tracked()
+ {
+ removeRouteSerializer({ "text", "html" });
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ PopularPtr u = new Popular();
+ auto _ar_c = prx2->begin_getAllCategories(request->getContext());
+ addUser(request, u);
+ auto _ar_p = prx2->begin_getUserTrackedPackages(u->user->userid, request->getContext());
+ u->categories = prx2->end_getAllCategories(_ar_c);
+ u->packages = prx2->end_getUserTrackedPackages(_ar_p);
+ request->response(this, u);
+ }
+
+ private:
+ const IceSpider::SessionManagerPrx prx0;
+ const Gentoo::UsersPrx prx1;
+ const Gentoo::PortagePrx prx2;
+ };
+
+ // Route name: logout
+ // path: /user/logout
+ class logout : public IceSpider::IRouteHandler {
+ public:
+ logout(const IceSpider::Core * core) :
+ IceSpider::IRouteHandler(IceSpider::HttpMethod::GET, "/user/logout"),
+ prx0(core->getProxy<IceSpider::SessionManager>())
+ {
+ }
+
+ void execute(IceSpider::IHttpRequest * request) const
+ {
+ prx0->destroySession(*request->getCookieParam<std::string>(SESSIONID));
+ request->setCookie(SESSIONID, std::string(), IceUtil::None, "/", false, 0);
+ request->responseRedirect("/", "Logged out");
+ }
+
+ private:
+ const IceSpider::SessionManagerPrx prx0;
+ };
+
+
+} // namespace gentoobrowse
+
+// Register route handlers.
+FACTORY(GentooBrowse::login, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::home, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::tracked, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::logout, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::signup, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::signupPost, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::verification, IceSpider::RouteHandlerFactory);
+FACTORY(GentooBrowse::verificationPost, IceSpider::RouteHandlerFactory);
+