2 import std.stdio, std.path, std.process, std.file, std.array, std.string, std.algorithm, std.datetime, std.ascii;
8 void html(string s) { writeln(indent ~ s); }
9 void html_pop(string s) { indent = indent[0..max(0, $-4)]; html(s); }
10 void html_push(string s) { html(s); indent ~= " "; }
12 void write_link(string to, bool expand) {
13 bool isdir = dirExists(dweb_root ~ "/srv/" ~ to[url_root.length..$]);
14 string flair = nav_tree_chev? (expand? "» " : "› ") : "";
15 html_push("<li" ~ (expand? " class=\"thisPage\" " : "") ~ ">");
16 html("<a href=\"" ~ to ~ (isdir ? "/" : "") ~ "\">"
17 ~ flair ~ baseName(to) ~ (isdir ? "/" : "") ~ "</a>");
21 void nav_tree_r(string url, string cur_loc, string[] subdirs) {
22 string[] dirs = array(map!"a.name"(dirEntries(dweb_root ~ "/srv/" ~ cur_loc, SpanMode.shallow)));
24 if (dirs.length == 0) return;
25 bool inserted_ul = false;
28 foreach(string s; dirs) {
29 s= s[(dweb_root ~ "/srv/").length..$];
30 string name = stripExtension(baseName(s));
31 if (name.length == 0) continue; // e.g. ".md", should we do something else with these files?
32 if (name == "index") continue; // "index" will never appear in the nav_tree.
33 if (name[0] == '@') continue; // hidden file
34 if (!inserted_ul) { html_push("<ul>"); inserted_ul = true; }
35 bool expand = subdirs.length > 0 && name == subdirs[0];
36 write_link(url_root ~ stripExtension(s), expand);
38 if (expand && isDir(dweb_root ~ "/srv/" ~ s)) {
41 nav_tree_r(url, (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0], subdirs[1..$]);
45 next_loc = (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0];
50 if (inserted_ul) html_pop("</ul>");
51 if (next) nav_tree_r(url, next_loc, subdirs[1..$]);
54 void do_nav_tree(string url) {
55 html_push("<div id=\"" ~ (nav_tree_vert ? "" : "horiz-") ~ "side-bar\">");
56 nav_tree_r(url, "", cast(string[])array(pathSplitter(url)));
60 void not_found(string path) {
61 html("The page <code>" ~ path ~ "</code> does not exist. (404)");
65 html_push("<div id=\"header\">");
67 html_push("<div class=\"superHeader\">");
69 html_push("<div class=\"left\">");
72 html_push("<div class=\"right\">");
73 html("<a href=\"" ~ url_root ~ "changelog\">changelog</a>");
78 html_push("<div class=\"midHeader\">");
79 html_push("<h1 class=\"headerTitle\">");
80 html("<a href=\"" ~ url_root ~ "\">" ~ site_title ~ " <span id=\"headerSubTitle\">" ~ site_subtitle ~ "</span></a>");
84 html_push("<div class=\"subHeader\">");
91 bool dirExists(string path) { try { if (isDir(path)) return true; else return false; } catch (Exception e) { return false; } }
93 void do_content(string url) {
94 html_push("<div id=\"main-copy\"" ~ (nav_tree_vert? " class=\"main-copy-side-bar\"" : "") ~ ">");
95 // first, see if we have something that wants to handle url outright
96 foreach (string glob, string h; handlers) {
97 if (globMatch(url, glob)) {
98 html(shell(dweb_root ~ "/bin/" ~ h ~ " " ~ url));
103 // if that failed, see if we can handle the file
104 if (url == "" ? false : url[$-1] == '/') url ~= "index";
105 foreach (f; array(map!"a.name"(dirEntries(dirName(dweb_root ~ "/srv/" ~ url), SpanMode.shallow)))) {
106 if (isDir(f)) continue;
107 string name = baseName(f); name = name[0] == '@' ? name[1..$] : name;
108 if (stripExtension(name) == baseName(url)) {
109 foreach (string glob, string h; handlers) {
110 if (globMatch(name, glob)) {
111 html(shell(dweb_root ~ "/bin/" ~ h ~ " " ~ f));
118 if (baseName(url) != "index") not_found(url);
123 html_push("<div id=\"footer\">");
125 html_push("<div class=\"left\">");
126 html("<a href=\"" ~ url_root ~ "dweb\">Powered by dweb</a>");
129 html_push("<div class=\"right\">");
133 html_pop("</div>\n");
136 bool evil(string s) {
137 foreach(char c; s) if (!isAlphaNum(c) && c != '/' && c != '-' && c != '_') return true;
141 void main(string[] args) {
143 dweb_root = getcwd()[0..$-4]; // take out bin/
145 html("Content-type: text/html\n");
146 html("<!DOCTYPE html>");
147 html_push("<html>\n");
149 string url = getenv("SCRIPT_URL")[url_root.length..$];
150 if (evil(url)) { html ("bad url."); return; }
152 string pagename = baseName(url);
153 if (pagename.length != 0) pagename = " - " ~ pagename;
154 pagename = site_title ~ pagename;
157 html("<title>" ~ pagename ~ "</title>");
158 html("<link rel=\"stylesheet\" href=\"" ~ url_root ~ "pub/style/style.css\" type=\"text/css\" media=\"screen, handheld\" title=\"default\">");
159 html("<meta charset=\"UTF-8\">");
160 html("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
161 html_pop("</head>\n");
163 html_push("<body" ~ (page_container? " style=\"text-align: center\"" : "")~ ">");
164 if (page_container) html_push("<div id=\"container\">");
169 if (page_container) html_pop("</div>");
170 html_pop("</body>\n");