Exemplo n.º 1
0
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();
}
Exemplo n.º 3
0
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();
        }
    }
}
Exemplo n.º 5
0
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>"));
    }
}