You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.5 KiB
C
120 lines
2.5 KiB
C
#include "model/status.h"
|
|
|
|
// Submodules
|
|
#include "collections/array.h"
|
|
#include "util/format.h"
|
|
|
|
// Model
|
|
#include "model/account.h"
|
|
#include "model/emoji.h"
|
|
|
|
// Standard Library
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <strings.h>
|
|
#include <ctype.h>
|
|
|
|
char* status_render_source( struct status* s )
|
|
{
|
|
if( s->content ) {
|
|
goto done;
|
|
}
|
|
if( !s->source ) {
|
|
s->content = strdup("");
|
|
goto done;
|
|
}
|
|
|
|
char account_server[50]; {
|
|
struct account* status_account = account_from_id(s->account_id);
|
|
strncpy( account_server, status_account->server, 50 );
|
|
account_free(status_account);
|
|
}
|
|
|
|
char* result = NULL;
|
|
size_t size = 0;
|
|
FILE* f = open_memstream(&result,&size);
|
|
|
|
for( char* i = s->source; *i; ++i ) {
|
|
|
|
// Handle URLs
|
|
if( 0 == strncmp( i, "https://", 8 ) ) {
|
|
char* start = i;
|
|
while( *i && !index(" ,\r\n\t",*i) ) ++i;
|
|
|
|
char* url = strndup( start, i - start );
|
|
fprintf( f, "<a href='%s' rel='ugc'>%s</a>", url, url );
|
|
free(url);
|
|
} else if( isalpha(i[1]) && *i == '@' ) {
|
|
char* start = i;
|
|
while( *i && !index(" ,\r\n",*i) ) ++i;
|
|
char* handle = strndup( start, i - start );
|
|
|
|
struct account* user = account_from_webfinger( &handle[1] );
|
|
if( !user ) {
|
|
char buffer[512];
|
|
format( buffer, 512, "%s@%s", handle, account_server );
|
|
user = account_from_webfinger( &handle[1] );
|
|
}
|
|
|
|
if( user ) {
|
|
status_add_mention( s, user->id );
|
|
|
|
fprintf( f,
|
|
"<span class='h-card'>"
|
|
"<a class='u-url mention' href='%s' rel='ugc'>"
|
|
"@<span>%s</span>"
|
|
"</a>"
|
|
"</span>",
|
|
user->account_url, user->handle
|
|
);
|
|
account_free(user);
|
|
} else {
|
|
fprintf( f, "%s", handle );
|
|
}
|
|
free(handle);
|
|
} else if( *i == ':' ) {
|
|
// Emoji
|
|
++i;
|
|
char* start = i;
|
|
while( *i && !index(" ,:",*i) ) ++i;
|
|
|
|
char* shortcode = strndup( start, i - start );
|
|
|
|
// Check if shortcode is already present in status
|
|
for( int i = 0; i < s->emoji.count; ++i ) {
|
|
struct emoji* e = s->emoji.items[i];
|
|
if( 0 == strcmp( e->shortcode, shortcode ) ) { goto already_has_emoji; }
|
|
}
|
|
|
|
struct emoji* e = emoji_from_shortcode( shortcode );
|
|
if( e ) {
|
|
array_append( &s->emoji, sizeof(e), &e );
|
|
}
|
|
|
|
already_has_emoji:
|
|
fprintf( f, ":%s", shortcode );
|
|
free(shortcode);
|
|
} else if( *i == '\n' ) {
|
|
fprintf( f, "<br/>" );
|
|
continue;
|
|
} else if( *i == '\r' ) {
|
|
// Ignore
|
|
}
|
|
|
|
if( !*i ) { break; }
|
|
|
|
fputc( *i, f );
|
|
}
|
|
|
|
fputc( '\0', f );
|
|
fclose(f);
|
|
|
|
s->content = result;
|
|
|
|
done:
|
|
status_save(s);
|
|
return s->content;
|
|
}
|
|
|