page_reply.cpp

00001
00002 /***************************************************************************
00003  *  page_reply.h - Web request reply for a normal page
00004  *
00005  *  Created: Thu Oct 23 16:13:48 2008
00006  *  Copyright  2006-2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include "page_reply.h"
00024 #include <utils/system/hostinfo.h>
00025 #include <utils/misc/string_conversions.h>
00026
00027 #include <cstdlib>
00028 #include <cstring>
00029 #include <cstdio>
00030 
00031 /** @class WebPageReply "page_reply.h"
00032  * Basic page reply.
00033  * This reply adds header and footer as appropriate to form a HTML document
00034  * with logo and navigation.
00035  * @author Tim Niemueller
00036  */
00037 
00038 /** Page header template. */
00039 const char *  WebPageReply::PAGE_HEADER =
00040   "<html>\n"
00041   " <head>\n"
00042   "  <title>%s (%s)</title>\n"
00043   "  <link rel=\"stylesheet\" type=\"text/css\" href=\"/static/webview.css\" />\n"
00044   " </head>\n"
00045   " <body>\n"
00046   "  <div id=\"header\">"
00047   "<a id=\"logo\" href=\"/\"/><img src=\"/static/webview.png\" alt=\"Fawkes WebView\"/></a>"
00048   "<hr /></div>\n";
00049 
00050 /** Page footer template. */
00051 const char *  WebPageReply::PAGE_FOOTER =
00052   "\n </body>\n"
00053   "</html>\n";
00054
00055 std::map<std::string, std::string> WebPageReply::__nav_entries;
00056 std::string WebPageReply::__current_baseurl = "";
00057 WebviewServiceBrowseHandler * WebPageReply::__service_browser = NULL;
00058 
00059 /** Constructor.
00060  * @param title title of the page
00061  * @param body Optional initial body of the page
00062  */
00063 WebPageReply::WebPageReply(std::string title, std::string body)
00064   : StaticWebReply(WebReply::HTTP_OK, body)
00065 {
00066   _title = title;
00067 }
00068
00069 
00070 /** Base constructor.
00071  * Constructor that does not set a title or anything. Use for sub-classes.
00072  * @param code HTTP code for this reply
00073  */
00074 WebPageReply::WebPageReply(response_code_t code)
00075   : StaticWebReply(code)
00076 {
00077 }
00078
00079
00080 void
00081 WebPageReply::pack()
00082 {
00083   __merged_body  = html_header(_title) + _body + html_footer();
00084 }
00085
00086 std::string::size_type
00087 WebPageReply::body_length()
00088 {
00089   return __merged_body.length();
00090 }
00091
00092
00093 const std::string &
00094 WebPageReply::body()
00095 {
00096   return __merged_body;
00097 }
00098
00099 
00100 /** Generate HTML header.
00101  * Generate basic HTML header for the body and generate the navigation in
00102  * the page header.
00103  * @param title title of the page
00104  * @return generated header
00105  */
00106 std::string
00107 WebPageReply::html_header(std::string &title)
00108 {
00109   fawkes::HostInfo hi;
00110
00111   std::string rv = "";
00112   char *s;
00113   if ( asprintf(&s, PAGE_HEADER, title.c_str(), hi.short_name()) != -1 ) {
00114     rv = s;
00115     free(s);
00116   }
00117
00118   rv += "  <div id=\"mainnav\" class=\"nav\"><ul>";
00119   std::map<std::string, std::string>::iterator nei;
00120   for (nei = __nav_entries.begin(); nei != __nav_entries.end(); ++nei) {
00121     rv += "<li";
00122     if ( nei->first == __current_baseurl ) {
00123       rv += " class=\"active\"";
00124     }
00125     rv += "><a href=\"" + nei->first + "\">" + nei->second + "</a></li>";
00126   }
00127   rv += "</ul></div>";
00128
00129   return rv;
00130 }
00131
00132 
00133 /** Generate HTML footer.
00134  * Generate basic HTML footer and possibly additional footer content.
00135  * @return generated footer
00136  */
00137 std::string
00138 WebPageReply::html_footer()
00139 {
00140   std::string f = std::string("\n  <div id=\"footer\">\n")
00141     + "    <hr />\n";
00142   WebviewServiceBrowseHandler::ServiceList sl = __service_browser->service_list();
00143   if (! sl.empty()) {
00144     f += "    <div class=\"instances\"><ul>";
00145     WebviewServiceBrowseHandler::ServiceList &sl = __service_browser->service_list();
00146     WebviewServiceBrowseHandler::ServiceList::iterator i;
00147     for (i = sl.begin(); i != sl.end(); ++i) {
00148       std::string short_host = i->second->host();
00149       std::string::size_type s = short_host.find(".");
00150       if (s != std::string::npos)  short_host = short_host.substr(0, s);
00151
00152       f += std::string("<li><a href=\"http://") + i->second->host() + ":"
00153         + fawkes::StringConversions::to_string(i->second->port()) + "/\""
00154         + " title=\"" + i->first + "\">"
00155         + short_host + "</a></li>";
00156     }
00157     f += "</ul></div>\n";
00158   }
00159   f += "  </div>";
00160
00161   return f;
00162 }
00163
00164 
00165 /** Add navigation entry.
00166  * @param baseurl baseurl that should be linked for this entry
00167  * @param name string to print as link name
00168  */
00169 void
00170 WebPageReply::add_nav_entry(std::string baseurl, std::string name)
00171 {
00172   __nav_entries[baseurl] = name;
00173 }
00174
00175 
00176 /** Remove navigation entry.
00177  * @param baseurl baseurl whose config entry to remove
00178  */
00179 void
00180 WebPageReply::remove_nav_entry(std::string baseurl)
00181 {
00182   __nav_entries.erase(baseurl);
00183 }
00184
00185 
00186 /** Set current active baseurl.
00187  * @param baseurl new currently active baseurl
00188  */
00189 void
00190 WebPageReply::set_active_baseurl(std::string baseurl)
00191 {
00192   __current_baseurl = baseurl;
00193 }
00194
00195 
00196 /** Set service browser.
00197  * The service browser is queried to show a list of other hosts in the footer.
00198  */
00199 void
00200 WebPageReply::set_service_browse_handler(WebviewServiceBrowseHandler *service_browser)
00201 {
00202   __service_browser = service_browser;
00203 }