Move state modification code from controller to model, add pleroma api endpoint, add stub for emoji reactions, add messages for block/unfollow events

master
teknomunk 1 year ago
parent 134d9afc5a
commit f4b019eff0

@ -12,7 +12,6 @@
#include "model/notification.h"
#include "model/ap/activity.h"
#include "model/ap/inbox_envelope.h"
#include "model/ap/outbox_envelope.h"
#include "model/crypto/http_sign.h"
// Stdlib
@ -56,8 +55,6 @@ static bool route_undo_follow( struct ap_activity* act )
account_remove_follower( a, follower );
// TODO: create a notification for unfollow
return true;
}
@ -90,27 +87,11 @@ static bool route_follow( struct ap_activity* act )
account_add_follower( a, follower );
// Create Accept activity
accept = ap_activity_create_accept(act);
ap_activity_save(accept);
struct outbox_envelope* env = outbox_envelope_new();
env->activity_id = accept->local_id;
env->account_id = follower->id;
outbox_envelope_save( env );
outbox_envelope_free( env );
// Create notification for follow
struct notification* note = notification_new();
note->type = nt_follow;
note->account_id = follower->id;
note->created_at = time(NULL);
notification_save( note );
notification_free( note );
ap_activity_accept( act, follower->id );
success:
res = true;
cleanup:
ap_activity_free(accept);
account_free(a);
account_free(follower);

