start breaking up src/controller/inbox.c to reduce file size, handle pin

master
teknomunk 1 year ago
parent b83d9db75a
commit f19ea54b1d

@ -11,6 +11,7 @@
#include "model/account.h"
#include "model/notification.h"
#include "model/ap/activity.h"
#include "model/ap/account.h"
#include "model/ap/inbox_envelope.h"
#include "model/crypto/http_sign.h"
//#include "model/timeline.h"
@ -39,26 +40,6 @@ bool route_inbox( struct http_request* req )
return true;
}
static bool route_undo_follow( struct ap_activity* act )
{
const char* target = act->object.ptr->object.ref;
struct account* a = account_from_uri( target );
if( !a || 0 != strcmp( a->server, g_server_name ) ) {
printf( "Unfollow not targeted at local account. Discarding.\n" );
return true;
}
struct account* follower = account_from_uri( act->actor );
if( !follower ) {
printf( "Follower account not present local. Active follow not possible. Discarding undo\n" );
return true;
}
account_remove_follower( a, follower );
return true;
}
static bool route_follow( struct ap_activity* act )
{
struct account* follower = NULL;
@ -105,8 +86,8 @@ failed:
static bool route_undo_activity( struct ap_activity* act )
{
if( act->object.tag != apaot_activity ) {
// Don't undo activities that are references
return false;
printf( "Can't undo reference activities, discarding...\n" );
return true;
}
if( !act->object.ptr ) {
printf( "No object in activity\n" );
@ -280,65 +261,6 @@ static bool route_accept( struct ap_activity* act )
return true;
}
static bool route_announce( struct ap_activity* act )
{
bool result = false;
struct status* s = NULL;
struct account* owner_account = account_from_id( owner_account_id );
struct account* actor_account = account_from_uri( act->actor );
if( !account_does_follow( owner_account, actor_account->id ) ) {
// Not following, discard
printf( "%s does not follow %s\n", owner_account->handle, actor_account->account_url );
goto discard;
}
// Reposts do not show up in notifications unless notifications for the user are enabled
if( actor_account->notify_for_posts ) {
printf( "? TODO: notification\n" );
}
if( act->object.tag != apaot_ref ) {
printf( "! object not reference\n" );
goto failed;
}
struct status* original_post = status_fetch_from_uri( act->object.ref );
if( !original_post ) {
goto discard;
}
// TODO: handle repost
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
s->url = strdup(act->id);
s->published = act->published;
s->repost_id = original_post->id;
s->account_id = actor_account->id;
s->sensitive = act->sensitive;
status_save_new(s);
status_add_to_timeline( s, home_timeline_id );
status_add_to_timeline( s, public_timeline_id );
status_add_to_timeline( s, actor_account->id );
result = true;
cleanup:
status_free(s);
status_free(original_post);
account_free(owner_account);
account_free(actor_account);
return result;
discard:
result = true;
goto cleanup;
failed:
result = false;
goto cleanup;
}
bool route_activity( struct ap_activity* act )
{
printf( "Handling %s\n", act->id );
@ -351,6 +273,7 @@ bool route_activity( struct ap_activity* act )
case apat_create: return route_create(act);
case apat_accept: return route_accept(act);
case apat_announce: return route_announce(act);
case apat_add: return route_add(act);
case apat_emoji_react: return route_emoji_react(act);
default:
printf( "Unhandled activity type: %d\n", act->type );

@ -5,6 +5,10 @@
struct http_request;
struct ap_activity;
bool route_undo_follow( struct ap_activity* act );
bool route_announce( struct ap_activity* act );
bool route_add( struct ap_activity* act );
bool route_inbox( struct http_request* req );
bool route_activity( struct ap_activity* act );
void process_inbox();

@ -0,0 +1,49 @@
#include "../inbox.h"
#include "model/account.h"
#include "model/ap/account.h"
#include "model/ap/activity.h"
#include "model/status.h"
#include <string.h>
bool route_add( struct ap_activity* act )
{
bool result = false;
struct status* s = NULL;
struct account* a = NULL;
struct ap_account* apa = NULL;
// Make sure this is to pin a status
a = account_from_uri_or_fetch( act->actor );
if( !a ) {
printf( "Don't have account...\n" );
goto failed;
} // Don't have ActivityPub account data, try again later
apa = account_activity_pub_data(a);
if( 0 != strcmp( apa->featured, act->target ) ) {
printf( "Not adding to featured...\n" );
printf( "apa->featured = %s\n", apa->featured );
printf( "act->target = %s\n", act->target );
goto failed;
}
// Get the status
if( act->object.tag == apaot_ref ) {
s = status_from_uri_or_fetch( act->object.ref );
}
if( !s ) { goto failed; }
s->pinned = true;
status_save(s);
result = true;
cleanup:
status_free(s);
ap_account_free(apa);
account_free(a);
return result;
failed:
result = false;
goto cleanup;
}

@ -0,0 +1,69 @@
#include "../inbox.h"
#include "model/account.h"
#include "model/status.h"
#include "model/ap/activity.h"
#include <string.h>
#include <stdlib.h>
bool route_announce( struct ap_activity* act )
{
bool result = false;
struct status* s = NULL;
struct account* owner_account = account_from_id( owner_account_id );
struct account* actor_account = account_from_uri( act->actor );
if( !account_does_follow( owner_account, actor_account->id ) ) {
// Not following, discard
printf( "%s does not follow %s\n", owner_account->handle, actor_account->account_url );
goto discard;
}
// Reposts do not show up in notifications unless notifications for the user are enabled
if( actor_account->notify_for_posts ) {
printf( "? TODO: notification\n" );
}
if( act->object.tag != apaot_ref ) {
printf( "! object not reference\n" );
goto failed;
}
struct status* original_post = status_fetch_from_uri( act->object.ref );
if( !original_post ) {
goto discard;
}
// TODO: handle repost
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
s->url = strdup(act->id);
s->published = act->published;
s->repost_id = original_post->id;
s->account_id = actor_account->id;
s->sensitive = act->sensitive;
status_save_new(s);
status_add_to_timeline( s, home_timeline_id );
status_add_to_timeline( s, public_timeline_id );
status_add_to_timeline( s, actor_account->id );
result = true;
cleanup:
status_free(s);
status_free(original_post);
account_free(owner_account);
account_free(actor_account);
return result;
discard:
result = true;
goto cleanup;
failed:
result = false;
goto cleanup;
}

@ -0,0 +1,30 @@
#include "../inbox.h"
#include "model/account.h"
#include "model/ap/activity.h"
#include "model/server.h"
#include <stdio.h>
#include <string.h>
bool route_undo_follow( struct ap_activity* act )
{
const char* target = act->object.ptr->object.ref;
struct account* a = account_from_uri( target );
if( !a || 0 != strcmp( a->server, g_server_name ) ) {
printf( "Unfollow not targeted at local account. Discarding.\n" );
return true;
}
struct account* follower = account_from_uri( act->actor );
if( !follower ) {
printf( "Follower account not present local. Active follow not possible. Discarding undo\n" );
return true;
}
account_remove_follower( a, follower );
return true;
}

@ -1 +1 @@
Subproject commit a415e6a851221eabe796d89a486fca603a2af2d7
Subproject commit 6f0f39a98f798d5f6c2299f633e86b939188e32b

@ -52,7 +52,7 @@ bool run_webserver( struct app_args* args )
while(!terminate) {
http_server_process( srv );
usleep(1);
usleep(25000);
}
http_server_release( srv );

@ -172,6 +172,14 @@ struct account* account_from_webfinger( const char* handle )
return account_from_id(id);
}
struct ap_account* account_activity_pub_data( struct account* a )
{
char filename[512];
return ap_account_from_file(
format( filename, 512, "data/accounts/%d/ap.json", a->id )
);
}
bool account_sync_from_acitvity_pub( unsigned int account_id )
{
char filename[512];
@ -182,7 +190,7 @@ bool account_sync_from_acitvity_pub( unsigned int account_id )
printf( "! Failed to sync account %d from %s\n", account_id, filename );
return false;
}
printf( "ap = " ); ap_account_debug_dump(ap);
//printf( "ap = " ); ap_account_debug_dump(ap);
struct account* a = malloc(sizeof(struct account));
memset(a,0,sizeof(*a));

@ -55,7 +55,11 @@ struct account* account_fetch_from_uri( const char* uri );
struct account* account_new();
void account_free( struct account* a );
void account_save( struct account* a );
bool account_sync_from_acitvity_pub( unsigned int id );
struct ap_account;
struct ap_account* account_activity_pub_data( struct account* a );
struct crypto_keys* account_get_public_key( struct account* a, const char* key_name );
struct crypto_keys* account_get_private_key( struct account* a );

@ -85,8 +85,23 @@ void ap_activity_free_composite( struct ap_activity* act )
{
free(act->id);
free(act->actor);
free(act->context);
free(act->attributed_to);
free(act->target);
free(act->content.content);
free(act->source.content);
free(act->conversation);
free(act->summary);
for( int i = 0; i < act->tags.count; ++i ) {
ap_activity_tag_free(act->tags.items[i]);
}
free(act->tags.items);
for( int i = 0; i < act->attachments.count; ++i ) {
ap_attachement_free( act->attachments.items[i] );
}
free( act->attachments.items );
for( int i = 0; i < act->to.count; ++i ) {
free(act->to.items[i]);

@ -90,6 +90,7 @@ struct ap_activity
bool direct_message;
char* attributed_to;
char* target;
struct ap_activity_source content;

@ -0,0 +1,4 @@
#pragma once
void ap_attachement_free( struct ap_attachement* a );

@ -104,6 +104,7 @@ struct json_object_field ap_activity_layout[] = {
.offset = offsetof(OBJ_TYPE,attributed_to),
.type = &json_field_string,
},
JSON_FIELD_STRING( target, false ),
{
.key = "directMessage",

@ -14,3 +14,5 @@ struct ap_activity_tag
extern struct json_field_type ap_activity_tag_type;
void ap_activity_tag_free( struct ap_activity_tag* tag );

@ -20,6 +20,7 @@ static struct json_enum notification_type_enum[] = {
{ "unfollow", nt_unfollow },
{ "block", nt_block },
{ "like", nt_like },
{ "react", nt_react },
{ NULL, -1 },
};

@ -191,6 +191,10 @@ bool status_sync( struct status* s )
{
return status_sync_from_uri( s, s->url );
}
struct status* status_from_uri_or_fetch( const char* uri )
{
return status_fetch_from_uri( uri );
}
struct status* status_fetch_from_uri( const char* uri )
{
struct status* s = status_from_uri(uri);
@ -447,6 +451,7 @@ void status_add_react( struct status* s, const char* react, struct account* a )
// Create notification for liking the owner's post
struct notification* note = notification_new();
note->type = nt_react;
note->status_id = s->id;
note->account_id = a->id;
note->react = strdup(react);
note->created_at = time(NULL);

@ -57,6 +57,7 @@ struct status* status_new_system_block( int account_id );
struct status* status_new_system_stub( struct status* s );
struct status* status_from_uri( const char* uri );
struct status* status_fetch_from_uri( const char* uri );
struct status* status_from_uri_or_fetch( const char* uri );
struct ap_activity;
struct status* status_from_activity( struct ap_activity* act );

Loading…
Cancel
Save