diff --git a/meson.build b/meson.build index d2a9b13198dc8a6f0fe4b556dec2eaa97ccba990..99f26836c9a37a3050582269825d92f6d20a9134 100644 --- a/meson.build +++ b/meson.build @@ -74,7 +74,7 @@ srv = executable( meson.project_name() + 'd' # Admin executable metadata = executable( 'lktadm' - , files('src/main/lktadm.c') + , files('src/main/lktadm.c', 'src/cmd.c') , include_directories : includes , dependencies : bin_deps ) diff --git a/src/main/lktadm.c b/src/main/lktadm.c index 17ea343bf50c1a216ede55c2e7f4987518e96a3c..2cc95f682dfb11b68bf64a4378f62c53996262bb 100644 --- a/src/main/lktadm.c +++ b/src/main/lktadm.c @@ -1,255 +1,266 @@ #define _POSIX_C_SOURCE 200809L #define _DEFAULT_SOURCE +#include <lektor/macro.h> +#include <lektor/defines.h> +#include <lektor/cmd.h> #include <lektor/config.h> #include <lektor/mkv.h> #include <lektor/database.h> #include <lektor/repo.h> #include <lektor/utils.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <stdbool.h> -#include <stdlib.h> -#include <regex.h> -#include <unistd.h> -#include <pwd.h> -#include <fcntl.h> -#include <linux/limits.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> /* ----------------- * * The main function * * ----------------- */ -int -main(int argc, char *argv[]) -{ - int i, num; - sqlite3 *db; - bool ret = true; - char kara_dir[PATH_MAX], *db_path, mkvpropedit[PATH_MAX], buf[100]; - struct kara_metadata data; - struct lkt_repo repo; - - if (argc < 2) - goto print_help; - - /* Read the config file. */ +static sqlite3 *db = NULL; +static char kara_dir[PATH_MAX], db_path[PATH_MAX], mkvpropedit[PATH_MAX], buf[100]; +void +open_db(void) +{ if (!database_new(&db)) { fprintf(stderr, " ! Failed to initialize memory database\n"); - return 1; + exit(EXIT_FAILURE); } if (config_open(db)) { fprintf(stderr, " ! could not load configuration\n"); - return 1; + exit(EXIT_FAILURE); } - /* In any case, we won't free the mkvpropedit, this is not a daemon. */ if (!database_config_get_text(db, "externals", "mkvpropedit", mkvpropedit, PATH_MAX)) { fprintf(stderr, " ! could not get the 'mkvpropedit property from the externals section\n'"); - return 1; + exit(EXIT_FAILURE); } - /* Arguments handle. */ - - if (strcmp(argv[1], "--init") == 0) { - if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX)) { - fprintf(stderr, " ! failed to get the kara directory\n"); - return 10; - } + if (!database_config_get_text(db, "database", "db_path", db_path, PATH_MAX)) { + fprintf(stderr, " ! Failed to get database path\n"); + exit(EXIT_FAILURE); + } - return metadata_set_directory(kara_dir, mkvpropedit); + if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX)) { + fprintf(stderr, " ! Failed to get kara directory\n"); + exit(EXIT_FAILURE); } - else if (strcmp(argv[1], "--populate-all") == 0) { - db_path = (char *) calloc(PATH_MAX, sizeof(char)); +} - if (!database_config_get_text(db, "database", "db_path", db_path, PATH_MAX)) { - fprintf(stderr, " ! Failed to get database path\n"); - goto end_populate; - } +noreturn void +help(void) +{ + printf("Usage for lktadm:\n\n" + " --init: init metadata for all the database according to the root of\n" + " the root of the base\n\n" + " --file <file.mkv, ...>: set automatically metadata for the file file.mkv\n\n" + " --prompt-file <file.mkv, ...>: prompt metadata to put for the file file.mkv\n\n" + " --populate-all: populate the database with whate is found in the fs\n\n" + " --cat <file.mkv, ...>: print the metadata of files\n\n" + " --get-id <id>: print metadata from kurisu with an id\n\n" + " --down-id <id> <path>: download a kara from kurisu to a path\n\n" + " --default-conf: output to stdout the default configuration file\n\n"); + exit(EXIT_SUCCESS); +} - if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX)) { - fprintf(stderr, " ! Failed to get kara directory\n"); - goto end_populate; - } +noreturn void +conf__(struct lkt_cmd_args *args) +{ + (void) args; + fprintf(stdout, "%s\n", lkt_default_config_file); + fprintf(stderr, "You may redirect this output to ~/.config/lektor/lektor.ini\n"); + exit(EXIT_SUCCESS); +} - if (!database_open(db, db_path)) { - fprintf(stderr, " ! lkt_listen: Failed to open database\n"); - return 1; +noreturn void +cat__(struct lkt_cmd_args *args) +{ + int i; + struct kara_metadata data; + for (i = 0; i < args->argc; ++i) { + if (kara_metadata_read(&data, args->argv[i])) { + printf("Failed to read metadata of file %s\n", args->argv[i]); + exit(EXIT_FAILURE); } - - database_update(db, kara_dir); - sqlite3_close(db); - - ret = 0; -end_populate: - free(db_path); - return ret; + printf("Kara path: %s\n" + " Song source: %s\n" + " Song title: %s\n" + " Category: %s\n" + " Type: %s (number %d)\n" + " Author: %s\n" + " Language: %s\n", + args->argv[i], data.source_name, data.song_name, data.category, + data.song_type, data.song_number, data.author_name, data.language); } + exit(EXIT_SUCCESS); +} - else if (strcmp(argv[1], "--file") == 0) { - ret = 0; - for (i = 2; i < argc; ++i) - ret |= metadata_set_file(argv[i], mkvpropedit); - return ret; +noreturn void +init_metadata__(struct lkt_cmd_args *args) +{ + (void) args; + open_db(); + if (!database_config_get_text(db, "database", "kara_dir", kara_dir, PATH_MAX)) { + fprintf(stderr, " ! failed to get the kara directory\n"); + exit(EXIT_FAILURE); } + metadata_set_directory(kara_dir, mkvpropedit); + exit(EXIT_SUCCESS); +} + +noreturn void +init_populate__(struct lkt_cmd_args *args) +{ + (void) args; + open_db(); + database_update(db, kara_dir); + sqlite3_close(db); + exit(EXIT_SUCCESS); +} - else if (strcmp(argv[1], "--prompt-file") == 0) { - ret = 0; - for (i = 2; i < argc; ++i) { - fprintf(stdout, "Asking for file '%s':\n", argv[i]); +noreturn void +init_file__(struct lkt_cmd_args *args) +{ + int i; + for (i = 0; i < args->argc; ++i) + metadata_set_file((char *) args->argv[i], mkvpropedit); + exit(EXIT_SUCCESS); +} - if (get_stdin_line(" song_name (TITLE): ", data.song_name, LEKTOR_TAG_MAX)) - goto input_error; +noreturn void +init_file_prompt__(struct lkt_cmd_args *args) +{ + int i, num; + struct kara_metadata data; + for (i = 0; i < args->argc; ++i) { + fprintf(stdout, "Asking for file '%s':\n", args->argv[i]); - if (get_stdin_line(" source_name (NAME): ", data.source_name, LEKTOR_TAG_MAX)) - goto input_error; + if (get_stdin_line(" song_name (TITLE): ", data.song_name, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - if (get_stdin_line(" category (cdg, vo, ...): ", data.category, LEKTOR_TAG_MAX)) - goto input_error; + if (get_stdin_line(" source_name (NAME): ", data.source_name, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - if (get_stdin_line(" type (OP, AMV, ...): ", data.song_type, LEKTOR_TAG_MAX)) - goto input_error; + if (get_stdin_line(" category (cdg, vo, ...): ", data.category, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - if (get_stdin_line(" language (jp, fr, undefined, ...): ", data.language, LEKTOR_TAG_MAX)) - goto input_error; + if (get_stdin_line(" type (OP, AMV, ...): ", data.song_type, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - if (get_stdin_line(" author_name (Your peudal): ", data.author_name, LEKTOR_TAG_MAX)) - goto input_error; + if (get_stdin_line(" language (jp, fr, undefined, ...): ", data.language, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - if (!get_stdin_line(" type's number(1, 2, ...): ", buf, 100)) - data.song_number = ((num = atoi(buf)) <= 0) ? 1 : num; + if (get_stdin_line(" author_name (Your peudal): ", data.author_name, LEKTOR_TAG_MAX)) + exit(EXIT_FAILURE); - else - goto input_error; + if (!get_stdin_line(" type's number(1, 2, ...): ", buf, 100)) + data.song_number = ((num = atoi(buf)) <= 0) ? 1 : num; - ret |= kara_metadata_write(&data, argv[i], mkvpropedit); - } + else + exit(EXIT_FAILURE); + kara_metadata_write(&data, args->argv[i], mkvpropedit); fprintf(stdout, "You may name this kara with the following name: '%s - %s%d - %s'\n", data.source_name, data.song_type, data.song_number, data.song_name); - - return ret; -input_error: - fprintf(stderr, "\n ! error occured while reading input\n"); - return 1; - } - - else if (strcmp(argv[1], "--cat") == 0) { - for (i = 2; i < argc; ++i) { - if (kara_metadata_read(&data, argv[2])) { - printf("Failed to read metadata of file %s\n", argv[2]); - return 1; - } - - printf("Kara path: %s\n" - " Song source: %s\n" - " Song title: %s\n" - " Category: %s\n" - " Type: %s (number %d)\n" - " Author: %s\n" - " Language: %s\n", - argv[i], data.source_name, data.song_name, data.category, - data.song_type, data.song_number, data.author_name, - data.language - ); - } - return 0; } - else if (strcmp(argv[1], "--get-id") == 0) { - - if (argc != 3) { - fprintf(stderr, " ! invalid argument, just need one id\n"); - return 1; - } - - i = atoi(argv[2]); - - if (repo_new(&repo, "kurisu", "https://kurisu.iiens.net")) { - fprintf(stderr, " ! could not create the repo\n"); - return 60; - } - - if (repo_get_id(&repo, i, &data)) { - fprintf(stderr, " ! could not download json for kara %d\n", i); - return 61; - } + exit(EXIT_SUCCESS); +} - printf("Kara id: %d\n" - " Song source: %s\n" - " Song title: %s\n" - " Category: %s\n" - " Type: %s (number %d)\n" - " Author: %s\n" - " Language: %s\n", - i, data.source_name, data.song_name, data.category, - data.song_type, data.song_number, data.author_name, - data.language - ); +noreturn void +get__(struct lkt_cmd_args *args) +{ + int i; + struct kara_metadata data; + struct lkt_repo repo; - return 0; + if (args->argc != 1) { + fprintf(stderr, " ! invalid argument, just need one id\n"); + exit(EXIT_FAILURE); } - else if (strcmp(argv[1], "--down-id") == 0) { - - if (argc != 4) - goto print_help; + i = atoi(args->argv[0]); - i = atoi(argv[2]); + if (repo_new(&repo, "kurisu", "https://kurisu.iiens.net")) { + fprintf(stderr, " ! could not create the repo\n"); + exit(EXIT_FAILURE); + } - if (repo_new(&repo, "kurisu", "https://kurisu.iiens.net")) { - fprintf(stderr, " ! could not create the repo\n"); - return 60; - } + if (repo_get_id(&repo, i, &data)) { + fprintf(stderr, " ! could not download json for kara %d\n", i); + exit(EXIT_FAILURE); + } - if (repo_download_id_sync(&repo, NULL, i, argv[3], &data)) { - fprintf(stderr, " ! could not download json for kara %d\n", i); - return 61; - } + printf("Kara id: %d\n" + " Song source: %s\n" + " Song title: %s\n" + " Category: %s\n" + " Type: %s (number %d)\n" + " Author: %s\n" + " Language: %s\n", + i, data.source_name, data.song_name, data.category, + data.song_type, data.song_number, data.author_name, + data.language); + exit(EXIT_SUCCESS); +} - printf("Kara %d at %s\n" - " Song source: %s\n" - " Song title: %s\n" - " Category: %s\n" - " Type: %s (number %d)\n" - " Author: %s\n" - " Language: %s\n", - i, argv[3], data.source_name, data.song_name, data.category, - data.song_type, data.song_number, data.author_name, data.language - ); +noreturn void +download__(struct lkt_cmd_args *args) +{ + if (args->argc != 2) + exit(EXIT_FAILURE); + struct lkt_repo repo; + struct kara_metadata data; + int i = atoi(args->argv[0]); - return 0; + if (repo_new(&repo, "kurisu", "https://kurisu.iiens.net")) { + fprintf(stderr, " ! could not create the repo\n"); + exit(EXIT_FAILURE); } - else if (strcmp(argv[1], "--default-conf") == 0) { - fprintf(stdout, "%s\n", lkt_default_config_file); - fprintf(stderr, "You may redirect this output to ~/.config/lektor/lektor.ini\n"); - return 0; + if (repo_download_id_sync(&repo, NULL, i, args->argv[1], &data)) { + fprintf(stderr, " ! could not download json for kara %d\n", i); + exit(EXIT_FAILURE); } - /* The help. */ + printf("Kara %d at %s\n" + " Song source: %s\n" + " Song title: %s\n" + " Category: %s\n" + " Type: %s (number %d)\n" + " Author: %s\n" + " Language: %s\n", + i, args->argv[1], data.source_name, data.song_name, data.category, + data.song_type, data.song_number, data.author_name, data.language); + exit(EXIT_SUCCESS); +} -print_help: - printf("Usage for %s:\n\n" - " --init: init metadata for all the database according to the root of\n" - " the root of the base\n\n" - " --file <file.mkv, ...>: set automatically metadata for the file file.mkv\n\n" - " --prompt-file <file.mkv, ...>: prompt metadata to put for the file file.mkv\n\n" - " --populate-all: populate the database with whate is found in the fs\n\n" - " --cat <file.mkv, ...>: print the metadata of files\n\n" - " --get-id <id>: print metadata from kurisu with an id\n\n" - " --down-id <id> <path>: download a kara from kurisu to a path\n\n" - " --default-conf: output to stdout the default configuration file\n\n", - argv[0]); +static struct lkt_cmd_opt options_init[] = { +// { .name = "database", .call = init_database__ }, + { .name = "populate", .call = init_populate__ }, + { .name = "metadata", .call = init_metadata__ }, + LKT_OPT_NULL, +}; + +noreturn void +init__(struct lkt_cmd_args *args) +{ + lkt_cmd_parse(options_init, args->argc, args->argv, help); +} + +static struct lkt_cmd_opt options[] = { + { .name = "init", .call = init__ }, + { .name = "get", .call = get__, }, + { .name = "download", .call = download__ }, + { .name = "cat", .call = cat__, }, + { .name = "conf", .call = conf__, }, + LKT_OPT_NULL, +}; - return 0; +int +main(int argc, char *argv[]) +{ + lkt_cmd_parse(options, argc, (const char **) argv, help); } +