@ -10,6 +10,8 @@
#include "model/timeline.h"
#include "model/server.h"
#include "controller/pleroma_api.h"
#include "api/client_apps.h"
#include "api/status.h"
#include "api/notice.h"
@ -97,12 +99,12 @@ bool handle_mastodon_api_show_account( struct http_request* req, struct account*
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
account_write_as_json(a,f);
api_account_write_as_json(a,f);
return true;
}
static bool http_request_route_id( struct http_request* req, int* id )
bool http_request_route_id( struct http_request* req, int* id )
{
char* id_str = http_request_route_get_dir_or_file(req);
if( !id_str || !*id_str ) { return false; }
@ -129,11 +131,11 @@ bool route_mastodon_api( struct http_request* req )
return true;
}
//*
if( !check_bearer_token(req) ) { return false; }
//printf( "authorization still valid\n" );
//*/
if( http_request_route( req, "pleroma" ) ) {
return route_pleroma_api( req );
}
if( http_request_route( req, "notifications" ) ) {
return handle_notifications(req);
@ -143,11 +145,16 @@ bool route_mastodon_api( struct http_request* req )
fprintf( f, "[]" );
return true;
} else if( http_request_route( req, "statuses" ) ) {
printf( "route: statuses\n" );
if( http_request_route( req, "/" ) ) {
int id = -1;
if( http_request_route_id( req, &id ) ) {
struct status* s = status_from_id(id);
if( !s ) {
return false;
}
if( http_request_route( req, "context" ) ) {
show_status_context( req, s );
} else {

@ -0,0 +1,47 @@
#include "pleroma_api.h"
#include "http_server/http_request.h"
#include "model/status.h"
#include "src/controller/api/client_apps.h"
#include <stdlib.h>
bool http_request_route_id( struct http_request* req, int* id );
static bool route_status( struct http_request* req, struct status* s )
{
if( http_request_route( req, "reactions/" ) ) {
char* react = http_request_route_get_dir_or_file( req );
status_add_react( s, react );
free(react);
return true;
}
return false;
}
bool route_pleroma_api( struct http_request* req )
{
if( http_request_route( req, "/statuses" ) ) {
printf( "route: statuses\n" );
if( http_request_route( req, "/" ) ) {
int id = -1;
if( http_request_route_id( req, &id ) ) {
struct status* s = status_from_id(id);
if( !s ) {
printf( "Status %d not found\n", id );
return false;
}
bool result = route_status( req, s );
status_free(s);
return result;
}
}
}
return false;
}

@ -0,0 +1,7 @@
#pragma once
#include <stdbool.h>
struct http_request;
bool route_pleroma_api( struct http_request* req );

@ -1 +1 @@
Subproject commit 3cacd9fa083d94088c87e826be5f123c8056b880
Subproject commit c5b4f6e732131995377c1a40b9fba1f86845e519

@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include "account.h"
// Submodules
@ -12,6 +13,7 @@
#include "model/server.h"
#include "model/ap/account.h"
#include "model/crypto/keys.h"
#include "model/notification.h"
// Stdlib
#include <stdio.h>
@ -19,6 +21,7 @@
#include <string.h>
#include <stddef.h>
#include <sys/stat.h>
#include <time.h>
static const char* safe( const char* value, const char* other )
{
@ -52,8 +55,31 @@ static struct json_object_field account_layout[] = {
{ NULL },
};
struct account* account_from_id( unsigned int id )
static struct account* new_system_account()
{
struct account* a;
a = malloc(sizeof(*a));
memset(a,0,sizeof(*a));
a->id = -1;
a->handle = strdup("system");
a->display_name = strdup("Apogee System");
a->account_type = at_bot,
a->bot = true;
asprintf( &a->avatar.url, "https://%s/system-account.png", g_server_name );
a->avatar.static_url = strdup(a->avatar.url);
return a;
}
struct account* account_from_id( int id )
{
switch( id ) {
case -1:
// System account
return new_system_account();
}
char filename[512];
snprintf( filename, 512, "data/accounts/%d.json", id );
@ -268,6 +294,14 @@ void account_add_follower( struct account* a, struct account* follower )
// Update follower count
a->followers_count = ffdb_trie_count(filename);
// Create notification for follow
struct notification* note = notification_new();
note->type = nt_follow;
note->account_id = follower->id;
note->created_at = time(NULL);
notification_save( note );
notification_free( note );
}
void account_remove_follower( struct account* a, struct account* follower )
{
@ -281,10 +315,19 @@ void account_remove_follower( struct account* a, struct account* follower )
// Update follower count
a->followers_count = ffdb_trie_count(filename);
// create a notification for unfollow
struct notification* note = notification_new();
note->type = nt_unfollow;
note->account_id = -1;
note->ref_account_id = follower->id;
note->created_at = time(NULL);
notification_save( note );
notification_free( note );
}
// TODO: move to controller/view
void account_write_as_json( struct account* a, FILE* f )
void api_account_write_as_json( struct account* a, FILE* f )
{
#include "src/view/api/account.json.inc"
}

@ -38,7 +38,7 @@ struct account
bool locked;
};
struct account* account_from_id( unsigned int id );
struct account* account_from_id( int id );
struct account* account_from_uri( const char* uri );
struct account* account_fetch_from_uri( const char* uri );
struct account* account_new();
@ -52,5 +52,5 @@ void account_add_follower( struct account* a, struct account* follower );
void account_remove_follower( struct account* a, struct account* follower );
// TODO: move to controller/view and rename api_account_write_as_json
void account_write_as_json( struct account* a, FILE* f );
void api_account_write_as_json( struct account* a, FILE* f );

@ -6,6 +6,7 @@
#include "collections/array.h"
#include "model/server.h"
#include "model/ap/outbox_envelope.h"
#include <stddef.h>
#include <stdlib.h>
@ -129,4 +130,17 @@ struct ap_activity* ap_activity_create_accept( struct ap_activity* act )
return accept;
}
void ap_activity_accept( struct ap_activity* act, int deliver_to_account_id )
{
struct ap_activity* accept = ap_activity_create_accept(act);
ap_activity_save(accept);
struct outbox_envelope* env = outbox_envelope_new();
env->activity_id = accept->local_id;
env->account_id = deliver_to_account_id;
outbox_envelope_save( env );
outbox_envelope_free( env );
ap_activity_free(accept);
}

@ -125,5 +125,6 @@ void ap_activity_write_to_FILE( struct ap_activity* act, FILE* f );
void ap_activity_save( struct ap_activity* act );
struct ap_activity* ap_activity_create_accept( struct ap_activity* act );
void ap_activity_accept( struct ap_activity* act, int deliver_to_account_id );

@ -17,12 +17,15 @@ static struct json_enum notification_type_enum[] = {
{ "favorite", nt_favorite },
{ "follow", nt_follow },
{ "mention", nt_mention },
{ "unfollow", nt_unfollow },
{ "block", nt_block },
{ NULL, -1 },
};
static struct json_object_field notification_layout[] = {
{ "account_id", offsetof( struct notification, account_id ), true, &json_field_integer },
{ "status_id", offsetof( struct notification, status_id ), false, &json_field_integer },
{ "ref_account_id", offsetof( struct notification, ref_account_id ), false, &json_field_integer },
{ "type", offsetof( struct notification, type ), true, &json_field_enum, notification_type_enum },
{ NULL }
};
@ -72,6 +75,15 @@ void notification_write_as_json( struct notification* n, FILE* f )
struct account* owner = account_from_id( 0 );
struct status* s = status_from_id( n->status_id );
switch( n->type ) {
case nt_unfollow:
s = status_new_system_unfollow( n->ref_account_id );
break;
case nt_block:
s = status_new_system_block( n->ref_account_id );
break;
}
#include "src/model/notification.json.inc"
status_free(s);

@ -6,9 +6,10 @@
struct notification
{
unsigned int id;
unsigned int account_id;
unsigned int status_id;
int id;
int account_id;
int status_id;
int ref_account_id;
time_t created_at;
bool is_muted;
bool is_seen;
@ -20,6 +21,8 @@ enum notification_type
nt_favorite = 1,
nt_follow = 2,
nt_mention = 3,
nt_unfollow = 4,
nt_block = 5,
};
struct notification* notification_from_id( int id );

@ -1,5 +1,5 @@
{
"account": %( account_write_as_json(a,f); ),
"account": %( api_account_write_as_json(a,f); ),
"created_at": "2022-12-12T15:31:54.000Z",
"id": "%d{n->id}",
"pleroma": {
@ -13,6 +13,8 @@
switch(n->type) {
case nt_favorite: fprintf(f,"favourite"); break;
case nt_follow: fprintf(f,"follow"); break;
case nt_unfollow:
case nt_block:
case nt_mention: fprintf(f,"mention"); break;
default: fprintf(f,"unknown-%d",n->type); break;
}; )"

@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include "status.h"
#include "status/react.h"
@ -16,10 +17,11 @@
static struct json_object_field status_layout[] = {
{ "account_id", offsetof( struct status, account_id ), true, &json_field_integer },
{ "url", offsetof( struct status, url ), false, &json_field_string },
{ "sensitive", offsetof( struct status, sensitive ), true, &json_field_bool },
{ "content", offsetof( struct status, content ), true, &json_field_string },
{ "media", offsetof( struct status, media ), false, &json_field_array_of, &json_field_string },
{ "reacts", offsetof( struct status, reacts ), false, &json_field_array_of, &status_react_type },
//{ "reacts", offsetof( struct status, reacts ), false, &json_field_array_of, &status_react_type },
{ NULL }
};
@ -47,6 +49,42 @@ struct status* status_from_id( unsigned int id )
return s;
}
struct status* status_new_system_unfollow( int account_id )
{
struct account* a = account_from_id(account_id);
if( !a ) { return NULL; }
struct status* s;
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
s->id = -1;
s->account_id = -1;
asprintf( &s->content, "%s unfollowed you\n", a->display_name );
s->sensitive = true;
account_free(a);
return s;
}
struct status* status_new_system_block( int account_id )
{
struct account* a = account_from_id(account_id);
if( !a ) { return NULL; }
struct status* s;
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
s->id = -1;
s->account_id = -1;
asprintf( &s->content, "%s blocked you\n", a->display_name );
s->sensitive = true;
account_free(a);
return s;
}
struct status* status_from_activity( struct ap_activity* act )
{
@ -59,6 +97,7 @@ struct status* status_from_activity( struct ap_activity* act )
account_free(a);
s->content = status_render_source( act->source );
s->url = strdup( act->id );
return s;
}
@ -109,3 +148,12 @@ void status_free( struct status* s )
free(s);
}
void status_add_react( struct status* s, const char* react )
{
printf( "TODO: add reaction '%s' to status #%d\n", react, s->id );
if( s->url ) {
// TODO generate outbox element
}
}

@ -1,13 +1,14 @@
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdio.h>
struct status
{
unsigned int id;
unsigned int account_id;
int account_id;
char* url;
char* content;
bool sensitive;
@ -23,6 +24,8 @@ struct status
};
struct status* status_from_id( unsigned int id );
struct status* status_new_system_unfollow( int account_id );
struct status* status_new_system_block( int account_id );
struct ap_activity;
struct status* status_from_activity( struct ap_activity* act );
@ -31,5 +34,7 @@ bool status_save_new( struct status* s );
void status_save( struct status* s );
void status_free( struct status* s );
void status_add_react( struct status* s, const char* react );
char* status_render_source( const char* src );

@ -1,5 +1,5 @@
{
"account": %( account_write_as_json(account,f); ),
"account": %( api_account_write_as_json(account,f); ),
"application": null,
"bookmarked": false,
"card": null,

Loading…
Cancel
Save