Refactored import and export. No user on disk.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4164 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2023-02-02 02:09:05 +00:00
parent ec52e62908
commit e04d137af5
12 changed files with 288 additions and 155 deletions

@@ -9,7 +9,7 @@
#include <sqlite3.h>
#include <uv.h>
static void _write_file(const char* path, void* blob, size_t size)
static void _write_file(const char* path, const void* blob, size_t size)
{
FILE* file = fopen(path, "wb");
if (file)
@@ -35,6 +35,45 @@ static void _make_dir(const char* path)
}
}
typedef struct _tf_export_t
{
tf_ssb_t* ssb;
const char* parent;
JSValue files;
uv_fs_t req;
bool done;
} tf_export_t;
static void _tf_ssb_export_scandir(uv_fs_t* req)
{
tf_export_t* export = req->data;
JSContext* context = tf_ssb_get_context(export->ssb);
uv_dirent_t ent;
while (uv_fs_scandir_next(req, &ent) == 0)
{
if (ent.type == UV_DIRENT_FILE)
{
JSValue found = JS_GetPropertyStr(context, export->files, ent.name);
if (JS_IsUndefined(found))
{
size_t len = strlen(export->parent) + strlen(ent.name) + 2;
char* path = tf_malloc(len);
snprintf(path, len, "%s/%s", export->parent, ent.name);
uv_fs_t req = { 0 };
int r = uv_fs_unlink(tf_ssb_get_loop(export->ssb), &req, path, NULL);
if (r)
{
printf("Failed to unlink %s: %s.", path, uv_strerror(r));
}
uv_fs_req_cleanup(&req);
tf_free(path);
}
JS_FreeValue(context, found);
}
}
export->done = true;
}
void tf_ssb_export(tf_ssb_t* ssb, const char* key)
{
char user[256] = { 0 };
@@ -80,12 +119,9 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key)
}
char file_path[1024];
_make_dir("apps/");
snprintf(file_path, sizeof(file_path), "apps/%s", user);
snprintf(file_path, sizeof(file_path), "apps/%s", path);
_make_dir(file_path);
snprintf(file_path, sizeof(file_path), "apps/%s/%s", user, path);
_make_dir(file_path);
snprintf(file_path, sizeof(file_path), "apps/%s/%s.json", user, path);
_write_file(file_path, blob, size);
snprintf(file_path, sizeof(file_path), "apps/%s.json", path);
JSContext* context = tf_ssb_get_context(ssb);
JSValue app = JS_ParseJSON(context, (const char*)blob, size, NULL);
tf_free(blob);
@@ -108,7 +144,7 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key)
size_t file_size = 0;
if (tf_ssb_db_blob_get(ssb, blob_id, &file_blob, &file_size))
{
snprintf(file_path, sizeof(file_path), "apps/%s/%s/%s", user, path, file_name);
snprintf(file_path, sizeof(file_path), "apps/%s/%s", path, file_name);
_write_file(file_path, file_blob, file_size);
tf_free(file_blob);
}
@@ -129,6 +165,40 @@ void tf_ssb_export(tf_ssb_t* ssb, const char* key)
}
js_free(context, ptab);
JSAtom files_atom = JS_NewAtom(context, "files");
JS_DeleteProperty(context, app, files_atom, 0);
JS_FreeAtom(context, files_atom);
JSValue json = JS_JSONStringify(context, app, JS_NULL, JS_NewInt32(context, 2));
size_t length = 0;
const char* string = JS_ToCStringLen(context, &length, json);
snprintf(file_path, sizeof(file_path), "apps/%s.json", path);
_write_file(file_path, string, length);
JS_FreeCString(context, string);
JS_FreeValue(context, json);
snprintf(file_path, sizeof(file_path), "apps//%s", path);
tf_export_t export =
{
.parent = file_path,
.ssb = ssb,
.files = files,
.req =
{
.data = &export,
},
};
int r = uv_fs_scandir(tf_ssb_get_loop(ssb), &export.req, file_path, 0, _tf_ssb_export_scandir);
if (r)
{
printf("Failed to scan directory %s: %s.", file_path, uv_strerror(r));
}
while (!export.done)
{
uv_run(tf_ssb_get_loop(ssb), UV_RUN_ONCE);
}
uv_fs_req_cleanup(&export.req);
JS_FreeValue(context, files);
JS_FreeValue(context, app);
}