diff options
| -rw-r--r-- | libwaitress/src/waitress.c | 64 | ||||
| -rw-r--r-- | libwaitress/src/waitress.h | 1 | ||||
| -rw-r--r-- | src/main.c | 68 | ||||
| -rw-r--r-- | src/settings.h | 4 | ||||
| -rw-r--r-- | src/ui.c | 133 | ||||
| -rw-r--r-- | src/ui.h | 11 | ||||
| -rw-r--r-- | src/ui_act.c | 224 | 
7 files changed, 385 insertions, 120 deletions
| diff --git a/libwaitress/src/waitress.c b/libwaitress/src/waitress.c index 72f5f0f..b3ef618 100644 --- a/libwaitress/src/waitress.c +++ b/libwaitress/src/waitress.c @@ -488,3 +488,67 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {  #undef WRITE_RET  #undef READ_RET +const char *WaitressErrorToStr (WaitressReturn_t wRet) { +	switch (wRet) { +		case WAITRESS_RET_OK: +			return "Everything's fine :)"; +			break; + +		case WAITRESS_RET_ERR: +			return "Unknown."; +			break; + +		case WAITRESS_RET_STATUS_UNKNOWN: +			return "Unknown HTTP status code."; +			break; + +		case WAITRESS_RET_NOTFOUND: +			return "File not found."; +			break; +		 +		case WAITRESS_RET_FORBIDDEN: +			return "Forbidden."; +			break; + +		case WAITRESS_RET_CONNECT_REFUSED: +			return "Connection refused."; +			break; + +		case WAITRESS_RET_SOCK_ERR: +			return "Socket error."; +			break; + +		case WAITRESS_RET_GETADDR_ERR: +			return "getaddr failed."; +			break; + +		case WAITRESS_RET_CB_ABORT: +			return "Callback aborted request."; +			break; + +		case WAITRESS_RET_HDR_OVERFLOW: +			return "HTTP header overflow."; +			break; + +		case WAITRESS_RET_PARTIAL_FILE: +			return "Partial file."; +			break; +	 +		case WAITRESS_RET_TIMEOUT: +			return "Timeout."; +			break; + +		case WAITRESS_RET_READ_ERR: +			return "Read error."; +			break; + +		case WAITRESS_RET_CONNECTION_CLOSED: +			return "Connection closed by remote host."; +			break; + +		default: +			return "No error message available."; +			break; +	} +} + diff --git a/libwaitress/src/waitress.h b/libwaitress/src/waitress.h index ed5679f..04333fb 100644 --- a/libwaitress/src/waitress.h +++ b/libwaitress/src/waitress.h @@ -72,6 +72,7 @@ void WaitressSetHPP (WaitressHandle_t *, const char *, const char *,  		const char *);  WaitressReturn_t WaitressFetchBuf (WaitressHandle_t *, char **);  WaitressReturn_t WaitressFetchCall (WaitressHandle_t *); +const char *WaitressErrorToStr (WaitressReturn_t);  #endif /* _WAITRESS_H */ @@ -39,6 +39,7 @@ THE SOFTWARE.  /* tcset/getattr () */  #include <termios.h>  #include <pthread.h> +#include <assert.h>  /* pandora.com library */  #include <piano.h> @@ -54,6 +55,7 @@ THE SOFTWARE.  int main (int argc, char **argv) {  	/* handles */  	PianoHandle_t ph; +	WaitressHandle_t waith;  	static struct audioPlayer player;  	BarSettings_t settings;  	pthread_t playerThread; @@ -82,6 +84,11 @@ int main (int argc, char **argv) {  	/* init some things */  	ao_initialize ();  	PianoInit (&ph); + +	WaitressInit (&waith); +	strncpy (waith.host, PIANO_RPC_HOST, sizeof (waith.host)-1); +	strncpy (waith.port, PIANO_RPC_PORT, sizeof (waith.port)-1); +  	BarSettingsInit (&settings);  	BarSettingsRead (&settings); @@ -118,22 +125,36 @@ int main (int argc, char **argv) {  	/* setup control connection */  	if (settings.controlProxy != NULL) {  		char tmpPath[2]; -		WaitressSplitUrl (settings.controlProxy, ph.waith.proxyHost, -				sizeof (ph.waith.proxyHost), ph.waith.proxyPort, -				sizeof (ph.waith.proxyPort), tmpPath, sizeof (tmpPath)); +		WaitressSplitUrl (settings.controlProxy, waith.proxyHost, +				sizeof (waith.proxyHost), waith.proxyPort, +				sizeof (waith.proxyPort), tmpPath, sizeof (tmpPath));  	} -	BarUiMsg (MSG_INFO, "Login... "); -	if (BarUiPrintPianoStatus (PianoConnect (&ph, settings.username, -			settings.password)) != -			PIANO_RET_OK) { -		BarTermRestore (&termOrig); -		return 0; +	{ +		PianoReturn_t pRet; +		WaitressReturn_t wRet; +		PianoRequestDataLogin_t reqData; +		reqData.user = settings.username; +		reqData.password = settings.password; +		 +		BarUiMsg (MSG_INFO, "Login... "); +		if (!BarUiPianoCall (&ph, PIANO_REQUEST_LOGIN, &waith, &reqData, &pRet, +				&wRet)) { +			BarTermRestore (&termOrig); +			return 0; +		}  	} -	BarUiMsg (MSG_INFO, "Get stations... "); -	if (BarUiPrintPianoStatus (PianoGetStations (&ph)) != PIANO_RET_OK) { -		BarTermRestore (&termOrig); -		return 0; + +	{ +		PianoReturn_t pRet; +		WaitressReturn_t wRet; + +		BarUiMsg (MSG_INFO, "Get stations... "); +		if (!BarUiPianoCall (&ph, PIANO_REQUEST_GET_STATIONS, &waith, NULL, +				&pRet, &wRet)) { +			BarTermRestore (&termOrig); +			return 0; +		}  	}  	/* try to get autostart station */ @@ -160,7 +181,7 @@ int main (int argc, char **argv) {  		/* song finished playing, clean up things/scrobble song */  		if (player.mode == PLAYER_FINISHED_PLAYBACK) {  			BarUiStartEventCmd (&settings, "songfinish", curStation, playlist, -					&player, PIANO_RET_OK); +					&player, PIANO_RET_OK, WAITRESS_RET_OK);  			/* FIXME: pthread_join blocks everything if network connection  			 * is hung up e.g. */  			void *threadRet; @@ -210,21 +231,25 @@ int main (int argc, char **argv) {  					}  				}  				if (playlist == NULL) { -					PianoReturn_t pRet = PIANO_RET_ERR; +					PianoReturn_t pRet; +					WaitressReturn_t wRet; +					PianoRequestDataGetPlaylist_t reqData; +					reqData.station = curStation; +					reqData.format = settings.audioFormat;  					BarUiMsg (MSG_INFO, "Receiving new playlist... "); -					if ((pRet = BarUiPrintPianoStatus (PianoGetPlaylist (&ph, -							curStation->id, settings.audioFormat, -							&playlist))) != PIANO_RET_OK) { +					if (!BarUiPianoCall (&ph, PIANO_REQUEST_GET_PLAYLIST, +							&waith, &reqData, &pRet, &wRet)) {  						curStation = NULL;  					} else { +						playlist = reqData.retPlaylist;  						if (playlist == NULL) {  							BarUiMsg (MSG_INFO, "No tracks left.\n");  							curStation = NULL;  						}  					}  					BarUiStartEventCmd (&settings, "stationfetchplaylist", -							curStation, playlist, &player, pRet); +							curStation, playlist, &player, pRet, wRet);  				}  				/* song ready to play */  				if (playlist != NULL) { @@ -246,7 +271,8 @@ int main (int argc, char **argv) {  						/* throw event */  						BarUiStartEventCmd (&settings, "songstart", curStation, -								playlist, &player, PIANO_RET_OK); +								playlist, &player, PIANO_RET_OK, +								WAITRESS_RET_OK);  						/* prevent race condition, mode must _not_ be FREED if  						 * thread has been started */ @@ -289,7 +315,7 @@ int main (int argc, char **argv) {  							BarUiActSelectStation, BarUiActTempBanSong,  							BarUiActPrintUpcoming, BarUiActSelectQuickMix,  							BarUiActDebug, BarUiActBookmark}; -					idToF[i] (&ph, &player, &settings, &playlist, +					idToF[i] (&ph, &waith, &player, &settings, &playlist,  							&curStation, &songHistory, &doQuit, curFd);  					break;  				} diff --git a/src/settings.h b/src/settings.h index 6185b93..85ab71a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -25,10 +25,12 @@ THE SOFTWARE.  #define _SETTINGS_H  #include <piano.h> +#include <waitress.h>  #include "player.h" -#define BAR_KS_ARGS PianoHandle_t *ph, struct audioPlayer *player, \ +#define BAR_KS_ARGS PianoHandle_t *ph, WaitressHandle_t *waith, \ +		struct audioPlayer *player, \  		BarSettings_t *settings, PianoSong_t **curSong, \  		PianoStation_t **curStation, PianoSong_t **songHistory, char *doQuit, \  		FILE *curFd @@ -94,6 +94,81 @@ inline PianoReturn_t BarUiPrintPianoStatus (PianoReturn_t ret) {  	return ret;  } +/*	fetch http resource (post request) + *	@param waitress handle + *	@param piano request (initialized by PianoRequest()) + */ +static WaitressReturn_t BarPianoHttpRequest (WaitressHandle_t *waith, +		PianoRequest_t *req) { +	waith->extraHeaders = "Content-Type: text/xml\r\n"; +	waith->postData = req->postData; +	waith->method = WAITRESS_METHOD_POST; +	strncpy (waith->path, req->urlPath, sizeof (waith->path)-1); + +	return WaitressFetchBuf (waith, &req->responseData); +} + +/*	piano wrapper: prepare/execute http request and pass result back to + *	libpiano (updates data structures) + *	@param piano handle + *	@param request type + *	@param waitress handle + *	@param data pointer (used as request data) + *	@return 1 on success, 0 otherwise + */ +int BarUiPianoCall (PianoHandle_t *ph, PianoRequestType_t type, +		WaitressHandle_t *waith, void *data, PianoReturn_t *pRet, +		WaitressReturn_t *wRet) { +	PianoRequest_t req; + +	memset (&req, 0, sizeof (req)); + +	/* repeat as long as there are http requests to do */ +	do { +		req.data = data; + +		*pRet = PianoRequest (ph, &req, type); +		if (*pRet != PIANO_RET_OK) { +			BarUiMsg (MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); +			PianoDestroyRequest (&req); +			return 0; +		} + +		*wRet = BarPianoHttpRequest (waith, &req); +		if (*wRet != WAITRESS_RET_OK) { +			BarUiMsg (MSG_NONE, "Network error: %s\n", WaitressErrorToStr (*wRet)); +			PianoDestroyRequest (&req); +			if (req.responseData != NULL) { +				free (req.responseData); +			} +			return 0; +		} + +		*pRet = PianoResponse (ph, &req); +		if (*pRet != PIANO_RET_CONTINUE_REQUEST) { +			if (*pRet != PIANO_RET_OK) { +				BarUiMsg (MSG_NONE, "Error: %s\n", PianoErrorToStr (*pRet)); +				PianoDestroyRequest (&req); +				if (req.responseData != NULL) { +					free (req.responseData); +				} +				return 0; +			} else { +				BarUiMsg (MSG_NONE, "Ok.\n"); +			} +		} +		/* we can destroy the request at this point, even when this call needs +		 * more than one http request. persistend data (step counter, e.g.) is +		 * stored in req.data */ +		if (req.responseData != NULL) { +			free (req.responseData); +		} +		PianoDestroyRequest (&req); +	} while (*pRet == PIANO_RET_CONTINUE_REQUEST); + +	return 1; +} +  /*	compare stations by name (ignore case)   *	@param station a   *	@param station b @@ -232,7 +307,8 @@ PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd) {   *	@param allow seed suggestions if != NULL   *	@return musicId or NULL on abort/error   */ -char *BarUiSelectMusicId (PianoHandle_t *ph, FILE *curFd, char *similarToId) { +char *BarUiSelectMusicId (PianoHandle_t *ph, WaitressHandle_t *waith, +		FILE *curFd, char *similarToId) {  	char *musicId = NULL;  	char lineBuf[100], selectBuf[2];  	PianoSearchResult_t searchResult; @@ -242,20 +318,36 @@ char *BarUiSelectMusicId (PianoHandle_t *ph, FILE *curFd, char *similarToId) {  	BarUiMsg (MSG_QUESTION, "Search for artist/title: ");  	if (BarReadlineStr (lineBuf, sizeof (lineBuf), 0, curFd) > 0) {  		if (strcmp ("?", lineBuf) == 0 && similarToId != NULL) { +			PianoReturn_t pRet; +			WaitressReturn_t wRet; +			PianoRequestDataGetSeedSuggestions_t reqData; + +			reqData.musicId = similarToId; +			reqData.max = 20; +  			BarUiMsg (MSG_INFO, "Receiving suggestions... "); -			if (BarUiPrintPianoStatus (PianoSeedSuggestions (ph, similarToId, -					20, &searchResult)) != PIANO_RET_OK) { +			if (!BarUiPianoCall (ph, PIANO_REQUEST_GET_SEED_SUGGESTIONS, +					waith, &reqData, &pRet, &wRet)) {  				return NULL;  			} +			memcpy (&searchResult, &reqData.searchResult, sizeof (searchResult));  		} else { +			PianoReturn_t pRet; +			WaitressReturn_t wRet; +			PianoRequestDataSearch_t reqData; + +			reqData.searchStr = lineBuf; +  			BarUiMsg (MSG_INFO, "Searching... "); -			if (BarUiPrintPianoStatus (PianoSearchMusic (ph, lineBuf, -					&searchResult)) != PIANO_RET_OK) { +			if (!BarUiPianoCall (ph, PIANO_REQUEST_SEARCH, waith, &reqData, +					&pRet, &wRet)) {  				return NULL;  			} +			memcpy (&searchResult, &reqData.searchResult, sizeof (searchResult));  		}  		BarUiMsg (MSG_NONE, "\r"); -		if (searchResult.songs != NULL && searchResult.artists != NULL) { +		if (searchResult.songs != NULL && +				searchResult.artists != NULL) {  			/* songs and artists found */  			BarUiMsg (MSG_QUESTION, "Is this an [a]rtist or [t]rack name? ");  			BarReadline (selectBuf, sizeof (selectBuf), "at", 1, 0, curFd); @@ -294,16 +386,22 @@ char *BarUiSelectMusicId (PianoHandle_t *ph, FILE *curFd, char *similarToId) {  /*	browse genre stations and create shared station   *	@param piano handle   */ -void BarStationFromGenre (PianoHandle_t *ph, FILE *curFd) { -	int i; +void BarStationFromGenre (PianoHandle_t *ph, WaitressHandle_t *waith, FILE *curFd) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	PianoGenreCategory_t *curCat;  	PianoStation_t *curStation; +	PianoRequestDataCreateStation_t reqData; +	int i;  	/* receive genre stations list if not yet available */  	if (ph->genreStations == NULL) { +		PianoReturn_t pRet; +		WaitressReturn_t wRet; +  		BarUiMsg (MSG_INFO, "Receiving genre stations... "); -		if (BarUiPrintPianoStatus (PianoGetGenreStations (ph)) != -				PIANO_RET_OK) { +		if (!BarUiPianoCall (ph, PIANO_REQUEST_GET_GENRE_STATIONS, waith, NULL, +				&pRet, &wRet)) {  			return;  		}  	} @@ -346,7 +444,10 @@ void BarStationFromGenre (PianoHandle_t *ph, FILE *curFd) {  	}  	/* create station */  	BarUiMsg (MSG_INFO, "Adding shared station \"%s\"... ", curStation->name); -	BarUiPrintPianoStatus (PianoCreateStation (ph, "sh", curStation->id)); +	reqData.id = curStation->id; +	reqData.type = "sh"; +	BarUiPianoCall (ph, PIANO_REQUEST_CREATE_STATION, waith, &reqData, &pRet, +			&wRet);  }  /*	Print station infos (including station id) @@ -373,11 +474,13 @@ inline void BarUiPrintSong (PianoSong_t *song, PianoStation_t *station) {   *	@param event type   *	@param current station   *	@param current song - *	@param piano error-code + *	@param piano error-code (PIANO_RET_OK if not applicable) + *	@param waitress error-code (WAITRESS_RET_OK if not applicable)   */  void BarUiStartEventCmd (const BarSettings_t *settings, const char *type,  		const PianoStation_t *curStation, const PianoSong_t *curSong, -		const struct audioPlayer *player, PianoReturn_t pRet) { +		const struct audioPlayer *player, PianoReturn_t pRet, +		WaitressReturn_t wRet) {  	pid_t chld;  	char pipeBuf[1024];  	int pipeFd[2]; @@ -396,6 +499,8 @@ void BarUiStartEventCmd (const BarSettings_t *settings, const char *type,  			"stationName=%s\n"  			"pRet=%i\n"  			"pRetStr=%s\n" +			"wRet=%i\n" +			"wRetStr=%s\n"  			"songDuration=%lu\n"  			"songPlayed=%lu\n"  			"rating=%i\n", @@ -405,6 +510,8 @@ void BarUiStartEventCmd (const BarSettings_t *settings, const char *type,  			curStation == NULL ? "" : curStation->name,  			pRet,  			PianoErrorToStr (pRet), +			wRet, +			WaitressErrorToStr (wRet),  			player->songDuration,  			player->songPlayed,  			curSong == NULL ? PIANO_RATE_NONE : curSong->rating @@ -25,6 +25,7 @@ THE SOFTWARE.  #define _UI_H  #include <piano.h> +#include <waitress.h>  #include "settings.h"  #include "player.h" @@ -38,12 +39,14 @@ PianoStation_t *BarUiSelectStation (PianoHandle_t *ph, const char *prompt,  		FILE *curFd);  PianoSong_t *BarUiSelectSong (PianoSong_t *startSong, FILE *curFd);  PianoArtist_t *BarUiSelectArtist (PianoArtist_t *startArtist, FILE *curFd); -char *BarUiSelectMusicId (PianoHandle_t *ph, FILE *curFd, char *); -void BarStationFromGenre (PianoHandle_t *ph, FILE *curFd); +char *BarUiSelectMusicId (PianoHandle_t *ph, WaitressHandle_t *, FILE *curFd, char *); +void BarStationFromGenre (PianoHandle_t *ph, WaitressHandle_t *, FILE *curFd);  void BarUiPrintStation (PianoStation_t *);  void BarUiPrintSong (PianoSong_t *, PianoStation_t *);  void BarUiStartEventCmd (const BarSettings_t *, const char *, -		const PianoStation_t *, const PianoSong_t *, -		const struct audioPlayer *, PianoReturn_t); +		const PianoStation_t *, const PianoSong_t *, const struct audioPlayer *, +		PianoReturn_t, WaitressReturn_t); +int BarUiPianoCall (PianoHandle_t *, PianoRequestType_t, WaitressHandle_t *, +		void *, PianoReturn_t *, WaitressReturn_t *);  #endif /* _UI_H */ diff --git a/src/ui_act.c b/src/ui_act.c index 23b0f34..bb0769b 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -52,12 +52,16 @@ static inline void BarUiDoSkipSong (struct audioPlayer *player) {   *	@param transform this station   *	@return 0 = error, 1 = everything went well   */ -static int BarTransformIfShared (PianoHandle_t *ph, PianoStation_t *station) { +static int BarTransformIfShared (PianoHandle_t *ph, WaitressHandle_t *waith, +		PianoStation_t *station) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +  	/* shared stations must be transformed */  	if (!station->isCreator) {  		BarUiMsg (MSG_INFO, "Transforming station... "); -		if (BarUiPrintPianoStatus (PianoTransformShared (ph, station)) != -				PIANO_RET_OK) { +		if (!BarUiPianoCall (ph, PIANO_REQUEST_TRANSFORM_STATION, waith, +				station, &pRet, &wRet)) {  			return 0;  		}  	} @@ -104,81 +108,100 @@ void BarUiActHelp (BAR_KS_ARGS) {  /*	add more music to current station   */  void BarUiActAddMusic (BAR_KS_ARGS) { -	char *musicId; -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +	PianoRequestDataAddSeed_t reqData;  	RETURN_IF_NO_STATION; -	musicId = BarUiSelectMusicId (ph, curFd, (*curSong)->musicId); -	if (musicId != NULL) { -		if (!BarTransformIfShared (ph, *curStation)) { +	reqData.musicId = BarUiSelectMusicId (ph, waith, curFd, (*curSong)->musicId); +	if (reqData.musicId != NULL) { +		if (!BarTransformIfShared (ph, waith, *curStation)) {  			return;  		} +		reqData.station = *curStation; +  		BarUiMsg (MSG_INFO, "Adding music to station... "); -		pRet = BarUiPrintPianoStatus (PianoStationAddMusic (ph, *curStation, musicId)); -		free (musicId); +		BarUiPianoCall (ph, PIANO_REQUEST_ADD_SEED, waith, &reqData, &pRet, +				&wRet); + +		free (reqData.musicId);  		BarUiStartEventCmd (settings, "stationaddmusic", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  }  /*	ban song   */  void BarUiActBanSong (BAR_KS_ARGS) { -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	RETURN_IF_NO_SONG; -	if (!BarTransformIfShared (ph, *curStation)) { +	if (!BarTransformIfShared (ph, waith, *curStation)) {  		return;  	} + +	PianoRequestDataRateSong_t reqData; +	reqData.song = *curSong; +	reqData.rating = PIANO_RATE_BAN; +  	BarUiMsg (MSG_INFO, "Banning song... "); -	if ((pRet = BarUiPrintPianoStatus (PianoRateTrack (ph, *curSong, -			PIANO_RATE_BAN))) == PIANO_RET_OK) { +	if (BarUiPianoCall (ph, PIANO_REQUEST_RATE_SONG, waith, &reqData, &pRet, +			&wRet)) {  		BarUiDoSkipSong (player);  	}  	BarUiStartEventCmd (settings, "songban", *curStation, *curSong, player, -			pRet); +			pRet, wRet);  }  /*	create new station   */  void BarUiActCreateStation (BAR_KS_ARGS) { -	char *musicId; -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +	PianoRequestDataCreateStation_t reqData; -	musicId = BarUiSelectMusicId (ph, curFd, NULL); -	if (musicId != NULL) { +	reqData.id = BarUiSelectMusicId (ph, waith, curFd, NULL); +	if (reqData.id != NULL) { +		reqData.type = "mi";  		BarUiMsg (MSG_INFO, "Creating station... "); -		pRet = BarUiPrintPianoStatus (PianoCreateStation (ph, "mi", musicId)); -		free (musicId); +		BarUiPianoCall (ph, PIANO_REQUEST_CREATE_STATION, waith, &reqData, +				&pRet, &wRet); +		free (reqData.id);  		BarUiStartEventCmd (settings, "stationcreate", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  }  /*	add shared station by id   */  void BarUiActAddSharedStation (BAR_KS_ARGS) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +	PianoRequestDataCreateStation_t reqData;  	char stationId[50]; -	PianoReturn_t pRet = PIANO_RET_ERR;  	BarUiMsg (MSG_QUESTION, "Station id: ");  	if (BarReadline (stationId, sizeof (stationId), "0123456789", 0, 0,  			curFd) > 0) { +		reqData.id = stationId; +		reqData.type = "sh";  		BarUiMsg (MSG_INFO, "Adding shared station... "); -		pRet = BarUiPrintPianoStatus (PianoCreateStation (ph, "sh", -				(char *) stationId)); +		BarUiPianoCall (ph, PIANO_REQUEST_CREATE_STATION, waith, &reqData, +				&pRet, &wRet);  		BarUiStartEventCmd (settings, "stationaddshared", *curStation, -				*curSong, player, pRet); +				*curSong, player, pRet, wRet);  	}  }  /*	delete current station   */  void BarUiActDeleteStation (BAR_KS_ARGS) { -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	RETURN_IF_NO_STATION; @@ -186,41 +209,44 @@ void BarUiActDeleteStation (BAR_KS_ARGS) {  			(*curStation)->name);  	if (BarReadlineYesNo (0, curFd)) {  		BarUiMsg (MSG_INFO, "Deleting station... "); -		if ((pRet = BarUiPrintPianoStatus (PianoDeleteStation (ph, -				*curStation))) == PIANO_RET_OK) { +		if (BarUiPianoCall (ph, PIANO_REQUEST_DELETE_STATION, waith, +				*curStation, &pRet, &wRet)) {  			BarUiDoSkipSong (player);  			PianoDestroyPlaylist (*curSong);  			*curSong = NULL;  			*curStation = NULL;  		}  		BarUiStartEventCmd (settings, "stationdelete", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  }  /*	explain pandora's song choice   */  void BarUiActExplain (BAR_KS_ARGS) { -	char *explanation; -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +	PianoRequestDataExplain_t reqData;  	RETURN_IF_NO_STATION; +	reqData.song = *curSong; +  	BarUiMsg (MSG_INFO, "Receiving explanation... "); -	if ((pRet = BarUiPrintPianoStatus (PianoExplain (ph, *curSong, -			&explanation))) == PIANO_RET_OK) { -		BarUiMsg (MSG_INFO, "%s\n", explanation); -		free (explanation); +	if (BarUiPianoCall (ph, PIANO_REQUEST_EXPLAIN, waith, &reqData, &pRet, +			&wRet)) { +		BarUiMsg (MSG_INFO, "%s\n", reqData.retExplain); +		free (reqData.retExplain);  	}  	BarUiStartEventCmd (settings, "songexplain", *curStation, *curSong, player, -			pRet); +			pRet, wRet);  }  /*	choose genre station and add it as shared station   */  void BarUiActStationFromGenre (BAR_KS_ARGS) {  	/* use genre station */ -	BarStationFromGenre (ph, curFd); +	BarStationFromGenre (ph, waith, curFd);  }  /*	print verbose song information @@ -264,17 +290,24 @@ void BarUiActDebug (BAR_KS_ARGS) {  /*	rate current song   */  void BarUiActLoveSong (BAR_KS_ARGS) { -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	RETURN_IF_NO_SONG; -	if (!BarTransformIfShared (ph, *curStation)) { +	if (!BarTransformIfShared (ph, waith, *curStation)) {  		return;  	} + +	PianoRequestDataRateSong_t reqData; +	reqData.song = *curSong; +	reqData.rating = PIANO_RATE_LOVE; +  	BarUiMsg (MSG_INFO, "Loving song... "); -	pRet = BarUiPrintPianoStatus (PianoRateTrack (ph, *curSong, PIANO_RATE_LOVE)); +	BarUiPianoCall (ph, PIANO_REQUEST_RATE_SONG, waith, &reqData, &pRet, +			&wRet);  	BarUiStartEventCmd (settings, "songlove", *curStation, *curSong, player, -			pRet); +			pRet, wRet);  }  /*	skip song @@ -286,29 +319,36 @@ void BarUiActSkipSong (BAR_KS_ARGS) {  /*	move song to different station   */  void BarUiActMoveSong (BAR_KS_ARGS) { -	PianoStation_t *moveStation, *fromStation; -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet; +	PianoRequestDataMoveSong_t reqData; + +	reqData.step = 0;  	RETURN_IF_NO_SONG; -	moveStation = BarUiSelectStation (ph, "Move song to station: ", curFd); -	if (moveStation != NULL) { -		if (!BarTransformIfShared (ph, *curStation) || -				!BarTransformIfShared (ph, moveStation)) { +	reqData.to = BarUiSelectStation (ph, "Move song to station: ", curFd); +	if (reqData.to != NULL) { +		/* find original station (just is case we're playing a quickmix +		 * station) */ +		reqData.from = PianoFindStationById (ph->stations, (*curSong)->stationId); +		if (reqData.from == NULL) { +			BarUiMsg (MSG_ERR, "Station not found\n");  			return;  		} -		BarUiMsg (MSG_INFO, "Moving song to \"%s\"... ", moveStation->name); -		fromStation = PianoFindStationById (ph->stations, (*curSong)->stationId); -		if (fromStation == NULL) { -			BarUiMsg (MSG_ERR, "Station not found\n"); + +		if (!BarTransformIfShared (ph, waith, reqData.from) || +				!BarTransformIfShared (ph, waith, reqData.to)) {  			return;  		} -		if ((pRet = BarUiPrintPianoStatus (PianoMoveSong (ph, fromStation, -				moveStation, *curSong))) == PIANO_RET_OK) { +		BarUiMsg (MSG_INFO, "Moving song to \"%s\"... ", reqData.to->name); +		reqData.song = *curSong; +		if (BarUiPianoCall (ph, PIANO_REQUEST_MOVE_SONG, waith, &reqData, +				&pRet, &wRet)) {  			BarUiDoSkipSong (player);  		}  		BarUiStartEventCmd (settings, "songmove", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  } @@ -324,21 +364,27 @@ void BarUiActPause (BAR_KS_ARGS) {  /*	rename current station   */  void BarUiActRenameStation (BAR_KS_ARGS) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	char lineBuf[100]; -	PianoReturn_t pRet = PIANO_RET_ERR;  	RETURN_IF_NO_STATION;  	BarUiMsg (MSG_QUESTION, "New name: ");  	if (BarReadlineStr (lineBuf, sizeof (lineBuf), 0, curFd) > 0) { -		if (!BarTransformIfShared (ph, *curStation)) { +		PianoRequestDataRenameStation_t reqData; +		if (!BarTransformIfShared (ph, waith, *curStation)) {  			return;  		} + +		reqData.station = *curStation; +		reqData.newName = lineBuf; +  		BarUiMsg (MSG_INFO, "Renaming station... "); -		pRet = BarUiPrintPianoStatus (PianoRenameStation (ph, *curStation, -				(char *) lineBuf)); +		BarUiPianoCall (ph, PIANO_REQUEST_RENAME_STATION, waith, &reqData, +				&pRet, &wRet);  		BarUiStartEventCmd (settings, "stationrename", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  } @@ -357,17 +403,18 @@ void BarUiActSelectStation (BAR_KS_ARGS) {  /*	ban song for 1 month   */  void BarUiActTempBanSong (BAR_KS_ARGS) { -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	RETURN_IF_NO_SONG;  	BarUiMsg (MSG_INFO, "Putting song on shelf... "); -	if ((pRet = BarUiPrintPianoStatus (PianoSongTired (ph, *curSong))) == -			PIANO_RET_OK) { +	if (BarUiPianoCall (ph, PIANO_REQUEST_ADD_TIRED_SONG, waith, *curSong, +			&pRet, &wRet)) {  		BarUiDoSkipSong (player);  	}  	BarUiStartEventCmd (settings, "songshelf", *curStation, *curSong, player, -			pRet); +			pRet, wRet);  }  /*	print upcoming songs @@ -393,7 +440,8 @@ void BarUiActPrintUpcoming (BAR_KS_ARGS) {   *	quickmix   */  void BarUiActSelectQuickMix (BAR_KS_ARGS) { -	PianoReturn_t pRet = PIANO_RET_ERR; +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	RETURN_IF_NO_STATION; @@ -404,9 +452,10 @@ void BarUiActSelectQuickMix (BAR_KS_ARGS) {  			selStation->useQuickMix = !selStation->useQuickMix;  		}  		BarUiMsg (MSG_INFO, "Setting quickmix stations... "); -		pRet = BarUiPrintPianoStatus (PianoSetQuickmix (ph)); +		BarUiPianoCall (ph, PIANO_REQUEST_SET_QUICKMIX, waith, NULL, &pRet, +				&wRet);  		BarUiStartEventCmd (settings, "stationquickmixtoggle", *curStation, -				*curSong, player, pRet); +				*curSong, player, pRet, wRet);  	} else {  		BarUiMsg (MSG_ERR, "Not a QuickMix station.\n");  	} @@ -422,6 +471,8 @@ void BarUiActQuit (BAR_KS_ARGS) {  /*	song history   */  void BarUiActHistory (BAR_KS_ARGS) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	char selectBuf[2], allowedBuf[3];  	PianoSong_t *selectedSong; @@ -440,7 +491,6 @@ void BarUiActHistory (BAR_KS_ARGS) {  			if (selectBuf[0] == settings->keys[BAR_KS_LOVE] ||  					selectBuf[0] == settings->keys[BAR_KS_BAN]) { -				PianoReturn_t pRet = PIANO_RET_ERR;  				/* make sure we're transforming the _original_ station (not  				 * curStation) */  				PianoStation_t *songStation = @@ -452,23 +502,32 @@ void BarUiActHistory (BAR_KS_ARGS) {  					return;  				} -				if (!BarTransformIfShared (ph, songStation)) { +				if (!BarTransformIfShared (ph, waith, songStation)) {  					return;  				}  				if (selectBuf[0] == settings->keys[BAR_KS_LOVE]) {  					/* FIXME: copy&waste */ +					PianoRequestDataRateSong_t reqData; +					reqData.song = selectedSong; +					reqData.rating = PIANO_RATE_LOVE; +  					BarUiMsg (MSG_INFO, "Loving song... "); -					pRet = BarUiPrintPianoStatus (PianoRateTrack (ph, -							selectedSong, PIANO_RATE_LOVE)); +					BarUiPianoCall (ph, PIANO_REQUEST_RATE_SONG, waith, +							&reqData, &pRet, &wRet); +  					BarUiStartEventCmd (settings, "songlove", songStation, -							selectedSong, player, pRet); +							selectedSong, player, pRet, wRet);  				} else if (selectBuf[0] == settings->keys[BAR_KS_BAN]) { +					PianoRequestDataRateSong_t reqData; +					reqData.song = selectedSong; +					reqData.rating = PIANO_RATE_BAN; +  					BarUiMsg (MSG_INFO, "Banning song... "); -					pRet = BarUiPrintPianoStatus (PianoRateTrack (ph, -							selectedSong, PIANO_RATE_BAN)); +					BarUiPianoCall (ph, PIANO_REQUEST_RATE_SONG, waith, +							&reqData, &pRet, &wRet);  					BarUiStartEventCmd (settings, "songban", songStation, -							selectedSong, player, pRet); +							selectedSong, player, pRet, wRet);  				} /* end if */  			} /* end if selectBuf[0] */  		} /* end if selectedSong != NULL */ @@ -481,8 +540,9 @@ void BarUiActHistory (BAR_KS_ARGS) {  /*	create song bookmark   */  void BarUiActBookmark (BAR_KS_ARGS) { +	PianoReturn_t pRet; +	WaitressReturn_t wRet;  	char selectBuf[2]; -	PianoReturn_t pRet = PIANO_RET_ERR;  	RETURN_IF_NO_SONG; @@ -490,14 +550,16 @@ void BarUiActBookmark (BAR_KS_ARGS) {  	BarReadline (selectBuf, sizeof (selectBuf), "sa", 1, 0, curFd);  	if (selectBuf[0] == 's') {  		BarUiMsg (MSG_INFO, "Bookmarking song... "); -		pRet = BarUiPrintPianoStatus (PianoBookmarkSong (ph, *curSong)); +		BarUiPianoCall (ph, PIANO_REQUEST_BOOKMARK_SONG, waith, *curSong, +				&pRet, &wRet);  		BarUiStartEventCmd (settings, "songbookmark", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	} else if (selectBuf[0] == 'a') {  		BarUiMsg (MSG_INFO, "Bookmarking artist... "); -		pRet = BarUiPrintPianoStatus (PianoBookmarkArtist (ph, *curSong)); +		BarUiPianoCall (ph, PIANO_REQUEST_BOOKMARK_ARTIST, waith, *curSong, +				&pRet, &wRet);  		BarUiStartEventCmd (settings, "artistbookmark", *curStation, *curSong, -				player, pRet); +				player, pRet, wRet);  	}  } | 
