mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-03 09:56:00 -05:00
Default browse/query
This commit is contained in:
parent
773028d478
commit
537233256b
15
configure.in
15
configure.in
@ -40,21 +40,6 @@ AC_ARG_ENABLE(howl,[ --enable-howl Use the howl mDNS library],
|
|||||||
no) rend_howl=false;;
|
no) rend_howl=false;;
|
||||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-howl);;
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-howl);;
|
||||||
esac ],[rend_howl=false])
|
esac ],[rend_howl=false])
|
||||||
AC_ARG_ENABLE(browse,[ --enable-browse enable experimenal browse support],
|
|
||||||
[ case "${enableval}" in
|
|
||||||
yes) opt_browse=true; CPPFLAGS="${CPPFLAGS} -DOPT_BROWSE";;
|
|
||||||
no) opt_browse=false;;
|
|
||||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-browse);;
|
|
||||||
esac ],[opt_browse=false])
|
|
||||||
AC_ARG_ENABLE(query,[ --enable-query enable experimenal query support],
|
|
||||||
[ case "${enableval}" in
|
|
||||||
yes) opt_query=true; CPPFLAGS="${CPPFLAGS} -DOPT_QUERY";;
|
|
||||||
no) opt_query=false;;
|
|
||||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-query);;
|
|
||||||
esac ],[opt_query=false])
|
|
||||||
|
|
||||||
AM_CONDITIONAL(OPT_BROWSE, test x$opt_browse = xtrue)
|
|
||||||
AM_CONDITIONAL(OPT_QUERY, test x$opt_query = xtrue)
|
|
||||||
|
|
||||||
AM_CONDITIONAL(COND_REND_HOWL, test x$rend_howl = xtrue)
|
AM_CONDITIONAL(COND_REND_HOWL, test x$rend_howl = xtrue)
|
||||||
AM_CONDITIONAL(COND_REND_POSIX, test x$rend_howl = xfalse)
|
AM_CONDITIONAL(COND_REND_POSIX, test x$rend_howl = xfalse)
|
||||||
|
@ -18,16 +18,12 @@ if COND_REND_OSX
|
|||||||
ORENDSRC=rend-osx.c
|
ORENDSRC=rend-osx.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if OPT_QUERY
|
|
||||||
QUERYSRC = query.c query.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
|
mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
|
||||||
webserver.h configfile.c configfile.h err.c err.h restart.c restart.h \
|
webserver.h configfile.c configfile.h err.c err.h restart.c restart.h \
|
||||||
daap-proto.c daap-proto.h daap.c daap.h db-gdbm.c db-memory.h \
|
daap-proto.c daap-proto.h daap.c daap.h db-gdbm.c db-memory.h \
|
||||||
mp3-scanner.h mp3-scanner.c playlist.c playlist.h rend-unix.c \
|
mp3-scanner.h mp3-scanner.c playlist.c playlist.h rend-unix.c \
|
||||||
rend-unix.h lexer.l parser.y strcasestr.c strcasestr.h strsep.c \
|
rend-unix.h lexer.l parser.y strcasestr.c strcasestr.h strsep.c \
|
||||||
redblack.c redblack.h dynamic-art.c dynamic-art.h \
|
redblack.c redblack.h dynamic-art.c dynamic-art.h query.c query.h \
|
||||||
$(PRENDSRC) $(ORENDSRC) $(HRENDSRC) $(QUERYSRC)
|
$(PRENDSRC) $(ORENDSRC) $(HRENDSRC) $(QUERYSRC)
|
||||||
|
|
||||||
EXTRA_DIST = mDNS.c mDNSClientAPI.h mDNSDebug.h mDNSPosix.c \
|
EXTRA_DIST = mDNS.c mDNSClientAPI.h mDNSDebug.h mDNSPosix.c \
|
||||||
|
41
src/daap.c
41
src/daap.c
@ -40,9 +40,7 @@
|
|||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "daapd.h"
|
#include "daapd.h"
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct tag_daap_items {
|
typedef struct tag_daap_items {
|
||||||
int type;
|
int type;
|
||||||
@ -138,7 +136,6 @@ DAAP_ITEMS taglist[] = {
|
|||||||
{ 0x00, NULL, NULL }
|
{ 0x00, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
#define OFFSET_OF(__type, __field) ((size_t) (&((__type*) 0)->__field))
|
#define OFFSET_OF(__type, __field) ((size_t) (&((__type*) 0)->__field))
|
||||||
|
|
||||||
static query_field_t song_fields[] = {
|
static query_field_t song_fields[] = {
|
||||||
@ -169,7 +166,6 @@ static query_field_t song_fields[] = {
|
|||||||
{ qft_i32, "daap.songyear", OFFSET_OF(MP3FILE, year) },
|
{ qft_i32, "daap.songyear", OFFSET_OF(MP3FILE, year) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Forwards */
|
/* Forwards */
|
||||||
|
|
||||||
@ -410,9 +406,8 @@ DAAP_BLOCK *daap_response_songlist(char* metaStr, char* query) {
|
|||||||
ENUMHANDLE henum;
|
ENUMHANDLE henum;
|
||||||
MP3FILE *current;
|
MP3FILE *current;
|
||||||
MetaField_t meta;
|
MetaField_t meta;
|
||||||
#ifdef OPT_QUERY
|
|
||||||
query_node_t* filter = 0;
|
query_node_t* filter = 0;
|
||||||
#endif
|
|
||||||
int songs = 0;
|
int songs = 0;
|
||||||
|
|
||||||
// if the meta tag is specified, encode it, if it's not specified
|
// if the meta tag is specified, encode it, if it's not specified
|
||||||
@ -423,7 +418,6 @@ DAAP_BLOCK *daap_response_songlist(char* metaStr, char* query) {
|
|||||||
else
|
else
|
||||||
meta = encodeMetaRequest(metaStr, gSongMetaDataMap);
|
meta = encodeMetaRequest(metaStr, gSongMetaDataMap);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != query)
|
if(0 != query)
|
||||||
{
|
{
|
||||||
filter = query_build(query, song_fields);
|
filter = query_build(query, song_fields);
|
||||||
@ -433,7 +427,6 @@ DAAP_BLOCK *daap_response_songlist(char* metaStr, char* query) {
|
|||||||
query_dump(stderr, filter, 0);
|
query_dump(stderr, filter, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
DPRINTF(ERR_DEBUG,"Preparing to send db items\n");
|
DPRINTF(ERR_DEBUG,"Preparing to send db items\n");
|
||||||
|
|
||||||
@ -454,9 +447,7 @@ DAAP_BLOCK *daap_response_songlist(char* metaStr, char* query) {
|
|||||||
|
|
||||||
if(mlcl) {
|
if(mlcl) {
|
||||||
while(g && (current=db_enum(&henum))) {
|
while(g && (current=db_enum(&henum))) {
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(filter == 0 || query_test(filter, current))
|
if(filter == 0 || query_test(filter, current))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
DPRINTF(ERR_DEBUG,"Got entry for %s\n",current->fname);
|
DPRINTF(ERR_DEBUG,"Got entry for %s\n",current->fname);
|
||||||
// song entry generation extracted for usage with
|
// song entry generation extracted for usage with
|
||||||
@ -470,10 +461,8 @@ DAAP_BLOCK *daap_response_songlist(char* metaStr, char* query) {
|
|||||||
|
|
||||||
db_enum_end(henum);
|
db_enum_end(henum);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(filter != 0)
|
if(filter != 0)
|
||||||
query_free(filter);
|
query_free(filter);
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!g) {
|
if(!g) {
|
||||||
DPRINTF(ERR_DEBUG,"Error enumerating database\n");
|
DPRINTF(ERR_DEBUG,"Error enumerating database\n");
|
||||||
@ -819,12 +808,8 @@ DAAP_BLOCK *daap_response_server_info(char *name, char *client_version) {
|
|||||||
g = g && daap_add_char(root,"msex",0); /* extensions */
|
g = g && daap_add_char(root,"msex",0); /* extensions */
|
||||||
g = g && daap_add_char(root,"msix",0); /* indexing? */
|
g = g && daap_add_char(root,"msix",0); /* indexing? */
|
||||||
|
|
||||||
#ifdef OPT_BROWSE
|
|
||||||
g = g && daap_add_char(root,"msbr",0); /* browsing */
|
g = g && daap_add_char(root,"msbr",0); /* browsing */
|
||||||
#endif
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
g = g && daap_add_char(root,"msqy",0); /* queries */
|
g = g && daap_add_char(root,"msqy",0); /* queries */
|
||||||
#endif
|
|
||||||
|
|
||||||
g = g && daap_add_char(root,"msup",0); /* update */
|
g = g && daap_add_char(root,"msup",0); /* update */
|
||||||
|
|
||||||
@ -859,9 +844,7 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
int itemid;
|
int itemid;
|
||||||
int g=1;
|
int g=1;
|
||||||
unsigned long long meta;
|
unsigned long long meta;
|
||||||
#ifdef OPT_QUERY
|
|
||||||
query_node_t* filter = 0;
|
query_node_t* filter = 0;
|
||||||
#endif
|
|
||||||
int songs = 0;
|
int songs = 0;
|
||||||
|
|
||||||
// if no meta information is specifically requested, return only
|
// if no meta information is specifically requested, return only
|
||||||
@ -877,7 +860,6 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
else
|
else
|
||||||
meta = encodeMetaRequest(metaStr, gSongMetaDataMap);
|
meta = encodeMetaRequest(metaStr, gSongMetaDataMap);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != query)
|
if(0 != query)
|
||||||
{
|
{
|
||||||
filter = query_build(query, song_fields);
|
filter = query_build(query, song_fields);
|
||||||
@ -887,7 +869,6 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
query_dump(stderr, filter, 0);
|
query_dump(stderr, filter, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
DPRINTF(ERR_DEBUG,"Preparing to send playlist items for pl #%d\n",playlist);
|
DPRINTF(ERR_DEBUG,"Preparing to send playlist items for pl #%d\n",playlist);
|
||||||
|
|
||||||
@ -914,9 +895,7 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
if(mlcl) {
|
if(mlcl) {
|
||||||
if(playlist == 1) {
|
if(playlist == 1) {
|
||||||
while((current=db_enum(&henum))) {
|
while((current=db_enum(&henum))) {
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 == filter || query_test(filter, current))
|
if(0 == filter || query_test(filter, current))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
songs++;
|
songs++;
|
||||||
mlit=daap_add_song_entry(mlcl, current, meta);
|
mlit=daap_add_song_entry(mlcl, current, meta);
|
||||||
@ -930,10 +909,8 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
while((itemid=db_playlist_items_enum(&henum)) != -1) {
|
while((itemid=db_playlist_items_enum(&henum)) != -1) {
|
||||||
current = db_find(itemid);
|
current = db_find(itemid);
|
||||||
if(0 != current) {
|
if(0 != current) {
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 == filter || query_test(filter, current))
|
if(0 == filter || query_test(filter, current))
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
songs++;
|
songs++;
|
||||||
DPRINTF(ERR_DEBUG,"Adding itemid %d\n",itemid);
|
DPRINTF(ERR_DEBUG,"Adding itemid %d\n",itemid);
|
||||||
mlit=daap_add_song_entry(mlcl,current,meta);
|
mlit=daap_add_song_entry(mlcl,current,meta);
|
||||||
@ -941,9 +918,7 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
if(wantsMeta(meta, metaContainerItemId)) // current->id?
|
if(wantsMeta(meta, metaContainerItemId)) // current->id?
|
||||||
g = g && daap_add_int(mlit,"mcti",playlist);
|
g = g && daap_add_int(mlit,"mcti",playlist);
|
||||||
} else g = 0;
|
} else g = 0;
|
||||||
#ifdef OPT_QUERY
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} else g = 0;
|
} else g = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -955,10 +930,8 @@ DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, c
|
|||||||
else
|
else
|
||||||
db_playlist_items_enum_end(henum);
|
db_playlist_items_enum_end(henum);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != filter)
|
if(0 != filter)
|
||||||
query_free(filter);
|
query_free(filter);
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!g) {
|
if(!g) {
|
||||||
daap_free(root);
|
daap_free(root);
|
||||||
@ -1105,7 +1078,6 @@ void daap_handle_index(DAAP_BLOCK* block, const char* index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPT_BROWSE
|
|
||||||
typedef struct _browse_item browse_item;
|
typedef struct _browse_item browse_item;
|
||||||
struct _browse_item
|
struct _browse_item
|
||||||
{
|
{
|
||||||
@ -1155,7 +1127,6 @@ static int count_browse_items(browse_item* root)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
/* in theory each type of browse has a separate subset of these fields
|
/* in theory each type of browse has a separate subset of these fields
|
||||||
which can be used for filtering, but it's just not worth the effort
|
which can be used for filtering, but it's just not worth the effort
|
||||||
and doesn't save anything */
|
and doesn't save anything */
|
||||||
@ -1166,7 +1137,6 @@ static query_field_t browse_fields[] = {
|
|||||||
{ qft_string, "daap.songcomposer", OFFSET_OF(MP3FILE, composer) },
|
{ qft_string, "daap.songcomposer", OFFSET_OF(MP3FILE, composer) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
DAAP_BLOCK* daap_response_browse(const char* name, const char* filter)
|
DAAP_BLOCK* daap_response_browse(const char* name, const char* filter)
|
||||||
{
|
{
|
||||||
@ -1205,7 +1175,6 @@ DAAP_BLOCK* daap_response_browse(const char* name, const char* filter)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != filter &&
|
if(0 != filter &&
|
||||||
0 == (query = query_build(filter, browse_fields)))
|
0 == (query = query_build(filter, browse_fields)))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1215,16 +1184,13 @@ DAAP_BLOCK* daap_response_browse(const char* name, const char* filter)
|
|||||||
fprintf(stderr, "query: %s\n", query);
|
fprintf(stderr, "query: %s\n", query);
|
||||||
query_dump(stderr, query, 0);
|
query_dump(stderr, query, 0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if(0 == (henum = db_enum_begin()))
|
if(0 == (henum = db_enum_begin()))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while((current = db_enum(&henum)))
|
while((current = db_enum(&henum)))
|
||||||
{
|
{
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 == query || query_test(query, current))
|
if(0 == query || query_test(query, current))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
char* name = * (char**) ((size_t) current + field);
|
char* name = * (char**) ((size_t) current + field);
|
||||||
|
|
||||||
@ -1255,24 +1221,19 @@ DAAP_BLOCK* daap_response_browse(const char* name, const char* filter)
|
|||||||
|
|
||||||
free_browse_items(items);
|
free_browse_items(items);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != query)
|
if(0 != query)
|
||||||
query_free(query);
|
query_free(query);
|
||||||
#endif
|
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free_browse_items(items);
|
free_browse_items(items);
|
||||||
|
|
||||||
#ifdef OPT_QUERY
|
|
||||||
if(0 != query)
|
if(0 != query)
|
||||||
query_free(query);
|
query_free(query);
|
||||||
#endif
|
|
||||||
|
|
||||||
if(root != 0)
|
if(root != 0)
|
||||||
daap_free(root);
|
daap_free(root);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -33,8 +33,6 @@ DAAP_BLOCK *daap_response_dbinfo(char *name);
|
|||||||
DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, char* query);
|
DAAP_BLOCK *daap_response_playlist_items(unsigned int playlist, char* metaStr, char* query);
|
||||||
void daap_handle_index(DAAP_BLOCK* block, const char* index);
|
void daap_handle_index(DAAP_BLOCK* block, const char* index);
|
||||||
DAAP_BLOCK* daap_add_song_entry(DAAP_BLOCK* mlcl, MP3FILE* song, unsigned long long meta);
|
DAAP_BLOCK* daap_add_song_entry(DAAP_BLOCK* mlcl, MP3FILE* song, unsigned long long meta);
|
||||||
#ifdef OPT_BROWSE
|
|
||||||
DAAP_BLOCK* daap_response_browse(const char* name, const char* filter);
|
DAAP_BLOCK* daap_response_browse(const char* name, const char* filter);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _DAAP_H_ */
|
#endif /* _DAAP_H_ */
|
||||||
|
@ -234,14 +234,12 @@ void daap_handler(WS_CONNINFO *pwsc) {
|
|||||||
free(uri);
|
free(uri);
|
||||||
root=daap_response_playlists(config.servername);
|
root=daap_response_playlists(config.servername);
|
||||||
config_set_status(pwsc,session_id,"Sending playlist info");
|
config_set_status(pwsc,session_id,"Sending playlist info");
|
||||||
#ifdef OPT_BROWSE
|
|
||||||
} else if (strncasecmp(last,"browse/",7)==0) {
|
} else if (strncasecmp(last,"browse/",7)==0) {
|
||||||
config_set_status(pwsc,session_id,"Compiling browse info");
|
config_set_status(pwsc,session_id,"Compiling browse info");
|
||||||
root = daap_response_browse(last + 7,
|
root = daap_response_browse(last + 7,
|
||||||
ws_getvar(pwsc, "filter"));
|
ws_getvar(pwsc, "filter"));
|
||||||
config_set_status(pwsc,session_id,"Sending browse info");
|
config_set_status(pwsc,session_id,"Sending browse info");
|
||||||
free(uri);
|
free(uri);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +60,14 @@
|
|||||||
* Typedefs
|
* Typedefs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
typedef struct tag_scan_id3header {
|
typedef struct tag_scan_id3header {
|
||||||
unsigned char id[3];
|
unsigned char id[3];
|
||||||
unsigned char version[2];
|
unsigned char version[2];
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
unsigned char size[4];
|
unsigned char size[4];
|
||||||
} SCAN_ID3HEADER;
|
} SCAN_ID3HEADER;
|
||||||
|
#pragma pack(0)
|
||||||
|
|
||||||
#define MAYBEFREE(a) { if((a)) free((a)); };
|
#define MAYBEFREE(a) { if((a)) free((a)); };
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user