aboutsummaryrefslogtreecommitdiff
path: root/brep
diff options
context:
space:
mode:
Diffstat (limited to 'brep')
-rw-r--r--brep/buildfile4
-rw-r--r--brep/options.cli4
-rw-r--r--brep/package-details.cxx5
-rw-r--r--brep/package-search.cxx6
-rw-r--r--brep/package-version-details.cxx7
-rw-r--r--brep/page22
-rw-r--r--brep/page.cxx65
-rw-r--r--brep/repository-details32
-rw-r--r--brep/repository-details.cxx96
-rw-r--r--brep/services.cxx7
10 files changed, 222 insertions, 26 deletions
diff --git a/brep/buildfile b/brep/buildfile
index 6676095..464118d 100644
--- a/brep/buildfile
+++ b/brep/buildfile
@@ -22,8 +22,8 @@ libso{brep}: cxx.export.poptions = -I$out_root -I$src_root
import libs += libstudxml%lib{studxml}
brep = cxx{diagnostics module services package-search package-details \
- package-version-details shared-database page types-parsers} \
- cli.cxx{options}
+ package-version-details repository-details shared-database page \
+ types-parsers} cli.cxx{options}
web = ../web/apache/cxx{request service} ../web/cxx{mime-url-encoding}
diff --git a/brep/options.cli b/brep/options.cli
index 6c3c7f1..77dc45a 100644
--- a/brep/options.cli
+++ b/brep/options.cli
@@ -43,6 +43,10 @@ namespace brep
std::uint16_t description-length = 400;
std::uint16_t changes-length = 800;
};
+
+ class repository_details: module, db
+ {
+ };
}
// Web module HTTP request parameters.
diff --git a/brep/package-details.cxx b/brep/package-details.cxx
index ef787b0..780d98a 100644
--- a/brep/package-details.cxx
+++ b/brep/package-details.cxx
@@ -61,7 +61,6 @@ namespace brep
void package_details::
handle (request& rq, response& rs)
{
- using namespace xml;
using namespace web;
using namespace web::xhtml;
@@ -108,7 +107,7 @@ namespace brep
return u;
});
- serializer s (rs.content (), name);
+ xml::serializer s (rs.content (), name);
const string& title (sq.empty () ? name : name + " " + sq);
static const path sp ("package-details.css");
@@ -219,7 +218,7 @@ namespace brep
//
// Hm, I am not so sure about this. Consider: stable/testing/unstable.
//
- s << TR_LOCATION (p->internal_repository.object_id ())
+ s << TR_LOCATION (p->internal_repository.object_id (), rt)
<< TR_DEPENDS (p->dependencies, rt)
<< TR_REQUIRES (p->requirements)
<< ~TBODY
diff --git a/brep/package-search.cxx b/brep/package-search.cxx
index b0352f3..1617e58 100644
--- a/brep/package-search.cxx
+++ b/brep/package-search.cxx
@@ -57,8 +57,6 @@ namespace brep
void package_search::
handle (request& rq, response& rs)
{
- using namespace xml;
- using namespace web;
using namespace web::xhtml;
MODULE_DIAG;
@@ -82,10 +80,10 @@ namespace brep
}
const string& sq (pr.query ()); // Search query.
- string qp (sq.empty () ? "" : "q=" + mime_url_encode (sq));
+ string qp (sq.empty () ? "" : "q=" + web::mime_url_encode (sq));
size_t pg (pr.page ());
- serializer s (rs.content (), "Packages");
+ xml::serializer s (rs.content (), "Packages");
const string& title (
sq.empty () ? s.output_name () : s.output_name () + " " + sq);
diff --git a/brep/package-version-details.cxx b/brep/package-version-details.cxx
index b8f30ff..d00c10a 100644
--- a/brep/package-version-details.cxx
+++ b/brep/package-version-details.cxx
@@ -46,7 +46,6 @@ namespace brep
void package_version_details::
handle (request& rq, response& rs)
{
- using namespace xml;
using namespace web;
using namespace web::xhtml;
@@ -99,7 +98,7 @@ namespace brep
return u;
});
- serializer s (rs.content (), name);
+ xml::serializer s (rs.content (), name);
static const path go ("go");
static const path sp ("package-version-details.css");
@@ -171,7 +170,7 @@ namespace brep
<< TR_PRIORITY (p->priority)
<< TR_LICENSES (p->license_alternatives)
- << TR_LOCATION (p->internal_repository.object_id ())
+ << TR_LOCATION (p->internal_repository.object_id (), rt)
<< TR_DOWNLOAD (du)
<< ~TBODY
<< ~TABLE
@@ -249,7 +248,7 @@ namespace brep
s << ' ' << A(HREF=u / path (p->version.string ())) << *dc << ~A;
}
else
- // Display the dependency as a plain text in no repository URL
+ // Display the dependency as a plain text if no repository URL
// available.
//
s << d;
diff --git a/brep/page b/brep/page
index c968389..0d0887f 100644
--- a/brep/page
+++ b/brep/page
@@ -22,8 +22,7 @@ namespace brep
class CSS_LINKS
{
public:
- CSS_LINKS (const path& p, const dir_path& r):
- path_ (p), root_ (r) {}
+ CSS_LINKS (const path& p, const dir_path& r): path_ (p), root_ (r) {}
void
operator() (xml::serializer& s) const;
@@ -263,13 +262,15 @@ namespace brep
class TR_LOCATION
{
public:
- TR_LOCATION (const std::string& l): location_ (l) {}
+ TR_LOCATION (const std::string& n, const dir_path& r)
+ : name_ (n), root_ (r) {}
void
operator() (xml::serializer& s) const;
private:
- const std::string& location_;
+ const std::string& name_;
+ const dir_path& root_;
};
// Generates package download URL element.
@@ -307,13 +308,13 @@ namespace brep
public:
// Genereate full description.
//
- P_DESCRIPTION (const std::string& d)
- : description_ (d), length_ (d.size ()), url_ (nullptr) {}
+ P_DESCRIPTION (const std::string& d, bool u = true)
+ : description_ (d), length_ (d.size ()), url_ (nullptr), unique_ (u) {}
// Genereate brief description.
//
P_DESCRIPTION (const std::string& d, size_t l, const std::string& u)
- : description_ (d), length_ (l), url_ (&u) {}
+ : description_ (d), length_ (l), url_ (&u), unique_ (false) {}
void
operator() (xml::serializer& s) const;
@@ -322,6 +323,7 @@ namespace brep
const std::string& description_;
std::size_t length_;
const std::string* url_; // Full page url.
+ bool unique_;
};
// Generates package description element.
@@ -369,6 +371,12 @@ namespace brep
std::size_t page_number_count_;
const std::string& url_;
};
+
+ // Convert the argument to a string representing the valid HTML 5 'id'
+ // attribute value.
+ //
+ std::string
+ id_attribute (const std::string& v);
}
#endif // BREP_PAGE
diff --git a/brep/page.cxx b/brep/page.cxx
index fbbcda8..5b650a3 100644
--- a/brep/page.cxx
+++ b/brep/page.cxx
@@ -5,10 +5,13 @@
#include <brep/page>
#include <set>
+#include <ios> // hex, uppercase, right
#include <string>
#include <memory> // shared_ptr
#include <cstddef> // size_t
#include <cassert>
+#include <sstream>
+#include <iomanip> // setw(), setfill()
#include <algorithm> // min()
#include <xml/serializer>
@@ -27,6 +30,7 @@ using namespace web::xhtml;
namespace brep
{
static const path go ("go");
+ static const path about ("about");
// CSS_LINKS
//
@@ -44,12 +48,10 @@ namespace brep
void DIV_HEADER::
operator() (serializer& s) const
{
- static const path a ("about");
-
s << DIV(ID="header")
<< DIV(ID="header-menu")
<< A(HREF=root_) << "packages" << ~A
- << A(HREF=root_ / a) << "about" << ~A
+ << A(HREF=root_ / about) << "about" << ~A
<< ~DIV
<< ~DIV;
}
@@ -305,7 +307,7 @@ namespace brep
else if (p->internal ())
s << A(HREF=root_ / go / path (en)) << n << ~A;
else
- // Display the dependency as a plain text in no repository URL
+ // Display the dependency as a plain text if no repository URL
// available.
//
s << n;
@@ -440,7 +442,16 @@ namespace brep
{
s << TR(CLASS="location")
<< TH << "location" << ~TH
- << TD << SPAN(CLASS="value") << location_ << ~SPAN << ~TD
+ << TD
+ << SPAN(CLASS="value")
+ << A
+ << HREF
+ << root_ / about << "#" << mime_url_encode (id_attribute (name_))
+ << ~HREF
+ << name_
+ << ~A
+ << ~SPAN
+ << ~TD
<< ~TR;
}
@@ -486,7 +497,10 @@ namespace brep
// Format the description into paragraphs, recognizing a blank line as
// paragraph separator, and replacing single newlines with a space.
//
- s << P(ID="description");
+ s << P;
+
+ if (unique_)
+ s << ID("description");
bool nl (false); // The previous character is '\n'.
for (const auto& c: d)
@@ -614,4 +628,43 @@ namespace brep
s << ~DIV;
}
}
+
+ // Convert the argument to a string conformant to the section
+ // "3.2.5.1 The id attribute" of the HTML 5 specification at
+ // http://www.w3.org/TR/html5/dom.html#the-id-attribute.
+ //
+ string
+ id_attribute (const string& v)
+ {
+ ostringstream o;
+ o << hex << uppercase << right << setfill ('0');
+
+ // Replace space characters (as specified at
+ // http://www.w3.org/TR/html5/infrastructure.html#space-character) with
+ // the respective escape sequences.
+ //
+ for (auto c: v)
+ {
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\f':
+ case '~':
+ {
+ // Intentionally use '~' as an escape character to leave it unescaped
+ // being a part of URL. For example
+ // http://cppget.org/about#cppget.org%2Fmath~20lab
+ //
+ o << "~" << setw (2) << static_cast<unsigned short> (c);
+ break;
+ }
+ default: o << c; break;
+ }
+ }
+
+ return o.str ();
+ }
}
diff --git a/brep/repository-details b/brep/repository-details
new file mode 100644
index 0000000..a3008dc
--- /dev/null
+++ b/brep/repository-details
@@ -0,0 +1,32 @@
+// file : brep/repository-details -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BREP_REPOSITORY_DETAILS
+#define BREP_REPOSITORY_DETAILS
+
+#include <memory> // shared_ptr
+
+#include <odb/forward.hxx> // database
+
+#include <brep/module>
+#include <brep/options>
+
+namespace brep
+{
+ class repository_details: public module
+ {
+ private:
+ virtual void
+ handle (request&, response&);
+
+ virtual void
+ init (cli::scanner&);
+
+ private:
+ std::shared_ptr<options::repository_details> options_;
+ std::shared_ptr<odb::core::database> db_;
+ };
+}
+
+#endif // BREP_REPOSITORY_DETAILS
diff --git a/brep/repository-details.cxx b/brep/repository-details.cxx
new file mode 100644
index 0000000..4302c15
--- /dev/null
+++ b/brep/repository-details.cxx
@@ -0,0 +1,96 @@
+// file : brep/repository-details.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <brep/repository-details>
+
+#include <string>
+#include <memory> // make_shared()
+
+#include <xml/serializer>
+
+#include <odb/database.hxx>
+#include <odb/transaction.hxx>
+
+#include <web/xhtml>
+#include <web/module>
+#include <web/mime-url-encoding>
+
+#include <brep/page>
+#include <brep/options>
+#include <brep/package>
+#include <brep/package-odb>
+#include <brep/shared-database>
+
+using namespace std;
+using namespace odb::core;
+
+namespace brep
+{
+ using namespace cli;
+
+ void repository_details::
+ init (scanner& s)
+ {
+ MODULE_DIAG;
+
+ options_ = make_shared<options::repository_details> (
+ s, unknown_mode::fail, unknown_mode::fail);
+
+ db_ = shared_database (options_->db_host (), options_->db_port ());
+ }
+
+ void repository_details::
+ handle (request&, response& rs)
+ {
+ using namespace web::xhtml;
+
+ MODULE_DIAG;
+
+ // The module options object is not changed after being created once per
+ // server process.
+ //
+ static const dir_path& rt (options_->root ());
+
+ xml::serializer s (rs.content (), "About");
+ const string& title (s.output_name ());
+ static const path sp ("repository-details.css");
+
+ s << HTML
+ << HEAD
+ << TITLE << title << ~TITLE
+ << CSS_LINKS (sp, rt)
+ << ~HEAD
+ << BODY
+ << DIV_HEADER (rt)
+ << DIV(ID="content");
+
+ transaction t (db_->begin ());
+
+ using query = query<repository>;
+ auto rp (db_->query<repository> (query::internal + "ORDER BY name"));
+
+ for (const auto& r: rp)
+ {
+ string id (id_attribute (r.name));
+ s << H1(ID=id)
+ << A(HREF="#" + web::mime_url_encode (id)) << r.name << ~A
+ << ~H1;
+
+ if (r.email)
+ s << A << HREF << "mailto:" << *r.email << ~HREF << *r.email << ~A;
+
+ if (r.summary)
+ s << H2 << *r.summary << ~H2;
+
+ if (r.description)
+ s << P_DESCRIPTION (*r.description, false);
+ }
+
+ t.commit ();
+
+ s << ~DIV
+ << ~BODY
+ << ~HTML;
+ }
+}
diff --git a/brep/services.cxx b/brep/services.cxx
index 9b7043c..e41d3f3 100644
--- a/brep/services.cxx
+++ b/brep/services.cxx
@@ -8,6 +8,7 @@
#include <brep/package-search>
#include <brep/package-details>
+#include <brep/repository-details>
#include <brep/package-version-details>
using namespace brep;
@@ -30,3 +31,9 @@ service AP_MODULE_DECLARE_DATA package_version_details_srv (
"package-version-details",
package_version_details_mod,
{"root", "db-host", "db-port", "conf"});
+
+static repository_details repository_details_mod;
+service AP_MODULE_DECLARE_DATA repository_details_srv (
+ "repository-details",
+ repository_details_mod,
+ {"root", "db-host", "db-port", "conf"});