Fossil SCM

Add the "fossil email subscribers" and "fossil email unsubscribe" commands.

drh 2018-06-22 19:03 UTC email-alerts
Commit ba60f8744c69d6122d56186fcb7fa9df8740f9434715dc3021be67a77e6b277c
1 file changed +79 -9
+79 -9
--- src/email.c
+++ src/email.c
@@ -453,10 +453,18 @@
453453
** COMMAND: email
454454
**
455455
** Usage: %fossil email SUBCOMMAND ARGS...
456456
**
457457
** Subcommands:
458
+**
459
+** exec Compose and send pending email alerts.
460
+** Some installations may want to do this via
461
+** a cron-job to make sure alerts are sent
462
+** in a timely manner.
463
+** Options:
464
+**
465
+** --digest Send digests
458466
**
459467
** inbound [FILE] Receive an inbound email message. This message
460468
** is analyzed to see if it is a bounce, and if
461469
** necessary, subscribers may be disabled.
462470
**
@@ -474,18 +482,28 @@
474482
** --stdout
475483
** --subject|-S SUBJECT
476484
**
477485
** settings [NAME VALUE] With no arguments, list all email settings.
478486
** Or change the value of a single email setting.
487
+**
488
+** subscribers [PATTERN] List all subscribers matching PATTERN.
489
+**
490
+** unsubscribe EMAIL Remove a single subscriber with the given EMAIL.
479491
*/
480492
void email_cmd(void){
481493
const char *zCmd;
482494
int nCmd;
483495
db_find_and_open_repository(0, 0);
484496
email_schema();
485497
zCmd = g.argc>=3 ? g.argv[2] : "x";
486498
nCmd = (int)strlen(zCmd);
499
+ if( strncmp(zCmd, "exec", nCmd)==0 ){
500
+ u32 eFlags = 0;
501
+ if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
502
+ verify_all_options();
503
+ email_send_alerts(eFlags);
504
+ }else
487505
if( strncmp(zCmd, "inbound", nCmd)==0 ){
488506
Blob email;
489507
const char *zInboundDir = db_get("email-receive-dir","");
490508
verify_all_options();
491509
if( g.argc!=3 && g.argc!=4 ){
@@ -564,12 +582,12 @@
564582
email_send(&hdr, &body, 0, zDest);
565583
}
566584
blob_zero(&hdr);
567585
blob_zero(&body);
568586
blob_zero(&prompt);
569
- }
570
- else if( strncmp(zCmd, "settings", nCmd)==0 ){
587
+ }else
588
+ if( strncmp(zCmd, "settings", nCmd)==0 ){
571589
int isGlobal = find_option("global",0,0)!=0;
572590
int nSetting;
573591
const Setting *pSetting = setting_info(&nSetting);
574592
db_open_config(1, 0);
575593
verify_all_options();
@@ -586,13 +604,41 @@
586604
pSetting = setting_info(&nSetting);
587605
for(; nSetting>0; nSetting--, pSetting++ ){
588606
if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
589607
print_setting(pSetting);
590608
}
591
- }
592
- else{
593
- usage("inbound|reset|send|setting");
609
+ }else
610
+ if( strncmp(zCmd, "subscribers", nCmd)==0 ){
611
+ Stmt q;
612
+ verify_all_options();
613
+ if( g.argc!=3 && g.argc!=4 ) usage("subscribers [PATTERN]");
614
+ if( g.argc==4 ){
615
+ char *zPattern = g.argv[3];
616
+ db_prepare(&q,
617
+ "SELECT semail FROM subscriber"
618
+ " WHERE semail LIKE '%%%q%%' OR suname LIKE '%%%q%%'"
619
+ " OR semail GLOB '*%q*' or suname GLOB '*%q*'"
620
+ " ORDER BY semail",
621
+ zPattern, zPattern, zPattern, zPattern);
622
+ }else{
623
+ db_prepare(&q,
624
+ "SELECT semail FROM subscriber"
625
+ " ORDER BY semail");
626
+ }
627
+ while( db_step(&q)==SQLITE_ROW ){
628
+ fossil_print("%s\n", db_column_text(&q, 0));
629
+ }
630
+ db_finalize(&q);
631
+ }else
632
+ if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){
633
+ verify_all_options();
634
+ if( g.argc!=4 ) usage("unsubscribe EMAIL");
635
+ db_multi_exec(
636
+ "DELETE FROM subscriber WHERE semail=%Q", g.argv[3]);
637
+ }else
638
+ {
639
+ usage("exec|inbound|reset|send|setting|subscribers|unsubscribe");
594640
}
595641
}
596642
597643
/*
598644
** Do error checking on a submitted subscription form. Return TRUE
@@ -1393,10 +1439,31 @@
13931439
email_footer(&out);
13941440
fossil_print("%s", blob_str(&out));
13951441
blob_zero(&out);
13961442
db_end_transaction(0);
13971443
}
1444
+
1445
+/*
1446
+** COMMAND: test-add-alerts
1447
+**
1448
+** Usage: %fossil test-add-alerts EVENTID ...
1449
+**
1450
+** Add one or more events to the pending_alert queue. Use this
1451
+** command during testing to force email notifications for specific
1452
+** events.
1453
+*/
1454
+void test_add_alert_cmd(void){
1455
+ int i;
1456
+ db_find_and_open_repository(0, 0);
1457
+ verify_all_options();
1458
+ db_begin_transaction();
1459
+ email_schema();
1460
+ for(i=2; i<g.argc; i++){
1461
+ db_multi_exec("INSERT INTO pending_alert(eventId) VALUES(%Q)", g.argv[i]);
1462
+ }
1463
+ db_end_transaction(0);
1464
+}
13981465
13991466
#if INTERFACE
14001467
/*
14011468
** Flags for email_send_alerts()
14021469
*/
@@ -1416,17 +1483,18 @@
14161483
Blob hdr, body;
14171484
const char *zUrl;
14181485
const char *zRepoName;
14191486
const char *zFrom;
14201487
1421
- if( !email_enabled() ) return;
1488
+ db_begin_transaction();
1489
+ if( !email_enabled() ) goto send_alerts_done;
14221490
zUrl = db_get("email-url",0);
1423
- if( zUrl==0 ) return;
1491
+ if( zUrl==0 ) goto send_alerts_done;
14241492
zRepoName = db_get("email-subname",0);
1425
- if( zRepoName==0 ) return;
1493
+ if( zRepoName==0 ) goto send_alerts_done;
14261494
zFrom = db_get("email-self",0);
1427
- if( zFrom==0 ) return;
1495
+ if( zFrom==0 ) goto send_alerts_done;
14281496
db_multi_exec(
14291497
"DROP TABLE IF EXISTS temp.wantalert;"
14301498
"CREATE TEMP TABLE wantalert(eventId TEXT);"
14311499
);
14321500
if( flags & SENDALERT_DIGEST ){
@@ -1493,6 +1561,8 @@
14931561
}else{
14941562
db_multi_exec("UPDATE pending_alert SET sentSep=true");
14951563
}
14961564
db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep");
14971565
}
1566
+send_alerts_done:
1567
+ db_end_transaction(0);
14981568
}
14991569
--- src/email.c
+++ src/email.c
@@ -453,10 +453,18 @@
453 ** COMMAND: email
454 **
455 ** Usage: %fossil email SUBCOMMAND ARGS...
456 **
457 ** Subcommands:
 
 
 
 
 
 
 
 
458 **
459 ** inbound [FILE] Receive an inbound email message. This message
460 ** is analyzed to see if it is a bounce, and if
461 ** necessary, subscribers may be disabled.
462 **
@@ -474,18 +482,28 @@
474 ** --stdout
475 ** --subject|-S SUBJECT
476 **
477 ** settings [NAME VALUE] With no arguments, list all email settings.
478 ** Or change the value of a single email setting.
 
 
 
 
479 */
480 void email_cmd(void){
481 const char *zCmd;
482 int nCmd;
483 db_find_and_open_repository(0, 0);
484 email_schema();
485 zCmd = g.argc>=3 ? g.argv[2] : "x";
486 nCmd = (int)strlen(zCmd);
 
 
 
 
 
 
487 if( strncmp(zCmd, "inbound", nCmd)==0 ){
488 Blob email;
489 const char *zInboundDir = db_get("email-receive-dir","");
490 verify_all_options();
491 if( g.argc!=3 && g.argc!=4 ){
@@ -564,12 +582,12 @@
564 email_send(&hdr, &body, 0, zDest);
565 }
566 blob_zero(&hdr);
567 blob_zero(&body);
568 blob_zero(&prompt);
569 }
570 else if( strncmp(zCmd, "settings", nCmd)==0 ){
571 int isGlobal = find_option("global",0,0)!=0;
572 int nSetting;
573 const Setting *pSetting = setting_info(&nSetting);
574 db_open_config(1, 0);
575 verify_all_options();
@@ -586,13 +604,41 @@
586 pSetting = setting_info(&nSetting);
587 for(; nSetting>0; nSetting--, pSetting++ ){
588 if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
589 print_setting(pSetting);
590 }
591 }
592 else{
593 usage("inbound|reset|send|setting");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594 }
595 }
596
597 /*
598 ** Do error checking on a submitted subscription form. Return TRUE
@@ -1393,10 +1439,31 @@
1393 email_footer(&out);
1394 fossil_print("%s", blob_str(&out));
1395 blob_zero(&out);
1396 db_end_transaction(0);
1397 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1398
1399 #if INTERFACE
1400 /*
1401 ** Flags for email_send_alerts()
1402 */
@@ -1416,17 +1483,18 @@
1416 Blob hdr, body;
1417 const char *zUrl;
1418 const char *zRepoName;
1419 const char *zFrom;
1420
1421 if( !email_enabled() ) return;
 
