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, ¤t_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; + */ }