Fix more protocol bugs and try to organize UI into sensible pieces
This commit is contained in:
parent
e713439b70
commit
359b3b805b
11 changed files with 218 additions and 66 deletions
|
@ -33,7 +33,10 @@ OTHER_FILES += qml/harbour-weechatrelay.qml \
|
||||||
qml/js/utils.js \
|
qml/js/utils.js \
|
||||||
qml/js/moment.js \
|
qml/js/moment.js \
|
||||||
qml/js/connection.js \
|
qml/js/connection.js \
|
||||||
qml/js/debug.js
|
qml/js/debug.js \
|
||||||
|
qml/js/buffers.js \
|
||||||
|
qml/js/eventqueue.js \
|
||||||
|
qml/js/uniqid.js
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/relayconnection.h \
|
src/relayconnection.h \
|
||||||
|
|
55
qml/js/buffers.js
Normal file
55
qml/js/buffers.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* © Mikko Ahlroth 2014
|
||||||
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
|
* the LICENCE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
.import "eventqueue.js" as EQ
|
||||||
|
.import "debug.js" as D
|
||||||
|
|
||||||
|
function Buffer(id) {
|
||||||
|
this.id = id;
|
||||||
|
this.window = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _buffers = {};
|
||||||
|
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
EQ.addHandler("__weecrapp_ready", connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function connected() {
|
||||||
|
EQ.command("hdata buffer:gui_buffers(*) name,number", bufferListData);
|
||||||
|
EQ.command("sync");
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnected() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function bufferListData(data) {
|
||||||
|
D.d("Got buffer list data:");
|
||||||
|
|
||||||
|
data = data[0];
|
||||||
|
var buffers = data.objectSets;
|
||||||
|
|
||||||
|
for (var i = 0; i < buffers.length; ++i) {
|
||||||
|
D.d(buffers[i].number + " " + buffers[i].name);
|
||||||
|
|
||||||
|
//EQ.command("sync " + buffers[i].name + " buffer,nicklist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bufferSyncData(data) {
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,8 @@
|
||||||
.import harbour.weechatrelay.qsslcertificateinfo 1.0 as QSCI
|
.import harbour.weechatrelay.qsslcertificateinfo 1.0 as QSCI
|
||||||
.import "storage.js" as S
|
.import "storage.js" as S
|
||||||
.import "debug.js" as D
|
.import "debug.js" as D
|
||||||
|
.import "eventqueue.js" as EQ
|
||||||
|
.import "buffers.js" as B
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* © Mikko Ahlroth 2014
|
* © Mikko Ahlroth 2014
|
||||||
|
@ -30,30 +32,45 @@ var sslVerifyDialog = null;
|
||||||
function init(connectionHandler, pageStack) {
|
function init(connectionHandler, pageStack) {
|
||||||
handler = connectionHandler;
|
handler = connectionHandler;
|
||||||
ps = pageStack;
|
ps = pageStack;
|
||||||
|
|
||||||
|
// Register to receive all send events to actually send them to the backend
|
||||||
|
// This is done so we can avoid cyclic imports
|
||||||
|
EQ.addHandler("__weecrapp_send", function(str) {
|
||||||
|
send(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for init reply to let system know it's ready to send
|
||||||
|
EQ.addHandler("init", function() {
|
||||||
|
EQ.handleEvent("__weecrapp_ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
B.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Signal handlers for incoming data from connection
|
// Signal handlers for incoming data from connection
|
||||||
function newEvent(id, data) {
|
function newEvent(id, data) {
|
||||||
debugViewPage.display("Event received: " + id);
|
D.d("Event received: " + id);
|
||||||
debugViewPage.display(JSON.stringify(data));
|
D.d(JSON.stringify(data));
|
||||||
_handleEvent(id, data);
|
EQ.handleEvent(id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDisplayDebugData(str) {
|
function onDisplayDebugData(str) {
|
||||||
debugViewPage.display(str);
|
D.d(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onConnected() {
|
function onConnected() {
|
||||||
connected = true;
|
connected = true;
|
||||||
debugViewPage.connected();
|
debugViewPage.connected();
|
||||||
debug("Connected");
|
D.d("Connected");
|
||||||
|
EQ.handleEvent("__weecrapp_connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDisconnected() {
|
function onDisconnected() {
|
||||||
connected = false;
|
connected = false;
|
||||||
debugViewPage.disconnected();
|
debugViewPage.disconnected();
|
||||||
debug("Disconnected");
|
D.d("Disconnected");
|
||||||
|
EQ.handleEvent("__weecrapp_disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSslError(errorStrings,
|
function onSslError(errorStrings,
|
||||||
|
@ -61,7 +78,7 @@ function onSslError(errorStrings,
|
||||||
startDate,
|
startDate,
|
||||||
expiryDate,
|
expiryDate,
|
||||||
digest) {
|
digest) {
|
||||||
debug("SSL verification error when connecting");
|
D.d("SSL verification error when connecting");
|
||||||
|
|
||||||
sslVerifyDialog = ps.push("../pages/SslVerifyDialog.qml",
|
sslVerifyDialog = ps.push("../pages/SslVerifyDialog.qml",
|
||||||
{
|
{
|
||||||
|
@ -78,7 +95,8 @@ function onSslError(errorStrings,
|
||||||
|
|
||||||
function connect(connObj) {
|
function connect(connObj) {
|
||||||
debugViewPage = ps.replace("../pages/DebugView.qml");
|
debugViewPage = ps.replace("../pages/DebugView.qml");
|
||||||
debug("Connecting...");
|
D.setDebugPage(debugViewPage);
|
||||||
|
D.d("Connecting...");
|
||||||
|
|
||||||
var connType = (connObj.type === "ssl")
|
var connType = (connObj.type === "ssl")
|
||||||
? CH.ConnectionHandler.SSL
|
? CH.ConnectionHandler.SSL
|
||||||
|
@ -111,13 +129,13 @@ function disconnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function reconnect() {
|
function reconnect() {
|
||||||
debug("Reconnecting...");
|
D.d("Reconnecting...");
|
||||||
handler.reconnect();
|
handler.reconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconnect, accepting the previously failed certificate
|
// Reconnect, accepting the previously failed certificate
|
||||||
function reconnectWithFailed() {
|
function reconnectWithFailed() {
|
||||||
debug("Reconnecting...");
|
D.d("Reconnecting...");
|
||||||
handler.reconnectWithFailed();
|
handler.reconnectWithFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,31 +160,12 @@ function clearConnection() {
|
||||||
handler.clearData();
|
handler.clearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a line to the debug view (will go to console if debug view isn't open)
|
// Send a command to the WeeChat server
|
||||||
function debug(str) {
|
function send(str) {
|
||||||
if (debugViewPage !== null) {
|
D.d("Sending command: " + str);
|
||||||
debugViewPage.display(str);
|
handler.send(str);
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Private API
|
// Private API
|
||||||
|
|
||||||
var _pendingEvents = {};
|
|
||||||
|
|
||||||
function _handleEvent(id, data) {
|
|
||||||
if (id in _pendingEvents) {
|
|
||||||
_pendingEvents.id(data);
|
|
||||||
delete _pendingEvents.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _addPendingEvent(id, callback) {
|
|
||||||
_pendingEvents.id = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
.pragma library
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* © Mikko Ahlroth 2014
|
* © Mikko Ahlroth 2014
|
||||||
* WeeCRApp is open source software. For licensing information, please check
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
* the LICENCE file.
|
* the LICENCE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function d(o) {
|
.pragma library
|
||||||
console.log(o);
|
|
||||||
|
|
||||||
|
var _page = null;
|
||||||
|
|
||||||
|
// Write a line to the debug view (will go to console if debug view isn't open)
|
||||||
|
function debug(str) {
|
||||||
|
if (_page != null) {
|
||||||
|
_page.display(str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDebugPage(o) {
|
||||||
|
_page = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function d(str) {
|
||||||
|
debug(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function e(o) {
|
function e(o) {
|
||||||
|
|
55
qml/js/eventqueue.js
Normal file
55
qml/js/eventqueue.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* © Mikko Ahlroth 2014
|
||||||
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
|
* the LICENCE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The event queue allows attaching callbacks to event IDs coming from the
|
||||||
|
* backend. Callbacks can be one-shot or continuous.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
.import "uniqid.js" as UID
|
||||||
|
.import "debug.js" as D
|
||||||
|
|
||||||
|
var _pendingEvents = {};
|
||||||
|
|
||||||
|
function handleEvent(id, data) {
|
||||||
|
//D.d("Handling " + id);
|
||||||
|
//D.d(JSON.stringify(_pendingEvents));
|
||||||
|
if (id in _pendingEvents) {
|
||||||
|
var c = _pendingEvents[id];
|
||||||
|
c.callback(data);
|
||||||
|
|
||||||
|
if (c.isOneshot) {
|
||||||
|
delete _pendingEvents[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addHandler(id, callback, isOneshot) {
|
||||||
|
_pendingEvents[id] = {
|
||||||
|
"callback": callback,
|
||||||
|
"isOneshot": !!isOneshot
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a command and execute callback when the response arrives
|
||||||
|
function command(command, callback) {
|
||||||
|
// If callback is null, don't add an ID
|
||||||
|
var read_write = !!callback;
|
||||||
|
|
||||||
|
if (read_write) {
|
||||||
|
var id = UID.get();
|
||||||
|
command = "(" + id + ") " + command;
|
||||||
|
|
||||||
|
D.d("Adding handler for " + id);
|
||||||
|
addHandler(id, callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEvent("__weecrapp_send", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
19
qml/js/uniqid.js
Normal file
19
qml/js/uniqid.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* © Mikko Ahlroth 2014
|
||||||
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
|
* the LICENCE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unique IDs will be used to match responses with the right
|
||||||
|
* callbacks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
var _counter = 0;
|
||||||
|
var _prefix = "msg_";
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
return _prefix + _counter++;
|
||||||
|
}
|
|
@ -176,6 +176,7 @@ void ConnectionHandler::sendDebugData(QString string)
|
||||||
|
|
||||||
void ConnectionHandler::send(QString string)
|
void ConnectionHandler::send(QString string)
|
||||||
{
|
{
|
||||||
|
string = string.append("\n");
|
||||||
connection->write(string.toUtf8());
|
connection->write(string.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* © Mikko Ahlroth 2014
|
||||||
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
|
* the LICENCE file.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "dynamictypeexception.h"
|
#include "dynamictypeexception.h"
|
||||||
|
|
||||||
DynamicTypeException::DynamicTypeException(const std::string &__arg):
|
DynamicTypeException::DynamicTypeException(const std::string &__arg):
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* © Mikko Ahlroth 2014
|
||||||
|
* WeeCRApp is open source software. For licensing information, please check
|
||||||
|
* the LICENCE file.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef DYNAMICTYPEEXCEPTION_H
|
#ifndef DYNAMICTYPEEXCEPTION_H
|
||||||
#define DYNAMICTYPEEXCEPTION_H
|
#define DYNAMICTYPEEXCEPTION_H
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ WeeChatProtocolHandler::WeeChatProtocolHandler(QObject* parent) :
|
||||||
void WeeChatProtocolHandler::initialize(QString password)
|
void WeeChatProtocolHandler::initialize(QString password)
|
||||||
{
|
{
|
||||||
emitData("init compression=off,password=" + password);
|
emitData("init compression=off,password=" + password);
|
||||||
|
emitData("(init) info version");
|
||||||
emitData("(starttest) test");
|
emitData("(starttest) test");
|
||||||
emitData("sync");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,13 +64,20 @@ QVariant WeeChatProtocolHandler::handleDynamicType(Type type, QDataStream* data)
|
||||||
{
|
{
|
||||||
return QVariant(handleHashTable(data));
|
return QVariant(handleHashTable(data));
|
||||||
}
|
}
|
||||||
|
else if (type == HDATA) {
|
||||||
|
return QVariant(handleHdata(data));
|
||||||
|
}
|
||||||
else if (type == ARRAY)
|
else if (type == ARRAY)
|
||||||
{
|
{
|
||||||
return QVariant(handleArray(data));
|
return QVariant(handleArray(data));
|
||||||
}
|
}
|
||||||
else
|
else if (type == INFO)
|
||||||
{
|
{
|
||||||
throw new DynamicTypeException("Cannot read hdata as QVariant.");
|
return QVariant(handleInfo(data));
|
||||||
|
}
|
||||||
|
else if (type == INFOLIST)
|
||||||
|
{
|
||||||
|
return QVariant(handleInfoList(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,9 +301,15 @@ QVariantMap WeeChatProtocolHandler::handleHdata(QDataStream* data)
|
||||||
QVariantMap WeeChatProtocolHandler::handleInfo(QDataStream* data)
|
QVariantMap WeeChatProtocolHandler::handleInfo(QDataStream* data)
|
||||||
{
|
{
|
||||||
// Info consists of a string key and a string value
|
// Info consists of a string key and a string value
|
||||||
|
qDebug() << "Reading info";
|
||||||
QVariantMap ret;
|
QVariantMap ret;
|
||||||
ret.insert("key", handleString(data));
|
QString key = handleString(data);
|
||||||
ret.insert("value", handleString(data));
|
qDebug() << "Key: " << key;
|
||||||
|
QString value = handleString(data);
|
||||||
|
qDebug() << "Value: " << value;
|
||||||
|
|
||||||
|
ret.insert("key", key);
|
||||||
|
ret.insert("value", value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,15 +482,6 @@ void WeeChatProtocolHandler::handleBody(QDataStream* data)
|
||||||
|
|
||||||
// EVENTS
|
// EVENTS
|
||||||
|
|
||||||
// Handle event containing a hdata
|
|
||||||
void WeeChatProtocolHandler::handleHdataEvent(QString id, QDataStream* data)
|
|
||||||
{
|
|
||||||
qDebug() << "Making hdata!";
|
|
||||||
QVariantMap hdata = handleHdata(data);
|
|
||||||
qDebug() << "Got hdata made!";
|
|
||||||
emit newEvent(id, hdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::handlePong(QString id, QDataStream* data)
|
void WeeChatProtocolHandler::handlePong(QString id, QDataStream* data)
|
||||||
{
|
{
|
||||||
QString response = handleString(data);
|
QString response = handleString(data);
|
||||||
|
@ -502,23 +506,10 @@ void WeeChatProtocolHandler::handleOtherEvent(QString id, QDataStream* data)
|
||||||
// read all incoming types into a list
|
// read all incoming types into a list
|
||||||
QVariantList ret;
|
QVariantList ret;
|
||||||
|
|
||||||
// If the first element is a hdata, it is the only element
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
while (!data->atEnd())
|
while (!data->atEnd())
|
||||||
{
|
{
|
||||||
Type type = readType(data);
|
Type type = readType(data);
|
||||||
|
|
||||||
if (first && type == HDATA)
|
|
||||||
{
|
|
||||||
handleHdataEvent(id, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant obj = handleDynamicType(type, data);
|
QVariant obj = handleDynamicType(type, data);
|
||||||
ret.append(obj);
|
ret.append(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ protected:
|
||||||
void handlePong(QString id, QDataStream* data);
|
void handlePong(QString id, QDataStream* data);
|
||||||
void handleUpgrade(QString id);
|
void handleUpgrade(QString id);
|
||||||
void handleUpgradeEnded(QString id);
|
void handleUpgradeEnded(QString id);
|
||||||
void handleHdataEvent(QString id, QDataStream* data);
|
|
||||||
void handleOtherEvent(QString id, QDataStream* data);
|
void handleOtherEvent(QString id, QDataStream* data);
|
||||||
|
|
||||||
bool readingBody;
|
bool readingBody;
|
||||||
|
|
Loading…
Reference in a new issue