More remote work. Clementine now requires QJson.

This commit is contained in:
John Maguire 2011-01-06 15:09:09 +00:00
parent d4d7f19fab
commit c9d5b8100b
7 changed files with 106 additions and 12 deletions

View File

@ -57,6 +57,7 @@ pkg_check_modules(PLIST libplist)
pkg_check_modules(USBMUXD libusbmuxd)
pkg_check_modules(LIBMTP libmtp>=1.0)
pkg_check_modules(INDICATEQT indicate-qt)
pkg_check_modules(QJSON QJson)
if (WIN32)
find_package(ZLIB REQUIRED)
@ -111,6 +112,7 @@ include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
include_directories(${LIBXML_INCLUDE_DIRS})
include_directories("3rdparty/universalchardet")
include_directories(${QJSON_INCLUDE_DIRS})
# Remove GLU and GL from the link line - they're not really required
# and don't exist on my mingw toolchain

View File

@ -814,6 +814,7 @@ target_link_libraries(clementine_lib
${QTSINGLECOREAPPLICATION_LIBRARIES}
${QTIOCOMPRESSOR_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${QJSON_LIBRARIES}
dl
z
)

View File

@ -319,10 +319,11 @@ int main(int argc, char *argv[]) {
Zeroconf* zeroconf = Zeroconf::GetZeroconf();
if (zeroconf) {
HttpServer* server = new HttpServer;
server->Listen(QHostAddress::Any, 12345);
HttpServer* server = new HttpServer(&player);
int port = 12345;
while (!server->Listen(QHostAddress::Any, port)) { ++port; }
zeroconf->Publish("local", "_clementine._tcp", "Clementine", 12345);
zeroconf->Publish("local", "_clementine._tcp", "Clementine", port);
}
// Window

View File

@ -1,13 +1,27 @@
#include "httpconnection.h"
#include <QBuffer>
#include <QStringList>
#include <QTcpSocket>
HttpConnection::HttpConnection(QTcpSocket* socket)
#include <qjson/serializer.h>
#include "core/player.h"
#include "playlist/playlistitem.h"
HttpConnection::HttpConnection(Player* player, QTcpSocket* socket)
: QObject(socket),
socket_(socket),
state_(WaitingForRequest) {
state_(WaitingForRequest),
player_(player),
cover_loader_(new AlbumCoverLoader(this)) {
connect(socket_, SIGNAL(readyRead()), SLOT(ReadyRead()));
connect(cover_loader_, SIGNAL(ImageLoaded(quint64, const QImage&)),
SLOT(ImageReady(quint64, const QImage&)));
connect(socket_, SIGNAL(disconnected()), socket_, SLOT(deleteLater()));
cover_loader_->SetDesiredHeight(400);
cover_loader_->SetScaleOutputImage(true);
}
void HttpConnection::ReadyRead() {
@ -40,6 +54,7 @@ void HttpConnection::ReadyRead() {
if (state_ == Error) {
socket_->close();
socket_->deleteLater();
return;
}
@ -64,9 +79,64 @@ bool HttpConnection::ParseRequest(const QString& line) {
}
void HttpConnection::DoRequest() {
PlaylistItemPtr current_item = player_->GetCurrentItem();
if (current_item) {
quint64 id = cover_loader_->LoadImageAsync(current_item->Metadata());
pending_tasks_[id] = current_item->Metadata();
return;
}
SendHeaders();
QVariantMap state = GetState();
QJson::Serializer serializer;
QString output = serializer.serialize(state);
socket_->write(output.toUtf8());
socket_->disconnectFromHost();
}
void HttpConnection::ImageReady(quint64 id, const QImage& image) {
Song song = pending_tasks_.take(id);
SendSongInfo(song, image);
}
void HttpConnection::SendHeaders() {
socket_->write("HTTP/1.0 200 OK\r\n");
socket_->write("Content-type: application/json\r\n");
socket_->write("\r\n");
socket_->write("{content:'Hello World!'}");
socket_->close();
}
QVariantMap HttpConnection::GetState() {
QVariantMap json;
json.insert("state", player_->GetState());
json.insert("volume", player_->GetVolume());
return json;
}
void HttpConnection::SendSongInfo(Song song, const QImage& cover) {
SendHeaders();
QVariantMap metadata;
metadata.insert("title", song.title());
metadata.insert("album", song.album());
metadata.insert("artist", song.artist());
if (!cover.isNull()) {
QByteArray cover_data;
{
QBuffer cover_buffer(&cover_data);
cover_buffer.open(QIODevice::WriteOnly);
cover.save(&cover_buffer, "PNG");
}
metadata.insert("cover", cover_data.toBase64());
}
QVariantMap state = GetState();
state.insert("song", metadata);
QJson::Serializer serializer;
QString output = serializer.serialize(state);
socket_->write(output.toUtf8());
socket_->disconnectFromHost();
}

View File

@ -3,20 +3,30 @@
#include <QNetworkAccessManager>
#include <QString>
#include <QVariantMap>
#include "core/song.h"
class QTcpSocket;
class AlbumCoverLoader;
class Player;
class HttpConnection : public QObject {
Q_OBJECT
public:
HttpConnection(QTcpSocket* sock);
HttpConnection(Player* player, QTcpSocket* sock);
private slots:
void ReadyRead();
void ImageReady(quint64 id, const QImage& image);
private:
void DoRequest();
bool ParseRequest(const QString& line);
void SendHeaders();
QVariantMap GetState();
void SendSongInfo(Song song, const QImage& cover);
QTcpSocket* socket_;
@ -30,6 +40,11 @@ class HttpConnection : public QObject {
QNetworkAccessManager::Operation method_;
QString path_;
Player* player_;
AlbumCoverLoader* cover_loader_;
QMap<quint64, Song> pending_tasks_;
};
#endif

View File

@ -5,8 +5,9 @@
#include "httpconnection.h"
HttpServer::HttpServer(QObject* parent)
: QObject(parent) {
HttpServer::HttpServer(Player* player, QObject* parent)
: QObject(parent),
player_(player) {
connect(&server_, SIGNAL(newConnection()), SLOT(NewConnection()));
}
@ -17,5 +18,5 @@ bool HttpServer::Listen(const QHostAddress& addr, quint16 port) {
void HttpServer::NewConnection() {
qDebug() << Q_FUNC_INFO;
QTcpSocket* socket = server_.nextPendingConnection();
new HttpConnection(socket);
new HttpConnection(player_, socket);
}

View File

@ -3,10 +3,12 @@
#include <QTcpServer>
class Player;
class HttpServer : public QObject {
Q_OBJECT
public:
HttpServer(QObject* parent = 0);
HttpServer(Player* player, QObject* parent = 0);
bool Listen(const QHostAddress& addr, quint16 port);
private slots:
@ -14,6 +16,8 @@ class HttpServer : public QObject {
private:
QTcpServer server_;
Player* player_;
};
#endif