diff --git a/.gitignore b/.gitignore index 1b13b04..88b523f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ /go .deps/ .dirstamp -duc +/duc diff --git a/Makefile.am b/Makefile.am index 61e621a..3aa84eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,7 @@ duc_SOURCES += \ src/duc/cmd-ls.c \ src/duc/cmd-ui.c \ src/duc/cmd-xml.c \ + src/duc/cmd-json.c \ src/duc/ducrc.c \ src/duc/ducrc.h \ src/duc/main.c diff --git a/src/duc/cmd-json.c b/src/duc/cmd-json.c new file mode 100644 index 0000000..be26851 --- /dev/null +++ b/src/duc/cmd-json.c @@ -0,0 +1,192 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "duc.h" + + +static bool opt_apparent = false; +static char *opt_database = NULL; +static double opt_min_size = 0; +static bool opt_exclude_files = false; + + +static void indent(int n) +{ + int i; + for(i=0; isize, st); + + if (!first) printf(",\n"); + + if(e->type == DUC_FILE_TYPE_DIR && size>= min_size) { + duc_dir *dir_child = duc_dir_openent(dir, e); + if(dir_child) { + indent(depth); + printf("{\n"); + + indent(depth + 2); + printf("\"name\": \""); + print_escaped(e->name); + printf("\",\n"); + + indent(depth + 2); + printf("\"count\": %jd,\n", e->size.count); + + indent(depth + 2); + printf("\"size_apparent\": %jd,\n", e->size.apparent); + + indent(depth + 2); + printf("\"size_actual\": %jd,\n", e->size.actual); + + indent(depth + 2); + printf("\"children\": [\n"); + + dump(duc, dir_child, depth + 4, min_size, ex_files); + + printf("\n"); + indent(depth + 2); + printf("]\n"); + + indent(depth); + printf("}"); + } + duc_dir_close(dir_child); + } else { + if(!ex_files && size >= min_size) { + indent(depth); + printf("{\n"); + + indent(depth + 2); + printf("\"name\": \""); + print_escaped(e->name); + printf("\",\n"); + + indent(depth + 2); + printf("\"size_apparent\": %jd,\n", e->size.apparent); + + indent(depth + 2); + printf("\"size_actual\": %jd\n", e->size.actual); + + indent(depth); + printf("}"); + } + } + first = false; + } +} + + +static int json_main(duc *duc, int argc, char **argv) +{ + char *path = "."; + if(argc > 0) path = argv[0]; + + int r = duc_open(duc, opt_database, DUC_OPEN_RO); + if(r != DUC_OK) { + duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); + return -1; + } + + duc_dir *dir = duc_dir_open(duc, path); + if(dir == NULL) { + duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); + return -1; + } + + struct duc_size size; + duc_dir_get_size(dir, &size); + + printf("{\n"); + + indent(2); + printf("\"name\": \""); + print_escaped(path); + printf("\",\n"); + + indent(2); + printf("\"count\": %jd,\n", size.count); + + indent(2); + printf("\"size_apparent\": %jd,\n", size.apparent); + + indent(2); + printf("\"size_actual\": %jd,\n", size.actual); + + indent(2); + printf("\"children\": [\n"); + + dump(duc, dir, 4, (off_t)opt_min_size, opt_exclude_files); + printf("\n"); + + indent(2); + printf("]\n"); + + printf("}\n"); + + duc_dir_close(dir); + duc_close(duc); + + return 0; +} + + +static struct ducrc_option options[] = { + { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "interpret min_size/-s value as apparent size" }, + { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, + { &opt_exclude_files, "exclude-files", 'x', DUCRC_TYPE_BOOL, "exclude file from json output, only include directories" }, + { &opt_min_size, "min_size", 's', DUCRC_TYPE_DOUBLE, "specify min size for files or directories" }, + { NULL } +}; + + +struct cmd cmd_json = { + .name = "json", + .descr_short = "Dump JSON output", + .usage = "[options] [PATH]", + .main = json_main, + .options = options, +}; + + +/* + * End + */ diff --git a/src/duc/main.c b/src/duc/main.c index 4af1631..d038c24 100644 --- a/src/duc/main.c +++ b/src/duc/main.c @@ -33,6 +33,7 @@ extern struct cmd cmd_gui; extern struct cmd cmd_guigl; extern struct cmd cmd_graph; extern struct cmd cmd_xml; +extern struct cmd cmd_json; extern struct cmd cmd_cgi; extern struct cmd cmd_ui; @@ -44,6 +45,7 @@ struct cmd *cmd_list[] = { &cmd_manual, &cmd_ls, &cmd_xml, + &cmd_json, &cmd_graph, &cmd_cgi, #ifdef ENABLE_X11