Rework CLI controller, add 'activity import' stub and 'status import' command, start ActivityPub->status fetch and import

master
teknomunk 1 year ago
parent d675a087e5
commit 1fb3f84b9b

@ -1,24 +1,43 @@
#include "cli.h"
#include "model/account.h"
#include "model/status.h"
#include "controller/inbox.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static char* binary_name = NULL;
struct cli_request
{
char** argv;
int argc;
char* binary_name;
};
static bool handle_command_follow( char** argv, int argc )
static int cli_route_command( struct cli_request* req, const char* cmd, int count, const char* usage_args )
{
if( 0 != strcmp(argv[0],"follow") ) { return false; }
if( 0 != strcmp(req->argv[0], cmd ) ) {
return 0;
}
req->argv += 1;
req->argc -= 1;
if( argc < 2 ) {
printf( "Usage: %s follow [account webfinger]\n", binary_name );
return true;
if( req->argc < count ) {
printf( "Usage: %s %s %s", req->binary_name, cmd, usage_args );
return -1;
}
return 1;
}
static bool handle_command_follow( struct cli_request* req )
{
int res = cli_route_command( req, "follow", 1, "[account webfinger]" );
if( res != 1 ) { return !!res; }
struct account* owner = account_from_id( owner_account_id );
struct account* to_follow = account_from_webfinger( argv[1] );
struct account* to_follow = account_from_webfinger( req->argv[0] );
account_follow( owner, to_follow );
@ -27,17 +46,13 @@ static bool handle_command_follow( char** argv, int argc )
return true;
}
static bool handle_command_unfollow( char** argv, int argc )
static bool handle_command_unfollow( struct cli_request* req )
{
if( 0 != strcmp(argv[0],"unfollow") ) { return false; }
if( argc < 2 ) {
printf( "Usage: %s unfollow [account webfinger]\n", binary_name );
return true;
}
int res = cli_route_command( req, "unfollow", 1, "[account webfinger]" );
if( res != 1 ) { return !!res; }
struct account* owner = account_from_id( owner_account_id );
struct account* to_unfollow = account_from_webfinger( argv[1] );
struct account* to_unfollow = account_from_webfinger( req->argv[0] );
account_unfollow( owner, to_unfollow );
@ -46,12 +61,57 @@ static bool handle_command_unfollow( char** argv, int argc )
return true;
}
static bool handle_command_activity_import( struct cli_request* req )
{
int res = cli_route_command( req, "import", 1, "[activity uri]" );
if( res != 1 ) { return !!res; }
printf( "TODO: import activity from %s\n", req->argv[0] );
return false;
}
static bool handle_command_activity( struct cli_request* req )
{
int res = cli_route_command( req, "activity", 1, "(import) ..." );
if( res != 1 ) { return !!res; }
return false
|| handle_command_activity_import( req )
;
}
static bool handle_command_status_import( struct cli_request* req )
{
int res = cli_route_command( req, "import", 1, "[status uri]" );
if( res != 1 ) { return !!res; }
struct status* s = status_fetch_from_uri( req->argv[0] );
if( s ) {
printf( "Status id=%d\n", s->id );
status_free(s);
}
}
static bool handle_command_status( struct cli_request* req )
{
int res = cli_route_command( req, "status", 1, "(import) ..." );
if( res != 1 ) { return !!res; }
return false
|| handle_command_status_import( req );
}
void handle_command( char** argv, int argc )
{
binary_name = argv[0];
struct cli_request req = {
.argv = &argv[1],
.argc = argc - 1,
.binary_name = argv[0]
};
false
|| handle_command_follow(&argv[1],argc-1)
|| handle_command_unfollow(&argv[1],argc-1)
|| handle_command_follow(&req)
|| handle_command_unfollow(&req)
|| handle_command_activity(&req)
|| handle_command_status(&req)
;
}

@ -138,7 +138,14 @@ static struct status* lookup_object_status( struct ap_activity* act )
if( s ) { return s; }
printf( "! Status %s doesn't exist locally\n", act->object.ptr->id );
switch( act->object.tag ) {
case apaot_ref:
printf( "! Status %s doesn't exist locally\n", act->object.ref );
break;
case apaot_activity:
printf( "! Status %s doesn't exist locally\n", act->object.ptr->id );
break;
}
return NULL;
}
@ -220,8 +227,12 @@ check_is_follower:
}
// Create local status
struct status* s = status_from_activity(obj);
status_save_new(s);
struct status* s;
s = status_from_uri( obj->id );
if( !s ) {
s = status_from_activity(obj);
status_save_new(s);
}
// Add to timelines
if( follows_me ) {
@ -261,7 +272,7 @@ static bool route_accept( struct ap_activity* act )
return true;
}
static bool route_activity( struct ap_activity* act )
bool route_activity( struct ap_activity* act )
{
printf( "Handling %s\n", act->id );

@ -3,7 +3,9 @@
#include <stdbool.h>
struct http_request;
struct ap_activity;
bool route_inbox( struct http_request* req );
bool route_activity( struct ap_activity* act );
void process_inbox();

@ -269,21 +269,24 @@ struct account* account_fetch_from_uri( const char* uri )
snprintf( tmp_filename, 512, "%s.tmp", filename );
printf( "tmp_filename = %s\n", tmp_filename );
f = fopen(tmp_filename,"w");
if( !f ) {
printf( "Unable to open %s\n", tmp_filename );
FILE* tmp = fopen(tmp_filename,"w");
if( !tmp ) {
printf( "! Unable to open %s\n", tmp_filename );
return NULL;
}
long status_code = -1;
const void* request[] = {
HTTP_REQ_URL, uri,
HTTP_REQ_HEADER, "Accept: application/json",
HTTP_REQ_OUTFILE, f,
HTTP_REQ_OUTFILE, tmp,
HTTP_REQ_RESULT_STATUS, &status_code,
NULL,
};
if( !http_client_do( request ) ) {
printf( "Unable to fetch %s\n", uri );
printf( "! Unable to fetch %s\n", uri );
return NULL;
}
printf( "status_code = %d\n", status_code );
fclose(f);
rename(tmp_filename,filename);

@ -58,9 +58,11 @@ static bool context_reader( struct json_pull_parser* jpp, void* field_data, stru
}
static const char* langs[] = {
"und",
"en",
};
ctx->language = clang_unknown;
for( int i = 0; i < 1; ++i ) {
for( int i = 0; i < sizeof(langs)/sizeof(langs[0]); ++i ) {
printf( "candidate: %s ==? %s\n", langs[i], lang );
if( 0 == strcmp(langs[i],lang) ) {
ctx->language = i+1;
}

@ -4,6 +4,7 @@ enum context_language
{
clang_unspecified = 0,
clang_undefined = 1,
clang_en = 2,
clang_unknown = 999999,
};

@ -13,6 +13,8 @@
#include "ffdb/hash_index.h"
#include "sha256/sha256.h"
#include "collections/array.h"
#include "http/client/client.h"
#include "format.h"
#include <stdio.h>
#include <string.h>
@ -83,6 +85,96 @@ struct status* status_from_uri( const char* uri )
return status_from_id(id);
}
static bool status_sync_from_activity_pub( struct status* s, struct ap_activity* act )
{
bool result = false;
struct account* a = account_from_uri(act->actor);
if( !a ) {
printf( "! Unable to get account for %s\n", act->actor );
goto failed;
}
s->account_id = a->id;
s->published = act->published;
s->remote = true;
s->source = strdup(act->source);
s->url = strdup( act->id );
status_save(s);
result = true;
cleanup:
account_free(a);
return result;
failed:
result = false;
goto cleanup;
};
struct status* status_fetch_from_uri( const char* uri )
{
struct ap_activity* act = NULL;
FILE* f = NULL;
struct status* s = status_from_uri(uri);
if( !s ) {
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
s->remote = true;
s->stub = true;
status_save_new(s);
hash_index_set( "data/statuses/uri", uri, s->id );
}
// Fetch the object from the remote server
char filename[512];
snprintf( filename, sizeof(filename), "data/statuses/%d.ap.json", s->id );
f = fopen(filename,"r");
if( !f ) {
printf( "* Fetching %s\n", uri );
char tmp_filename[512];
FILE* f = fopen(format(tmp_filename,512,"%s.tmp",filename),"w");
long status_code = -1;
const void* request[] = {
HTTP_REQ_URL, uri,
HTTP_REQ_HEADER, "Accept: application/ld+json",
HTTP_REQ_OUTFILE, f,
HTTP_REQ_RESULT_STATUS, &status_code,
NULL,
};
if( !http_client_do( request ) ) {
printf( "! Unable to fetch %s\n", uri );
return NULL;
}
printf( "status_code = %d\n", status_code );
if( status_code != 200 ) {
return NULL;
}
rename(tmp_filename,filename);
}
f = fopen(filename,"r");
if( !f ) { return NULL; }
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
// Load the activity and sync status
act = ap_activity_from_FILE(f); f = NULL;
if( !act ) { goto failed; }
if( !status_sync_from_activity_pub(s,act) ) { goto failed; }
cleanup:
if( f ) { fclose(f); }
ap_activity_free(act);
return s;
failed:
status_free(s);
s = NULL;
goto cleanup;
}
struct status* status_new_system_unfollow( int account_id )
{
struct account* a = account_from_id(account_id);
@ -126,14 +218,10 @@ struct status* status_from_activity( struct ap_activity* act )
s = malloc(sizeof(*s));
memset(s,0,sizeof(*s));
struct account* a = account_from_uri(act->actor);
s->account_id = a->id;
s->published = act->published;
s->remote = true;
s->source = strdup(act->source);
//s->content = status_render_source(s);
s->url = strdup( act->id );
if( !status_sync_from_activity_pub(s,act) ) {
status_free(s);
return NULL;
}
return s;
}

@ -54,6 +54,7 @@ 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 status* status_from_uri( const char* uri );
struct status* status_fetch_from_uri( const char* uri );
struct ap_activity;
struct status* status_from_activity( struct ap_activity* act );

Loading…
Cancel
Save