Ejemplo n.º 1
0
void ArtistBiography::FetchInfo(int id, const Song& metadata) {
  if (metadata.artist().isEmpty()) {
    emit Finished(id);
    return;
  }

  QUrl url(kArtistBioUrl);
  url.addQueryItem("artist", metadata.artist());
  url.addQueryItem("lang", GetLocale());

  qLog(Debug) << "Biography url: " << url;

  QNetworkRequest request(url);
  QNetworkReply* reply = network_->get(request);

  NewClosure(reply, SIGNAL(finished()), [this, reply, id]() {
    reply->deleteLater();

    QJson::Parser parser;
    QVariantMap response = parser.parse(reply).toMap();

    QString body = response["articleBody"].toString();
    QString url = response["url"].toString();

    CountdownLatch* latch = new CountdownLatch;

    if (url.contains("wikipedia.org")) {
      FetchWikipediaImages(id, url, latch);
      FetchWikipediaArticle(id, url, latch);
    } else {
      latch->Wait();
      // Use the simple article body from KG.
      if (!body.isEmpty()) {
        CollapsibleInfoPane::Data data;
        data.id_ = url;
        data.title_ = tr("Biography");
        data.type_ = CollapsibleInfoPane::Data::Type_Biography;

        QString text;
        text += "<p><a href=\"" + url + "\">" + tr("Open in your browser") +
                "</a></p>";

        text += body;
        SongInfoTextView* editor = new SongInfoTextView;
        editor->SetHtml(text);
        data.contents_ = editor;
        emit InfoReady(id, data);
      }
      latch->CountDown();
    }

    NewClosure(latch, SIGNAL(Done()), [this, id, latch]() {
      latch->deleteLater();
      emit Finished(id);
    });
  });
}
Ejemplo n.º 2
0
void GPodderSearchPage::SearchClicked() {
  emit Busy(true);

  mygpo::PodcastListPtr list(api_->search(ui_->query->text()));
  NewClosure(list, SIGNAL(finished()), this,
             SLOT(SearchFinished(mygpo::PodcastListPtr)), list);
  NewClosure(list, SIGNAL(parseError()), this,
             SLOT(SearchFailed(mygpo::PodcastListPtr)), list);
  NewClosure(list, SIGNAL(requestError(QNetworkReply::NetworkError)), this,
             SLOT(SearchFailed(mygpo::PodcastListPtr)), list);
}
Ejemplo n.º 3
0
void ArtistBiography::FetchWikipediaImages(int id, const QString& wikipedia_url,
                                           CountdownLatch* latch) {
  latch->Wait();
  qLog(Debug) << wikipedia_url;
  QRegExp regex("([a-z]+)\\.wikipedia\\.org/wiki/(.*)");
  if (regex.indexIn(wikipedia_url) == -1) {
    emit Finished(id);
    return;
  }
  QString wiki_title = QUrl::fromPercentEncoding(regex.cap(2).toUtf8());
  QString language = regex.cap(1);
  QUrl url(QString(kWikipediaImageListUrl).arg(language));
  url.addQueryItem("titles", wiki_title);

  qLog(Debug) << "Wikipedia images:" << url;

  QNetworkRequest request(url);
  QNetworkReply* reply = network_->get(request);
  NewClosure(reply, SIGNAL(finished()), [this, id, reply, language, latch]() {
    reply->deleteLater();

    QJson::Parser parser;
    QVariantMap response = parser.parse(reply).toMap();

    QStringList image_titles = ExtractImageTitles(response);

    for (const QString& image_title : image_titles) {
      latch->Wait();
      QUrl url(QString(kWikipediaImageInfoUrl).arg(language));
      url.addQueryItem("titles", image_title);
      qLog(Debug) << "Image info:" << url;

      QNetworkRequest request(url);
      QNetworkReply* reply = network_->get(request);
      NewClosure(reply, SIGNAL(finished()), [this, id, reply, latch]() {
        reply->deleteLater();
        QJson::Parser parser;
        QVariantMap json = parser.parse(reply).toMap();
        QUrl url = ExtractImageUrl(json);
        qLog(Debug) << "Found wikipedia image url:" << url;
        if (!url.isEmpty()) {
          emit ImageReady(id, url);
        }
        latch->CountDown();
      });
    }

    latch->CountDown();
  });
}
Ejemplo n.º 4
0
void OAuthenticator::StartAuthorisation(const QString& oauth_endpoint,
                                        const QString& token_endpoint,
                                        const QString& scope) {
  token_endpoint_ = QUrl(token_endpoint);
  LocalRedirectServer* server = new LocalRedirectServer(this);
  server->Listen();

  QUrl url = QUrl(oauth_endpoint);
  url.addQueryItem("response_type", "code");
  url.addQueryItem("client_id", client_id_);
  QUrl redirect_url;

  const QString port = QString::number(server->url().port());

  if (redirect_style_ == RedirectStyle::REMOTE) {
    redirect_url = QUrl(kRemoteURL);
    redirect_url.addQueryItem("port", port);
  } else if (redirect_style_ == RedirectStyle::REMOTE_WITH_STATE) {
    redirect_url = QUrl(kRemoteURL);
    url.addQueryItem("state", port);
  } else {
    redirect_url = server->url();
  }

  url.addQueryItem("redirect_uri", redirect_url.toString());
  url.addQueryItem("scope", scope);

  NewClosure(server, SIGNAL(Finished()), this, &OAuthenticator::RedirectArrived,
             server, redirect_url);

  QDesktopServices::openUrl(url);
}
Ejemplo n.º 5
0
void DumbCallback::notify() {
  std::list<DumbCall *>::iterator i;
  for (i=calls_.begin() ; i!=calls_.end() ; i++) {
    (*i)->enqueue();
    dispatcher_->add_job(NewClosure(*i, &DumbCall::notify));
  }
}
Ejemplo n.º 6
0
void SpotifyImages::FetchImagesForArtist(int id, const QString& spotify_id) {
  QUrl artist_url(QString(kSpotifyArtistUrl).arg(spotify_id));
  qLog(Debug) << "Fetching images for artist:" << artist_url;
  QNetworkRequest request(artist_url);
  QNetworkReply* reply = network_->get(request);
  NewClosure(reply, SIGNAL(finished()), [this, id, reply]() {
    reply->deleteLater();
    QJson::Parser parser;
    QVariantMap result = parser.parse(reply).toMap();
    QVariantList images = result["images"].toList();
    QList<QPair<QUrl, QSize>> image_candidates;
    for (QVariant i : images) {
      QVariantMap image = i.toMap();
      int height = image["height"].toInt();
      int width = image["width"].toInt();
      QUrl url = image["url"].toUrl();
      image_candidates.append(qMakePair(url, QSize(width, height)));
    }
    if (!image_candidates.isEmpty()) {
      QPair<QUrl, QSize> winner =
          *std::max_element(
              image_candidates.begin(), image_candidates.end(),
              [](const QPair<QUrl, QSize>& a, const QPair<QUrl, QSize>& b) {
                return (a.second.height() * a.second.width()) <
                       (b.second.height() * b.second.width());
              });
      emit ImageReady(id, winner.first);
    }
    emit Finished(id);
  });
}
Ejemplo n.º 7
0
 foreach ( ConfigStorage* cs, m_configStorageById )
 {
     m_configStorageLoading.insert( cs->id() );
     NewClosure( cs, SIGNAL( ready() ),
                 this, SLOT( finishLoadingFromConfig( QString ) ), cs->id() );
     cs->init();
 }
