Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 404 lines (366 sloc) 15.189 kb
4d4d90b @hzeller o More legalese
authored
1 // Folve - A fuse filesystem that convolves audio files on-the-fly.
2 //
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
3 // Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
1bce634 @hzeller o Remove some trailing whitespaces
authored
4 //
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 #include <arpa/inet.h>
19 #include <fcntl.h>
036c6e1 @hzeller o not wide cellspacing needed anymore.
authored
20 #include <math.h>
b5c1e96 @hzeller o more useful output on status server.
authored
21 #include <stdio.h>
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
22 #include <stdlib.h>
1bce634 @hzeller o Remove some trailing whitespaces
authored
23 #include <string.h>
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
24 #include <sys/select.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28
1bce634 @hzeller o Remove some trailing whitespaces
authored
29 // Microhttpd's headers (at least v0.4.4) are broken and don't include stdarg.h
30 #include <stdarg.h>
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
31 #include <microhttpd.h>
32
b4eec5c @hzeller o libboost caused too many troubles in embedded systems with weak
authored
33 #include <algorithm>
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
34
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
35 #include "folve-filesystem.h"
c1a03f2 @hzeller o Needed convenient sub-second resolution time. Added CurrentTime()
authored
36 #include "status-server.h"
37 #include "util.h"
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
38
8268c37 @hzeller o Bubble up error messages in status server.
authored
39 using folve::Appendf;
40
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
41 // To be used in CSS constant.
42 #define PROGRESS_WIDTH "300"
b698853 @hzeller o README updates.
authored
43 static const int kProgressWidth = 300;
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
44
45 static const size_t kMaxRetired = 20;
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
46 static const char kActiveProgress[] = "#7070ff";
47 static const char kRetiredProgress[] = "#d0d0d0";
249865a @hzeller o Make debug mode switchable in UI.
authored
48 static const char kSettingsUrl[] = "/settings";
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
49
78e66dd @hzeller o I need to find my browser-tab :) Add favicon.
authored
50 // Aaah, I need to find the right Browser-Tab :)
51 // Sneak in a favicon without another resource access.
52 // TODO: make a nice icon, recognizable as something that has to do with "
53 // files and music ...
a372a03 @hzeller o Make meta-refresh configurable.
authored
54 static const char kStartHtmlHeader[] = "<html><head>"
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
55 "<title>Folve</title>\n"
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
56 "<link rel='icon' type='image/png' "
78e66dd @hzeller o I need to find my browser-tab :) Add favicon.
authored
57 "href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2"
58 "AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wJDwUlEA/UBrsA"
59 "AABSSURBVCjPrZIxDgAgDAKh8f9froOTirU1ssKFYqS7Q4mktAxFRQDJcsPORMDYsDCXhn331"
a372a03 @hzeller o Make meta-refresh configurable.
authored
60 "9GPwHJVuaFl3l4D1+h0UjIdbTh9SpP2KQ2AgSfVAdEQGx23tOopAAAAAElFTkSuQmCC'/>\n";
78e66dd @hzeller o I need to find my browser-tab :) Add favicon.
authored
61
adde81e @hzeller o some link prettify.
authored
62 // TODO: someone with a bit more stylesheet-fu can attempt to make this
63 // more pretty and the HTML more compact.
64 // Also, maybe move to external file, makes editing much faster, then compile
65 // that into a C-string that we can include it in the binary.
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
66 static const char kCSS[] =
adde81e @hzeller o some link prettify.
authored
67 "<style type='text/css'>"
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
68 " body { font-family:Sans-Serif; }\n"
adde81e @hzeller o some link prettify.
authored
69 " a:link { text-decoration:none; }\n"
70 " a:visited { text-decoration:none; }\n"
71 " a:hover { text-decoration:underline; }\n"
72 " a:active { text-decoration:underline; }\n"
23dc276 @hzeller o make switch-message ('affects new files') more prominent.
authored
73 " .rounded_box, .filter_sel {\n"
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
74 " float: left;\n"
75 " margin: 5px;\n"
76 " margin-right: 5px;\n"
77 " margin-bottom: 5px;\n"
23dc276 @hzeller o make switch-message ('affects new files') more prominent.
authored
78 " padding: 5px 15px;\n"
79 " border-radius: 5px;\n"
80 " -moz-border-radius: 5px; }\n"
81 " .filter_sel { font-weight:bold; }\n"
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
82 " .active { background-color:#a0a0ff; }\n"
adde81e @hzeller o some link prettify.
authored
83 " .inactive { background-color:#e0e0e0; }\n"
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
84 " .inactive:hover { background-color:#e0e0ff;\n"
adde81e @hzeller o some link prettify.
authored
85 " color: #000000;\n"
86 " text-decoration:none;}\n"
87 " .inactive:link { color: #000000;text-decoration:none;}\n"
88 " .inactive:visited { color: #000000;text-decoration:none;}\n"
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
89 // CSS classes used in the file-listin. Keep things compact.
90 " td { text-wrap:none; white-space:nowrap; }\n"
91 " .fn { font-size:small; text-wrap:none; white-space:nowrap; }\n" // filename
92 " .pf { width:" PROGRESS_WIDTH "px;\n" // progress-
93 " background: white; border:1px solid black; }\n" // frame
94 " .nf { text-align:right; }\n" // number formatting.
95 " .fb { background-color:#c0c0c0;"
96 " border-radius: 3px;\n"
97 " -moz-border-radius: 3px; }\n" // format box
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
98 "</style>";
99
b698853 @hzeller o README updates.
authored
100 // Callback function called by micro http daemon. Gets the StatusServer pointer
101 // in the user_argument.
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
102 int StatusServer::HandleHttp(void* user_argument,
103 struct MHD_Connection *connection,
104 const char *url, const char *method,
105 const char *version,
106 const char *upload_data, size_t *upload_size,
107 void**) {
108 StatusServer* server = (StatusServer*) user_argument;
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
109 struct MHD_Response *response;
110 int ret;
111
249865a @hzeller o Make debug mode switchable in UI.
authored
112 if (strcmp(url, kSettingsUrl) == 0) {
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
113 server->SetFilter(MHD_lookup_connection_value(connection,
114 MHD_GET_ARGUMENT_KIND, "f"));
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
115 // We redirect to slash after this, to remove parameters from the GET-URL
116 response = MHD_create_response_from_data(0, (void*)"", MHD_NO, MHD_NO);
117 MHD_add_response_header(response, "Location", "/");
1bce634 @hzeller o Remove some trailing whitespaces
authored
118 ret = MHD_queue_response(connection, 302, response);
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
119 } else {
120 const std::string &page = server->CreatePage();
121 response = MHD_create_response_from_data(page.length(), (void*) page.data(),
122 MHD_NO, MHD_NO);
123 MHD_add_response_header(response, "Content-Type",
124 "text/html; charset=utf-8");
125 ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
126 }
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
127 // Tell aggressive cachers not to do so.
128 MHD_add_response_header(response, "Cache-Control", "no-cache");
129 MHD_add_response_header(response, "Expires", "24 Nov 1972 23:42:42 GMT");
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
130 MHD_destroy_response(response);
131 return ret;
132 }
133
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
134 StatusServer::StatusServer(FolveFilesystem *fs)
5f9848b @hzeller o Get rid of marginally useful feature to show music seen/convolved.
authored
135 : expunged_retired_(0),
a372a03 @hzeller o Make meta-refresh configurable.
authored
136 meta_refresh_time_(-1),
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
137 filesystem_(fs), daemon_(NULL), filter_switched_(false) {
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
138 fs->handler_cache()->SetObserver(this);
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
139 }
140
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
141 void StatusServer::SetFilter(const char *filter) {
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
142 if (filter == NULL) return;
143 filter_switched_ = filesystem_->SwitchCurrentConfigDir(filter);
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
144 }
145
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
146 bool StatusServer::Start(int port) {
1bce634 @hzeller o Remove some trailing whitespaces
authored
147 daemon_ = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
148 &HandleHttp, this,
149 MHD_OPTION_END);
150 return daemon_ != NULL;
151 }
152
153 StatusServer::~StatusServer() {
b698853 @hzeller o README updates.
authored
154 if (daemon_) MHD_stop_daemon(daemon_);
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
155 }
156
20e139c @hzeller o Less cluttered output in UI if -D is not set.
authored
157 bool StatusServer::show_details() {
158 // Right now, we just make this dependent on debug output. Could be a separate
159 // option.
160 return folve::IsDebugLogEnabled();
161 }
162
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
163 // FileHandlerCache::Observer interface.
164 void StatusServer::RetireHandlerEvent(FileHandler *handler) {
165 HandlerStats stats;
166 handler->GetHandlerStatus(&stats); // Get last available stats.
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
167 stats.last_access = folve::CurrentTime();
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
168 stats.status = HandlerStats::RETIRED;
b4eec5c @hzeller o libboost caused too many troubles in embedded systems with weak
authored
169 folve::MutexLock l(&retired_mutex_);
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
170 retired_.push_front(stats);
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
171 while (retired_.size() > kMaxRetired) {
172 ++expunged_retired_;
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
173 retired_.pop_back();
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
174 }
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
175 }
1bce634 @hzeller o Remove some trailing whitespaces
authored
176
c277300 @hzeller o HTML sanitize printing of the filename as well. They often contain
authored
177 // The directories are user-input, so we need to sanitize stuff.
178 static void AppendSanitizedUrlParam(const std::string &in, std::string *out) {
179 for (std::string::const_iterator i = in.begin(); i != in.end(); ++i) {
180 if (isupper(*i) || islower(*i) || isdigit(*i)) {
181 out->append(1, *i);
182 } else {
183 Appendf(out, "%%%02x", (unsigned char) *i);
184 }
185 }
186 }
187
188 static void AppendSanitizedHTML(const std::string &in, std::string *out) {
189 for (std::string::const_iterator i = in.begin(); i != in.end(); ++i) {
190 switch (*i) {
191 case '<': out->append("&lt;"); break;
192 case '>': out->append("&gt;"); break;
193 case '&': out->append("&amp;"); break;
194 default: out->append(1, *i);
195 }
196 }
197 }
198
f1ef960 @hzeller o a bit HTML polishing.
authored
199 // As ugly #defines, so that gcc can warn about printf() format problems.
200 #define sMessageRowHtml \
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
201 "<td>%s</td><td colspan='3' style='font-size:small;'>%s</td>"
b5c1e96 @hzeller o more useful output on status server.
authored
202
f1ef960 @hzeller o a bit HTML polishing.
authored
203 #define sProgressRowHtml \
204 "<td>%s</td>" \
205 "<td>%s</td>" \
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
206 "<td><div class='pf'>" \
207 "<div style='width:%dpx;background:%s;'>&nbsp;</div>\n</div></td>" \
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
208 "<td>%s</td>"
f1ef960 @hzeller o a bit HTML polishing.
authored
209
210 #define sTimeColumns \
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
211 "<td class='nf'>%2d:%02d</td><td>/</td><td class='nf'>%2d:%02d</td>"
f1ef960 @hzeller o a bit HTML polishing.
authored
212 #define sDecibelColumn \
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
213 "<td class='nf'%s>%.1f dB</td>"
b5c1e96 @hzeller o more useful output on status server.
authored
214
118a454 @hzeller o Show the filter used for a particular format.
authored
215 void StatusServer::AppendFileInfo(const char *progress_style,
216 const HandlerStats &stats) {
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
217 content_.append("<tr>");
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
218 const char *status = "";
219 switch (stats.status) {
220 case HandlerStats::OPEN: status = "open"; break;
221 case HandlerStats::IDLE: status = "idle"; break;
bcb77e7 @hzeller o Ran with Amarok over my files. Looks like it sometimes only 'almost'
authored
222 case HandlerStats::RETIRED: status = "&nbsp;----&nbsp;"; break;
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
223 // no default to let the compiler detect new values.
224 }
f1ef960 @hzeller o a bit HTML polishing.
authored
225
8268c37 @hzeller o Bubble up error messages in status server.
authored
226 if (!stats.message.empty()) {
118a454 @hzeller o Show the filter used for a particular format.
authored
227 Appendf(&content_, sMessageRowHtml, status, stats.message.c_str());
8268c37 @hzeller o Bubble up error messages in status server.
authored
228 } else if (stats.progress == 0) {
118a454 @hzeller o Show the filter used for a particular format.
authored
229 Appendf(&content_, sMessageRowHtml, status, "Only header accessed");
b5c1e96 @hzeller o more useful output on status server.
authored
230 } else {
118a454 @hzeller o Show the filter used for a particular format.
authored
231 Appendf(&content_, sProgressRowHtml, status,
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
232 stats.in_gapless ? "&rarr;" : "",
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
233 (int) (kProgressWidth * stats.progress),
b9ae86d @hzeller o Higher than percent resolution progress bar.
authored
234 progress_style,
f1ef960 @hzeller o a bit HTML polishing.
authored
235 stats.out_gapless ? "&rarr;" : "");
236 }
237 const int secs = stats.duration_seconds;
238 const int fract_sec = stats.progress * secs;
6d4f28b @hzeller o if there is a time, show it.
authored
239 if (secs >= 0 && fract_sec >= 0) {
1bce634 @hzeller o Remove some trailing whitespaces
authored
240 Appendf(&content_, sTimeColumns,
f1ef960 @hzeller o a bit HTML polishing.
authored
241 fract_sec / 60, fract_sec % 60,
242 secs / 60, secs % 60);
243 } else {
118a454 @hzeller o Show the filter used for a particular format.
authored
244 content_.append("<td colspan='3'>-</td>");
b5c1e96 @hzeller o more useful output on status server.
authored
245 }
f00e6a4 @hzeller o Don't do unprotected read on status information such as
authored
246
036c6e1 @hzeller o not wide cellspacing needed anymore.
authored
247 if (stats.max_output_value > 1e-6) {
118a454 @hzeller o Show the filter used for a particular format.
authored
248 Appendf(&content_, sDecibelColumn,
218e0d1 @hzeller o make HTML a bit more compact and centralize most styles.
authored
249 stats.max_output_value > 1.0 ? " style='background:#FF8080;'" : "",
7b499ea @hzeller o Uh, log() is actually ln() and log10f() is log() :)
authored
250 20 * log10f(stats.max_output_value));
f1ef960 @hzeller o a bit HTML polishing.
authored
251 } else {
118a454 @hzeller o Show the filter used for a particular format.
authored
252 content_.append("<td>-</td>");
f1ef960 @hzeller o a bit HTML polishing.
authored
253 }
254
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
255 const char *filter_dir = stats.filter_dir.empty()
256 ? "Pass Through" : stats.filter_dir.c_str();
c277300 @hzeller o HTML sanitize printing of the filename as well. They often contain
authored
257 Appendf(&content_, "<td class='fb'>&nbsp;%s (", stats.format.c_str());
258 AppendSanitizedHTML(filter_dir, &content_);
259 content_.append(")&nbsp;</td><td class='fn'>");
260 AppendSanitizedHTML(stats.filename, &content_);
261 content_.append("</td></tr>\n");
f439f8d @hzeller o allow for non-ascii or space-containing directory names that
authored
262 }
263
264 static void CreateSelection(const std::set<std::string> &options,
265 const std::string &selected,
266 std::string *result) {
d280fce @hzeller o Reload page with a meta-refresn.
authored
267 if (options.size() == 1) {
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
268 result->append(selected);
d280fce @hzeller o Reload page with a meta-refresn.
authored
269 return;
270 }
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
271 typedef std::set<std::string> Set;
272 for (Set::const_iterator it = options.begin(); it != options.end(); ++it) {
273 const bool active = (*it == selected);
274 const char *title = it->empty() ? "None : Pass Through" : it->c_str();
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
275 if (active) {
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
276 result->append("<span class='filter_sel active'>");
277 AppendSanitizedHTML(title, result);
278 result->append("</span>");
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
279 } else {
f439f8d @hzeller o allow for non-ascii or space-containing directory names that
authored
280 Appendf(result, "<a class='filter_sel inactive' href='%s?f=",
281 kSettingsUrl);
282 AppendSanitizedUrlParam(*it, result);
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
283 result->append("'>");
284 AppendSanitizedHTML(title, result);
285 result->append("</a>\n");
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
286 }
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
287 }
d280fce @hzeller o Reload page with a meta-refresn.
authored
288 }
289
290 void StatusServer::AppendSettingsForm() {
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
291 content_.append("<p><span class='filter_sel'>Active filter:</span>");
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
292 std::set<std::string> available_dirs = filesystem_->GetAvailableConfigDirs();
f439f8d @hzeller o allow for non-ascii or space-containing directory names that
authored
293 CreateSelection(available_dirs,
294 filesystem_->current_config_subdir(),
295 &content_);
31096bb @hzeller o remove option -c and add -C: give a base directory for all filters.
authored
296 if (available_dirs.empty() == 1) {
297 content_.append(" (This is a boring configuration, add filter directories)");
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
298 } else if (filter_switched_) {
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
299 content_.append("<span class='rounded_box' "
23dc276 @hzeller o make switch-message ('affects new files') more prominent.
authored
300 "style='font-size:small;background:#FFFFa0;'>"
4c6565f @hzeller o don't put 'affects...' message in parenthesis.
authored
301 "Affects re- or newly opened files.</span>");
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
302 filter_switched_ = false; // only show once.
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
303 }
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
304 content_.append("</p><hr style='clear:both;'/>");
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
305 }
306
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
307 struct CompareStats {
b76ff19 @hzeller o ICE in 2.7.1; don't have the machine in front of me, but reported
authored
308 bool operator() (const HandlerStats *a, const HandlerStats *b) {
309 if (a->status < b->status) return true; // open before idle.
310 else if (a->status > b->status) return false;
311 return b->last_access < a->last_access; // reverse time.
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
312 }
313 };
314
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
315 const std::string &StatusServer::CreatePage() {
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
316 const double start = folve::CurrentTime();
b698853 @hzeller o README updates.
authored
317 // We re-use a string to avoid re-allocing memory every time we generate
318 // a page. Since we run with MHD_USE_SELECT_INTERNALLY, this is only accessed
319 // by one thread.
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
320 content_.clear();
a372a03 @hzeller o Make meta-refresh configurable.
authored
321 content_.append(kStartHtmlHeader);
322 if (meta_refresh_time_ > 0) {
323 Appendf(&content_, "<meta http-equiv='refresh' content='%d'>\n",
324 meta_refresh_time_);
325 }
537e34b @hzeller o cleanup UI: no radio buttons anymore, just simple links.
authored
326 content_.append(kCSS);
a372a03 @hzeller o Make meta-refresh configurable.
authored
327 content_.append("</head>\n");
328
60badba @hzeller o HTML escaping for directories with nasty names (<, >, &)
authored
329 content_.append("<body>\n");
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
330 Appendf(&content_, "<center style='background-color:#A0FFA0;'>"
53130a3 @hzeller o link to github page
authored
331 "Welcome to "
ee675fe @hzeller o Provide a way to select between different filter diretories.
authored
332 "<a href='https://github.com/hzeller/folve#readme'>Folve</a> "
20e139c @hzeller o Less cluttered output in UI if -D is not set.
authored
333 FOLVE_VERSION "</center>\n");
334 if (show_details()) {
e296ede @hzeller o Errmsg: print short name of filter.
authored
335 Appendf(&content_, "Convolving audio files from <code>%s</code>; "
336 "Filter base directory <code>%s</code>\n",
337 filesystem_->underlying_dir().c_str(),
338 filesystem_->base_config_dir().c_str());
20e139c @hzeller o Less cluttered output in UI if -D is not set.
authored
339 }
d280fce @hzeller o Reload page with a meta-refresn.
authored
340 AppendSettingsForm();
27c44cd @hzeller o Use fuse option handling to extract our flags and options.
authored
341
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
342 std::vector<HandlerStats> stat_list;
343 filesystem_->handler_cache()->GetStats(&stat_list);
344
20e139c @hzeller o Less cluttered output in UI if -D is not set.
authored
345 if (show_details()) {
1bce634 @hzeller o Remove some trailing whitespaces
authored
346 Appendf(&content_, "Total opening files <b>%d</b> "
347 ".. and re-opened from recency cache <b>%d</b><br/>",
348 filesystem_->total_file_openings(),
349 filesystem_->total_file_reopen());
350 }
bea11d6 @hzeller o Don't use snprintf, but use a new function Appendf() to assemble
authored
351
43bb82b @hzeller o Make gapless transfer legend a bit more compact (not separate line).
authored
352 Appendf(&content_, "<h3>Accessed Recently</h3>\n%zd in recency cache.\n",
bea11d6 @hzeller o Don't use snprintf, but use a new function Appendf() to assemble
authored
353 stat_list.size());
354
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
355 if (filesystem_->gapless_processing()) {
43bb82b @hzeller o Make gapless transfer legend a bit more compact (not separate line).
authored
356 content_.append("Gapless transfers indicated with '&rarr;'.\n");
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
357 }
036c6e1 @hzeller o not wide cellspacing needed anymore.
authored
358 content_.append("<table>\n");
08bbf28 @hzeller o First shot at gapless. Works pretty well for my test-case.
authored
359 Appendf(&content_, "<tr><th>Stat</th><td><!--gapless in--></td>"
360 "<th width='%dpx'>Progress</th>" // progress bar.
361 "<td><!-- gapless out --></td>"
43bb82b @hzeller o Make gapless transfer legend a bit more compact (not separate line).
authored
362 "<th>Pos</th><td></td><th>Len</th><th>Max&nbsp;out</th>"
363 "<th>Format&nbsp;(used&nbsp;filter)</th>"
b698853 @hzeller o README updates.
authored
364 "<th align='left'>File</th></tr>\n", kProgressWidth);
277930c @hzeller o update comment.
authored
365 // ICE in arm 2.7.1 compiler if we sort values. So sort pointers
366 // to the values instead.
b76ff19 @hzeller o ICE in 2.7.1; don't have the machine in front of me, but reported
authored
367 std::vector<HandlerStats *> stat_ptrs;
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
368 for (size_t i = 0; i < stat_list.size(); ++i) {
b76ff19 @hzeller o ICE in 2.7.1; don't have the machine in front of me, but reported
authored
369 stat_ptrs.push_back(&stat_list[i]);
370 }
371 CompareStats comparator;
372 std::sort(stat_ptrs.begin(), stat_ptrs.end(), comparator);
373 for (size_t i = 0; i < stat_ptrs.size(); ++i) {
374 AppendFileInfo(kActiveProgress, *stat_ptrs[i]);
b5c1e96 @hzeller o more useful output on status server.
authored
375 }
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
376 content_.append("</table><hr/>\n");
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
377
378 if (retired_.size() > 0) {
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
379 content_.append("<h3>Retired</h3>\n");
380 content_.append("<table>\n");
b4eec5c @hzeller o libboost caused too many troubles in embedded systems with weak
authored
381 folve::MutexLock l(&retired_mutex_);
1bce634 @hzeller o Remove some trailing whitespaces
authored
382 for (RetiredList::const_iterator it = retired_.begin();
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
383 it != retired_.end(); ++it) {
118a454 @hzeller o Show the filter used for a particular format.
authored
384 AppendFileInfo(kRetiredProgress, *it);
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
385 }
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
386 content_.append("</table>\n");
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
387 if (expunged_retired_ > 0) {
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
388 Appendf(&content_, "... (%d more)<p></p>", expunged_retired_);
1e9ff21 @hzeller o main: report if parameters are not directories.
authored
389 }
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
390 content_.append("<hr/>");
223f392 @hzeller o Have a separate HandlerStats object that contains relevant
authored
391 }
392
a9d3e53 @hzeller o Found a project name: "Folve". Some renamings because of that.
authored
393 const double duration = folve::CurrentTime() - start;
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
394 Appendf(&content_,
a451825 @hzeller o make page generation time less obtrusive.
authored
395 "<span style='float:left;font-size:x-small;'>%.2fms</span>"
75867a2 @hzeller o legalese: add COPYING, provide "Appropriate Legal Notices" and
authored
396 "<span style='float:right;font-size:x-small;'>"
397 "&copy; 2012 Henner Zeller"
398 " | Folve is free software and comes with no warranty. "
399 " | Conveyed under the terms of the "
400 "<a href='http://www.gnu.org/licenses/gpl.html'>GPLv3</a>.</span>"
e619ff2 @hzeller o Redirect to / after settings. That way, a reload won't change any
authored
401 "</body></html>\n", duration * 1000.0);
7d695c6 @hzeller o Rename current_page_ to content_ to be more generic.
authored
402 return content_;
8d1fbe7 @hzeller o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
authored
403 }
Something went wrong with that request. Please try again.