Skip to content

Instantly share code, notes, and snippets.

@nega0
Created April 26, 2012 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nega0/262f681a08f71be228c0 to your computer and use it in GitHub Desktop.
Save nega0/262f681a08f71be228c0 to your computer and use it in GitHub Desktop.
diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c
index 2a67a2b..e298d2f 100644
--- a/src/libpiano/piano.c
+++ b/src/libpiano/piano.c
@@ -1,3 +1,4 @@
+/* -*- mode: c; tab-width: 8; c-basic-offset: 8; indent-tabs-mode: t -*- */
/*
Copyright (c) 2008-2011
Lars-Dominik Braun <lars@6xq.net>
@@ -42,7 +43,7 @@ THE SOFTWARE.
#include "crypt.h"
#include "config.h"
-#define PIANO_PROTOCOL_VERSION "33"
+#define PIANO_PROTOCOL_VERSION "34"
#define PIANO_RPC_HOST "www.pandora.com"
#define PIANO_RPC_PORT "80"
#define PIANO_RPC_PATH "/radio/xmlrpc/v" PIANO_PROTOCOL_VERSION "?"
@@ -62,7 +63,7 @@ void PianoInit (PianoHandle_t *ph) {
/* destroy artist linked list
*/
-void PianoDestroyArtists (PianoArtist_t *artists) {
+static void PianoDestroyArtists (PianoArtist_t *artists) {
PianoArtist_t *curArtist, *lastArtist;
curArtist = artists;
@@ -92,13 +93,13 @@ void PianoDestroyStation (PianoStation_t *station) {
free (station->name);
free (station->id);
free (station->seedId);
- memset (station, 0, sizeof (station));
+ memset (station, 0, sizeof (*station));
}
/* free complete station list
* @param piano handle
*/
-void PianoDestroyStations (PianoStation_t *stations) {
+static void PianoDestroyStations (PianoStation_t *stations) {
PianoStation_t *curStation, *lastStation;
curStation = stations;
@@ -150,7 +151,7 @@ void PianoDestroyStationInfo (PianoStationInfo_t *info) {
/* destroy genre linked list
*/
-void PianoDestroyGenres (PianoGenre_t *genres) {
+static void PianoDestroyGenres (PianoGenre_t *genres) {
PianoGenre_t *curGenre, *lastGenre;
curGenre = genres;
@@ -165,7 +166,7 @@ void PianoDestroyGenres (PianoGenre_t *genres) {
/* destroy user information
*/
-void PianoDestroyUserInfo (PianoUserInfo_t *user) {
+static void PianoDestroyUserInfo (PianoUserInfo_t *user) {
free (user->webAuthToken);
free (user->authToken);
free (user->listenerId);
@@ -270,8 +271,17 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,
"<?xml version=\"1.0\"?><methodCall>"
"<methodName>listener.authenticateListener</methodName>"
"<params><param><value><int>%lu</int></value></param>"
+ "<param><value><string></string></value></param>"
+ /* user */
"<param><value><string>%s</string></value></param>"
+ /* password */
"<param><value><string>%s</string></value></param>"
+ /* vendor */
+ "<param><value><string>html5tuner</string></value></param>"
+ "<param><value><string/></value></param>"
+ "<param><value><string/></value></param>"
+ "<param><value><string>HTML5</string></value></param>"
+ "<param><value><boolean>1</boolean></value></param>"
"</params></methodCall>", (unsigned long) timestamp,
logindata->user, xmlencodedPassword);
snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH
@@ -890,24 +900,24 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
/* abusing parseNarrative; has same xml structure */
ret = PianoXmlParseNarrative (req->responseData, &cryptedTimestamp);
- if (cryptedTimestamp != NULL) {
+ if (ret == PIANO_RET_OK && cryptedTimestamp != NULL) {
unsigned long timestamp = 0;
- time_t realTimestamp = time (NULL);
+ const time_t realTimestamp = time (NULL);
char *decryptedTimestamp = NULL, *decryptedPos = NULL;
unsigned char i = 4;
+ ret = PIANO_RET_ERR;
if ((decryptedTimestamp = PianoDecryptString (cryptedTimestamp)) != NULL) {
decryptedPos = decryptedTimestamp;
/* skip four bytes garbage? at beginning */
while (i-- > 0 && *decryptedPos++ != '\0');
timestamp = strtoul (decryptedPos, NULL, 0);
ph->timeOffset = realTimestamp - timestamp;
-
- free (decryptedTimestamp);
+ ret = PIANO_RET_CONTINUE_REQUEST;
}
- free (cryptedTimestamp);
+ free (decryptedTimestamp);
}
- ret = PIANO_RET_CONTINUE_REQUEST;
+ free (cryptedTimestamp);
++reqData->step;
break;
}
@@ -1220,6 +1230,14 @@ const char *PianoErrorToStr (PianoReturn_t ret) {
return "Last seed cannot be removed.";
break;
+ case PIANO_RET_EXCESSIVE_ACTIVITY:
+ return "Excessive activity.";
+ break;
+
+ case PIANO_RET_DAILY_SKIP_LIMIT_REACHED:
+ return "Daily skip limit reached.";
+ break;
+
default:
return "No error message available.";
break;
diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h
index 437cd4e..a7cd2ec 100644
--- a/src/libpiano/piano.h
+++ b/src/libpiano/piano.h
@@ -252,6 +252,8 @@ typedef enum {
PIANO_RET_PLAYLIST_END = 14,
PIANO_RET_QUICKMIX_NOT_PLAYABLE = 15,
PIANO_RET_REMOVING_TOO_MANY_SEEDS = 16,
+ PIANO_RET_EXCESSIVE_ACTIVITY = 17,
+ PIANO_RET_DAILY_SKIP_LIMIT_REACHED = 18,
} PianoReturn_t;
void PianoInit (PianoHandle_t *);
diff --git a/src/libpiano/xml.c b/src/libpiano/xml.c
index 510d036..fc26bf9 100644
--- a/src/libpiano/xml.c
+++ b/src/libpiano/xml.c
@@ -32,6 +32,7 @@ THE SOFTWARE.
#include <ezxml.h>
#include <assert.h>
+#include "xml.h"
#include "piano.h"
#include "crypt.h"
#include "config.h"
@@ -93,6 +94,10 @@ static void PianoXmlIsFaultCb (const char *key, const ezxml_t value,
*ret = PIANO_RET_QUICKMIX_NOT_PLAYABLE;
} else if (strcmp ("REMOVING_TOO_MANY_SEEDS", matchStart) == 0) {
*ret = PIANO_RET_REMOVING_TOO_MANY_SEEDS;
+ } else if (strcmp ("EXCESSIVE_ACTIVITY", matchStart) == 0) {
+ *ret = PIANO_RET_EXCESSIVE_ACTIVITY;
+ } else if (strcmp ("DAILY_SKIP_LIMIT_REACHED", matchStart) == 0) {
+ *ret = PIANO_RET_DAILY_SKIP_LIMIT_REACHED;
} else {
*ret = PIANO_RET_ERR;
printf (PACKAGE ": Unknown error %s in %s\n",
@@ -299,7 +304,7 @@ static void PianoXmlParsePlaylistCb (const char *key, const ezxml_t value,
} else if (strcmp (valueStr, "mp3") == 0) {
song->audioFormat = PIANO_AF_MP3;
} else if (strcmp (valueStr, "mp3-hifi") == 0) {
- song->audioFormat = PIANO_AF_MP3_HI;
+ song->audioFormat = PIANO_AF_MP3_HI;
}
} else if (strcmp ("artistMusicId", key) == 0) {
song->artistMusicId = strdup (valueStr);
@@ -314,7 +319,6 @@ static void PianoXmlParsePlaylistCb (const char *key, const ezxml_t value,
} else if (strcmp ("trackToken", key) == 0) {
song->trackToken = strdup (valueStr);
}
-
}
/* parses userinfos sent by pandora as login response
@@ -695,9 +699,10 @@ PianoReturn_t PianoXmlParseSeedSuggestions (char *xml,
* @return encoded string or NULL
*/
char *PianoXmlEncodeString (const char *s) {
- char *replacements[] = {"&&amp;", "'&apos;", "\"&quot;", "<&lt;",
- ">&gt;", NULL};
- char **r, *sOut, *sOutCurr, found;
+ static const char *replacements[] = {"&&amp;", "'&apos;", "\"&quot;",
+ "<&lt;", ">&gt;", NULL};
+ const char **r;
+ char *sOut, *sOutCurr, found;
if ((sOut = calloc (strlen (s) * 5 + 1, sizeof (*sOut))) == NULL) {
return NULL;
diff --git a/src/libpiano/xml.h b/src/libpiano/xml.h
index cca82c0..58ee28f 100644
--- a/src/libpiano/xml.h
+++ b/src/libpiano/xml.h
@@ -26,21 +26,21 @@ THE SOFTWARE.
#include "piano.h"
-PianoReturn_t PianoXmlParseUserinfo (PianoHandle_t *ph, const char *xml);
-PianoReturn_t PianoXmlParseStations (PianoHandle_t *ph, const char *xml);
-PianoReturn_t PianoXmlParsePlaylist (PianoHandle_t *ph, const char *xml,
+PianoReturn_t PianoXmlParseUserinfo (PianoHandle_t *ph, char *xml);
+PianoReturn_t PianoXmlParseStations (PianoHandle_t *ph, char *xml);
+PianoReturn_t PianoXmlParsePlaylist (PianoHandle_t *ph, char *xml,
PianoSong_t **);
-PianoReturn_t PianoXmlParseSearch (const char *searchXml,
+PianoReturn_t PianoXmlParseSearch (char *searchXml,
PianoSearchResult_t *searchResult);
-PianoReturn_t PianoXmlParseSimple (const char *xml);
+PianoReturn_t PianoXmlParseSimple (char *xml);
PianoReturn_t PianoXmlParseCreateStation (PianoHandle_t *ph,
- const char *xml);
-PianoReturn_t PianoXmlParseAddSeed (PianoHandle_t *ph, const char *xml,
+ char *xml);
+PianoReturn_t PianoXmlParseAddSeed (PianoHandle_t *ph, char *xml,
PianoStation_t *station);
PianoReturn_t PianoXmlParseGenreExplorer (PianoHandle_t *ph,
- const char *xmlContent);
-PianoReturn_t PianoXmlParseTranformStation (const char *searchXml);
-PianoReturn_t PianoXmlParseNarrative (const char *xml, char **retNarrative);
+ char *xmlContent);
+PianoReturn_t PianoXmlParseTranformStation (char *searchXml);
+PianoReturn_t PianoXmlParseNarrative (char *xml, char **retNarrative);
PianoReturn_t PianoXmlParseSeedSuggestions (char *, PianoSearchResult_t *);
PianoReturn_t PianoXmlParseGetStationInfo (char *, PianoStationInfo_t *);
diff --git a/src/main.c b/src/main.c
index 990efca..3d2b5d2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -90,10 +90,31 @@ static bool BarMainLoginUser (BarApp_t *app) {
WaitressReturn_t wRet;
PianoRequestDataLogin_t reqData;
bool ret;
+ WaitressHandle_t waithSync;
+ char *syncTime;
+ unsigned long int syncTimeInt;
+
+ /* skip sync step by fetching time from somewhere else */
+ WaitressInit (&waithSync);
+ WaitressSetUrl (&waithSync, "http://ridetheclown.com/s2/synctime.php");
+ if (app->settings.proxy != NULL && strlen (app->settings.proxy) > 0) {
+ WaitressSetProxy (&waithSync, app->settings.proxy);
+ }
+ wRet = WaitressFetchBuf (&waithSync, &syncTime);
+ WaitressFree (&waithSync);
+ if (wRet != WAITRESS_RET_OK) {
+ BarUiMsg (&app->settings, MSG_ERR, "Unable to sync: %s\n",
+ WaitressErrorToStr (wRet));
+ return false;
+ }
+
+ syncTimeInt = strtoul (syncTime, NULL, 0);
+ app->ph.timeOffset = time (NULL) - syncTimeInt;
+ free (syncTime);
reqData.user = app->settings.username;
reqData.password = app->settings.password;
- reqData.step = 0;
+ reqData.step = 1;
BarUiMsg (&app->settings, MSG_INFO, "Login... ");
ret = BarUiPianoCall (app, PIANO_REQUEST_LOGIN, &reqData, &pRet, &wRet);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment