Trying to get organized. Move things db, import, and export out of ssb.c.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3655 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
100
src/ssb.export.c
Normal file
100
src/ssb.export.c
Normal file
@ -0,0 +1,100 @@
|
||||
#include "ssb.export.h"
|
||||
|
||||
#include "ssb.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sqlite3.h>
|
||||
#include <uv.h>
|
||||
|
||||
static void _write_file(const char* path, void* blob, size_t size)
|
||||
{
|
||||
FILE* file = fopen(path, "wb");
|
||||
if (file) {
|
||||
fwrite(blob, 1, size, file);
|
||||
fclose(file);
|
||||
} else {
|
||||
printf("Failed to open %s for write: %s.\n", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_export(tf_ssb_t* ssb, const char* key)
|
||||
{
|
||||
char user[256] = { 0 };
|
||||
char path[256] = { 0 };
|
||||
if (sscanf(key, "/~%255[^/]/%255s", user, path) != 2) {
|
||||
printf("Unable to export %s.\n", key);
|
||||
return;
|
||||
}
|
||||
|
||||
char app_blob_id[64] = { 0 };
|
||||
|
||||
sqlite3_stmt* statement;
|
||||
if (sqlite3_prepare(tf_ssb_get_db(ssb), "SELECT value FROM properties WHERE id = $1 AND key = 'path:' || $2", -1, &statement, NULL) == SQLITE_OK) {
|
||||
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_bind_text(statement, 2, path, -1, NULL) == SQLITE_OK &&
|
||||
sqlite3_step(statement) == SQLITE_ROW) {
|
||||
int len = sqlite3_column_bytes(statement, 0);
|
||||
if (len >= (int)sizeof(app_blob_id)) {
|
||||
len = sizeof(app_blob_id) - 1;
|
||||
}
|
||||
memcpy(app_blob_id, sqlite3_column_text(statement, 0), len);
|
||||
app_blob_id[len] = '\0';
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
|
||||
if (!*app_blob_id) {
|
||||
printf("Did not find app blob ID for %s.\n", key);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* blob = NULL;
|
||||
size_t size = 0;
|
||||
if (!tf_ssb_blob_get(ssb, app_blob_id, &blob, &size)) {
|
||||
printf("Did not find blob for %s: %s.\n", key, app_blob_id);
|
||||
return;
|
||||
}
|
||||
char file_path[1024];
|
||||
snprintf(file_path, sizeof(file_path), "apps/%s/%s.json", user, path);
|
||||
_write_file(file_path, blob, size);
|
||||
JSContext* context = tf_ssb_get_context(ssb);
|
||||
JSValue app = JS_ParseJSON(context, (const char*)blob, size, NULL);
|
||||
free(blob);
|
||||
|
||||
JSValue files = JS_GetPropertyStr(context, app, "files");
|
||||
JSPropertyEnum* ptab = NULL;
|
||||
uint32_t plen = 0;
|
||||
if (JS_GetOwnPropertyNames(context, &ptab, &plen, files, JS_GPN_STRING_MASK) == 0) {
|
||||
for (uint32_t i = 0; i < plen; ++i) {
|
||||
JSPropertyDescriptor desc;
|
||||
if (JS_GetOwnProperty(context, &desc, files, ptab[i].atom) == 1) {
|
||||
JSValue key = JS_AtomToString(context, ptab[i].atom);
|
||||
const char* file_name = JS_ToCString(context, key);
|
||||
const char* blob_id = JS_ToCString(context, desc.value);
|
||||
|
||||
uint8_t* file_blob = NULL;
|
||||
size_t file_size = 0;
|
||||
if (tf_ssb_blob_get(ssb, blob_id, &file_blob, &file_size)) {
|
||||
snprintf(file_path, sizeof(file_path), "apps/%s/%s/%s", user, path, file_name);
|
||||
_write_file(file_path, file_blob, file_size);
|
||||
free(file_blob);
|
||||
}
|
||||
|
||||
JS_FreeCString(context, file_name);
|
||||
JS_FreeValue(context, key);
|
||||
JS_FreeCString(context, blob_id);
|
||||
JS_FreeValue(context, desc.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < plen; ++i) {
|
||||
JS_FreeAtom(context, ptab[i].atom);
|
||||
}
|
||||
js_free(context, ptab);
|
||||
|
||||
JS_FreeValue(context, files);
|
||||
JS_FreeValue(context, app);
|
||||
}
|
||||
|
Reference in New Issue
Block a user