basic sync wrapper
This commit is contained in:
parent
8d6f8fda05
commit
6e604860e6
8 changed files with 209 additions and 24 deletions
|
@ -5,17 +5,34 @@
|
|||
#include <3ds.h>
|
||||
#include <jansson.h>
|
||||
|
||||
class MatrixClient {
|
||||
namespace Matrix {
|
||||
|
||||
class Store {
|
||||
public:
|
||||
virtual void setSyncToken(std::string token) = 0;
|
||||
virtual std::string getSyncToken() = 0;
|
||||
};
|
||||
|
||||
class Client {
|
||||
private:
|
||||
public:
|
||||
std::string hsUrl;
|
||||
std::string token;
|
||||
int requestId;
|
||||
bool stopSyncing;
|
||||
Store* store;
|
||||
void startSync();
|
||||
void processSync(json_t* sync);
|
||||
json_t* doSync(std::string token);
|
||||
json_t* doRequest(const char* method, std::string path, json_t* body = NULL);
|
||||
public:
|
||||
MatrixClient(std::string homeserverUrl, std::string matrixToken);
|
||||
Client(std::string homeserverUrl, std::string matrixToken, Store* clientStore = NULL);
|
||||
std::string userId();
|
||||
std::string sendTextMessage(std::string roomId, std::string text);
|
||||
std::string sendMessage(std::string roomId, json_t* content);
|
||||
std::string sendEvent(std::string roomId, std::string eventType, json_t* content);
|
||||
json_t* doRequest(const char* method, std::string path, json_t* body = NULL);
|
||||
};
|
||||
|
||||
}; // namespace Matrix
|
||||
|
||||
#endif // _matrixclient_h_
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef _templatelib_h_
|
||||
#define _templatelib_h_
|
||||
|
||||
int myLibFunction();
|
||||
|
||||
#endif // _templatelib_h_
|
|
@ -6,22 +6,46 @@
|
|||
#include <malloc.h>
|
||||
#include <curl/curl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "memorystore.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define SOC_ALIGN 0x1000
|
||||
#define SOC_BUFFERSIZE 0x100000
|
||||
#define SYNC_TIMEOUT 10000
|
||||
|
||||
namespace Matrix {
|
||||
|
||||
static u32 *SOC_buffer = NULL;
|
||||
|
||||
MatrixClient::MatrixClient(std::string homeserverUrl, std::string matrixToken) {
|
||||
Client::Client(std::string homeserverUrl, std::string matrixToken, Store* clientStore) {
|
||||
hsUrl = homeserverUrl;
|
||||
token = matrixToken;
|
||||
requestId = 0;
|
||||
stopSyncing = false;
|
||||
if (!clientStore) {
|
||||
clientStore = new MemoryStore();
|
||||
}
|
||||
store = clientStore;
|
||||
}
|
||||
|
||||
std::string MatrixClient::sendTextMessage(std::string roomId, std::string text) {
|
||||
std::string Client::userId() {
|
||||
json_t* ret = doRequest("GET", "/_matrix/client/r0/account/whoami");
|
||||
if (!ret) {
|
||||
return "";
|
||||
}
|
||||
json_t* userId = json_object_get(ret, "user_id");
|
||||
if (!userId) {
|
||||
json_decref(ret);
|
||||
return "";
|
||||
}
|
||||
const char* userIdStr = json_string_value(userId);
|
||||
json_decref(ret);
|
||||
return userIdStr;
|
||||
}
|
||||
|
||||
std::string Client::sendTextMessage(std::string roomId, std::string text) {
|
||||
json_t* request = json_object();
|
||||
json_object_set_new(request, "msgtype", json_string("m.text"));
|
||||
json_object_set_new(request, "body", json_string(text.c_str()));
|
||||
|
@ -30,13 +54,13 @@ std::string MatrixClient::sendTextMessage(std::string roomId, std::string text)
|
|||
return eventId;
|
||||
}
|
||||
|
||||
std::string MatrixClient::sendMessage(std::string roomId, json_t* content) {
|
||||
std::string Client::sendMessage(std::string roomId, json_t* content) {
|
||||
return sendEvent(roomId, "m.room.message", content);
|
||||
}
|
||||
|
||||
std::string MatrixClient::sendEvent(std::string roomId, std::string eventType, json_t* content) {
|
||||
std::string Client::sendEvent(std::string roomId, std::string eventType, json_t* content) {
|
||||
std::string txid = std::to_string(time(NULL)) + "_REQ_" + std::to_string(requestId);
|
||||
std::string path = "/_matrix/client/r0/rooms/" + roomId + "/send/" + eventType + "/" + txid;
|
||||
std::string path = "/_matrix/client/r0/rooms/" + urlencode(roomId) + "/send/" + urlencode(eventType) + "/" + urlencode(txid);
|
||||
json_t* ret = doRequest("PUT", path, content);
|
||||
if (!ret) {
|
||||
return "";
|
||||
|
@ -52,12 +76,95 @@ std::string MatrixClient::sendEvent(std::string roomId, std::string eventType, j
|
|||
return eventIdStr;
|
||||
}
|
||||
|
||||
void Client::processSync(json_t* sync) {
|
||||
json_t* rooms = json_object_get(sync, "rooms");
|
||||
if (!rooms) {
|
||||
return; // nothing to do
|
||||
}
|
||||
json_t* leftRooms = json_object_get(rooms, "leave");
|
||||
json_t* invitedRooms = json_object_get(rooms, "invite");
|
||||
json_t* joinedRooms = json_object_get(rooms, "join");
|
||||
|
||||
const char* roomId;
|
||||
json_t* room;
|
||||
|
||||
if (leftRooms) {
|
||||
json_object_foreach(leftRooms, roomId, room) {
|
||||
// rooms that we left
|
||||
}
|
||||
}
|
||||
|
||||
if (invitedRooms) {
|
||||
json_object_foreach(invitedRooms, roomId, room) {
|
||||
// rooms that we were invited to
|
||||
}
|
||||
}
|
||||
|
||||
if (joinedRooms) {
|
||||
json_object_foreach(joinedRooms, roomId, room) {
|
||||
// rooms that we are joined
|
||||
printf(roomId);
|
||||
printf(":\n");
|
||||
json_t* timeline = json_object_get(room, "timeline");
|
||||
if (!timeline) {
|
||||
printf("no timeline\n");
|
||||
continue;
|
||||
}
|
||||
json_t* events = json_object_get(timeline, "events");
|
||||
if (!events) {
|
||||
printf("no events\n");
|
||||
continue;
|
||||
}
|
||||
size_t index;
|
||||
json_t* event;
|
||||
json_array_foreach(events, index, event) {
|
||||
json_t* eventType = json_object_get(event, "type");
|
||||
printf(json_string_value(eventType));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::startSync() {
|
||||
std::string token = store->getSyncToken();
|
||||
if (stopSyncing) {
|
||||
return;
|
||||
}
|
||||
json_t* ret = doSync(token);
|
||||
if (ret) {
|
||||
// set the token for the next batch
|
||||
json_t* token = json_object_get(ret, "next_batch");
|
||||
if (token) {
|
||||
printf("Found next batch\n");
|
||||
store->setSyncToken(json_string_value(token));
|
||||
} else {
|
||||
printf("No next batch\n");
|
||||
store->setSyncToken("");
|
||||
}
|
||||
processSync(ret);
|
||||
json_decref(ret);
|
||||
}
|
||||
}
|
||||
|
||||
json_t* Client::doSync(std::string token) {
|
||||
printf("Doing sync with token ");
|
||||
printf(token.c_str());
|
||||
printf("\n");
|
||||
|
||||
std::string query = "?full_state=false&timeout=" + std::to_string(SYNC_TIMEOUT);
|
||||
if (token != "") {
|
||||
query += "&since=" + token;
|
||||
}
|
||||
return doRequest("GET", "/_matrix/client/r0/sync" + query);
|
||||
}
|
||||
|
||||
size_t DoRequestWriteCallback(char *contents, size_t size, size_t nmemb, void *userp) {
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
json_t* MatrixClient::doRequest(const char* method, std::string path, json_t* body) {
|
||||
json_t* Client::doRequest(const char* method, std::string path, json_t* body) {
|
||||
std::string url = hsUrl + path;
|
||||
requestId++;
|
||||
|
||||
|
@ -101,6 +208,7 @@ json_t* MatrixClient::doRequest(const char* method, std::string path, json_t* bo
|
|||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DoRequestWriteCallback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
|
||||
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
|
||||
|
@ -111,8 +219,8 @@ json_t* MatrixClient::doRequest(const char* method, std::string path, json_t* bo
|
|||
}
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
printf(readBuffer.c_str());
|
||||
printf("\n");
|
||||
// printf(readBuffer.c_str());
|
||||
// printf("\n");
|
||||
json_error_t error;
|
||||
json_t* content = json_loads(readBuffer.c_str(), 0, &error);
|
||||
if (!content) {
|
||||
|
@ -121,3 +229,5 @@ json_t* MatrixClient::doRequest(const char* method, std::string path, json_t* bo
|
|||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
}; // namespace Matrix
|
||||
|
|
18
source/memorystore.cpp
Normal file
18
source/memorystore.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "memorystore.h"
|
||||
#include <string>
|
||||
|
||||
namespace Matrix {
|
||||
|
||||
MemoryStore::MemoryStore() {
|
||||
syncToken = "";
|
||||
}
|
||||
|
||||
void MemoryStore::setSyncToken(std::string token) {
|
||||
syncToken = token;
|
||||
}
|
||||
|
||||
std::string MemoryStore::getSyncToken() {
|
||||
return syncToken;
|
||||
}
|
||||
|
||||
}; // namespace Matrix
|
20
source/memorystore.h
Normal file
20
source/memorystore.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef _memorystore_h_
|
||||
#define _memorystore_h_
|
||||
|
||||
#include "../include/matrixclient.h"
|
||||
#include <string>
|
||||
|
||||
namespace Matrix {
|
||||
|
||||
class MemoryStore : public Store {
|
||||
private:
|
||||
std::string syncToken;
|
||||
public:
|
||||
MemoryStore();
|
||||
void setSyncToken(std::string token);
|
||||
std::string getSyncToken();
|
||||
};
|
||||
|
||||
}; // namespace Matrix
|
||||
|
||||
#endif // _memorystore_h_
|
|
@ -1,6 +0,0 @@
|
|||
int myLibFunction() {
|
||||
|
||||
|
||||
return 42;
|
||||
|
||||
}
|
24
source/util.cpp
Normal file
24
source/util.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "util.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
// from http://www.zedwood.com/article/cpp-urlencode-function
|
||||
std::string urlencode(std::string s) {
|
||||
static const char lookup[]= "0123456789abcdef";
|
||||
std::stringstream e;
|
||||
for(int i = 0, ix = s.length(); i < ix; i++) {
|
||||
const char& c = s[i];
|
||||
if ( (48 <= c && c <= 57) ||//0-9
|
||||
(65 <= c && c <= 90) ||//abc...xyz
|
||||
(97 <= c && c <= 122) || //ABC...XYZ
|
||||
(c=='-' || c=='_' || c=='.' || c=='~')
|
||||
) {
|
||||
e << c;
|
||||
} else {
|
||||
e << '%';
|
||||
e << lookup[ (c&0xF0)>>4 ];
|
||||
e << lookup[ (c&0x0F) ];
|
||||
}
|
||||
}
|
||||
return e.str();
|
||||
}
|
8
source/util.h
Normal file
8
source/util.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string urlencode(std::string str);
|
||||
|
||||
#endif // _UTIL_H_
|
Loading…
Reference in a new issue