now more flexible list, search, find, where you can enter pairs of
"conditionals". Note that logical and is implied. git-svn-id: https://svn.musicpd.org/mpd/trunk@2624 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
		
							
								
								
									
										6
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								TODO
									
									
									
									
									
								
							@@ -1,13 +1,13 @@
 | 
			
		||||
0.12
 | 
			
		||||
----
 | 
			
		||||
*) rewrite search, find, locate to tag LocateTagItem pairs
 | 
			
		||||
 | 
			
		||||
*) better handle streams so they don't use TagTracker
 | 
			
		||||
 | 
			
		||||
*) implement listener socket protocol as documented here:
 | 
			
		||||
	http://www.musicpd.org/wiki/moin.cgi/MpdListenerProtocol
 | 
			
		||||
 | 
			
		||||
*) add support for coverart using freedesktop standard for icons/images
 | 
			
		||||
*) add support for coverart 
 | 
			
		||||
	*) using freedesktop standard for icons/images
 | 
			
		||||
	*) use coverart in tags in the audio file
 | 
			
		||||
 | 
			
		||||
*) rewrite saved playlist code
 | 
			
		||||
	*) abstract out saved playlists from playlist.c
 | 
			
		||||
 
 | 
			
		||||
@@ -444,17 +444,18 @@ int handleFind(FILE * fp, unsigned int * permission, int argArrayLength,
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	LocateTagItem * item = newLocateTagItem(argArray[1], argArray[2]);
 | 
			
		||||
	LocateTagItem * items;
 | 
			
		||||
	int numItems = newLocateTagItemArrayFromArgArray(argArray+1, 
 | 
			
		||||
			argArrayLength-1, &items);
 | 
			
		||||
 | 
			
		||||
	if(!item) {
 | 
			
		||||
		commandError(fp, ACK_ERROR_ARG, "\%s\" isn't recognized", 
 | 
			
		||||
				argArray[1]);
 | 
			
		||||
	if(numItems <= 0) {
 | 
			
		||||
		commandError(fp, ACK_ERROR_ARG, "incorrect ags", NULL); 
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        ret = findSongsIn(fp, NULL, item);
 | 
			
		||||
        ret = findSongsIn(fp, NULL, numItems, items);
 | 
			
		||||
 | 
			
		||||
	freeLocateTagItem(item);
 | 
			
		||||
	freeLocateTagItemArray(numItems, items);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -464,17 +465,18 @@ int handleSearch(FILE * fp, unsigned int * permission, int argArrayLength,
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	LocateTagItem * item = newLocateTagItem(argArray[1], argArray[2]);
 | 
			
		||||
	LocateTagItem * items;
 | 
			
		||||
	int numItems = newLocateTagItemArrayFromArgArray(argArray+1, 
 | 
			
		||||
			argArrayLength-1, &items);
 | 
			
		||||
 | 
			
		||||
	if(!item) {
 | 
			
		||||
		commandError(fp, ACK_ERROR_ARG, "\%s\" isn't recognized", 
 | 
			
		||||
				argArray[1]);
 | 
			
		||||
	if(numItems <= 0) {
 | 
			
		||||
		commandError(fp, ACK_ERROR_ARG, "incorrect ags", NULL); 
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        ret = searchForSongsIn(fp, NULL, item);
 | 
			
		||||
        ret = searchForSongsIn(fp, NULL, numItems, items);
 | 
			
		||||
 | 
			
		||||
	freeLocateTagItem(item);
 | 
			
		||||
	freeLocateTagItemArray(numItems, items);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -636,10 +638,20 @@ int handleList(FILE * fp, unsigned int * permission, int argArrayLength,
 | 
			
		||||
					argArray[2]);
 | 
			
		||||
		numConditionals = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		numConditionals = newLocateTagItemArrayFromArgArray(argArray+2,
 | 
			
		||||
					argArrayLength-2, &conditionals);
 | 
			
		||||
 | 
			
		||||
		if(numConditionals < 0) {
 | 
			
		||||
                	commandError(fp, ACK_ERROR_ARG,
 | 
			
		||||
					"not able to parse args", NULL);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
        
 | 
			
		||||
	ret = listAllUniqueTags(fp, tagType, numConditionals,conditionals);
 | 
			
		||||
 | 
			
		||||
	if(conditionals) free(conditionals);
 | 
			
		||||
	if(conditionals) freeLocateTagItemArray(numConditionals, conditionals);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -904,8 +916,8 @@ void initCommands() {
 | 
			
		||||
        addCommand(COMMAND_LSINFO      ,PERMISSION_READ,    0, 1,handleLsInfo,NULL);
 | 
			
		||||
        addCommand(COMMAND_RM          ,PERMISSION_CONTROL, 1, 1,handleRm,NULL);
 | 
			
		||||
        addCommand(COMMAND_PLAYLISTINFO,PERMISSION_READ,    0, 1,handlePlaylistInfo,NULL);
 | 
			
		||||
        addCommand(COMMAND_FIND        ,PERMISSION_READ,    2, 2,handleFind,NULL);
 | 
			
		||||
        addCommand(COMMAND_SEARCH      ,PERMISSION_READ,    2, 2,handleSearch,NULL);
 | 
			
		||||
        addCommand(COMMAND_FIND        ,PERMISSION_READ,    2,-1,handleFind,NULL);
 | 
			
		||||
        addCommand(COMMAND_SEARCH      ,PERMISSION_READ,    2,-1,handleSearch,NULL);
 | 
			
		||||
        addCommand(COMMAND_UPDATE      ,PERMISSION_ADMIN,   0, 1,handleUpdate,listHandleUpdate);
 | 
			
		||||
        addCommand(COMMAND_NEXT        ,PERMISSION_CONTROL, 0, 0,handleNext,NULL);
 | 
			
		||||
        addCommand(COMMAND_PREVIOUS    ,PERMISSION_CONTROL, 0, 0,handlePrevious,NULL);
 | 
			
		||||
@@ -915,7 +927,7 @@ void initCommands() {
 | 
			
		||||
        addCommand(COMMAND_RANDOM      ,PERMISSION_CONTROL, 1, 1,handleRandom,NULL);
 | 
			
		||||
        addCommand(COMMAND_STATS       ,PERMISSION_READ,    0, 0,handleStats,NULL);
 | 
			
		||||
        addCommand(COMMAND_CLEAR_ERROR ,PERMISSION_CONTROL, 0, 0,handleClearError,NULL);
 | 
			
		||||
        addCommand(COMMAND_LIST        ,PERMISSION_READ,    1, 2,handleList,NULL);
 | 
			
		||||
        addCommand(COMMAND_LIST        ,PERMISSION_READ,    1,-1,handleList,NULL);
 | 
			
		||||
        addCommand(COMMAND_MOVE        ,PERMISSION_CONTROL, 2, 2,handleMove,NULL);
 | 
			
		||||
        addCommand(COMMAND_MOVEID      ,PERMISSION_CONTROL, 2, 2,handleMoveId,NULL);
 | 
			
		||||
        addCommand(COMMAND_SWAP        ,PERMISSION_CONTROL, 2, 2,handleSwap,NULL);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										136
									
								
								src/dbUtils.c
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								src/dbUtils.c
									
									
									
									
									
								
							@@ -11,12 +11,17 @@
 | 
			
		||||
#define LOCATE_TAG_FILE_TYPE	TAG_NUM_OF_ITEM_TYPES+10
 | 
			
		||||
#define LOCATE_TAG_FILE_KEY	"filename"
 | 
			
		||||
 | 
			
		||||
typedef struct ListCommandItem {
 | 
			
		||||
typedef struct _ListCommandItem {
 | 
			
		||||
	mpd_sint8 tagType;
 | 
			
		||||
	int numConditionals;
 | 
			
		||||
	LocateTagItem * conditionals;
 | 
			
		||||
} ListCommandItem;
 | 
			
		||||
 | 
			
		||||
typedef struct _LocateTagItemArray {
 | 
			
		||||
	int numItems;
 | 
			
		||||
	LocateTagItem * items;
 | 
			
		||||
} LocateTagItemArray;
 | 
			
		||||
 | 
			
		||||
int getLocateTagItemType(char * str) {
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
@@ -31,21 +36,67 @@ int getLocateTagItemType(char * str) {
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int initLocateTagItem(LocateTagItem * item, char * typeStr, 
 | 
			
		||||
		char * needle)
 | 
			
		||||
{
 | 
			
		||||
	item->tagType = getLocateTagItemType(typeStr);
 | 
			
		||||
 | 
			
		||||
	if(item->tagType < 0) return -1;
 | 
			
		||||
 | 
			
		||||
	item->needle = strdup(needle);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LocateTagItem * newLocateTagItem(char * typeStr, char * needle) {
 | 
			
		||||
	LocateTagItem * ret = malloc(sizeof(LocateTagItem));
 | 
			
		||||
 | 
			
		||||
	ret->tagType = getLocateTagItemType(typeStr);
 | 
			
		||||
 | 
			
		||||
	if(ret->tagType < 0) {
 | 
			
		||||
	if(initLocateTagItem(ret, typeStr, needle) < 0) {
 | 
			
		||||
		free(ret);
 | 
			
		||||
		return NULL;
 | 
			
		||||
		ret = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret->needle = strdup(needle);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void freeLocateTagItemArray(int count, LocateTagItem * array) {
 | 
			
		||||
	int i;
 | 
			
		||||
	
 | 
			
		||||
	for(i = 0; i < count; i++) free(array[i].needle);
 | 
			
		||||
 | 
			
		||||
	free(array);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int newLocateTagItemArrayFromArgArray(char * argArray[],
 | 
			
		||||
						int numArgs,
 | 
			
		||||
						LocateTagItem ** arrayRet)
 | 
			
		||||
{
 | 
			
		||||
	int i,j;
 | 
			
		||||
	LocateTagItem * item;
 | 
			
		||||
	
 | 
			
		||||
	if(numArgs == 0) return 0;
 | 
			
		||||
 | 
			
		||||
	if(numArgs%2 != 0) return -1;
 | 
			
		||||
	
 | 
			
		||||
	*arrayRet = malloc(sizeof(LocateTagItem)*numArgs/2);
 | 
			
		||||
 | 
			
		||||
	for(i = 0, item = *arrayRet; i < numArgs/2; i++, item++) {
 | 
			
		||||
		if(initLocateTagItem(item, argArray[i*2], argArray[i*2+1]) < 0)
 | 
			
		||||
			goto fail;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return numArgs/2;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	for(j = 0; j < i; j++) {
 | 
			
		||||
		free((*arrayRet)[j].needle);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(*arrayRet);
 | 
			
		||||
	*arrayRet = NULL;
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void freeLocateTagItem(LocateTagItem * item) {
 | 
			
		||||
	free(item->needle);
 | 
			
		||||
	free(item);
 | 
			
		||||
@@ -96,25 +147,48 @@ static inline int strstrSearchTag(Song * song, int type, char * str) {
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int searchInDirectory(FILE * fp, Song * song, void * item) {
 | 
			
		||||
	if(strstrSearchTag(song, ((LocateTagItem *)item)->tagType,
 | 
			
		||||
			((LocateTagItem *)item)->needle)) {
 | 
			
		||||
		printSongInfo(fp, song);
 | 
			
		||||
int searchInDirectory(FILE * fp, Song * song, void * data) {
 | 
			
		||||
	LocateTagItemArray * array = data;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < array->numItems; i++) {
 | 
			
		||||
		if(!strstrSearchTag(song, array->items[i].tagType,
 | 
			
		||||
				array->items[i].needle)) 
 | 
			
		||||
		{
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printSongInfo(fp, song);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item) {
 | 
			
		||||
	char * originalNeedle = item->needle;
 | 
			
		||||
int searchForSongsIn(FILE * fp, char * name, int numItems, 
 | 
			
		||||
		LocateTagItem * items) 
 | 
			
		||||
{
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	item->needle = strDupToUpper(originalNeedle);
 | 
			
		||||
	char ** originalNeedles = malloc(numItems*sizeof(char *));
 | 
			
		||||
	LocateTagItemArray array;
 | 
			
		||||
 | 
			
		||||
	ret = traverseAllIn(fp,name,searchInDirectory, NULL,
 | 
			
		||||
			(void *)item);
 | 
			
		||||
	for(i = 0; i < numItems; i++) {
 | 
			
		||||
		originalNeedles[i] = items[i].needle;
 | 
			
		||||
		items[i].needle = strDupToUpper(originalNeedles[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(item->needle);
 | 
			
		||||
	item->needle = originalNeedle;
 | 
			
		||||
	array.numItems = numItems;
 | 
			
		||||
	array.items = items;
 | 
			
		||||
 | 
			
		||||
	ret = traverseAllIn(fp,name,searchInDirectory, NULL, &array);
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < numItems; i++) {
 | 
			
		||||
		free(items[i].needle);
 | 
			
		||||
		items[i].needle = originalNeedles[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(originalNeedles);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@@ -137,17 +211,31 @@ static inline int tagItemFoundAndMatches(Song * song, int type, char * str) {
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int findInDirectory(FILE * fp, Song * song, void * item) {
 | 
			
		||||
	if(tagItemFoundAndMatches(song, ((LocateTagItem *)item)->tagType,
 | 
			
		||||
			((LocateTagItem *)item)->needle)) {
 | 
			
		||||
		printSongInfo(fp, song);
 | 
			
		||||
int findInDirectory(FILE * fp, Song * song, void * data) {
 | 
			
		||||
	LocateTagItemArray * array = data;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < 0; i++) {
 | 
			
		||||
		if(!tagItemFoundAndMatches(song, array->items[i].tagType,
 | 
			
		||||
				array->items[i].needle)) 
 | 
			
		||||
		{
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printSongInfo(fp, song);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int findSongsIn(FILE * fp, char * name, LocateTagItem * item) {
 | 
			
		||||
int findSongsIn(FILE * fp, char * name, int numItems, LocateTagItem * items) {
 | 
			
		||||
	LocateTagItemArray array;
 | 
			
		||||
 | 
			
		||||
	array.numItems = numItems;
 | 
			
		||||
	array.items = items;
 | 
			
		||||
	
 | 
			
		||||
	return traverseAllIn(fp, name, findInDirectory, NULL,
 | 
			
		||||
			(void *)item);
 | 
			
		||||
			(void *)&array);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int printAllIn(FILE * fp, char * name) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,10 +12,17 @@ typedef struct _LocateTagItem {
 | 
			
		||||
	char * needle;
 | 
			
		||||
} LocateTagItem;
 | 
			
		||||
 | 
			
		||||
int getLocateTagItemType(char * str);
 | 
			
		||||
 | 
			
		||||
/* returns NULL if not a known type */
 | 
			
		||||
LocateTagItem * newLocateTagItem(char * typeString, char * needle);
 | 
			
		||||
 | 
			
		||||
int getLocateTagItemType(char * str);
 | 
			
		||||
/* return number of items or -1 on error */
 | 
			
		||||
int newLocateTagItemArrayFromArgArray(char * argArray[], int numArgs,
 | 
			
		||||
					LocateTagItem ** arrayRet);
 | 
			
		||||
						
 | 
			
		||||
 | 
			
		||||
void freeLocateTagItemArray(int count, LocateTagItem * array);
 | 
			
		||||
 | 
			
		||||
void freeLocateTagItem(LocateTagItem * item);
 | 
			
		||||
 | 
			
		||||
@@ -25,9 +32,11 @@ int addAllIn(FILE * fp, char * name);
 | 
			
		||||
 | 
			
		||||
int printInfoForAllIn(FILE * fp, char * name);
 | 
			
		||||
 | 
			
		||||
int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item);
 | 
			
		||||
int searchForSongsIn(FILE * fp, char * name, int numItems,
 | 
			
		||||
				LocateTagItem * items);
 | 
			
		||||
 | 
			
		||||
int findSongsIn(FILE * fp, char * name, LocateTagItem * item);
 | 
			
		||||
int findSongsIn(FILE * fp, char * name, int numItems, 
 | 
			
		||||
				LocateTagItem * items);
 | 
			
		||||
 | 
			
		||||
int countSongsIn(FILE * fp, char * name);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user