static LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static char *username, *password; switch(uMsg) { case WM_TIMER: DSFYDEBUG("uMsg=%u (%s), wParam=%u, lParam=%u\n", uMsg, WM2STR(uMsg), wParam, lParam); if(session) { int timeout; KillTimer(hwnd, TIMERID); sp_session_process_events(session, &timeout); SetTimer(hwnd, TIMERID, timeout, NULL); } break; case WM_USER: switch(LOWORD(wParam)) { case 1: // Set tree root ID m_TreeRootId = (UINT_PTR)lParam; break; case 2: // Set username username = (char *)lParam; DSFYDEBUG("Got username '%s'\n", username); break; case 3: // Set password password = (char *)lParam; DSFYDEBUG("Got password '%s'\n", password); break; case 4: // Login if not yet logged in if(sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) sp_session_login(session, username, password); break; case 5: // Get connection status if(!session) return -1; else if(sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) return -1; return 0; } break; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
int main() { struct mg_server *server = mg_create_server(NULL, event_handler); mg_set_option(server, "Partyfy", "."); mg_set_option(server, "listening_port", "8080"); const char *username = "******"; //size_t size; char *password = getpass("Enter the password for the account\n"); sp_session *sp; spconfig.application_key_size = g_appkey_size; sp_error err = sp_session_create(&spconfig, &sp); if(SP_ERROR_OK != err) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); exit(1); } g_sess = sp; pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); sp_session_login(g_sess, username, password, 0, NULL); // See if the user logged in successfully printConnectionState(); int timeout = 0; sp_connectionstate state = sp_session_connectionstate(g_sess); while (state != SP_CONNECTION_STATE_LOGGED_IN) { sp_session_process_events(g_sess, &timeout); printf("Logging in...\n"); usleep(100000); state = sp_session_connectionstate(g_sess); } //audio_init(&g_audiofifo); printf("Logged in\n"); for(;;) { mg_poll_server(server, 1000); sp_session_process_events(g_sess, &timeout); //while(!g_notify_do) // pthread_cond_wait(&g_notify_cond, &g_notify_mutex); //g_notify_do = 0; //pthread_mutex_unlock(&g_notify_mutex); //if(g_playback_done) { // g_playback_done = 0; //} //pthread_mutex_lock(&g_notify_mutex); } mg_destroy_server(&server); }
sp_playlist * sp_session_inbox_create(sp_session *session) { if (sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) { return NULL; } return session->inbox; }
sp_playlist * sp_session_starred_create(sp_session *session) { if (sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) { return NULL; } return sp_session_starred_for_user_create(session, sp_user_canonical_name(session->user)); }
// Returns 1 if logged in, 0 otherwise // This is needed as libspotify will segfault in places if we are no longer logged in! // Must be called with session mutex held int session_logged_in(php_spotify_session *session) { sp_connectionstate state; assert(session != NULL); state = sp_session_connectionstate(session->session); if (state == SP_CONNECTION_STATE_LOGGED_IN) return 1; return 0; }
sp_connectionstate Session::GetConnectionState() { if (m_pSession) { return sp_session_connectionstate(m_pSession); } else { return SP_CONNECTION_STATE_LOGGED_OUT; } }
/** relogin used when forced to remove cache **/ void SpotifySession::relogin() { qDebug() << Q_FUNC_INFO; if( sp_session_connectionstate(m_session) != SP_CONNECTION_STATE_LOGGED_OUT || m_loggedIn) { qDebug() << Q_FUNC_INFO << "SpotifySession asked to relog in! Logging out"; delete m_SpotifyPlaylists; m_SpotifyPlaylists = new SpotifyPlaylists( this ); m_relogin = true; logout( true ); return; } }
sp_playlist * sp_session_starred_for_user_create(sp_session *session, const char *name) { char *link; if (sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) { return NULL; } link = ALLOC_STR(strlen("spotify:user:"******":starred")); sprintf(link, "spotify:user:%s:starred", name); return (sp_playlist *)registry_find(link); }
sp_playlistcontainer * sp_session_publishedcontainer_for_user_create(sp_session *session, const char *username) { char *link; if (sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) { return NULL; } if (username == NULL && session->user) { username = session->user->canonical_name; } link = ALLOC_STR(strlen("spotify:container:") + strlen(username)); sprintf(link, "spotify:container:%s", username); return (sp_playlistcontainer *)registry_find(link); }
static void sess_callback_connectionstate_updated(sp_session *session) { char *state; switch(sp_session_connectionstate(session)) { case SP_CONNECTION_STATE_LOGGED_OUT: state = "logged out"; break; case SP_CONNECTION_STATE_LOGGED_IN: state = "logged in"; break; case SP_CONNECTION_STATE_DISCONNECTED: state = "disconnected"; break; case SP_CONNECTION_STATE_UNDEFINED: state = "undefined"; break; case SP_CONNECTION_STATE_OFFLINE: state = "offline"; break; } syslog(LOG_NOTICE, "%s: Connection state changed to: %s", __func__, state); }
void printConnectionState() { sp_connectionstate state = sp_session_connectionstate(g_sess); switch(state) { case SP_CONNECTION_STATE_LOGGED_OUT: printf(".User is logged out.\n"); break; case SP_CONNECTION_STATE_LOGGED_IN: printf(".User is logged in.\n"); break; case SP_CONNECTION_STATE_DISCONNECTED: printf(".Someone was logged in.. but now they're not.\n"); break; case SP_CONNECTION_STATE_UNDEFINED: printf(".Connection state is undefined.\n"); break; case SP_CONNECTION_STATE_OFFLINE: printf(".User in offline mode.\n"); break; default: printf(".Not sure what the state is..."); break; } }
bool QSpotifySession::event(QEvent *e) { if (e->type() == NotifyMainThreadEventType) { qDebug() << "Process spotify event"; processSpotifyEvents(); e->accept(); return true; } else if (e->type() == QEvent::Timer) { qDebug() << "Timer, start spotify events"; QTimerEvent *te = static_cast<QTimerEvent *>(e); if (te->timerId() == m_timerID) { processSpotifyEvents(); e->accept(); return true; } } else if (e->type() == ConnectionErrorEventType) { qDebug() << "Connection error"; QSpotifyConnectionErrorEvent *ev = static_cast<QSpotifyConnectionErrorEvent *>(e); setConnectionError(ConnectionError(ev->error()), QString::fromUtf8(sp_error_message(ev->error()))); e->accept(); return true; } else if (e->type() == MetaDataEventType) { qDebug() << "Meta data"; emit metadataUpdated(); e->accept(); return true; } else if (e->type() == EndOfTrackEventType) { qDebug() << "End track"; m_trackChangedAutomatically = true; playNext(); e->accept(); return true; } else if (e->type() == StopEventType) { qDebug() << "Stop"; stop(); e->accept(); return true; } else if (e->type() == TrackProgressEventType) { qDebug() << "Track progress"; if(!m_isPlaying) { e->accept(); return true; } // Track progressed QSpotifyTrackProgressEvent *ev = static_cast<QSpotifyTrackProgressEvent *>(e); int currentTrackPositionDelta = ev->delta(); if (m_previousTrackRemaining > 0) { // We're still playing the previous back from our buffer int fromPreviousTrack = qMin(currentTrackPositionDelta, m_previousTrackRemaining); currentTrackPositionDelta -= fromPreviousTrack; m_previousTrackRemaining -= fromPreviousTrack; } m_currentTrackPosition += currentTrackPositionDelta; m_currentTrackPlayedDuration += currentTrackPositionDelta; emit currentTrackPositionChanged(); e->accept(); return true; } else if (e->type() == SendImageRequestEventType) { qDebug() << "Send image request"; QSpotifyRequestImageEvent *ev = static_cast<QSpotifyRequestImageEvent *>(e); sendImageRequest(ev->imageId()); e->accept(); return true; } else if (e->type() == ReceiveImageRequestEventType) { qDebug() << "Receive image request"; QSpotifyReceiveImageEvent *ev = static_cast<QSpotifyReceiveImageEvent *>(e); receiveImageResponse(ev->image()); e->accept(); return true; } else if (e->type() == PlayTokenLostEventType) { qDebug() << "Play token lost"; emit playTokenLost(); pause(); e->accept(); return true; } else if (e->type() == LoggedInEventType) { qDebug() << "Logged in 1"; onLoggedIn(); e->accept(); return true; } else if (e->type() == LoggedOutEventType) { qDebug() << "Logged out"; onLoggedOut(); e->accept(); return true; } else if (e->type() == OfflineErrorEventType) { qDebug() << "Offline error"; QSpotifyOfflineErrorEvent *ev = static_cast<QSpotifyOfflineErrorEvent *>(e); m_offlineErrorMessage = QString::fromUtf8(sp_error_message(ev->error())); emit offlineErrorMessageChanged(); e->accept(); return true; } else if (e->type() == ScrobbleLoginErrorEventType) { qDebug() << "Scrobble login error"; m_lfmLoggedIn = false; emit lfmLoggedInChanged(); emit lfmLoginError(); e->accept(); return true; } else if (e->type() == ConnectionStateUpdateEventType) { qDebug() << "Connectionstate update event"; setConnectionStatus(ConnectionStatus(sp_session_connectionstate(m_sp_session))); if (m_offlineMode && m_connectionStatus == LoggedIn) { setConnectionRules(m_connectionRules | AllowNetwork); setConnectionRules(m_connectionRules & ~AllowNetwork); } e->accept(); return true; } return QObject::event(e); }
JNIEXPORT int JNICALL Java_jahspotify_impl_JahSpotifyImpl_initialize ( JNIEnv *env, jobject obj, jstring username, jstring password ) { sp_session *sp; sp_error err; uint8_t *nativePassword = NULL; uint8_t *nativeUsername = NULL; int next_timeout = 0; if ( !username || !password ) { fprintf ( stderr, "Username or password not specified\n" ); return 1; } /* Create session */ spconfig.application_key_size = g_appkey_size; err = sp_session_create ( &spconfig, &sp ); if ( SP_ERROR_OK != err ) { fprintf ( stderr, "Unable to create session: %s\n",sp_error_message ( err ) ); return 1; } fprintf ( stderr, "Session created %x\n",(int)sp); nativeUsername = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, username, NULL ); nativePassword = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, password, NULL ); g_sess = sp; pthread_mutex_init ( &g_notify_mutex, NULL ); pthread_cond_init ( &g_notify_cond, NULL ); sp_playlistcontainer_add_callbacks ( sp_session_playlistcontainer ( g_sess ),&pc_callbacks,NULL ); fprintf ( stderr, "Initiating login: %s\n",nativeUsername ); sp_session_login ( sp, nativeUsername, nativePassword ); pthread_mutex_lock ( &g_notify_mutex ); for ( ;; ) { if ( next_timeout == 0 ) { while ( !g_notify_do && !g_playback_done ) pthread_cond_wait ( &g_notify_cond, &g_notify_mutex ); } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime ( CLOCK_REALTIME, &ts ); #else struct timeval tv; gettimeofday ( &tv, NULL ); TIMEVAL_TO_TIMESPEC ( &tv, &ts ); #endif ts.tv_sec += next_timeout / 1000; ts.tv_nsec += ( next_timeout % 1000 ) * 1000000; pthread_cond_timedwait ( &g_notify_cond, &g_notify_mutex, &ts ); } g_notify_do = 0; pthread_mutex_unlock ( &g_notify_mutex ); if ( g_playback_done ) { track_ended(); g_playback_done = 0; } sp_connectionstate conn_state = sp_session_connectionstate(sp); switch (conn_state) { case SP_CONNECTION_STATE_UNDEFINED: case SP_CONNECTION_STATE_LOGGED_OUT: case SP_CONNECTION_STATE_LOGGED_IN: break; case SP_CONNECTION_STATE_DISCONNECTED: fprintf ( stderr, "Disconnected!\n"); break; } do { sp_session_process_events ( sp, &next_timeout ); } while ( next_timeout == 0 ); pthread_mutex_lock ( &g_notify_mutex ); } // FIXME: Release the username/password allocated? return 0; }
/** login takes username, password tries to login with previous remembered user, thus, password can be empty will also try and utilize blob **/ void SpotifySession::login( const QString& username, const QString& password, const QByteArray& blob ) { if ( m_loggedIn && m_username == username && m_password == password ) { /// Always relogin when ever credentials change qDebug() << "Asked to log in with same username and pw that we are already logged in with, ignoring login"; /// Send response, and notifyAllreadyLoggedin, this will make config gui to stop "loading", and refetch all playlists emit loginResponse( true, "Logged in" ); emit notifyAllreadyLoggedin(); return; } if( m_username != username && m_loggedIn ) { // qDebug() << "We were previously logged in with a different user, so notify client of difference!"; emit userChanged(); } m_username = username; m_password = password; char reloginname[256]; sp_error error; int ok = sp_session_remembered_user( m_session, reloginname, sizeof(reloginname) ); if( ok != -1 && QString::fromUtf8( reloginname, strlen(reloginname) ) == m_username.toUtf8() ) { if ( sp_session_relogin(m_session) == SP_ERROR_NO_CREDENTIALS) { qDebug() << "No stored credentials tryin blob"; } else { qDebug() << "Logging in as remembered user"; return; } } else { // Forget last user if( ok == -1 ) qDebug() << " Relogin username was truncated or an error occured... Logging in with credentials"; else qDebug() << "Forgetting last user!" << QString::fromUtf8( reloginname, strlen( reloginname ) ) << m_username; sp_session_forget_me(m_session); } if( !m_username.isEmpty() && ( !m_password.isEmpty() || !blob.isEmpty() ) ) { /// @note: If current state is not logged out, logout this session /// and relogin in callback /// @note2: We can be logged out, but the session is still connected to accesspoint /// Wait for that to. if( sp_session_connectionstate(m_session) != SP_CONNECTION_STATE_LOGGED_OUT || m_loggedIn) { qDebug() << Q_FUNC_INFO << "SpotifySession asked to relog in! Logging out"; m_relogin = true; m_blob = blob; logout( true ); return; } qDebug() << Q_FUNC_INFO << "Logging in with username:"******" and is " << ( blob.isEmpty() ? "not" : "" ) << "using blob"; #if SPOTIFY_API_VERSION >= 12 error = sp_session_login(m_session, m_username.toUtf8(), m_password.toUtf8(), 1, blob.isEmpty() ? NULL : blob.constData() ); if( error != SP_ERROR_OK ) emit loginResponse( false, sp_error_message( error ) ); #elif SPOTIFY_API_VERSION >= 11 sp_session_login(m_session, m_username.toUtf8(), m_password.toUtf8(), 1, blob.isEmpty() ? NULL : blob.constData() ); #else sp_session_login(m_session, m_username.toUtf8(), m_password.toUtf8(), 1); #endif } else { qDebug() << "No username, password or blob provided!"; /// TODO: need a way to prompt for password if fail to login as remebered on startup /// If auth widget is not visual, we should promt user for re-entering creds emit loginResponse( false, "Failed to authenticate credentials." ); } }
int session_state(void) { int state; state = sp_session_connectionstate(g_session); return state; }