Fossil SCM

Webmail navigation updates. Move message between Unread/Read/Trash. Show 50 messages per page with Newer and Older links when appropriate.

drh 2018-07-14 18:36 webmail
Commit 485d01fb17d22f6da320da797bde045d3800c99be1423375d935b519cee1fcba
1 file changed +201 -68
+201 -68
--- src/webmail.c
+++ src/webmail.c
@@ -352,10 +352,164 @@
352352
}
353353
}
354354
emailtoc_free(p);
355355
blob_reset(&email);
356356
}
357
+
358
+/*
359
+** Paint a page showing a single email message
360
+*/
361
+static void webmail_show_one_message(
362
+ HQuery *pUrl, /* Calling context */
363
+ int emailid, /* emailbox.ebid to display */
364
+ const char *zUser /* User who owns it, or NULL if does not matter */
365
+){
366
+ Blob sql;
367
+ Stmt q;
368
+ int eState = -1;
369
+ char zENum[30];
370
+ style_submenu_element("Index", "%s", url_render(pUrl,"id",0,0,0));
371
+ blob_init(&sql, 0, 0);
372
+ db_begin_transaction();
373
+ blob_append_sql(&sql,
374
+ "SELECT decompress(etxt), estate"
375
+ " FROM emailblob, emailbox"
376
+ " WHERE emailid=emsgid AND ebid=%d",
377
+ emailid
378
+ );
379
+ if( zUser ) blob_append_sql(&sql, " AND euser=%Q", zUser);
380
+ db_prepare_blob(&q, &sql);
381
+ blob_reset(&sql);
382
+ style_header("Message %d",emailid);
383
+ if( db_step(&q)==SQLITE_ROW ){
384
+ Blob msg = db_column_text_as_blob(&q, 0);
385
+ int eFormat = atoi(PD("f","0"));
386
+ eState = db_column_int(&q, 1);
387
+ url_add_parameter(pUrl, "id", P("id"));
388
+ if( eFormat==1 ){
389
+ @ <pre>%h(db_column_text(&q, 0))</pre>
390
+ style_submenu_element("Decoded", "%s", url_render(pUrl,"f",0,0,0));
391
+ }else{
392
+ EmailToc *p = emailtoc_from_email(&msg);
393
+ int i, j;
394
+ style_submenu_element("Raw", "%s", url_render(pUrl,"f","1",0,0));
395
+ @ <p>
396
+ for(i=0; i<p->nHdr; i++){
397
+ char *z = p->azHdr[i];
398
+ email_hdr_unfold(z);
399
+ for(j=0; z[j] && z[j]!=':'; j++){}
400
+ if( z[j]!=':' ){
401
+ @ %h(z)<br>
402
+ }else{
403
+ z[j] = 0;
404
+ @ <b>%h(z):</b> %h(z+j+1)<br>
405
+ }
406
+ }
407
+ for(i=0; i<p->nBody; i++){
408
+ @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \
409
+ if( p->aBody[i].zFilename ){
410
+ @ "%h(p->aBody[i].zFilename)"
411
+ }
412
+ @ </b>
413
+ if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue;
414
+ switch( p->aBody[i].encoding ){
415
+ case EMAILENC_B64: {
416
+ int n = 0;
417
+ decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent);
418
+ break;
419
+ }
420
+ case EMAILENC_QUOTED: {
421
+ int n = 0;
422
+ decodeQuotedPrintable(p->aBody[i].zContent, &n);
423
+ break;
424
+ }
425
+ }
426
+ @ <pre>%h(p->aBody[i].zContent)</pre>
427
+ }
428
+ }
429
+ }
430
+ db_finalize(&q);
431
+
432
+ if( eState==0 ){
433
+ /* If is message is currently Unread, change it to Read */
434
+ blob_append_sql(&sql,
435
+ "UPDATE emailbox SET estate=1 "
436
+ " WHERE estate=0 AND ebid=%d",
437
+ emailid
438
+ );
439
+ if( zUser ) blob_append_sql(&sql, " AND euser=%Q", zUser);
440
+ db_multi_exec("%s", blob_sql_text(&sql));
441
+ blob_reset(&sql);
442
+ eState = 1;
443
+ }
444
+
445
+ url_add_parameter(pUrl, "id", 0);
446
+ sqlite3_snprintf(sizeof(zENum), zENum, "e%d", emailid);
447
+ if( eState==2 ){
448
+ style_submenu_element("Undelete","%s",
449
+ url_render(pUrl,"read","1",zENum,"1"));
450
+ }
451
+ if( eState==1 ){
452
+ style_submenu_element("Delete", "%s",
453
+ url_render(pUrl,"trash","1",zENum,"1"));
454
+ style_submenu_element("Mark As Unread", "%s",
455
+ url_render(pUrl,"unread","1",zENum,"1"));
456
+ }
457
+
458
+ db_end_transaction(0);
459
+ style_footer();
460
+ return;
461
+}
462
+
463
+/*
464
+** Scan the query parameters looking for parameters with name of the
465
+** form "eN" where N is an integer. For all such integers, change
466
+** the state of every emailbox entry with ebid==N to eStateNew provided
467
+** that either zUser is NULL or matches.
468
+*/
469
+static void webmail_change_state(int eNewState, const char *zUser){
470
+ Blob sql;
471
+ int sep = '(';
472
+ int i;
473
+ const char *zName;
474
+ int n;
475
+ if( !cgi_csrf_safe(0) ) return;
476
+ blob_init(&sql, 0, 0);
477
+ blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ",
478
+ eNewState);
479
+ for(i=0; (zName = cgi_parameter_name(i))!=0; i++){
480
+ if( zName[0]!='e' ) continue;
481
+ if( !fossil_isdigit(zName[1]) ) continue;
482
+ n = atoi(zName+1);
483
+ blob_append_sql(&sql, "%c%d", sep, n);
484
+ sep = ',';
485
+ }
486
+ if( zUser ){
487
+ blob_append_sql(&sql, ") AND euser=%Q", zUser);
488
+ }else{
489
+ blob_append_sql(&sql, ")");
490
+ }
491
+ if( sep==',' ){
492
+ db_multi_exec("%s", blob_sql_text(&sql));
493
+ }
494
+ blob_reset(&sql);
495
+}
496
+
497
+
498
+/*
499
+** Add the select/option box to the timeline submenu that shows
500
+** which messages to include in the index.
501
+*/
502
+static void webmail_d_submenu(void){
503
+ static const char *az[] = {
504
+ "0", "InBox",
505
+ "1", "Unread",
506
+ "2", "Trash",
507
+ "3", "Everything",
508
+ };
509
+ style_submenu_multichoice("d", sizeof(az)/(2*sizeof(az[0])), az, 0);
510
+}
357511
358512
/*
359513
** WEBPAGE: webmail
360514
**
361515
** This page can be used to read content from the EMAILBOX table
@@ -378,10 +532,16 @@
378532
int emailid;
379533
Stmt q;
380534
Blob sql;
381535
int showAll = 0;
382536
const char *zUser = 0;
537
+ int d = 0; /* Display mode. 0..3. d= query parameter */
538
+ int pg = 0; /* Page number */
539
+ int N = 50; /* Results per page */
540
+ int got; /* Number of results on this page */
541
+ char zPPg[30]; /* Previous page */
542
+ char zNPg[30]; /* Next page */
383543
HQuery url;
384544
login_check_credentials();
385545
if( !login_is_individual() ){
386546
login_needed(0);
387547
return;
@@ -402,88 +562,37 @@
402562
if( fossil_strcmp(zUser,"*")==0 ){
403563
showAll = 1;
404564
zUser = 0;
405565
}
406566
}
567
+ }else{
568
+ zUser = g.zLogin;
407569
}
570
+ if( P("d") ) url_add_parameter(&url, "d", P("d"));
408571
if( emailid>0 ){
409
- style_submenu_element("Index", "%s", url_render(&url,"id",0,0,0));
410
- blob_init(&sql, 0, 0);
411
- db_begin_transaction();
412
- blob_append_sql(&sql, "SELECT decompress(etxt)"
413
- " FROM emailblob, emailbox"
414
- " WHERE emailid=emsgid AND ebid=%d",
415
- emailid);
416
- if( !g.perm.Admin ){
417
- blob_append_sql(&sql, " AND euser=%Q", g.zLogin);
418
- }
419
- db_prepare_blob(&q, &sql);
420
- blob_reset(&sql);
421
- if( db_step(&q)==SQLITE_ROW ){
422
- Blob msg = db_column_text_as_blob(&q, 0);
423
- int eFormat = atoi(PD("f","0"));
424
- url_add_parameter(&url, "id", P("id"));
425
- style_header("Message %d",emailid);
426
- if( eFormat==1 ){
427
- @ <pre>%h(db_column_text(&q, 0))</pre>
428
- style_submenu_element("Decoded", "%s", url_render(&url,"f",0,0,0));
429
- }else{
430
- EmailToc *p = emailtoc_from_email(&msg);
431
- int i, j;
432
- style_submenu_element("Raw", "%s", url_render(&url,"f","1",0,0));
433
- @ <p>
434
- for(i=0; i<p->nHdr; i++){
435
- char *z = p->azHdr[i];
436
- email_hdr_unfold(z);
437
- for(j=0; z[j] && z[j]!=':'; j++){}
438
- if( z[j]!=':' ){
439
- @ %h(z)<br>
440
- }else{
441
- z[j] = 0;
442
- @ <b>%h(z):</b> %h(z+j+1)<br>
443
- }
444
- }
445
- for(i=0; i<p->nBody; i++){
446
- @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \
447
- if( p->aBody[i].zFilename ){
448
- @ "%h(p->aBody[i].zFilename)"
449
- }
450
- @ </b>
451
- if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue;
452
- switch( p->aBody[i].encoding ){
453
- case EMAILENC_B64: {
454
- int n = 0;
455
- decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent);
456
- break;
457
- }
458
- case EMAILENC_QUOTED: {
459
- int n = 0;
460
- decodeQuotedPrintable(p->aBody[i].zContent, &n);
461
- break;
462
- }
463
- }
464
- @ <pre>%h(p->aBody[i].zContent)</pre>
465
- }
466
- }
467
- style_footer();
468
- db_finalize(&q);
469
- return;
470
- }
471
- db_finalize(&q);
572
+ webmail_show_one_message(&url, emailid, zUser);
573
+ return;
472574
}
473575
style_header("Webmail");
576
+ webmail_d_submenu();
577
+ db_begin_transaction();
578
+ if( P("trash")!=0 ) webmail_change_state(2,zUser);
579
+ if( P("unread")!=0 ) webmail_change_state(0,zUser);
580
+ if( P("read")!=0 ) webmail_change_state(1,zUser);
474581
blob_init(&sql, 0, 0);
475582
blob_append_sql(&sql,
583
+ "CREATE TEMP TABLE tmbox AS "
476584
"SELECT ebid," /* 0 */
477585
" efrom," /* 1 */
478586
" datetime(edate,'unixepoch')," /* 2 */
479587
" estate," /* 3 */
480588
" esubject," /* 4 */
481589
" euser" /* 5 */
482590
" FROM emailbox"
483591
);
484
- switch( atoi(PD("d","0")) ){
592
+ d = atoi(PD("d","0"));
593
+ switch( d ){
485594
case 0: { /* Show unread and read */
486595
blob_append_sql(&sql, " WHERE estate<=1");
487596
break;
488597
}
489598
case 1: { /* Unread messages only */
@@ -497,11 +606,10 @@
497606
case 3: { /* Everything */
498607
blob_append_sql(&sql, " WHERE 1");
499608
break;
500609
}
501610
}
502
-
503611
if( showAll ){
504612
style_submenu_element("My Emails", "%s", url_render(&url,"user",0,0,0));
505613
}else if( zUser!=0 ){
506614
style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
507615
if( fossil_strcmp(zUser, g.zLogin)!=0 ){
@@ -516,14 +624,38 @@
516624
if( g.perm.Admin ){
517625
style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
518626
}
519627
blob_append_sql(&sql, " AND euser=%Q", g.zLogin);
520628
}
521
- blob_append_sql(&sql, " ORDER BY edate DESC limit 50");
522
- db_prepare_blob(&q, &sql);
629
+ pg = atoi(PD("pg","0"));
630
+ blob_append_sql(&sql, " ORDER BY edate DESC limit %d offset %d", N+1, pg*N);
631
+ db_multi_exec("%s", blob_sql_text(&sql));
632
+ got = db_int(0, "SELECT count(*) FROM tmbox");
633
+ db_prepare(&q, "SELECT * FROM tmbox LIMIT %d", N);
523634
blob_reset(&sql);
524635
@ <form action="%R/webmail" method="POST">
636
+ @ <table border="0" width="100%%">
637
+ @ <tr><td align="left">
638
+ if( d==2 ){
639
+ @ <input type="submit" name="read" value="Undelete">
640
+ }else{
641
+ @ <input type="submit" name="trash", value="Delete">
642
+ if( d!=1 ){
643
+ @ <input type="submit" name="unread" value="Mark as unread">
644
+ }
645
+ @ <input type="submit" name="read" value="Mark as read">
646
+ }
647
+ @ </td><td align="right">
648
+ if( pg>0 ){
649
+ sqlite3_snprintf(sizeof(zPPg), zPPg, "%d", pg-1);
650
+ @ <a href="%s(url_render(&url,"pg",zPPg,0,0))">&lt; Newer</a>&nbsp;&nbsp;
651
+ }
652
+ if( got>50 ){
653
+ sqlite3_snprintf(sizeof(zNPg),zNPg,"%d",pg+1);
654
+ @ <a href="%s(url_render(&url,"pg",zNPg,0,0))">Older &gt;</a></td>
655
+ }
656
+ @ </table>
525657
@ <table>
526658
while( db_step(&q)==SQLITE_ROW ){
527659
const char *zId = db_column_text(&q,0);
528660
const char *zFrom = db_column_text(&q, 1);
529661
const char *zDate = db_column_text(&q, 2);
@@ -540,7 +672,8 @@
540672
@ </tr>
541673
}
542674
db_finalize(&q);
543675
@ </table>
544676
@ </form>
545
- style_footer();
677
+ style_footer();
678
+ db_end_transaction(0);
546679
}
547680
--- src/webmail.c
+++ src/webmail.c
@@ -352,10 +352,164 @@
352 }
353 }
354 emailtoc_free(p);
355 blob_reset(&email);
356 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
358 /*
359 ** WEBPAGE: webmail
360 **
361 ** This page can be used to read content from the EMAILBOX table
@@ -378,10 +532,16 @@
378 int emailid;
379 Stmt q;
380 Blob sql;
381 int showAll = 0;
382 const char *zUser = 0;
 
 
 
 
 
 
383 HQuery url;
384 login_check_credentials();
385 if( !login_is_individual() ){
386 login_needed(0);
387 return;
@@ -402,88 +562,37 @@
402 if( fossil_strcmp(zUser,"*")==0 ){
403 showAll = 1;
404 zUser = 0;
405 }
406 }
 
 
407 }
 
408 if( emailid>0 ){
409 style_submenu_element("Index", "%s", url_render(&url,"id",0,0,0));
410 blob_init(&sql, 0, 0);
411 db_begin_transaction();
412 blob_append_sql(&sql, "SELECT decompress(etxt)"
413 " FROM emailblob, emailbox"
414 " WHERE emailid=emsgid AND ebid=%d",
415 emailid);
416 if( !g.perm.Admin ){
417 blob_append_sql(&sql, " AND euser=%Q", g.zLogin);
418 }
419 db_prepare_blob(&q, &sql);
420 blob_reset(&sql);
421 if( db_step(&q)==SQLITE_ROW ){
422 Blob msg = db_column_text_as_blob(&q, 0);
423 int eFormat = atoi(PD("f","0"));
424 url_add_parameter(&url, "id", P("id"));
425 style_header("Message %d",emailid);
426 if( eFormat==1 ){
427 @ <pre>%h(db_column_text(&q, 0))</pre>
428 style_submenu_element("Decoded", "%s", url_render(&url,"f",0,0,0));
429 }else{
430 EmailToc *p = emailtoc_from_email(&msg);
431 int i, j;
432 style_submenu_element("Raw", "%s", url_render(&url,"f","1",0,0));
433 @ <p>
434 for(i=0; i<p->nHdr; i++){
435 char *z = p->azHdr[i];
436 email_hdr_unfold(z);
437 for(j=0; z[j] && z[j]!=':'; j++){}
438 if( z[j]!=':' ){
439 @ %h(z)<br>
440 }else{
441 z[j] = 0;
442 @ <b>%h(z):</b> %h(z+j+1)<br>
443 }
444 }
445 for(i=0; i<p->nBody; i++){
446 @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \
447 if( p->aBody[i].zFilename ){
448 @ "%h(p->aBody[i].zFilename)"
449 }
450 @ </b>
451 if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue;
452 switch( p->aBody[i].encoding ){
453 case EMAILENC_B64: {
454 int n = 0;
455 decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent);
456 break;
457 }
458 case EMAILENC_QUOTED: {
459 int n = 0;
460 decodeQuotedPrintable(p->aBody[i].zContent, &n);
461 break;
462 }
463 }
464 @ <pre>%h(p->aBody[i].zContent)</pre>
465 }
466 }
467 style_footer();
468 db_finalize(&q);
469 return;
470 }
471 db_finalize(&q);
472 }
473 style_header("Webmail");
 
 
 
 
 
474 blob_init(&sql, 0, 0);
475 blob_append_sql(&sql,
 
476 "SELECT ebid," /* 0 */
477 " efrom," /* 1 */
478 " datetime(edate,'unixepoch')," /* 2 */
479 " estate," /* 3 */
480 " esubject," /* 4 */
481 " euser" /* 5 */
482 " FROM emailbox"
483 );
484 switch( atoi(PD("d","0")) ){
 
485 case 0: { /* Show unread and read */
486 blob_append_sql(&sql, " WHERE estate<=1");
487 break;
488 }
489 case 1: { /* Unread messages only */
@@ -497,11 +606,10 @@
497 case 3: { /* Everything */
498 blob_append_sql(&sql, " WHERE 1");
499 break;
500 }
501 }
502
503 if( showAll ){
504 style_submenu_element("My Emails", "%s", url_render(&url,"user",0,0,0));
505 }else if( zUser!=0 ){
506 style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
507 if( fossil_strcmp(zUser, g.zLogin)!=0 ){
@@ -516,14 +624,38 @@
516 if( g.perm.Admin ){
517 style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
518 }
519 blob_append_sql(&sql, " AND euser=%Q", g.zLogin);
520 }
521 blob_append_sql(&sql, " ORDER BY edate DESC limit 50");
522 db_prepare_blob(&q, &sql);
 
 
 
523 blob_reset(&sql);
524 @ <form action="%R/webmail" method="POST">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525 @ <table>
526 while( db_step(&q)==SQLITE_ROW ){
527 const char *zId = db_column_text(&q,0);
528 const char *zFrom = db_column_text(&q, 1);
529 const char *zDate = db_column_text(&q, 2);
@@ -540,7 +672,8 @@
540 @ </tr>
541 }
542 db_finalize(&q);
543 @ </table>
544 @ </form>
545 style_footer();
 
546 }
547
--- src/webmail.c
+++ src/webmail.c
@@ -352,10 +352,164 @@
352 }
353 }
354 emailtoc_free(p);
355 blob_reset(&email);
356 }
357
358 /*
359 ** Paint a page showing a single email message
360 */
361 static void webmail_show_one_message(
362 HQuery *pUrl, /* Calling context */
363 int emailid, /* emailbox.ebid to display */
364 const char *zUser /* User who owns it, or NULL if does not matter */
365 ){
366 Blob sql;
367 Stmt q;
368 int eState = -1;
369 char zENum[30];
370 style_submenu_element("Index", "%s", url_render(pUrl,"id",0,0,0));
371 blob_init(&sql, 0, 0);
372 db_begin_transaction();
373 blob_append_sql(&sql,
374 "SELECT decompress(etxt), estate"
375 " FROM emailblob, emailbox"
376 " WHERE emailid=emsgid AND ebid=%d",
377 emailid
378 );
379 if( zUser ) blob_append_sql(&sql, " AND euser=%Q", zUser);
380 db_prepare_blob(&q, &sql);
381 blob_reset(&sql);
382 style_header("Message %d",emailid);
383 if( db_step(&q)==SQLITE_ROW ){
384 Blob msg = db_column_text_as_blob(&q, 0);
385 int eFormat = atoi(PD("f","0"));
386 eState = db_column_int(&q, 1);
387 url_add_parameter(pUrl, "id", P("id"));
388 if( eFormat==1 ){
389 @ <pre>%h(db_column_text(&q, 0))</pre>
390 style_submenu_element("Decoded", "%s", url_render(pUrl,"f",0,0,0));
391 }else{
392 EmailToc *p = emailtoc_from_email(&msg);
393 int i, j;
394 style_submenu_element("Raw", "%s", url_render(pUrl,"f","1",0,0));
395 @ <p>
396 for(i=0; i<p->nHdr; i++){
397 char *z = p->azHdr[i];
398 email_hdr_unfold(z);
399 for(j=0; z[j] && z[j]!=':'; j++){}
400 if( z[j]!=':' ){
401 @ %h(z)<br>
402 }else{
403 z[j] = 0;
404 @ <b>%h(z):</b> %h(z+j+1)<br>
405 }
406 }
407 for(i=0; i<p->nBody; i++){
408 @ <hr><b>Messsage Body #%d(i): %h(p->aBody[i].zMimetype) \
409 if( p->aBody[i].zFilename ){
410 @ "%h(p->aBody[i].zFilename)"
411 }
412 @ </b>
413 if( strncmp(p->aBody[i].zMimetype, "text/", 5)!=0 ) continue;
414 switch( p->aBody[i].encoding ){
415 case EMAILENC_B64: {
416 int n = 0;
417 decodeBase64(p->aBody[i].zContent, &n, p->aBody[i].zContent);
418 break;
419 }
420 case EMAILENC_QUOTED: {
421 int n = 0;
422 decodeQuotedPrintable(p->aBody[i].zContent, &n);
423 break;
424 }
425 }
426 @ <pre>%h(p->aBody[i].zContent)</pre>
427 }
428 }
429 }
430 db_finalize(&q);
431
432 if( eState==0 ){
433 /* If is message is currently Unread, change it to Read */
434 blob_append_sql(&sql,
435 "UPDATE emailbox SET estate=1 "
436 " WHERE estate=0 AND ebid=%d",
437 emailid
438 );
439 if( zUser ) blob_append_sql(&sql, " AND euser=%Q", zUser);
440 db_multi_exec("%s", blob_sql_text(&sql));
441 blob_reset(&sql);
442 eState = 1;
443 }
444
445 url_add_parameter(pUrl, "id", 0);
446 sqlite3_snprintf(sizeof(zENum), zENum, "e%d", emailid);
447 if( eState==2 ){
448 style_submenu_element("Undelete","%s",
449 url_render(pUrl,"read","1",zENum,"1"));
450 }
451 if( eState==1 ){
452 style_submenu_element("Delete", "%s",
453 url_render(pUrl,"trash","1",zENum,"1"));
454 style_submenu_element("Mark As Unread", "%s",
455 url_render(pUrl,"unread","1",zENum,"1"));
456 }
457
458 db_end_transaction(0);
459 style_footer();
460 return;
461 }
462
463 /*
464 ** Scan the query parameters looking for parameters with name of the
465 ** form "eN" where N is an integer. For all such integers, change
466 ** the state of every emailbox entry with ebid==N to eStateNew provided
467 ** that either zUser is NULL or matches.
468 */
469 static void webmail_change_state(int eNewState, const char *zUser){
470 Blob sql;
471 int sep = '(';
472 int i;
473 const char *zName;
474 int n;
475 if( !cgi_csrf_safe(0) ) return;
476 blob_init(&sql, 0, 0);
477 blob_append_sql(&sql, "UPDATE emailbox SET estate=%d WHERE ebid IN ",
478 eNewState);
479 for(i=0; (zName = cgi_parameter_name(i))!=0; i++){
480 if( zName[0]!='e' ) continue;
481 if( !fossil_isdigit(zName[1]) ) continue;
482 n = atoi(zName+1);
483 blob_append_sql(&sql, "%c%d", sep, n);
484 sep = ',';
485 }
486 if( zUser ){
487 blob_append_sql(&sql, ") AND euser=%Q", zUser);
488 }else{
489 blob_append_sql(&sql, ")");
490 }
491 if( sep==',' ){
492 db_multi_exec("%s", blob_sql_text(&sql));
493 }
494 blob_reset(&sql);
495 }
496
497
498 /*
499 ** Add the select/option box to the timeline submenu that shows
500 ** which messages to include in the index.
501 */
502 static void webmail_d_submenu(void){
503 static const char *az[] = {
504 "0", "InBox",
505 "1", "Unread",
506 "2", "Trash",
507 "3", "Everything",
508 };
509 style_submenu_multichoice("d", sizeof(az)/(2*sizeof(az[0])), az, 0);
510 }
511
512 /*
513 ** WEBPAGE: webmail
514 **
515 ** This page can be used to read content from the EMAILBOX table
@@ -378,10 +532,16 @@
532 int emailid;
533 Stmt q;
534 Blob sql;
535 int showAll = 0;
536 const char *zUser = 0;
537 int d = 0; /* Display mode. 0..3. d= query parameter */
538 int pg = 0; /* Page number */
539 int N = 50; /* Results per page */
540 int got; /* Number of results on this page */
541 char zPPg[30]; /* Previous page */
542 char zNPg[30]; /* Next page */
543 HQuery url;
544 login_check_credentials();
545 if( !login_is_individual() ){
546 login_needed(0);
547 return;
@@ -402,88 +562,37 @@
562 if( fossil_strcmp(zUser,"*")==0 ){
563 showAll = 1;
564 zUser = 0;
565 }
566 }
567 }else{
568 zUser = g.zLogin;
569 }
570 if( P("d") ) url_add_parameter(&url, "d", P("d"));
571 if( emailid>0 ){
572 webmail_show_one_message(&url, emailid, zUser);
573 return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574 }
575 style_header("Webmail");
576 webmail_d_submenu();
577 db_begin_transaction();
578 if( P("trash")!=0 ) webmail_change_state(2,zUser);
579 if( P("unread")!=0 ) webmail_change_state(0,zUser);
580 if( P("read")!=0 ) webmail_change_state(1,zUser);
581 blob_init(&sql, 0, 0);
582 blob_append_sql(&sql,
583 "CREATE TEMP TABLE tmbox AS "
584 "SELECT ebid," /* 0 */
585 " efrom," /* 1 */
586 " datetime(edate,'unixepoch')," /* 2 */
587 " estate," /* 3 */
588 " esubject," /* 4 */
589 " euser" /* 5 */
590 " FROM emailbox"
591 );
592 d = atoi(PD("d","0"));
593 switch( d ){
594 case 0: { /* Show unread and read */
595 blob_append_sql(&sql, " WHERE estate<=1");
596 break;
597 }
598 case 1: { /* Unread messages only */
@@ -497,11 +606,10 @@
606 case 3: { /* Everything */
607 blob_append_sql(&sql, " WHERE 1");
608 break;
609 }
610 }
 
611 if( showAll ){
612 style_submenu_element("My Emails", "%s", url_render(&url,"user",0,0,0));
613 }else if( zUser!=0 ){
614 style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
615 if( fossil_strcmp(zUser, g.zLogin)!=0 ){
@@ -516,14 +624,38 @@
624 if( g.perm.Admin ){
625 style_submenu_element("All Users", "%s", url_render(&url,"user","*",0,0));
626 }
627 blob_append_sql(&sql, " AND euser=%Q", g.zLogin);
628 }
629 pg = atoi(PD("pg","0"));
630 blob_append_sql(&sql, " ORDER BY edate DESC limit %d offset %d", N+1, pg*N);
631 db_multi_exec("%s", blob_sql_text(&sql));
632 got = db_int(0, "SELECT count(*) FROM tmbox");
633 db_prepare(&q, "SELECT * FROM tmbox LIMIT %d", N);
634 blob_reset(&sql);
635 @ <form action="%R/webmail" method="POST">
636 @ <table border="0" width="100%%">
637 @ <tr><td align="left">
638 if( d==2 ){
639 @ <input type="submit" name="read" value="Undelete">
640 }else{
641 @ <input type="submit" name="trash", value="Delete">
642 if( d!=1 ){
643 @ <input type="submit" name="unread" value="Mark as unread">
644 }
645 @ <input type="submit" name="read" value="Mark as read">
646 }
647 @ </td><td align="right">
648 if( pg>0 ){
649 sqlite3_snprintf(sizeof(zPPg), zPPg, "%d", pg-1);
650 @ <a href="%s(url_render(&url,"pg",zPPg,0,0))">&lt; Newer</a>&nbsp;&nbsp;
651 }
652 if( got>50 ){
653 sqlite3_snprintf(sizeof(zNPg),zNPg,"%d",pg+1);
654 @ <a href="%s(url_render(&url,"pg",zNPg,0,0))">Older &gt;</a></td>
655 }
656 @ </table>
657 @ <table>
658 while( db_step(&q)==SQLITE_ROW ){
659 const char *zId = db_column_text(&q,0);
660 const char *zFrom = db_column_text(&q, 1);
661 const char *zDate = db_column_text(&q, 2);
@@ -540,7 +672,8 @@
672 @ </tr>
673 }
674 db_finalize(&q);
675 @ </table>
676 @ </form>
677 style_footer();
678 db_end_transaction(0);
679 }
680

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button