Merge pull request #80 from AlexanderPavlenko/master
[shell-fm.git] / source / playlist.c
blob3e69851ed1b9d0e8a4da55addb27da7fa3cf2acd
1 /*
2 Copyright (C) 2006 by Jonas Kramer
3 Published under the terms of the GNU General Public License (GPL).
4 */
6 #define _GNU_SOURCE
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <unistd.h>
14 #include <sys/types.h>
17 #include "hash.h"
18 #include "http.h"
19 #include "settings.h"
20 #include "service.h"
21 #include "strary.h"
22 #include "util.h"
24 #include "playlist.h"
25 #include "globals.h"
27 #include "interface.h"
28 #include "json.h"
29 #include "rest.h"
32 int expand(struct playlist * list) {
33 struct hash p = { 0, NULL };
34 char * response;
36 assert(list != NULL);
38 set(& p, "discovery", (!!enabled(DISCOVERY)) ? "true" : "false");
39 response = rest("radio.getPlaylist", & p);
41 if(response != NULL) {
42 int result = parse_playlist(list, response);
43 free(response);
44 return result;
46 else {
47 return 0;
51 void trim(char * string){
52 int offset = 0;
53 while(string[offset] == ' ')
54 offset++;
56 if(offset)
57 memmove(string, string + offset, strlen(string + offset) + 1);
61 int parse_playlist(struct playlist * list, char * plain_json) {
62 json_value * playlist, * track_array, * track, * extension;
63 unsigned n;
65 assert(list != NULL);
66 assert(plain_json != NULL);
68 playlist = json_parse(plain_json);
70 assert(playlist != NULL);
72 track_array = json_query(playlist, "playlist", "trackList", "track", NULL);
74 assert(track_array != NULL);
76 for(n = 0; n < track_array->u.array.length; ++n) {
77 struct tracknode * node = NULL;
78 char * duration;
80 node = malloc(sizeof(struct tracknode));
81 assert(node != NULL);
83 memset(node, 0, sizeof(struct tracknode));
86 track = track_array->u.array.values[n];
87 extension = json_query(track, "extension", NULL);
89 json_hash(track, & node->track, NULL);
90 json_hash(extension, & node->track, NULL);
92 if((duration = strdup(value(& node->track, "duration"))) != NULL) {
93 duration[strlen(duration) - 3] = 0;
94 set(& node->track, "duration", duration);
95 free(duration);
98 if(list->title) {
99 trim(list->title);
101 set(& node->track, "station", list->title);
103 else {
104 set(& node->track, "station", "Unknown Station");
107 push(list, node);
109 debug("track location: %s\n", value(& node->track, "location"));
112 json_value_free(playlist);
114 return 1;
118 void freelist(struct playlist * list) {
119 if(list->title != NULL)
120 free(list->title);
122 while(list->track)
123 shift(list);
125 memset(list, 0, sizeof(struct playlist));
129 void push(struct playlist * list, struct tracknode * node) {
130 if(!list->track)
131 list->track = node;
132 else {
133 struct tracknode * last = list->track;
134 while(last->next != NULL)
135 last = last->next;
136 last->next = node;
139 ++list->left;
143 void shift(struct playlist * list) {
144 if(list->track) {
145 struct tracknode * node = list->track;
146 list->track = node->next;
147 empty(& node->track);
148 free(node);
149 --(list->left);
153 void preview(struct playlist list) {
154 struct tracknode * node;
155 unsigned n = 0;
157 if (list.track != NULL)
158 node = list.track->next;
159 else
161 puts("No tracks in queue.");
162 return;
165 if(node == NULL) {
166 puts("No tracks in queue.");
168 else {
169 puts("Upcoming tracks:");
170 while(node != NULL) {
171 const char * format;
173 format = haskey(& rc, "preview-format")
174 ? value(& rc, "preview-format")
175 : "%a - %t";
177 printf("%2d %s\n", n++, meta(format, M_COLORED, & node->track));
179 node = node->next;