[mirrorbrain] please review r8334: improving HTML output of mod_mirrorbrain

From: Peter Pöml <peter_at_poeml.de>
Date: Wed, 22 Jan 2014 23:57:55 +0100
Hi,

I hope you'll like this change as much as I do: improved HTML output for
the "details" pages that mod_mirrorbrain generates. See attached mail
for details.

I committed this to trunk so it'll be released with 2.18.0. The change
implies that some of you guys will need to adjust your webdesign,
though. A little bit of public review can't harm I guess. So anyone with
an interest in web design please look at it!

See 
http://svn.mirrorbrain.org/viewvc/mirrorbrain?view=revision&revision=8334
http://svn.mirrorbrain.org/viewvc/mirrorbrain/trunk/mod_mirrorbrain/mod_mirrorbrain.c?r1=8334&r2=8333&pathrev=8334

Thanks, Nick, this is a wonderful addition!
Peter


attached mail follows:


Author: poeml
Date: Wed Jan 22 23:42:04 2014
New Revision: 8334

URL: http://svn.mirrorbrain.org/viewvc/mirrorbrain?rev=8334&view=rev
Log:
mod_mirrorbrain:
Apply patch from Nick Schermer improving HTML output for the details page.
See issue #123. 

Summary of changes (copied from issue #123):
- Use heads to create categories in the html (h2 for title, h3 for main groups,
  h4 for subs).
- Make a more complete "File information" group with a link for direct download
  (KDE has this, kinds nice if you style it to a button).
- Do not show Torrent information (torrent/magnet links and btih hash) if no
  MirrorBrainTorrentTrackerURL is set in the apache configuration.
- Add css classes and ids for webdesigners (divs around sections and some spans
  to markup the file info).
- Less invasive h2 header (only the name, not the full patch since it gets
  excessively long in some deep-tree situations).
- Drop the google map image, but only provide a link (50x50 is not showing any
  information imho). Did a bit of styling in the uri to make a bigger, nicer map.
- Fix incorrect html when no mirror is found.
- Move mirrorbrain powered-by link to bottom of the html.

Modified:
    trunk/mod_mirrorbrain/mod_mirrorbrain.c

Modified: trunk/mod_mirrorbrain/mod_mirrorbrain.c
URL: http://svn.mirrorbrain.org/viewvc/mirrorbrain/trunk/mod_mirrorbrain/mod_mirrorbrain.c?rev=8334&r1=8333&r2=8334&view=diff
==============================================================================
--- trunk/mod_mirrorbrain/mod_mirrorbrain.c	(original)
+++ trunk/mod_mirrorbrain/mod_mirrorbrain.c	Wed Jan 22 23:42:04 2014
_at_@ -2992,6 +2992,7 @@
             ap_rputs(DOCTYPE_XHTML_1_0T
                      "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
                      "<head>\n"
+                     "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
                      "  <title>Mirror List</title>\n", r);
             if (scfg->mirrorlist_stylesheet) {
                 ap_rprintf(r, "  <link type=\"text/css\" rel=\"stylesheet\" href=\"%s\" />\n",
_at_@ -3001,34 +3002,40 @@
         }
 
         ap_rputs("<div id=\"mirrorbrain-details\">\n", r);
-        ap_rprintf(r, "  <h2>Mirrors for <a href=\"http://%s%s\">http://%s%s</a></h2>\n" 
-                   "  <br/>\n", 
-                   r->hostname, r->uri, r->hostname, r->uri);
-
-        ap_rputs("  <address>Powered by <a href=\"http://mirrorbrain.org/\">MirrorBrain</a></address>\n", r);
+        ap_rprintf(r, "  <h2>Mirrors for <a href=\"http://%s%s\">%s</a></h2>\n", 
+                   r->hostname, r->uri, basename);
 
         /* Metadata */
-        ap_rputs("  <ul>\n", r);
+        ap_rputs("<div id=\"mirrorbrain-fileinfo\">\n"
+                 "<h3>File information</h3>\n"
+                 "<ul>\n", r);
         char buf[5];
-        ap_rprintf(r, "  <li>Size: %s (%s bytes)</li>\n", 
+        ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">Filename:</span> %s</li>\n", basename);
+        ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">Size:</span> %s (%s bytes)</li>\n", 
                    apr_strfsize(r->finfo.size, buf),
                    apr_off_t_toa(r->pool, r->finfo.size));
         time_str = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
         apr_rfc822_date(time_str, r->finfo.mtime);
-        ap_rprintf(r, "  <li>Last modified: %s (Unix time: %" APR_INT64_T_FMT ")</li>\n", time_str, apr_time_sec(r->finfo.mtime));
+        ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">Last modified:</span> "
+                      "%s (Unix time: %" APR_INT64_T_FMT ")</li>\n",
+                   time_str, apr_time_sec(r->finfo.mtime));
 
         if (hashbag != NULL) {
             if (hashbag->sha256hex)
-                ap_rprintf(r, "  <li><a href=\"http://%s%s.sha256\">SHA-256 Hash</a>: <tt>%s</tt> "
+                ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">"
+                              "<a href=\"http://%s%s.sha256\">SHA-256 Hash</a>:</span> <tt>%s</tt>"
                               "</li>\n", r->hostname, r->uri, hashbag->sha256hex);
             if (hashbag->sha1hex)
-                ap_rprintf(r, "  <li><a href=\"http://%s%s.sha1\">SHA-1 Hash</a>: <tt>%s</tt> "
+                ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">"
+                              "<a href=\"http://%s%s.sha1\">SHA-1 Hash</a>:</span> <tt>%s</tt>"
                               "</li>\n", r->hostname, r->uri, hashbag->sha1hex);
             if (hashbag->md5hex)
-                ap_rprintf(r, "  <li><a href=\"http://%s%s.md5\">MD5 Hash</a>: <tt>%s</tt> "
+                ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">"
+                              "<a href=\"http://%s%s.md5\">MD5 Hash</a>:</span> <tt>%s</tt>"
                               "</li>\n", r->hostname, r->uri, hashbag->md5hex);
-            if (hashbag->btihhex)
-                ap_rprintf(r, "  <li><a href=\"http://%s%s.btih\">BitTorrent Information Hash</a>: <tt>%s</tt> "
+            if (hashbag->btihhex && !apr_is_empty_array(scfg->tracker_urls))
+                ap_rprintf(r, "  <li><span class=\"mirrorbrain-label\">"
+                              "<a href=\"http://%s%s.btih\">BitTorrent Information Hash</a>:</span> <tt>%s</tt>"
                               "</li>\n", r->hostname, r->uri, hashbag->btihhex);
 
             if (hashbag->pgp) {
_at_@ -3038,36 +3045,61 @@
                               "</li>\n", r->hostname, r->uri);
             }
         }
-        ap_rputs("  </ul>\n", r);
-
+
+        /* Direct download link */
+        ap_rputs("</ul>\n", r);
+        ap_rprintf(r, "<p><a href=\"http://%s%s\" class=\"mirrorbrain-btn\">Download file from preferred mirror</a></p>\n", r->hostname, r->uri);
+        ap_rputs("</div>\n\n", r);
+
+        /* Metalink / P2P / zsync section */
+        ap_rputs("<div id=\"mirrorbrain-links\">\n"
+                 "<h3>Reliable downloads</h3>\n", r);
 
         /* Metalink info */
-        ap_rputs("  <br/>\n" 
-                 "  <blockquote>Metalinks for reliable downloads:\n"
-                 "  <br/>\n", r);
-        ap_rprintf(r, "  <a href=\"http://%s%s.meta4\">http://%s%s.meta4</a> (IETF Metalink)"
-                      "  <br/>\n", 
-                r->hostname, r->uri, r->hostname, r->uri);
-        ap_rprintf(r, "  <a href=\"http://%s%s.metalink\">http://%s%s.metalink</a> (old (v3) Metalink)"
-                      "  <br/>\n", 
-                r->hostname, r->uri, r->hostname, r->uri);
+        ap_rputs("<div class=\"mirrorbrain-links-grp\">\n"
+                 "<h4>Metalink</h4>\n"
+                 "<ul>\n", r);
+        ap_rprintf(r, "  <li><a href=\"http://%s%s.meta4\">http://%s%s.meta4</a> (IETF Metalink)</li>\n",
+                   r->hostname, r->uri, r->hostname, r->uri);
+        ap_rprintf(r, "  <li><a href=\"http://%s%s.metalink\">http://%s%s.metalink</a> (old (v3) Metalink)</li>\n", 
+                   r->hostname, r->uri, r->hostname, r->uri);
+        ap_rputs("</ul>\n" "</div>\n", r);
+
         if (hashbag) {
-            ap_rprintf(r, "  P2P Links:\n<br/>"
-                          "  <a href=\"http://%s%s.torrent\">http://%s%s.torrent</a> (BitTorrent)\n", 
-                          r->hostname, r->uri, r->hostname, r->uri);
-            ap_rprintf(r, "  <br/><a href=\"http://%s%s.magnet\">http://%s%s.magnet</a> (Magnet)\n", 
-                          r->hostname, r->uri, r->hostname, r->uri);
+            if (!apr_is_empty_array(scfg->tracker_urls)) {
+                /* Torrent downloads */
+                ap_rputs("<div class=\"mirrorbrain-links-grp\">\n"
+                         "<h4>P2P links</h4>\n"
+                         "<ul>\n", r);
+                ap_rprintf(r, "  <li><a href=\"http://%s%s.torrent\">http://%s%s.torrent</a> (BitTorrent)</li>\n", 
+                           r->hostname, r->uri, r->hostname, r->uri);
+                ap_rprintf(r, "  <li><a href=\"http://%s%s.magnet\">http://%s%s.magnet</a> (Magnet)</li>\n", 
+                           r->hostname, r->uri, r->hostname, r->uri);
+                ap_rputs("</ul>\n" "</div>\n", r);
+            }
+
             if (hashbag->sha1hex && (hashbag->zblocksize > 0) 
                     && hashbag->zhashlens && hashbag->zsumshex) {
-                ap_rprintf(r, "  <br/>zsync Link:\n<br/>"
-                              "  <a href=\"http://%s%s.zsync\">http://%s%s.zsync</a>\n", 
-                              r->hostname, r->uri, r->hostname, r->uri);
-            }
-        }
-        ap_rputs("  </blockquote>\n\n", r);
-
-
-        ap_rprintf(r, "  <p>List of best mirrors for IP address %s, located ", clientip);
+                /* zSync */
+                ap_rputs("<div class=\"mirrorbrain-links-grp\">\n"
+                         "<h4>Zsync links</h4>\n"
+                         "<ul>\n", r);
+                ap_rprintf(r, "  <li><a href=\"http://%s%s.zsync\">http://%s%s.zsync</a></li>\n", 
+                           r->hostname, r->uri, r->hostname, r->uri);
+                ap_rputs("</ul>\n" "</div>\n", r);
+            }
+        }
+
+        /* End of Reliable downloads section */
+        ap_rputs("</div>\n\n", r);
+
+        /* Mirrors */
+        ap_rputs("<div id=\"mirrorbrain-mirrors\">\n"
+                 "<h3>Mirrors</h3>\n"
+                 "<p>", r);
+
+        /* Nice string where the user is located */
+        ap_rprintf(r, "List of best mirrors for IP address %s, located ", clientip);
         if (lat != 0 && lng != 0) {
             ap_rprintf(r, "at %f,%f ", lat, lng);
         }
_at_@ -3077,138 +3109,142 @@
             ap_rputs("in an unknown country", r);
         }
         if (strcmp(prefix, "--") != 0) {
-            ap_rprintf(r, ", \n     network %s (autonomous system %s)", prefix, as);
-        }
-        ap_rputs(": ", r);
-
+            ap_rprintf(r, ", network %s (autonomous system %s)", prefix, as);
+        }
+        ap_rputs(".</p>\n\n", r);
+
+        /* Link to static map of user and mirror locations */
         if (lat != 0 && lng != 0) {
-            ap_rputs("&nbsp;", r);
             apr_array_header_t *topten = get_n_best_mirrors(r, 9, mirrors_same_prefix, mirrors_same_as, 
                                                              mirrors_same_country, mirrors_same_region, 
                                                              mirrors_elsewhere);
             mirrorp = (mirror_entry_t **)topten->elts;
-            ap_rprintf(r, "\n     <a href=\"http://maps.google.com/maps/api/staticmap?size=640x640"
-                          "&amp;maptype=terrain&amp;visible&amp;sensor=false&amp;markers=size:mid|color:red|%f,%f", lat, lng);
+            ap_rprintf(r, "<p><a href=\"http://maps.google.com/maps/api/staticmap?size=640x512&amp;center=0,0&amp;"
+                          "visual_refresh=true&amp;scale=2&amp;maptype=roadmap&amp;sensor=false&amp;markers=color:red|%f,%f", lat, lng);
             for (i = 0; i < topten->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "&amp;markers=size:normal|color:yellow|label:%d|%f,%f", i+1, mirror->lat, mirror->lng);
-            }
-            ap_rputs("\">\n     <img src=\"", r);
-            ap_rprintf(r, "http://maps.google.com/maps/api/staticmap?size=50x50"
-                          "&amp;maptype=terrain&amp;visible&amp;sensor=false&amp;markers=size:mid|color:red|%f,%f", lat, lng);
-            for (i = 0; i < topten->nelts; i++) {
-                mirror = mirrorp[i];
-                ap_rprintf(r, "&amp;markers=size:normal|color:yellow|label:%d|%f,%f", i+1, mirror->lat, mirror->lng);
-            }
-            ap_rputs("\" width=\"50\" height=\"50\" alt=\"map showing the closest mirrors\"/></a> ", r);
-        }
-        ap_rputs("</p>\n", r);
+                ap_rprintf(r, "&amp;markers=color:yellow|label:%d|%f,%f", i+1, mirror->lat, mirror->lng);
+            }
+            ap_rputs("\">Map showing the closest mirrors</a></p>\n\n", r);
+        }
 
         if ((mirror_cnt <= 0) || (!mirrors_same_prefix->nelts && !mirrors_same_as->nelts 
                                   && !mirrors_same_country->nelts && !mirrors_same_region->nelts 
                                   && !mirrors_elsewhere->nelts)) {
-            ap_rprintf(r, "  <p>I am very sorry, but no mirror was found. Feel free to download directly:<br/>\n");
-            ap_rprintf(r, "  <a href=\"http://%s%s\">http://%s%s</a> </p>\n",
+            ap_rputs("<div id=\"mirrorbrain-mirrors-none\">\n"
+                     "<h4>No mirror was found</h4>\n", r);
+            ap_rputs("<p>I am very sorry, but no mirror was found. Feel free to download directly:<br />\n", r);
+            ap_rprintf(r, "  <a href=\"http://%s%s\">http://%s%s</a></p>\n",
                        r->hostname, r->uri, r->hostname, r->uri);
-            ap_rputs("</body></html>\n", r);
+            ap_rputs("</div>\n" "</div>\n", r);
+            ap_rputs("<address>Powered by <a href=\"http://mirrorbrain.org/\">MirrorBrain</a></address>\n", r);
+            ap_rputs("</div><!-- mirrorbrain-details -->\n", r);
+            ap_rputs("</body>\n" "</html>\n", r);
             return OK;
         }
-
 
         /* prefix */
         if (!apr_is_empty_array(mirrors_same_prefix)) {
-            ap_rprintf(r, "\n  <h3>Found %d mirror%s directly nearby (within the same network prefix: %s :-)</h3>\n", 
+            ap_rprintf(r, "<div class=\"mirrorbrain-mirrors-grp\">\n"
+                          "<h4>Found %d mirror%s directly nearby (within the same network prefix: %s)</h4>\n"
+                          "<ul>\n",
                        mirrors_same_prefix->nelts, 
                        (mirrors_same_prefix->nelts == 1) ? "" : "s",
                        prefix);
-            ap_rputs("  <ul>\n", r);
             mirrorp = (mirror_entry_t **)mirrors_same_prefix->elts;
             for (i = 0; i < mirrors_same_prefix->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "    <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
+                ap_rprintf(r, "  <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
                         mirror->baseurl, filename, 
                         mirror->baseurl, filename, 
                         mirror->country_code,
                         mirror->score);
             }
-            ap_rputs("  </ul>\n", r);
+            ap_rputs("</ul>\n" "</div>\n\n", r);
         }
 
         /* AS */
         if (!apr_is_empty_array(mirrors_same_as)) {
-            ap_rprintf(r, "\n  <h3>Found %d mirror%s very close (within the same autonomous system (AS%s):</h3>\n", 
+            ap_rprintf(r, "<div class=\"mirrorbrain-mirrors-grp\">\n"
+                          "<h4>Found %d mirror%s very close (within the same autonomous system (AS%s)</h4>\n"
+                          "<ul>\n",
                        mirrors_same_as->nelts, 
                        (mirrors_same_as->nelts == 1) ? "" : "s",
                        as);
-            ap_rputs("  <ul>\n", r);
             mirrorp = (mirror_entry_t **)mirrors_same_as->elts;
             for (i = 0; i < mirrors_same_as->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "    <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
+                ap_rprintf(r, "  <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
                         mirror->baseurl, filename, 
                         mirror->baseurl, filename, 
                         mirror->country_code,
                         mirror->score);
             }
-            ap_rputs("  </ul>\n", r);
+            ap_rputs("</ul>\n" "</div>\n\n", r);
         }
 
         /* country */
         if (!apr_is_empty_array(mirrors_same_country)) {
-            ap_rprintf(r, "\n  <h3>Found %d mirror%s which handle this country (%s):</h3>\n", 
+            ap_rprintf(r, "<div class=\"mirrorbrain-mirrors-grp\">\n"
+                          "<h4>Found %d mirror%s which handle this country (%s)</h4>\n"
+                          "<ul>\n", 
                        mirrors_same_country->nelts, 
                        (mirrors_same_country->nelts == 1) ? "" : "s",
                        country_code);
-            ap_rputs("  <ul>\n", r);
             mirrorp = (mirror_entry_t **)mirrors_same_country->elts;
             for (i = 0; i < mirrors_same_country->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "    <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
+                ap_rprintf(r, " <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
                         mirror->baseurl, filename, 
                         mirror->baseurl, filename, 
                         mirror->country_code,
                         mirror->score);
             }
-            ap_rputs("  </ul>\n", r);
+            ap_rputs("</ul>\n" "</div>\n\n", r);
         }
 
         /* region */
         if (!apr_is_empty_array(mirrors_same_region)) {
-            ap_rprintf(r, "\n  <h3>Found %d mirror%s in other countries, but same continent (%s):</h3>\n", 
+            ap_rprintf(r, "<div class=\"mirrorbrain-mirrors-grp\">\n"
+                          "<h4>Found %d mirror%s in other countries, but same continent (%s)</h4>\n"
+                          "<ul>\n", 
                        mirrors_same_region->nelts,
                        (mirrors_same_region->nelts == 1) ? "" : "s",
                        continent_code);
-            ap_rputs("  <ul>\n", r);
             mirrorp = (mirror_entry_t **)mirrors_same_region->elts;
             for (i = 0; i < mirrors_same_region->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "    <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
+                ap_rprintf(r, "  <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
                         mirror->baseurl, filename, 
                         mirror->baseurl, filename, 
                         mirror->country_code,
                         mirror->score);
             }
-            ap_rputs("  </ul>\n", r);
+            ap_rputs("</ul>\n" "</div>\n\n", r);
         }
 
         /* elsewhere */
         if (!apr_is_empty_array(mirrors_elsewhere)) {
-            ap_rprintf(r, "\n   <h3>Found %d mirror%s in other parts of the world:</h3>\n", 
+            ap_rprintf(r, "<div class=\"mirrorbrain-mirrors-grp\">\n"
+                          "<h4>Found %d mirror%s in other parts of the world</h4>\n"
+                          "<ul>\n",
                        mirrors_elsewhere->nelts,
                        (mirrors_elsewhere->nelts == 1) ? "" : "s");
-            ap_rputs("  <ul>\n", r);
             mirrorp = (mirror_entry_t **)mirrors_elsewhere->elts;
             for (i = 0; i < mirrors_elsewhere->nelts; i++) {
                 mirror = mirrorp[i];
-                ap_rprintf(r, "    <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
+                ap_rprintf(r, "  <li><a href=\"%s%s\">%s%s</a> (%s, prio %d)</li>\n", 
                         mirror->baseurl, filename, 
                         mirror->baseurl, filename, 
                         mirror->country_code,
                         mirror->score);
             }
-            ap_rputs("  </ul>\n", r);
-        }
-        ap_rputs("</div> <!-- mirrorbrain-details -->\n", r);
+            ap_rputs("</ul>\n" "</div>\n\n", r);
+        }
+
+        ap_rputs("</div>\n"
+                 "<address>Powered by <a href=\"http://mirrorbrain.org/\">MirrorBrain</a></address>\n"
+                 "</div><!-- mirrorbrain-details -->\n", r);
 
         if (scfg->mirrorlist_footer) {
             /* send the configured custom footer */




_______________________________________________
mirrorbrain-commits mailing list
Archive: http://mirrorbrain.org/archive/mirrorbrain-commits/

Note: To remove yourself from this list, send a mail with the content
 	unsubscribe
to the address mirrorbrain-commits-request_at_mirrorbrain.org



_______________________________________________
mirrorbrain mailing list
Archive: http://mirrorbrain.org/archive/mirrorbrain/

Note: To remove yourself from this mailing list, send a mail with the content
 	unsubscribe
to the address mirrorbrain-request_at_mirrorbrain.org
Received on Wed Jan 22 2014 - 22:57:59 GMT

This archive was generated by hypermail 2.3.0 : Thu Jan 23 2014 - 20:47:04 GMT