Add support for mail notification for local maildirs
Patch status: rejected
Patch by Timo Buhrmester
To apply this patch, use:
curl http://cr.i3wm.org/patch/670/raw.patch | git am
b/i3status.c
| 16 |
@@ -405,6 +405,18 @@ int main(int argc, char *argv[]) {
|
| 17 |
CFG_END() |
| 18 |
}; |
| 19 |
|
| 20 |
+ cfg_opt_t maildir_opts[] = {
|
| 21 |
+ CFG_STR("format", "%num new %mail", CFGF_NONE), /* format to use when there is new mail */
|
| 22 |
+ CFG_STR("format_nomail", "no mail", CFGF_NONE), /* format to use when there is NO new mail */
|
| 23 |
+ CFG_STR("path", "Maildir", CFGF_NONE), /* Path to maildir, absolute or relative to homedir */
|
| 24 |
+ CFG_STR("name", "INBOX", CFGF_NONE), /* Arbitrary name (for displaying purposes only) */
|
| 25 |
+ CFG_INT("max", 9, CFGF_NONE), /* Max. number of new mails to count (for huge maildirs) */
|
| 26 |
+ CFG_CUSTOM_ALIGN_OPT, |
| 27 |
+ CFG_CUSTOM_COLOR_OPTS, |
| 28 |
+ CFG_CUSTOM_MIN_WIDTH_OPT, |
| 29 |
+ CFG_END() |
| 30 |
+ }; |
| 31 |
+ |
| 32 |
cfg_opt_t opts[] = {
|
| 33 |
CFG_STR_LIST("order", "{}", CFGF_NONE),
|
| 34 |
CFG_SEC("general", general_opts, CFGF_NONE),
|
| 35 |
@@ -416,6 +428,7 @@ int main(int argc, char *argv[]) {
|
| 36 |
CFG_SEC("cpu_temperature", temp_opts, CFGF_TITLE | CFGF_MULTI),
|
| 37 |
CFG_SEC("disk", disk_opts, CFGF_TITLE | CFGF_MULTI),
|
| 38 |
CFG_SEC("volume", volume_opts, CFGF_TITLE | CFGF_MULTI),
|
| 39 |
+ CFG_SEC("maildir", maildir_opts, CFGF_TITLE | CFGF_MULTI),
|
| 40 |
CFG_SEC("ipv6", ipv6_opts, CFGF_NONE),
|
| 41 |
CFG_SEC("time", time_opts, CFGF_NONE),
|
| 42 |
CFG_SEC("tztime", tztime_opts, CFGF_TITLE | CFGF_MULTI),
|
| 43 |
@@ -644,6 +657,13 @@ int main(int argc, char *argv[]) {
|
| 44 |
SEC_CLOSE_MAP; |
| 45 |
} |
| 46 |
|
| 47 |
+ CASE_SEC_TITLE("maildir") {
|
| 48 |
+ SEC_OPEN_MAP("maildir");
|
| 49 |
+ print_maildir(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getstr(sec, "format_nomail"), |
| 50 |
+ cfg_getstr(sec, "path"), cfg_getstr(sec, "name"), cfg_getint(sec, "max")); |
| 51 |
+ SEC_CLOSE_MAP; |
| 52 |
+ } |
| 53 |
+ |
| 54 |
CASE_SEC_TITLE("cpu_temperature") {
|
| 55 |
SEC_OPEN_MAP("cpu_temperature");
|
| 56 |
print_cpu_temperature_info(json_gen, buffer, atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format"), cfg_getint(sec, "max_threshold")); |
b/include/i3status.h
| 61 |
@@ -184,6 +184,7 @@ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format); |
| 62 |
void print_eth_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down); |
| 63 |
void print_load(yajl_gen json_gen, char *buffer, const char *format, const float max_threshold); |
| 64 |
void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_muted, const char *device, const char *mixer, int mixer_idx); |
| 65 |
+void print_maildir(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_nomail, const char *path, const char *name, int max); |
| 66 |
bool process_runs(const char *path); |
| 67 |
|
| 68 |
/* socket file descriptor for general purposes */ |
b/src/print_maildir.c
| 74 |
@@ -0,0 +1,106 @@ |
| 75 |
+// vim:ts=8:expandtab |
| 76 |
+#include <time.h> |
| 77 |
+#include <string.h> |
| 78 |
+#include <stdbool.h> |
| 79 |
+#include <stdlib.h> |
| 80 |
+#include <stdio.h> |
| 81 |
+#include <yajl/yajl_gen.h> |
| 82 |
+#include <yajl/yajl_version.h> |
| 83 |
+ |
| 84 |
+#include <fcntl.h> |
| 85 |
+#include <unistd.h> |
| 86 |
+#include <dirent.h> |
| 87 |
+#include <pwd.h> |
| 88 |
+ |
| 89 |
+#include "i3status.h" |
| 90 |
+#include "queue.h" |
| 91 |
+ |
| 92 |
+void print_maildir(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_nomail, const char *path, const char *name, int max) {
|
| 93 |
+ char *outwalk = buffer; |
| 94 |
+ |
| 95 |
+ if (output_format == O_I3BAR) {
|
| 96 |
+ INSTANCE(path); |
| 97 |
+ } |
| 98 |
+ |
| 99 |
+ /* If `path' is relative, look up user's home dir and store in `pathpfx' */ |
| 100 |
+ char pathpfx[128]; |
| 101 |
+ if (path[0] != '/') {
|
| 102 |
+ /* path is relative, look up user's home dir */ |
| 103 |
+ struct passwd *pw = getpwuid(geteuid()); |
| 104 |
+ if (!pw) {
|
| 105 |
+ fprintf(stderr, "Failed to query user information for uid %d\n", geteuid()); |
| 106 |
+ return; |
| 107 |
+ } |
| 108 |
+ |
| 109 |
+ snprintf(pathpfx, sizeof pathpfx, "%s/", pw->pw_dir); |
| 110 |
+ } else {
|
| 111 |
+ pathpfx[0] = '\0'; |
| 112 |
+ } |
| 113 |
+ |
| 114 |
+ char fullpath[512]; /* full path to <maildir>/new */ |
| 115 |
+ snprintf(fullpath, sizeof fullpath, "%s%s/new", pathpfx, path); |
| 116 |
+ |
| 117 |
+ DIR *d = opendir(fullpath); |
| 118 |
+ if (!d) {
|
| 119 |
+ fprintf(stderr, "Failed to opendir('%s')\n", fullpath);
|
| 120 |
+ return; |
| 121 |
+ } |
| 122 |
+ |
| 123 |
+ /* Count files in 'new', but don't count more than `max' */ |
| 124 |
+ int cnt = -2; /* start w/ -2 because of . and .. */ |
| 125 |
+ bool overmax = false; |
| 126 |
+ struct dirent *de; |
| 127 |
+ while ((de = readdir(d))) {
|
| 128 |
+ if (++cnt > max && max) {
|
| 129 |
+ /* if we have a maximum, stop listing to preserve resources */ |
| 130 |
+ overmax = true; |
| 131 |
+ break; |
| 132 |
+ } |
| 133 |
+ } |
| 134 |
+ |
| 135 |
+ closedir(d); |
| 136 |
+ |
| 137 |
+ if (!cnt) {
|
| 138 |
+ fmt = fmt_nomail; |
| 139 |
+ } |
| 140 |
+ |
| 141 |
+ /* no news is good news */ |
| 142 |
+ START_COLOR(!cnt ? "color_good" : "color_bad"); |
| 143 |
+ |
| 144 |
+ const char *walk = fmt; |
| 145 |
+ for (; *walk != '\0'; walk++) {
|
| 146 |
+ if (*walk != '%') {
|
| 147 |
+ *(outwalk++) = *walk; |
| 148 |
+ continue; |
| 149 |
+ } |
| 150 |
+ |
| 151 |
+ if (BEGINS_WITH(walk+1, "%")) {
|
| 152 |
+ outwalk += sprintf(outwalk, "%%"); |
| 153 |
+ walk += strlen("%");
|
| 154 |
+ } |
| 155 |
+ |
| 156 |
+ /* %num expands to the amount of new mail |
| 157 |
+ * However, if `max' is >0, and there are more than `max' new mails, %num expands to `max'+ instead */ |
| 158 |
+ if (BEGINS_WITH(walk+1, "num")) {
|
| 159 |
+ outwalk += sprintf(outwalk, "%d%s", cnt - overmax, overmax ? "+" : ""); |
| 160 |
+ walk += strlen("num");
|
| 161 |
+ } |
| 162 |
+ |
| 163 |
+ /* %mail expands to "mail" or "mails", depending on whether we need singular or plural */ |
| 164 |
+ if (BEGINS_WITH(walk+1, "mail")) {
|
| 165 |
+ outwalk += sprintf(outwalk, "mail%s", cnt == 1 ? "" : "s"); |
| 166 |
+ walk += strlen("mail");
|
| 167 |
+ } |
| 168 |
+ |
| 169 |
+ /* %name expands to the (arbitrary) name specified for this maildir in i3status.conf */ |
| 170 |
+ if (BEGINS_WITH(walk+1, "name")) {
|
| 171 |
+ outwalk += sprintf(outwalk, "%s", name); |
| 172 |
+ walk += strlen("name");
|
| 173 |
+ } |
| 174 |
+ } |
| 175 |
+ |
| 176 |
+ *outwalk = '\0'; |
| 177 |
+ OUTPUT_FULL_TEXT(buffer); |
| 178 |
+ |
| 179 |
+ END_COLOR; |
| 180 |
+} |