summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichał Cichoń <michcic@gmail.com>2018-10-30 13:12:47 +0100
committerMichał Cichoń <michcic@gmail.com>2018-10-30 13:12:47 +0100
commitcb6789b17f81d29c6884c27715c705083e09a5db (patch)
treed6a47c38ff7dcb937992b15dc3c2d051bb877ac8 /src
parentcd5c65097ecf03480f477e47e0bb706dbf705a21 (diff)
parent82a13ad77bfcf2c6dc37fe0d1d55f93372db6509 (diff)
downloadpianobar-windows-2018.10.30.tar.gz
pianobar-windows-2018.10.30.tar.bz2
pianobar-windows-2018.10.30.zip
Merge branch 'release/2018.10.30'HEAD2018.10.30master
Diffstat (limited to 'src')
-rw-r--r--src/config.h2
-rw-r--r--src/http/http.c16
-rw-r--r--src/http/http.h2
-rw-r--r--src/libpiano/piano.c6
-rw-r--r--src/libpiano/piano.h3
-rw-r--r--src/libpiano/request.c6
-rw-r--r--src/libpiano/response.c12
-rw-r--r--src/main.c11
-rw-r--r--src/main.h2
-rw-r--r--src/settings.c15
-rw-r--r--src/settings.h5
-rw-r--r--src/ui.c63
-rw-r--r--src/ui.h7
-rw-r--r--src/ui_act.c14
14 files changed, 116 insertions, 48 deletions
diff --git a/src/config.h b/src/config.h
index 42a0b11..a8af710 100644
--- a/src/config.h
+++ b/src/config.h
@@ -3,7 +3,7 @@
/* package name */
#define PACKAGE "pianobar"
-#define VERSION "2017.05.18"
+#define VERSION "2018.10.30"
#define TITLE "Pianobar"
diff --git a/src/http/http.c b/src/http/http.c
index 4576d04..9457fab 100644
--- a/src/http/http.c
+++ b/src/http/http.c
@@ -41,7 +41,7 @@ struct _http_t {
static char* HttpToString(const wchar_t* wideString, int size);
static wchar_t* HttpToWideString(const char* string, int size);
-static bool HttpCreateConnection (http_t http);
+static bool HttpCreateConnection (http_t http, unsigned int timeOut);
static void HttpCloseConnection (http_t http);
static void HttpSetLastError (http_t http, const char* message);
static void HttpSetLastErrorW (http_t http, const wchar_t* message);
@@ -75,7 +75,7 @@ static wchar_t* HttpToWideString(const char* string, int size) {
}
-static bool HttpCreateConnection (http_t http) {
+static bool HttpCreateConnection (http_t http, unsigned int timeOut) {
INTERNET_PORT defaultPort = INTERNET_DEFAULT_PORT;
HttpCloseConnection (http);
@@ -89,10 +89,10 @@ static bool HttpCreateConnection (http_t http) {
WINHTTP_SAFE(http->session != NULL);
WinHttpSetTimeouts(http->session,
- 60 * 1000, // DNS time-out
- 60 * 1000, // connect time-out
- 30 * 1000, // send time-out
- 30 * 1000); // receive time-out
+ timeOut * 1000, // DNS time-out
+ timeOut * 1000, // connect time-out
+ timeOut * 1000, // send time-out
+ timeOut * 1000); // receive time-out
http->connection = WinHttpConnect(
http->session,
@@ -187,7 +187,7 @@ static char* HttpFormatWinHttpError (DWORD errorCode) {
return HttpFormatWinApiError(errorCode, NULL);
}
-bool HttpInit(http_t* http, const char* endpoint, const char* securePort) {
+bool HttpInit(http_t* http, const char* endpoint, const char* securePort, unsigned int timeOut) {
http_t out = malloc(sizeof(struct _http_t));
if (!out)
return false;
@@ -196,7 +196,7 @@ bool HttpInit(http_t* http, const char* endpoint, const char* securePort) {
out->endpoint = HttpToWideString(endpoint, -1);
out->securePort = HttpToWideString(securePort, -1);
- if (!HttpCreateConnection (out)) {
+ if (!HttpCreateConnection (out, timeOut)) {
HttpDestroy (out);
return false;
}
diff --git a/src/http/http.h b/src/http/http.h
index 5ea617f..415b0d0 100644
--- a/src/http/http.h
+++ b/src/http/http.h
@@ -32,7 +32,7 @@ THE SOFTWARE.
typedef struct _http_t *http_t;
-bool HttpInit (http_t*, const char*, const char*);
+bool HttpInit (http_t*, const char*, const char*, unsigned int);
void HttpDestroy (http_t);
bool HttpSetAutoProxy (http_t, const char*);
diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c
index c496ea1..7f1eff9 100644
--- a/src/libpiano/piano.c
+++ b/src/libpiano/piano.c
@@ -214,7 +214,11 @@ void PianoDestroyRequest (PianoRequest_t *req) {
*/
PianoStation_t *PianoFindStationById (PianoStation_t * const stations,
const char * const searchStation) {
- assert (searchStation != NULL);
+ assert (stations != NULL);
+
+ if (searchStation == NULL) {
+ return NULL;
+ }
PianoStation_t *currStation = stations;
PianoListForeachP (currStation) {
diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h
index 2dbf607..b595249 100644
--- a/src/libpiano/piano.h
+++ b/src/libpiano/piano.h
@@ -64,7 +64,8 @@ typedef struct PianoStation {
typedef enum {
PIANO_RATE_NONE = 0,
PIANO_RATE_LOVE = 1,
- PIANO_RATE_BAN = 2
+ PIANO_RATE_BAN = 2,
+ PIANO_RATE_TIRED = 3,
} PianoSongRating_t;
/* UNKNOWN should be 0, because memset sets audio format to 0 */
diff --git a/src/libpiano/request.c b/src/libpiano/request.c
index 5d499af..0df7005 100644
--- a/src/libpiano/request.c
+++ b/src/libpiano/request.c
@@ -156,6 +156,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
case PIANO_REQUEST_GET_STATIONS: {
/* get stations, user must be authenticated */
assert (ph->user.listenerId != NULL);
+
method = "user.getStationList";
break;
}
@@ -186,7 +187,8 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
assert (reqData != NULL);
assert (reqData->trackToken != NULL);
assert (reqData->stationId != NULL);
- assert (reqData->rating != PIANO_RATE_NONE);
+ assert (reqData->rating != PIANO_RATE_NONE &&
+ reqData->rating != PIANO_RATE_TIRED);
json_object_object_add (j, "stationToken",
json_object_new_string (reqData->stationId));
@@ -397,6 +399,8 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
json_object_new_string (reqData->station->id));
json_object_object_add (j, "includeExtendedAttributes",
json_object_new_boolean (true));
+ json_object_object_add (j, "includeExtraParams",
+ json_object_new_boolean (true));
method = "station.getStation";
break;
diff --git a/src/libpiano/response.c b/src/libpiano/response.c
index e37824e..fcc28b1 100644
--- a/src/libpiano/response.c
+++ b/src/libpiano/response.c
@@ -436,8 +436,13 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
break;
}
+ case PIANO_REQUEST_ADD_TIRED_SONG: {
+ PianoSong_t * const song = req->data;
+ song->rating = PIANO_RATE_TIRED;
+ break;
+ }
+
case PIANO_REQUEST_ADD_SEED:
- case PIANO_REQUEST_ADD_TIRED_SONG:
case PIANO_REQUEST_SET_QUICKMIX:
case PIANO_REQUEST_BOOKMARK_SONG:
case PIANO_REQUEST_BOOKMARK_ARTIST:
@@ -634,6 +639,11 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
feedbackSong->rating = getBoolDefault (s, "isPositive",
false) ? PIANO_RATE_LOVE : PIANO_RATE_BAN;
+ json_object *v;
+ feedbackSong->length =
+ json_object_object_get_ex (s, "trackLength", &v) ?
+ json_object_get_int (v) : 0;
+
info->feedback = PianoListAppendP (info->feedback,
feedbackSong);
}
diff --git a/src/main.c b/src/main.c
index 4f4214a..a75388e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -248,9 +248,9 @@ static void BarMainStartPlayback(BarApp_t *app)
PIANO_RET_OK);
if (!BarPlayer2Play(app->player))
- ++app->playerErrors;
+ ++app->retries;
else
- app->playerErrors = 0;
+ app->retries = 0;
}
}
@@ -265,11 +265,11 @@ static void BarMainPlayerCleanup(BarApp_t *app)
BarConsoleSetTitle(TITLE);
- if (app->playerErrors >= app->settings.maxPlayerErrors)
+ if (app->retries >= app->settings.maxRetry)
{
/* don't continue playback if thread reports too many error */
app->nextStation = NULL;
- app->playerErrors = 0;
+ app->retries = 0;
}
}
@@ -411,7 +411,8 @@ int main(int argc, char **argv)
app.settings.keys[BAR_KS_HELP]);
}
- HttpInit(&app.http2, app.settings.rpcHost, app.settings.rpcTlsPort);
+ HttpInit(&app.http2, app.settings.rpcHost, app.settings.rpcTlsPort,
+ app.settings.timeout);
if (app.settings.controlProxy)
HttpSetProxy(app.http2, app.settings.controlProxy);
diff --git a/src/main.h b/src/main.h
index 192ffdb..047f637 100644
--- a/src/main.h
+++ b/src/main.h
@@ -46,6 +46,6 @@ typedef struct {
PianoStation_t *curStation, *nextStation;
char doQuit;
BarReadline_t rl;
- unsigned int playerErrors;
+ unsigned int retries;
} BarApp_t;
diff --git a/src/settings.c b/src/settings.c
index 4f0ef8c..affb7f2 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -129,6 +129,7 @@ void BarSettingsDestroy (BarSettings_t *settings) {
free (settings->eventCmd);
free (settings->loveIcon);
free (settings->banIcon);
+ free (settings->tiredIcon);
free (settings->atIcon);
free (settings->npSongFormat);
free (settings->npStationFormat);
@@ -172,11 +173,14 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->autoselect = true;
settings->history = 5;
settings->volume = 0;
+ settings->timeout = 30; /* seconds */
settings->gainMul = 1.0;
- settings->maxPlayerErrors = 5;
+ /* should be > 4, otherwise expired audio urls (403) can stop playback */
+ settings->maxRetry = 5;
settings->sortOrder = BAR_SORT_NAME_AZ;
settings->loveIcon = strdup (" <3");
settings->banIcon = strdup (" </3");
+ settings->tiredIcon = strdup (" zZ");
settings->atIcon = strdup (" @ ");
settings->npSongFormat = strdup ("\"%t\" by \"%a\" on \"%l\"%r%@%s");
settings->npStationFormat = strdup ("Station \"%n\" (%i)");
@@ -351,8 +355,10 @@ void BarSettingsRead (BarSettings_t *settings) {
settings->eventCmd = BarSettingsExpandTilde (val, userhome);
} else if (streq ("history", key)) {
settings->history = atoi (val);
- } else if (streq ("max_player_errors", key)) {
- settings->maxPlayerErrors = atoi (val);
+ } else if (streq ("max_retry", key)) {
+ settings->maxRetry = atoi (val);
+ } else if (streq ("timeout", key)) {
+ settings->timeout = atoi (val);
} else if (streq ("sort", key)) {
size_t i;
static const char *mapping[] = {"name_az",
@@ -374,6 +380,9 @@ void BarSettingsRead (BarSettings_t *settings) {
} else if (streq ("ban_icon", key)) {
free (settings->banIcon);
settings->banIcon = strdup (val);
+ } else if (streq ("tired_icon", key)) {
+ free (settings->tiredIcon);
+ settings->tiredIcon = strdup (val);
} else if (streq ("at_icon", key)) {
free (settings->atIcon);
settings->atIcon = strdup (val);
diff --git a/src/settings.h b/src/settings.h
index 0edb544..719c39b 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -86,7 +86,7 @@ typedef struct {
typedef struct {
bool autoselect;
- unsigned int history, maxPlayerErrors;
+ unsigned int history, maxRetry, timeout;
int volume;
float gainMul;
BarStationSorting_t sortOrder;
@@ -98,8 +98,7 @@ typedef struct {
char *bindTo;
char *autostartStation;
char *eventCmd;
- char *loveIcon;
- char *banIcon;
+ char *loveIcon, *banIcon, *tiredIcon;
char *atIcon;
char *npSongFormat;
char *npStationFormat;
diff --git a/src/ui.c b/src/ui.c
index 88ad4d7..a044c78 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -388,20 +388,21 @@ PianoStation_t *BarUiSelectStation (BarApp_t *app, PianoStation_t *stations,
}
/* let user pick one song
- * @param pianobar settings
+ * @param app
* @param song list
* @param input fds
* @return pointer to selected item in song list or NULL
*/
-PianoSong_t *BarUiSelectSong (const BarSettings_t *settings,
+PianoSong_t *BarUiSelectSong (const BarApp_t * const app,
PianoSong_t *startSong, BarReadline_t rl) {
+ const BarSettings_t * const settings = &app->settings;
PianoSong_t *tmpSong = NULL;
char buf[100];
memset (buf, 0, sizeof (buf));
do {
- BarUiListSongs (settings, startSong, buf);
+ BarUiListSongs (app, startSong, buf);
BarUiMsg (settings, MSG_QUESTION, "Select song: ");
if (BarReadlineStr (buf, sizeof (buf), rl, BAR_RL_DEFAULT) == 0) {
@@ -498,7 +499,7 @@ char *BarUiSelectMusicId (BarApp_t *app, PianoStation_t *station,
musicId = strdup (tmpArtist->musicId);
}
} else if (*selectBuf == 't') {
- tmpSong = BarUiSelectSong (&app->settings, searchResult.songs,
+ tmpSong = BarUiSelectSong (app, searchResult.songs,
app->rl);
if (tmpSong != NULL) {
musicId = strdup (tmpSong->musicId);
@@ -506,7 +507,7 @@ char *BarUiSelectMusicId (BarApp_t *app, PianoStation_t *station,
}
} else if (searchResult.songs != NULL) {
/* songs found */
- tmpSong = BarUiSelectSong (&app->settings, searchResult.songs,
+ tmpSong = BarUiSelectSong (app, searchResult.songs,
app->rl);
if (tmpSong != NULL) {
musicId = strdup (tmpSong->musicId);
@@ -614,6 +615,23 @@ void BarUiPrintStation (const BarSettings_t *settings,
BarUiMsg (settings, MSG_PLAYING, "%s", outstr);
}
+static const char *ratingToIcon (const BarSettings_t * const settings,
+ const PianoSong_t * const song) {
+ switch (song->rating) {
+ case PIANO_RATE_LOVE:
+ return settings->loveIcon;
+
+ case PIANO_RATE_BAN:
+ return settings->banIcon;
+
+ case PIANO_RATE_TIRED:
+ return settings->tiredIcon;
+
+ default:
+ return "";
+ }
+}
+
/* Print song infos (artist, title, album, loved)
* @param pianobar settings
* @param the song
@@ -623,7 +641,7 @@ void BarUiPrintSong (const BarSettings_t *settings,
const PianoSong_t *song, const PianoStation_t *station) {
char outstr[512];
const char *vals[] = {song->title, song->artist, song->album,
- (song->rating == PIANO_RATE_LOVE) ? settings->loveIcon : "",
+ ratingToIcon (settings, song),
station != NULL ? settings->atIcon : "",
station != NULL ? station->name : "",
song->detailUrl};
@@ -644,23 +662,44 @@ void BarUiPrintSong (const BarSettings_t *settings,
* @param artist/song filter string
* @return # of songs
*/
-size_t BarUiListSongs (const BarSettings_t *settings,
+size_t BarUiListSongs (const BarApp_t * const app,
const PianoSong_t *song, const char *filter) {
+ const BarSettings_t * const settings = &app->settings;
size_t i = 0;
- char digits[8];
PianoListForeachP (song) {
if (filter == NULL ||
(filter != NULL && (BarStrCaseStr (song->artist, filter) != NULL ||
BarStrCaseStr (song->title, filter) != NULL))) {
- char outstr[512];
+ const char * const deleted = "(deleted)", * const empty = "";
+ const char *stationName = empty;
+
+ const PianoStation_t * const station =
+ PianoFindStationById (app->ph.stations, song->stationId);
+ if (station != NULL && station != app->curStation) {
+ stationName = station->name;
+ } else if (station == NULL && song->stationId != NULL) {
+ stationName = deleted;
+ }
+
+ char outstr[512], digits[8], duration[8] = "??:??";
const char *vals[] = {digits, song->artist, song->title,
- (song->rating == PIANO_RATE_LOVE) ? settings->loveIcon :
- ((song->rating == PIANO_RATE_BAN) ? settings->banIcon : "")};
+ ratingToIcon (settings, song),
+ duration,
+ stationName != empty ? settings->atIcon : "",
+ stationName,
+ };
+ /* pre-format a few strings */
snprintf (digits, sizeof (digits) / sizeof (*digits), "%2zu", i);
+ const unsigned int length = song->length;
+ if (length > 0) {
+ snprintf (duration, sizeof (duration), "%02u:%02u",
+ length / 60, length % 60);
+ }
+
BarUiCustomFormat (outstr, sizeof (outstr), settings->listSongFormat,
- "iatr", vals);
+ "iatrd@s", vals);
BarUiAppendNewline (outstr, sizeof (outstr));
BarUiMsg (settings, MSG_LIST, "%s", outstr);
}
diff --git a/src/ui.h b/src/ui.h
index 126f6bb..faca48e 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -38,14 +38,15 @@ typedef void (*BarUiSelectStationCallback_t) (BarApp_t *app, char *buf);
void BarUiMsg (const BarSettings_t *, const BarUiMsg_t, const char *, ...) __attribute__((format(printf, 3, 4)));
PianoStation_t *BarUiSelectStation (BarApp_t *, PianoStation_t *, const char *,
BarUiSelectStationCallback_t, bool);
-PianoSong_t *BarUiSelectSong (const BarSettings_t *, PianoSong_t *,
- BarReadline_t);
+PianoSong_t *BarUiSelectSong (const BarApp_t * const app,
+ PianoSong_t *startSong, BarReadline_t rl);
PianoArtist_t *BarUiSelectArtist (BarApp_t *, PianoArtist_t *);
char *BarUiSelectMusicId (BarApp_t *, PianoStation_t *, const char *);
void BarUiPrintStation (const BarSettings_t *, PianoStation_t *);
void BarUiPrintSong (const BarSettings_t *, const PianoSong_t *,
const PianoStation_t *);
-size_t BarUiListSongs (const BarSettings_t *, const PianoSong_t *, const char *);
+size_t BarUiListSongs (const BarApp_t * const app,
+ const PianoSong_t *song, const char *filter);
void BarUiStartEventCmd (const BarSettings_t *, const char *,
const PianoStation_t *, const PianoSong_t *, const player2_t * const,
PianoStation_t *, PianoReturn_t);
diff --git a/src/ui_act.c b/src/ui_act.c
index a036f19..b1ed8a4 100644
--- a/src/ui_act.c
+++ b/src/ui_act.c
@@ -482,7 +482,7 @@ BarUiActCallback(BarUiActTempBanSong) {
BarUiActCallback(BarUiActPrintUpcoming) {
PianoSong_t * const nextSong = PianoListNextP (selSong);
if (nextSong != NULL) {
- BarUiListSongs (&app->settings, nextSong, NULL);
+ BarUiListSongs (app, nextSong, NULL);
} else {
BarUiMsg (&app->settings, MSG_INFO, "No songs in queue.\n");
}
@@ -537,15 +537,15 @@ BarUiActCallback(BarUiActSelectQuickMix) {
if (selStation->isQuickMix) {
PianoStation_t *toggleStation;
while ((toggleStation = BarUiSelectStation (app, app->ph.stations,
- "Toggle quickmix for station: ",
+ "Toggle QuickMix for station: ",
BarUiActQuickmixCallback, false)) != NULL) {
toggleStation->useQuickMix = !toggleStation->useQuickMix;
}
- BarUiMsg (&app->settings, MSG_INFO, "Setting quickmix stations... ");
+ BarUiMsg (&app->settings, MSG_INFO, "Setting QuickMix stations... ");
BarUiActDefaultPianoCall (PIANO_REQUEST_SET_QUICKMIX, NULL);
BarUiActDefaultEventcmd ("stationquickmixtoggle");
} else {
- BarUiMsg (&app->settings, MSG_ERR, "Not a QuickMix station.\n");
+ BarUiMsg (&app->settings, MSG_ERR, "Please select a QuickMix station first.\n");
}
}
@@ -563,7 +563,7 @@ BarUiActCallback(BarUiActHistory) {
PianoSong_t *histSong;
if (app->songHistory != NULL) {
- histSong = BarUiSelectSong (&app->settings, app->songHistory,
+ histSong = BarUiSelectSong (app, app->songHistory,
app->rl);
if (histSong != NULL) {
BarKeyShortcutId_t action;
@@ -815,7 +815,7 @@ BarUiActCallback(BarUiActManageStation) {
BarUiActDefaultEventcmd ("stationdeleteartistseed");
}
} else if (selectBuf[0] == 's') {
- PianoSong_t *song = BarUiSelectSong (&app->settings,
+ PianoSong_t *song = BarUiSelectSong (app,
reqData.info.songSeeds, app->rl);
if (song != NULL) {
PianoRequestDataDeleteSeed_t subReqData;
@@ -842,7 +842,7 @@ BarUiActCallback(BarUiActManageStation) {
BarUiActDefaultEventcmd ("stationdeletestationseed");
}
} else if (selectBuf[0] == 'f') {
- PianoSong_t *song = BarUiSelectSong (&app->settings,
+ PianoSong_t *song = BarUiSelectSong (app,
reqData.info.feedback, app->rl);
if (song != NULL) {
BarUiMsg (&app->settings, MSG_INFO, "Deleting feedback... ");