Make web remote base url configurable by a flag.
This commit is contained in:
parent
6537ba4a06
commit
f88cf84bc2
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "closure.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/timeconstants.h"
|
||||
|
@ -32,8 +33,28 @@ CallbackClosure::CallbackClosure(QObject* sender, const char* signal,
|
|||
: ClosureBase(new ObjectHelper(sender, signal, this)),
|
||||
callback_(callback) {}
|
||||
|
||||
CallbackClosure::CallbackClosure(std::function<void()> callback)
|
||||
: ClosureBase(new ObjectHelper(this)),
|
||||
callback_(callback) {}
|
||||
|
||||
void CallbackClosure::Invoke() { callback_(); }
|
||||
|
||||
|
||||
MainThreadCallbackClosure::MainThreadCallbackClosure(
|
||||
std::function<void()> callback)
|
||||
: CallbackClosure(callback) {
|
||||
helper_->moveToThread(QApplication::instance()->thread());
|
||||
}
|
||||
|
||||
void MainThreadCallbackClosure::Invoke() {
|
||||
Q_ASSERT(QThread::thread() == QApplication::instance()->thread());
|
||||
CallbackClosure::Invoke();
|
||||
}
|
||||
|
||||
void MainThreadCallbackClosure::DoNow() {
|
||||
helper_->metaObject()->invokeMethod(helper_, "Invoked", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
ObjectHelper* ClosureBase::helper() const { return helper_; }
|
||||
|
||||
ObjectHelper::ObjectHelper(QObject* sender, const char* signal,
|
||||
|
@ -43,6 +64,9 @@ ObjectHelper::ObjectHelper(QObject* sender, const char* signal,
|
|||
connect(sender, SIGNAL(destroyed()), SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
ObjectHelper::ObjectHelper(ClosureBase* closure)
|
||||
: closure_(closure) {}
|
||||
|
||||
void ObjectHelper::Invoked() {
|
||||
closure_->Invoke();
|
||||
deleteLater();
|
||||
|
@ -65,3 +89,7 @@ void DoInAMinuteOrSo(QObject* receiver, const char* slot) {
|
|||
int msec = (60 + (qrand() % 60)) * kMsecPerSec;
|
||||
DoAfter(receiver, slot, msec);
|
||||
}
|
||||
|
||||
void RunOnMainThread(std::function<void()> callback) {
|
||||
(new _detail::MainThreadCallbackClosure(callback))->DoNow();
|
||||
}
|
||||
|
|
|
@ -53,8 +53,9 @@ class ObjectHelper : public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
ObjectHelper(QObject* parent, const char* signal, ClosureBase* closure);
|
||||
explicit ObjectHelper(ClosureBase* closure);
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void Invoked();
|
||||
|
||||
private:
|
||||
|
@ -138,6 +139,7 @@ class CallbackClosure : public ClosureBase {
|
|||
public:
|
||||
CallbackClosure(QObject* sender, const char* signal,
|
||||
std::function<void()> callback);
|
||||
explicit CallbackClosure(std::function<void()> callback);
|
||||
|
||||
virtual void Invoke();
|
||||
|
||||
|
@ -145,6 +147,14 @@ class CallbackClosure : public ClosureBase {
|
|||
std::function<void()> callback_;
|
||||
};
|
||||
|
||||
class MainThreadCallbackClosure : public CallbackClosure {
|
||||
public:
|
||||
explicit MainThreadCallbackClosure(std::function<void()> callback);
|
||||
virtual void Invoke();
|
||||
|
||||
void DoNow();
|
||||
};
|
||||
|
||||
} // namespace _detail
|
||||
|
||||
template <typename... Args>
|
||||
|
@ -189,5 +199,6 @@ _detail::ClosureBase* NewClosure(QObject* sender, const char* signal,
|
|||
|
||||
void DoAfter(QObject* receiver, const char* slot, int msec);
|
||||
void DoInAMinuteOrSo(QObject* receiver, const char* slot);
|
||||
void RunOnMainThread(std::function<void()> callback);
|
||||
|
||||
#endif // CLOSURE_H
|
||||
|
|
|
@ -77,6 +77,29 @@ Application::Application(QObject* parent)
|
|||
network_remote_(nullptr),
|
||||
network_remote_helper_(nullptr),
|
||||
scrobbler_(nullptr) {
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
// It's important that the device manager is deleted before the database.
|
||||
// Deleting the database deletes all objects that have been created in its
|
||||
// thread, including some device library backends.
|
||||
delete device_manager_;
|
||||
device_manager_ = nullptr;
|
||||
|
||||
for (QObject* object : objects_in_threads_) {
|
||||
object->deleteLater();
|
||||
}
|
||||
|
||||
for (QThread* thread : threads_) {
|
||||
thread->quit();
|
||||
}
|
||||
|
||||
for (QThread* thread : threads_) {
|
||||
thread->wait();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::Init() {
|
||||
tag_reader_client_ = new TagReaderClient(this);
|
||||
MoveToNewThread(tag_reader_client_);
|
||||
tag_reader_client_->Start();
|
||||
|
@ -133,26 +156,6 @@ Application::Application(QObject* parent)
|
|||
DoInAMinuteOrSo(database_, SLOT(DoBackup()));
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
// It's important that the device manager is deleted before the database.
|
||||
// Deleting the database deletes all objects that have been created in its
|
||||
// thread, including some device library backends.
|
||||
delete device_manager_;
|
||||
device_manager_ = nullptr;
|
||||
|
||||
for (QObject* object : objects_in_threads_) {
|
||||
object->deleteLater();
|
||||
}
|
||||
|
||||
for (QThread* thread : threads_) {
|
||||
thread->quit();
|
||||
}
|
||||
|
||||
for (QThread* thread : threads_) {
|
||||
thread->wait();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::MoveToNewThread(QObject* object) {
|
||||
QThread* thread = new QThread(this);
|
||||
|
||||
|
|
|
@ -54,14 +54,18 @@ class Application : public QObject {
|
|||
public:
|
||||
static bool kIsPortable;
|
||||
|
||||
Application(QObject* parent = nullptr);
|
||||
explicit Application(QObject* parent = nullptr);
|
||||
~Application();
|
||||
|
||||
void Init();
|
||||
|
||||
const QString& language_name() const { return language_name_; }
|
||||
// Same as language_name, but remove the region code at the end if there is
|
||||
// one
|
||||
QString language_without_region() const;
|
||||
void set_language_name(const QString& name) { language_name_ = name; }
|
||||
QString remote_base_url() const { return remote_base_url_; }
|
||||
void set_remote_base_url(const QString& url) { remote_base_url_ = url; }
|
||||
|
||||
TagReaderClient* tag_reader_client() const { return tag_reader_client_; }
|
||||
Database* database() const { return database_; }
|
||||
|
@ -107,6 +111,7 @@ signals:
|
|||
|
||||
private:
|
||||
QString language_name_;
|
||||
QString remote_base_url_;
|
||||
|
||||
TagReaderClient* tag_reader_client_;
|
||||
Database* database_;
|
||||
|
|
|
@ -63,6 +63,13 @@ const char* CommandlineOptions::kHelpText =
|
|||
|
||||
const char* CommandlineOptions::kVersionText = "Clementine %1";
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kDefaultRemoteBaseUrl =
|
||||
"https://dev-dot-clementine-data.appspot.com";
|
||||
|
||||
} // namespace
|
||||
|
||||
CommandlineOptions::CommandlineOptions(int argc, char** argv)
|
||||
: argc_(argc),
|
||||
argv_(argv),
|
||||
|
@ -75,7 +82,8 @@ CommandlineOptions::CommandlineOptions(int argc, char** argv)
|
|||
play_track_at_(-1),
|
||||
show_osd_(false),
|
||||
toggle_pretty_osd_(false),
|
||||
log_levels_(logging::kDefaultLogLevels) {
|
||||
log_levels_(logging::kDefaultLogLevels),
|
||||
remote_base_url_(kDefaultRemoteBaseUrl) {
|
||||
#ifdef Q_OS_DARWIN
|
||||
// Remove -psn_xxx option that Mac passes when opened from Finder.
|
||||
RemoveArg("-psn", 1);
|
||||
|
@ -125,6 +133,7 @@ bool CommandlineOptions::Parse() {
|
|||
{"verbose", no_argument, 0, Verbose},
|
||||
{"log-levels", required_argument, 0, LogLevels},
|
||||
{"version", no_argument, 0, Version},
|
||||
{"remote-base-url", required_argument, 0, RemoteBaseUrl},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
// Parse the arguments
|
||||
|
@ -261,6 +270,10 @@ bool CommandlineOptions::Parse() {
|
|||
if (!ok) play_track_at_ = -1;
|
||||
break;
|
||||
|
||||
case RemoteBaseUrl:
|
||||
remote_base_url_ = optarg;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -66,6 +66,7 @@ class CommandlineOptions {
|
|||
QList<QUrl> urls() const { return urls_; }
|
||||
QString language() const { return language_; }
|
||||
QString log_levels() const { return log_levels_; }
|
||||
QString remote_base_url() const { return remote_base_url_; }
|
||||
|
||||
QByteArray Serialize() const;
|
||||
void Load(const QByteArray& serialized);
|
||||
|
@ -84,7 +85,8 @@ class CommandlineOptions {
|
|||
Version,
|
||||
VolumeIncreaseBy,
|
||||
VolumeDecreaseBy,
|
||||
RestartOrPrevious
|
||||
RestartOrPrevious,
|
||||
RemoteBaseUrl,
|
||||
};
|
||||
|
||||
QString tr(const char* source_text);
|
||||
|
@ -107,6 +109,7 @@ class CommandlineOptions {
|
|||
bool toggle_pretty_osd_;
|
||||
QString language_;
|
||||
QString log_levels_;
|
||||
QString remote_base_url_;
|
||||
|
||||
QList<QUrl> urls_;
|
||||
};
|
||||
|
|
|
@ -448,6 +448,8 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
Application app;
|
||||
app.set_language_name(language);
|
||||
app.set_remote_base_url(options.remote_base_url());
|
||||
app.Init();
|
||||
|
||||
Echonest::Config::instance()->setAPIKey("DFLFLJBUF4EGTXHIG");
|
||||
Echonest::Config::instance()->setNetworkAccessManager(
|
||||
|
|
|
@ -11,30 +11,28 @@
|
|||
|
||||
namespace {
|
||||
|
||||
//const char* kRemoteEndpoint = "http://localhost:8080/channel/remote/%1";
|
||||
const char* kRemoteEndpoint = "https://remote-dot-clementine-data.appspot.com/channel/remote/%1";
|
||||
|
||||
const char* kInitialPage = "https://remote-dot-clementine-data.appspot.com/channel/clementine";
|
||||
const char* kInitialPagePath = "/channel/clementine";
|
||||
const char* kRemoteEndpointPath = "/channel/remote/%1";
|
||||
|
||||
} // namespace
|
||||
|
||||
ClementineWebPage::ClementineWebPage(QObject* parent)
|
||||
: QWebPage(parent) {
|
||||
qLog(Debug) << Q_FUNC_INFO;
|
||||
NewClosure(this, SIGNAL(loadFinished(bool)), [&]() {
|
||||
NewClosure(this, SIGNAL(loadFinished(bool)), [=]() {
|
||||
qLog(Debug) << Q_FUNC_INFO << "load finished" << totalBytes();
|
||||
qLog(Debug) << mainFrame()->toHtml();
|
||||
mainFrame()->evaluateJavaScript("window.setTimeout");
|
||||
});
|
||||
}
|
||||
|
||||
void ClementineWebPage::Init() {
|
||||
QMetaObject::invokeMethod(this, "InitOnMainThread", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void ClementineWebPage::InitOnMainThread() {
|
||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||
mainFrame()->load(QUrl(kInitialPage));
|
||||
void ClementineWebPage::Init(const QString& base_url) {
|
||||
RunOnMainThread([=]{
|
||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||
base_url_ = base_url;
|
||||
QUrl url(base_url_);
|
||||
url.setPath(kInitialPagePath);
|
||||
mainFrame()->load(url);
|
||||
});
|
||||
}
|
||||
|
||||
void ClementineWebPage::javaScriptConsoleMessage(
|
||||
|
@ -45,7 +43,9 @@ void ClementineWebPage::javaScriptConsoleMessage(
|
|||
bool ClementineWebPage::javaScriptConfirm(QWebFrame*, const QString& message) {
|
||||
id_ = message;
|
||||
qLog(Debug) << "id:" << message;
|
||||
qLog(Debug) << QString(kRemoteEndpoint).arg(message);
|
||||
QUrl url(base_url_);
|
||||
url.setPath(QString(kRemoteEndpointPath).arg(message));
|
||||
qLog(Debug) << url;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ class ClementineWebPage : public QWebPage {
|
|||
|
||||
public:
|
||||
explicit ClementineWebPage(QObject* parent = nullptr);
|
||||
void Init();
|
||||
void Init(const QString& base_url);
|
||||
const QString id() const { return id_; }
|
||||
|
||||
public slots:
|
||||
|
@ -17,9 +17,6 @@ class ClementineWebPage : public QWebPage {
|
|||
void Connected();
|
||||
void MessageReceived(const pb::remote::Message& msg);
|
||||
|
||||
private slots:
|
||||
void InitOnMainThread();
|
||||
|
||||
protected:
|
||||
// For OOB communication for controlling the appengine channel.
|
||||
virtual bool javaScriptConfirm(QWebFrame*, const QString& message);
|
||||
|
@ -31,4 +28,5 @@ class ClementineWebPage : public QWebPage {
|
|||
|
||||
private:
|
||||
QString id_;
|
||||
QString base_url_;
|
||||
};
|
||||
|
|
|
@ -75,7 +75,7 @@ void NetworkRemote::SetupServer() {
|
|||
connect(server_ipv6_.get(), SIGNAL(newConnection()), this,
|
||||
SLOT(AcceptConnection()));
|
||||
connect(web_channel_.get(), SIGNAL(Connected()), SLOT(AcceptWebConnection()));
|
||||
web_channel_->Init();
|
||||
web_channel_->Init(app_->remote_base_url());
|
||||
}
|
||||
|
||||
void NetworkRemote::StartServer() {
|
||||
|
|
|
@ -24,7 +24,7 @@ class RemoteClient : public QObject {
|
|||
signals:
|
||||
void Parse(const pb::remote::Message& msg);
|
||||
|
||||
private:
|
||||
protected:
|
||||
Application* app_;
|
||||
bool downloader_;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QByteArray>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/closure.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/network.h"
|
||||
|
@ -9,8 +10,7 @@
|
|||
|
||||
namespace {
|
||||
|
||||
//const char* kEndpoint = "http://localhost:8080/channel/clementine/push/%1";
|
||||
const char* kEndpoint = "https://remote-dot-clementine-data.appspot.com/channel/clementine/push/%1";
|
||||
const char* kEndpointPath = "/channel/clementine/push/%1";
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -29,8 +29,11 @@ void WebRemoteClient::SendData(pb::remote::Message* msg) {
|
|||
qLog(Debug) << "Sending:" << msg->DebugString().c_str();
|
||||
std::string data = msg->SerializeAsString();
|
||||
QByteArray base64 = QByteArray(data.data(), data.size()).toBase64();
|
||||
QNetworkRequest request = QNetworkRequest(
|
||||
QUrl(QString(kEndpoint).arg(web_channel_->id())));
|
||||
|
||||
QUrl url(app_->remote_base_url());
|
||||
url.setPath(QString(kEndpointPath).arg(web_channel_->id()));
|
||||
|
||||
QNetworkRequest request = QNetworkRequest(url);
|
||||
QNetworkReply* reply = network_->post(request, base64);
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
this, SLOT(SendDataFinished(QNetworkReply*)), reply);
|
||||
|
|
Loading…
Reference in New Issue