Ejemplo n.º 8
0
static void HandleService(
    google::protobuf::Service *service,
    const google::protobuf::MethodDescriptor *method,
    const google::protobuf::Message *request_prototype,
    const google::protobuf::Message *response_prototype,
    const ProtobufDecoder *decoder,
    boost::shared_ptr<Connection> connection) {
  VLOG(2) << connection->name() << " : " <<  "HandleService: " << method->full_name();
  const ProtobufLineFormat::MetaData &meta = decoder->meta();
  boost::shared_ptr<google::protobuf::Message> request(request_prototype->New());
  const string &content = decoder->meta().content();
  VLOG(2) << connection->name() << " : " << "content size: " << content.size();
  if (!request->ParseFromArray(
      content.c_str(),
      content.size())) {
    LOG(WARNING) << connection->name() << " : " << "HandleService but invalid format";
    return;
  }
  boost::shared_ptr<google::protobuf::Message> response(response_prototype->New());
  google::protobuf::Closure *done = NewClosure(
      boost::bind(CallServiceMethodDone,
                  connection,
                  decoder,
                  request,
                  response));
  service->CallMethod(method, connection.get(), request.get(), response.get(), done);
}
Ejemplo n.º 9
0
void
GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index )
{
    QPoint pos = m_playButton[ index ]->pos();
    clearButtons();

    AnimatedSpinner* spinner = new AnimatedSpinner( m_view );
    spinner->setAutoCenter( false );
    spinner->fadeIn();
    spinner->move( pos );
    spinner->setFocusPolicy( Qt::NoFocus );
    spinner->installEventFilter( this );

    m_spinner[ index ] = spinner;

    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );

    NewClosure(  AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ),
                const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) );

    if ( item )
    {
        if ( !item->query().isNull() )
            AudioEngine::instance()->playItem( m_model->playlistInterface(), item->query() );
        else if ( !item->album().isNull() )
            AudioEngine::instance()->playItem( item->album() );
        else if ( !item->artist().isNull() )
            AudioEngine::instance()->playItem( item->artist() );
    }
}
Ejemplo n.º 10
0
void EventLoop::cancel(uint64_t timerId) {
  Closure<void> *pCb = NewClosure(this, &EventLoop::innerCancel, uint64_t(timerId));
  {
    SpinLockGuard lock(lock_);
    pendingFunctors_.push_back(pCb);
  }
  wakeup();
}
Ejemplo n.º 11
0
void SpotifyServer::StartPlaybackLater(const QString& uri, quint16 port) {
  QTimer* timer = new QTimer(this);
  connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));

  timer->start(100);  // lol
  NewClosure(timer, SIGNAL(timeout()), this,
             SLOT(StartPlayback(QString, quint16)), uri, port);
}
Ejemplo n.º 12
0
TagCompleter::TagCompleter(LibraryBackend* backend, Playlist::Column column,
                           QLineEdit* editor)
    : QCompleter(editor), editor_(editor) {
  QFuture<TagCompletionModel*> future =
      QtConcurrent::run(&InitCompletionModel, backend, column);
  NewClosure(future, this, SLOT(ModelReady(QFuture<TagCompletionModel*>)),
             future);
}
Ejemplo n.º 13
0
TEST(ClosureTest, ClosureCallsLambda) {
  TestQObject sender;
  bool called = false;
  NewClosure(
      &sender, SIGNAL(Emitted()),
      [&called] () { called = true; });
  EXPECT_FALSE(called);
  sender.Emit();
  EXPECT_TRUE(called);
}
Ejemplo n.º 14
0
void
GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index )
{
    QPoint pos = m_playButton[ index ]->pos();
    foreach ( ImageButton* button, m_playButton )
        button->deleteLater();
    m_playButton.clear();

    AnimatedSpinner* spinner = new AnimatedSpinner( m_view );
    spinner->setAutoCenter( false );
    spinner->fadeIn();
    spinner->move( pos );
    spinner->setFocusPolicy( Qt::NoFocus );
    spinner->installEventFilter( this );

    m_spinner[ index ] = spinner;

    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
    if ( item )
    {
        NewClosure( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ),
                    const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) );

        m_closures.remove( index );

        m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ),
                                const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) );
        m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( stopped() ),
                                const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) );

        foreach ( _detail::Closure* closure, m_closures.values( index ) )
            closure->setAutoDelete( false );

        connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackFinished() ) );

        if ( !item->query().isNull() )
            AudioEngine::instance()->playItem( Tomahawk::playlistinterface_ptr(), item->query() );
        else if ( !item->album().isNull() )
            AudioEngine::instance()->playItem( item->album() );
        else if ( !item->artist().isNull() )
            AudioEngine::instance()->playItem( item->artist() );
    }
}
Ejemplo n.º 15
0
TEST(ClosureTest, ClosureInvokesReceiver) {
  TestQObject sender;
  TestQObject receiver;
  _detail::ClosureBase* closure = NewClosure(
      &sender, SIGNAL(Emitted()),
      &receiver, SLOT(Invoke()));
  EXPECT_EQ(0, receiver.invoked());
  sender.Emit();
  EXPECT_EQ(1, receiver.invoked());
}
Ejemplo n.º 16
0
TEST(ClosureTest, ClosureWorksWithMemberFunctionPointers) {
  TestQObject sender;
  Bar receiver(42);
  int q = 1;
  NewClosure(
      &sender, SIGNAL(Emitted()),
      &receiver, &Bar::Foo, &q);
  EXPECT_EQ(1, q);
  sender.Emit();
  EXPECT_EQ(42, q);
}
Ejemplo n.º 17
0
void DeviceProperties::UpdateFormats() {
    QString id = index_.data(DeviceManager::Role_UniqueId).toString();
    DeviceLister* lister = manager_->GetLister(index_.row());
    std::shared_ptr<ConnectedDevice> device =
        manager_->GetConnectedDevice(index_.row());

    // Transcode mode
    MusicStorage::TranscodeMode mode = MusicStorage::TranscodeMode(
                                           index_.data(DeviceManager::Role_TranscodeMode).toInt());
    switch (mode) {
    case MusicStorage::Transcode_Always:
        ui_->transcode_all->setChecked(true);
        break;

    case MusicStorage::Transcode_Never:
        ui_->transcode_off->setChecked(true);
        break;

    case MusicStorage::Transcode_Unsupported:
    default:
        ui_->transcode_unsupported->setChecked(true);
        break;
    }

    // If there's no lister then the device is physically disconnected
    if (!lister) {
        ui_->formats_stack->setCurrentWidget(ui_->formats_page_not_connected);
        ui_->open_device->setEnabled(false);
        return;
    }

    // If there's a lister but no device then the user just needs to open the
    // device.  This will cause a rescan so we don't do it automatically.
    if (!device) {
        ui_->formats_stack->setCurrentWidget(ui_->formats_page_not_connected);
        ui_->open_device->setEnabled(true);
        return;
    }

    if (!updating_formats_) {
        // Get the device's supported formats list.  This takes a long time and it
        // blocks, so do it in the background.
        supported_formats_.clear();

        QFuture<bool> future = QtConcurrent::run(std::bind(
                                   &ConnectedDevice::GetSupportedFiletypes, device, &supported_formats_));
        NewClosure(future, this, SLOT(UpdateFormatsFinished(QFuture<bool>)),
                   future);

        ui_->formats_stack->setCurrentWidget(ui_->formats_page_loading);
        updating_formats_ = true;
    }
}
Ejemplo n.º 18
0
void EditTagDialog::accept() {
  // Show the loading indicator
  if (!SetLoading(tr("Saving tracks") + "...")) return;

  abortRequested_ = false;
  ui_->abortSaveButton->setEnabled(true);

  // Save tags in the background
  QFuture<void> future =
      QtConcurrent::run(this, &EditTagDialog::SaveData, data_);
  NewClosure(future, this, SLOT(AcceptFinished()));
}
Ejemplo n.º 19
0
TinyThread::TinyThread(Closure<void>* func, const char* name)
  : mFunc(func),
    mHandle(0)
{
    if (name != NULL) {
        mName = name;
    }
    Closure<void>* routine = NewClosure(this, &TinyThread::Routine);
    if (::pthread_create(
            &mHandle, NULL, ThreadFunc, reinterpret_cast<void*>(routine))) {
        ::abort();
    }
}
Ejemplo n.º 20
0
TEST(ClosureTest, ClosureWorksWithFunctionPointers) {
  TestQObject sender;
  bool called = false;
  int question = 42;
  int answer = 0;
  NewClosure(
      &sender, SIGNAL(Emitted()),
      &Foo, &called, question, &answer);
  EXPECT_FALSE(called);
  sender.Emit();
  EXPECT_TRUE(called);
  EXPECT_EQ(question, answer);
}
Ejemplo n.º 21
0
bool OrganiseDialog::SetFilenames(const QStringList& filenames) {
  songs_future_ =
      QtConcurrent::run(this, &OrganiseDialog::LoadSongsBlocking, filenames);
  QFutureWatcher<SongList>* watcher = new QFutureWatcher<SongList>(this);
  watcher->setFuture(songs_future_);
  NewClosure(watcher, SIGNAL(finished()), [=]() {
    SetSongs(songs_future_.result());
    watcher->deleteLater();
  });

  SetLoadingSongs(true);
  return true;
}
Ejemplo n.º 22
0
void OAuthenticator::StartAuthorisation() {
  server_.listen(QHostAddress::LocalHost);
  const quint16 port = server_.serverPort();

  NewClosure(&server_, SIGNAL(newConnection()), this, SLOT(NewConnection()));

  QUrl url = QUrl(kGoogleOAuthEndpoint);
  url.addQueryItem("response_type", "code");
  url.addQueryItem("client_id", kClientId);
  url.addQueryItem("redirect_uri", QString("http://localhost:%1").arg(port));
  url.addQueryItem("scope", kGoogleOAuthScope);

  QDesktopServices::openUrl(url);
}
Ejemplo n.º 23
0
TEST(ClosureTest, ClosureWorksWithStandardFunctions) {
  TestQObject sender;
  bool called = false;
  int question = 42;
  int answer = 0;
  boost::function<void(bool*,int,int*)> callback(&Foo);
  NewClosure(
      &sender, SIGNAL(Emitted()),
      callback, &called, question, &answer);
  EXPECT_FALSE(called);
  sender.Emit();
  EXPECT_TRUE(called);
  EXPECT_EQ(question, answer);
}
Ejemplo n.º 24
0
static int EvalCompound(expADT exp, environmentADT env){
    char op;
    int lhs, rhs;
	valueADT lValue, rValue;

    op = ExpOperator(exp);

	lValue = Eval(ExpLHS(exp), NewClosure(env));
    rValue = Eval(ExpRHS(exp), NewClosure(env));
	
	lhs = GetIntValue(lValue);
	rhs = GetIntValue(rValue);
		


    switch (op) {
      case '+': return (lhs + rhs);
      case '-': return (lhs - rhs);
      case '*': return (lhs * rhs);
	  case '/': if (rhs == 0) Error("Division by zero\n"); else return (lhs / rhs);
      default:  Error("Illegal operator");
    }
}
Ejemplo n.º 25
0
void EditTagDialog::SetSongs(const SongList& s, const PlaylistItemList& items) {
  // Show the loading indicator
  if (!SetLoading(tr("Loading tracks") + "...")) return;

  data_.clear();
  playlist_items_ = items;
  ui_->song_list->clear();

  // Reload tags in the background
  QFuture<QList<Data>> future =
      QtConcurrent::run(this, &EditTagDialog::LoadData, s);
  NewClosure(future, this,
             SLOT(SetSongsFinished(QFuture<QList<EditTagDialog::Data>>)),
             future);
}
Ejemplo n.º 26
0
void GoogleDriveService::ListChangesFinished(
    google_drive::ListChangesResponse* changes_response) {
  changes_response->deleteLater();

  const QString cursor = changes_response->next_cursor();
  if (is_indexing()) {
    // Only save the cursor after all the songs have been indexed - that way if
    // Clementine is closed it'll resume next time.
    NewClosure(this, SIGNAL(AllIndexingTasksFinished()),
               this, SLOT(SaveCursor(QString)),
               cursor);
  } else {
    SaveCursor(cursor);
  }
}
Ejemplo n.º 27
0
void ArtistBiography::FetchWikipediaArticle(int id,
                                            const QString& wikipedia_url,
                                            CountdownLatch* latch) {
  latch->Wait();
  QRegExp regex("([a-z]+)\\.wikipedia\\.org/wiki/(.*)");
  if (regex.indexIn(wikipedia_url) == -1) {
    emit Finished(id);
    return;
  }
  QString wiki_title = QUrl::fromPercentEncoding(regex.cap(2).toUtf8());
  QString language = regex.cap(1);

  QUrl url(QString(kWikipediaExtractUrl).arg(language));
  url.addQueryItem("titles", wiki_title);
  QNetworkRequest request(url);
  QNetworkReply* reply = network_->get(request);

  qLog(Debug) << "Article url:" << url;

  NewClosure(reply, SIGNAL(finished()),
             [this, id, reply, wikipedia_url, latch]() {
    reply->deleteLater();

    QJson::Parser parser;
    QVariantMap json = parser.parse(reply).toMap();
    QString html = ExtractExtract(json);

    CollapsibleInfoPane::Data data;
    data.id_ = wikipedia_url;
    data.title_ = tr("Biography");
    data.type_ = CollapsibleInfoPane::Data::Type_Biography;
    data.icon_ = IconLoader::Load("wikipedia", IconLoader::Provider);

    QString text;
    text += "<p><a href=\"" + wikipedia_url + "\">" +
            tr("Open in your browser") + "</a></p>";

    text += html;
    SongInfoTextView* editor = new SongInfoTextView;
    editor->SetHtml(text);
    data.contents_ = editor;
    emit InfoReady(id, data);
    latch->CountDown();
  });
}
Ejemplo n.º 28
0
TEST(ClosureTest, ClosureDeletesSelf) {
  TestQObject sender;
  TestQObject receiver;
  _detail::ClosureBase* closure = NewClosure(
      &sender, SIGNAL(Emitted()),
      &receiver, SLOT(Invoke()));
  _detail::ObjectHelper* helper = closure->helper();
  QSignalSpy spy(helper, SIGNAL(destroyed()));
  EXPECT_EQ(0, receiver.invoked());
  sender.Emit();
  EXPECT_EQ(1, receiver.invoked());

  EXPECT_EQ(0, spy.count());
  QEventLoop loop;
  QObject::connect(helper, SIGNAL(destroyed()), &loop, SLOT(quit()));
  loop.exec();
  EXPECT_EQ(1, spy.count());
}
Ejemplo n.º 29
0
void PrettyImage::ImageFetched(RedirectFollower* follower) {
  follower->deleteLater();
  QNetworkReply* reply = follower->reply();
  reply->deleteLater();

  QImage image = QImage::fromData(reply->readAll());
  if (image.isNull()) {
    qLog(Debug) << "Image failed to load" << reply->request().url();
    deleteLater();
  } else {
    state_ = State_CreatingThumbnail;
    image_ = image;

    QFuture<QImage> future =
        QtConcurrent::run(image_, &QImage::scaled, image_size(),
                          Qt::KeepAspectRatio, Qt::SmoothTransformation);
    NewClosure(future, this, SLOT(ImageScaled(QFuture<QImage>)), future);
  }
}
Ejemplo n.º 30
0
int main(int argc, char** argv)
{
    FLAGS_alsologtostderr = true;
    google::ParseCommandLineFlags(&argc, &argv, true);
    google::InitGoogleLogging(argv[0]);


    LOG(INFO) << "begin main function.";
    ThreadPool th(4, 4);
    for (int idx = 0; idx < 5; ++idx) {
        th.AddTask(NewClosure(&Entery, idx));
    }

    th.Terminate();

    LOG(INFO) << "All is ok.";

    return 0;
}