commit 61acbd558cb8336f44c43ed9478023b247e26bb6 from: Omar Polo date: Sun Sep 03 18:58:26 2023 UTC msearchd: show excerpt of search results Since it works by mean of snippet() I don't have any clear idea of where sqlite added the tag and where/if that tag was part of the email' text; here's why clt_putmatch is a bit paranoic. commit - bfea7cffba681b0c8b49194f37e4bc59f584b179 commit + 61acbd558cb8336f44c43ed9478023b247e26bb6 blob - 6389a88ec1ab83623efd4b625340b0837fbb7b2b blob + c96d03f9df0062274eb70d38ab16e54190344639 --- msearchd/fcgi.c +++ msearchd/fcgi.c @@ -696,7 +696,56 @@ clt_putsan(struct client *clt, const char *s) break; case '>': r = clt_puts(clt, ">"); + break; + case '&': + r = clt_puts(clt, "&"); + break; + case '"': + r = clt_puts(clt, """); + break; + case '\'': + r = clt_puts(clt, "'"); + break; + default: + r = clt_putc(clt, *s); + break; + } + + if (r == -1) + return (-1); + } + + return (0); +} + +int +clt_putmatch(struct client *clt, const char *s) +{ + int r, instrong = 0, intag = 0, lastnl = 0; + + if (s == NULL) + return (0); + + for (; *s; ++s) { + switch (*s) { + case '<': + if (!instrong && !strncmp(s, "", 8)) { + instrong = intag = 1; + r = clt_putc(clt, *s); + } else if (instrong && !strncmp(s, "", 9)) { + instrong = 0; + intag = 1; + r = clt_putc(clt, *s); + } else + r = clt_puts(clt, "<"); break; + case '>': + if (intag) { + intag = 0; + r = clt_putc(clt, *s); + } else + r = clt_puts(clt, ">"); + break; case '&': r = clt_puts(clt, "&"); break; @@ -706,7 +755,14 @@ clt_putsan(struct client *clt, const char *s) case '\'': r = clt_puts(clt, "'"); break; + case '\n': + if (lastnl) + break; + r = clt_puts(clt, "
"); + lastnl = 1; + break; default: + lastnl = 0; r = clt_putc(clt, *s); break; } @@ -715,6 +771,8 @@ clt_putsan(struct client *clt, const char *s) return (-1); } + if (instrong) /* something went wrong... */ + return clt_puts(clt, "
"); return (0); } blob - e0ac0be5e89e31a03ddc36507791c0320adef3f9 blob + 2efdad37df16fbfd2cedee23b3be99d95a3618d6 --- msearchd/msearchd.h +++ msearchd/msearchd.h @@ -99,6 +99,7 @@ void fcgi_free(struct fcgi *); int clt_putc(struct client *, char); int clt_puts(struct client *, const char *); int clt_putsan(struct client *, const char *); +int clt_putmatch(struct client *, const char *); int clt_write_bufferevent(struct client *, struct bufferevent *); int clt_flush(struct client *); int clt_write(struct client *, const uint8_t *, size_t); blob - 9a533b7f961b04d3bd636c5dd42247025b4701c7 blob + 843b633e7a02b2e18bb16c2bf1bc2718f79cc063 --- msearchd/server.c +++ msearchd/server.c @@ -75,7 +75,8 @@ server_open_db(struct env *env) sqlite3_errmsg(env->env_db)); loadstmt(env->env_db, &env->env_query, - "select mid, \"from\", date, subj" + "select mid, \"from\", date, subj," + " snippet(email, 4, '', '', '...', 32)" " from email" " where email match ?" " order by rank, date" @@ -299,7 +300,7 @@ server_handle(struct env *env, struct client *clt) char dbuf[64]; char esc[QUERY_MAXLEN]; char *query; - const char *mid, *from, *subj; + const char *mid, *from, *subj, *snip; uint64_t date; time_t d; struct tm *tm; @@ -352,6 +353,7 @@ server_handle(struct env *env, struct client *clt) from = sqlite3_column_text(env->env_query, 1); date = sqlite3_column_int64(env->env_query, 2); subj = sqlite3_column_text(env->env_query, 3); + snip = sqlite3_column_text(env->env_query, 4); if ((sizeof(d) == 4) && date > UINT32_MAX) { log_warnx("overflow of 32bit time value"); @@ -381,7 +383,9 @@ server_handle(struct env *env, struct client *clt) clt_putsan(clt, mid) == -1 || clt_puts(clt, ".html'>") == -1 || clt_putsan(clt, subj) == -1 || - clt_puts(clt, "

") == -1) + clt_puts(clt, "

") == -1 || + clt_putmatch(clt, snip) == -1 || + clt_puts(clt, "

") == -1) goto err; } blob - f649383462eabfc4dce6458a3d315078edca16e8 blob + 9ff7493422cd1e57103466a3ae1da48d428d8994 --- style.css +++ style.css @@ -92,6 +92,11 @@ hr { margin: 0; } +.thread .excerpt { + margin-left: 10px; + margin-top: 5px; +} + .thread a { text-decoration: none; }