Fossil SCM

Rearrange some of the subcommands on "fossil alerts" for better UX. Fix a problem in the /webmail display for messages with no subject. Improved comments.

drh 2018-08-06 19:39 UTC failed-fix
Commit 81c254311e5b812bc392b413990e0a745c83f3d6fb014c536b828e939bd382ab
2 files changed +88 -64 +2 -1
+88 -64
--- src/email.c
+++ src/email.c
@@ -806,42 +806,42 @@
806806
**
807807
** Usage: %fossil alerts SUBCOMMAND ARGS...
808808
**
809809
** Subcommands:
810810
**
811
-** exec Compose and send pending email alerts.
811
+** pending Show all pending alerts. Useful for debugging.
812
+**
813
+** reset Hard reset of all email notification tables
814
+** in the repository. This erases all subscription
815
+** information. ** Use with extreme care **
816
+**
817
+** send Compose and send pending email alerts.
812818
** Some installations may want to do this via
813819
** a cron-job to make sure alerts are sent
814820
** in a timely manner.
815821
** Options:
816822
**
817823
** --digest Send digests
818
-** --test Resets to standard output
819
-**
820
-** pending Show all pending alerts. Useful for debugging.
821
-**
822
-** reset Hard reset of all email notification tables
823
-** in the repository. This erases all subscription
824
-** information. Use with extreme care.
825
-**
826
-** send TO [OPTIONS] Send a single email message using whatever
827
-** email sending mechanism is currently configured.
828
-** Use this for testing the email configuration.
829
-** Options:
830
-**
831
-** --body FILENAME
832
-** --smtp-trace
833
-** --stdout
834
-** --subject|-S SUBJECT
824
+** --test Write to standard output
835825
**
836826
** settings [NAME VALUE] With no arguments, list all email settings.
837827
** Or change the value of a single email setting.
838828
**
839829
** status Report on the status of the email alert
840830
** subsystem
841831
**
842832
** subscribers [PATTERN] List all subscribers matching PATTERN.
833
+**
834
+** test-message TO [OPTS] Send a single email message using whatever
835
+** email sending mechanism is currently configured.
836
+** Use this for testing the email notification
837
+** configuration. Options:
838
+**
839
+** --body FILENAME
840
+** --smtp-trace
841
+** --stdout
842
+** --subject|-S SUBJECT
843843
**
844844
** unsubscribe EMAIL Remove a single subscriber with the given EMAIL.
845845
*/
846846
void email_cmd(void){
847847
const char *zCmd;
@@ -848,19 +848,10 @@
848848
int nCmd;
849849
db_find_and_open_repository(0, 0);
850850
email_schema(0);
851851
zCmd = g.argc>=3 ? g.argv[2] : "x";
852852
nCmd = (int)strlen(zCmd);
853
- if( strncmp(zCmd, "exec", nCmd)==0 ){
854
- u32 eFlags = 0;
855
- if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
856
- if( find_option("test",0,0)!=0 ){
857
- eFlags |= SENDALERT_PRESERVE|SENDALERT_STDOUT;
858
- }
859
- verify_all_options();
860
- email_send_alerts(eFlags);
861
- }else
862853
if( strncmp(zCmd, "pending", nCmd)==0 ){
863854
Stmt q;
864855
verify_all_options();
865856
if( g.argc!=3 ) usage("pending");
866857
db_prepare(&q,"SELECT eventid, sentSep, sentDigest, sentMod"
@@ -902,43 +893,17 @@
902893
);
903894
email_schema(0);
904895
}
905896
}else
906897
if( strncmp(zCmd, "send", nCmd)==0 ){
907
- Blob prompt, body, hdr;
908
- const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
909
- int i;
910
- u32 mFlags = EMAIL_IMMEDIATE_FAIL;
911
- const char *zSubject = find_option("subject", "S", 1);
912
- const char *zSource = find_option("body", 0, 1);
913
- EmailSender *pSender;
914
- if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_TRACE;
898
+ u32 eFlags = 0;
899
+ if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
900
+ if( find_option("test",0,0)!=0 ){
901
+ eFlags |= SENDALERT_PRESERVE|SENDALERT_STDOUT;
902
+ }
915903
verify_all_options();
916
- blob_init(&prompt, 0, 0);
917
- blob_init(&body, 0, 0);
918
- blob_init(&hdr, 0, 0);
919
- blob_appendf(&hdr,"To: ");
920
- for(i=3; i<g.argc; i++){
921
- if( i>3 ) blob_append(&hdr, ", ", 2);
922
- blob_appendf(&hdr, "<%s>", g.argv[i]);
923
- }
924
- blob_append(&hdr,"\r\n",2);
925
- if( zSubject ){
926
- blob_appendf(&hdr, "Subject: %s\r\n", zSubject);
927
- }
928
- if( zSource ){
929
- blob_read_from_file(&body, zSource, ExtFILE);
930
- }else{
931
- prompt_for_user_comment(&body, &prompt);
932
- }
933
- blob_add_final_newline(&body);
934
- pSender = email_sender_new(zDest, mFlags);
935
- email_send(pSender, &hdr, &body);
936
- email_sender_free(pSender);
937
- blob_reset(&hdr);
938
- blob_reset(&body);
939
- blob_reset(&prompt);
904
+ email_send_alerts(eFlags);
940905
}else
941906
if( strncmp(zCmd, "settings", nCmd)==0 ){
942907
int isGlobal = find_option("global",0,0)!=0;
943908
int nSetting;
944909
const Setting *pSetting = setting_info(&nSetting);
@@ -959,11 +924,10 @@
959924
if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
960925
print_setting(pSetting);
961926
}
962927
}else
963928
if( strncmp(zCmd, "status", nCmd)==0 ){
964
- int isGlobal = find_option("global",0,0)!=0;
965929
int nSetting, n;
966930
static const char *zFmt = "%-29s %d\n";
967931
const Setting *pSetting = setting_info(&nSetting);
968932
db_open_config(1, 0);
969933
verify_all_options();
@@ -1002,19 +966,55 @@
1002966
}
1003967
while( db_step(&q)==SQLITE_ROW ){
1004968
fossil_print("%s\n", db_column_text(&q, 0));
1005969
}
1006970
db_finalize(&q);
971
+ }else
972
+ if( strncmp(zCmd, "test-message", nCmd)==0 ){
973
+ Blob prompt, body, hdr;
974
+ const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
975
+ int i;
976
+ u32 mFlags = EMAIL_IMMEDIATE_FAIL;
977
+ const char *zSubject = find_option("subject", "S", 1);
978
+ const char *zSource = find_option("body", 0, 1);
979
+ EmailSender *pSender;
980
+ if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_TRACE;
981
+ verify_all_options();
982
+ blob_init(&prompt, 0, 0);
983
+ blob_init(&body, 0, 0);
984
+ blob_init(&hdr, 0, 0);
985
+ blob_appendf(&hdr,"To: ");
986
+ for(i=3; i<g.argc; i++){
987
+ if( i>3 ) blob_append(&hdr, ", ", 2);
988
+ blob_appendf(&hdr, "<%s>", g.argv[i]);
989
+ }
990
+ blob_append(&hdr,"\r\n",2);
991
+ if( zSubject ){
992
+ blob_appendf(&hdr, "Subject: %s\r\n", zSubject);
993
+ }
994
+ if( zSource ){
995
+ blob_read_from_file(&body, zSource, ExtFILE);
996
+ }else{
997
+ prompt_for_user_comment(&body, &prompt);
998
+ }
999
+ blob_add_final_newline(&body);
1000
+ pSender = email_sender_new(zDest, mFlags);
1001
+ email_send(pSender, &hdr, &body);
1002
+ email_sender_free(pSender);
1003
+ blob_reset(&hdr);
1004
+ blob_reset(&body);
1005
+ blob_reset(&prompt);
10071006
}else
10081007
if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){
10091008
verify_all_options();
10101009
if( g.argc!=4 ) usage("unsubscribe EMAIL");
10111010
db_multi_exec(
10121011
"DELETE FROM subscriber WHERE semail=%Q", g.argv[3]);
10131012
}else
10141013
{
1015
- usage("exec|pending|reset|send|setting|status|subscribers|unsubscribe");
1014
+ usage("pending|reset|send|setting|status|"
1015
+ "subscribers|test-message|unsubscribe");
10161016
}
10171017
}
10181018
10191019
/*
10201020
** Do error checking on a submitted subscription form. Return TRUE
@@ -1971,12 +1971,12 @@
19711971
**
19721972
** Add one or more events to the pending_alert queue. Use this
19731973
** command during testing to force email notifications for specific
19741974
** events.
19751975
**
1976
-** EVENTIDs are text. The first character is 'c', 'w', or 't'
1977
-** for check-in, wiki, or ticket. The remaining text is a
1976
+** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w'
1977
+** for check-in, forum, ticket, or wiki. The remaining text is a
19781978
** integer that references the EVENT.OBJID value for the event.
19791979
** Run /timeline?showid to see these OBJID values.
19801980
**
19811981
** If the --backoffice option is included, then email_backoffice() is run
19821982
** after all alerts have been added. This will cause the alerts to
@@ -2008,11 +2008,35 @@
20082008
#define SENDALERT_TRACE 0x0008 /* Trace operation for debugging */
20092009
20102010
#endif /* INTERFACE */
20112011
20122012
/*
2013
-** Send alert emails to all subscribers.
2013
+** Send alert emails to subscribers.
2014
+**
2015
+** This procedure is run by either the backoffice, or in response to the
2016
+** "fossil alerts send" command. Details of operation are controlled by
2017
+** the flags parameter.
2018
+**
2019
+** Here is a summary of what happens:
2020
+**
2021
+** (1) Create a TEMP table wantalert(eventId,needMod) and fill it with
2022
+** all the events that we want to send alerts about. The needMod
2023
+** flags is set if and only if the event is still awaiting
2024
+** moderator approval. Events with the needMod flag are only
2025
+** shown to users that have moderator privileges.
2026
+**
2027
+** (2) Call email_compute_event_text() to compute a list of EmailEvent
2028
+** objects that describe all events about which we want to send
2029
+** alerts.
2030
+**
2031
+** (3) Loop over all subscribers. Compose and send one or more email
2032
+** messages to each subscriber that describe the events for
2033
+** which the subscriber has expressed interest and has
2034
+** appropriate privileges.
2035
+**
2036
+** (4) Update the pending_alerts table to indicate that alerts have been
2037
+** sent.
20142038
*/
20152039
void email_send_alerts(u32 flags){
20162040
EmailEvent *pEvents, *p;
20172041
int nEvent = 0;
20182042
Stmt q;
20192043
--- src/email.c
+++ src/email.c
@@ -806,42 +806,42 @@
806 **
807 ** Usage: %fossil alerts SUBCOMMAND ARGS...
808 **
809 ** Subcommands:
810 **
811 ** exec Compose and send pending email alerts.
 
 
 
 
 
 
812 ** Some installations may want to do this via
813 ** a cron-job to make sure alerts are sent
814 ** in a timely manner.
815 ** Options:
816 **
817 ** --digest Send digests
818 ** --test Resets to standard output
819 **
820 ** pending Show all pending alerts. Useful for debugging.
821 **
822 ** reset Hard reset of all email notification tables
823 ** in the repository. This erases all subscription
824 ** information. Use with extreme care.
825 **
826 ** send TO [OPTIONS] Send a single email message using whatever
827 ** email sending mechanism is currently configured.
828 ** Use this for testing the email configuration.
829 ** Options:
830 **
831 ** --body FILENAME
832 ** --smtp-trace
833 ** --stdout
834 ** --subject|-S SUBJECT
835 **
836 ** settings [NAME VALUE] With no arguments, list all email settings.
837 ** Or change the value of a single email setting.
838 **
839 ** status Report on the status of the email alert
840 ** subsystem
841 **
842 ** subscribers [PATTERN] List all subscribers matching PATTERN.
 
 
 
 
 
 
 
 
 
 
843 **
844 ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL.
845 */
846 void email_cmd(void){
847 const char *zCmd;
@@ -848,19 +848,10 @@
848 int nCmd;
849 db_find_and_open_repository(0, 0);
850 email_schema(0);
851 zCmd = g.argc>=3 ? g.argv[2] : "x";
852 nCmd = (int)strlen(zCmd);
853 if( strncmp(zCmd, "exec", nCmd)==0 ){
854 u32 eFlags = 0;
855 if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
856 if( find_option("test",0,0)!=0 ){
857 eFlags |= SENDALERT_PRESERVE|SENDALERT_STDOUT;
858 }
859 verify_all_options();
860 email_send_alerts(eFlags);
861 }else
862 if( strncmp(zCmd, "pending", nCmd)==0 ){
863 Stmt q;
864 verify_all_options();
865 if( g.argc!=3 ) usage("pending");
866 db_prepare(&q,"SELECT eventid, sentSep, sentDigest, sentMod"
@@ -902,43 +893,17 @@
902 );
903 email_schema(0);
904 }
905 }else
906 if( strncmp(zCmd, "send", nCmd)==0 ){
907 Blob prompt, body, hdr;
908 const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
909 int i;
910 u32 mFlags = EMAIL_IMMEDIATE_FAIL;
911 const char *zSubject = find_option("subject", "S", 1);
912 const char *zSource = find_option("body", 0, 1);
913 EmailSender *pSender;
914 if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_TRACE;
915 verify_all_options();
916 blob_init(&prompt, 0, 0);
917 blob_init(&body, 0, 0);
918 blob_init(&hdr, 0, 0);
919 blob_appendf(&hdr,"To: ");
920 for(i=3; i<g.argc; i++){
921 if( i>3 ) blob_append(&hdr, ", ", 2);
922 blob_appendf(&hdr, "<%s>", g.argv[i]);
923 }
924 blob_append(&hdr,"\r\n",2);
925 if( zSubject ){
926 blob_appendf(&hdr, "Subject: %s\r\n", zSubject);
927 }
928 if( zSource ){
929 blob_read_from_file(&body, zSource, ExtFILE);
930 }else{
931 prompt_for_user_comment(&body, &prompt);
932 }
933 blob_add_final_newline(&body);
934 pSender = email_sender_new(zDest, mFlags);
935 email_send(pSender, &hdr, &body);
936 email_sender_free(pSender);
937 blob_reset(&hdr);
938 blob_reset(&body);
939 blob_reset(&prompt);
940 }else
941 if( strncmp(zCmd, "settings", nCmd)==0 ){
942 int isGlobal = find_option("global",0,0)!=0;
943 int nSetting;
944 const Setting *pSetting = setting_info(&nSetting);
@@ -959,11 +924,10 @@
959 if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
960 print_setting(pSetting);
961 }
962 }else
963 if( strncmp(zCmd, "status", nCmd)==0 ){
964 int isGlobal = find_option("global",0,0)!=0;
965 int nSetting, n;
966 static const char *zFmt = "%-29s %d\n";
967 const Setting *pSetting = setting_info(&nSetting);
968 db_open_config(1, 0);
969 verify_all_options();
@@ -1002,19 +966,55 @@
1002 }
1003 while( db_step(&q)==SQLITE_ROW ){
1004 fossil_print("%s\n", db_column_text(&q, 0));
1005 }
1006 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007 }else
1008 if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){
1009 verify_all_options();
1010 if( g.argc!=4 ) usage("unsubscribe EMAIL");
1011 db_multi_exec(
1012 "DELETE FROM subscriber WHERE semail=%Q", g.argv[3]);
1013 }else
1014 {
1015 usage("exec|pending|reset|send|setting|status|subscribers|unsubscribe");
 
1016 }
1017 }
1018
1019 /*
1020 ** Do error checking on a submitted subscription form. Return TRUE
@@ -1971,12 +1971,12 @@
1971 **
1972 ** Add one or more events to the pending_alert queue. Use this
1973 ** command during testing to force email notifications for specific
1974 ** events.
1975 **
1976 ** EVENTIDs are text. The first character is 'c', 'w', or 't'
1977 ** for check-in, wiki, or ticket. The remaining text is a
1978 ** integer that references the EVENT.OBJID value for the event.
1979 ** Run /timeline?showid to see these OBJID values.
1980 **
1981 ** If the --backoffice option is included, then email_backoffice() is run
1982 ** after all alerts have been added. This will cause the alerts to
@@ -2008,11 +2008,35 @@
2008 #define SENDALERT_TRACE 0x0008 /* Trace operation for debugging */
2009
2010 #endif /* INTERFACE */
2011
2012 /*
2013 ** Send alert emails to all subscribers.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2014 */
2015 void email_send_alerts(u32 flags){
2016 EmailEvent *pEvents, *p;
2017 int nEvent = 0;
2018 Stmt q;
2019
--- src/email.c
+++ src/email.c
@@ -806,42 +806,42 @@
806 **
807 ** Usage: %fossil alerts SUBCOMMAND ARGS...
808 **
809 ** Subcommands:
810 **
811 ** pending Show all pending alerts. Useful for debugging.
812 **
813 ** reset Hard reset of all email notification tables
814 ** in the repository. This erases all subscription
815 ** information. ** Use with extreme care **
816 **
817 ** send Compose and send pending email alerts.
818 ** Some installations may want to do this via
819 ** a cron-job to make sure alerts are sent
820 ** in a timely manner.
821 ** Options:
822 **
823 ** --digest Send digests
824 ** --test Write to standard output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
825 **
826 ** settings [NAME VALUE] With no arguments, list all email settings.
827 ** Or change the value of a single email setting.
828 **
829 ** status Report on the status of the email alert
830 ** subsystem
831 **
832 ** subscribers [PATTERN] List all subscribers matching PATTERN.
833 **
834 ** test-message TO [OPTS] Send a single email message using whatever
835 ** email sending mechanism is currently configured.
836 ** Use this for testing the email notification
837 ** configuration. Options:
838 **
839 ** --body FILENAME
840 ** --smtp-trace
841 ** --stdout
842 ** --subject|-S SUBJECT
843 **
844 ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL.
845 */
846 void email_cmd(void){
847 const char *zCmd;
@@ -848,19 +848,10 @@
848 int nCmd;
849 db_find_and_open_repository(0, 0);
850 email_schema(0);
851 zCmd = g.argc>=3 ? g.argv[2] : "x";
852 nCmd = (int)strlen(zCmd);
 
 
 
 
 
 
 
 
 
853 if( strncmp(zCmd, "pending", nCmd)==0 ){
854 Stmt q;
855 verify_all_options();
856 if( g.argc!=3 ) usage("pending");
857 db_prepare(&q,"SELECT eventid, sentSep, sentDigest, sentMod"
@@ -902,43 +893,17 @@
893 );
894 email_schema(0);
895 }
896 }else
897 if( strncmp(zCmd, "send", nCmd)==0 ){
898 u32 eFlags = 0;
899 if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST;
900 if( find_option("test",0,0)!=0 ){
901 eFlags |= SENDALERT_PRESERVE|SENDALERT_STDOUT;
902 }
 
 
 
903 verify_all_options();
904 email_send_alerts(eFlags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905 }else
906 if( strncmp(zCmd, "settings", nCmd)==0 ){
907 int isGlobal = find_option("global",0,0)!=0;
908 int nSetting;
909 const Setting *pSetting = setting_info(&nSetting);
@@ -959,11 +924,10 @@
924 if( strncmp(pSetting->name,"email-",6)!=0 ) continue;
925 print_setting(pSetting);
926 }
927 }else
928 if( strncmp(zCmd, "status", nCmd)==0 ){
 
929 int nSetting, n;
930 static const char *zFmt = "%-29s %d\n";
931 const Setting *pSetting = setting_info(&nSetting);
932 db_open_config(1, 0);
933 verify_all_options();
@@ -1002,19 +966,55 @@
966 }
967 while( db_step(&q)==SQLITE_ROW ){
968 fossil_print("%s\n", db_column_text(&q, 0));
969 }
970 db_finalize(&q);
971 }else
972 if( strncmp(zCmd, "test-message", nCmd)==0 ){
973 Blob prompt, body, hdr;
974 const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0;
975 int i;
976 u32 mFlags = EMAIL_IMMEDIATE_FAIL;
977 const char *zSubject = find_option("subject", "S", 1);
978 const char *zSource = find_option("body", 0, 1);
979 EmailSender *pSender;
980 if( find_option("smtp-trace",0,0)!=0 ) mFlags |= EMAIL_TRACE;
981 verify_all_options();
982 blob_init(&prompt, 0, 0);
983 blob_init(&body, 0, 0);
984 blob_init(&hdr, 0, 0);
985 blob_appendf(&hdr,"To: ");
986 for(i=3; i<g.argc; i++){
987 if( i>3 ) blob_append(&hdr, ", ", 2);
988 blob_appendf(&hdr, "<%s>", g.argv[i]);
989 }
990 blob_append(&hdr,"\r\n",2);
991 if( zSubject ){
992 blob_appendf(&hdr, "Subject: %s\r\n", zSubject);
993 }
994 if( zSource ){
995 blob_read_from_file(&body, zSource, ExtFILE);
996 }else{
997 prompt_for_user_comment(&body, &prompt);
998 }
999 blob_add_final_newline(&body);
1000 pSender = email_sender_new(zDest, mFlags);
1001 email_send(pSender, &hdr, &body);
1002 email_sender_free(pSender);
1003 blob_reset(&hdr);
1004 blob_reset(&body);
1005 blob_reset(&prompt);
1006 }else
1007 if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){
1008 verify_all_options();
1009 if( g.argc!=4 ) usage("unsubscribe EMAIL");
1010 db_multi_exec(
1011 "DELETE FROM subscriber WHERE semail=%Q", g.argv[3]);
1012 }else
1013 {
1014 usage("pending|reset|send|setting|status|"
1015 "subscribers|test-message|unsubscribe");
1016 }
1017 }
1018
1019 /*
1020 ** Do error checking on a submitted subscription form. Return TRUE
@@ -1971,12 +1971,12 @@
1971 **
1972 ** Add one or more events to the pending_alert queue. Use this
1973 ** command during testing to force email notifications for specific
1974 ** events.
1975 **
1976 ** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w'
1977 ** for check-in, forum, ticket, or wiki. The remaining text is a
1978 ** integer that references the EVENT.OBJID value for the event.
1979 ** Run /timeline?showid to see these OBJID values.
1980 **
1981 ** If the --backoffice option is included, then email_backoffice() is run
1982 ** after all alerts have been added. This will cause the alerts to
@@ -2008,11 +2008,35 @@
2008 #define SENDALERT_TRACE 0x0008 /* Trace operation for debugging */
2009
2010 #endif /* INTERFACE */
2011
2012 /*
2013 ** Send alert emails to subscribers.
2014 **
2015 ** This procedure is run by either the backoffice, or in response to the
2016 ** "fossil alerts send" command. Details of operation are controlled by
2017 ** the flags parameter.
2018 **
2019 ** Here is a summary of what happens:
2020 **
2021 ** (1) Create a TEMP table wantalert(eventId,needMod) and fill it with
2022 ** all the events that we want to send alerts about. The needMod
2023 ** flags is set if and only if the event is still awaiting
2024 ** moderator approval. Events with the needMod flag are only
2025 ** shown to users that have moderator privileges.
2026 **
2027 ** (2) Call email_compute_event_text() to compute a list of EmailEvent
2028 ** objects that describe all events about which we want to send
2029 ** alerts.
2030 **
2031 ** (3) Loop over all subscribers. Compose and send one or more email
2032 ** messages to each subscriber that describe the events for
2033 ** which the subscriber has expressed interest and has
2034 ** appropriate privileges.
2035 **
2036 ** (4) Update the pending_alerts table to indicate that alerts have been
2037 ** sent.
2038 */
2039 void email_send_alerts(u32 flags){
2040 EmailEvent *pEvents, *p;
2041 int nEvent = 0;
2042 Stmt q;
2043
+2 -1
--- src/webmail.c
+++ src/webmail.c
@@ -708,11 +708,11 @@
708708
@ <tr><td align="left">
709709
if( d==2 ){
710710
@ <input type="submit" name="read" value="Undelete">
711711
@ <input type="submit" name="purge" value="Delete Permanently">
712712
}else{
713
- @ <input type="submit" name="trash", value="Delete">
713
+ @ <input type="submit" name="trash" value="Delete">
714714
if( d!=1 ){
715715
@ <input type="submit" name="unread" value="Mark as unread">
716716
}
717717
@ <input type="submit" name="read" value="Mark as read">
718718
}
@@ -732,10 +732,11 @@
732732
while( db_step(&q)==SQLITE_ROW ){
733733
const char *zId = db_column_text(&q,0);
734734
const char *zFrom = db_column_text(&q, 1);
735735
const char *zDate = db_column_text(&q, 2);
736736
const char *zSubject = db_column_text(&q, 4);
737
+ if( zSubject==0 || zSubject[0]==0 ) zSubject = "(no subject)";
737738
@ <tr>
738739
@ <td><input type="checkbox" class="webmailckbox" name="e%s(zId)"></td>
739740
@ <td>%h(zFrom)</td>
740741
@ <td><a href="%s(url_render(&url,"id",zId,0,0))">%h(zSubject)</a> \
741742
@ %s(zDate)</td>
742743
--- src/webmail.c
+++ src/webmail.c
@@ -708,11 +708,11 @@
708 @ <tr><td align="left">
709 if( d==2 ){
710 @ <input type="submit" name="read" value="Undelete">
711 @ <input type="submit" name="purge" value="Delete Permanently">
712 }else{
713 @ <input type="submit" name="trash", value="Delete">
714 if( d!=1 ){
715 @ <input type="submit" name="unread" value="Mark as unread">
716 }
717 @ <input type="submit" name="read" value="Mark as read">
718 }
@@ -732,10 +732,11 @@
732 while( db_step(&q)==SQLITE_ROW ){
733 const char *zId = db_column_text(&q,0);
734 const char *zFrom = db_column_text(&q, 1);
735 const char *zDate = db_column_text(&q, 2);
736 const char *zSubject = db_column_text(&q, 4);
 
737 @ <tr>
738 @ <td><input type="checkbox" class="webmailckbox" name="e%s(zId)"></td>
739 @ <td>%h(zFrom)</td>
740 @ <td><a href="%s(url_render(&url,"id",zId,0,0))">%h(zSubject)</a> \
741 @ %s(zDate)</td>
742
--- src/webmail.c
+++ src/webmail.c
@@ -708,11 +708,11 @@
708 @ <tr><td align="left">
709 if( d==2 ){
710 @ <input type="submit" name="read" value="Undelete">
711 @ <input type="submit" name="purge" value="Delete Permanently">
712 }else{
713 @ <input type="submit" name="trash" value="Delete">
714 if( d!=1 ){
715 @ <input type="submit" name="unread" value="Mark as unread">
716 }
717 @ <input type="submit" name="read" value="Mark as read">
718 }
@@ -732,10 +732,11 @@
732 while( db_step(&q)==SQLITE_ROW ){
733 const char *zId = db_column_text(&q,0);
734 const char *zFrom = db_column_text(&q, 1);
735 const char *zDate = db_column_text(&q, 2);
736 const char *zSubject = db_column_text(&q, 4);
737 if( zSubject==0 || zSubject[0]==0 ) zSubject = "(no subject)";
738 @ <tr>
739 @ <td><input type="checkbox" class="webmailckbox" name="e%s(zId)"></td>
740 @ <td>%h(zFrom)</td>
741 @ <td><a href="%s(url_render(&url,"id",zId,0,0))">%h(zSubject)</a> \
742 @ %s(zDate)</td>
743

Keyboard Shortcuts

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