From ba60fbc4274e85fb63d373207f525aa57bc75eb3 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sat, 22 Oct 2011 16:34:48 +0200 Subject: Support seed stations Fixes #165 --- src/libpiano/piano.c | 7 ++++++- src/libpiano/piano.h | 3 +++ src/libpiano/xml.c | 32 +++++++++++++++++++++++++++++--- src/main.c | 2 +- src/ui.c | 8 ++++---- src/ui.h | 3 ++- src/ui_act.c | 27 +++++++++++++++++++++------ 7 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c index d6071f2..9a7e8d3 100644 --- a/src/libpiano/piano.c +++ b/src/libpiano/piano.c @@ -91,6 +91,7 @@ void PianoDestroySearchResult (PianoSearchResult_t *searchResult) { void PianoDestroyStation (PianoStation_t *station) { free (station->name); free (station->id); + free (station->seedId); memset (station, 0, sizeof (station)); } @@ -141,6 +142,7 @@ void PianoDestroyStationInfo (PianoStationInfo_t *info) { PianoDestroyPlaylist (info->feedback); PianoDestroyPlaylist (info->songSeeds); PianoDestroyArtists (info->artistSeeds); + PianoDestroyStations (info->stationSeeds); } /* destroy genre linked list @@ -769,12 +771,15 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req, char *seedId = NULL; assert (reqData != NULL); - assert (reqData->song != NULL || reqData->artist != NULL); + assert (reqData->song != NULL || reqData->artist != NULL || + reqData->station != NULL); if (reqData->song != NULL) { seedId = reqData->song->seedId; } else if (reqData->artist != NULL) { seedId = reqData->artist->seedId; + } else if (reqData->station != NULL) { + seedId = reqData->station->seedId; } assert (seedId != NULL); diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h index 7b692c6..b692a47 100644 --- a/src/libpiano/piano.h +++ b/src/libpiano/piano.h @@ -43,6 +43,7 @@ typedef struct PianoStation { char useQuickMix; /* station will be included in quickmix */ char *name; char *id; + char *seedId; struct PianoStation *next; } PianoStation_t; @@ -119,6 +120,7 @@ typedef struct PianoSearchResult { typedef struct { PianoSong_t *songSeeds; PianoArtist_t *artistSeeds; + PianoStation_t *stationSeeds; PianoSong_t *feedback; } PianoStationInfo_t; @@ -230,6 +232,7 @@ typedef struct { typedef struct { PianoSong_t *song; PianoArtist_t *artist; + PianoStation_t *station; } PianoRequestDataDeleteSeed_t; typedef enum { diff --git a/src/libpiano/xml.c b/src/libpiano/xml.c index 7f21f8d..1dd2a24 100644 --- a/src/libpiano/xml.c +++ b/src/libpiano/xml.c @@ -831,6 +831,7 @@ struct PianoXmlParseSeedBag { char *seedId; PianoSong_t *song; PianoArtist_t *artist; + PianoStation_t *station; }; /* parse seed struct @@ -853,6 +854,14 @@ static void PianoXmlParseSeedCb (const char *key, const ezxml_t value, PianoXmlStructParser (ezxml_child (value, "struct"), PianoXmlParseSearchArtistCb, bag->artist); + } else if (strcmp ("nonGenomeStation", key) == 0) { + /* genre stations are "non genome" station seeds */ + if ((bag->station = calloc (1, sizeof (*bag->station))) == NULL) { + return; + } + + PianoXmlStructParser (ezxml_child (value, "struct"), + PianoXmlParseStationsCb, bag->station); } else if (strcmp ("seedId", key) == 0) { char *valueStr = PianoXmlGetNodeText (value); bag->seedId = strdup (valueStr); @@ -875,10 +884,15 @@ static void PianoXmlParseGetStationInfoCb (const char *key, const ezxml_t value, PianoXmlStructParser (ezxml_child (seedNode, "struct"), PianoXmlParseSeedCb, &bag); - /* FIXME: use if-clause */ - assert (bag.seedId != NULL); - assert (bag.song != NULL || bag.artist != NULL); + assert (bag.song != NULL || bag.artist != NULL || + bag.station != NULL); + + if (bag.seedId == NULL) { + /* seeds without id are useless */ + continue; + } + /* FIXME: copy&waste */ if (bag.song != NULL) { bag.song->seedId = bag.seedId; @@ -903,6 +917,18 @@ static void PianoXmlParseGetStationInfoCb (const char *key, const ezxml_t value, } curSong->next = bag.artist; } + } else if (bag.station != NULL) { + bag.station->seedId = bag.seedId; + + if (info->stationSeeds == NULL) { + info->stationSeeds = bag.station; + } else { + PianoStation_t *curStation = info->stationSeeds; + while (curStation->next != NULL) { + curStation = curStation->next; + } + curStation->next = bag.station; + } } else { free (bag.seedId); } diff --git a/src/main.c b/src/main.c index c103bdd..ed80753 100644 --- a/src/main.c +++ b/src/main.c @@ -136,7 +136,7 @@ static void BarMainGetInitialStation (BarApp_t *app) { } /* no autostart? ask the user */ if (app->curStation == NULL) { - app->curStation = BarUiSelectStation (app, "Select station: ", NULL); + app->curStation = BarUiSelectStation (app, app->ph.stations, "Select station: ", NULL); } if (app->curStation != NULL) { BarUiPrintStation (&app->settings, app->curStation); diff --git a/src/ui.c b/src/ui.c index dc2acb3..1857170 100644 --- a/src/ui.c +++ b/src/ui.c @@ -333,13 +333,13 @@ static PianoStation_t **BarSortedStations (PianoStation_t *unsortedStations, * @param called if input was not a number * @return pointer to selected station or NULL */ -PianoStation_t *BarUiSelectStation (BarApp_t *app, const char *prompt, - BarUiSelectStationCallback_t callback) { +PianoStation_t *BarUiSelectStation (BarApp_t *app, PianoStation_t *stations, + const char *prompt, BarUiSelectStationCallback_t callback) { PianoStation_t **sortedStations = NULL, *retStation = NULL; size_t stationCount, i; char buf[100]; - if (app->ph.stations == NULL) { + if (stations == NULL) { BarUiMsg (&app->settings, MSG_ERR, "No station available.\n"); return NULL; } @@ -347,7 +347,7 @@ PianoStation_t *BarUiSelectStation (BarApp_t *app, const char *prompt, memset (buf, 0, sizeof (buf)); /* sort and print stations */ - sortedStations = BarSortedStations (app->ph.stations, &stationCount, + sortedStations = BarSortedStations (stations, &stationCount, app->settings.sortOrder); do { diff --git a/src/ui.h b/src/ui.h index 64899ef..01d30fb 100644 --- a/src/ui.h +++ b/src/ui.h @@ -36,7 +36,8 @@ THE SOFTWARE. typedef void (*BarUiSelectStationCallback_t) (BarApp_t *app, char *buf); void BarUiMsg (const BarSettings_t *, const BarUiMsg_t, const char *, ...); -PianoStation_t *BarUiSelectStation (BarApp_t *, const char *, BarUiSelectStationCallback_t); +PianoStation_t *BarUiSelectStation (BarApp_t *, PianoStation_t *, const char *, + BarUiSelectStationCallback_t); PianoSong_t *BarUiSelectSong (const BarSettings_t *, PianoSong_t *, BarReadlineFds_t *); PianoArtist_t *BarUiSelectArtist (BarApp_t *, PianoArtist_t *); diff --git a/src/ui_act.c b/src/ui_act.c index c1e7cb7..029be91 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -317,7 +317,8 @@ BarUiActCallback(BarUiActMoveSong) { reqData.step = 0; - reqData.to = BarUiSelectStation (app, "Move song to station: ", NULL); + reqData.to = BarUiSelectStation (app, app->ph.stations, + "Move song to station: ", NULL); if (reqData.to != NULL) { /* find original station (just is case we're playing a quickmix * station) */ @@ -379,8 +380,8 @@ BarUiActCallback(BarUiActRenameStation) { /* play another station */ BarUiActCallback(BarUiActSelectStation) { - PianoStation_t *newStation = BarUiSelectStation (app, "Select station: ", - NULL); + PianoStation_t *newStation = BarUiSelectStation (app, app->ph.stations, + "Select station: ", NULL); if (newStation != NULL) { app->curStation = newStation; BarUiPrintStation (&app->settings, app->curStation); @@ -474,7 +475,7 @@ BarUiActCallback(BarUiActSelectQuickMix) { if (selStation->isQuickMix) { PianoStation_t *toggleStation; - while ((toggleStation = BarUiSelectStation (app, + while ((toggleStation = BarUiSelectStation (app, app->ph.stations, "Toggle quickmix for station: ", BarUiActQuickmixCallback)) != NULL) { toggleStation->useQuickMix = !toggleStation->useQuickMix; @@ -587,8 +588,9 @@ BarUiActCallback(BarUiActManageStation) { BarUiActDefaultPianoCall (PIANO_REQUEST_GET_STATION_INFO, &reqData); BarUiActDefaultEventcmd ("stationfetchinfo"); - BarUiMsg (&app->settings, MSG_QUESTION, "Delete [a]rtist/[s]ong seeds or [f]eedback? "); - if (BarReadline (selectBuf, sizeof (selectBuf), "asf", &app->input, + BarUiMsg (&app->settings, MSG_QUESTION, "Delete [a]rtist/[s]ong/s[t]ation " + "seeds or [f]eedback? "); + if (BarReadline (selectBuf, sizeof (selectBuf), "astf", &app->input, BAR_RL_FULLRETURN, -1)) { if (selectBuf[0] == 'a') { PianoArtist_t *artist = BarUiSelectArtist (app, @@ -616,6 +618,19 @@ BarUiActCallback(BarUiActManageStation) { BarUiActDefaultPianoCall (PIANO_REQUEST_DELETE_SEED, &reqData); BarUiActDefaultEventcmd ("stationdeletesongseed"); } + } else if (selectBuf[0] == 't') { + PianoStation_t *station = BarUiSelectStation (app, + reqData.info.stationSeeds, "Delete seed station: ", NULL); + if (station != NULL) { + PianoRequestDataDeleteSeed_t reqData; + + memset (&reqData, 0, sizeof (reqData)); + reqData.station = station; + + BarUiMsg (&app->settings, MSG_INFO, "Deleting station seed... "); + BarUiActDefaultPianoCall (PIANO_REQUEST_DELETE_SEED, &reqData); + BarUiActDefaultEventcmd ("stationdeletestationseed"); + } } else if (selectBuf[0] == 'f') { PianoSong_t *song = BarUiSelectSong (&app->settings, reqData.info.feedback, &app->input); -- cgit v1.2.3