seamus

commit dbbcdcd649cb3b3ca1f4b8dd1d2ab15af8a15840

Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>

all: refactor to use structs and a proper project structure

 src/seamus.c | 237 +++++++++++++++++++----------------------------------


diff --git a/src/seamus.c b/src/seamus.c
index 54f60aed1bbc96b2ab5fb6c5e3e8620f841a2ee4..9db16befbd4be962b637ba82d75cbecf934b7055 100755
--- a/src/seamus.c
+++ b/src/seamus.c
@@ -2,69 +2,86 @@ #include 
 #include <stdlib.h>
 #include <errno.h>
 #include <tickit.h>
-#include <poll.h>
+#include <string.h>
+#include <assert.h>
 #include <mpd/client.h>
 
-TickitWindow *main_window;
-Tickit *t;
+struct seamus_song {
+	char *title;
+	char *artist;
+};
 
-static struct mpd_connection *setup_connection(void)
+struct seamus_frontend {
+	struct mpd_connection *conn;
+	struct seamus_song *queue;
+	size_t queue_size;
+	TickitWindow *main_window;
+	Tickit *t;
+};
+
+int
+setup_connection(struct seamus_frontend *s)
 {
 	struct mpd_connection *connection = mpd_connection_new(NULL, 0, 0);
 
+	// XXX: Check which conditions could lead to this being NULL and notify
+	// accordingly
 	if (connection == NULL) {
-		fprintf(stderr, "Couldn't establish a connection!");
-		tickit_stop(t);
-		tickit_unref(t);
-		exit(1);
+		return 1;
 	}
 
 	if (mpd_connection_get_error(connection) != MPD_ERROR_SUCCESS) {
 		const char *message = mpd_connection_get_error_message(connection);
 		mpd_connection_free(connection);
 
-		fprintf(stderr, "seamus error: %s\n", message);
-		tickit_stop(t);
-		tickit_unref(t);
-		exit(1);
+		fprintf(stderr, "MPD connection error: %s\n", message);
+		return 1;
 	}
 
-	return connection;
+	s->conn = connection;
+	return 0;
 }
 
