Fossil SCM
Alert sending logic compiles but is so far untested.
Commit
44f9f355979539388d83305ae56844a76bf402191e6baf0ecd33169695a159b5
Parent
6c06b1c896e9c97…
2 files changed
+7
+101
+7
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -480,10 +480,17 @@ | ||
| 480 | 480 | ** Rewind the cursor on a blob back to the beginning. |
| 481 | 481 | */ |
| 482 | 482 | void blob_rewind(Blob *p){ |
| 483 | 483 | p->iCursor = 0; |
| 484 | 484 | } |
| 485 | + | |
| 486 | +/* | |
| 487 | +** Truncate a blob back to zero length | |
| 488 | +*/ | |
| 489 | +void blob_truncate(Blob *p){ | |
| 490 | + p->nUsed = 0; | |
| 491 | +} | |
| 485 | 492 | |
| 486 | 493 | /* |
| 487 | 494 | ** Seek the cursor in a blob to the indicated offset. |
| 488 | 495 | */ |
| 489 | 496 | int blob_seek(Blob *p, int offset, int whence){ |
| 490 | 497 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -480,10 +480,17 @@ | |
| 480 | ** Rewind the cursor on a blob back to the beginning. |
| 481 | */ |
| 482 | void blob_rewind(Blob *p){ |
| 483 | p->iCursor = 0; |
| 484 | } |
| 485 | |
| 486 | /* |
| 487 | ** Seek the cursor in a blob to the indicated offset. |
| 488 | */ |
| 489 | int blob_seek(Blob *p, int offset, int whence){ |
| 490 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -480,10 +480,17 @@ | |
| 480 | ** Rewind the cursor on a blob back to the beginning. |
| 481 | */ |
| 482 | void blob_rewind(Blob *p){ |
| 483 | p->iCursor = 0; |
| 484 | } |
| 485 | |
| 486 | /* |
| 487 | ** Truncate a blob back to zero length |
| 488 | */ |
| 489 | void blob_truncate(Blob *p){ |
| 490 | p->nUsed = 0; |
| 491 | } |
| 492 | |
| 493 | /* |
| 494 | ** Seek the cursor in a blob to the indicated offset. |
| 495 | */ |
| 496 | int blob_seek(Blob *p, int offset, int whence){ |
| 497 |
+101
| --- src/email.c | ||
| +++ src/email.c | ||
| @@ -1393,5 +1393,106 @@ | ||
| 1393 | 1393 | email_footer(&out); |
| 1394 | 1394 | fossil_print("%s", blob_str(&out)); |
| 1395 | 1395 | blob_zero(&out); |
| 1396 | 1396 | db_end_transaction(0); |
| 1397 | 1397 | } |
| 1398 | + | |
| 1399 | +#if INTERFACE | |
| 1400 | +/* | |
| 1401 | +** Flags for email_send_alerts() | |
| 1402 | +*/ | |
| 1403 | +#define SENDALERT_DIGEST 0x0001 /* Send a digest */ | |
| 1404 | +#define SENDALERT_PRESERVE 0x0002 /* Do not mark the task as done */ | |
| 1405 | + | |
| 1406 | +#endif /* INTERFACE */ | |
| 1407 | + | |
| 1408 | +/* | |
| 1409 | +** Send alert emails to all subscribers | |
| 1410 | +*/ | |
| 1411 | +void email_send_alerts(u32 flags){ | |
| 1412 | + EmailEvent *pEvents, *p; | |
| 1413 | + int nEvent = 0; | |
| 1414 | + Stmt q; | |
| 1415 | + const char *zDigest = "false"; | |
| 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 ){ | |
| 1433 | + db_multi_exec( | |
| 1434 | + "INSERT INTO wantalert SELECT eventid FROM pending_alert" | |
| 1435 | + " WHERE sentDigest IS FALSE" | |
| 1436 | + ); | |
| 1437 | + zDigest = "true"; | |
| 1438 | + }else{ | |
| 1439 | + db_multi_exec( | |
| 1440 | + "INSERT INTO wantalert SELECT eventid FROM pending_alert" | |
| 1441 | + " WHERE sentSep IS FALSE" | |
| 1442 | + ); | |
| 1443 | + } | |
| 1444 | + pEvents = email_compute_event_text(&nEvent); | |
| 1445 | + if( nEvent==0 ) return; | |
| 1446 | + blob_init(&hdr, 0, 0); | |
| 1447 | + blob_init(&body, 0, 0); | |
| 1448 | + db_prepare(&q, | |
| 1449 | + "SELECT" | |
| 1450 | + " subscriberCode," /* 0 */ | |
| 1451 | + " semail," /* 1 */ | |
| 1452 | + " ssub" /* 2 */ | |
| 1453 | + " FROM subscriber" | |
| 1454 | + " WHERE sverified AND NOT sdonotcall" | |
| 1455 | + " AND sdigest IS %s", | |
| 1456 | + zDigest/*safe-for-%s*/ | |
| 1457 | + ); | |
| 1458 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 1459 | + const char *zCode = db_column_text(&q, 0); | |
| 1460 | + const char *zSub = db_column_text(&q, 2); | |
| 1461 | + const char *zEmail = db_column_text(&q, 1); | |
| 1462 | + int nHit = 0; | |
| 1463 | + for(p=pEvents; p; p=p->pNext){ | |
| 1464 | + if( strchr(zSub,p->type)==0 ) continue; | |
| 1465 | + if( nHit==0 ){ | |
| 1466 | + blob_appendf(&hdr,"To: %s\n", zEmail); | |
| 1467 | + blob_appendf(&hdr,"From: %s\n", zFrom); | |
| 1468 | + blob_appendf(&hdr,"Subject: %s activity alert\n", zRepoName); | |
| 1469 | + blob_appendf(&body, | |
| 1470 | + "This is an automated email sent by the Fossil repository " | |
| 1471 | + "at %s to alert you to changes.\n", | |
| 1472 | + zUrl | |
| 1473 | + ); | |
| 1474 | + } | |
| 1475 | + nHit++; | |
| 1476 | + blob_append(&body, "\n", 1); | |
| 1477 | + blob_append(&body, blob_buffer(&p->txt), blob_size(&p->txt)); | |
| 1478 | + } | |
| 1479 | + if( nHit==0 ) continue; | |
| 1480 | + blob_appendf(&body,"\n%.72c\nSubscription info: %s/alerts/%s\n", | |
| 1481 | + '-', zUrl, zCode); | |
| 1482 | + email_send(&hdr,&body,0,0); | |
| 1483 | + blob_truncate(&hdr); | |
| 1484 | + blob_truncate(&body); | |
| 1485 | + } | |
| 1486 | + blob_zero(&hdr); | |
| 1487 | + blob_zero(&body); | |
| 1488 | + db_finalize(&q); | |
| 1489 | + email_free_eventlist(pEvents); | |
| 1490 | + if( (flags & SENDALERT_PRESERVE)==0 ){ | |
| 1491 | + if( flags & SENDALERT_DIGEST ){ | |
| 1492 | + db_multi_exec("UPDATE pending_alert SET sentDigest=true"); | |
| 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 | +} | |
| 1398 | 1499 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1393,5 +1393,106 @@ | |
| 1393 | email_footer(&out); |
| 1394 | fossil_print("%s", blob_str(&out)); |
| 1395 | blob_zero(&out); |
| 1396 | db_end_transaction(0); |
| 1397 | } |
| 1398 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1393,5 +1393,106 @@ | |
| 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 | */ |
| 1403 | #define SENDALERT_DIGEST 0x0001 /* Send a digest */ |
| 1404 | #define SENDALERT_PRESERVE 0x0002 /* Do not mark the task as done */ |
| 1405 | |
| 1406 | #endif /* INTERFACE */ |
| 1407 | |
| 1408 | /* |
| 1409 | ** Send alert emails to all subscribers |
| 1410 | */ |
| 1411 | void email_send_alerts(u32 flags){ |
| 1412 | EmailEvent *pEvents, *p; |
| 1413 | int nEvent = 0; |
| 1414 | Stmt q; |
| 1415 | const char *zDigest = "false"; |
| 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 ){ |
| 1433 | db_multi_exec( |
| 1434 | "INSERT INTO wantalert SELECT eventid FROM pending_alert" |
| 1435 | " WHERE sentDigest IS FALSE" |
| 1436 | ); |
| 1437 | zDigest = "true"; |
| 1438 | }else{ |
| 1439 | db_multi_exec( |
| 1440 | "INSERT INTO wantalert SELECT eventid FROM pending_alert" |
| 1441 | " WHERE sentSep IS FALSE" |
| 1442 | ); |
| 1443 | } |
| 1444 | pEvents = email_compute_event_text(&nEvent); |
| 1445 | if( nEvent==0 ) return; |
| 1446 | blob_init(&hdr, 0, 0); |
| 1447 | blob_init(&body, 0, 0); |
| 1448 | db_prepare(&q, |
| 1449 | "SELECT" |
| 1450 | " subscriberCode," /* 0 */ |
| 1451 | " semail," /* 1 */ |
| 1452 | " ssub" /* 2 */ |
| 1453 | " FROM subscriber" |
| 1454 | " WHERE sverified AND NOT sdonotcall" |
| 1455 | " AND sdigest IS %s", |
| 1456 | zDigest/*safe-for-%s*/ |
| 1457 | ); |
| 1458 | while( db_step(&q)==SQLITE_ROW ){ |
| 1459 | const char *zCode = db_column_text(&q, 0); |
| 1460 | const char *zSub = db_column_text(&q, 2); |
| 1461 | const char *zEmail = db_column_text(&q, 1); |
| 1462 | int nHit = 0; |
| 1463 | for(p=pEvents; p; p=p->pNext){ |
| 1464 | if( strchr(zSub,p->type)==0 ) continue; |
| 1465 | if( nHit==0 ){ |
| 1466 | blob_appendf(&hdr,"To: %s\n", zEmail); |
| 1467 | blob_appendf(&hdr,"From: %s\n", zFrom); |
| 1468 | blob_appendf(&hdr,"Subject: %s activity alert\n", zRepoName); |
| 1469 | blob_appendf(&body, |
| 1470 | "This is an automated email sent by the Fossil repository " |
| 1471 | "at %s to alert you to changes.\n", |
| 1472 | zUrl |
| 1473 | ); |
| 1474 | } |
| 1475 | nHit++; |
| 1476 | blob_append(&body, "\n", 1); |
| 1477 | blob_append(&body, blob_buffer(&p->txt), blob_size(&p->txt)); |
| 1478 | } |
| 1479 | if( nHit==0 ) continue; |
| 1480 | blob_appendf(&body,"\n%.72c\nSubscription info: %s/alerts/%s\n", |
| 1481 | '-', zUrl, zCode); |
| 1482 | email_send(&hdr,&body,0,0); |
| 1483 | blob_truncate(&hdr); |
| 1484 | blob_truncate(&body); |
| 1485 | } |
| 1486 | blob_zero(&hdr); |
| 1487 | blob_zero(&body); |
| 1488 | db_finalize(&q); |
| 1489 | email_free_eventlist(pEvents); |
| 1490 | if( (flags & SENDALERT_PRESERVE)==0 ){ |
| 1491 | if( flags & SENDALERT_DIGEST ){ |
| 1492 | db_multi_exec("UPDATE pending_alert SET sentDigest=true"); |
| 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 |