217 lines
5.0 KiB
C

#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "cJSON.h"
#include "esp_spiffs.h"
#include "RemindMe.h"
#include <time.h>
static const char *TAG = "JSON_READER";
static void copy_json_string(cJSON *item,
const char *key,
char *dst,
size_t dst_size)
{
cJSON *v = cJSON_GetObjectItem(item, key);
if (cJSON_IsString(v) && v->valuestring)
{
strncpy(dst, v->valuestring, dst_size - 1);
dst[dst_size - 1] = '\0';
}
}
static RemindMeEvent *get_events_from_file(const char *filepath, int *count)
{
*count = 0;
FILE *f = fopen(filepath, "r");
if (!f)
{
ESP_LOGE(TAG, "Impossible d'ouvrir le fichier");
return NULL;
}
fseek(f, 0, SEEK_END);
long size = ftell(f);
fseek(f, 0, SEEK_SET);
char *json_string = malloc(size + 1);
if (!json_string)
{
fclose(f);
return NULL;
}
fread(json_string, 1, size, f);
fclose(f);
json_string[size] = 0;
cJSON *json = cJSON_Parse(json_string);
free(json_string);
if (!cJSON_IsArray(json))
{
cJSON_Delete(json);
return NULL;
}
int n = cJSON_GetArraySize(json);
if (n == 0)
{
cJSON_Delete(json);
return NULL;
}
RemindMeEvent *events = calloc(n, sizeof(RemindMeEvent));
if (!events)
{
cJSON_Delete(json);
return NULL;
}
for (int i = 0; i < n; i++)
{
cJSON *item = cJSON_GetArrayItem(json, i);
copy_json_string(item, "evenement", events[i].evenement, sizeof(events[i].evenement));
copy_json_string(item, "affichage", events[i].affichage, sizeof(events[i].affichage));
copy_json_string(item, "date", events[i].date, sizeof(events[i].date));
copy_json_string(item, "type", events[i].type, sizeof(events[i].type));
}
cJSON_Delete(json);
*count = n;
return events;
}
static void read_json_file(const char *filepath, cJSON **root)
{
FILE *f = fopen(filepath, "r");
if (!f)
{
ESP_LOGE(TAG, "Impossible d'ouvrir le fichier");
return;
}
fseek(f, 0, SEEK_END);
long size = ftell(f);
fseek(f, 0, SEEK_SET);
char *json_string = malloc(size + 1);
if (!json_string)
{
fclose(f);
return;
}
fread(json_string, 1, size, f);
fclose(f);
json_string[size] = 0;
*root = cJSON_Parse(json_string);
free(json_string);
}
/**
* Parse une date au format "YYYY-MM-DD" et retourne le timestamp
*/
time_t parse_date(const char *date_str)
{
struct tm tm = {0};
// Parser la date (format: YYYY-MM-DD)
sscanf(date_str, "%d-%d-%d",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
tm.tm_year -= 1900; // Années depuis 1900
tm.tm_mon -= 1; // Mois de 0 à 11
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
return mktime(&tm);
}
/**
* Calcule le nombre de jours entre maintenant et la date donnée
* Retourne un nombre négatif si la date est passée
*/
int days_until(const char *date_str)
{
// Obtenir l'heure actuelle
time_t now;
time(&now);
// Parser la date cible
time_t target = parse_date(date_str);
// Calculer la différence en secondes
double diff_seconds = difftime(target, now);
// Convertir en jours (arrondi)
int days = (int)(diff_seconds / (60 * 60 * 24));
return days;
}
RemindMeEvent *get_events(int *count)
{
RemindMeEvent *evts = get_events_from_file(
"/spiffs/events.json",
count);
for (size_t i = 0; i < *count; i++)
{
sprintf(evts[i].affichage, evts[i].affichage, days_until(evts[i].date));
}
return evts;
}
esp_err_t events_save_atomic(char *eventsJson)
{
FILE *f = fopen("/spiffs/events.tmp", "w");
if (!f)
goto error;
fwrite(eventsJson, 1, strlen(eventsJson), f);
fclose(f);
rename("/spiffs/events.json", "/spiffs/events.bak");
rename("/spiffs/events.tmp", "/spiffs/events.json");
//unlink("/spiffs/events.bak");
free(eventsJson);
return ESP_OK;
error:
free(eventsJson);
return ESP_FAIL;
}
void add_event(RemindMeEvent e){
int count=0;
cJSON *root = cJSON_CreateObject();
read_json_file("/spiffs/events.json", &root);
printf("%s","####################### AVANT\n");
//printf("%s\n",cJSON_Print(root));
if (!cJSON_IsArray(root))
{
ESP_LOGE(TAG, "'root' n'est pas un tableau");
return;
}else{
cJSON *new_event = cJSON_CreateObject();
if (!new_event)
return;
cJSON_AddStringToObject(new_event, "evenement", e.evenement);
cJSON_AddStringToObject(new_event, "affichage", e.affichage);
cJSON_AddStringToObject(new_event, "date", e.date);
cJSON_AddStringToObject(new_event, "type", e.type);
cJSON_AddItemToArray(root, new_event);
}
printf("%s", "####################### APRES\n");
//printf("%s\n", cJSON_Print(root));
char *eventsJson=cJSON_Print(root);
events_save_atomic(eventsJson);
}