Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 428 lines (391 sloc) 16.669 kb
4d4d90b3 »
2012-09-23 o More legalese
1 // Folve - A fuse filesystem that convolves audio files on-the-fly.
2 //
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
3 // Copyright (C) 2012 Henner Zeller <h.zeller@acm.org>
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
4 //
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
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>
036c6e1c »
2012-09-21 o not wide cellspacing needed anymore.
20 #include <math.h>
b5c1e960 »
2012-09-14 o more useful output on status server.
21 #include <stdio.h>
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
22 #include <stdlib.h>
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
23 #include <string.h>
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
24 #include <sys/select.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
29 // Microhttpd's headers (at least v0.4.4) are broken and don't include stdarg.h
30 #include <stdarg.h>
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
31 #include <microhttpd.h>
32
b4eec5c1 »
2012-09-29 o libboost caused too many troubles in embedded systems with weak
33 #include <algorithm>
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
34
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
35 #include "folve-filesystem.h"
c1a03f22 »
2012-09-14 o Needed convenient sub-second resolution time. Added CurrentTime()
36 #include "status-server.h"
37 #include "util.h"
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
38
8268c37e »
2012-09-15 o Bubble up error messages in status server.
39 using folve::Appendf;
40
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
41 // To be used in CSS constant.
42 #define PROGRESS_WIDTH "300"
b6988530 »
2012-09-15 o README updates.
43 static const int kProgressWidth = 300;
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
44
45 static const size_t kMaxRetired = 20;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
46 static const char kActiveProgress[] = "#7070ff";
47 static const char kRetiredProgress[] = "#d0d0d0";
249865ac »
2012-09-17 o Make debug mode switchable in UI.
48 static const char kSettingsUrl[] = "/settings";
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
49
78e66ddc »
2012-09-14 o I need to find my browser-tab :) Add favicon.
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 ...
a372a03d »
2012-09-22 o Make meta-refresh configurable.
54 static const char kStartHtmlHeader[] = "<html><head>"
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
55 "<title>Folve</title>\n"
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
56 "<link rel='icon' type='image/png' "
78e66ddc »
2012-09-14 o I need to find my browser-tab :) Add favicon.
57 "href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2"
58 "AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wJDwUlEA/UBrsA"
59 "AABSSURBVCjPrZIxDgAgDAKh8f9froOTirU1ssKFYqS7Q4mktAxFRQDJcsPORMDYsDCXhn331"
a372a03d »
2012-09-22 o Make meta-refresh configurable.
60 "9GPwHJVuaFl3l4D1+h0UjIdbTh9SpP2KQ2AgSfVAdEQGx23tOopAAAAAElFTkSuQmCC'/>\n";
78e66ddc »
2012-09-14 o I need to find my browser-tab :) Add favicon.
61
adde81e9 »
2012-09-23 o some link prettify.
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.
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
66 static const char kCSS[] =
adde81e9 »
2012-09-23 o some link prettify.
67 "<style type='text/css'>"
68 " a:link { text-decoration:none; }\n"
69 " a:visited { text-decoration:none; }\n"
70 " a:hover { text-decoration:underline; }\n"
71 " a:active { text-decoration:underline; }\n"
23dc2760 »
2012-09-24 o make switch-message ('affects new files') more prominent.
72 " .rounded_box, .filter_sel {\n"
73 " padding: 5px 15px;\n"
74 " border-radius: 5px;\n"
75 " -moz-border-radius: 5px; }\n"
76 " .filter_sel { font-weight:bold; }\n"
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
77 " .active { background-color:#a0a0ff; }\n"
adde81e9 »
2012-09-23 o some link prettify.
78 " .inactive { background-color:#e0e0e0; }\n"
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
79 " .inactive:hover { background-color:#e0e0ff;\n"
adde81e9 »
2012-09-23 o some link prettify.
80 " color: #000000;\n"
81 " text-decoration:none;}\n"
82 " .inactive:link { color: #000000;text-decoration:none;}\n"
83 " .inactive:visited { color: #000000;text-decoration:none;}\n"
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
84 // CSS classes used in the file-listin. Keep things compact.
85 " td { text-wrap:none; white-space:nowrap; }\n"
86 " .fn { font-size:small; text-wrap:none; white-space:nowrap; }\n" // filename
87 " .pf { width:" PROGRESS_WIDTH "px;\n" // progress-
88 " background: white; border:1px solid black; }\n" // frame
89 " .nf { text-align:right; }\n" // number formatting.
90 " .fb { background-color:#c0c0c0;"
91 " border-radius: 3px;\n"
92 " -moz-border-radius: 3px; }\n" // format box
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
93 "</style>";
94
b6988530 »
2012-09-15 o README updates.
95 // Callback function called by micro http daemon. Gets the StatusServer pointer
96 // in the user_argument.
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
97 int StatusServer::HandleHttp(void* user_argument,
98 struct MHD_Connection *connection,
99 const char *url, const char *method,
100 const char *version,
101 const char *upload_data, size_t *upload_size,
102 void**) {
103 StatusServer* server = (StatusServer*) user_argument;
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
104 struct MHD_Response *response;
105 int ret;
106
249865ac »
2012-09-17 o Make debug mode switchable in UI.
107 if (strcmp(url, kSettingsUrl) == 0) {
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
108 server->SetFilter(MHD_lookup_connection_value(connection,
109 MHD_GET_ARGUMENT_KIND, "f"));
249865ac »
2012-09-17 o Make debug mode switchable in UI.
110 server->SetDebug(MHD_lookup_connection_value(connection,
111 MHD_GET_ARGUMENT_KIND, "d"));
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
112 // We redirect to slash after this, to remove parameters from the GET-URL
113 response = MHD_create_response_from_data(0, (void*)"", MHD_NO, MHD_NO);
114 MHD_add_response_header(response, "Location", "/");
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
115 ret = MHD_queue_response(connection, 302, response);
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
116 } else {
117 const std::string &page = server->CreatePage();
118 response = MHD_create_response_from_data(page.length(), (void*) page.data(),
119 MHD_NO, MHD_NO);
120 MHD_add_response_header(response, "Content-Type",
121 "text/html; charset=utf-8");
122 ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
123 }
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
124 // Tell aggressive cachers not to do so.
125 MHD_add_response_header(response, "Cache-Control", "no-cache");
126 MHD_add_response_header(response, "Expires", "24 Nov 1972 23:42:42 GMT");
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
127 MHD_destroy_response(response);
128 return ret;
129 }
130
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
131 StatusServer::StatusServer(FolveFilesystem *fs)
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
132 : expunged_retired_(0), total_seconds_filtered_(0),
133 total_seconds_music_seen_(0),
a372a03d »
2012-09-22 o Make meta-refresh configurable.
134 meta_refresh_time_(-1),
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
135 filesystem_(fs), daemon_(NULL), filter_switched_(false) {
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
136 fs->handler_cache()->SetObserver(this);
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
137 }
138
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
139 void StatusServer::SetFilter(const char *filter) {
140 if (filter == NULL || *filter == '\0') return;
141 char *end;
142 int index = strtol(filter, &end, 10);
143 if (end == NULL || *end != '\0') return;
144 filter_switched_ = (index != filesystem_->current_cfg_index());
145 filesystem_->SwitchCurrentConfigIndex(index);
146 }
147
249865ac »
2012-09-17 o Make debug mode switchable in UI.
148 void StatusServer::SetDebug(const char *dbg) {
8c7e5c11 »
2012-09-18 o Only if -D is given, the debug toggle is active in the UI.
149 if (!filesystem_->is_debug_ui_enabled()) return;
7689c9a8 »
2012-09-22 o preparation to extract classes from folve-filesystem into their
150 folve::EnableDebugLog(dbg != NULL && *dbg == '1');
249865ac »
2012-09-17 o Make debug mode switchable in UI.
151 }
152
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
153 bool StatusServer::Start(int port) {
118a454a »
2012-09-22 o Show the filter used for a particular format.
154 PrepareConfigDirectoriesForUI();
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
155 daemon_ = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
156 &HandleHttp, this,
157 MHD_OPTION_END);
158 return daemon_ != NULL;
159 }
160
161 StatusServer::~StatusServer() {
b6988530 »
2012-09-15 o README updates.
162 if (daemon_) MHD_stop_daemon(daemon_);
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
163 }
164
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
165 bool StatusServer::show_details() {
166 // Right now, we just make this dependent on debug output. Could be a separate
167 // option.
168 return folve::IsDebugLogEnabled();
169 }
170
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
171 // FileHandlerCache::Observer interface.
172 void StatusServer::RetireHandlerEvent(FileHandler *handler) {
173 HandlerStats stats;
174 handler->GetHandlerStatus(&stats); // Get last available stats.
175 if (stats.progress >= 0) {
8268c37e »
2012-09-15 o Bubble up error messages in status server.
176 total_seconds_music_seen_ += stats.duration_seconds;
177 total_seconds_filtered_ += stats.duration_seconds * stats.progress;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
178 }
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
179 stats.last_access = folve::CurrentTime();
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
180 stats.status = HandlerStats::RETIRED;
b4eec5c1 »
2012-09-29 o libboost caused too many troubles in embedded systems with weak
181 folve::MutexLock l(&retired_mutex_);
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
182 retired_.push_front(stats);
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
183 while (retired_.size() > kMaxRetired) {
184 ++expunged_retired_;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
185 retired_.pop_back();
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
186 }
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
187 }
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
188
f1ef9608 »
2012-09-21 o a bit HTML polishing.
189 // As ugly #defines, so that gcc can warn about printf() format problems.
190 #define sMessageRowHtml \
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
191 "<td>%s</td><td colspan='3' style='font-size:small;'>%s</td>"
b5c1e960 »
2012-09-14 o more useful output on status server.
192
f1ef9608 »
2012-09-21 o a bit HTML polishing.
193 #define sProgressRowHtml \
194 "<td>%s</td>" \
195 "<td>%s</td>" \
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
196 "<td><div class='pf'>" \
197 "<div style='width:%dpx;background:%s;'>&nbsp;</div>\n</div></td>" \
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
198 "<td>%s</td>"
f1ef9608 »
2012-09-21 o a bit HTML polishing.
199
200 #define sTimeColumns \
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
201 "<td class='nf'>%2d:%02d</td><td>/</td><td class='nf'>%2d:%02d</td>"
f1ef9608 »
2012-09-21 o a bit HTML polishing.
202 #define sDecibelColumn \
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
203 "<td class='nf'%s>%.1f dB</td>"
b5c1e960 »
2012-09-14 o more useful output on status server.
204
118a454a »
2012-09-22 o Show the filter used for a particular format.
205 void StatusServer::AppendFileInfo(const char *progress_style,
206 const HandlerStats &stats) {
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
207 content_.append("<tr>");
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
208 const char *status = "";
209 switch (stats.status) {
210 case HandlerStats::OPEN: status = "open"; break;
211 case HandlerStats::IDLE: status = "idle"; break;
bcb77e7f »
2012-09-14 o Ran with Amarok over my files. Looks like it sometimes only 'almost'
212 case HandlerStats::RETIRED: status = "&nbsp;----&nbsp;"; break;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
213 // no default to let the compiler detect new values.
214 }
f1ef9608 »
2012-09-21 o a bit HTML polishing.
215
8268c37e »
2012-09-15 o Bubble up error messages in status server.
216 if (!stats.message.empty()) {
118a454a »
2012-09-22 o Show the filter used for a particular format.
217 Appendf(&content_, sMessageRowHtml, status, stats.message.c_str());
8268c37e »
2012-09-15 o Bubble up error messages in status server.
218 } else if (stats.progress == 0) {
118a454a »
2012-09-22 o Show the filter used for a particular format.
219 Appendf(&content_, sMessageRowHtml, status, "Only header accessed");
b5c1e960 »
2012-09-14 o more useful output on status server.
220 } else {
118a454a »
2012-09-22 o Show the filter used for a particular format.
221 Appendf(&content_, sProgressRowHtml, status,
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
222 stats.in_gapless ? "&rarr;" : "",
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
223 (int) (kProgressWidth * stats.progress),
b9ae86d9 »
2012-09-22 o Higher than percent resolution progress bar.
224 progress_style,
f1ef9608 »
2012-09-21 o a bit HTML polishing.
225 stats.out_gapless ? "&rarr;" : "");
226 }
227 const int secs = stats.duration_seconds;
228 const int fract_sec = stats.progress * secs;
6d4f28bc »
2012-09-21 o if there is a time, show it.
229 if (secs >= 0 && fract_sec >= 0) {
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
230 Appendf(&content_, sTimeColumns,
f1ef9608 »
2012-09-21 o a bit HTML polishing.
231 fract_sec / 60, fract_sec % 60,
232 secs / 60, secs % 60);
233 } else {
118a454a »
2012-09-22 o Show the filter used for a particular format.
234 content_.append("<td colspan='3'>-</td>");
b5c1e960 »
2012-09-14 o more useful output on status server.
235 }
f00e6a47 »
2012-09-22 o Don't do unprotected read on status information such as
236
036c6e1c »
2012-09-21 o not wide cellspacing needed anymore.
237 if (stats.max_output_value > 1e-6) {
118a454a »
2012-09-22 o Show the filter used for a particular format.
238 Appendf(&content_, sDecibelColumn,
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
239 stats.max_output_value > 1.0 ? " style='background:#FF8080;'" : "",
7b499ea6 »
2012-09-22 o Uh, log() is actually ln() and log10f() is log() :)
240 20 * log10f(stats.max_output_value));
f1ef9608 »
2012-09-21 o a bit HTML polishing.
241 } else {
118a454a »
2012-09-22 o Show the filter used for a particular format.
242 content_.append("<td>-</td>");
f1ef9608 »
2012-09-21 o a bit HTML polishing.
243 }
244
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
245 Appendf(&content_, "<td class='fb'>&nbsp;%s (%s)&nbsp;</td>",
118a454a »
2012-09-22 o Show the filter used for a particular format.
246 stats.format.c_str(), ui_config_directories_[stats.filter_id].c_str());
218e0d1f »
2012-09-25 o make HTML a bit more compact and centralize most styles.
247 Appendf(&content_,"<td class='fn'>%s</td>", stats.filename.c_str());
118a454a »
2012-09-22 o Show the filter used for a particular format.
248 content_.append("</tr>\n");
b5c1e960 »
2012-09-14 o more useful output on status server.
249 }
250
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
251 void StatusServer::PrepareConfigDirectoriesForUI() {
252 // Essentially only keep the directory name.
253 if (!ui_config_directories_.empty()) return;
118a454a »
2012-09-22 o Show the filter used for a particular format.
254 ui_config_directories_.push_back("None : Pass Through");
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
255 for (size_t i = 1; i < filesystem_->config_dirs().size(); ++i) {
256 std::string d = filesystem_->config_dirs()[i];
257 while (d.length() > 0 && d[d.length() - 1] == '/') {
258 d.resize(d.length() - 1); // trim trailing slashes.
259 }
260 const std::string::size_type slash_pos = d.find_last_of('/');
261 if (slash_pos != std::string::npos) {
262 d = d.substr(slash_pos + 1);
263 }
264 ui_config_directories_.push_back(d);
265 }
266 }
267
268 static void CreateSelection(std::string *result,
3dc037e8 »
2012-09-24 o Provide tooltip to full path of filter.
269 const std::vector<std::string> &option_titles,
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
270 const std::vector<std::string> &options,
271 int selected) {
272 if (options.size() == 1) {
273 result->append(options[0]); // no reason to make this a form :)
274 return;
275 }
276 for (size_t i = 0; i < options.size(); ++i) {
277 const std::string &c = options[i];
adde81e9 »
2012-09-23 o some link prettify.
278 result->append("&nbsp;");
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
279 const bool active = (int) i == selected;
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
280 if (active) {
3dc037e8 »
2012-09-24 o Provide tooltip to full path of filter.
281 Appendf(result, "<span title='%s' class='filter_sel active'>%s</span>\n",
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
282 (option_titles.size() > i) ? option_titles[i].c_str() : "",
283 c.c_str());
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
284 } else {
3dc037e8 »
2012-09-24 o Provide tooltip to full path of filter.
285 Appendf(result, "<a title='%s' class='filter_sel inactive' "
286 "href='%s?f=%zd'>%s</a>\n",
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
287 (option_titles.size() > i) ? option_titles[i].c_str() : "",
288 kSettingsUrl, i, c.c_str());
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
289 }
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
290 }
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
291 }
292
293 void StatusServer::AppendSettingsForm() {
a3907456 »
2012-09-23 o rename 'config directory' to 'active filter' in the UI. Easier
294 content_.append("<p>Active filter: ");
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
295 CreateSelection(&content_,
296 show_details()
297 ? filesystem_->config_dirs()
298 : std::vector<std::string>(),
299 ui_config_directories_,
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
300 filesystem_->current_cfg_index());
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
301 if (filesystem_->config_dirs().size() == 1) {
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
302 content_.append(" (This is a boring configuration, add filter directories "
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
303 "with -c &lt;dir&gt; [-c &lt;another-dir&gt; ...] :-) )");
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
304 } else if (filter_switched_) {
23dc2760 »
2012-09-24 o make switch-message ('affects new files') more prominent.
305 content_.append("&nbsp;<span class='rounded_box' "
306 "style='font-size:small;background:#FFFFa0;'>"
4c6565f6 »
2012-09-24 o don't put 'affects...' message in parenthesis.
307 "Affects re- or newly opened files.</span>");
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
308 filter_switched_ = false; // only show once.
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
309 }
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
310 // TODO: re-add something for filesystem_->is_debug_ui_enabled()
adde81e9 »
2012-09-23 o some link prettify.
311 content_.append("</p><hr/>");
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
312 }
313
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
314 struct CompareStats {
b76ff197 »
2012-09-29 o ICE in 2.7.1; don't have the machine in front of me, but reported
315 bool operator() (const HandlerStats *a, const HandlerStats *b) {
316 if (a->status < b->status) return true; // open before idle.
317 else if (a->status > b->status) return false;
318 return b->last_access < a->last_access; // reverse time.
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
319 }
320 };
321
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
322 const std::string &StatusServer::CreatePage() {
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
323 const double start = folve::CurrentTime();
b6988530 »
2012-09-15 o README updates.
324 // We re-use a string to avoid re-allocing memory every time we generate
325 // a page. Since we run with MHD_USE_SELECT_INTERNALLY, this is only accessed
326 // by one thread.
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
327 content_.clear();
a372a03d »
2012-09-22 o Make meta-refresh configurable.
328 content_.append(kStartHtmlHeader);
329 if (meta_refresh_time_ > 0) {
330 Appendf(&content_, "<meta http-equiv='refresh' content='%d'>\n",
331 meta_refresh_time_);
332 }
537e34b8 »
2012-09-23 o cleanup UI: no radio buttons anymore, just simple links.
333 content_.append(kCSS);
a372a03d »
2012-09-22 o Make meta-refresh configurable.
334 content_.append("</head>\n");
335
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
336 content_.append("<body style='font-family:Sans-Serif;'>\n");
337 Appendf(&content_, "<center style='background-color:#A0FFA0;'>"
53130a38 »
2012-09-16 o link to github page
338 "Welcome to "
ee675fea »
2012-09-17 o Provide a way to select between different filter diretories.
339 "<a href='https://github.com/hzeller/folve#readme'>Folve</a> "
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
340 FOLVE_VERSION "</center>\n");
341 if (show_details()) {
342 Appendf(&content_, "Convolving audio files from <code>%s</code>\n",
343 filesystem_->underlying_dir().c_str());
344 }
d280fcec »
2012-09-22 o Reload page with a meta-refresn.
345 AppendSettingsForm();
27c44cd1 »
2012-09-17 o Use fuse option handling to extract our flags and options.
346
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
347 std::vector<HandlerStats> stat_list;
348 filesystem_->handler_cache()->GetStats(&stat_list);
349
562b4936 »
2012-09-15 o Print out config file name while spotting a problem
350 // Get statistics of active files to add to the existing ones.
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
351 double active_music_seen = 0.0;
352 double active_filtered = 0.0;
353 for (size_t i = 0; i < stat_list.size(); ++i) {
354 const HandlerStats &stats = stat_list[i];
355 if (stats.progress >= 0) {
8268c37e »
2012-09-15 o Bubble up error messages in status server.
356 active_music_seen += stats.duration_seconds;
357 active_filtered += stats.duration_seconds * stats.progress;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
358 }
359 }
20e139ca »
2012-09-24 o Less cluttered output in UI if -D is not set.
360 if (show_details()) {
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
361 const int t_seen = total_seconds_music_seen_ + active_music_seen;
362 const int t_filtered = total_seconds_filtered_ + active_filtered;
363 Appendf(&content_, "Total opening files <b>%d</b> "
364 ".. and re-opened from recency cache <b>%d</b><br/>",
365 filesystem_->total_file_openings(),
366 filesystem_->total_file_reopen());
367 Appendf(&content_, "Total music seen <b>%dd %d:%02d:%02d</b> ",
368 t_seen / 86400, (t_seen % 86400) / 3600,
369 (t_seen % 3600) / 60, t_seen % 60);
370 Appendf(&content_, ".. and convolved <b>%dd %d:%02d:%02d</b> ",
371 t_filtered / 86400, (t_filtered % 86400) / 3600,
372 (t_filtered % 3600) / 60, t_filtered % 60);
373 Appendf(&content_, "(%.1f%%)<br/>",
374 (t_seen == 0) ? 0.0 : (100.0 * t_filtered / t_seen));
375 }
bea11d6b »
2012-09-15 o Don't use snprintf, but use a new function Appendf() to assemble
376
43bb82bb »
2012-09-25 o Make gapless transfer legend a bit more compact (not separate line).
377 Appendf(&content_, "<h3>Accessed Recently</h3>\n%zd in recency cache.\n",
bea11d6b »
2012-09-15 o Don't use snprintf, but use a new function Appendf() to assemble
378 stat_list.size());
379
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
380 if (filesystem_->gapless_processing()) {
43bb82bb »
2012-09-25 o Make gapless transfer legend a bit more compact (not separate line).
381 content_.append("Gapless transfers indicated with '&rarr;'.\n");
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
382 }
036c6e1c »
2012-09-21 o not wide cellspacing needed anymore.
383 content_.append("<table>\n");
08bbf282 »
2012-09-21 o First shot at gapless. Works pretty well for my test-case.
384 Appendf(&content_, "<tr><th>Stat</th><td><!--gapless in--></td>"
385 "<th width='%dpx'>Progress</th>" // progress bar.
386 "<td><!-- gapless out --></td>"
43bb82bb »
2012-09-25 o Make gapless transfer legend a bit more compact (not separate line).
387 "<th>Pos</th><td></td><th>Len</th><th>Max&nbsp;out</th>"
388 "<th>Format&nbsp;(used&nbsp;filter)</th>"
b6988530 »
2012-09-15 o README updates.
389 "<th align='left'>File</th></tr>\n", kProgressWidth);
277930c3 »
2012-09-29 o update comment.
390 // ICE in arm 2.7.1 compiler if we sort values. So sort pointers
391 // to the values instead.
b76ff197 »
2012-09-29 o ICE in 2.7.1; don't have the machine in front of me, but reported
392 std::vector<HandlerStats *> stat_ptrs;
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
393 for (size_t i = 0; i < stat_list.size(); ++i) {
b76ff197 »
2012-09-29 o ICE in 2.7.1; don't have the machine in front of me, but reported
394 stat_ptrs.push_back(&stat_list[i]);
395 }
396 CompareStats comparator;
397 std::sort(stat_ptrs.begin(), stat_ptrs.end(), comparator);
398 for (size_t i = 0; i < stat_ptrs.size(); ++i) {
399 AppendFileInfo(kActiveProgress, *stat_ptrs[i]);
b5c1e960 »
2012-09-14 o more useful output on status server.
400 }
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
401 content_.append("</table><hr/>\n");
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
402
403 if (retired_.size() > 0) {
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
404 content_.append("<h3>Retired</h3>\n");
405 content_.append("<table>\n");
b4eec5c1 »
2012-09-29 o libboost caused too many troubles in embedded systems with weak
406 folve::MutexLock l(&retired_mutex_);
1bce6345 »
2012-09-24 o Remove some trailing whitespaces
407 for (RetiredList::const_iterator it = retired_.begin();
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
408 it != retired_.end(); ++it) {
118a454a »
2012-09-22 o Show the filter used for a particular format.
409 AppendFileInfo(kRetiredProgress, *it);
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
410 }
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
411 content_.append("</table>\n");
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
412 if (expunged_retired_ > 0) {
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
413 Appendf(&content_, "... (%d more)<p></p>", expunged_retired_);
1e9ff217 »
2012-09-15 o main: report if parameters are not directories.
414 }
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
415 content_.append("<hr/>");
223f392f »
2012-09-14 o Have a separate HandlerStats object that contains relevant
416 }
417
a9d3e538 »
2012-09-15 o Found a project name: "Folve". Some renamings because of that.
418 const double duration = folve::CurrentTime() - start;
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
419 Appendf(&content_,
a4518251 »
2012-09-24 o make page generation time less obtrusive.
420 "<span style='float:left;font-size:x-small;'>%.2fms</span>"
75867a23 »
2012-09-23 o legalese: add COPYING, provide "Appropriate Legal Notices" and
421 "<span style='float:right;font-size:x-small;'>"
422 "&copy; 2012 Henner Zeller"
423 " | Folve is free software and comes with no warranty. "
424 " | Conveyed under the terms of the "
425 "<a href='http://www.gnu.org/licenses/gpl.html'>GPLv3</a>.</span>"
e619ff21 »
2012-09-21 o Redirect to / after settings. That way, a reload won't change any
426 "</body></html>\n", duration * 1000.0);
7d695c60 »
2012-09-18 o Rename current_page_ to content_ to be more generic.
427 return content_;
8d1fbe7c »
2012-09-13 o Move fuse-convolve.c to fuse-convolve.cc. Make filter-interface
428 }
Something went wrong with that request. Please try again.