Exemple #1
0
/*	parse stations returned by pandora
 *	@param piano handle
 *	@param xml returned by pandora
 *	@return _RET_OK or error
 */
PianoReturn_t PianoXmlParseStations (PianoHandle_t *ph, char *xml) {
	ezxml_t xmlDoc, dataNode;
	PianoReturn_t ret;
	char **quickMixIds = NULL, **curQuickMixId = NULL;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}

	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "array",
			0, "data", -1);

	for (dataNode = ezxml_child (dataNode, "value"); dataNode;
			dataNode = dataNode->next) {
		PianoStation_t *tmpStation;

		if ((tmpStation = calloc (1, sizeof (*tmpStation))) == NULL) {
			ezxml_free (xmlDoc);
			return PIANO_RET_OUT_OF_MEMORY;
		}

		PianoXmlStructParser (ezxml_child (dataNode, "struct"),
				PianoXmlParseStationsCb, tmpStation);

		/* get stations selected for quickmix */
		if (tmpStation->isQuickMix) {
			PianoXmlStructParser (ezxml_child (dataNode, "struct"),
					PianoXmlParseQuickMixStationsCb, &quickMixIds);
		}
		/* start new linked list or append */
		if (ph->stations == NULL) {
			ph->stations = tmpStation;
		} else {
			PianoStation_t *curStation = ph->stations;
			while (curStation->next != NULL) {
				curStation = curStation->next;
			}
			curStation->next = tmpStation;
		}
	}
	/* set quickmix flags after all stations are read */
	if (quickMixIds != NULL) {
		curQuickMixId = quickMixIds;
		while (*curQuickMixId != NULL) {
			PianoStation_t *curStation = PianoFindStationById (ph->stations,
					*curQuickMixId);
			if (curStation != NULL) {
				curStation->useQuickMix = 1;
			}
			free (*curQuickMixId);
			curQuickMixId++;
		}
		free (quickMixIds);
	}

	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #2
0
/*	callback for xml struct parser used in PianoXmlParseSearch, "switch" for
 *	PianoXmlParseSearchArtistCb and PianoXmlParsePlaylistCb
 */
static void PianoXmlParseSearchCb (const char *key, const ezxml_t value,
		void *data) {
	PianoSearchResult_t *searchResult = data;
	ezxml_t curNode;

	if (strcmp ("artists", key) == 0) {
		/* skip <value><array><data> */
		for (curNode = ezxml_child (ezxml_get (value, "array", 0, "data", -1), "value");
				curNode; curNode = curNode->next) {
			PianoArtist_t *artist;
			
			if ((artist = calloc (1, sizeof (*artist))) == NULL) {
				/* fail silently */
				break;
			}

			memset (artist, 0, sizeof (*artist));

			PianoXmlStructParser (ezxml_child (curNode, "struct"),
					PianoXmlParseSearchArtistCb, artist);

			/* add result to linked list */
			if (searchResult->artists == NULL) {
				searchResult->artists = artist;
			} else {
				PianoArtist_t *curArtist = searchResult->artists;
				while (curArtist->next != NULL) {
					curArtist = curArtist->next;
				}
				curArtist->next = artist;
			}
		}
	} else if (strcmp ("songs", key) == 0) {
		for (curNode = ezxml_child (ezxml_get (value, "array", 0, "data", -1), "value");
				curNode; curNode = curNode->next) {
			/* FIXME: copy & waste */
			PianoSong_t *tmpSong;
			
			if ((tmpSong = calloc (1, sizeof (*tmpSong))) == NULL) {
				/* fail silently */
				break;
			}

			PianoXmlStructParser (ezxml_child (curNode, "struct"),
					PianoXmlParsePlaylistCb, tmpSong);
			/* begin linked list or append */
			if (searchResult->songs == NULL) {
				searchResult->songs = tmpSong;
			} else {
				PianoSong_t *curSong = searchResult->songs;
				while (curSong->next != NULL) {
					curSong = curSong->next;
				}
				curSong->next = tmpSong;
			}
		}
	}
}
Exemple #3
0
/*	parse "create station" answer (it returns a new station structure)
 *	@param piano handle
 *	@param xml document
 *	@return nothing yet
 */
PianoReturn_t PianoXmlParseCreateStation (PianoHandle_t *ph, char *xml) {
	ezxml_t xmlDoc, dataNode;
	PianoStation_t *tmpStation;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}

	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1);

	if ((tmpStation = calloc (1, sizeof (*tmpStation))) == NULL) {
		ezxml_free (xmlDoc);
		return PIANO_RET_OUT_OF_MEMORY;
	}
	PianoXmlStructParser (dataNode, PianoXmlParseStationsCb, tmpStation);
	/* FIXME: copy & waste */
	/* start new linked list or append */
	if (ph->stations == NULL) {
		ph->stations = tmpStation;
	} else {
		PianoStation_t *curStation = ph->stations;
		while (curStation->next != NULL) {
			curStation = curStation->next;
		}
		curStation->next = tmpStation;
	}
	
	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #4
