diff --git a/src/cmd.c b/src/cmd.c index a5cb0d4..8e5e62f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -24,7 +24,7 @@ static const struct cmd_entry ents[] = { { .arg_name = "uptime", .fn = cmd_server_uptime, .need_auth = true }, { .arg_name = "ed2k", .fn = cmd_ed2k, }, { .arg_name = "add", .fn = cmd_add, .argcheck = cmd_add_argcheck, .need_auth = true, .need_cache = true, }, - { .arg_name = "modify", .fn = cmd_modify, .need_auth = true, .need_cache = false, }, + { .arg_name = "modify", .fn = cmd_modify, .argcheck = cmd_modify_argcheck, .need_auth = true, .need_cache = true, }, }; static const int32_t ents_len = sizeof(ents)/sizeof(*ents); diff --git a/src/cmd.h b/src/cmd.h index 27da97f..709bb5c 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -40,5 +40,6 @@ enum error cmd_prog_version(void *); * Modifies a mylist entry */ enum error cmd_modify(void *data); +enum error cmd_modify_argcheck(); #endif /* _CMD_H */ diff --git a/src/cmd_modify.c b/src/cmd_modify.c index 795ac4e..0cf1068 100644 --- a/src/cmd_modify.c +++ b/src/cmd_modify.c @@ -1,7 +1,9 @@ +#include #include #include #include #include +#include #include "cmd.h" #include "error.h" @@ -59,6 +61,107 @@ uint64_t cmd_modify_arg_parse(const char *str, uint64_t *out_wdate) return ce.lid; } +static enum error cmd_modify_api_send(uint64_t lid, struct api_mylistadd_opts *opts) +{ + struct api_result res; + enum error err = api_cmd_mylistmod(lid, opts, &res); + if (err != NOERR) + return err; + + if (res.code == APICODE_NO_SUCH_MYLIST_ENTRY) { + uio_error("No mylist entry with id: '%lu'", lid); + return ERR_UNKNOWN; + } + +#if 0 + if (!cache_is_init()) { + if ((err = cache_init()) != NOERR) + return err; + did_cache_init = true; + } +#endif + + err = cache_update(lid, opts); + if (err == NOERR) { + uio_user("Successfully updated entry with lid:%lu", lid); + } + + return err; +} + +static enum error cmd_modify_file_cb(const char *path, const struct stat *fstat, void *data) +{ + struct cache_entry ce; + enum error err; + struct api_mylistadd_opts *opts = data; + char *basename = util_basename(path); + + uio_debug("Modifying mylist by file: %s", basename); + + /* Get the mylist id from the cache */ + err = cache_get(basename, fstat->st_size, CACHE_S_LID, &ce); + if (err != NOERR) { + uio_error("Failed to get file from cache: %lu:%s. Maybe we should add it now?", + fstat->st_size, basename); + return err; + } + + /* We have the mylistid, so actually send the change to the api */ + return cmd_modify_api_send(ce.lid, opts); +} + +static enum error cmd_modify_by_file(const char *fpath, struct api_mylistadd_opts *opts) +{ + return util_iterpath(fpath, cmd_modify_file_cb, opts); +} + +static enum error cmd_modify_by_mylistid(const char *arg, struct api_mylistadd_opts *opts) +{ + struct api_mylistadd_opts local_opts = *opts; + uint64_t wdate, lid; + + lid = cmd_modify_arg_parse(arg, &wdate); + + if (lid == 0) { + uio_error("Argument '%s' is not valid. Skipping", arg); + return ERR_UNKNOWN; + } + + /* If info is present in the argument line set it for the update */ + if (wdate != 0) { + local_opts.watched = true; + local_opts.watched_set = true; + + local_opts.wdate = wdate; + local_opts.wdate_set = true; + } + + return cmd_modify_api_send(lid, &local_opts); +} + +static enum error cmd_modify_process_arg(const char *arg, struct api_mylistadd_opts *opts) +{ + struct stat fs; + + /* Check if the given path is a file/directory */ + if (stat(arg, &fs) == 0) { + /* File exists handle with the file handler */ + return cmd_modify_by_file(arg, opts); + } + + /* If stat failed */ + int eno = errno; + if (eno != ENOENT) { + /* Failed for some other reason apart from file not existing */ + uio_warning("Stat for file '%s' failed with: %s", arg, strerror(eno)); + return ERR_UNKNOWN; + } + /* File simply not found, try the with the mylistid syntax */ + + return cmd_modify_by_mylistid(arg, opts); + +} + enum error cmd_modify(void *data) { struct api_mylistadd_opts mopt = {0}; @@ -68,10 +171,6 @@ enum error cmd_modify(void *data) int fcount; fcount = config_get_nonopt_count(); - if (fcount == 0) { - uio_error("No mylist ids specified"); - return ERR_CMD_ARG; - } if (config_get_subopt("modify", "watched", (void**)&watched) == NOERR && *watched) { mopt.watched = *watched; @@ -90,49 +189,26 @@ enum error cmd_modify(void *data) } for (int i = 0; i < fcount; i++) { - struct api_result res; - struct api_mylistadd_opts l_opts = mopt; const char *arg = config_get_nonopt(i); - uint64_t wdate; - uint64_t lid = cmd_modify_arg_parse(arg, &wdate); - - if (lid == 0) { - uio_error("Argument '%s' is not valid. Skipping", arg); - continue; - } - - if (wdate != 0) { - l_opts.watched = true; - l_opts.watched_set = true; - l_opts.wdate = wdate; - l_opts.wdate_set = true; - } - - err = api_cmd_mylistmod(lid, &l_opts, &res); - if (err != NOERR) - break; - - if (res.code == APICODE_NO_SUCH_MYLIST_ENTRY) { - uio_error("No mylist entry with id: '%lu'", lid); - continue; - } - - if (!cache_is_init()) { - if ((err = cache_init()) != NOERR) - return err; - did_cache_init = true; - } - - err = cache_update(lid, &l_opts); - if (err != NOERR) - break; + cmd_modify_process_arg(arg, &mopt); } +#if 0 if (did_cache_init) { did_cache_init = false; cache_free(); } +#endif return err; } + +enum error cmd_modify_argcheck() +{ + if (config_get_nonopt_count() == 0) { + uio_error("No arguments given for modify"); + return ERR_CMD_ARG; + } + return NOERR; +} diff --git a/src/config.c b/src/config.c index e71c048..0690eb3 100644 --- a/src/config.c +++ b/src/config.c @@ -67,7 +67,7 @@ static struct conf_entry modify_add_subopts[] = { { .l_name = "wdate", .s_name = UCHAR_MAX + 4, .has_arg = required_argument, .set_func = config_set_str, .in_args = true, .type = OTYPE_S, .handle_order = 0, - .h_desc = "Set the watched date when adding/modifying files", }, + .h_desc = "Set the watched date when adding/modifying files. Either in unix time or in YY-MM-DDTHH:MM:SS", }, }; static struct conf_entry options[] = { diff --git a/src/util.h b/src/util.h index 896645e..5e4486f 100644 --- a/src/util.h +++ b/src/util.h @@ -63,4 +63,5 @@ uint64_t util_iso2unix(const char *isotime); typedef enum error (*util_itercb)(const char *path, const struct stat *fstat, void *data); enum error util_iterpath(const char *path, util_itercb cb, void *data); + #endif /* _UTIL_H */