Ejemplo n.º 1
0
void execcmd(const char * cmd, char * reply) {
	char arg[1024], * ptr;
	unsigned ncmd;
	const char * known [] = {
		"play",
		"love",
		"ban",
		"skip",
		"quit",
		"info",
		"pause",
		"discovery",
		"tag-artist",
		"tag-album",
		"tag-track",
		"artist-tags",
		"album-tags",
		"track-tags",
		"stop",
	};

	memset(arg, 0, sizeof(arg));
	memset(reply, 0, REPLYBUFSIZE);

	for(ncmd = 0; ncmd < (sizeof(known) / sizeof(char *)); ++ncmd) {
		if(!strncmp(known[ncmd], cmd, strlen(known[ncmd])))
			break;
	}

	switch(ncmd) {
		case (sizeof(known) / sizeof(char *)):
			strncpy(reply, "ERROR", REPLYBUFSIZE);
			break;

		case 0:
			if(sscanf(cmd, "play %128[a-zA-Z0-9:/_ %,*.-]", arg) == 1) {
				char * url;
				decode(arg, & url);
				station(url);
				free(url);
			}
			break;

		case 1:
			rate("L");
			break;

		case 2:
			rate("B");
			break;

		case 3:
			rate("S");
			break;

		case 4:
			quit();

		case 5:
			if(* (cmd + 5))
				strncpy(reply, meta(cmd + 5, 0, & track), REPLYBUFSIZE);
			else if(haskey(& rc, "np-file-format"))
				strncpy(
					reply,
					meta(value(& rc, "np-file-format"), 0, & track),
					REPLYBUFSIZE
				);

			break;

		case 6:
			if(playfork) {
				if(pausetime) {
					kill(playfork, SIGCONT);
				}
				else {
					time(& pausetime);
					kill(playfork, SIGSTOP);
				}
			}
			break;

		case 7:
			toggle(DISCOVERY);
			break;

		case 8:
			if(sscanf(cmd, "tag-artist %128s", arg) == 1)
				sendtag('a', arg, track);
			break;

		case 9:
			if(sscanf(cmd, "tag-album %128s", arg) == 1)
				sendtag('l', arg, track);
			break;

		case 10:
			if(sscanf(cmd, "tag-track %128s", arg) == 1)
				sendtag('t', arg, track);
			break;

		case 11:
			if((ptr = oldtags('a', track)) != NULL) {
				strncpy(reply, ptr, REPLYBUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;

		case 12:
			if((ptr = oldtags('l', track)) != NULL) {
				strncpy(reply, ptr, REPLYBUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;

		case 13:
			if((ptr = oldtags('t', track)) != NULL) {
				strncpy(reply, ptr, REPLYBUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;

		case 14:
			if(playfork) {
				enable(STOPPED);
				kill(playfork, SIGUSR1);
			}
			break;
	}
}
Ejemplo n.º 2
0
void tag(struct hash data) {
	char key, * tagstring;
	struct prompt setup = {
		.prompt = "Tags (comma separated): ",
		.line = NULL,
		.history = NULL,
		.callback = tagcomplete,
	};

	if(!data.content)
		return;

	fputs("Tag (a)rtist, a(l)bum, (t)rack or (c)ancel?\n", stderr);

	while(!strchr("altc", (key = fetchkey(2))));

	if(key == 'c')
		return;

	popular = merge(toptags(key, data), usertags(value(& rc, "username")), 0);

	setup.line = oldtags(key, data);

	assert((tagstring = strdup(readline(& setup))) != NULL);

	if(setup.line) {
		free(setup.line);
		setup.line = NULL;
	}

	purge(popular);
	popular = NULL;

	sendtag(key, tagstring, data);
	free(tagstring);
}


char * oldtags(char key, struct hash track) {
	unsigned length, x;
	char * tags = NULL, * url = calloc(512, sizeof(char)),
		 * user = NULL, * artist = NULL, * arg = NULL,
		 * file = NULL, ** resp;
	
	assert(url != NULL);
	
	switch(key) {
		case 'a':
			file = "artisttags.xml";
			break;
		case 'l':
			file = "albumtags.xml";
			break;
		case 't':
		default:
			file = "tracktags.xml";
	}

	encode(value(& track, "creator"), & artist);
	stripslashes(artist);

	encode(value(& rc, "username"), & user);

	length = snprintf(
			url, 512, "http://ws.audioscrobbler.com/1.0/user/%s/%s?artist=%s",
			user, file, artist);

	free(user);
	free(artist);

	if(key == 'l') {
		encode(value(& track, "album"), & arg);
		stripslashes(arg);
		length += snprintf(url + length, 512 - length, "&album=%s", arg);
	} else if(key == 't') {
		encode(value(& track, "title"), & arg);
		stripslashes(arg);
		length += snprintf(url + length, 512 - length, "&track=%s", arg);
	}

	if(arg)
		free(arg);

	resp = fetch(url, NULL, NULL, NULL);
	free(url);

	if(!resp)
		return NULL;

	for(x = 0, length = 0; resp[x]; ++x) {
		char * pbeg = strstr(resp[x], "<name>"), * pend;
		if(pbeg) {
			pbeg += 6;
			pend = strstr(pbeg, "</name>");
			if(pend) {
				char * thistag = strndup(pbeg, pend - pbeg);
				unsigned nlength = strlen(thistag) + length;

				assert(thistag != NULL);

				if(length)
					++nlength;

				tags = realloc(tags, nlength + 1);

				assert(tags != NULL);

				sprintf(tags + length, "%s%s", length ? "," : "", thistag);

				free(thistag);
				length = nlength;
			}
		}
	}

	purge(resp);

	return tags;
}
Ejemplo n.º 3
0
int execcmd(const char * cmd, char * reply) {
	char arg[1024], * ptr;
	unsigned ncmd;
	const char * known [] = {
		"play",
		"love",
		"ban",
		"skip",
		"quit",
		"info",
		"pause",
		"discovery",
		"tag-artist",
		"tag-album",
		"tag-track",
		"artist-tags",
		"album-tags",
		"track-tags",
		"stop",
		"volume-up",
		"volume-down",
		"volume",
		"rtp",
		"status",
		"unlove",
		"detach"
	};

	memset(arg, 0, sizeof(arg));
	memset(reply, 0, BUFSIZE);

	for(ncmd = 0; ncmd < (sizeof(known) / sizeof(char *)); ++ncmd) {
		if(!strncmp(known[ncmd], cmd, strlen(known[ncmd])))
			break;
	}

	switch(ncmd) {
		case (sizeof(known) / sizeof(char *)):
			strncpy(reply, "ERROR", BUFSIZE);
			break;

		/* "play lastfm://station" */
		case 0:
			if(sscanf(cmd, "play %128[a-zA-Z0-9:/_ %,*.+-]", arg) == 1) {
				char * url;
				decode(arg, & url);
				station(url);
				free(url);
			}
			break;

		/* Love currently played track. */
		case 1:
			rate("L");
			break;

		/* Ban currently played track. */
		case 2:
			rate("B");
			break;

		/* Skip track. */
		case 3:
			rate("S");
			break;

		/* Kill Shell.FM. */
		case 4:
			quit();

		/* "info FORMAT" - returns the format string with the meta data filled in. */
		case 5:
			if(* (cmd + 5))
				strncpy(reply, meta(cmd + 5, 0, & track), BUFSIZE);
			else if(haskey(& rc, "np-file-format"))
				strncpy(
					reply,
					meta(value(& rc, "np-file-format"), 0, & track),
					BUFSIZE
				);

			break;

		/* Pause playback. */
		case 6:
			if(playfork) {
				if(pausetime) {
					kill(playfork, SIGCONT);
				}
				else {
					time(& pausetime);
					kill(playfork, SIGSTOP);
				}
			}
			break;

		/* Toggle discovery mode. Returns "DISCOVERY <ON|OFF>" */
		case 7:
			toggle(DISCOVERY);
			snprintf(
				reply,
				BUFSIZE,
				"DISCOVERY %s",
				enabled(DISCOVERY) ? "ON" : "OFF"
			);
			break;

		/* "tag-artist tag1,tag2,..." - tag the artist of the current track. */
		case 8:
			if(sscanf(cmd, "tag-artist %128s", arg) == 1)
				sendtag('a', arg, track);
			break;

		/* "tag-album tag1,tag2,..." - tag the album of the current track. */
		case 9:
			if(sscanf(cmd, "tag-album %128s", arg) == 1)
				sendtag('l', arg, track);
			break;

		/* "tag-track tag1,tag2,..." - tag the current track. */
		case 10:
			if(sscanf(cmd, "tag-track %128s", arg) == 1)
				sendtag('t', arg, track);
			break;

		/* Return comma-separated list of the current artists tags. */
		case 11:
			if((ptr = oldtags('a', track)) != NULL) {
				strncpy(reply, ptr, BUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;

		/* Return comma-separated list of the current albums tags. */
		case 12:
			if((ptr = oldtags('l', track)) != NULL) {
				strncpy(reply, ptr, BUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;

		/* Return comma-separated list of the current tracks tags. */
		case 13:
			if((ptr = oldtags('t', track)) != NULL) {
				strncpy(reply, ptr, BUFSIZE);
				free(ptr);
				ptr = NULL;
			}
			break;


		/* Stop playback. */
		case 14:
			if(playfork) {
				enable(STOPPED);
				kill(playfork, SIGUSR1);
			}
			break;

		/* Increase absolute volume (0-64) by 1. */
		case 15:
			volume_up();
			break;

		/* Decrease absolute volume (0-64) by 1. */
		case 16:
			volume_down();
			break;

		/*
			Set volume.
			"volume 32" - set absolute volume (0-64) to 32 (50%).
			"volume %50" - same, but using percentual volume.
			"volume +1" - same as "volume_up".
			"volume -1" - same as "volume_down".

			Returns absolute volume ("VOLUME 32").
		*/
		case 17:
			parse_volume(cmd);
			snprintf(reply, BUFSIZE, "VOLUME %d", volume);
			break;

		/* Toggle RTP (report to profile, "scrobbling"). Returns "RTP <ON|OFF>". */
		case 18:
			/* RTP on/off */
			toggle(RTP);
			snprintf(reply, BUFSIZE, "RTP %s", enabled(RTP) ? "ON" : "OFF");
			break;

		/* Get current status. Returns on of "PAUSE", "PLAYING" and "STOPPED". */
		case 19:
			strncpy(reply, PLAYBACK_STATUS, BUFSIZE);
			break;

		/* Unlove currently played track. */
		case 20:
			rate("U");
			break;
		
		/* Detach from network interface. */
		case 21:
			return 1;	
	}

	return 0;
}