2 Copyright (C) 2006 by Jonas Kramer
3 Copyright (C) 2006 by Bart Trojanowski <bart@jukie.net>
5 Published under the terms of the GNU General Public License (GPLv2).
20 #include "interface.h"
21 #include "completion.h"
31 char ** popular
= NULL
;
33 void tag(struct hash data
) {
34 char key
, * tagstring
;
35 struct prompt setup
= {
36 .prompt
= "Tags (comma separated): ",
39 .callback
= tagcomplete
,
45 fputs("Tag (a)rtist, a(l)bum, (t)rack or (c)ancel?\n", stderr
);
47 while(!strchr("altc", (key
= fetchkey(2))));
52 popular
= merge(toptags(key
, data
), usertags(value(& rc
, "username")), 0);
54 setup
.line
= oldtags(key
, data
);
56 assert((tagstring
= strdup(readline(& setup
))) != NULL
);
66 sendtag(key
, tagstring
, data
);
71 char * oldtags(char key
, struct hash track
) {
73 char * tags
= NULL
, * url
= calloc(512, sizeof(char)),
74 * user
= NULL
, * artist
= NULL
, * arg
= NULL
,
75 * file
= NULL
, ** resp
;
81 file
= "artisttags.xml";
84 file
= "albumtags.xml";
88 file
= "tracktags.xml";
91 encode(value(& track
, "creator"), & artist
);
94 encode(value(& rc
, "username"), & user
);
97 url
, 512, "http://ws.audioscrobbler.com/1.0/user/%s/%s?artist=%s",
104 encode(value(& track
, "album"), & arg
);
105 /* don't request tags for a not-existing album */
111 length
+= snprintf(url
+ length
, 512 - length
, "&album=%s", arg
);
112 } else if(key
== 't') {
113 encode(value(& track
, "title"), & arg
);
115 length
+= snprintf(url
+ length
, 512 - length
, "&track=%s", arg
);
121 resp
= fetch(url
, NULL
, NULL
, NULL
);
127 for(x
= 0, length
= 0; resp
[x
]; ++x
) {
128 char * pbeg
= strstr(resp
[x
], "<name>"), * pend
;
131 pend
= strstr(pbeg
, "</name>");
133 char * thistag
= strndup(pbeg
, pend
- pbeg
);
134 unsigned nlength
= strlen(thistag
) + length
;
136 assert(thistag
!= NULL
);
141 tags
= realloc(tags
, nlength
+ 1);
143 assert(tags
!= NULL
);
145 sprintf(tags
+ length
, "%s%s", length
? "," : "", thistag
);
159 void stripslashes(char * string
) {
161 while(x
< strlen(string
)) {
162 if(string
[x
] == 0x2F)
163 strncpy(string
+ x
, string
+ x
+ 1, strlen(string
+ x
+ 1));
170 int tagcomplete(char * line
, const unsigned max
, int changed
) {
171 unsigned length
, nres
= 0;
174 const char * match
= NULL
;
176 assert(line
!= NULL
);
178 length
= strlen(line
);
180 /* Remove spaces at the beginning of the string. */
181 while(isspace(line
[0])) {
183 memmove(line
, line
+ 1, strlen(line
+ 1));
187 /* Remove spaces at the end of the string. */
188 while((length
= strlen(line
)) > 0 && isspace(line
[length
- 1])) {
193 /* No need for tab completion if there are no popular tags. */
194 if(!popular
|| !popular
[0])
197 /* Get pointer to the beginning of the last tag in tag string. */
198 if((ptr
= strrchr(line
, ',')) == NULL
)
203 length
= strlen(ptr
);
207 /* Get next match in list of popular tags. */
208 if((match
= nextmatch(popular
, changed
? ptr
: NULL
, & nres
)) != NULL
) {
209 snprintf(ptr
, max
- (ptr
- line
) - 1, "%s%s", match
, nres
< 2 ? "," : "");
217 void sendtag(char key
, char * tagstring
, struct hash data
) {
223 unsigned length
= strlen(tagstring
);
224 /* remove trailing commas */
225 while(tagstring
[length
-1] == ',')
226 tagstring
[--length
] = 0;
228 splt
= split(tagstring
, ",\n", & nsplt
);
234 xmlrpc("tagArtist", "sas", value(& data
, "creator"), splt
, "set");
240 value(& data
, "creator"),
241 value(& data
, "album"),
249 value(& data
, "creator"),
250 value(& data
, "title"),
257 puts(result
? "Tagged." : "Sorry, failed.");