2 Copyright (C) 2006 by Jonas Kramer
3 Published under the terms of the GNU General Public License (GPL).
14 #include <sys/types.h>
27 #include "interface.h"
30 int expand(struct playlist
* list
) {
31 char url
[512], ** response
, * xml
= NULL
;
33 "http://ws.audioscrobbler.com/radio/xspf.php"
34 "?sk=%s&discovery=%d&desktop=0";
38 memset(url
, 0, sizeof(url
));
40 url
, sizeof(url
), fmt
,
41 value(& data
, "session"), !!enabled(DISCOVERY
)
44 response
= fetch(url
, NULL
, NULL
, NULL
);
46 if(response
!= NULL
) {
49 xml
= join(response
, 0);
52 retval
= parsexspf(list
, xml
);
59 void trim(char * string
){
61 while(string
[offset
] == ' ')
65 memmove(string
, string
+ offset
, strlen(string
+ offset
) + 1);
69 int parsexspf(struct playlist
* list
, char * xml
) {
71 unsigned i
, tracks
= 0;
77 while((track
= strcasestr(ptr
, "<track>")) != NULL
) {
78 struct tracknode
* node
= NULL
;
79 char * next
= strcasestr(track
+ 7, "<track>"), * duration
;
81 const char * tags
[] = {
82 "location", "title", "album", "creator", "duration", "image",
86 const char * links
[] = { "artistpage", "albumpage", "trackpage", "freeTrackURL", };
92 node
= malloc(sizeof(struct tracknode
));
95 memset(node
, 0, sizeof(struct tracknode
));
97 for(i
= 0; i
< (sizeof(tags
) / sizeof(char *)); ++i
) {
98 char begin
[32] = { 0 }, end
[32] = { 0 };
100 sprintf(begin
, "<%s>", tags
[i
]);
101 sprintf(end
, "</%s>", tags
[i
]);
103 if((ptr
= strcasestr(track
, begin
)) != NULL
) {
104 char * text
= strndup(
106 (strcasestr(ptr
, end
)) - (ptr
+ strlen(begin
))
109 assert(text
!= NULL
);
112 set(& node
->track
, tags
[i
], text
);
117 for(i
= 0; i
< (sizeof(links
) / sizeof(char *)); ++i
) {
118 char begin
[64] = { 0 };
120 sprintf(begin
, "<link rel=\"http://www.last.fm/%s\">", links
[i
]);
122 if((ptr
= strcasestr(track
, begin
)) != NULL
) {
123 char * text
= strndup(
125 (strcasestr(ptr
, "</link>")) - (ptr
+ strlen(begin
))
128 assert(text
!= NULL
);
130 set(& node
->track
, links
[i
], text
);
138 set(& node
->track
, "station", list
->title
);
141 set(& node
->track
, "station", "Unknown Station");
144 duration
= strdup(value(& node
->track
, "duration"));
145 if(duration
!= NULL
) {
146 duration
[strlen(duration
) - 3] = 0;
147 set(& node
->track
, "duration", duration
);
164 void freelist(struct playlist
* list
) {
165 if(list
->title
!= NULL
)
171 memset(list
, 0, sizeof(struct playlist
));
175 void push(struct playlist
* list
, struct tracknode
* node
) {
179 struct tracknode
* last
= list
->track
;
180 while(last
->next
!= NULL
)
189 void shift(struct playlist
* list
) {
191 struct tracknode
* node
= list
->track
;
192 list
->track
= node
->next
;
193 empty(& node
->track
);
199 void preview(struct playlist list
) {
200 struct tracknode
* node
;
203 if (list
.track
!= NULL
)
204 node
= list
.track
->next
;
207 puts("No tracks in queue.");
212 puts("No tracks in queue.");
215 puts("Upcoming tracks:");
216 while(node
!= NULL
) {
219 format
= haskey(& rc
, "preview-format")
220 ? value(& rc
, "preview-format")
223 printf("%2d %s\n", n
++, meta(format
, M_COLORED
, & node
->track
));