0
static PianoReturn_t PianoXmlParsePlaylistStruct (ezxml_t xml,
		PianoSong_t **retSong) {
	PianoSong_t *playlist = *retSong, *tmpSong;
	
	if ((tmpSong = calloc (1, sizeof (*tmpSong))) == NULL) {
		return PIANO_RET_OUT_OF_MEMORY;
	}

	PianoXmlStructParser (ezxml_child (xml, "struct"), PianoXmlParsePlaylistCb,
			tmpSong);
	/* begin linked list or append */
	if (playlist == NULL) {
		playlist = tmpSong;
	} else {
		PianoSong_t *curSong = playlist;
		while (curSong->next != NULL) {
			curSong = curSong->next;
		}
		curSong->next = tmpSong;
	}

	*retSong = playlist;

	return PIANO_RET_OK;
}
Exemple #5
0
/*	parse getStation xml struct
 */
static void PianoXmlParseGetStationInfoCb (const char *key, const ezxml_t value,
		void *data) {
	PianoStationInfo_t *info = data;

	if (strcmp ("seeds", key) == 0) {
		const ezxml_t dataNode = ezxml_get (value, "array", 0, "data", -1);
		for (ezxml_t seedNode = ezxml_child (dataNode, "value"); seedNode;
					seedNode = seedNode->next) {
			struct PianoXmlParseSeedBag bag;
			memset (&bag, 0, sizeof (bag));

			PianoXmlStructParser (ezxml_child (seedNode, "struct"),
					PianoXmlParseSeedCb, &bag);

			/* FIXME: use if-clause */
			assert (bag.seedId != NULL);
			assert (bag.song != NULL || bag.artist != NULL);

			if (bag.song != NULL) {
				bag.song->seedId = bag.seedId;

				if (info->songSeeds == NULL) {
					info->songSeeds = bag.song;
				} else {
					PianoSong_t *curSong = info->songSeeds;
					while (curSong->next != NULL) {
						curSong = curSong->next;
					}
					curSong->next = bag.song;
				}
			} else if (bag.artist != NULL) {
				bag.artist->seedId = bag.seedId;

				if (info->artistSeeds == NULL) {
					info->artistSeeds = bag.artist;
				} else {
					PianoArtist_t *curSong = info->artistSeeds;
					while (curSong->next != NULL) {
						curSong = curSong->next;
					}
					curSong->next = bag.artist;
				}
			} else {
				free (bag.seedId);
			}
		}
	} else if (strcmp ("feedback", key) == 0) {
		const ezxml_t dataNode = ezxml_get (value, "array", 0, "data", -1);
		for (ezxml_t feedbackNode = ezxml_child (dataNode, "value"); feedbackNode;
					feedbackNode = feedbackNode->next) {
			if (PianoXmlParsePlaylistStruct (feedbackNode, &info->feedback) !=
					PIANO_RET_OK) {
				break;
			}
		}
	}
}
Exemple #6
0
/*	check whether pandora returned an error or not
 *	@param document root of xml doc
 *	@return _RET_OK or fault code (_RET_*)
 */
static PianoReturn_t PianoXmlIsFault (ezxml_t xmlDoc) {
	PianoReturn_t ret;

	if ((xmlDoc = ezxml_child (xmlDoc, "fault")) != NULL) {
		xmlDoc = ezxml_get (xmlDoc, "value", 0, "struct", -1);
		PianoXmlStructParser (xmlDoc, PianoXmlIsFaultCb, &ret);
		return ret;
	}
	return PIANO_RET_OK;
}
Exemple #7
0
/*	parse seed struct
 */
static void PianoXmlParseSeedCb (const char *key, const ezxml_t value,
		void *data) {
	struct PianoXmlParseSeedBag *bag = data;

	assert (bag != NULL);

	if (strcmp ("song", key) == 0) {
		assert (bag->song == NULL);

		if ((bag->song = calloc (1, sizeof (*bag->song))) == NULL) {
			return;
		}

		PianoXmlStructParser (ezxml_child (value, "struct"),
				PianoXmlParsePlaylistCb, bag->song);
	} else if (strcmp ("artist", key) == 0) {
		assert (bag->artist == NULL);

		if ((bag->artist = calloc (1, sizeof (*bag->artist))) == NULL) {
			return;
		}

		PianoXmlStructParser (ezxml_child (value, "struct"),
				PianoXmlParseSearchArtistCb, bag->artist);
	} else if (strcmp ("nonGenomeStation", key) == 0) {
		/* genre stations are "non genome" station seeds */
		assert (bag->station == NULL);

		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);
	}
}
Exemple #8
0
/*	parses userinfos sent by pandora as login response
 *	@param piano handle
 *	@param utf-8 string
 *	@return _RET_OK or error
 */
PianoReturn_t PianoXmlParseUserinfo (PianoHandle_t *ph, char *xml) {
	ezxml_t xmlDoc, structNode;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}

	/* <methodResponse> <params> <param> <value> <struct> */
	structNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1);
	PianoXmlStructParser (structNode, PianoXmlParseUserinfoCb, &ph->user);

	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #9
0
/*	parse getStation response
 */
PianoReturn_t PianoXmlParseGetStationInfo (char *xml,
		PianoStationInfo_t *stationInfo) {
	ezxml_t xmlDoc, dataNode;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}
	
	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1);
	PianoXmlStructParser (dataNode, PianoXmlParseGetStationInfoCb, stationInfo);

	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #10
0
/*	parse "add seed" answer, nearly the same as ParseCreateStation
 *	@param piano handle
 *	@param xml document
 *	@param update this station
 */
PianoReturn_t PianoXmlParseAddSeed (char *xml, PianoStation_t *station) {
	ezxml_t xmlDoc, dataNode;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}

	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1);
	PianoDestroyStation (station);
	PianoXmlStructParser (dataNode, PianoXmlParseStationsCb, station);
	
	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #11
0
/*	parse search result; searchResult is nulled before use
 *	@param xml document
 *	@param returns search result
 *	@return nothing yet
 */
PianoReturn_t PianoXmlParseSearch (char *xml,
		PianoSearchResult_t *searchResult) {
	ezxml_t xmlDoc, dataNode;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}
	
	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "struct", -1);
	/* we need a "clean" search result (with null pointers) */
	memset (searchResult, 0, sizeof (*searchResult));
	PianoXmlStructParser (dataNode, PianoXmlParseSearchCb, searchResult);

	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}
Exemple #12
0
/*	callback for xml struct parser used in PianoXmlParseSearch, "switch" for
 *	PianoXmlParseSearchArtistCb and PianoXmlParsePlaylistCb
 */
static void PianoXmlParseSearchCb (const char *key, const ezxml_t value,
		void *data) {
	PianoSearchResult_t *searchResult = data;
	ezxml_t curNode;

	if (strcmp ("artists", key) == 0) {
		/* skip <value><array><data> */
		for (curNode = ezxml_child (ezxml_get (value, "array", 0, "data", -1), "value");
				curNode; curNode = curNode->next) {
			PianoArtist_t *artist;
			
			if ((artist = calloc (1, sizeof (*artist))) == NULL) {
				/* fail silently */
				break;
			}

			memset (artist, 0, sizeof (*artist));

			PianoXmlStructParser (ezxml_child (curNode, "struct"),
					PianoXmlParseSearchArtistCb, artist);

			/* add result to linked list */
			if (searchResult->artists == NULL) {
				searchResult->artists = artist;
			} else {
				PianoArtist_t *curArtist = searchResult->artists;
				while (curArtist->next != NULL) {
					curArtist = curArtist->next;
				}
				curArtist->next = artist;
			}
		}
	} else if (strcmp ("songs", key) == 0) {
		for (curNode = ezxml_child (ezxml_get (value, "array", 0, "data", -1), "value");
				curNode; curNode = curNode->next) {
			if (PianoXmlParsePlaylistStruct (curNode, &searchResult->songs) !=
					PIANO_RET_OK) {
				break;
			}
		}
	}
}
Exemple #13
0
/*	parses playlist; used when searching too
 *	@param piano handle
 *	@param xml document
 *	@param return: playlist
 */
PianoReturn_t PianoXmlParsePlaylist (PianoHandle_t *ph, char *xml,
		PianoSong_t **retPlaylist) {
	ezxml_t xmlDoc, dataNode;
	PianoReturn_t ret;

	if ((ret = PianoXmlInitDoc (xml, &xmlDoc)) != PIANO_RET_OK) {
		return ret;
	}

	dataNode = ezxml_get (xmlDoc, "params", 0, "param", 0, "value", 0, "array",
			0, "data", -1);

	for (dataNode = ezxml_child (dataNode, "value"); dataNode;
			dataNode = dataNode->next) {
		PianoSong_t *tmpSong;
		
		if ((tmpSong = calloc (1, sizeof (*tmpSong))) == NULL) {
			ezxml_free (xmlDoc);
			return PIANO_RET_OUT_OF_MEMORY;
		}

		PianoXmlStructParser (ezxml_child (dataNode, "struct"),
				PianoXmlParsePlaylistCb, tmpSong);
		/* begin linked list or append */
		if (*retPlaylist == NULL) {
			*retPlaylist = tmpSong;
		} else {
			PianoSong_t *curSong = *retPlaylist;
			while (curSong->next != NULL) {
				curSong = curSong->next;
			}
			curSong->next = tmpSong;
		}
	}

	ezxml_free (xmlDoc);

	return PIANO_RET_OK;
}