Implement mailbox output format for ls.
authorAndre Noll <maan@systemlinux.org>
Sun, 30 Sep 2007 23:24:54 +0000 (01:24 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 30 Sep 2007 23:24:54 +0000 (01:24 +0200)
Alos, fix a bug in com_lsblob_callback() which caused incorrect
detection of the given options.

afs.h
aft.c
blob.c

diff --git a/afs.h b/afs.h
index 8b86cac..546a19e 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -135,6 +135,7 @@ int playlist_check_callback(__a_unused const struct osl_object *query,
        int table_name ## _init(struct table_info *ti, const char *db); \
        void table_name ## _shutdown(enum osl_close_flags flags); \
        int cmd_prefix ## _get_name_by_id(uint32_t id, char **name); \
+       int cmd_prefix ## _get_def_by_id(uint32_t id, struct osl_object *def); \
        int cmd_prefix ## _get_name_and_def_by_row(const struct osl_row *row, \
                char **name, struct osl_object *def); \
        extern struct osl_table *table_name ## _table;
diff --git a/aft.c b/aft.c
index 9e4fec2..209ea52 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -683,12 +683,17 @@ err:
 }
 
 static int get_local_time(uint64_t *seconds, char *buf, size_t size,
-       time_t current_time)
+       time_t current_time, enum ls_listing_mode lm)
 {
        struct tm t;
 
        if (!localtime_r((time_t *)seconds, &t))
                return -E_LOCALTIME;
+       if (lm == LS_MODE_MBOX) {
+               if (!strftime(buf, size, "%c", &t))
+                       return -E_STRFTIME;
+               return 1;
+       }
        if (*seconds + 6 * 30 * 24 * 3600 > current_time) {
                if (!strftime(buf, size, "%b %e %k:%M", &t))
                        return -E_STRFTIME;
@@ -775,6 +780,8 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        struct audio_format_info *afhi = &d->afhi;
        struct ls_widths *w = &opts->widths;
        int have_score = opts->flags & LS_FLAG_ADMISSIBLE_ONLY;
+       char asc_hash[2 * HASH_SIZE + 1];
+       char *att_line, *lyrics_line, *image_line;
 
        if (opts->mode == LS_MODE_SHORT) {
                para_printf(b, "%s\n", d->path);
@@ -782,7 +789,7 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
        }
        get_attribute_bitmap(&afsi->attributes, att_buf);
        ret = get_local_time(&afsi->last_played, last_played_time,
-               sizeof(last_played_time), current_time);
+               sizeof(last_played_time), current_time, opts->mode);
        if (ret < 0)
                return ret;
        get_duration_buf(afhi->seconds_total, duration_buf, w->duration_width);
@@ -823,14 +830,12 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
                );
                return 1;
        }
+       hash_to_asc(d->hash, asc_hash);
+       att_line = make_attribute_line(att_buf, afsi);
+       lyrics_line = make_lyrics_line(afsi);
+       image_line = make_image_line(afsi);
        if (opts->mode == LS_MODE_VERBOSE) {
-               char asc_hash[2 * HASH_SIZE + 1];
-               char *att_line, *lyrics_line, *image_line;
 
-               hash_to_asc(d->hash, asc_hash);
-               att_line = make_attribute_line(att_buf, afsi);
-               lyrics_line = make_lyrics_line(afsi);
-               image_line = make_image_line(afsi);
                para_printf(b,
                        "%s: %s\n" /* path */
                        "%s%s%s" /* score */
@@ -863,11 +868,50 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
                        last_played_time,
                        afhi->info_string
                );
-               free(att_line);
-               free(lyrics_line);
-               free(image_line);
-               return 1;
+       } else { /* mbox mode */
+               struct osl_object lyrics_def;
+               lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def);
+               para_printf(b,
+                       "From foo@localhost %s\n"
+                       "Received: from\nTo: bar\nFrom: a\n"
+                       "Subject: %s\n\n" /* path */
+                       "%s%s%s" /* score */
+                       "attributes: %s\n"
+                       "hash: %s\n"
+                       "image_id: %s\n"
+                       "lyrics_id: %s\n"
+                       "bitrate: %dkbit/s\n"
+                       "format: %s\n"
+                       "frequency: %dHz\n"
+                       "channels: %d\n"
+                       "duration: %s\n"
+                       "num_played: %d\n"
+                       "tag info: %s\n"
+                       "%s%s\n",
+                       last_played_time,
+                       d->path,
+                       have_score? "score: " : "", score_buf,
+                               have_score? "\n" : "",
+                       att_line,
+                       asc_hash,
+                       image_line,
+                       lyrics_line,
+                       afhi->bitrate,
+                       audio_format_name(afsi->audio_format_id),
+                       afhi->frequency,
+                       afhi->channels,
+                       duration_buf,
+                       afsi->num_played,
+                       afhi->info_string,
+                       lyrics_def.data? "Lyrics:\n~~~~~~~\n" : "",
+                       lyrics_def.data? (char *)lyrics_def.data : ""
+               );
+               if (lyrics_def.data)
+                       osl_close_disk_object(lyrics_def.data);
        }
