diff --git a/inc/common/macro.h b/inc/common/macro.h index 99e756c10b7dc822b57e7852296c5d1944394d7a..c3175cd5a2476939b30d84436a5728675346c6c4 100644 --- a/inc/common/macro.h +++ b/inc/common/macro.h @@ -22,15 +22,15 @@ #define MIN(a, b) ((a) > (b) ? (b) : (a)) #endif /* MIN */ -#define RETURN_IF(cond, msg, ret) \ - if (cond) { \ - LOG_ERROR("", "%s", msg); \ - return ret; \ +#define RETURN_IF(cond, msg, ret) \ + if (cond) { \ + LOG_DEBUG("DEBUG", "%s", msg); \ + return ret; \ } -#define GOTO_IF(cond, msg, label) \ - if (cond) { \ - LOG_ERROR("", "%s", msg); \ - goto label; \ +#define GOTO_IF(cond, msg, label) \ + if (cond) { \ + LOG_DEBUG("DEBUG", "%s", msg); \ + goto label; \ } #define GOTO_UNLESS(cond, msg, label) GOTO_IF(!(cond), msg, label) @@ -62,10 +62,10 @@ enum log_level { __func__, \ __VA_ARGS__); \ } -#define LOG_INFO(section, format, ...) LOG(format, INFO, section, __VA_ARGS__) -#define LOG_WARN(section, format, ...) LOG(format, WARN, section, __VA_ARGS__) -#define LOG_ERROR(section, format, ...) LOG(format, ERROR, section, __VA_ARGS__) -#define LOG_DEBUG(section, format, ...) LOG(format, DEBUG, section, __VA_ARGS__) +#define LOG_INFO(section, format, ...) LOG(format, INFO, section, __VA_ARGS__) +#define LOG_WARN(section, format, ...) LOG(format, WARN, section, __VA_ARGS__) +#define LOG_ERROR(section, format, ...) LOG(format, ERROR, section, __VA_ARGS__) +#define LOG_DEBUG(section, format, ...) LOG(format, DEBUG, section, __VA_ARGS__) /* Defines for lektor */ @@ -90,7 +90,6 @@ enum log_level { #define LKT_DATABASE_NAME_KCAT "category" #define LKT_DATABASE_NAME_KTYPE "song_type" #define LKT_DATABASE_NAME_KAUTHOR "author_name" -#define LKT_DATABASE_NAME_KAUTHOR_YEAR "author_year" #define LKT_DATABASE_NAME_KLANG "language" #define LKT_DATABASE_KARA_COLUMNT_ANY "any_col" #define LKT_DATABASE_KARA_ALL "string" diff --git a/meson.build b/meson.build index 9d2322971f33735e289aff57c7ddd71b860f017b..35025c615e71dce5be66caf643af2d3a8320b8a1 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,6 @@ project( 'lektor' ) libdl = meson.get_compiler('c').find_library('dl') -librt = meson.get_compiler('c').find_library('rt') dep_x11 = dependency('x11', required: false) dep_mpv = dependency('mpv', required: false) dep_sdl = dependency('sdl2', required: false) @@ -97,7 +96,6 @@ core_deps = [ dependency('sqlite3', version: '>= 3.31.0') , dependency('libcurl', required: true) , dependency('json-c', required: true) , dependency('threads', required: true) - , librt , libdl ] diff --git a/src/common.c b/src/common.c index cc7dd77b7bc4b3fae7c0afd2112db61c8c9de9c0..bb330464876adaa5e3129c024891f2734482178b 100644 --- a/src/common.c +++ b/src/common.c @@ -138,7 +138,7 @@ get_stdin_line(const char *prompt, char *buf, size_t len) inline long get_mtime(const char *path) { - struct stat statbuf; + struct stat statbuf = {0}; return (stat(path, &statbuf) == -1) ? 0 : statbuf.st_mtime; } diff --git a/src/database/disk.sql b/src/database/disk.sql index ed2fbb8aba5f493861b13642f7ee46a14aeaa42f..d1e356f6bb2ac14244e3931dcbd3e0510d65aed9 100644 --- a/src/database/disk.sql +++ b/src/database/disk.sql @@ -16,7 +16,6 @@ CREATE TABLE IF NOT EXISTS kara , file_path TEXT NOT NULL UNIQUE , is_new INTEGER NOT NULL , author_name TEXT - , author_year INTEGER CHECK(author_year > 0) , available INTEGER CHECK(available = 0 OR available = 1) DEFAULT 1 NOT NULL , string TEXT GENERATED ALWAYS AS ( category || ' - ' || language || ' / ' || source_name || ' - ' || song_type || diff --git a/src/database/queue.c b/src/database/queue.c index a6f9e36b0ea9d7674c666192b180d15de648f752..e7815cd29e16dc1921275399283e9531bff09bcb 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -550,12 +550,14 @@ bool database_get_kara_path(volatile sqlite3 *db, int id, char filepath[PATH_MAX]) { sqlite3_stmt *stmt = NULL; - static const char *SQL = "SELECT file_path FROM kara WHERE id = ?;"; - RETURN_UNLESS(id && db && filepath, "Invalid argument", false); + static const char *SQL = "SELECT file_path FROM kara WHERE id = ? AND available = 1;"; + RETURN_UNLESS(id && db, "Invalid argument", false); SQLITE_PREPARE(db, stmt, SQL, error); SQLITE_BIND_INT(db, stmt, 1, id, error); SQLITE_STEP_ROW(db, stmt, error); - strncpy(filepath, (const char *) sqlite3_column_text(stmt, 0), PATH_MAX); + if (!filepath) + return true; + strncpy(filepath, sqlite3_column_chars(stmt, 0), PATH_MAX); filepath[PATH_MAX - 1] = '\0'; return true; error: diff --git a/src/database/update.c b/src/database/update.c index d2fe7e5f4a288e3824617e4f0ee3b1278694565b..f910b2436cd6acde69b9e24ca9687499eb0fdffe 100644 --- a/src/database/update.c +++ b/src/database/update.c @@ -26,7 +26,7 @@ __add_kara_to_update_job(volatile sqlite3 *db, size_t id) sqlite3_stmt *stmt; SQLITE_PREPARE(db, stmt, SQL, error); SQLITE_BIND_INT(db, stmt, 1, (int) id, error); - SQLITE_STEP_DONE(db, stmt, error); + sqlite3_step(stmt); /* Ignore result of that one */ return true; error: return false; @@ -39,24 +39,17 @@ __database_add_kara(volatile sqlite3 *db, const char *filename) static const char *SQL_STMT = "INSERT INTO " "kara (song_name, source_name, category, song_type, language, " - "file_path, is_new, author_name, author_year, song_number)" - "SELECT ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s','now'), ?"; + "file_path, is_new, author_name, song_number)" + "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?"; static const char *SQL_STMT_WITH_ID = "INSERT INTO " "kara (song_name, source_name, category, song_type, language, " - "file_path, is_new, author_name, author_year, song_number, id)" - "SELECT ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s','now'), ?, ?"; + "file_path, is_new, author_name, song_number, id)" + "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"; sqlite3_stmt *stmt = NULL; - long code = SQLITE_OK, status = false, kara_id = 0; + long status = false, kara_id = 0; struct kara_metadata data; - time_t the_time = time(NULL); - struct tm *the_local_time = localtime(&the_time); - char year[10], path[PATH_MAX], *saveptr = NULL, *token, *id = NULL; - - /* A timestamp */ - code = safe_snprintf(year, 10, "%d", the_local_time->tm_year + 1900); - if (code < 0 || code >= 10) - return false; + char path[PATH_MAX], *saveptr = NULL, *token, *id = NULL; /* Metadata */ if (kara_metadata_read(&data, filename) != 0) { @@ -90,7 +83,7 @@ __database_add_kara(volatile sqlite3 *db, const char *filename) (sqlite3_bind_text(stmt, 4, data.song_type, -1, 0) != SQLITE_OK) || (sqlite3_bind_text(stmt, 5, data.language, -1, 0) != SQLITE_OK) || (sqlite3_bind_text(stmt, 6, filename, -1, 0) != SQLITE_OK) || - (sqlite3_bind_int (stmt, 7, 0) != SQLITE_OK) || + (sqlite3_bind_int (stmt, 7, 0) /* TODO */ != SQLITE_OK) || (sqlite3_bind_text(stmt, 8, data.author_name, -1, 0) != SQLITE_OK) || (sqlite3_bind_int (stmt, 9, data.song_number) != SQLITE_OK) ) { @@ -136,17 +129,11 @@ database_update_add(volatile sqlite3 *db, const char *kara_path, RETURN_UNLESS(db && kara_path && mdt && id, "Invalid argument", false); static const char *SQL_STMT = "INSERT OR REPLACE INTO kara (song_name, source_name, category, " - "song_type, language, file_path, is_new, author_name, author_year, " + "song_type, language, file_path, is_new, author_name, " "song_number, id, available)" - "SELECT ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s','now'), ?, ?, ?"; + "SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"; sqlite3_stmt *stmt = NULL; - int code = SQLITE_OK, ret = false; - time_t the_time = time(NULL); - struct tm *the_local_time = localtime(&the_time); - char year[10]; - code = safe_snprintf(year, 10, "%d", the_local_time->tm_year + 1900); - if (code < 0 || code >= 10) - return false; + int ret = false; /* From here we initialize the sqlite stmt. */ @@ -158,7 +145,7 @@ database_update_add(volatile sqlite3 *db, const char *kara_path, (sqlite3_bind_text(stmt, 4, mdt->song_type, -1, 0) != SQLITE_OK) || (sqlite3_bind_text(stmt, 5, mdt->language, -1, 0) != SQLITE_OK) || (sqlite3_bind_text(stmt, 6, kara_path, -1, 0) != SQLITE_OK) || - (sqlite3_bind_int (stmt, 7, 0) != SQLITE_OK) /* TODO */ || /* No new kara added (TODO). */ + (sqlite3_bind_int (stmt, 7, 0) /* TODO */ != SQLITE_OK) || (sqlite3_bind_text(stmt, 8, mdt->author_name, -1, 0) != SQLITE_OK) || (sqlite3_bind_int (stmt, 9, mdt->song_number) != SQLITE_OK) || (sqlite3_bind_int (stmt, 10, id) != SQLITE_OK) || diff --git a/src/module/repo.c b/src/module/repo.c index f9b139114cbe82a2eee073fc2112a7aa2f5d4bcc..7e9f6ceeab77907ac54fc84289fa7afda7a0c121 100644 --- a/src/module/repo.c +++ b/src/module/repo.c @@ -7,9 +7,11 @@ #include <strings.h> #include <limits.h> #include <stdlib.h> +#include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> +#include <time.h> #include <common/common.h> #include <mthread/mthread.h> @@ -332,14 +334,20 @@ void __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_object *json) { - size_t i, len = json_object_array_length(json); + size_t i, len = json_object_array_length(json), update_count = 0, + ignored_count = 0; struct json_object *kara_json; int32_t integer, err; struct kara kara; - long filestamp = 0, timestamp = 0, db_timestamp = 0; - char mkvpropedit[PATH_MAX], url[URL_MAX_LEN]; + long filestamp = 0, timestamp = 0; + char *mkvpropedit = safe_zero_malloc(sizeof(char) * PATH_MAX); + char *url = safe_zero_malloc(sizeof(char) * URL_MAX_LEN); int current_id; struct lkt_state *srv = repo->srv; + struct timespec time_sleep = { + .tv_sec = 0, + .tv_nsec = 100000000L, + }; /* Sleep for 0.1s */ RETURN_UNLESS(len > 0 && json_object_get_array(json), "Json invalid or array empty", NOTHING); @@ -349,6 +357,7 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, LOG_INFO("REPO", "Starting to process json for repo %s", repo->name); for (i = 0; i < len; ++i) { + nanosleep(&time_sleep, NULL); /* Sleep a bit, better for Hard drive */ kara_json = json_object_array_get_idx(json, i); err = 0; @@ -368,6 +377,24 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, safe_snprintf(kara.filename + kara_dir_len, PATH_MAX - kara_dir_len, "%d.mkv", integer); + /* Timestamp and presence verification */ + if (!database_get_kara_path(db, kara.id, NULL)) + goto do_it; + if (safe_json_get_long(kara_json, "unix_timestamp", ×tamp)) + continue; + filestamp = get_mtime(kara.filename); + if (!(filestamp > timestamp)) + goto do_it; + else { + ++ignored_count; + database_update_touch(db, kara.id); + database_update_set_available(db, kara.id); + LOG_DEBUG("REPO", "Ignore kara '%ld' with path '%s'", + kara.id, kara.filename); + continue; + } +do_it: + /* Reads the json */ err |= safe_json_get_string(kara_json, "song_name", kara.mdt.song_name, LEKTOR_TAG_MAX); err |= safe_json_get_string(kara_json, "source_name", kara.mdt.source_name, LEKTOR_TAG_MAX); @@ -380,20 +407,6 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, continue; } - /* Timestamp verification */ - if (safe_json_get_long(kara_json, "unix_timestamp", ×tamp)) - continue; - filestamp = get_mtime(kara.filename); - database_get_update(db, &db_timestamp, NULL, NULL); - if (db_timestamp >= filestamp && filestamp > timestamp && - ! kara_metadata_equals(&kara.mdt, kara.filename)) { - database_update_touch(db, kara.id); - database_update_set_available(db, kara.id); - LOG_INFO("REPO", "Ignore kara '%ld' with path '%s'", - kara.id, kara.filename); - continue; - } - current_id = 0; database_queue_current_kara(db, NULL, ¤t_id); if (current_id == (int) kara.id) { @@ -431,9 +444,14 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, } database_stamp(db); + ++update_count; LOG_INFO("REPO", "Added kara %ld from repo %s, filepath is %s", kara.id, repo->name, kara.filename); } + LOG_INFO("REPO", "Updated %ld karas and ignored %ld karas, total is %ld", + update_count, ignored_count, len); + free(mkvpropedit); + free(url); } static inline void diff --git a/src/net/listen.c b/src/net/listen.c index daad13d8ace43a705fab6f62d904f8fca86c571f..4fe673c28a86f3bd0e0c0c2c079d714c823ee0fa 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -716,7 +716,7 @@ static inline void handle_queue_events(struct lkt_state *srv) { lkt_event evt; - char *string = calloc(BUFFER_MAX, sizeof(char)); + char *string = malloc(BUFFER_MAX * sizeof(char)); if (!string) return; redo: