void Spotify::run() { int next_timeout = 0; sp = spotify_ll_init(Spotify_Wrapper::sessionCallbacks()); if (!sp) { return; } bool running = true; while (running) { SpotifyEvent_t ev = EVENT_NO_EVENT; // Get next event (or timeout) if (next_timeout == 0) { eq.get(ev); } else { if (!eq.get(ev, next_timeout)) { // Timed out ev = EVENT_TIMEOUT; } } switch (ev) { case EVENT_SPOTIFY_MAIN_TICK: case EVENT_TIMEOUT: break; case EVENT_LOGIN_CREDENTIALS_CHANGED: if (pass.isEmpty()) { // Try using credential blob sp_session_login(sp, user.toLocal8Bit().constData(), NULL, false, blob.constData()); } else { sp_session_login(sp, user.toLocal8Bit().constData(), pass.toLocal8Bit().constData(), false, NULL); } break; case EVENT_LOGGED_IN: emit loggedIn(); break; case EVENT_PLAYLIST_CONTAINER_LOADED: compileNewListOfPlaylists(); break; case EVENT_LOGGED_OUT: emit loggedOut(); break; case EVENT_URI_CHANGED: changeCurrentlyPlayingSong(); break; case EVENT_PLAYLIST_IDX_CHANGED: changeCurrentPlaylist(); break; case EVENT_METADATA_UPDATED: tryLoadTrack(); break; case EVENT_START_PLAYBACK: if (!audioThread.isRunning()) { fprintf(stderr, "Spotify: Starting audio worker\n"); SpotifyAudioWorker * audioWorker = new SpotifyAudioWorker(this); audioWorker->moveToThread(&audioThread); connect(&audioThread, SIGNAL(started()), audioWorker, SLOT(startStreaming())); connect(&audioThread, SIGNAL(finished()), audioWorker, SLOT(stopStreaming())); connect(&audioThread, SIGNAL(finished()), audioWorker, SLOT(deleteLater())); connect(audioWorker, SIGNAL(streamingFailed()), this, SIGNAL(audioStreamingFailed())); audioThread.start(); } break; case EVENT_STOP_PLAYBACK: if (audioThread.isRunning()) { audioThread.quit(); audioThread.wait(); } accessMutex.lock(); audioBuffer.close(); readPos = 0; writePos = 0; accessMutex.unlock(); break; case EVENT_END_OF_TRACK: sp_session_player_unload(sp); sp_track_release(currentTrack); currentURI.clear(); nextTrack = 0; currentTrack = 0; break; default: qDebug() << "Unknown event:" << (int)ev; break; } do { sp_session_process_events(sp, &next_timeout); } while (next_timeout == 0); } }
SmoozikSimplestClientWindow::SmoozikSimplestClientWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::SmoozikSimplestClientWindow) { ui->setupUi(this); // Initialize SmoozikManager smoozikManager = new SmoozikManager(APIKEY, SECRET, SmoozikManager::XML, false, this); smoozikPlaylist = new SmoozikPlaylist; connect(smoozikManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetworkReply(QNetworkReply*))); // Initialize music directory #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) _dirName = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); #else _dirName = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); #endif // Initialize playlist filler ui->setupUi(this); smoozikPlaylistFillerThread = new QThread(); smoozikPlaylistFiller = new SmoozikPlaylistFiller(smoozikPlaylist); smoozikPlaylistFiller->moveToThread(smoozikPlaylistFillerThread); connect(smoozikPlaylistFiller, SIGNAL(trackFound(QString,QString,QString,QString,uint)), this, SLOT(addTrackToPlaylist(QString,QString,QString,QString,uint))); connect(smoozikPlaylistFiller, SIGNAL(tracksRetrieved()), this, SIGNAL(tracksRetrieved())); connect(smoozikPlaylistFiller, SIGNAL(noTrackRetrieved()), this, SLOT(noTrackRetrievedMessage())); connect(smoozikPlaylistFiller, SIGNAL(maxPlaylistSizeReached()), this, SLOT(maxPlaylistSizeReachedMessage())); connect(smoozikPlaylistFillerThread, SIGNAL(started()), smoozikPlaylistFiller, SLOT(fillPlaylist())); connect(smoozikPlaylistFiller, SIGNAL(finished()), smoozikPlaylistFillerThread, SLOT(quit()), Qt::DirectConnection); // Initialize player #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) player = new Phonon::MediaObject(this); Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); Phonon::createPath(player, audioOutput); connect(player, SIGNAL(currentSourceChanged(Phonon::MediaSource)), this, SLOT(updateTrackLabels())); connect(player, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(playerStateChanged())); #else player = new QMediaPlayer(this); player->setPlaylist(new QMediaPlaylist(player)); player->playlist()->setPlaybackMode(QMediaPlaylist::Sequential); connect(player, SIGNAL(currentMediaChanged(QMediaContent)), this, SLOT(updateTrackLabels())); connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged())); #endif connect(ui->playButton, SIGNAL(clicked()), player, SLOT(play())); connect(ui->pauseButton, SIGNAL(clicked()), player, SLOT(pause())); connect(this, SIGNAL(currentTrackSet()), this, SLOT(updateTrackLabels())); connect(this, SIGNAL(nextTrackSet()), this, SLOT(updateTrackLabels())); // Initialize main state machine which controls what is displayed QStateMachine *mainStateMachine = new QStateMachine(this); QState *mainState = new QState(mainStateMachine); QState *loginState = new QState(mainState); QState *startPartyState = new QState(mainState); QState *connectedState = new QState(mainState); QState *retrieveTracksState = new QState(connectedState); QState *sendPlaylistState = new QState(connectedState); QState *getTopTracksState = new QState(connectedState); QState *partyState = new QState(connectedState); QState *waitingState = new QState(partyState); QState *sendCurrentTrackState = new QState(partyState); QState *sendNextTrackState = new QState(partyState); QStateMachine *playerStateMachine = new QStateMachine(this); QState *playerState = new QState(playerStateMachine); QState *playingState = new QState(playerState); QState *pausedState = new QState(playerState); // Define state initial states and transitions mainStateMachine->setInitialState(mainState); mainState->setInitialState(loginState); connectedState->setInitialState(retrieveTracksState); partyState->setInitialState(waitingState); playerStateMachine->setInitialState(playerState); playerState->setInitialState(pausedState); mainState->addTransition(this, SIGNAL(disconnected()), loginState); loginState->addTransition(this, SIGNAL(loggedIn()), startPartyState); startPartyState->addTransition(this, SIGNAL(partyStarted()), connectedState); connectedState->addTransition(ui->changePlaylistButton, SIGNAL(clicked()), retrieveTracksState); retrieveTracksState->addTransition(this, SIGNAL(tracksRetrieved()), sendPlaylistState); sendPlaylistState->addTransition(this, SIGNAL(playlistSent()), getTopTracksState); getTopTracksState->addTransition(this, SIGNAL(currentTrackSet()), sendCurrentTrackState); sendCurrentTrackState->addTransition(this, SIGNAL(currentTrackSent()), getTopTracksState); getTopTracksState->addTransition(this, SIGNAL(nextTrackSet()), sendNextTrackState); sendNextTrackState->addTransition(this, SIGNAL(nextTrackSent()), waitingState); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) waitingState->addTransition(player, SIGNAL(currentSourceChanged(Phonon::MediaSource)), sendCurrentTrackState); #else waitingState->addTransition(player, SIGNAL(currentMediaChanged(QMediaContent)), sendCurrentTrackState); #endif playerState->addTransition(this, SIGNAL(playing()), playingState); playerState->addTransition(this, SIGNAL(paused()), pausedState); // Define state properties loginState->assignProperty(this, "state", Login); loginState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->loginPage)); loginState->assignProperty(ui->loginButton, "enabled", true); loginState->assignProperty(ui->disconnectButton, "visible", false); loginState->assignProperty(ui->changePlaylistButton, "visible", false); loginState->assignProperty(ui->usernameLineEdit, "enabled", true); loginState->assignProperty(ui->passwordLineEdit, "enabled", true); loginState->assignProperty(ui->loginStateLabel, "text", QString()); startPartyState->assignProperty(this, "state", StartParty); startPartyState->assignProperty(ui->loginStateLabel, "text", tr("Starting party...")); startPartyState->assignProperty(ui->disconnectButton, "visible", false); startPartyState->assignProperty(ui->changePlaylistButton, "visible", false); connectedState->assignProperty(ui->disconnectButton, "visible", true); retrieveTracksState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->loadingPage)); retrieveTracksState->assignProperty(ui->loginStateLabel, "text", tr("Connected")); retrieveTracksState->assignProperty(ui->loadingLabel, "text", tr("Retrieving tracks...")); retrieveTracksState->assignProperty(ui->changePlaylistButton, "visible", false); sendPlaylistState->assignProperty(this, "state", SendPlaylist); sendPlaylistState->assignProperty(ui->loadingLabel, "text", tr("Sending playlist...")); sendPlaylistState->assignProperty(ui->changePlaylistButton, "visible", true); getTopTracksState->assignProperty(this, "state", GetTopTracks); getTopTracksState->assignProperty(ui->loadingLabel, "text", tr("Get top tracks...")); getTopTracksState->assignProperty(ui->nextButton, "enabled", false); getTopTracksState->assignProperty(ui->changePlaylistButton, "visible", true); partyState->assignProperty(ui->stackedWidget, "currentIndex", ui->stackedWidget->indexOf(ui->playerPage)); partyState->assignProperty(ui->changePlaylistButton, "visible", true); sendCurrentTrackState->assignProperty(this, "state", SendCurrentTrack); sendCurrentTrackState->assignProperty(ui->nextButton, "enabled", false); sendNextTrackState->assignProperty(this, "state", SendNextTrack); sendNextTrackState->assignProperty(ui->nextButton, "enabled", false); waitingState->assignProperty(ui->nextButton, "enabled", true); playingState->assignProperty(ui->playButton, "visible", false); playingState->assignProperty(ui->pauseButton, "visible", true); pausedState->assignProperty(ui->playButton, "visible", true); pausedState->assignProperty(ui->pauseButton, "visible", false); // Connect states and actions connect(startPartyState, SIGNAL(entered()), this, SLOT(startParty())); connect(retrieveTracksState, SIGNAL(entered()), this, SLOT(retrieveTracksDialog())); connect(sendPlaylistState, SIGNAL(entered()), this, SLOT(sendPlaylist())); connect(getTopTracksState, SIGNAL(entered()), this, SLOT(getTopTracks())); connect(sendCurrentTrackState, SIGNAL(entered()), this, SLOT(sendCurrentTrack())); connect(sendNextTrackState, SIGNAL(entered()), this, SLOT(sendNextTrack())); // Connect gui and actions connect(ui->usernameLineEdit, SIGNAL(returnPressed()), this, SLOT(submitLogin())); connect(ui->passwordLineEdit, SIGNAL(returnPressed()), this, SLOT(submitLogin())); connect(ui->loginButton, SIGNAL(clicked()), this, SLOT(submitLogin())); connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(nextTrack())); connect(ui->disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect())); // Start state machine mainStateMachine->start(); playerStateMachine->start(); }
MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { QString hostname="localhost"; unsigned port=LPCORE_CONNECTION_TCP_PORT; QString username; QString password; bool track_state=false; bool ok=false; // // Fonts // QFont label_font("helvetica",12,QFont::Bold); label_font.setPixelSize(12); // // Read Command Options // LPCmdSwitch *cmd= new LPCmdSwitch(qApp->argc(),qApp->argv(),"lpcore",LPCORE_USAGE); for(unsigned i=0;i<cmd->keys();i++) { if(cmd->key(i)=="--hostname") { hostname=cmd->value(i); cmd->setProcessed(i,true); } if(cmd->key(i)=="--port") { port=cmd->value(i).toUInt(&ok); if((!ok)||(port>0xFFFF)) { fprintf(stderr,"invalid port value\n"); exit(256); } cmd->setProcessed(i,true); } if(cmd->key(i)=="--username") { username=cmd->value(i); cmd->setProcessed(i,true); } if(cmd->key(i)=="--password") { password=cmd->value(i); cmd->setProcessed(i,true); } if(cmd->key(i)=="--track-state") { track_state=true; cmd->setProcessed(i,true); } if(!cmd->processed(i)) { fprintf(stderr,"unknown option \"%s\"\n", (const char *)cmd->key(i).toAscii()); exit(256); } } delete cmd; // // Open Syslog // openlog("lpcore",LOG_PERROR,LOG_USER); // // Connection // lp_connection=new LPConnection(track_state,this); connect(lp_connection,SIGNAL(messageReceived(const LPMessage &)), this,SLOT(messageReceivedData(const LPMessage &))); connect(lp_connection,SIGNAL(watchdogStateChanged(bool)), this,SLOT(watchdogStateChangedData(bool))); connect(lp_connection,SIGNAL(loggedIn(LPConnection::Result)), this,SLOT(loggedInData(LPConnection::Result))); connect(lp_connection, SIGNAL(socketError(QAbstractSocket::SocketError,const QString &)), this, SLOT(socketErrorData(QAbstractSocket::SocketError,const QString &))); // // Context Selector // lp_context_label=new QLabel(tr("Context")+":",this); lp_context_label->setFont(label_font); lp_context_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); lp_context_box=new QComboBox(this); lp_context_box->insertItem(-1,tr("Global")); lp_context_box->insertItem(-1,tr("Isolated")); lp_context_box->setCurrentIndex(1); connect(lp_context_box,SIGNAL(activated(int)), this,SLOT(contextChangedData(int))); lp_clear_button=new QPushButton(tr("Clear"),this); lp_clear_button->setFont(label_font); // // Send Widget // lp_send_edit=new QLineEdit(this); lp_send_edit->setDisabled(true); connect(lp_send_edit,SIGNAL(returnPressed()),this,SLOT(returnPressedData())); // // Receive Widget // lp_recv_edit=new QTextEdit(this); lp_recv_edit->setReadOnly(true); connect(lp_clear_button,SIGNAL(clicked()),lp_recv_edit,SLOT(clear())); contextChangedData(lp_context_box->currentIndex()); lp_connection->connectToHost(hostname,port,username,password); UpdateWindowTitle(); }
void SmoozikSimplestClientWindow::getNextTrackInfo(QString *localId, QString *name, QString *artist, QString *album) { *localId = QString(); *name = QString(); *artist = QString(); *album = QString(); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) if (!player->queue().isEmpty()) { *localId = player->queue().at(0).url().toLocalFile(); #else if (player->playlist()->currentIndex() >= 0 && player->playlist()->mediaCount() > player->playlist()->currentIndex() + 1) { *localId = player->playlist()->media(player->playlist()->currentIndex() + 1).canonicalUrl().toLocalFile(); #endif TagLib::FileRef mediaFileRef(QFile::encodeName(*localId).constData()); if (!mediaFileRef.isNull()) { *name = TStringToQString(mediaFileRef.tag()->title()); *artist = TStringToQString(mediaFileRef.tag()->artist()); *album = TStringToQString(mediaFileRef.tag()->album()); } } } void SmoozikSimplestClientWindow::processNetworkReply(QNetworkReply *reply) { QString path = reply->url().path(); SmoozikXml xml(reply); if (xml.error() != 0) { error(xml.errorMsg()); } else { // Process different cases of request if (path.endsWith("login", Qt::CaseInsensitive) && state() == Login) { //Retrieve sessionKey smoozikManager->setSessionKey(xml["sessionKey"].toString()); emit loggedIn(); } else if (path.endsWith("startParty", Qt::CaseInsensitive) && state() == StartParty) { emit partyStarted(); } else if (path.endsWith("sendPlaylist", Qt::CaseInsensitive) && state() == SendPlaylist) { emit playlistSent(); } else if (path.endsWith("getTopTracks", Qt::CaseInsensitive) && state() == GetTopTracks) { // Set mediaPlaylist from top tracks. SmoozikPlaylist topTracksPlaylist(xml["tracks"].toList()); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) if (player->queue().isEmpty()) { if(player->currentSource().type() != Phonon::MediaSource::LocalFile) { player->setCurrentSource(Phonon::MediaSource(topTracksPlaylist.value(0)->localId())); emit currentTrackSet(); } else { player->enqueue(Phonon::MediaSource(topTracksPlaylist.value(0)->localId())); emit nextTrackSet(); } } #else if (player->playlist()->mediaCount() < 2 || player->playlist()->currentIndex() >= player->playlist()->mediaCount() - 2) { player->playlist()->addMedia(QUrl::fromLocalFile(topTracksPlaylist.value(0)->localId())); if(player->playlist()->mediaCount() == 1 || player->playlist()->currentIndex() == player->playlist()->mediaCount() - 1) { emit currentTrackSet(); } else { emit nextTrackSet(); } } #endif } else if (path.endsWith("setTrack", Qt::CaseInsensitive) && state() == SendCurrentTrack) { emit currentTrackSent(); } else if (path.endsWith("setTrack", Qt::CaseInsensitive) && state() == SendNextTrack) { emit nextTrackSent(); } } }
void Pastebin::readData(QNetworkReply* reply) { QByteArray response = reply->readAll(); qDebug() << reply->header(QNetworkRequest::ContentTypeHeader); if (response.contains("Bad API request")) { m_errorString = response; QString code = response.split(',')[1].simplified().toLower(); if (code == "use post request, not get") emit error(InvalidRequestType); else if (code == "invalid api_dev_key") emit error(InvalidDevKey); else if (code == "invalid login") emit error(InvalidLogin); else if (code == "account not active") emit error(InactiveAccount); else if (code == "invalid post parameters") emit error(InvalidPostParameters); else if (code == "invalid permission to remove paste") emit error(InvalidPermissions); else if (code == "invalid api_option") emit error(InvalidOption); else if (code == "invalid api_user_key") emit error(InvalidUserKey); else if (code == "ip blocked") emit error(BlockedIP); else if (code.contains("maximum number of 10")) emit error(Max10Exceeded); else if (code.contains("maximum number of 25")) emit error(Max25Exceeded); else if (code == "invalid_expire_date") emit error(InvalidExpireDate); else if (code == "maximum paste file size exceeded") emit error(MaxSizeExceeded); else if (code == "invalid api_paste_format") emit error(InvalidFormat); else if (code == "api_paste_code was empty") emit error(EmptyCode); else emit unknownError(response); } else if (reply->url().toString().contains(PASTEBIN_LOGIN)) { m_userKey = QString(response).simplified(); emit loggedIn(m_userKey); } else if (reply->url().toString().contains(PASTEBIN_POST)) { if (response.indexOf(PASTEBIN_URL) == 0) emit pasteSuccessful(QUrl(response.simplified())); if (response.indexOf("Paste Removed") == 0) emit deleteSuccessful(); if (response.contains("<user>")) emit user(UserInfo::fromData(response)); if (response.contains("<paste>")) // We have to add opening and closing tags so QXmlStreamReader reads the data correctly. // For some reason if the data is not enclosed, the reader flips a shit and goes into an // infinite loop. emit pastes(PasteInfo::fromList("<trends>\n"+response +"\n</trends>")); } }