217 lines
5.0 KiB
C
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);
|
|
}
|