From c65003e3dbc1cd44ee742da5a15a859ece1b23c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?s=C3=B8renpeter?= Date: Tue, 26 Dec 2023 18:48:47 +0100 Subject: [PATCH 1/7] Gallery is now working, with some hickups still --- index.php | 2 +- libs/twtxt.php | 459 ++------------------------- partials/__img_posts.php | 51 +++ partials/header.php | 8 +- partials/profile.php | 14 +- partials/timeline.php | 2 +- style.css | 29 +- views/{profile.php => __profile.php} | 0 views/gallery.php | 61 ++-- 9 files changed, 148 insertions(+), 478 deletions(-) create mode 100644 partials/__img_posts.php rename views/{profile.php => __profile.php} (100%) diff --git a/index.php b/index.php index bddbf4d..5a00668 100644 --- a/index.php +++ b/index.php @@ -34,7 +34,7 @@ $routes = [ '/login' => 'login.php', '/logout' => 'logout.php', '/profile' => 'profile.php', - '/profile' => 'profile.php', + '/gallery' => 'gallery.php', //'/profile/([a-zA-Z0-9_-]+)' => 'profile.php', '/conv/([a-zA-Z0-9]{7})' => 'conv.php', // matches only twtHash of exactly 7 alphanumeric characters '/post/([a-zA-Z0-9]{7})' => 'post.php', // matches only twtHash of exactly 7 alphanumeric characters diff --git a/libs/twtxt.php b/libs/twtxt.php index dea66b5..a1f0af3 100644 --- a/libs/twtxt.php +++ b/libs/twtxt.php @@ -1,875 +1,452 @@ [ - 'peer_name' => 'generic-server', - 'verify_peer' => FALSE, - 'verify_peer_name' => FALSE, - 'allow_self_signed' => TRUE - ] - ] - ); - curl_setopt($curl, CURLOPT_SSLVERSION, 4); - */ - - /** - * The function searches for a key-value pair in a string and returns the value if found. - * - * @param keyToFind The key we want to find in the string. - * @param string The string in which to search for the key-value pair. - * - * @return the value of the key that matches the given keyToFind in the given string. If a match is - * found, the function returns the value of the key as a string after trimming any whitespace. If no - * match is found, the function returns null. - */ - function getSingleParameter($keyToFind, $string) { - if (!str_contains($string, $keyToFind)) { - return null; - } - - $pattern = '/\s*' . $keyToFind . '\s*=\s*([^#\n]+)/'; - //$pattern = '/\s*' . $keyToFind . '\s*=\s*([^\s#]+)/'; // Only matches the first word - preg_match($pattern, $string, $matches); - - if (isset($matches[1])) { - return trim($matches[1]); - } - - return null; - } - - function getDoubleParameter($keywordToFind, $string) { - // Returns string or null - $pattern = '/#\s*' . preg_quote($keywordToFind, '/') . '\s*=\s*(\S+)\s*(\S+)/'; - // Matches "# = " - preg_match($pattern, $string, $matches); - - if (isset($matches[1]) && isset($matches[2])) { - $result = array($matches[1], $matches[2]); - return $result; - } - - return null; - } - - function getReplyHashFromTwt(string $twtString): string { - // Extract the text between parentheses using regular expressions - $pattern = '/\(#([^\)]+)\)/'; // Matches "(#)" - preg_match($pattern, $twtString, $matches); - - if (isset($matches[1])) { - $textBetweenParentheses = $matches[1]; - return $textBetweenParentheses; - } - - return ''; - } - - -function getMentionsFromTwt(string $twtString) { - - $pattern = '/@<([^>]+)\s([^>]+)>/'; // Matches "@" - +function getImagesFromTwt(string $twtString) { + $pattern = '/(]+>)/i'; preg_match_all($pattern, $twtString, $matches, PREG_SET_ORDER); - - $result = array(); - - foreach ($matches as $match) { - - $nick = $match[1]; - - $url = $match[2]; - - $result[] = array("nick" => $nick, "url" => $url); - + $result[] = array($match[0]); } - - return $result; - } +function getMentionsFromTwt(string $twtString) { + $pattern = '/@<([^>]+)\s([^>]+)>/'; // Matches "@" + preg_match_all($pattern, $twtString, $matches, PREG_SET_ORDER); + $result = array(); + + foreach ($matches as $match) { + $nick = $match[1]; + $url = $match[2]; + $result[] = array("nick" => $nick, "url" => $url); + } + + return $result; +} function replaceMentionsFromTwt(string $twtString): string { - // Example input: 'Hello @, how are you? @'; - // Example output: Hello @eapl.mx@eapl.mx/twtxt.txt, how are you? @nick@server.com/something/twtxt.txt - - $pattern = '/@<([^ ]+)\s([^>]+)>/'; - //$replacement = '@$1'; - $replacement = '@$1'; $replacement .= ''; // Adds a hidden link direcly to the twtxt.txt of the mentioned target - #$twtString = '@'; - #$pattern = '/@<([^ ]+) ([^>]+)>/'; - #$replacement = '@$1'; - $result = preg_replace($pattern, $replacement, $twtString); - return $result; - - // from https://github.com/hxii/picoblog/blob/master/picoblog.php - //$pattern = '/\@<([a-zA-Z0-9\.]+)\W+(https?:\/\/[^>]+)>/'; - //return preg_replace($pattern,'@$1',$twtString); - } - - function replaceLinksFromTwt(string $twtString) { - - // TODO: Make this NOT match with `inline code` to avoid links in code-snippets - // 1. Look into how yarnd handles this - - // Regular expression pattern to match URLs - $pattern = '/(?$1'; - $result = preg_replace($pattern, $replacement, $twtString); - - return $result; - } - - function replaceMarkdownLinksFromTwt(string $twtString) { - $pattern = '/\[([^\]]+)\]\(([^)]+)\)/'; - - $replacement = '$1'; - $result = preg_replace($pattern, $replacement, $twtString); - - return $result; - } - - function replaceImagesFromTwt(string $twtString) { - $pattern = '/!\[(.*?)\]\((.*?)\)/'; - //$replacement = '$1'; - $replacement = '$1'; - $result = preg_replace($pattern, $replacement, $twtString); - - return $result; - } - - function replaceTagsFromTwt(string $twtString) { - $pattern = '/#(\w+)?/'; - $replacement = '#\1'; // Dummy link - //$replacement = '#${1}'; - $result = preg_replace($pattern, $replacement, $twtString); - - return $result; - } - - - function getTimeElapsedString($timestamp, $full = false) { - $now = new DateTime; - $ago = new DateTime; - $ago->setTimestamp($timestamp); - - $agoText = 'ago'; - if ($now < $ago) { - $agoText = 'in the future'; - } - - $diff = $now->diff($ago); - - //$diff->w = floor($diff->d / 7); - $w = floor($diff->d / 7); - $d = $diff->d - ($w * 7); - //$diff->d -= $diff->w * 7; - - $string = array( - 'y' => 'year', - 'm' => 'month', - 'w' => 'week', - 'd' => 'day', - 'h' => 'hour', - 'i' => 'minute', - 's' => 'second', - ); - foreach ($string as $k => &$v) { // k is key, and v is value... Obviously - if ($k === 'w') { - if ($w) { - $v = $w . ' ' . $v . ($w > 1 ? 's' : ''); - } else { - unset($string[$k]); - } - } else { - if ($diff->$k) { - $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : ''); - } else { - unset($string[$k]); - } - } - } - - if (!$full) $string = array_slice($string, 0, 1); - return $string ? implode(', ', $string) . " $agoText" : 'just now'; - } - - function getCachedFileContentsOrUpdate($fileURL, $cacheDurationSecs = 15) { - # TODO: Process the Warning - # Warning: file_get_contents(https://eapl.mx/twtxt.net): - # failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in - - $cacheFilePath = getCachedFileName($fileURL); - - // Check if cache file exists and it's not expired - if (file_exists($cacheFilePath) && (time() - filemtime($cacheFilePath)) < $cacheDurationSecs) { - return file_get_contents($cacheFilePath); - } - - // File doesn't exist in cache or has expired, so fetch and cache it - $contents = file_get_contents($fileURL); - file_put_contents($cacheFilePath, $contents); - - return $contents; - } - - function getCachedFileContents($filePath) { - $cacheFile = getCachedFileName($filePath); - - // Check if cache file exists and it's not expired - if (file_exists($cacheFile)) { - return file_get_contents($cacheFile); - } - - return null; - } - - function updateCachedFile($filePath, $cacheDurationSecs = 15) { - $cacheFilePath = getCachedFileName($filePath); - - // File doesn't exist in cache or has expired, so fetch and cache it - // TODO: Seems it's not working right! - $fileDoesntExist = !file_exists($cacheFilePath); - $fileIsOld = false; - if (!$fileDoesntExist) { - $fileIsOld = !((time() - filemtime($cacheFilePath)) < $cacheDurationSecs); - } - - if ($fileDoesntExist || $fileIsOld) { - #echo "Loading Cached file $cacheFilePath
\n"; - $contents = @file_get_contents($filePath); - - if ($contents === false) { - // File loaded with errors, skip saving it - return; - } - - file_put_contents($cacheFilePath, $contents); - } - } - - function getTwtsFromTwtxtString($url) { - $fileContent = getCachedFileContents($url); - - if (is_null($fileContent)) { - return null; - } - $fileContent = mb_convert_encoding($fileContent, 'UTF-8'); - - $fileLines = explode("\n", $fileContent); - - $twtxtData = new TwtxtFile(); - - foreach ($fileLines as $currentLine) { - // Remove empty lines - if (empty($currentLine)) { - continue; - } - - if (str_starts_with($currentLine, '#')) { - // Check if comments (starting with #) have some metadata - if (!is_null(getSingleParameter('url', $currentLine))) { - $currentURL = getSingleParameter('url', $currentLine); - - if (empty($twtxtData->URLs)) { - $twtxtData->mainURL = $currentURL; - } - $twtxtData->URLs[] = $currentURL; - } - if (!is_null(getSingleParameter('nick', $currentLine))) { - $twtxtData->nick = getSingleParameter('nick', $currentLine); - } - if (!is_null(getSingleParameter('avatar', $currentLine))) { - $twtxtData->avatar = getSingleParameter('avatar', $currentLine); - } - if (!is_null(getSingleParameter('emoji', $currentLine))) { - $twtxtData->emoji = getSingleParameter('emoji', $currentLine); - } - if (!is_null(getSingleParameter('lang', $currentLine))) { - $twtxtData->lang = getSingleParameter('lang', $currentLine); - } - if (!is_null(getSingleParameter('description', $currentLine))) { - $twtxtData->description = getSingleParameter('description', $currentLine); - // TODO - FIX BUG: only takes first word! - } - if (!is_null(getSingleParameter('follow', $currentLine))) { - $twtxtData->following[] = getSingleParameter('follow', $currentLine); - } - } - - if (!str_starts_with($currentLine, '#')) { - $explodedLine = explode("\t", $currentLine); - if (count($explodedLine) >= 2) { - $dateStr = $explodedLine[0]; - $twtContent = $explodedLine[1]; - - $twtContent = replaceMentionsFromTwt($twtContent); - - // Convert HTML problematic characters - //$twtContent = htmlentities($twtContent); // TODO: Messing up rendering of @mentions #BUG - - // Replace the Line separator character (U+2028) - // \u2028 is \xE2 \x80 \xA8 in UTF-8 - // Check here: https://www.mclean.net.nz/ucf/ - //$twtContent = str_replace("\xE2\x80\xA8", "
\n", $twtContent); - - // For some reason I was having trouble finding this nomenclature - // that's why I leave the UTF-8 representation for future reference - $twtContent = str_replace("\u{2028}", "\n
\n", $twtContent); - - //$twtContent = replaceMarkdownLinksFromTwt($twtContent); - //$twtContent = replaceImagesFromTwt($twtContent); - $twtContent = Slimdown::render($twtContent); - $twtContent = replaceLinksFromTwt($twtContent); // TODO: - - - // Get and remote the hash - + // Get and remove the hash $hash = getReplyHashFromTwt($twtContent); - if ($hash) { - $twtContent = str_replace("(#$hash)", '', $twtContent); - } - - // TODO: Make ?tag= filtering feature - //$twtContent = replaceTagsFromTwt($twtContent); - - // TODO: Get mentions - $mentions = getMentionsFromTwt($twtContent); - - // Get Lang metadata - - if (($timestamp = strtotime($dateStr)) === false) { - //echo "The string ($dateStr) is incorrect"; - // Incorrect date string, skip this twt - continue; - } else { - $displayDate = getTimeElapsedString($timestamp); - } - - // TODO: Only 1 twt by second is allowed here - $twt = new Twt(); - - $twt->originalTwtStr = $currentLine; - $twt->hash = getHashFromTwt($currentLine, $twtxtData->mainURL); - $twt->fullDate = date('j F Y h:i:s A', $timestamp) . ' (UTC)'; - $twt->displayDate = $displayDate; - $twt->content = $twtContent; - $twt->replyToHash = $hash; - $twt->mentions = $mentions; - $twt->avatar = $twtxtData->avatar; - $twt->emoji = $twtxtData->emoji; - $twt->nick = $twtxtData->nick; - $twt->mainURL = $twtxtData->mainURL; - - $twtxtData->twts[$timestamp] = $twt; - // TODO: Interpret the content as markdown -- @DONE using Slimdown.php above - } - } - } - - return $twtxtData; - } - - function insertFollowingURL($urlString) { - // Check if it's a valid URL - // Retrieve the nickname, if didn't find a nick, ask for one - - $originalCode = ' - Lorem ipsum dolor sit amet, - #~~~# - consectetur adipiscing elit.'; - - $text = '#~~~#'; - $newText = '123' . PHP_EOL . $text; - $result = str_replace('#~~~#', $newText, $originalCode); - - echo $result; - } - - function getCachedFileName($filePath) { - return __DIR__ . '/../private/cache/' . hash('sha256', $filePath); // TODO: make better path - } - - if (!function_exists('str_starts_with')) { - function str_starts_with($haystack, $needle) { - return (string)$needle !== '' && strncmp($haystack, $needle, strlen($needle)) === 0; - } - } - if (!function_exists('str_ends_with')) { - function str_ends_with($haystack, $needle) { - return $needle !== '' && substr($haystack, -strlen($needle)) === (string)$needle; - } - } - if (!function_exists('str_contains')) { - function str_contains($haystack, $needle) { - return $needle !== '' && mb_strpos($haystack, $needle) !== false; - } - } - diff --git a/partials/__img_posts.php b/partials/__img_posts.php new file mode 100644 index 0000000..2bc37d2 --- /dev/null +++ b/partials/__img_posts.php @@ -0,0 +1,51 @@ +'; + +foreach ($twts as $twt) { + $img_array = getImagesFromTwt($twt->content); + + foreach ($img_array as $img) { + //echo ''.$img[0].''; + // Workaround until cache issue is resolved + echo ''.$img[0].''; + } +} + +echo ''; + + +/* + +// old way from Pixelblog, for refernece/inspiration + +// Loop through each post and extract date and entry text: + +foreach ($img_posts as $post) { + + $date = preg_filter('/^(?[^\t]+)\t(?.+)/', '\1', $post); + $entry = preg_filter('/^(?[^\t]+)\t(?.+)/', '\2', $post); + $text_only = preg_filter('/!\[(.*?)\]\((.*?)\)/', '\1', $entry); // this gives the post without the markdown img links (not sure why, but it works) + $text_only = trim($text_only); + $text_only = strip_tags($text_only); + + preg_match_all('/!\[(?.*?)\]\((?.*?)\)/', $entry, $img_array); + //echo '
'; print_r($img_array);    echo '
'; // FOR DEBUGING + + foreach ($img_array['url'] as $img => $val) { + $url = $img_array['url'][$img]; + //$alt = $img_array['alt'][$img]; + echo ''.$text_only.''; + //echo '' . $text_only . ''; + + } +} + +*/ + +?> diff --git a/partials/header.php b/partials/header.php index 45a17a9..3e6b887 100644 --- a/partials/header.php +++ b/partials/header.php @@ -19,7 +19,7 @@ $profile = getTwtsFromTwtxtString($config['public_txt_url']);

- nick ?>@mainURL, PHP_URL_HOST); ?> + nick ?>@mainURL, PHP_URL_HOST); ?>