void sess_cleanup() { sess_disconnect(); audio_exit(audio_device); log_append("Destroyed audio output"); // Free search results. for (sess_search_t *s = g_session.search; s;) { despotify_free_search(s->res); sess_search_t *p = s; s = s->next; free(p); } if (!despotify_cleanup()) panic("despotify_cleanup() failed"); free(g_session.username); g_session.username = 0; free(g_session.password); g_session.password = 0; }
void command_loop(struct despotify_session* ds) { bool loop = true; char buf[80]; struct playlist* rootlist = NULL; struct playlist* searchlist = NULL; struct search_result *search = NULL; struct album_browse* playalbum = NULL; print_help(); do { wprintf(L"\n> "); fflush(stdout); bzero(buf, sizeof buf); fgets(buf, sizeof buf -1, stdin); buf[strlen(buf) - 1] = 0; /* remove newline */ /* list */ if (!strncmp(buf, "list", 4)) { int num = atoi(buf + 5); if (num) { struct playlist* p = get_playlist(rootlist, num); if (p) { print_tracks(p->tracks); lastlist = p; } } else { if (!rootlist) rootlist = despotify_get_stored_playlists(ds); print_list_of_lists(rootlist); } } /* rename */ else if (!strncmp(buf, "rename", 6)) { int num = 0; char *name = 0; if (strlen(buf) > 9) { num = atoi(buf + 7); name = strchr(buf + 7, ' ') + 1; } if (num && name && name[0]) { struct playlist* p = get_playlist(rootlist, num); if (p) { if (despotify_rename_playlist(ds, p, name)) wprintf(L"Renamed playlist %d to \"%s\".\n", num, name); else wprintf(L"Rename failed: %s\n", despotify_get_error(ds)); } } else wprintf(L"Usage: rename [num] [string]\n"); } /* collab */ else if (!strncmp(buf, "collab", 6)) { int num = 0; if (strlen(buf) > 7) num = atoi(buf + 7); if (num) { struct playlist* p = get_playlist(rootlist, num); if (p) { if (despotify_set_playlist_collaboration(ds, p, !p->is_collaborative)) wprintf(L"Changed playlist %d collaboration to %s.\n", num, p->is_collaborative ? "ON" : "OFF"); else wprintf(L"Setting playlist collaboration state failed: %s\n", despotify_get_error(ds)); } } else wprintf(L"Usage: collab [num]\n"); } /* search */ else if (!strncmp(buf, "search", 6)) { if (buf[7]) { if (search) despotify_free_search(search); despotify_stop(ds); /* since we replace the list */ search = despotify_search(ds, buf + 7, MAX_SEARCH_RESULTS); if (!search) { wprintf(L"Search failed: %s\n", despotify_get_error(ds)); continue; } searchlist = search->playlist; } else if (searchlist && (searchlist->num_tracks < search->total_tracks)) if (!despotify_search_more(ds, search, searchlist->num_tracks, MAX_SEARCH_RESULTS)) { wprintf(L"Search failed: %s\n", despotify_get_error(ds)); continue; } if (searchlist) { print_search(search); lastlist = searchlist; } else wprintf(L"No previous search\n"); } /* artist */ else if (!strncmp(buf, "artist", 6)) { int num = atoi(buf + 7); if (!num) { wprintf(L"usage: artist [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; for (struct artist* aptr = t->artist; aptr; aptr = aptr->next) { struct artist_browse* a = despotify_get_artist(ds, aptr->id); print_artist(a); despotify_free_artist_browse(a); } } /* album */ else if (!strncmp(buf, "album", 5)) { int num = atoi(buf + 6); if (!num) { wprintf(L"usage: album [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; if (t) { struct album_browse* a = despotify_get_album(ds, t->album_id); if (a) { print_album(a); despotify_free_album_browse(a); } else wprintf(L"Got no album for id %s\n", t->album_id); } } /* playalbum */ else if (!strncmp(buf, "playalbum", 9)) { int num = atoi(buf + 10); if (!num) { wprintf(L"usage: playalbum [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; if (t) { if (playalbum) despotify_free_album_browse(playalbum); despotify_stop(ds); playalbum = despotify_get_album(ds, t->album_id); if (playalbum) despotify_play(ds, playalbum->tracks, true); else wprintf(L"Got no album for id %s\n", t->album_id); } } /* uri */ else if (!strncmp(buf, "uri", 3)) { char *uri = buf + 4; if(strlen(uri) == 0) { wprintf(L"usage: info <uri>\n"); continue; } struct link* link = despotify_link_from_uri(uri); struct album_browse* al; struct artist_browse* ar; struct playlist* pls; struct search_result* s; struct track* t; switch(link->type) { case LINK_TYPE_ALBUM: al = despotify_link_get_album(ds, link); if(al) { print_album(al); despotify_free_album_browse(al); } break; case LINK_TYPE_ARTIST: ar = despotify_link_get_artist(ds, link); if(ar) { print_artist(ar); despotify_free_artist_browse(ar); } break; case LINK_TYPE_PLAYLIST: pls = despotify_link_get_playlist(ds, link); if(pls) { print_playlist(pls); despotify_free_playlist(pls); } break; case LINK_TYPE_SEARCH: s = despotify_link_get_search(ds, link); if(s) { print_search(s); despotify_free_search(s); } break; case LINK_TYPE_TRACK: t = despotify_link_get_track(ds, link); if(t) { print_track_full(t); despotify_free_track(t); } break; default: wprintf(L"%s is a invalid Spotify URI\n", uri); } despotify_free_link(link); } /* portrait */ else if (!strncmp(buf, "portrait", 8)) { int num = atoi(buf + 9); if (!num) { wprintf(L"usage: portrait [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested artist */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; struct artist_browse* a = despotify_get_artist(ds, t->artist->id); if (a && a->portrait_id[0]) { int len; void* portrait = despotify_get_image(ds, a->portrait_id, &len); if (portrait && len) { wprintf(L"Writing %d bytes into portrait.jpg\n", len); FILE* f = fopen("portrait.jpg", "w"); if (f) { fwrite(portrait, len, 1, f); fclose(f); } free(portrait); } } else wprintf(L"Artist %s has no portrait.\n", a->name); despotify_free_artist_browse(a); } /* play */ else if (!strncmp(buf, "play", 4)) { if (!lastlist) { wprintf(L"No list to play from. Use 'list' or 'search' to select a list.\n"); continue; } /* skip to track <num> */ listoffset = atoi(buf + 5); struct track* t = lastlist->tracks; for (int i=1; i<listoffset && t; i++) t = t->next; if (t) despotify_play(ds, t, true); else wprintf(L"Invalid track number %d\n", listoffset); } /* stop */ else if (!strncmp(buf, "stop", 4)) { despotify_stop(ds); } /* pause */ else if (!strncmp(buf, "pause", 5)) { despotify_pause(ds); } /* resume */ else if (!strncmp(buf, "resume", 5)) { despotify_resume(ds); } /* info */ else if (!strncmp(buf, "info", 4)) { print_info(ds); } /* help */ else if (!strncmp(buf, "help", 4)) { print_help(); } /* quit */ else if (!strncmp(buf, "quit", 4)) { loop = false; } } while(loop); if (rootlist) despotify_free_playlist(rootlist); if (search) despotify_free_search(search); if (playalbum) despotify_free_album_browse(playalbum); }