From 75825230abcc5f303a29f1f74b29c36e6140a064 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 13 Sep 2015 22:46:48 +0200 Subject: Implement package details page --- brep/package-version-search.cxx | 162 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 2 deletions(-) (limited to 'brep/package-version-search.cxx') diff --git a/brep/package-version-search.cxx b/brep/package-version-search.cxx index a989434..d95b392 100644 --- a/brep/package-version-search.cxx +++ b/brep/package-version-search.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -60,14 +61,171 @@ namespace brep throw invalid_request (400, e.what ()); } - const char* title ("Package"); + const char* ident ("\n "); + const string title ("Package " + name); serializer s (rs.content (), title); s << HTML << HEAD << TITLE << title << ~TITLE + << CSS_STYLE << ident + << pager_style () << ident + << "a {text-decoration: none;}" << ident + << "a:hover {text-decoration: underline;}" << ident + << ".name {font-size: xx-large; font-weight: bold;}" << ident + << ".summary {font-size: x-large; margin: 0.2em 0 0;}" << ident + << ".url {font-size: small;}" << ident + << ".email {font-size: small;}" << ident + << ".description {margin: 0.5em 0 0;}" << ident + << ".tags {margin: 0.5em 0 0;}" << ident + << ".tag {padding: 0 0.3em 0 0;}" << ident + << ".versions {font-size: x-large; margin: 0.5em 0 0;}" << ident + << ".package_version {margin: 0.5em 0 0;}" << ident + << ".version {font-size: x-large;}" << ident + << ~CSS_STYLE << ~HEAD - << BODY << name << ~BODY + << BODY; + + transaction t (db_->begin ()); + + shared_ptr p; + + try + { + p = db_->load (name); + } + catch (const object_not_persistent& ) + { + throw invalid_request (404, "Package '" + name + "' not found"); + } + + s << DIV(CLASS="name") + << name + << ~DIV + << DIV(CLASS="summary") + << p->summary + << ~DIV; + + s << DIV(CLASS="url") + << A << HREF << p->url << ~HREF << p->url << ~A + << ~DIV + << DIV(CLASS="email") + << A << HREF << "mailto:" << p->email << ~HREF << p->email << ~A + << ~DIV; + + if (p->description) + s << DIV(CLASS="description") + << *p->description + << ~DIV; + + if (!p->tags.empty ()) + { + s << DIV(CLASS="tags"); + + for (const auto& t: p->tags) + s << SPAN(CLASS="tag") << t << ~SPAN << " "; + + s << ~DIV; + } + + // @@ Query will also include search criteria if specified. + // + size_t pvc ( + db_->query_value ( + query::id.data.package == name).count); + + s << DIV(CLASS="versions") + << "Versions (" << pvc << ")" + << ~DIV; + + if (p->package_url) + s << DIV(CLASS="url") + << A << HREF << *p->package_url << ~HREF << *p->package_url << ~A + << ~DIV; + + if (p->package_email) + s << DIV(CLASS="email") + << A + << HREF << "mailto:" << *p->package_email << ~HREF + << *p->package_email + << ~A + << ~DIV; + + size_t rop (options_->results_on_page ()); + + // @@ Use appropriate view when clarify which package version info to be + // displayed and search index structure get implemented. Query will also + // include search criteria if specified. + // + using query = query; + auto r ( + db_->query ((query::id.data.package == name) + + "ORDER BY" + query::id.data.epoch + "DESC," + + query::id.data.canonical_upstream + "DESC," + + query::id.revision + "DESC " + + "OFFSET" + to_string (pr.page () * rop) + + "LIMIT" + to_string (rop))); + + for (const auto& v: r) + { + static const strings priority_names ( + {"low", "medium", "high", "security"}); + + assert (v.priority < priority_names.size ()); + + const string& vs (v.version.string ()); + + s << DIV(CLASS="package_version") + << DIV(CLASS="version") + << A + << HREF + << "/go/" << mime_url_encode (name) << "/" << vs << "/" + << ~HREF + << vs + << ~A + << ~DIV + << DIV(CLASS="priority") + << "Priority: " << priority_names[v.priority] + << ~DIV + << DIV(CLASS="licenses") + << "Licenses: "; + + for (const auto& la: v.license_alternatives) + { + if (&la != &v.license_alternatives[0]) + s << " or "; + + for (const auto& l: la) + { + if (&l != &la[0]) + s << ", "; + + s << l; + } + } + + s << ~DIV + << ~DIV; + } + + t.commit (); + + auto u ( + [&name, &pr](size_t p) + { + string url ("/go/" + name + "/"); + if (p > 0) + url += "?p=" + to_string (p); + + if (!pr.query ().empty ()) + url += + string (p > 0 ? "&" : "?") + "q=" + mime_url_encode (pr.query ()); + + return url; + }); + + s << pager (pr.page (), pvc, rop, options_->pages_in_pager (), u) + << ~BODY << ~HTML; } } -- cgit v1.1