X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=aft.c;h=8c7dd21a0f86ac25e39b1bfdae33ccc5f6032b71;hp=cbea5eb1593a1ed8f0fdaa02de634a9e1f0e92e9;hb=e60387b0557fbeb97895bc3d6d4423be12436c52;hpb=fbfc694f85103a86c18469c6fdd2f4f03c812337 diff --git a/aft.c b/aft.c index cbea5eb1..8c7dd21a 100644 --- a/aft.c +++ b/aft.c @@ -457,9 +457,9 @@ static int load_chunk_info(struct osl_object *obj, struct audio_format_info *afh * * \return The return value of the underlying call to osl_get_row(). */ -int aft_get_row_of_path(char *path, struct osl_row **row) +int aft_get_row_of_path(const char *path, struct osl_row **row) { - struct osl_object obj = {.data = path, .size = strlen(path) + 1}; + struct osl_object obj = {.data = (char *)path, .size = strlen(path) + 1}; return osl_get_row(audio_file_table, AFTCOL_PATH, &obj, row); } @@ -500,7 +500,7 @@ int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj) * * \return Positive on success, negative on errors. */ -int get_afsi_object_of_path(char *path, struct osl_object *obj) +int get_afsi_object_of_path(const char *path, struct osl_object *obj) { struct osl_row *row; int ret = aft_get_row_of_path(path, &row); @@ -526,6 +526,23 @@ int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi) return load_afsi(afsi, &obj); } +/** + * Get the audio file selector info, given the path of an audio table. + * + * \param path The full path of the audio file. + * \param afsi Result pointer. + * + * \return Positive on success, negative on errors. + */ +int get_afsi_of_path(const char *path, struct afs_info *afsi) +{ + struct osl_object obj; + int ret = get_afsi_object_of_path(path, &obj); + if (ret < 0) + return ret; + return load_afsi(afsi, &obj); +} + /** * Get the path of an audio file, given a row of the audio file table. * @@ -1800,7 +1817,6 @@ static int com_touch_callback(const struct osl_object *query, return ret < 0? ret : 0; } - int com_touch(int fd, int argc, char * const * const argv) { struct com_touch_options cto = { @@ -1974,6 +1990,146 @@ int com_afs_rm(int fd, int argc, char * const * const argv) return ret; } +enum cpsi_flags { + CPSI_FLAG_COPY_LYRICS_ID = 1, + CPSI_FLAG_COPY_IMAGE_ID = 2, + CPSI_FLAG_COPY_LASTPLAYED = 4, + CPSI_FLAG_COPY_NUMPLAYED = 8, + CPSI_FLAG_COPY_ATTRIBUTES = 16, + CPSI_FLAG_VERBOSE = 32, +}; + +struct cpsi_action_data { + unsigned flags; + unsigned num_copied; + struct para_buffer pb; + struct afs_info source_afsi; +}; + +static int copy_selector_info(__a_unused struct osl_table *table, + struct osl_row *row, const char *name, void *data) +{ + struct cpsi_action_data *cad = data; + struct osl_object target_afsi_obj; + int ret; + struct afs_info target_afsi; + + ret = get_afsi_object_of_row(row, &target_afsi_obj); + if (ret < 0) + return ret; + load_afsi(&target_afsi, &target_afsi_obj); + if (cad->flags & CPSI_FLAG_COPY_LYRICS_ID) + target_afsi.lyrics_id = cad->source_afsi.lyrics_id; + if (cad->flags & CPSI_FLAG_COPY_IMAGE_ID) + target_afsi.image_id = cad->source_afsi.image_id; + if (cad->flags & CPSI_FLAG_COPY_LASTPLAYED) + target_afsi.last_played = cad->source_afsi.last_played; + if (cad->flags & CPSI_FLAG_COPY_NUMPLAYED) + target_afsi.num_played = cad->source_afsi.num_played; + if (cad->flags & CPSI_FLAG_COPY_ATTRIBUTES) + target_afsi.attributes = cad->source_afsi.attributes; + save_afsi(&target_afsi, &target_afsi_obj); /* in-place update */ + cad->num_copied++; + if (cad->flags & CPSI_FLAG_VERBOSE) + para_printf(&cad->pb, "copied afsi to %s\n", name); + return 1; +} + +static int com_cpsi_callback(const struct osl_object *query, + struct osl_object *result) +{ + struct cpsi_action_data cad = {.flags = *(unsigned *)query->data}; + int ret; + char *source_path = (char *)query->data + sizeof(cad.flags); + + ret = get_afsi_of_path(source_path, &cad.source_afsi); + if (ret < 0) + goto out; + struct pattern_match_data pmd = { + .table = audio_file_table, + .loop_col_num = AFTCOL_HASH, + .match_col_num = AFTCOL_PATH, + .patterns = {.data = source_path + strlen(source_path) + 1, + .size = query->size - sizeof(cad.flags) + - strlen(source_path) - 1}, + .data = &cad, + .action = copy_selector_info + }; + ret = for_each_matching_row(&pmd); +out: + if (ret < 0) + para_printf(&cad.pb, "%s\n", PARA_STRERROR(-ret)); + if (cad.flags & CPSI_FLAG_VERBOSE) { + if (cad.num_copied) + para_printf(&cad.pb, "copied requested afsi from %s " + "to %u files\n", + source_path, cad.num_copied); + else + para_printf(&cad.pb, "nothing copied\n"); + } + if (cad.pb.buf) { + result->data = cad.pb.buf; + result->size = cad.pb.size; + return 1; + } + return ret < 0? ret : 0; +} + +int com_cpsi(int fd, int argc, char * const * const argv) +{ + unsigned flags = 0; + int i, ret; + struct osl_object options = {.data = &flags, .size = sizeof(flags)}, + result; + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (arg[0] != '-') + break; + if (!strcmp(arg, "--")) { + i++; + break; + } + if (!strcmp(arg, "-y")) { + flags |= CPSI_FLAG_COPY_LYRICS_ID; + continue; + } + if (!strcmp(arg, "-i")) { + flags |= CPSI_FLAG_COPY_IMAGE_ID; + continue; + } + if (!strcmp(arg, "-l")) { + flags |= CPSI_FLAG_COPY_LASTPLAYED; + continue; + } + if (!strcmp(arg, "-n")) { + flags |= CPSI_FLAG_COPY_NUMPLAYED; + continue; + } + if (!strcmp(arg, "-a")) { + flags |= CPSI_FLAG_COPY_ATTRIBUTES; + continue; + } + if (!strcmp(arg, "-v")) { + flags |= CPSI_FLAG_VERBOSE; + continue; + } + break; + } + if (i + 1 >= argc) /* need at least souce file and pattern */ + return -E_AFT_SYNTAX; + if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */ + flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags; + ret = send_option_arg_callback_request(&options, argc - i, argv + i, + com_cpsi_callback, &result); + if (ret > 0) { + send_buffer(fd, (char *)result.data); + free(result.data); + } else + send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret)); + return ret; +} + /* TODO: optionally fix problems by removing offending rows */ static int check_audio_file(struct osl_row *row, void *data) { @@ -2022,6 +2178,8 @@ int aft_check_callback(__a_unused const struct osl_object *query, struct osl_obj } + + /** * Close the audio file table. *