strawberry-audio-player-win.../src/core/tagreaderclient.cpp

224 lines
6.3 KiB
C++
Raw Normal View History

2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
2021-03-20 21:14:47 +01:00
* Copyright 2019-2021, Jonas Kvinge <jonas@jkvinge.net>
2018-02-27 18:06:05 +01:00
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Strawberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
2018-08-09 18:39:44 +02:00
*
2018-02-27 18:06:05 +01:00
*/
#include "config.h"
#include <string>
2018-02-27 18:06:05 +01:00
#include <QtGlobal>
#include <QObject>
2018-02-27 18:06:05 +01:00
#include <QThread>
#include <QByteArray>
#include <QString>
#include <QImage>
#include <QtDebug>
#include "core/logging.h"
#include "core/workerpool.h"
#include "song.h"
#include "tagreaderclient.h"
2018-02-27 18:06:05 +01:00
const char *TagReaderClient::kWorkerExecutableName = "strawberry-tagreader";
TagReaderClient *TagReaderClient::sInstance = nullptr;
TagReaderClient::TagReaderClient(QObject *parent) : QObject(parent), worker_pool_(new WorkerPool<HandlerType>(this)) {
sInstance = this;
2019-07-24 23:29:09 +02:00
original_thread_ = thread();
2018-02-27 18:06:05 +01:00
worker_pool_->SetExecutableName(kWorkerExecutableName);
2019-11-27 22:57:51 +01:00
worker_pool_->SetWorkerCount(qBound(1, QThread::idealThreadCount() / 2, 4));
2021-01-26 16:48:04 +01:00
QObject::connect(worker_pool_, &WorkerPool<HandlerType>::WorkerFailedToStart, this, &TagReaderClient::WorkerFailedToStart);
2019-10-19 15:09:18 +02:00
2018-02-27 18:06:05 +01:00
}
void TagReaderClient::Start() { worker_pool_->Start(); }
2019-07-24 23:29:09 +02:00
void TagReaderClient::ExitAsync() {
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(this, "Exit", Qt::QueuedConnection);
2019-07-24 23:29:09 +02:00
}
void TagReaderClient::Exit() {
2021-09-27 19:09:18 +02:00
Q_ASSERT(QThread::currentThread() == thread());
2019-07-24 23:29:09 +02:00
moveToThread(original_thread_);
emit ExitFinished();
}
2018-02-27 18:06:05 +01:00
void TagReaderClient::WorkerFailedToStart() {
qLog(Error) << "The" << kWorkerExecutableName << "executable was not found in the current directory or on the PATH. Strawberry will not be able to read music file tags without it.";
}
2021-10-18 23:15:30 +02:00
TagReaderReply *TagReaderClient::IsMediaFile(const QString &filename) {
2018-10-02 00:38:52 +02:00
2021-02-20 17:06:55 +01:00
spb::tagreader::Message message;
2021-10-18 23:15:30 +02:00
spb::tagreader::IsMediaFileRequest *req = message.mutable_is_media_file_request();
2018-02-27 18:06:05 +01:00
req->set_filename(DataCommaSizeFromQString(filename));
return worker_pool_->SendMessageWithReply(&message);
}
2021-10-18 23:15:30 +02:00
TagReaderReply *TagReaderClient::ReadFile(const QString &filename) {
2018-02-27 18:06:05 +01:00
2021-02-20 17:06:55 +01:00
spb::tagreader::Message message;
2021-10-18 23:15:30 +02:00
spb::tagreader::ReadFileRequest *req = message.mutable_read_file_request();
2018-02-27 18:06:05 +01:00
req->set_filename(DataCommaSizeFromQString(filename));
2021-10-18 23:15:30 +02:00
return worker_pool_->SendMessageWithReply(&message);
2018-02-27 18:06:05 +01:00
}
2021-10-18 23:15:30 +02:00
TagReaderReply *TagReaderClient::SaveFile(const QString &filename, const Song &metadata) {
2018-10-02 00:38:52 +02:00
2021-02-20 17:06:55 +01:00
spb::tagreader::Message message;
2021-10-18 23:15:30 +02:00
spb::tagreader::SaveFileRequest *req = message.mutable_save_file_request();
2018-02-27 18:06:05 +01:00
req->set_filename(DataCommaSizeFromQString(filename));
2021-10-18 23:15:30 +02:00
metadata.ToProtobuf(req->mutable_metadata());
2018-02-27 18:06:05 +01:00
2021-10-18 23:15:30 +02:00
ReplyType *reply = worker_pool_->SendMessageWithReply(&message);
return reply;
2018-02-27 18:06:05 +01:00
}
TagReaderReply *TagReaderClient::LoadEmbeddedArt(const QString &filename) {
2018-10-02 00:38:52 +02:00
2021-02-20 17:06:55 +01:00
spb::tagreader::Message message;
spb::tagreader::LoadEmbeddedArtRequest *req = message.mutable_load_embedded_art_request();
2018-02-27 18:06:05 +01:00
req->set_filename(DataCommaSizeFromQString(filename));
return worker_pool_->SendMessageWithReply(&message);
}
TagReaderReply *TagReaderClient::SaveEmbeddedArt(const QString &filename, const QByteArray &data) {
2021-02-20 17:06:55 +01:00
spb::tagreader::Message message;
spb::tagreader::SaveEmbeddedArtRequest *req = message.mutable_save_embedded_art_request();
req->set_filename(DataCommaSizeFromQString(filename));
req->set_data(data.constData(), data.size());
return worker_pool_->SendMessageWithReply(&message);
}
2021-10-18 23:15:30 +02:00
bool TagReaderClient::IsMediaFileBlocking(const QString &filename) {
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
Q_ASSERT(QThread::currentThread() != thread());
2021-10-18 23:15:30 +02:00
bool ret = false;
TagReaderReply *reply = IsMediaFile(filename);
2018-02-27 18:06:05 +01:00
if (reply->WaitForFinished()) {
2021-10-18 23:15:30 +02:00
ret = reply->message().is_media_file_response().success();
2018-02-27 18:06:05 +01:00
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
2018-02-27 18:06:05 +01:00
2021-10-18 23:15:30 +02:00
return ret;
2018-02-27 18:06:05 +01:00
}
2021-10-18 23:15:30 +02:00
void TagReaderClient::ReadFileBlocking(const QString &filename, Song *song) {
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
Q_ASSERT(QThread::currentThread() != thread());
2021-10-18 23:15:30 +02:00
TagReaderReply *reply = ReadFile(filename);
2018-02-27 18:06:05 +01:00
if (reply->WaitForFinished()) {
2021-10-18 23:15:30 +02:00
song->InitFromProtobuf(reply->message().read_file_response().metadata());
2018-02-27 18:06:05 +01:00
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
2018-02-27 18:06:05 +01:00
}
2021-10-18 23:15:30 +02:00
bool TagReaderClient::SaveFileBlocking(const QString &filename, const Song &metadata) {
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
Q_ASSERT(QThread::currentThread() != thread());
bool ret = false;
2021-10-18 23:15:30 +02:00
TagReaderReply *reply = SaveFile(filename, metadata);
2018-02-27 18:06:05 +01:00
if (reply->WaitForFinished()) {
2021-10-18 23:15:30 +02:00
ret = reply->message().save_file_response().success();
2018-02-27 18:06:05 +01:00
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
2018-02-27 18:06:05 +01:00
return ret;
}
QByteArray TagReaderClient::LoadEmbeddedArtBlocking(const QString &filename) {
Q_ASSERT(QThread::currentThread() != thread());
QByteArray ret;
TagReaderReply *reply = LoadEmbeddedArt(filename);
if (reply->WaitForFinished()) {
const std::string &data_str = reply->message().load_embedded_art_response().data();
ret = QByteArray(data_str.data(), data_str.size());
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
return ret;
}
QImage TagReaderClient::LoadEmbeddedArtAsImageBlocking(const QString &filename) {
2018-10-02 00:38:52 +02:00
2018-02-27 18:06:05 +01:00
Q_ASSERT(QThread::currentThread() != thread());
QImage ret;
TagReaderReply *reply = LoadEmbeddedArt(filename);
if (reply->WaitForFinished()) {
const std::string &data_str = reply->message().load_embedded_art_response().data();
ret.loadFromData(QByteArray(data_str.data(), data_str.size()));
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
return ret;
}
bool TagReaderClient::SaveEmbeddedArtBlocking(const QString &filename, const QByteArray &data) {
Q_ASSERT(QThread::currentThread() != thread());
bool ret = false;
TagReaderReply *reply = SaveEmbeddedArt(filename, data);
if (reply->WaitForFinished()) {
ret = reply->message().save_embedded_art_response().success();
}
2021-09-09 21:53:14 +02:00
QMetaObject::invokeMethod(reply, "deleteLater", Qt::QueuedConnection);
2018-02-27 18:06:05 +01:00
return ret;
}