+       free(att_line);
+       free(lyrics_line);
+       free(image_line);
        return 1;
 }
 
diff --git a/blob.c b/blob.c
index 8438e73..150a15e 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -83,7 +83,7 @@ static int print_blob(struct osl_table *table, struct osl_row *row,
 static int com_lsblob_callback(struct osl_table *table,
                const struct osl_object *query, struct osl_object *result)
 {
-       struct lsblob_action_data lbad = {.flags = *(uint32_t *)query};
+       struct lsblob_action_data lbad = {.flags = *(uint32_t *)query->data};
        struct pattern_match_data pmd = {
                .table = table,
                .patterns = {.data = (char *)query->data + sizeof(uint32_t),
@@ -138,6 +138,7 @@ static int com_lsblob(callback_function *f, int fd, int argc, char * const * con
                        flags |= BLOB_LS_FLAG_REVERSE;
                        continue;
                }
+               break;
        }
 //     if (argc > i)
 //             return -E_BLOB_SYNTAX;
@@ -409,6 +410,29 @@ static int blob_get_name_by_id(struct osl_table *table, uint32_t id,
                return blob_get_name_by_id(table_name ## _table, id, name); \
        }
 
+static int blob_get_def_by_id(struct osl_table *table, uint32_t id,
+               struct osl_object *def)
+{
+       struct osl_row *row;
+       struct osl_object obj = {.data = &id, .size = sizeof(id)};
+       int ret;
+
+       def->data = NULL;
+       if (!id)
+               return 1;
+       ret = osl_get_row(table, BLOBCOL_ID, &obj, &row);
+       if (ret < 0)
+               return ret;
+       return osl_open_disk_object(table, row, BLOBCOL_DEF, def);
+}
+
+/** Define the \p get_def_by_id function for this blob type. */
+#define DEFINE_GET_DEF_BY_ID(table_name, cmd_prefix) \
+       int cmd_prefix ## _get_def_by_id(uint32_t id, struct osl_object *def) \
+       { \
+               return blob_get_def_by_id(table_name ## _table, id, def); \
+       }
+
 static int blob_get_name_and_def_by_row(struct osl_table *table,
                const struct osl_row *row, char **name, struct osl_object *def)
 {
@@ -467,6 +491,7 @@ static int blob_init(struct osl_table **table,
        DEFINE_BLOB_COMMAND(rm, table_name, cmd_prefix) \
        DEFINE_BLOB_COMMAND(mv, table_name, cmd_prefix) \
        DEFINE_GET_NAME_BY_ID(table_name, cmd_prefix); \
+       DEFINE_GET_DEF_BY_ID(table_name, cmd_prefix); \
        DEFINE_GET_NAME_AND_DEF_BY_ROW(table_name, cmd_prefix); \
        DEFINE_BLOB_SHUTDOWN(table_name); \
        DEFINE_BLOB_INIT(table_name);