diff --git a/README.md b/README.md index 8008095b418f4c4d55f58b325bd62ff0a0deba27..f8e7088d1ad5e7a9ac11a413f4b7b43715984f7e 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,4 @@ the `path` property. ## MPD Lektor is almost MPD compatible, at least it uses the same protocol, which can -be got [here](https://www.musicpd.org/doc/html/protocol.html#). +be gotten [here](https://www.musicpd.org/doc/html/protocol.html#). diff --git a/doc/lkt.1 b/doc/lkt.1 index 3976f00b303da4ea953a2cefa5ad59793a4207c1..fd8e1648ea56b3786598cd1dad0fa640639280fc 100644 --- a/doc/lkt.1 +++ b/doc/lkt.1 @@ -118,7 +118,7 @@ Replace the queue with the content of a playlist. Keep the playling state .PD 0 .TP .PD -\fBsearch get\fP <query> +\fBsearch database\fP <query> Search and prints the kara that correspond to the query in the database .TP \fBsearch plt\fP <plt-name> <query> @@ -128,6 +128,9 @@ the query \fBsearch count\fP <query> Search and prints the number of karas that match the query .TP +\fBsearch get\fP <id> +Get informations about a specific id +.TP \fBsearch queue\fP <query> Search in the queue and prints the karas that match the query .PP diff --git a/inc/lektor/database.h b/inc/lektor/database.h index b6fe3bf2aa4333f7223d80d612ef99b1849be357..3c46b47351981ce1ebb791bad495a58f1d1e9dc1 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -122,6 +122,7 @@ bool database_search_queue_init (volatile sqlite3 *db, struct lkt_search *ret) bool database_search_sticker_init (volatile sqlite3 *db, struct lkt_search *ret); bool database_search_playlist_init(volatile sqlite3 *db, struct lkt_search *ret); bool database_search_iter(struct lkt_search *item); +bool database_kara_by_id(volatile sqlite3 *db, int id, struct kara_metadata *kara, char filepath[PATH_MAX]); /* Next and prev operation on the queue. */ bool database_queue_next(volatile sqlite3 *db, char filepath[PATH_MAX]); diff --git a/meson.build b/meson.build index 7426181a76d25e858895eb95cd645993b77a44fe..35025c615e71dce5be66caf643af2d3a8320b8a1 100644 --- a/meson.build +++ b/meson.build @@ -166,12 +166,6 @@ lkt = executable( 'lkt' , include_directories: includes , install: true ) -debug = executable( 'lkt-debug' - , files('src/main/debug.c') - , include_directories: includes - , dependencies: [ bin_deps ] - ) - # Man pages man_sh = find_program('scripts/man.sh') man_header = run_command('realpath', 'doc/header').stdout().strip() diff --git a/src/commands.c b/src/commands.c index 497786cee00542d7dac11879057c1949d7179be9..5b32c96822f13739745be2b82b5bbba58e135b72 100644 --- a/src/commands.c +++ b/src/commands.c @@ -433,6 +433,43 @@ lkt_callback_send_row_v2(struct lkt_state *srv, size_t c, int id, int id_len, co return true; } +static bool +command_findid(struct lkt_state *srv, size_t c, char *id_str) +{ + double duration; + struct kara_metadata kara = {0}; + char filepath[PATH_MAX] = {0}; + long id = strtol(id_str, NULL, 0); /* XXX: Must be valid here */ + if (!database_kara_by_id(srv->db, id, &kara, filepath)) { + LOG_ERROR("COMMAND", "Can't get a kara with id %ld", id); + return false; + } + if (kara_read_length(&duration, filepath)) { + LOG_WARN("COMMAND", "Can't get duration of kara %ld", id); + duration = 0.; + } + int s = duration * 10e-10; + int h = s / 3600; + s = s % 3600; + int m = s / 60; + s = s % 60; + struct lkt_message *out = lkt_message_new(); + out->data_len = safe_snprintf(out->data, LKT_MESSAGE_MAX, + "Title: %s\n" + "Author: %s\n" + "Source: %s\n" + "Type: %s%d\n" + "Category: %s\n" + "Language: %s\n" + "Duration: %d:%02d:%02d\n", + kara.song_name, kara.author_name, + kara.source_name, kara.song_type, + kara.song_number, kara.category, + kara.language, h, m, s); + lkt_state_send(srv, c, out); + return true; +} + bool command_find(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX], long continuation, bool(*init)(volatile sqlite3 *, struct lkt_search *)) @@ -449,8 +486,13 @@ command_find(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX], .plt_name = args[0], /* In case of playlist searchs */ }; - /* Check args */ RETURN_UNLESS(args[0], "Invalid argument", false); + + /* Just an id */ + if (!args[1] && (count = strtol(args[0], NULL, 0))) + return command_findid(srv, c, args[0]); + + /* With an URI */ if (!lkt_uri_from_list(&search.ka_uri, args)) { /* Try from idx 1, in case of playlust searches */ LOG_DEBUG("COMMAND", "URI may not starts at idx 0, may be because " @@ -459,9 +501,7 @@ command_find(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX], "Failed to create the uri", false); } - /* Make the search langand do the right action */ RETURN_UNLESS(init(srv->db, &search), "Failed to init search", false); - for (count = 0; database_search_iter(&search); ++count) continue; @@ -469,7 +509,6 @@ command_find(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX], lkt_set_continuation(srv, c, continuation + count); else LOG_WARN("COMMAND", "%s", "Nothing found"); - lkt_uri_free(&search.ka_uri); return true; } diff --git a/src/database/find.c b/src/database/find.c index c8abc0febb018e14d56e176763f6c0f196599803..7e2f5befe2b926367b3c40f0d5ab28fa538de4ab 100644 --- a/src/database/find.c +++ b/src/database/find.c @@ -185,3 +185,33 @@ end: sqlite3_finalize(item->stmt); return false; } + +bool +database_kara_by_id(volatile sqlite3 *db, int id, struct kara_metadata *res, + char filepath[PATH_MAX]) +{ + static const char *SQL = + "SELECT song_name, source_name, category, language, author_name, " + "song_type, song_number, file_path FROM kara WHERE id = ?;"; + sqlite3_stmt *stmt = 0; + int ret = false; + + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_BIND_INT(db, stmt, 1, id, error); + SQLITE_STEP_ROW(db, stmt, error); + if (!res) + goto no_metadata; + strncpy(res->song_name, sqlite3_column_chars(stmt, 0), LEKTOR_TAG_MAX - 1); + strncpy(res->source_name, sqlite3_column_chars(stmt, 1), LEKTOR_TAG_MAX - 1); + strncpy(res->category, sqlite3_column_chars(stmt, 2), LEKTOR_TAG_MAX - 1); + strncpy(res->language, sqlite3_column_chars(stmt, 3), LEKTOR_TAG_MAX - 1); + strncpy(res->author_name, sqlite3_column_chars(stmt, 4), LEKTOR_TAG_MAX - 1); + strncpy(res->song_type, sqlite3_column_chars(stmt, 5), LEKTOR_TAG_MAX - 1); + res->song_number = sqlite3_column_int(stmt, 6); +no_metadata: + strncpy(filepath, sqlite3_column_chars(stmt, 7), PATH_MAX - 1); + ret = true; +error: + sqlite3_finalize(stmt); + return ret; +} diff --git a/src/main/debug.c b/src/main/debug.c deleted file mode 100644 index 78374983e5a6880a7f48f0ca78ccd23dd86359be..0000000000000000000000000000000000000000 --- a/src/main/debug.c +++ /dev/null @@ -1,22 +0,0 @@ -#include <lektor/mkv.h> -#include <stdio.h> - -int -main(int argc, char **argv) -{ - double len = 0.; - - if (argc != 2) - return 1; - - if (kara_read_length(&len, argv[1]) < 0) - return 2; - - int s = len * 10e-10; - int h = s / 3600; - s = s % 3600; - int m = s / 60; - s = s % 60; - printf("%02d:%02d:%02d\n", h, m, s); - return 0; -} diff --git a/src/main/lkt.c b/src/main/lkt.c index 6057953f84154b01486ddeb97d9d04ad75354885..3999db0fd3f3a3ff3d08e2e6f397be5acbbe2372 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -842,6 +842,26 @@ redo: } } +noreturn void +search_get__(struct lkt_cmd_args *args) +{ + fail_if(args->argc != 1, "Invalid number of arguments"); + fail_if(!strtol(args->argv[0], NULL, 0), "Invalid id"); + char buff[LKT_MESSAGE_MAX]; + FILE *sock = lkt_connect(); + + write_socket(sock, "find %s\n", args->argv[0]); + for (;;) { + memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); + read_socket(sock, buff, LKT_MESSAGE_MAX - 1); + if (STR_NMATCH(buff, "OK", 2)) + exit(EXIT_SUCCESS); + else if (STR_NMATCH(buff, "ACK", 3)) + exit(EXIT_FAILURE); + write(1, buff, strlen(buff)); + } +} + noreturn void search_plt__(struct lkt_cmd_args *args) { @@ -880,7 +900,7 @@ redo: #define search_with_cmd(func, cmd) /* I don't want to write always the same things */ \ noreturn void func (struct lkt_cmd_args *args) { search_with_cmd__(args, #cmd); } -search_with_cmd(search_get__, search) +search_with_cmd(search_db__, search) search_with_cmd(search_count__, count) search_with_cmd(search_queue__, playlistfind) #undef search_with_cmd @@ -910,6 +930,7 @@ static struct lkt_cmd_opt options_plt[] = { }; static struct lkt_cmd_opt options_search[] = { + { .name = "database", .call = search_db__ }, { .name = "get", .call = search_get__ }, { .name = "plt", .call = search_plt__ }, { .name = "count", .call = search_count__ }, diff --git a/src/mkv/mkv.c b/src/mkv/mkv.c index c202b6610aafc772687365984e9b1cf4676da91c..a108cdcddbb1322c353c6f1666c7b224130fbe70 100644 --- a/src/mkv/mkv.c +++ b/src/mkv/mkv.c @@ -550,7 +550,6 @@ kara_read_segment_info(struct bufferfd *bf, double *len) if (eid == EBML_MKV_SEG_DURATION) { if ((n = mkv_read_float(bf, len)) < 0) return -1; - printf("%ld\n", n); } else if (eid == EBML_MKV_SEG_TS_SCALE) { @@ -610,7 +609,6 @@ kara_read_length(double *len, const char *filename) if (mkv_read_element_length(&file, &elength) < 0) goto error; if (bufferfd_skip(&file, elength) < 0) { - printf("Failed to skip %ld (bufferfd)\n", elength); goto error; } }