require 'Res/FastVoltMarkdown.php';
use FastVolt\Helper\Markdown;
$markdown = Markdown::new();
$instance = 'https://memos.octt.eu.org';
$footer = "";
$id = $_GET['id'];
$uid = $_GET['uid'];
function uidfromdata ( $data ) {
return explode( '%', explode( '%12%16', urlencode($data) )[1] )[0];
}
if ( !$id && !$uid ) {
// when no memo is specified, show links to the latest ones
// the JSON API won't list memos without auth, so we (mis)use the GRPC one
$memos = array_slice( explode( "\n\tmemos/", file_get_contents( "{$instance}/memos.api.v1.MemoService/ListMemos", false, stream_context_create([ 'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/grpc-web+proto',
'content' => urldecode('%00%00%00%008%08%10%1A4row_status%20%3D%3D%20%22NORMAL%22%20%26%26%20visibilities%20%3D%3D%20%5B\'PUBLIC\'%5D'),
]]) ) ), 1 );
$titletitle = '
Latest public memos';
if ( $_GET['rss'] ) {
header('Content-Type: application/rss+xml; charset=utf-8');
echo '';
echo "{$titletitle}{$instance}";
foreach ( $memos as $memo ) {
if ( ($uid = uidfromdata($memo)) ) {
echo "- {$uid}{$instance}/m/{$uid}
";
}
}
echo '';
} else {
echo "{$titletitle}Latest public memos from {$instance}:
";
foreach ( $memos as $memo ) {
if ( ($uid = uidfromdata($memo)) ) {
//$user = explode( '*', explode( 'users/', $memo )[1] )[0];
echo "- ${uid}
";
}
}
echo "
{$footer}";
}
return;
}
// pre-v0.22.4
//if ( !$id ) {
// // as of writing this, there is no JSON API to get a memo by its uid
// // so, we first get the numeric id by sloppily parsing the GRPC API
// $id = explode( '%', urlencode(explode( 'memos/', file_get_contents( "{$instance}/memos.api.v1.MemoService/SearchMemos", false, stream_context_create([ 'http' => [
// 'method' => 'POST',
// 'header' => 'Content-Type: application/grpc-web+proto',
// 'content' => urldecode('%00%00%00%00!%0A%1Fuid%20%3D%3D%20%22' . $uid . '%22'),
// ]]) ) )[1]))[0];
//}
$base = file_get_contents($instance);
$warning = '';
if ( $_GET['structure'] === 'original' ) {
$warning = '';
}
// pre-v0.22.4
//if ( !$id ) {
// http_response_code(400);
// echo $base;
// return;
//}
// pre-v0.22.4: we always use the numeric id to get memo data via the JSON API
//$memo = json_decode(file_get_contents("{$instance}/api/v1/memos/{$id}"));
$idoruidendpoint = ($uid ? "memos:by-uid/{$uid}" : "memos/{$id}");
$memo = json_decode(file_get_contents("{$instance}/api/v1/{$idoruidendpoint}")); // post-v0.22.4
$user = json_decode(file_get_contents("{$instance}/api/v1/{$memo->creator}"));
// patch Markdown before parsing it, so output is quasi-consistent with Memos
$content = '';
$inblock = false;
$lines = explode( "\n", $memo->content );
foreach ( $lines as $line ) {
if ( str_starts_with( $line, '```' ) ) {
$inblock = !$inblock;
} else if ( !$inblock && str_starts_with( $line, '#' ) ) {
// prevent hashtags from being interpreted as headings
$firstword = explode( ' ', str_replace( "\t", ' ', $line ) )[0];
if ( $firstword !== '#' ) {
$content .= " {$firstword}";
$line = substr( $line, strlen($firstword) );
}
}
$content .= $line . "\n";
if ( !$inblock ) {
// the parser won't support Markdown natural-linebreak mode, so add \n's
$content .= "\n";
}
}
$markdown->setContent($content);
$content = $markdown->toHtml();
$htmlparts = explode( '', $content );
$content = array_shift($htmlparts);
foreach ( $htmlparts as $part ) {
[$inside, $after] = explode( '
', $part );
//$content .= '' . $inside . '
' . $after;
$content .= '' . html_entity_decode($inside)) . '">' . $after;
}
$nickname = htmlspecialchars($user->nickname);
$pagetitle = "Memo by {$nickname}";
$pagedescription = htmlspecialchars($memo->content);
$htmlimage = implode( '', array_slice( explode( '"', implode( '', array_slice( explode( '
";
}
$meta = "
{$pagetitle}
{$htmlimage}
";
$body = "";
$base = str_replace( 'Memos', '', $base );
$base = str_replace( "", "{$meta}", $base );
$base = str_replace( "", "{$body}
", $base );
echo $base;