1 /* 2 * Copyright (c) 2010, 2011 Ryan Flannery <ryan.flannery@gmail.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef META_INFO_H 18 #define META_INFO_H 19 20 #include <ctype.h> 21 #include <limits.h> 22 #include <err.h> 23 #include <errno.h> 24 #include <stdbool.h> 25 #include <stdint.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <strings.h> 30 #include <time.h> 31 32 /* non-baes includes (just TagLib) */ 33 #include <tag_c.h> 34 35 #include "debug.h" 36 #include "enums.h" 37 38 #include "compat.h" 39 40 /* the character-info fields. used for all meta-info that's shown */ 41 #define MI_NUM_CINFO 8 42 #define MI_CINFO_ARTIST 0 43 #define MI_CINFO_ALBUM 1 44 #define MI_CINFO_TITLE 2 45 #define MI_CINFO_TRACK 3 46 #define MI_CINFO_YEAR 4 47 #define MI_CINFO_GENRE 5 48 #define MI_CINFO_LENGTH 6 49 #define MI_CINFO_COMMENT 7 50 51 /* struct used to represent all meta information from a given file */ 52 typedef struct { 53 char *filename; /* filename of file itself */ 54 char *cinfo[MI_NUM_CINFO]; /* character meta info array */ 55 int length; /* play length in seconds */ 56 time_t last_updated; /* last time info was extracted */ 57 bool is_url; /* if this is a url */ 58 } meta_info; 59 60 /* 61 * XXX Note in the above that the playlength is stored both numerically 62 * in the member 'length' and as a character string in the cinfo array 63 * in the form "hh:mm:ss" 64 */ 65 66 /* array of human-readable names of each CINFO member */ 67 extern const char *MI_CINFO_NAMES[MI_NUM_CINFO]; 68 69 /* create/destroy meta_info structs */ 70 meta_info *mi_new(void); 71 void mi_free(meta_info *info); 72 73 /* read/write meta_info structs to a file */ 74 void mi_fwrite(meta_info *mi, FILE *fout); 75 void mi_fread(meta_info *mi, FILE *fin); 76 77 /* used to extract meta info from a media file */ 78 meta_info* mi_extract(const char *filename); 79 80 81 /***************************************************************************** 82 * XXX Important Note XXX These functions are used to replace any 83 * non-printable characters in a string -or- any of the cinfo fields of a 84 * meta-info struct. This must be done as some files (sadly, some Aphex Twin) 85 * contain such characters in their meta info, and these characters correspond 86 * to ncurses control sequences, thus mucking-up the display when painted to 87 * the screen. See "vitunes -e help check" for details. 88 * This is NOT called explicitly during mi_extract, and MUST be done 89 * eleswhere (medialib_db_update, medialib_db_scan_dirs, ecmd_addurl, etc.) 90 * This is so that one may use the "check" e-command to see which files have 91 * such characters, and then tag them correctly. 92 ****************************************************************************/ 93 94 void str_sanitize(char *s); 95 void mi_sanitize(meta_info *mi); 96 97 98 /***************************************************************************** 99 * Functions used to query meta_info's (i.e. to match them against a given 100 * search/filter). It works by setting-up a global query description which 101 * contains a list of tokens in the search and whether or not each token 102 * should be matched positively/negatively. 103 * 104 * After the global query has been set, mi_match() can be used to compare a 105 * given meta_info against this global query description. 106 ****************************************************************************/ 107 108 /* structure used to describe what to match meta_info's against */ 109 #define MI_MAX_QUERY_TOKENS 255 110 typedef struct { 111 char *tokens[MI_MAX_QUERY_TOKENS]; 112 char match[MI_MAX_QUERY_TOKENS]; 113 int ntokens; 114 char *raw; /* a copy of the original, un-tokenized query */ 115 } mi_query_description; 116 117 /* flag to indicate if we should include filename when matching */ 118 extern bool mi_query_match_filename; 119 120 /* initialize, set, and clear global query description */ 121 void mi_query_init(); 122 bool mi_query_isset(); 123 void mi_query_clear(); 124 void mi_query_add_token(const char *token); 125 126 void mi_query_setraw(const char *query); 127 const char *mi_query_getraw(); 128 129 /* match a given meta_info/string against the global query description */ 130 bool mi_match(const meta_info *mi); 131 bool str_match_query(const char *s); 132 133 134 /***************************************************************************** 135 * Functions used to sort meta_info's. These work by setting-up a global 136 * sort description that includes the ordering of the CINFO items to sort and 137 * which, if any, to sort descending. 138 * 139 * Once the global sort description has been setup, mi_compare() can be used 140 * to compare two meta_info's in a way that works with qsort(3), heapsort(3), 141 * or mergesort(3). 142 ****************************************************************************/ 143 144 /* structure used to describe how to sort meta_info structs */ 145 typedef struct { 146 int order[MI_NUM_CINFO]; 147 bool descending[MI_NUM_CINFO]; 148 int nfields; 149 } mi_sort_description; 150 151 /* initialize, set, and clear global sort description */ 152 void mi_sort_init(); 153 void mi_sort_clear(); 154 int mi_sort_set(const char *str, const char **errmsg); 155 156 /* compare two meta_info's using the global sort description */ 157 int mi_compare(const void *a, const void *b); 158 159 160 /***************************************************************************** 161 * Functions to control how to display meta_info's to the screen. These 162 * setup a global description of the display format, which includes an ordered 163 * list of the fields and the width of each field. 164 ****************************************************************************/ 165 166 /* structure used to describe how to display meta_info structs */ 167 typedef struct { 168 int nfields; 169 int order[MI_NUM_CINFO]; 170 int widths[MI_NUM_CINFO]; 171 Direction align[MI_NUM_CINFO]; 172 } mi_display_description; 173 extern mi_display_description mi_display; 174 175 /* initialize and set the global display description */ 176 void mi_display_init(); 177 int mi_display_set(const char *str, const char **errmsg); 178 void mi_display_reset(); 179 180 /* convert current display to a string */ 181 char *mi_display_tostr(); 182 183 /* get total width of display */ 184 int mi_display_getwidth(); 185 186 #endif 187