Implement Like federation, fix system account id, add defunct flag to accounts and stop delivery to accounds so flagged

master
teknomunk 1 year ago
parent 2d45847e41
commit bf37930623

@ -20,9 +20,7 @@ bool get_local_account_id( struct http_request* req, int* id )
char* id_str = http_request_route_get_dir_or_file(req);
if( !id_str || !*id_str ) { goto failed; }
*id = -1;
sscanf( id_str, "%d", id );
if( *id == -1 ) {
if( 1 != sscanf( id_str, "%d", id ) ) {
struct account* a = account_from_webfinger(id_str);
if( a ) {
*id = a->id;

@ -232,6 +232,19 @@ bool handle_show_bookmarks( struct http_request* req )
return true;
}
// route: GET /api/v1/statuses/%d{id}/favourite
bool handle_favorite( struct http_request* req, struct status* s )
{
struct account* owner = account_from_id( owner_account_id );
status_add_like(s,owner);
status_save(s);
show_status( req, s );
account_free(owner);
return true;
}
bool http_request_route_id( struct http_request* req, int* id )
{
char* id_str = http_request_route_get_dir_or_file(req);
@ -277,16 +290,20 @@ bool route_statuses( struct http_request* req )
if( handle_bookmark( req, s ) ) { goto success; }
} else if( http_request_route_term( req, "unbookmark" ) ) {
if( handle_unbookmark( req, s ) ) { goto success; }
} else if( http_request_route_term( req, "favourite" ) ) {
if( handle_favorite( req, s ) ) { goto success; }
} else if( http_request_route_term( req, "" ) ) {
show_status( req, s );
goto success;
}
failed:
result = false;
goto failed;
cleanup:
status_free(s);
return result;
success:
result = true;
goto cleanup;
failed:
result = false;
}

@ -65,6 +65,7 @@ static struct json_field_type string_pair_type = {
static struct json_object_field account_layout[] = {
JSON_FIELD_STRING( handle, true ),
JSON_FIELD_BOOL( local, false ),
JSON_FIELD_BOOL( defunct, false ),
JSON_FIELD_STRING( server, true ),
JSON_FIELD_STRING( display_name, true ),
JSON_FIELD_BOOL( stub, false ),
@ -118,7 +119,7 @@ static struct account* new_system_account()
a = malloc(sizeof(*a));
memset(a,0,sizeof(*a));
a->id = -1;
a->id = system_account_id;
a->handle = strdup("system");
a->display_name = strdup("Apogee System");
a->account_type = at_bot,
@ -151,6 +152,7 @@ struct account* account_from_id( int id )
{
switch( id ) {
case -1:
case system_account_id:
// System account
return new_system_account();
}

@ -3,6 +3,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <limits.h>
struct crypto_keys;
struct status;
@ -11,7 +12,7 @@ struct outbox_envelope;
struct outbox_envelope_list;
enum {
system_account_id = -1,
system_account_id = INT_MAX,
owner_account_id = 0,
home_timeline_id = 1,
public_timeline_id = 2,
@ -39,6 +40,7 @@ struct account
char* server;
char* display_name;
bool stub;
bool defunct;
time_t next_stub_recheck;
int account_type;

@ -19,6 +19,10 @@
void account_deliver_activity( struct account* a, struct ap_object* act, struct outbox_envelope_list* oel )
{
if( a->defunct ) {
printf( "Account %s id defunct, not delivering activity\n" );
return;
}
printf( "Delivering activity %s to account %s\n", act->id, a->account_url );
if( a->shared_inbox ) {

@ -49,6 +49,14 @@ struct ap_object* activity_from_local_id( int id )
return act;
}
static struct ap_object* new_local_activity()
{
struct ap_object* act = ap_object_new();
ap_object_add_context( act, "https://www.w3.org/ns/activitystreams");
char buffer[512];
ap_object_add_context( act, format( buffer, 512, "https://%s/schemas/litepub-0.1.jsonld", g_server->domain ) );
return act;
}
struct ap_object* activity_create_Accept( struct ap_object* act )
{
@ -91,10 +99,8 @@ struct ap_object* activity_create_EmojiReact( struct status* s, const char* reac
struct account* a = account_from_id( s->account_id );
struct ap_object* act = ap_object_new();
struct ap_object* act = new_local_activity();
activity_allocate_local_id(act);
ap_object_add_context( act, "https://www.w3.org/ns/activitystreams");
ap_object_add_context( act, "https://apogee.polaris-1.work/schemas/litepub-0.1.jsonld");
act->id = aformat( "https://%s/activity/%d", g_server->domain, act->local_id );
act->actor = aformat( "https://%s/owner/actor", g_server->domain );
act->type = pleroma_EmojiReact;
@ -222,21 +228,48 @@ failed:
struct ap_object* activity_create_Like( struct status* s )
{
return NULL;
struct ap_object* act = new_local_activity();
activity_allocate_local_id(act);
act->id = aformat( "https://%s/activity/%d", g_server->domain, act->local_id );
act->actor = aformat( "https://%s/owner/actor", g_server->domain );
act->type = ap_Like;
act->published = time(NULL);
act->object.tag = apaot_ref;
act->object.ref = strdup( s->url );
struct account* a = account_from_id( s->account_id );
char* to = aformat( "https://%s/owner/followers", g_server->domain );
array_append( &act->to, sizeof(to), &to );
to = strdup(a->account_url);
array_append( &act->to, sizeof(to), &to );
for( int i = 0; i < s->mentions.count; ++i ) {
struct account* mentioned = account_from_id( s->mentions.items[i] );
to = strdup(mentioned->account_url);
array_append( &act->to, sizeof(to), &to );
account_free(mentioned);
}
char* cc = strdup( "https://www.w3.org/ns/activitystreams#Public" );
array_append( &act->cc, sizeof(cc), &cc );
account_free(a);
return act;
}
int activity_like( struct status* s )
{
printf( "TODO: like\n" );
struct ap_object* act = activity_create_Like( s );
if( !act ) { return 0; }
activity_save(act);
activity_deliver( act );
return -1;
return 1;
}
struct ap_object* activity_create_Note( struct status* s )
{
struct ap_object* act = ap_object_new();
ap_object_add_context( act, "https://www.w3.org/ns/activitystreams");
ap_object_add_context( act, "https://apogee.polaris-1.work/schemas/litepub-0.1.jsonld");
struct ap_object* act = new_local_activity();
act->id = aformat( "https://%s/note/%d", g_server->domain, s->id );
act->type = ap_Note;
act->published = s->published;

@ -77,6 +77,7 @@ void notification_free( struct notification* note )
if( !note ) { return; }
free(note->react);
status_free(note->system_status);
free(note);
}

@ -4,6 +4,7 @@
#include <time.h>
#include <stdbool.h>
struct status;
struct notification
{
int debug;
@ -11,6 +12,7 @@ struct notification
int id;
int account_id;
int status_id;
struct status* system_status;
int ref_account_id;
time_t created_at;
bool is_muted;

@ -423,6 +423,7 @@ struct status* status_new_system_unfollow( int account_id )
memset(s,0,sizeof(*s));
s->id = -1;
s->published = time(NULL);
s->account_id = -1;
asprintf( &s->content, "%s unfollowed you\n", a->display_name );
s->sensitive = true;
@ -441,9 +442,10 @@ struct status* status_new_system_block( int account_id )
memset(s,0,sizeof(*s));
s->id = -1;
s->published = time(NULL);
s->account_id = -1;
asprintf( &s->content, "%s blocked you\n", a->display_name );
s->sensitive = true;
asprintf( &s->content, "%s blocked you. View their account <a href='%s'>here</a>.", a->display_name, a->account_url );
s->sensitive = false;
account_free(a);

@ -98,7 +98,7 @@ bool int_to_string_callback( void* field_data, bool is_read, char** res )
if( is_read ) {
return 1 == sscanf( *res, "%d", field );
} else {
*res = aformat( "%018d", *field );
*res = aformat( "%018u", *field );
return true;
}
}

@ -5,6 +5,7 @@
#include "format.h"
#include "model/notification.h"
#include "model/status.h"
#include "view/api/Status.h"
#include "view/api/Account.h"
@ -52,6 +53,12 @@ static struct json_object_field api_Notification_layout[] = {
.key = "status",
.offset = offsetof( OBJ_TYPE, status_id ),
.required = false,
.type = &api_Status_from_id_type,
},
{
.key = "status",
.offset = offsetof( OBJ_TYPE, system_status ),
.required = false,
.type = &api_Status_type,
},
{
@ -73,16 +80,15 @@ void api_Notification_write( struct notification* note, FILE* f, int indent )
.indent = indent,
};
/*
switch( n->type ) {
// Handle notifications requiring a system-generated note as they are not part of Mastodon or Pleroma
switch( note->type ) {
case nt_unfollow:
s = status_new_system_unfollow( n->ref_account_id );
note->system_status = status_new_system_unfollow( note->ref_account_id );
break;
case nt_block:
s = status_new_system_block( n->ref_account_id );
note->system_status = status_new_system_block( note->ref_account_id );
break;
}
*/
json_write_pretty_object_layout( &jw, api_Notification_layout, note );
}

@ -31,7 +31,7 @@ static struct json_object_field Relationship_layout[] = {
void api_Relationship_init( struct Relationship* r, struct account* a, struct account* rel )
{
memset( r, 0, sizeof(*r) );
r->id = aformat( "%d",rel->id );
r->id = aformat( "%018u",rel->id );
r->followed_by = account_does_follow( rel, a->id );
r->following = account_does_follow( a, rel->id );
}

@ -38,7 +38,7 @@ static bool write_in_reply_to( struct json_writer* jw, const char* field_name, v
json_write_indention(jw);
json_write_field_name(jw,"in_reply_to_id");
fprintf( jw->f, "\"%018d\"", in_reply_to->id );
fprintf( jw->f, "\"%018u\"", in_reply_to->id );
} else {
json_write_field_name(jw,"in_reply_to_account_id");
fprintf( jw->f, "null" );
@ -357,7 +357,7 @@ struct json_object_field api_Status_layout[] = {
.fixed_bool = false,
},
{
.key = "favourited_count",
.key = "favourites_count",
.required = true,
.offset = offsetof( OBJ_TYPE, likes.count ),
.type = &json_field_integer,
@ -457,11 +457,16 @@ static bool api_Status_writer( struct json_writer* jw, const char* field_name, v
return true;
}
struct json_field_type api_Status_type = {
struct json_field_type api_Status_from_id_type = {
.writer = api_Status_writer,
.size = sizeof(int),
.layout = api_Status_layout,
};
struct json_field_type api_Status_type = {
.writer = json_field_object_type_writer,
.size = sizeof(struct status*),
.layout = api_Status_layout,
};
void api_Status_write( struct status* s, FILE* f, int indent )
{

@ -4,6 +4,7 @@
struct json_field_type;
struct status;
extern struct json_field_type api_Status_from_id_type;
extern struct json_field_type api_Status_type;
void api_Status_write( struct status* s, FILE* f, int indent );

Loading…
Cancel
Save