98 lines
3.2 KiB
C
98 lines
3.2 KiB
C
|
|
#include "notify.h"
|
||
|
|
#include "config.h"
|
||
|
|
#include "json.h"
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <pthread.h>
|
||
|
|
|
||
|
|
Notification g_notifs[MAX_NOTIF];
|
||
|
|
int g_notif_count = 0;
|
||
|
|
int g_notif_tail = 0;
|
||
|
|
|
||
|
|
static pthread_mutex_t notif_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||
|
|
|
||
|
|
void notify_add(const char *msg, const char *type) {
|
||
|
|
pthread_mutex_lock(¬if_mutex);
|
||
|
|
Notification *nf = &g_notifs[g_notif_tail];
|
||
|
|
nf->ts = time(NULL);
|
||
|
|
strncpy(nf->type, type, sizeof(nf->type)-1);
|
||
|
|
strncpy(nf->msg, msg, sizeof(nf->msg)-1);
|
||
|
|
g_notif_tail = (g_notif_tail + 1) % MAX_NOTIF;
|
||
|
|
if (g_notif_count < MAX_NOTIF) g_notif_count++;
|
||
|
|
pthread_mutex_unlock(¬if_mutex);
|
||
|
|
notify_save();
|
||
|
|
}
|
||
|
|
|
||
|
|
void notify_save(void) {
|
||
|
|
char path[512]; config_notif_path(path, sizeof(path));
|
||
|
|
FILE *f = fopen(path, "w");
|
||
|
|
if (!f) return;
|
||
|
|
pthread_mutex_lock(¬if_mutex);
|
||
|
|
fputc('[', f);
|
||
|
|
int start = (g_notif_count < MAX_NOTIF) ? 0 : g_notif_tail;
|
||
|
|
for (int i = 0; i < g_notif_count; i++) {
|
||
|
|
Notification *n = &g_notifs[(start + i) % MAX_NOTIF];
|
||
|
|
if (i > 0) fputc(',', f);
|
||
|
|
fprintf(f, "{\"ts\":%ld,\"type\":\"%s\",\"msg\":", (long)n->ts, n->type);
|
||
|
|
fwrite_json_str(f, n->msg);
|
||
|
|
fputc('}', f);
|
||
|
|
}
|
||
|
|
fprintf(f, "]\n");
|
||
|
|
pthread_mutex_unlock(¬if_mutex);
|
||
|
|
fclose(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
void notify_load(void) {
|
||
|
|
char path[512]; config_notif_path(path, sizeof(path));
|
||
|
|
FILE *f = fopen(path, "r");
|
||
|
|
if (!f) return;
|
||
|
|
fseek(f, 0, SEEK_END); long sz = ftell(f); fseek(f, 0, SEEK_SET);
|
||
|
|
char *buf = malloc(sz + 1);
|
||
|
|
if (!buf) { fclose(f); return; }
|
||
|
|
fread(buf, 1, sz, f); buf[sz] = 0; fclose(f);
|
||
|
|
int n; char **arr = json_array(buf, &n);
|
||
|
|
free(buf);
|
||
|
|
if (!arr) return;
|
||
|
|
for (int i = 0; i < n; i++) {
|
||
|
|
char *ts_s = json_str(arr[i], "ts");
|
||
|
|
char *type = json_str(arr[i], "type");
|
||
|
|
char *msg = json_str(arr[i], "msg");
|
||
|
|
if (ts_s && type && msg) {
|
||
|
|
Notification *nf = &g_notifs[g_notif_tail];
|
||
|
|
nf->ts = (time_t)atol(ts_s);
|
||
|
|
strncpy(nf->type, type, sizeof(nf->type)-1);
|
||
|
|
strncpy(nf->msg, msg, sizeof(nf->msg)-1);
|
||
|
|
g_notif_tail = (g_notif_tail + 1) % MAX_NOTIF;
|
||
|
|
if (g_notif_count < MAX_NOTIF) g_notif_count++;
|
||
|
|
}
|
||
|
|
free(ts_s); free(type); free(msg); free(arr[i]);
|
||
|
|
}
|
||
|
|
free(arr);
|
||
|
|
fprintf(stderr, "iptv-dl: loaded %d notifications\n", g_notif_count);
|
||
|
|
}
|
||
|
|
|
||
|
|
int notify_dismiss(time_t ts) {
|
||
|
|
pthread_mutex_lock(¬if_mutex);
|
||
|
|
int start = (g_notif_count < MAX_NOTIF) ? 0 : g_notif_tail;
|
||
|
|
int found = 0;
|
||
|
|
for (int i = 0; i < g_notif_count; i++) {
|
||
|
|
int idx = (start + i) % MAX_NOTIF;
|
||
|
|
if (g_notifs[idx].ts == ts) {
|
||
|
|
for (int j = i; j < g_notif_count - 1; j++) {
|
||
|
|
int cur = (start + j) % MAX_NOTIF;
|
||
|
|
int nxt = (start + j + 1) % MAX_NOTIF;
|
||
|
|
g_notifs[cur] = g_notifs[nxt];
|
||
|
|
}
|
||
|
|
g_notif_count--;
|
||
|
|
if (g_notif_tail == 0) g_notif_tail = MAX_NOTIF - 1;
|
||
|
|
else g_notif_tail--;
|
||
|
|
found = 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
pthread_mutex_unlock(¬if_mutex);
|
||
|
|
if (found) notify_save();
|
||
|
|
return found;
|
||
|
|
}
|