forked from cory/tildefriends
Allow visiting/viewing an app message by id.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3635 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
d8657866f5
commit
2b5a56abfe
@ -52,7 +52,7 @@ function socket(request, response, client) {
|
|||||||
var packageName;
|
var packageName;
|
||||||
var blobId;
|
var blobId;
|
||||||
var match;
|
var match;
|
||||||
if (match = /^\/(&[^\.]*\.\w+)(\/?.*)/.exec(message.path)) {
|
if (match = /^\/([&%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(message.path)) {
|
||||||
blobId = match[1];
|
blobId = match[1];
|
||||||
} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
|
} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
|
||||||
var user = match[1];
|
var user = match[1];
|
||||||
|
34
core/core.js
34
core/core.js
@ -267,16 +267,16 @@ async function getProcessBlob(blobId, key, options) {
|
|||||||
}
|
}
|
||||||
process.task.setImports(imports);
|
process.task.setImports(imports);
|
||||||
process.task.activate();
|
process.task.activate();
|
||||||
let source = await ssb.blobGet(blobId);
|
let source = await getBlobOrContent(blobId);
|
||||||
var appSource = utf8Decode(source);
|
var appSource = utf8Decode(source);
|
||||||
try {
|
try {
|
||||||
var app = JSON.parse(appSource);
|
var app = JSON.parse(appSource);
|
||||||
if (app.type == "tildefriends-app") {
|
if (app.type == "tildefriends-app") {
|
||||||
var id = app.files["app.js"];
|
var id = app.files["app.js"];
|
||||||
var blob = await ssb.blobGet(id);
|
var blob = await getBlobOrContent(id);
|
||||||
appSource = utf8Decode(blob);
|
appSource = utf8Decode(blob);
|
||||||
await Promise.all(Object.keys(app.files).map(async function(f) {
|
await Promise.all(Object.keys(app.files).map(async function(f) {
|
||||||
await process.task.loadFile([f, await ssb.blobGet(app.files[f])]);
|
await process.task.loadFile([f, await getBlobOrContent(app.files[f])]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -387,6 +387,16 @@ function sendData(response, data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getBlobOrContent(id) {
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
} else if (id.startsWith('&')) {
|
||||||
|
return ssb.blobGet(id);
|
||||||
|
} else if (id.startsWith('%')) {
|
||||||
|
return ssb.messageContentGet(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function blobHandler(request, response, blobId, uri) {
|
async function blobHandler(request, response, blobId, uri) {
|
||||||
var found = false;
|
var found = false;
|
||||||
if (!found) {
|
if (!found) {
|
||||||
@ -402,7 +412,7 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
response.writeHead(301, {"Location": blobId + "/"});
|
response.writeHead(301, {"Location": "/" + blobId + "/"});
|
||||||
response.end(data);
|
response.end(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -414,14 +424,14 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
if (match = /^\/\~(\w+)\/(\w+)$/.exec(blobId)) {
|
||||||
var id = await new Database(match[1]).get('path:' + match[2]);
|
var id = await new Database(match[1]).get('path:' + match[2]);
|
||||||
if (id) {
|
if (id) {
|
||||||
data = await ssb.blobGet(id);
|
data = await getBlobOrContent(id);
|
||||||
if (match[3]) {
|
if (match[3]) {
|
||||||
var app = JSON.parse(data);
|
var app = JSON.parse(data);
|
||||||
data = app.files[match[3]];
|
data = app.files[match[3]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = await ssb.blobGet(blobId);
|
data = await getBlobOrContent(blobId);
|
||||||
}
|
}
|
||||||
sendData(response, data);
|
sendData(response, data);
|
||||||
} else if (uri == "/save") {
|
} else if (uri == "/save") {
|
||||||
@ -449,12 +459,16 @@ async function blobHandler(request, response, blobId, uri) {
|
|||||||
var db = new Database(match[1]);
|
var db = new Database(match[1]);
|
||||||
var id = await db.get('path:' + match[2]);
|
var id = await db.get('path:' + match[2]);
|
||||||
if (id) {
|
if (id) {
|
||||||
data = utf8Decode(await ssb.blobGet(id));
|
data = utf8Decode(await getBlobOrContent(id));
|
||||||
var app = JSON.parse(data);
|
var app = JSON.parse(data);
|
||||||
print(JSON.stringify(app));
|
|
||||||
data = app.files[uri.substring(1)];
|
data = app.files[uri.substring(1)];
|
||||||
data = await ssb.blobGet(data);
|
data = await getBlobOrContent(data);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
data = utf8Decode(await getBlobOrContent(blobId));
|
||||||
|
var app = JSON.parse(data);
|
||||||
|
data = app.files[uri.substring(1)];
|
||||||
|
data = await getBlobOrContent(data);
|
||||||
}
|
}
|
||||||
sendData(response, data);
|
sendData(response, data);
|
||||||
}
|
}
|
||||||
@ -479,7 +493,7 @@ httpd.all("", function(request, response) {
|
|||||||
return response.end();
|
return response.end();
|
||||||
} else if (match = /^(\/~[^\/]+\/[^\/]+)(\/?.*)$/.exec(request.uri)) {
|
} else if (match = /^(\/~[^\/]+\/[^\/]+)(\/?.*)$/.exec(request.uri)) {
|
||||||
return blobHandler(request, response, match[1], match[2]);
|
return blobHandler(request, response, match[1], match[2]);
|
||||||
} else if (match = /^\/(&[^\.]*\.\w+)(\/?.*)/.exec(request.uri)) {
|
} else if (match = /^\/([&\%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(request.uri)) {
|
||||||
return blobHandler(request, response, match[1], match[2]);
|
return blobHandler(request, response, match[1], match[2]);
|
||||||
} else if (match = /^\/static(\/.*)/.exec(request.uri)) {
|
} else if (match = /^\/static(\/.*)/.exec(request.uri)) {
|
||||||
return staticFileHandler(request, response, null, match[1]);
|
return staticFileHandler(request, response, null, match[1]);
|
||||||
|
25
src/ssb.c
25
src/ssb.c
@ -1902,6 +1902,31 @@ bool tf_ssb_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* ou
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tf_ssb_message_content_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
sqlite3_stmt* statement;
|
||||||
|
const char* query = "SELECT content FROM messages WHERE id = ?";
|
||||||
|
if (sqlite3_prepare(ssb->db, query, -1, &statement, NULL) == SQLITE_OK) {
|
||||||
|
if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK &&
|
||||||
|
sqlite3_step(statement) == SQLITE_ROW) {
|
||||||
|
const uint8_t* blob = sqlite3_column_blob(statement, 0);
|
||||||
|
int size = sqlite3_column_bytes(statement, 0);
|
||||||
|
if (out_blob) {
|
||||||
|
*out_blob = malloc(size + 1);
|
||||||
|
memcpy(*out_blob, blob, size);
|
||||||
|
(*out_blob)[size] = '\0';
|
||||||
|
}
|
||||||
|
if (out_size) {
|
||||||
|
*out_size = size;
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static bool _tf_ssb_parse_broadcast(const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast)
|
static bool _tf_ssb_parse_broadcast(const char* in_broadcast, tf_ssb_broadcast_t* out_broadcast)
|
||||||
{
|
{
|
||||||
char public_key_str[45] = { 0 };
|
char public_key_str[45] = { 0 };
|
||||||
|
@ -70,6 +70,8 @@ bool tf_ssb_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* author
|
|||||||
bool tf_ssb_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size);
|
bool tf_ssb_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size);
|
||||||
bool tf_ssb_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* out_id, size_t out_id_size);
|
bool tf_ssb_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* out_id, size_t out_id_size);
|
||||||
|
|
||||||
|
bool tf_ssb_message_content_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size);
|
||||||
|
|
||||||
typedef void (tf_ssb_connections_changed_callback_t)(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data);
|
typedef void (tf_ssb_connections_changed_callback_t)(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data);
|
||||||
void tf_ssb_add_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connections_changed_callback_t callback, void* user_data);
|
void tf_ssb_add_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_connections_changed_callback_t callback, void* user_data);
|
||||||
const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb);
|
const char** tf_ssb_get_connection_ids(tf_ssb_t* ssb);
|
||||||
|
@ -82,6 +82,22 @@ static JSValue _tf_ssb_blobStore(JSContext* context, JSValueConst this_val, int
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue _tf_ssb_messageContentGet(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
|
{
|
||||||
|
JSValue result = JS_NULL;
|
||||||
|
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||||
|
if (ssb) {
|
||||||
|
const char* id = JS_ToCString(context, argv[0]);
|
||||||
|
uint8_t* blob = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
if (tf_ssb_message_content_get(ssb, id, &blob, &size)) {
|
||||||
|
result = JS_NewArrayBufferCopy(context, blob, size);
|
||||||
|
free(blob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
{
|
{
|
||||||
JSValue result = JS_NULL;
|
JSValue result = JS_NULL;
|
||||||
@ -285,6 +301,7 @@ void tf_ssb_init(JSContext* context, tf_ssb_t* ssb)
|
|||||||
JS_SetPropertyStr(context, object, "getMessage", JS_NewCFunction(context, _tf_ssb_getMessage, "getMessage", 2));
|
JS_SetPropertyStr(context, object, "getMessage", JS_NewCFunction(context, _tf_ssb_getMessage, "getMessage", 2));
|
||||||
JS_SetPropertyStr(context, object, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1));
|
JS_SetPropertyStr(context, object, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1));
|
||||||
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 2));
|
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 2));
|
||||||
|
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
||||||
JS_SetPropertyStr(context, object, "connections", JS_NewCFunction(context, _tf_ssb_connections, "connections", 0));
|
JS_SetPropertyStr(context, object, "connections", JS_NewCFunction(context, _tf_ssb_connections, "connections", 0));
|
||||||
JS_SetPropertyStr(context, object, "createHistoryStream", JS_NewCFunction(context, _tf_ssb_createHistoryStream, "createHistoryStream", 1));
|
JS_SetPropertyStr(context, object, "createHistoryStream", JS_NewCFunction(context, _tf_ssb_createHistoryStream, "createHistoryStream", 1));
|
||||||
JS_SetPropertyStr(context, object, "sqlStream", JS_NewCFunction(context, _tf_ssb_sqlStream, "sqlStream", 3));
|
JS_SetPropertyStr(context, object, "sqlStream", JS_NewCFunction(context, _tf_ssb_sqlStream, "sqlStream", 3));
|
||||||
|
Loading…
Reference in New Issue
Block a user