parent
57ab5d1d1f
commit
35ff50746c
4 changed files with 357 additions and 122 deletions
|
@ -1,3 +1,4 @@
|
|||
U0 (*@slon_api_status_boost_fedi)(JsonObject* status) = NULL;
|
||||
U0 (*@slon_api_status_create_fedi)(JsonObject* status) = NULL;
|
||||
U0 (*@slon_api_status_delete_fedi)(JsonObject* status) = NULL;
|
||||
|
||||
|
@ -62,7 +63,14 @@ U0 @slon_api_v1_statuses_query(SlonHttpSession* session, JsonArray* status_array
|
|||
for (i = status_array->length - 1; i > -1; i--) {
|
||||
status = Json.Clone(status_array->o(i), session->mem_task);
|
||||
status_id = Str2I64(status->@("id"));
|
||||
status->set("bookmarked", @slon_api_status_is_bookmarked(session, status, account_id), JSON_BOOLEAN);
|
||||
status->set("favourited", @slon_api_status_is_favourited(session, status, account_id), JSON_BOOLEAN);
|
||||
if (@slon_api_status_is_reblogged(session, status, account_id)) {
|
||||
status->set("reblogged", TRUE, JSON_BOOLEAN);
|
||||
if (status->@("reblog")) {
|
||||
status->o("reblog")->set("reblogged", TRUE, JSON_BOOLEAN);
|
||||
}
|
||||
}
|
||||
exclude_status = FALSE;
|
||||
if (status->@("deleted")) {
|
||||
exclude_status = TRUE;
|
||||
|
@ -82,6 +90,9 @@ U0 @slon_api_v1_statuses_query(SlonHttpSession* session, JsonArray* status_array
|
|||
if (pinned && !status->@("pinned")) {
|
||||
exclude_status = TRUE;
|
||||
}
|
||||
if (exclude_reblogs && status->@("reblogged")) {
|
||||
exclude_status = TRUE;
|
||||
}
|
||||
if (!exclude_status) {
|
||||
statuses->append(status);
|
||||
count++;
|
||||
|
@ -199,7 +210,14 @@ U0 @slon_api_v1_statuses_get(SlonHttpSession* session)
|
|||
status = @slon_api_find_status_by_id(id, NULL);
|
||||
if (status) {
|
||||
status = Json.Clone(status, session->mem_task);
|
||||
status->set("bookmarked", @slon_api_status_is_bookmarked(session, status, account_id), JSON_BOOLEAN);
|
||||
status->set("favourited", @slon_api_status_is_favourited(session, status, account_id), JSON_BOOLEAN);
|
||||
if (@slon_api_status_is_reblogged(session, status, account_id)) {
|
||||
status->set("reblogged", TRUE, JSON_BOOLEAN);
|
||||
if (status->@("reblog")) {
|
||||
status->o("reblog")->set("reblogged", TRUE, JSON_BOOLEAN);
|
||||
}
|
||||
}
|
||||
session->send(status);
|
||||
return;
|
||||
}
|
||||
|
@ -223,6 +241,7 @@ U0 @slon_api_v1_statuses_post(SlonHttpSession* session)
|
|||
|
||||
U8* id = NULL;
|
||||
JsonObject* status = NULL;
|
||||
JsonObject* boost = NULL;
|
||||
|
||||
if (session->path_count() > 4) {
|
||||
id = session->path(3);
|
||||
|
@ -266,6 +285,25 @@ U0 @slon_api_v1_statuses_post(SlonHttpSession* session)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!StrICmp("reblog", verb)) {
|
||||
status = Json.Clone(status, slon_db_mem_task);
|
||||
boost = Json.Clone(@slon_api_reblog_status(session, status, account_id), session->mem_task);
|
||||
boost->set("reblogged", TRUE, JSON_BOOLEAN);
|
||||
session->send(boost);
|
||||
if (@slon_api_status_boost_fedi) {
|
||||
@slon_api_status_boost_fedi(Json.Clone(boost, slon_mem_task));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StrICmp("unreblog", verb)) {
|
||||
status = Json.Clone(status, session->mem_task);
|
||||
@slon_api_unreblog_status(session, status, account_id);
|
||||
status->set("reblogged", FALSE, JSON_BOOLEAN);
|
||||
session->send(status);
|
||||
return;
|
||||
}
|
||||
|
||||
session->status(400);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -523,6 +523,54 @@ U0 @slon_activitypub_async_create_status_to(JsonObject* status, U8* dest)
|
|||
Free(fetch_buffer);
|
||||
}
|
||||
|
||||
U0 @slon_activitypub_async_boost_status_to(JsonObject* status, U8* dest)
|
||||
{
|
||||
Sleep(1000);
|
||||
I64 i;
|
||||
|
||||
U8 scratch_buffer[2048];
|
||||
|
||||
// U8* this_actor = StrNew(status->@("uri"), slon_mem_task);
|
||||
// StrFind("/statuses/", this_actor)[0] = NULL;
|
||||
U8* this_actor = db->o("actors")->o(status->o("account")->@("acct"))->@("id");
|
||||
if (!this_actor) {
|
||||
AdamLog("slon_activitypub_async_boost_status_to: this_actor is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject* announce_object = Json.CreateObject(slon_mem_task);
|
||||
|
||||
announce_object->set("@context", "https://www.w3.org/ns/activitystreams", JSON_STRING);
|
||||
StrPrint(scratch_buffer, "%s/activity", status->@("uri"));
|
||||
announce_object->set("id", scratch_buffer, JSON_STRING);
|
||||
announce_object->set("type", "Announce", JSON_STRING);
|
||||
announce_object->set("actor", this_actor, JSON_STRING);
|
||||
announce_object->set("object", status->o("reblog")->@("uri"), JSON_STRING);
|
||||
announce_object->set("published", status->@("created_at"), JSON_STRING);
|
||||
announce_object->set("to", Json.Parse("[\"https://www.w3.org/ns/activitystreams#Public\"]", slon_mem_task), JSON_ARRAY);
|
||||
JsonArray* cc = Json.CreateArray(slon_mem_task);
|
||||
StrPrint(scratch_buffer, "%s/followers", this_actor);
|
||||
cc->append(scratch_buffer, JSON_STRING);
|
||||
announce_object->set("cc", cc, JSON_ARRAY);
|
||||
|
||||
U8* fetch_buffer = CAlloc(HTTP_FETCH_BUFFER_SIZE, slon_mem_task);
|
||||
StrPrint(scratch_buffer, "%s/inbox", dest);
|
||||
@slon_activitypub_signed_request(scratch_buffer, fetch_buffer, announce_object);
|
||||
Free(fetch_buffer);
|
||||
}
|
||||
|
||||
U0 @slon_activitypub_async_boost_status(JsonObject* status)
|
||||
{
|
||||
I64 i;
|
||||
JsonArray* followers = db->o("followers")->a(status->o("account")->@("username"));
|
||||
if (!followers) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < followers->length; i++) {
|
||||
@slon_activitypub_async_boost_status_to(status, followers->@(i));
|
||||
}
|
||||
}
|
||||
|
||||
U0 @slon_activitypub_async_create_status(JsonObject* status)
|
||||
{
|
||||
I64 i;
|
||||
|
@ -591,6 +639,11 @@ U0 @slon_activitypub_follow_fedi(JsonObject* follow)
|
|||
Spawn(&@slon_activitypub_async_follow, follow, "SlonAsyncFollowTask");
|
||||
}
|
||||
|
||||
U0 @slon_activitypub_boost_status_fedi(JsonObject* status)
|
||||
{
|
||||
Spawn(&@slon_activitypub_async_boost_status, status, "SlonAsyncBoostTask");
|
||||
}
|
||||
|
||||
U0 @slon_activitypub_create_status_fedi(JsonObject* status)
|
||||
{
|
||||
Spawn(&@slon_activitypub_async_create_status, status, "SlonAsyncCreateTask");
|
||||
|
@ -602,6 +655,7 @@ U0 @slon_activitypub_delete_status_fedi(JsonObject* status)
|
|||
}
|
||||
|
||||
@slon_api_follow_fedi = &@slon_activitypub_follow_fedi;
|
||||
@slon_api_status_boost_fedi = &@slon_activitypub_boost_status_fedi;
|
||||
@slon_api_status_create_fedi = &@slon_activitypub_create_status_fedi;
|
||||
@slon_api_status_delete_fedi = &@slon_activitypub_delete_status_fedi;
|
||||
|
||||
|
|
|
@ -147,6 +147,126 @@ JsonObject* @slon_api_announcement_by_id(U8* id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_id(U8* id, JsonArray* statuses)
|
||||
{
|
||||
if (!id || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("id") && !StrICmp(status->@("id"), id)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_in_reply_to_id(U8* id, JsonArray* statuses)
|
||||
{
|
||||
if (!id || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("in_reply_to_id") && !StrICmp(status->@("in_reply_to_id"), id)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_uri(U8* uri, JsonArray* statuses)
|
||||
{
|
||||
if (!uri || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("uri") && !StrICmp(status->@("uri"), uri)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_find_status_by_id(U8* id, U8* account_id = NULL)
|
||||
{
|
||||
if (account_id) {
|
||||
return @slon_api_status_lookup_by_id(id, db->o("statuses")->a(account_id));
|
||||
}
|
||||
JsonObject* status = NULL;
|
||||
JsonKey* key = db->o("statuses")->keys;
|
||||
while (key) {
|
||||
status = @slon_api_status_lookup_by_id(id, key->value);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
key = key->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_find_status_by_uri(U8* uri, U8* account_id = NULL)
|
||||
{
|
||||
if (account_id) {
|
||||
return @slon_api_status_lookup_by_uri(uri, db->o("statuses")->a(account_id));
|
||||
}
|
||||
JsonObject* status = NULL;
|
||||
JsonKey* key = db->o("statuses")->keys;
|
||||
while (key) {
|
||||
status = @slon_api_status_lookup_by_uri(uri, key->value);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
key = key->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 @slon_api_create_status(JsonObject* status, U8* account_id, U8* to_ap_user = NULL)
|
||||
{
|
||||
if (!status || !account_id) {
|
||||
return;
|
||||
}
|
||||
if (!db->o("statuses")->a(account_id)) {
|
||||
db->o("statuses")->set(account_id, Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("statuses")->a(account_id)->append(status);
|
||||
@slon_db_save_status_to_disk(status);
|
||||
@slon_db_instance_increment_status_count;
|
||||
@slon_db_save_instance_to_disk;
|
||||
|
||||
JsonObject* status_item = Json.CreateObject(slon_mem_task);
|
||||
status_item->set("account_id", account_id, JSON_STRING);
|
||||
status_item->set("status_id", status->@("id"), JSON_STRING);
|
||||
|
||||
// If account_id is a local account, publish to public timeline
|
||||
JsonObject* acct = @slon_api_account_by_id(account_id);
|
||||
if (!acct->@("remote_actor") && !StrICmp("public", status->@("visibility"))) {
|
||||
if (!db->o("timelines")->a("public")) {
|
||||
db->o("timelines")->set("public", Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("timelines")->a("public")->append(status_item);
|
||||
}
|
||||
// If account_id is a remote account, and we have an ActivityPub user, post to their timeline
|
||||
if (acct->@("remote_actor") && to_ap_user) {
|
||||
JsonObject* acct_for_ap_user = @slon_api_account_by_username(to_ap_user);
|
||||
if (acct_for_ap_user) {
|
||||
if (!db->o("timelines")->o("home")->a(acct_for_ap_user->@("id"))) {
|
||||
db->o("timelines")->o("home")->set(acct_for_ap_user->@("id"), Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("timelines")->o("home")->a(acct_for_ap_user->@("id"))->append(status_item);
|
||||
}
|
||||
}
|
||||
@slon_db_save_timelines_to_disk;
|
||||
}
|
||||
|
||||
Bool @slon_api_status_is_bookmarked(SlonHttpSession* session, JsonObject* status, U8* account_id)
|
||||
{
|
||||
no_warn session;
|
||||
|
@ -183,7 +303,7 @@ U0 @slon_api_bookmark_status(SlonHttpSession* session, JsonObject* status, U8* a
|
|||
}
|
||||
}
|
||||
if (!is_already_bookmarked) {
|
||||
bookmark = Json.CreateObject(session->mem_task);
|
||||
bookmark = Json.CreateObject(slon_db_mem_task);
|
||||
bookmark->set("status_id", status->@("id"), JSON_STRING);
|
||||
bookmark->set("account_id", status->o("account")->@("id"), JSON_STRING);
|
||||
bookmarks->append(bookmark);
|
||||
|
@ -229,6 +349,24 @@ Bool @slon_api_status_is_favourited(SlonHttpSession* session, JsonObject* status
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
Bool @slon_api_status_is_reblogged(SlonHttpSession* session, JsonObject* status, U8* account_id)
|
||||
{
|
||||
no_warn session;
|
||||
JsonArray* reblogs = db->o("reblogs")->a(account_id);
|
||||
JsonObject* reblog = NULL;
|
||||
if (!reblogs) {
|
||||
return FALSE;
|
||||
}
|
||||
I64 i;
|
||||
for (i = 0; i < reblogs->length; i++) {
|
||||
reblog = reblogs->o(i);
|
||||
if (!StrICmp(reblog->@("boost_id"), status->@("id")) || !StrICmp(reblog->@("status_id"), status->@("id"))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 @slon_api_favourite_status(SlonHttpSession* session, JsonObject* status, U8* account_id)
|
||||
{
|
||||
Bool is_already_favourited = FALSE;
|
||||
|
@ -247,7 +385,7 @@ U0 @slon_api_favourite_status(SlonHttpSession* session, JsonObject* status, U8*
|
|||
}
|
||||
}
|
||||
if (!is_already_favourited) {
|
||||
favourite = Json.CreateObject(session->mem_task);
|
||||
favourite = Json.CreateObject(slon_db_mem_task);
|
||||
favourite->set("status_id", status->@("id"), JSON_STRING);
|
||||
favourite->set("account_id", status->o("account")->@("id"), JSON_STRING);
|
||||
favourites->append(favourite);
|
||||
|
@ -275,6 +413,97 @@ U0 @slon_api_unfavourite_status(SlonHttpSession* session, JsonObject* status, U8
|
|||
}
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_reblog_status(SlonHttpSession* session, JsonObject* status, U8* account_id)
|
||||
{
|
||||
Bool is_already_reblogged = FALSE;
|
||||
JsonArray* reblogs = db->o("reblogs")->a(account_id);
|
||||
JsonObject* reblog = NULL;
|
||||
if (!reblogs) {
|
||||
reblogs = Json.CreateArray(slon_db_mem_task);
|
||||
db->o("reblogs")->set(account_id, reblogs, JSON_ARRAY);
|
||||
@slon_db_save_reblogs_to_disk;
|
||||
}
|
||||
I64 i;
|
||||
for (i = 0; i < reblogs->length; i++) {
|
||||
reblog = reblogs->o(i);
|
||||
if (!StrICmp(reblog->@("status_id"), status->@("id")) && !StrICmp(reblog->@("account_id"), status->o("account")->@("id"))) {
|
||||
return @slon_api_find_status_by_id(reblog->@("boost_id"), account_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Create boost object, which is our reblog status with the original status attached as a "reblog" object
|
||||
JsonObject* boost = Json.CreateObject(slon_db_mem_task);
|
||||
U8* boost_id = @slon_api_generate_unique_id(session);
|
||||
U8* boost_created_at = @slon_api_timestamp_from_cdate(session, Now);
|
||||
|
||||
boost->set("id", boost_id, JSON_STRING);
|
||||
boost->set("in_reply_to_id", NULL, JSON_NULL);
|
||||
boost->set("in_reply_to_account_id", NULL, JSON_NULL);
|
||||
boost->set("content", "", JSON_STRING);
|
||||
boost->set("created_at", boost_created_at, JSON_STRING);
|
||||
boost->set("visibility", "public", JSON_STRING);
|
||||
boost->set("uri", status->@("uri"), JSON_STRING);
|
||||
boost->set("url", status->@("url"), JSON_STRING);
|
||||
boost->set("account", @slon_api_account_by_id(account_id), JSON_OBJECT);
|
||||
boost->set("reblogs_count", 0, JSON_NUMBER);
|
||||
boost->set("favourites_count", 0, JSON_NUMBER);
|
||||
boost->set("emojis", SLON_EMPTY_JSON_ARRAY, JSON_ARRAY);
|
||||
boost->set("tags", SLON_EMPTY_JSON_ARRAY, JSON_ARRAY);
|
||||
boost->set("mentions", SLON_EMPTY_JSON_ARRAY, JSON_ARRAY);
|
||||
boost->set("media_attachments", SLON_EMPTY_JSON_ARRAY, JSON_ARRAY);
|
||||
boost->set("replies_count", 0, JSON_NUMBER);
|
||||
boost->set("spoiler_text", "", JSON_STRING);
|
||||
boost->set("sensitive", status->@("sensitive"), JSON_BOOLEAN);
|
||||
boost->set("reblog", status, JSON_OBJECT);
|
||||
|
||||
@slon_api_create_status(boost, account_id);
|
||||
|
||||
// Create a reblog object which is a lookup to status_id, account_id, boost_id
|
||||
reblog = Json.CreateObject(slon_db_mem_task);
|
||||
reblog->set("status_id", status->@("id"), JSON_STRING);
|
||||
reblog->set("account_id", status->o("account")->@("id"), JSON_STRING);
|
||||
reblog->set("boost_id", boost->@("id"), JSON_STRING);
|
||||
reblogs->append(reblog);
|
||||
@slon_db_save_reblogs_to_disk;
|
||||
|
||||
status->set("reblogs_count", status->@("reblogs_count") + 1, JSON_NUMBER);
|
||||
@slon_db_save_status_to_disk(status);
|
||||
|
||||
@slon_free(session, boost_created_at);
|
||||
@slon_free(session, boost_id);
|
||||
|
||||
return boost;
|
||||
}
|
||||
|
||||
U0 @slon_api_unreblog_status(SlonHttpSession* session, JsonObject* status, U8* account_id)
|
||||
{
|
||||
no_warn session;
|
||||
JsonArray* reblogs = db->o("reblogs")->a(account_id);
|
||||
JsonObject* reblog = NULL;
|
||||
JsonObject* boost = NULL;
|
||||
if (!reblogs) {
|
||||
reblogs = Json.CreateArray(slon_db_mem_task);
|
||||
db->o("reblogs")->set(account_id, reblogs, JSON_ARRAY);
|
||||
@slon_db_save_reblogs_to_disk;
|
||||
}
|
||||
I64 i;
|
||||
for (i = 0; i < reblogs->length; i++) {
|
||||
reblog = reblogs->o(i);
|
||||
if (!StrICmp(reblog->@("status_id"), status->@("id")) && !StrICmp(reblog->@("account_id"), status->o("account")->@("id"))) {
|
||||
reblogs->remove(i);
|
||||
@slon_db_save_reblogs_to_disk;
|
||||
status->set("reblogs_count", status->@("reblogs_count") - 1, JSON_NUMBER);
|
||||
@slon_db_save_status_to_disk(status);
|
||||
boost = @slon_api_find_status_by_id(reblog->@("boost_id"), account_id);
|
||||
if (boost) {
|
||||
boost->set("deleted", TRUE, JSON_BOOLEAN);
|
||||
@slon_db_save_status_to_disk(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 @slon_api_async_upload_to_catbox(SlonCatboxUpload* cb)
|
||||
{
|
||||
if (!cb) {
|
||||
|
@ -445,126 +674,6 @@ U0 @slon_api_async_delete_from_catbox(U8* filename)
|
|||
Free(filename);
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_id(U8* id, JsonArray* statuses)
|
||||
{
|
||||
if (!id || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("id") && !StrICmp(status->@("id"), id)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_in_reply_to_id(U8* id, JsonArray* statuses)
|
||||
{
|
||||
if (!id || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("in_reply_to_id") && !StrICmp(status->@("in_reply_to_id"), id)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_status_lookup_by_uri(U8* uri, JsonArray* statuses)
|
||||
{
|
||||
if (!uri || !statuses) {
|
||||
return NULL;
|
||||
}
|
||||
I64 i;
|
||||
JsonObject* status;
|
||||
for (i = 0; i < statuses->length; i++) {
|
||||
status = statuses->@(i);
|
||||
if (!status->@("deleted") && status->@("uri") && !StrICmp(status->@("uri"), uri)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_find_status_by_id(U8* id, U8* account_id = NULL)
|
||||
{
|
||||
if (account_id) {
|
||||
return @slon_api_status_lookup_by_id(id, db->o("statuses")->a(account_id));
|
||||
}
|
||||
JsonObject* status = NULL;
|
||||
JsonKey* key = db->o("statuses")->keys;
|
||||
while (key) {
|
||||
status = @slon_api_status_lookup_by_id(id, key->value);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
key = key->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_find_status_by_uri(U8* uri, U8* account_id = NULL)
|
||||
{
|
||||
if (account_id) {
|
||||
return @slon_api_status_lookup_by_uri(uri, db->o("statuses")->a(account_id));
|
||||
}
|
||||
JsonObject* status = NULL;
|
||||
JsonKey* key = db->o("statuses")->keys;
|
||||
while (key) {
|
||||
status = @slon_api_status_lookup_by_uri(uri, key->value);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
key = key->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 @slon_api_create_status(JsonObject* status, U8* account_id, U8* to_ap_user = NULL)
|
||||
{
|
||||
if (!status || !account_id) {
|
||||
return;
|
||||
}
|
||||
if (!db->o("statuses")->a(account_id)) {
|
||||
db->o("statuses")->set(account_id, Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("statuses")->a(account_id)->append(status);
|
||||
@slon_db_save_status_to_disk(status);
|
||||
@slon_db_instance_increment_status_count;
|
||||
@slon_db_save_instance_to_disk;
|
||||
|
||||
JsonObject* status_item = Json.CreateObject(slon_mem_task);
|
||||
status_item->set("account_id", account_id, JSON_STRING);
|
||||
status_item->set("status_id", status->@("id"), JSON_STRING);
|
||||
|
||||
// If account_id is a local account, publish to public timeline
|
||||
JsonObject* acct = @slon_api_account_by_id(account_id);
|
||||
if (!acct->@("remote_actor") && !StrICmp("public", status->@("visibility"))) {
|
||||
if (!db->o("timelines")->a("public")) {
|
||||
db->o("timelines")->set("public", Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("timelines")->a("public")->append(status_item);
|
||||
}
|
||||
// If account_id is a remote account, and we have an ActivityPub user, post to their timeline
|
||||
if (acct->@("remote_actor") && to_ap_user) {
|
||||
JsonObject* acct_for_ap_user = @slon_api_account_by_username(to_ap_user);
|
||||
if (acct_for_ap_user) {
|
||||
if (!db->o("timelines")->o("home")->a(acct_for_ap_user->@("id"))) {
|
||||
db->o("timelines")->o("home")->set(acct_for_ap_user->@("id"), Json.CreateArray(slon_mem_task), JSON_ARRAY);
|
||||
}
|
||||
db->o("timelines")->o("home")->a(acct_for_ap_user->@("id"))->append(status_item);
|
||||
}
|
||||
}
|
||||
@slon_db_save_timelines_to_disk;
|
||||
}
|
||||
|
||||
JsonObject* @slon_api_get_timeline_item(JsonObject* timeline_item)
|
||||
{
|
||||
if (!timeline_item) {
|
||||
|
|
|
@ -126,6 +126,26 @@ U0 @slon_db_load_favourites_from_disk()
|
|||
db->set("favourites", favourites, JSON_OBJECT);
|
||||
}
|
||||
|
||||
U0 @slon_db_load_reblogs_from_disk()
|
||||
{
|
||||
JsonObject* reblogs = Json.CreateObject(slon_db_mem_task);
|
||||
U8 scratch_buffer[256];
|
||||
StrPrint(scratch_buffer, "%s/reblogs/*.json", SLON_DB_PATH);
|
||||
CDirEntry* files = FilesFind(scratch_buffer);
|
||||
CDirEntry* de = files;
|
||||
JsonArray* reblog_array = NULL;
|
||||
while (de) {
|
||||
reblog_array = Json.ParseFile(de->full_name, slon_db_mem_task);
|
||||
if (reblog_array) {
|
||||
StrFind(".json", de->name)[0] = NULL;
|
||||
reblogs->set(de->name, reblog_array, JSON_ARRAY);
|
||||
}
|
||||
de = de->next;
|
||||
}
|
||||
DirTreeDel(files);
|
||||
db->set("reblogs", reblogs, JSON_OBJECT);
|
||||
}
|
||||
|
||||
U0 @slon_db_load_followers_from_disk()
|
||||
{
|
||||
JsonObject* followers = Json.CreateObject(slon_db_mem_task);
|
||||
|
@ -341,6 +361,17 @@ U0 @slon_db_save_favourites_to_disk()
|
|||
}
|
||||
}
|
||||
|
||||
U0 @slon_db_save_reblogs_to_disk()
|
||||
{
|
||||
U8 scratch_buffer[256];
|
||||
JsonKey* key = db->o("reblogs")->keys;
|
||||
while (key) {
|
||||
StrPrint(scratch_buffer, "%s/reblogs/%s.json", SLON_DB_PATH, key->name);
|
||||
Json.DumpToFile(scratch_buffer, key->value, slon_db_mem_task);
|
||||
key = key->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 @slon_db_save_followers_to_disk()
|
||||
{
|
||||
U8 scratch_buffer[256];
|
||||
|
@ -429,6 +460,7 @@ U0 @slon_db_save_to_disk()
|
|||
@slon_db_save_markers_to_disk();
|
||||
@slon_db_save_oauth_to_disk();
|
||||
@slon_db_save_private_keys_to_disk();
|
||||
@slon_db_save_reblogs_to_disk();
|
||||
@slon_db_save_settings_to_disk();
|
||||
@slon_db_save_statuses_to_disk();
|
||||
@slon_db_save_timelines_to_disk();
|
||||
|
@ -452,6 +484,7 @@ U0 @slon_db_load_from_defaults()
|
|||
db->set("instance", Json.ParseFile("M:/Slon/Static/defaults/instance.json", slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("markers", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("media", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("reblogs", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("settings", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("statuses", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
db->set("timelines", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
|
@ -485,6 +518,7 @@ U0 @slon_db_load_from_disk()
|
|||
@slon_db_load_markers_from_disk();
|
||||
db->set("media", Json.CreateObject(slon_db_mem_task), JSON_OBJECT);
|
||||
@slon_db_load_oauth_from_disk();
|
||||
@slon_db_load_reblogs_from_disk();
|
||||
@slon_db_load_settings_from_disk();
|
||||
@slon_db_load_statuses_from_disk();
|
||||
@slon_db_load_timelines_from_disk();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue