first commit
This commit is contained in:
commit
3696ca684f
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
takl.sqlite3
|
||||||
|
takl
|
||||||
|
|
||||||
|
out
|
||||||
|
.vscode
|
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FLAGS = -g -Wall -Wextra -lsqlite3
|
||||||
|
LD_FLAGS =
|
||||||
|
|
||||||
|
|
||||||
|
$(shell mkdir -p out)
|
||||||
|
|
||||||
|
|
||||||
|
out/%.o: src/%.c
|
||||||
|
$(CC) -c $(FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
out/%.o: src/%.cpp
|
||||||
|
$(CXX) -c $(FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
takl: out/main.o out/db.o out/tasks.o
|
||||||
|
$(CXX) $(FLAGS) $(LD_FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm out -r
|
||||||
|
rm ./takl
|
140
src/db.c
Normal file
140
src/db.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
Fonctions d'interaction avec la base de données
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "include/colors.h"
|
||||||
|
#include "include/config.h"
|
||||||
|
#include "include/struct.h"
|
||||||
|
|
||||||
|
|
||||||
|
sqlite3* get_db() {
|
||||||
|
sqlite3* db;
|
||||||
|
|
||||||
|
if (access(DB_FILE, F_OK) != 0) {
|
||||||
|
// Create DB
|
||||||
|
sqlite3_open(DB_FILE, &db);
|
||||||
|
|
||||||
|
char* zErrMsg = NULL;
|
||||||
|
int ret = sqlite3_exec(
|
||||||
|
db,
|
||||||
|
"CREATE TABLE tasks ( \
|
||||||
|
id INTEGER PRIMARY KEY,\
|
||||||
|
text TEXT NOT NULL,\
|
||||||
|
done INTEGER, \
|
||||||
|
due_to INTEGER \
|
||||||
|
);",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zErrMsg
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "(db creation) SQL error: %s\n", zErrMsg);
|
||||||
|
sqlite3_free(zErrMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
printf(GREEN "OK" RESET " Base de données créée\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = sqlite3_open(DB_FILE, &db);
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "(get_db) Unable to open db\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int add_task(task_t t) { //TODO
|
||||||
|
sqlite3* db = get_db();
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
|
(void)t;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int update_task(task_t t) { //TODO
|
||||||
|
(void)t;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void get_task(int id, task_t* t) {
|
||||||
|
sqlite3* db = get_db();
|
||||||
|
sqlite3_stmt* stmt;
|
||||||
|
|
||||||
|
int ret = sqlite3_prepare_v2(db, "SELECT id, text, done, due_to FROM tasks WHERE id=?1;", -1, &stmt, 0);
|
||||||
|
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
printf("(get_task) failure fetching data\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char str_id[10];
|
||||||
|
sprintf(str_id, "%d", id);
|
||||||
|
sqlite3_bind_text(stmt, 1, str_id, -1, SQLITE_STATIC);
|
||||||
|
|
||||||
|
ret = sqlite3_step(stmt);
|
||||||
|
if (ret == SQLITE_ROW) {
|
||||||
|
t->id = strtol((char*)sqlite3_column_text(stmt, 0), NULL, 10);
|
||||||
|
t->done = strtol((char*)sqlite3_column_text(stmt, 2), NULL, 10);
|
||||||
|
t->due_to = strtol((char*)sqlite3_column_text(stmt, 3), NULL, 10);
|
||||||
|
|
||||||
|
char* text = (char*)sqlite3_column_text(stmt, 1);
|
||||||
|
t->text = malloc(sizeof(char)*(strlen(text)+1));
|
||||||
|
strcpy(t->text, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
// t.id will be (-1) if not found
|
||||||
|
}
|
||||||
|
|
||||||
|
int list_tasks() {
|
||||||
|
sqlite3* db = get_db();
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
|
int ret = sqlite3_prepare_v2(db, "SELECT id, text, done, due_to FROM tasks;", -1, &stmt, NULL);
|
||||||
|
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
printf("(get_task) failure fetching data\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
task_t t;
|
||||||
|
|
||||||
|
t.id = strtol((char*)sqlite3_column_text(stmt, 0), NULL, 10);
|
||||||
|
t.text = (char*)sqlite3_column_text(stmt, 1);
|
||||||
|
t.done = strtol((char*)sqlite3_column_text(stmt, 2), NULL, 10);
|
||||||
|
t.due_to = strtol((char*)sqlite3_column_text(stmt, 3), NULL, 10);
|
||||||
|
//* Warning: t just lives here (particularly t.text)
|
||||||
|
|
||||||
|
if (t.done) {
|
||||||
|
printf(BOLD GREEN);
|
||||||
|
} else {
|
||||||
|
printf(BOLD YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[%d]" RESET " %s\n", t.id, t.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_new_task_id() {
|
||||||
|
return rand()%10000;
|
||||||
|
}
|
15
src/include/colors.h
Normal file
15
src/include/colors.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef DEF_COLORS_H
|
||||||
|
#define DEF_COLORS_H
|
||||||
|
|
||||||
|
#define RESET "\033[0m"
|
||||||
|
#define BLACK "\033[30m" /* Black */
|
||||||
|
#define RED "\033[31m" /* Red */
|
||||||
|
#define GREEN "\033[32m" /* Green */
|
||||||
|
#define YELLOW "\033[33m" /* Yellow */
|
||||||
|
#define BLUE "\033[34m" /* Blue */
|
||||||
|
#define MAGENTA "\033[35m" /* Magenta */
|
||||||
|
#define CYAN "\033[36m" /* Cyan */
|
||||||
|
#define WHITE "\033[37m" /* White */
|
||||||
|
#define BOLD "\033[1m" /* BOLD */
|
||||||
|
|
||||||
|
#endif
|
7
src/include/config.h
Normal file
7
src/include/config.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef DEF_CONFIG_H
|
||||||
|
#define DEF_CONFIG_H
|
||||||
|
|
||||||
|
#define VERSION "0.0.0"
|
||||||
|
#define DB_FILE "takl.sqlite3"
|
||||||
|
|
||||||
|
#endif
|
46
src/include/db.h
Normal file
46
src/include/db.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
#ifndef DEF_DB_H
|
||||||
|
#define DEF_DB_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
Création de la base de données
|
||||||
|
Arrête le programme en cas d'échec
|
||||||
|
*/
|
||||||
|
void create_db();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ajouter une tâche à la base de données.
|
||||||
|
Le numéro de tâche ne doit pas déjà être utilisé
|
||||||
|
Renvoie 0 si il n'y a pas d'erreur
|
||||||
|
*/
|
||||||
|
int add_task(task_t t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mettre à jour une tâche
|
||||||
|
*/
|
||||||
|
int update_task(task_t t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copie la tâche [id] dans *t si elle existe
|
||||||
|
*/
|
||||||
|
void get_task(int id, task_t* t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Liste les tâches dans un format prédéfini
|
||||||
|
*/
|
||||||
|
int list_tasks();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Renvoie un identifiant de tâche encore non utilisé
|
||||||
|
*/
|
||||||
|
int get_new_task_id();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
15
src/include/struct.h
Normal file
15
src/include/struct.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifndef DEF_STRUCT_H
|
||||||
|
#define DEF_STRUCT_H
|
||||||
|
|
||||||
|
struct task {
|
||||||
|
int id;
|
||||||
|
char* text;
|
||||||
|
bool done;
|
||||||
|
time_t due_to;
|
||||||
|
};
|
||||||
|
typedef struct task task_t;
|
||||||
|
|
||||||
|
#endif
|
10
src/include/tasks.h
Normal file
10
src/include/tasks.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
#ifndef DEF_TASKS_H
|
||||||
|
#define DEF_TASKS_H
|
||||||
|
|
||||||
|
task_t create_task(char* text, time_t due_to);
|
||||||
|
void print_task(task_t task);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
145
src/main.c
Normal file
145
src/main.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "include/colors.h"
|
||||||
|
#include "include/config.h"
|
||||||
|
#include "include/tasks.h"
|
||||||
|
#include "include/db.h"
|
||||||
|
|
||||||
|
void help(char* name) {
|
||||||
|
printf(BLUE "\t-- TaKl " VERSION " --\n" RESET);
|
||||||
|
printf("Utilisation: %s ( list | info | add | rm | done )\n", name);
|
||||||
|
printf("\tadd <task> [date]\n");
|
||||||
|
printf("\tFormat de la date:\n");
|
||||||
|
printf("\t\tRelatif: min+%%d, h+%%d, j+%%d\n");
|
||||||
|
printf("\t\tAbsolu: dd/mm (pas de changement d'année pour l'instant\n");
|
||||||
|
printf("\tinfo <id>\n");
|
||||||
|
printf("\tdone <id>\n");
|
||||||
|
printf("\trm <id>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_t parseDateTime(const char* input) {
|
||||||
|
struct tm date = {0}; // Initialize with zeros
|
||||||
|
|
||||||
|
// Get current time
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm* current_time = localtime(&now);
|
||||||
|
|
||||||
|
// Copy current time to 'date' structure
|
||||||
|
date.tm_year = current_time->tm_year;
|
||||||
|
date.tm_mon = current_time->tm_mon;
|
||||||
|
date.tm_mday = current_time->tm_mday;
|
||||||
|
date.tm_hour = current_time->tm_hour;
|
||||||
|
date.tm_min = current_time->tm_min;
|
||||||
|
date.tm_sec = current_time->tm_sec;
|
||||||
|
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
// Accepted formats: min+%d, h+%d, j+%d
|
||||||
|
if (sscanf(input, "min+%d", &offset)) {
|
||||||
|
date.tm_min += offset;
|
||||||
|
return mktime(&date);
|
||||||
|
} else if (sscanf(input, "h+%d", &offset)) {
|
||||||
|
date.tm_hour += offset;
|
||||||
|
return mktime(&date);
|
||||||
|
} else if (sscanf(input, "j+%d", &offset)) {
|
||||||
|
date.tm_mday += offset;
|
||||||
|
return mktime(&date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the input format is "dd/mm"
|
||||||
|
if (sscanf(input, "%d/%d", &date.tm_mday, &date.tm_mon) == 2) {
|
||||||
|
// Set the year to the current year
|
||||||
|
date.tm_year = current_time->tm_year;
|
||||||
|
// Adjust month and day values to be zero-based
|
||||||
|
date.tm_hour = 0;
|
||||||
|
date.tm_min = 0;
|
||||||
|
date.tm_sec = 0;
|
||||||
|
// Convert 'date' structure to 'time_t' value
|
||||||
|
return mktime(&date);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; // Return an error value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int add(int argc, char* argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
printf(BOLD YELLOW "Argument manquant\n" RESET);
|
||||||
|
help(argv[0]);
|
||||||
|
return 1; // TODO: trouver le bon code d'erreur
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t due_to = 0;
|
||||||
|
if (argc > 3) {
|
||||||
|
due_to = parseDateTime(argv[3]);
|
||||||
|
|
||||||
|
if (due_to == -1) {
|
||||||
|
printf(BOLD YELLOW "Échéance invalide, la tâche sera créé sans échéance.\n" RESET);
|
||||||
|
due_to = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task_t t = create_task(argv[2], due_to);
|
||||||
|
|
||||||
|
if (add_task(t) != 0) {
|
||||||
|
printf("Erreur lors de l'ajout à la base de données\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(BOLD YELLOW "[%d]" RESET " ajoutée\n", t.id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int info(int argc, char* argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
printf(BOLD YELLOW "Argument manquant\n" RESET);
|
||||||
|
help(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = strtol(argv[2], NULL, 10);
|
||||||
|
|
||||||
|
task_t t;
|
||||||
|
t.id = -1;
|
||||||
|
get_task(id, &t);
|
||||||
|
|
||||||
|
if (t.id == -1) {
|
||||||
|
printf(BOLD YELLOW "Tâche inexistante. Vérifiez que l'identifiant est bien correct\n" RESET);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_task(t);
|
||||||
|
|
||||||
|
free(t.text);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc <= 1) {
|
||||||
|
help(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "add")) {
|
||||||
|
return add(argc, argv);
|
||||||
|
} else if (!strcmp(argv[1], "list")) {
|
||||||
|
return list_tasks();
|
||||||
|
} else if (!strcmp(argv[1], "info")) {
|
||||||
|
return info(argc, argv);
|
||||||
|
} else if (!strcmp(argv[1], "done")) { //TODO
|
||||||
|
printf("Not Implemented\n");
|
||||||
|
return 1;
|
||||||
|
} else if (!strcmp(argv[1], "rm")) { //TODO
|
||||||
|
printf("Not Implemented\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(YELLOW "Option invalide " BOLD "%s\n" RESET, argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
46
src/tasks.cpp
Normal file
46
src/tasks.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Fonctions de création/ modification d'objet tâches
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "include/db.h"
|
||||||
|
#include "include/struct.h"
|
||||||
|
#include "include/colors.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
task_t create_task(char* text, time_t due_to) {
|
||||||
|
task_t task;
|
||||||
|
|
||||||
|
task.id = get_new_task_id();
|
||||||
|
task.text = text;
|
||||||
|
task.done = false;
|
||||||
|
task.due_to = due_to;
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void print_task(task_t task) {
|
||||||
|
printf(YELLOW "=== Tâche " BOLD "[%d]" RESET YELLOW " ===\n" RESET, task.id);
|
||||||
|
printf(BOLD "%s\n" RESET, task.text);
|
||||||
|
|
||||||
|
printf("Statut: ");
|
||||||
|
if (task.done) {
|
||||||
|
printf(GREEN "Complétée\n" RESET);
|
||||||
|
} else {
|
||||||
|
printf(BLUE "À faire\n" RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task.due_to != 0) {
|
||||||
|
struct tm * timeinfo;
|
||||||
|
char buffer[80];
|
||||||
|
|
||||||
|
timeinfo = localtime(&task.due_to);
|
||||||
|
|
||||||
|
strftime(buffer,sizeof(buffer),"%d-%m-%Y %H:%M:%S",timeinfo);
|
||||||
|
|
||||||
|
printf("Dûe le %s\n", buffer);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user