1422 zUrl = db_get("email-url",0);
1423 if( zUrl==0 ) return;
1424 zRepoName = db_get("email-subname",0);
1425 if( zRepoName==0 ) return;
1426 zFrom = db_get("email-self",0);
1427 if( zFrom==0 ) return;
1428 db_multi_exec(
1429 "DROP TABLE IF EXISTS temp.wantalert;"
1430 "CREATE TEMP TABLE wantalert(eventId TEXT);"
1431 );
1432 if( flags & SENDALERT_DIGEST ){
@@ -1493,6 +1561,8 @@
1493 }else{
1494 db_multi_exec("UPDATE pending_alert SET sentSep=true");
1495 }
1496 db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep");
1497 }
 
 
1498 }
1499
--- src/email.c
+++ src/email.c
@@ -453,10 +453,18 @@
453 ** COMMAND: email
454 **
455 ** Usage: %fossil email SUBCOMMAND ARGS...
456 **
457 ** Subcommands:
458 **
459 ** exec Compose and send pending email alerts.
460 ** Some installations may want to do this via
461 ** a cron-job to make sure alerts are sent
462 ** in a timely manner.
463 ** Options:
464 **
465 ** --digest Send digests
466 **
467 ** inbound [FILE] Receive an inbound email message. This message
468 ** is analyzed to see if it is a bounce, and if
469 ** necessary, subscribers may be disabled.
470 **
@@ -474,18 +482,28 @@
482 ** --stdout
483 ** --subject|-S SUBJECT
484 **
485 ** settings [NAME VALUE] With no arguments, list all email settings.
486 ** Or change the value of a single email setting.
487 **
488 ** subscribers [PATTERN] List all subscribers matching PATTERN.
489 **
490 ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL.
491 */
492 void email_cmd(void){
493 const char *zCmd;
494 int nCmd;
495 db_find_and_open_repository(0, 0);
496 email_schema();
497 zCmd = g.argc>=3 ? g.argv[2] : "x";
498 nCmd = (int)strlen(zCmd);
499 if( strncmp(zCmd, "exec", nCmd)==0 ){
500 u32 eFlags = 0;
501 if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
502 verify_all_options();
503 email_send_alerts(eFlags);
504 }else
505 if( strncmp(zCmd, "inbound", nCmd)==0 ){
506 Blob email;
507 const char *zInboundDir = db_get("email-receive-dir","");
508 verify_all_options();
509 if( g.argc!=3 && g.argc!=4 ){
@@ -564,12 +582,12 @@
582 email_send(&hdr, &body, 0, zDest);
583 }
584 blob_zero(&hdr);
585 blob_zero(&body);
586 blob_zero(&prompt);
587 }else
588 if( strncmp(zCmd, "settings", nCmd)==0 ){
589 int isGlobal = find_option("global",0,0)!=0;
590 int nSetting;
591 const Setting *pSetting = setting_info(&nSetting);
592 db_open_config(1, 0);
593 verify_all_options();
@@ -586,13 +604,41 @@
604 pSetting = setting_info(&nSetting);
605 for(; nSetting>0; nSetting--, pSetting++ ){
606 if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
607 print_setting(pSetting);
608 }
609 }else
610 if( strncmp(zCmd, "subscribers", nCmd)==0 ){
611 Stmt q;
612 verify_all_options();
613 if( g.argc!=3 && g.argc!=4 ) usage("subscribers [PATTERN]");
614 if( g.argc==4 ){
615 char *zPattern = g.argv[3];
616 db_prepare(&q,
617 "SELECT semail FROM subscriber"
618 " WHERE semail LIKE '%%%q%%' OR suname LIKE '%%%q%%'"
619 " OR semail GLOB '*%q*' or suname GLOB '*%q*'"
620 " ORDER BY semail",
621 zPattern, zPattern, zPattern, zPattern);
622 }else{
623 db_prepare(&q,
624 "SELECT semail FROM subscriber"
625 " ORDER BY semail");
626 }
627 while( db_step(&q)==SQLITE_ROW ){
628 fossil_print("%s\n", db_column_text(&q, 0));
629 }
630 db_finalize(&q);
631 }else
632 if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){
633 verify_all_options();
634 if( g.argc!=4 ) usage("unsubscribe EMAIL");
635 db_multi_exec(
636 "DELETE FROM subscriber WHERE semail=%Q", g.argv[3]);
637 }else
638 {
639 usage("exec|inbound|reset|send|setting|subscribers|unsubscribe");
640 }
641 }
642
643 /*
644 ** Do error checking on a submitted subscription form. Return TRUE
@@ -1393,10 +1439,31 @@
1439 email_footer(&out);
1440 fossil_print("%s", blob_str(&out));
1441 blob_zero(&out);
1442 db_end_transaction(0);
1443 }
1444
1445 /*
1446 ** COMMAND: test-add-alerts
1447 **
1448 ** Usage: %fossil test-add-alerts EVENTID ...
1449 **
1450 ** Add one or more events to the pending_alert queue. Use this
1451 ** command during testing to force email notifications for specific
1452 ** events.
1453 */
1454 void test_add_alert_cmd(void){
1455 int i;
1456 db_find_and_open_repository(0, 0);
1457 verify_all_options();
1458 db_begin_transaction();
1459 email_schema();
1460 for(i=2; i<g.argc; i++){
1461 db_multi_exec("INSERT INTO pending_alert(eventId) VALUES(%Q)", g.argv[i]);
1462 }
1463 db_end_transaction(0);
1464 }
1465
1466 #if INTERFACE
1467 /*
1468 ** Flags for email_send_alerts()
1469 */
@@ -1416,17 +1483,18 @@
1483 Blob hdr, body;
1484 const char *zUrl;
1485 const char *zRepoName;
1486 const char *zFrom;
1487
1488 db_begin_transaction();
1489 if( !email_enabled() ) goto send_alerts_done;
1490 zUrl = db_get("email-url",0);
1491 if( zUrl==0 ) goto send_alerts_done;
1492 zRepoName = db_get("email-subname",0);
1493 if( zRepoName==0 ) goto send_alerts_done;
1494 zFrom = db_get("email-self",0);
1495 if( zFrom==0 ) goto send_alerts_done;
1496 db_multi_exec(
1497 "DROP TABLE IF EXISTS temp.wantalert;"
1498 "CREATE TEMP TABLE wantalert(eventId TEXT);"
1499 );
1500 if( flags & SENDALERT_DIGEST ){
@@ -1493,6 +1561,8 @@
1561 }else{
1562 db_multi_exec("UPDATE pending_alert SET sentSep=true");
1563 }
1564 db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep");
1565 }
1566 send_alerts_done:
1567 db_end_transaction(0);
1568 }
1569

Keyboard Shortcuts

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