2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "directory.h"
28 #include "song_print.h"
31 #include "stored_playlist.h"
37 typedef struct _ListCommandItem
{
39 const struct locate_item_list
*criteria
;
42 typedef struct _SearchStats
{
43 const struct locate_item_list
*criteria
;
45 unsigned long playTime
;
49 printDirectoryInDirectory(struct directory
*directory
, void *data
)
51 struct client
*client
= data
;
53 if (!directory_is_root(directory
))
54 client_printf(client
, "directory: %s\n", directory_get_path(directory
));
60 printSongInDirectory(struct song
*song
, G_GNUC_UNUSED
void *data
)
62 struct client
*client
= data
;
63 song_print_uri(client
, song
);
68 struct client
*client
;
69 const struct locate_item_list
*criteria
;
73 searchInDirectory(struct song
*song
, void *_data
)
75 struct search_data
*data
= _data
;
77 if (locate_song_search(song
, data
->criteria
))
78 song_print_info(data
->client
, song
);
84 searchForSongsIn(struct client
*client
, const char *name
,
85 const struct locate_item_list
*criteria
)
88 struct locate_item_list
*new_list
89 = locate_item_list_casefold(criteria
);
90 struct search_data data
;
93 data
.criteria
= new_list
;
95 ret
= db_walk(name
, searchInDirectory
, NULL
, &data
);
97 locate_item_list_free(new_list
);
103 findInDirectory(struct song
*song
, void *_data
)
105 struct search_data
*data
= _data
;
107 if (locate_song_match(song
, data
->criteria
))
108 song_print_info(data
->client
, song
);
114 findSongsIn(struct client
*client
, const char *name
,
115 const struct locate_item_list
*criteria
)
117 struct search_data data
;
119 data
.client
= client
;
120 data
.criteria
= criteria
;
122 return db_walk(name
, findInDirectory
, NULL
, &data
);
125 static void printSearchStats(struct client
*client
, SearchStats
*stats
)
127 client_printf(client
, "songs: %i\n", stats
->numberOfSongs
);
128 client_printf(client
, "playtime: %li\n", stats
->playTime
);
132 searchStatsInDirectory(struct song
*song
, void *data
)
134 SearchStats
*stats
= data
;
136 if (locate_song_match(song
, stats
->criteria
)) {
137 stats
->numberOfSongs
++;
138 stats
->playTime
+= song_get_duration(song
);
145 searchStatsForSongsIn(struct client
*client
, const char *name
,
146 const struct locate_item_list
*criteria
)
151 stats
.criteria
= criteria
;
152 stats
.numberOfSongs
= 0;
155 ret
= db_walk(name
, searchStatsInDirectory
, NULL
, &stats
);
157 printSearchStats(client
, &stats
);
162 int printAllIn(struct client
*client
, const char *name
)
164 return db_walk(name
, printSongInDirectory
,
165 printDirectoryInDirectory
, client
);
169 directoryAddSongToPlaylist(struct song
*song
, G_GNUC_UNUSED
void *data
)
171 return playlist_append_song(&g_playlist
, song
, NULL
);
179 directoryAddSongToStoredPlaylist(struct song
*song
, void *_data
)
181 struct add_data
*data
= _data
;
183 if (spl_append_song(data
->path
, song
) != 0)
188 int addAllIn(const char *name
)
190 return db_walk(name
, directoryAddSongToPlaylist
, NULL
, NULL
);
193 int addAllInToStoredPlaylist(const char *name
, const char *utf8file
)
195 struct add_data data
= {
199 return db_walk(name
, directoryAddSongToStoredPlaylist
, NULL
, &data
);
203 findAddInDirectory(struct song
*song
, void *_data
)
205 struct search_data
*data
= _data
;
207 if (locate_song_match(song
, data
->criteria
))
208 return directoryAddSongToPlaylist(song
, data
);
213 int findAddIn(struct client
*client
, const char *name
,
214 const struct locate_item_list
*criteria
)
216 struct search_data data
;
218 data
.client
= client
;
219 data
.criteria
= criteria
;
221 return db_walk(name
, findAddInDirectory
, NULL
, &data
);
225 directoryPrintSongInfo(struct song
*song
, void *data
)
227 struct client
*client
= data
;
228 song_print_info(client
, song
);
232 int printInfoForAllIn(struct client
*client
, const char *name
)
234 return db_walk(name
, directoryPrintSongInfo
,
235 printDirectoryInDirectory
, client
);
238 static ListCommandItem
*
239 newListCommandItem(int tagType
, const struct locate_item_list
*criteria
)
241 ListCommandItem
*item
= g_new(ListCommandItem
, 1);
243 item
->tagType
= tagType
;
244 item
->criteria
= criteria
;
249 static void freeListCommandItem(ListCommandItem
* item
)
255 visitTag(struct client
*client
, struct strset
*set
,
256 struct song
*song
, enum tag_type tagType
)
258 struct tag
*tag
= song
->tag
;
261 if (tagType
== LOCATE_TAG_FILE_TYPE
) {
262 song_print_uri(client
, song
);
269 for (unsigned i
= 0; i
< tag
->num_items
; i
++) {
270 if (tag
->items
[i
]->type
== tagType
) {
271 strset_add(set
, tag
->items
[i
]->value
);
280 struct list_tags_data
{
281 struct client
*client
;
282 ListCommandItem
*item
;
287 listUniqueTagsInDirectory(struct song
*song
, void *_data
)
289 struct list_tags_data
*data
= _data
;
290 ListCommandItem
*item
= data
->item
;
292 if (locate_song_match(song
, item
->criteria
))
293 visitTag(data
->client
, data
->set
, song
, item
->tagType
);
298 int listAllUniqueTags(struct client
*client
, int type
,
299 const struct locate_item_list
*criteria
)
302 ListCommandItem
*item
= newListCommandItem(type
, criteria
);
303 struct list_tags_data data
= {
308 if (type
>= 0 && type
<= TAG_NUM_OF_ITEM_TYPES
) {
309 data
.set
= strset_new();
312 ret
= db_walk(NULL
, listUniqueTagsInDirectory
, NULL
, &data
);
314 if (type
>= 0 && type
<= TAG_NUM_OF_ITEM_TYPES
) {
317 strset_rewind(data
.set
);
319 while ((value
= strset_next(data
.set
)) != NULL
)
320 client_printf(client
, "%s: %s\n",
321 tag_item_names
[type
],
324 strset_free(data
.set
);
327 freeListCommandItem(item
);