From 2700ed6a3e1092a064f28b07f8e2c4e5b9b830e7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 16 Nov 2015 20:02:06 +0200 Subject: Implement new URL path schema for the web interface --- brep/package-version-details.cxx | 477 +++++++++++++++++++-------------------- 1 file changed, 232 insertions(+), 245 deletions(-) (limited to 'brep/package-version-details.cxx') diff --git a/brep/package-version-details.cxx b/brep/package-version-details.cxx index a1fe017..a0ad7d4 100644 --- a/brep/package-version-details.cxx +++ b/brep/package-version-details.cxx @@ -4,9 +4,6 @@ #include -#include -#include // shared_ptr, make_shared() -#include #include // invalid_argument #include @@ -20,6 +17,8 @@ #include #include +#include +#include #include #include #include @@ -27,297 +26,285 @@ using namespace std; using namespace odb::core; +using namespace brep::cli; -namespace brep +void brep::package_version_details:: +init (scanner& s) { - using namespace cli; + MODULE_DIAG; - void package_version_details:: - init (scanner& s) - { - MODULE_DIAG; - - options_ = make_shared ( - s, unknown_mode::fail, unknown_mode::fail); - - db_ = shared_database (options_->db_host (), options_->db_port ()); - } + options_ = make_shared ( + s, unknown_mode::fail, unknown_mode::fail); - void package_version_details:: - handle (request& rq, response& rs) - { - using namespace web; - using namespace web::xhtml; + db_ = shared_database (options_->db_host (), options_->db_port ()); +} - MODULE_DIAG; +void brep::package_version_details:: +handle (request& rq, response& rs) +{ + using namespace web; + using namespace web::xhtml; - // The module options object is not changed after being created once per - // server process. - // - static const dir_path& rt ( - options_->root ().empty () - ? dir_path ("/") - : options_->root ()); + MODULE_DIAG; - auto i (rq.path ().rbegin ()); - version v; + // The module options object is not changed after being created once per + // server process. + // + static const dir_path& root ( + options_->root ().empty () + ? dir_path ("/") + : options_->root ()); - try - { - v = version (*i++); - } - catch (const invalid_argument& ) - { - throw invalid_request (400, "invalid package version format"); - } + auto i (rq.path ().rbegin ()); + version ver; - const string& vs (v.string ()); + try + { + ver = version (*i++); + } + catch (const invalid_argument& ) + { + throw invalid_request (400, "invalid package version format"); + } - assert (i != rq.path ().rend ()); - const string& n (*i); // Package name. - const string name (n + " " + vs); + const string& sver (ver.string ()); - params::package_version_details pr; + assert (i != rq.path ().rend ()); + const string& name (*i); - try - { - param_scanner s (rq.parameters ()); - pr = params::package_version_details ( - s, unknown_mode::fail, unknown_mode::fail); - } - catch (const unknown_argument& e) - { - throw invalid_request (400, e.what ()); - } + params::package_version_details params; + bool full; - bool f (pr.full ()); + try + { + param_scanner s (rq.parameters ()); + params = params::package_version_details ( + s, unknown_mode::fail, unknown_mode::fail); - auto url ([&vs](bool f = false, const string& a = "") -> string - { - string u (vs); - - if (f) { u += "?full"; } - if (!a.empty ()) { u += '#' + a; } - return u; - }); - - xml::serializer s (rs.content (), name); - static const path go ("go"); - static const path sp ("package-version-details.css"); - - s << HTML - << HEAD - << TITLE << name << ~TITLE - << CSS_LINKS (sp, rt) - << ~HEAD - << BODY - << DIV_HEADER (rt) - << DIV(ID="content"); - - if (f) - s << CLASS("full"); - - s << DIV(ID="heading") - << H1 - << A(HREF=rt / go / path (mime_url_encode (n))) << n << ~A - << "/" - << A(HREF=url ()) << vs << ~A - << ~H1 - << A(HREF=url (!f)) << (f ? "[brief]" : "[full]") << ~A - << ~DIV; - - bool not_found (false); - shared_ptr p; - - session sn; - transaction t (db_->begin ()); - - try - { - p = db_->load (package_id (n, v)); + full = params.form () == page_form::full; + } + catch (const unknown_argument& e) + { + throw invalid_request (400, e.what ()); + } - // If the requested package turned up to be an "external" one just - // respond that no "internal" package is present. - // - not_found = !p->internal (); - } - catch (const object_not_persistent& ) + auto url ( + [&sver](bool f = false, const string& a = "") -> string { - not_found = true; - } - - if (not_found) - throw invalid_request (404, "Package '" + name + "' not found"); - - s << H2 << p->summary << ~H2; - - static const size_t dl (options_->description_length ()); - - if (const auto& d = p->description) - s << (f - ? P_DESCRIPTION (*d) - : P_DESCRIPTION (*d, dl, url (!f, "description"))); + string u (sver); + + if (f) { u += "?f=full"; } + if (!a.empty ()) { u += '#' + a; } + return u; + }); + + const string title (name + " " + sver); + xml::serializer s (rs.content (), title); + + s << HTML + << HEAD + << TITLE << title << ~TITLE + << CSS_LINKS (path ("package-version-details.css"), root) + << ~HEAD + << BODY + << DIV_HEADER (root) + << DIV(ID="content"); + + if (full) + s << CLASS("full"); + + s << DIV(ID="heading") + << H1 + << A(HREF=root / path (mime_url_encode (name))) << name << ~A + << "/" + << A(HREF=url ()) << sver << ~A + << ~H1 + << A(HREF=url (!full)) << (full ? "[brief]" : "[full]") << ~A + << ~DIV; + + bool not_found (false); + shared_ptr pkg; + + session sn; + transaction t (db_->begin ()); + + try + { + pkg = db_->load (package_id (name, ver)); - // Link to download from the internal repository. + // If the requested package turned up to be an "external" one just + // respond that no "internal" package is present. // - assert (p->location); - const string du (p->internal_repository.load ()->location.string () + "/" + - p->location->string ()); + not_found = !pkg->internal (); + } + catch (const object_not_persistent& ) + { + not_found = true; + } - s << TABLE(CLASS="proplist", ID="version") - << TBODY + if (not_found) + throw invalid_request (404, "Package '" + title + "' not found"); - // Repeat version here since it can be cut out in the header. - // - << TR_VERSION (p->version.string ()) + s << H2 << pkg->summary << ~H2; - << TR_PRIORITY (p->priority) - << TR_LICENSES (p->license_alternatives) - << TR_LOCATION (p->internal_repository.object_id (), rt) - << TR_DOWNLOAD (du) - << ~TBODY - << ~TABLE + static const string id ("description"); + if (const auto& d = pkg->description) + s << (full + ? P_DESCRIPTION (*d, id) + : P_DESCRIPTION (*d, options_->description_length (), + url (!full, id))); - << TABLE(CLASS="proplist", ID="package") - << TBODY - << TR_URL (p->url) - << TR_EMAIL (p->email); + assert (pkg->location); - if (p->package_url && *p->package_url != p->url) - s << TR_URL (*p->package_url, "pkg-url"); + s << TABLE(CLASS="proplist", ID="version") + << TBODY - if (p->package_email && *p->package_email != p->email) - s << TR_EMAIL (*p->package_email, "pkg-email"); + // Repeat version here since it can be cut out in the header. + // + << TR_VERSION (pkg->version.string ()) + + << TR_PRIORITY (pkg->priority) + << TR_LICENSES (pkg->license_alternatives) + << TR_LOCATION (pkg->internal_repository.object_id (), root) + << TR_DOWNLOAD (pkg->internal_repository.load ()->location.string () + + "/" + pkg->location->string ()) + << ~TBODY + << ~TABLE + + << TABLE(CLASS="proplist", ID="package") + << TBODY + << TR_URL (pkg->url) + << TR_EMAIL (pkg->email); + + const auto& pu (pkg->package_url); + if (pu && *pu != pkg->url) + s << TR_URL (*pu, "pkg-url"); + + const auto& pe (pkg->package_email); + if (pe && *pe != pkg->email) + s << TR_EMAIL (*pe, "pkg-email"); + + s << TR_TAGS (pkg->tags, root) + << ~TBODY + << ~TABLE; + + const auto& ds (pkg->dependencies); + if (!ds.empty ()) + { + s << H3 << "Depends" << ~H3 + << TABLE(CLASS="proplist", ID="depends") + << TBODY; - s << TR_TAGS (p->tags, rt) - << ~TBODY - << ~TABLE; + for (const auto& da: ds) + { + s << TR(CLASS="depends") + << TH; - const auto& ds (p->dependencies); + if (da.conditional) + s << "?"; - if (!ds.empty ()) - { - s << H3 << "Depends" << ~H3 - << TABLE(CLASS="proplist", ID="depends") - << TBODY; + s << ~TH + << TD + << SPAN(CLASS="value"); - for (const auto& da: ds) + for (const auto& d: da) { - s << TR(CLASS="depends") - << TH; + if (&d != &da[0]) + s << " | "; - if (da.conditional) - s << "?"; + shared_ptr p (d.package.load ()); + assert (p->internal () || !p->other_repositories.empty ()); - s << ~TH - << TD - << SPAN(CLASS="value"); + shared_ptr r ( + p->internal () + ? p->internal_repository.load () + : p->other_repositories[0].load ()); - for (const auto& d: da) + const auto& dcon (d.constraint); + const string& dname (p->id.name); + string ename (mime_url_encode (dname)); + + if (r->url) { - if (&d != &da[0]) - s << " | "; - - shared_ptr p (d.package.load ()); - assert (p->internal () || !p->other_repositories.empty ()); - - shared_ptr r ( - p->internal () - ? p->internal_repository.load () - : p->other_repositories[0].load ()); - - const auto& dc (d.constraint); - const string& dn (p->id.name); - string en (mime_url_encode (dn)); - - if (r->url) - { - string u (*r->url + "go/" + en); - s << A(HREF=u) << dn << ~A; - - if (dc) - s << ' ' - << A - << HREF << u << "/" << p->version.string () << ~HREF - << *dc - << ~A; - } - else if (p->internal ()) - { - path u (rt / go / path (en)); - s << A(HREF=u) << dn << ~A; - - if (dc) - s << ' ' << A(HREF=u / path (p->version.string ())) << *dc << ~A; - } - else - // Display the dependency as a plain text if no repository URL - // available. - // - s << d; + string u (*r->url + ename); + s << A(HREF=u) << dname << ~A; + + if (dcon) + s << ' ' << A(HREF=u + "/" + p->version.string ()) << *dcon << ~A; } + else if (p->internal ()) + { + path u (root / path (ename)); + s << A(HREF=u) << dname << ~A; - s << ~SPAN - << SPAN_COMMENT (da.comment) - << ~TD - << ~TR; + if (dcon) + s << ' ' << A(HREF=u / path (p->version.string ())) << *dcon << ~A; + } + else + // Display the dependency as a plain text if no repository URL + // available. + // + s << d; } - s << ~TBODY - << ~TABLE; + s << ~SPAN + << SPAN_COMMENT (da.comment) + << ~TD + << ~TR; } - t.commit (); + s << ~TBODY + << ~TABLE; + } - const auto& rm (p->requirements); + t.commit (); - if (!rm.empty ()) - { - s << H3 << "Requires" << ~H3 - << TABLE(CLASS="proplist", ID="requires") - << TBODY; + const auto& rm (pkg->requirements); + if (!rm.empty ()) + { + s << H3 << "Requires" << ~H3 + << TABLE(CLASS="proplist", ID="requires") + << TBODY; - for (const auto& ra: rm) - { - s << TR(CLASS="requires") - << TH; + for (const auto& ra: rm) + { + s << TR(CLASS="requires") + << TH; - if (ra.conditional) - s << "?"; + if (ra.conditional) + s << "?"; - s << ~TH - << TD - << SPAN(CLASS="value"); + s << ~TH + << TD + << SPAN(CLASS="value"); - for (const auto& r: ra) - { - if (&r != &ra[0]) - s << " | "; - - s << r; - } + for (const auto& r: ra) + { + if (&r != &ra[0]) + s << " | "; - s << ~SPAN - << SPAN_COMMENT (ra.comment) - << ~TD - << ~TR; + s << r; } - s << ~TBODY - << ~TABLE; + s << ~SPAN + << SPAN_COMMENT (ra.comment) + << ~TD + << ~TR; } - static const size_t cl (options_->changes_length ()); - const auto& ch (p->changes); - - if (!ch.empty ()) - s << H3 << "Changes" << ~H3 - << (f - ? PRE_CHANGES (ch) - : PRE_CHANGES (ch, cl, url (!f, "changes"))); - - s << ~DIV - << ~BODY - << ~HTML; + s << ~TBODY + << ~TABLE; } + + const auto& ch (pkg->changes); + if (!ch.empty ()) + s << H3 << "Changes" << ~H3 + << (full + ? PRE_CHANGES (ch) + : PRE_CHANGES (ch, options_->description_length (), + url (!full, "changes"))); + + s << ~DIV + << ~BODY + << ~HTML; } -- cgit v1.1