-void fetch_mpd_current_queue(struct mpd_connection *connection, char **list, int count) {
-	int queue_status = mpd_send_list_queue_meta(connection);
+int
+fetch_mpd_from_current_queue(struct seamus_frontend *seamus, int max_count)
+{
+	assert(seamus->conn != NULL);
+	int queue_status = mpd_send_list_queue_meta(seamus->conn);
 
 	if (queue_status == true) {
 		struct mpd_entity *entity;
 		int index;
 
-		for (index = 0; index < count; index++) {
-			entity = mpd_recv_entity(connection);
-			if (entity != NULL) {
+		seamus->queue = calloc(max_count, sizeof(struct seamus_song));
+
+		for (index = 0; index < max_count; index++) {
+			entity = mpd_recv_entity(seamus->conn);
+			if (entity == NULL) {
+				continue;
+			} else {
 				enum mpd_entity_type type = mpd_entity_get_type(entity);
 
 				if (type == MPD_ENTITY_TYPE_SONG) {
 					struct mpd_song *song = mpd_entity_get_song(entity);
 
 					enum mpd_tag_type tag_title = mpd_tag_name_iparse("Title");
-					const char *title = mpd_song_get_tag(song, tag_title, 0);
+					const char *stitle = mpd_song_get_tag(song, tag_title, 0);
 
 					enum mpd_tag_type tag_artist = mpd_tag_name_iparse("AlbumArtist");
-					const char *artist = mpd_song_get_tag(song, tag_artist, 0);
+					const char *sartist = mpd_song_get_tag(song, tag_artist, 0);
+
+					struct seamus_song *new = &seamus->queue[index];
+					memset(new, 0, sizeof(*new));
 
-					// Allocate enough to store artist, song
-					// title and the dash between those two
-					char *song_info = malloc(sizeof(char) *
-							strlen(artist) +
-							strlen(title) + 4
-							);
+					char *title = malloc(sizeof(char) * strlen(stitle) + 1);
+					strcpy(title, stitle);
 
-					sprintf(song_info, "%s - %s", artist, title);
+					char *artist = malloc(sizeof(char) * strlen(sartist) + 1);
+					strcpy(artist, sartist);
 
-					list[index] = malloc(strlen(song_info) + 1);
-					strcpy(list[index], song_info);
-					free(song_info);
+					new->title = title;
+					new->artist = artist;
+					seamus->queue_size++;
 				}
 
 				// When freeing the entity, it'll automatically
@@ -73,151 +90,70 @@ 				mpd_entity_free(entity);
 			}
 		}
 
+		return 0;
 	} else {
-		debug("Could not fetch queue");
+		fprintf(stderr, "Could not fetch queue");
+		return 1;
 	}
 }
 
-void fetch_mpd_status(struct mpd_connection *connection, char *str)
+void
+print_songs_from_queue(struct seamus_frontend *seamus)
 {
-	struct mpd_status *status = mpd_run_status(connection);
+	for (size_t i = 0; i < seamus->queue_size; ++i) {
+		struct seamus_song *s = &seamus->queue[i];
 
-	if (status == NULL) {
-		const char *message = mpd_connection_get_error_message(connection);
-		fprintf(stderr, "MPD Error - No Status: %s\n", message);
-		tickit_stop(t);
-		tickit_unref(t);
-		exit(1);
-	}
-
-	if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
-		mpd_status_get_state(status) == MPD_STATE_PAUSE) {
-
-		struct mpd_song *song = mpd_run_current_song(connection);
-
-		const char *state;
-
-		if (mpd_status_get_state(status) == MPD_STATE_PLAY) {
-			state = "[playing]";
+		if (s == NULL) {
+			printf("Nothing here...");
 		} else {
-			state = "[paused]";
-		}
-
-		if (song != NULL) {
-			enum mpd_tag_type tag_artist = mpd_tag_name_iparse("Artist");
-			enum mpd_tag_type tag_title = mpd_tag_name_iparse("Title");
-
-			const char *title = mpd_song_get_tag(song, tag_title, 0);
-			const char *artist = mpd_song_get_tag(song, tag_artist, 0);
-
-			char *elapsed_time = (char*) malloc(13 * sizeof(char));
-
-			sprintf(elapsed_time, "%3i:%02i",
-					mpd_status_get_elapsed_time(status) / 60,
-					mpd_status_get_elapsed_time(status) % 60);
-
-			char *total_time = (char*) malloc(13 * sizeof(char));
-
-			sprintf(total_time, "%i:%02i",
-					mpd_status_get_total_time(status) / 60,
-					mpd_status_get_total_time(status) % 60);
-
-			// Move this into a proper struct
-			asprintf(str, "%s %s - %s: %s/%s",
-				state,
-				artist,
-				title,
-				elapsed_time,
-				total_time
-			);
-
-			free(total_time);
-			free(elapsed_time);
-			mpd_song_free(song);
+			printf("Song queued: %s - %s \n", s->artist, s->title);
 		}
 	}
-
-	mpd_status_free(status);
 }
 
-static int update(Tickit *t, TickitEventFlags flags, void *_info, void *user);
-static int update(Tickit *t, TickitEventFlags flags, void *_info, void *user) {
-	tickit_window_expose(main_window, NULL);
-	tickit_watch_timer_after_msec(t, 1000, 0, &update, NULL);
-
-	return 0;
-}
-
-static int render(TickitWindow *win, TickitEventFlags flags, void *_info, void *data)
+void
+seamus_finish(struct seamus_frontend *seamus)
 {
-	TickitExposeEventInfo *info = _info;
-	TickitRenderBuffer *render_buffer = info->rb;
-	struct mpd_connection *connection = setup_connection();
+	int i;
+	for (i = 0; i < seamus->queue_size; i++) {
+		struct seamus_song *s = &seamus->queue[i];
+		if (s->title != NULL && s->artist != NULL) {
+			free(s->title);
+			free(s->artist);
+		}
 
-	tickit_renderbuffer_eraserect(render_buffer, &info->rect);
-
-	tickit_renderbuffer_goto(render_buffer, 0, 0);
-	{
-		tickit_renderbuffer_savepen(render_buffer);
-
-		TickitPen *pen = tickit_pen_new_attrs(
-			TICKIT_PEN_FG, 1,
-			TICKIT_PEN_BOLD, 1,
-		0);
-
-		tickit_renderbuffer_setpen(render_buffer, pen);
-		tickit_renderbuffer_text(render_buffer, "Hello, welcome to seamus");
-		tickit_renderbuffer_restore(render_buffer);
+		seamus->queue_size--;
 	}
 
-	// TODO: Connect this with the lines we can display to the user
-	int count = 9;
-
-	char *current_status;
-	char *queue[count];
-	fetch_mpd_status(connection, &current_status);
-
-	// XXX: Deal with pagination/offsetting?
-	fetch_mpd_current_queue(connection, queue, count);
-
-	tickit_renderbuffer_goto(render_buffer, tickit_window_lines(win) - 2, 0);
-	tickit_renderbuffer_text(render_buffer, current_status);
+	free(seamus->queue);
+}
 
-	int i;
-	for (i = 0; i < count; i++) {
-		tickit_renderbuffer_goto(render_buffer, 2 + i, 0);
-		tickit_renderbuffer_text(render_buffer, queue[i]);
-		free(queue[i]);
+int
+seamus_init(struct seamus_frontend *s)
+{
+	// Setup MPD connection
+	int mpd_con = setup_connection(s);
+	if (mpd_con != 0) {
+		// replace with a unified log
+		fprintf(stderr, "Weren't able to connect with MPD");
+		return 1;
 	}
-
-	free(current_status);
-	mpd_connection_free(connection);
-
-	return 1;
 }
 
-static int render_root(TickitWindow *win, TickitEventFlags flags, void *_info, void *data)
+int
+main(int argc, char *argv[])
 {
-	TickitExposeEventInfo *info = _info;
-	TickitRenderBuffer *render_buffer = info->rb;
+	struct seamus_frontend seamus = {0};
 
-	int right = tickit_window_cols(win) - 1;
-	int bottom = tickit_window_lines(win) - 1;
+	seamus_init(&seamus);
 
-	tickit_renderbuffer_eraserect(render_buffer, &(TickitRect){
-		.top = 0, .left = 0, .lines = bottom+1, .cols = right+1,
-	});
+	fetch_mpd_from_current_queue(&seamus, 10);
 
-	return 1;
-}
+	print_songs_from_queue(&seamus);
 
-void debug(char *message)
-{
-	fprintf(stderr, "DEBUG: %s \n", message);
-}
+	//return 0;
 
-int main(int argc, char *argv[])
-{
+	/*
 	t = tickit_new_stdtty();
 
 	TickitWindow *root = tickit_get_rootwin(t);
@@ -242,4 +178,5 @@ 	tickit_run(t);
 	tickit_window_close(root);
 	tickit_unref(t);
 	return 0;
+	*/
 }