diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-12-21 15:02:57 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-01-16 21:47:53 +0000 |
commit | 1f675b4dea063c5272b9b0421dafcb23f55ad959 (patch) | |
tree | b1a483a44bb3a4d319853cffc71865b022c75b2b /gentoobrowse/src | |
parent | Set cxxflags specifically, not cflags (diff) | |
download | gentoobrowse-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.jam | 59 | ||||
-rw-r--r-- | gentoobrowse/src/base.cpp | 67 | ||||
-rw-r--r-- | gentoobrowse/src/base.json | 21 | ||||
-rw-r--r-- | gentoobrowse/src/mash.ice | 107 | ||||
-rw-r--r-- | gentoobrowse/src/news.ice | 14 | ||||
-rw-r--r-- | gentoobrowse/src/news.json | 52 | ||||
-rw-r--r-- | gentoobrowse/src/packages.cpp | 323 | ||||
-rw-r--r-- | gentoobrowse/src/packages.json | 52 | ||||
-rw-r--r-- | gentoobrowse/src/pagebase.ice | 26 | ||||
-rw-r--r-- | gentoobrowse/src/search.cpp | 67 | ||||
-rw-r--r-- | gentoobrowse/src/search.json | 45 | ||||
-rw-r--r-- | gentoobrowse/src/use.json | 50 | ||||
-rw-r--r-- | gentoobrowse/src/user.cpp | 236 |
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); + |