Initial GitHub+Gists support; Handle Pinterest pin.it links; First functional testing cases

This commit is contained in:
2025-05-27 15:51:46 +02:00
parent a92a670bf6
commit ca6adc35ba
2 changed files with 132 additions and 22 deletions

View File

@@ -50,7 +50,7 @@ define('USER_AGENT', "Proxatore/2025/1 ({$_SERVER['SERVER_NAME']})");
/*************************************/
//define('SCRIPT_NAME', $_SERVER['SCRIPT_NAME'] /* '/' */);
define('SCRIPT_NAME', ($_SERVER['SCRIPT_NAME'] === '/' ? $_SERVER['SCRIPT_NAME'] : "{$_SERVER['SCRIPT_NAME']}/"));
define('SCRIPT_NAME', ($_SERVER['SCRIPT_NAME'] === '/' ? '/' : "{$_SERVER['SCRIPT_NAME']}/"));
define('HISTORY_FILE', './Proxatore.history.jsonl');
// const OPTIONS_OVERRIDES = [
@@ -61,6 +61,8 @@ define('HISTORY_FILE', './Proxatore.history.jsonl');
const PLATFORMS = [
'spaccbbs' => ['bbs.spacc.eu.org'],
'github' => ['github.com'],
'github-gist' => ['gist.github.com'],
'bilibili' => ['bilibili.com'],
'bluesky' => ['bsky.app'],
'facebook' => ['facebook.com', 'm.facebook.com'],
@@ -105,11 +107,15 @@ const PLATFORMS_PROXIES = [
];
const PLATFORMS_REDIRECTS = [
'pin.it' => 'pinterest',
'vm.tiktok.com' => 'tiktok',
'youtu.be' => 'youtube',
];
const PLATFORMS_API = [
'github-gist' => [
'tag' => 'article',
],
'spotify' => [
'id' => '__NEXT_DATA__',
'data' => [
@@ -150,6 +156,13 @@ const EMBEDS = [
'reddit' => ['embed.reddit.com'],
];
const EMBEDS_COMPLEX = [
'github-gist' => [
'prefix' => 'data:text/html;charset=utf-8,<script src="',
'suffix' => '.js"></script>',
],
];
const EMBEDS_API = [
'soundcloud' => [
'meta' => 'twitter:player',
@@ -309,6 +322,8 @@ function makeEmbedUrl(string $platform, string $relativeUrl, array $meta=null):
$url = EMBEDS_PREFIXES_FULL[$platform] . urlencode($relativeUrl);
} else if ($api = (EMBEDS_API[$platform] ?? null)) {
return $meta[$api['meta']];
//} else if ($api = EMBEDS_COMPLEX[$platform] ?? null) {
//return $api['prefix'] . $relativeUrl . $api['suffix'];
} else {
$url = (EMBEDS[$platform][0] ?? PLATFORMS[$platform][0] ?? PLATFORMS_PROXIES[$platform][0] ?? $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? '');
}
@@ -566,11 +581,16 @@ function fetchPageMedia(array &$item): void {
$relativeUrl = $item['result']['relativeurl'];
if ($api = platformMapGet($platform, PLATFORMS_API)) {
$json = null;
if (isset($api['url'])) {
$json = fetchContent($api['url'] . urlLast($relativeUrl))['body'];
} else if (isset($api['id'])) {
if ($apiUrl = $api['url'] ?? null) {
$json = fetchContent($apiUrl . urlLast($relativeUrl))['body'];
} else {
$doc = htmldom(fetchContent(makeEmbedUrl($platform, $relativeUrl, $item['meta']))['body']);
$json = $doc->getElementById($api['id'])->textContent;
if ($id = $api['id'] ?? null) {
$json = $doc->getElementById($id)->textContent;
} else if ($tag = $api['tag'] ?? null) {
$item['result']['description'] = $doc->getElementsByTagName($tag)[0]->textContent;
return;
}
}
$data = json_decode($json, true);
$values = [];
@@ -1071,23 +1091,6 @@ ul.platforms a {
and to view them with a clean and streamlined interface, that works well on both modern systems and old browsers or slow connections.
<br />Additionally, it allows you to share links between social media platforms, ensuring link previews, which are often blocked by competitors, always display correctly.
</p>
<h3>How to self-host?</h3><p>
This software is free and open-source, and you can host it on your own server, for either private or public use.
</p>
<h4>Base requirements</h4><dl>
<dt>A web server with PHP</dt>
<dd>(Currently only tested on nginx with PHP 8.2 and IIS with PHP 8.3, as of May 2025.)</dd>
<dt><code>curl</code> and <code>mbstring</code> PHP extensions</dt>
<dd>The program requires these PHP extensions to be installed and enabled on the server to work.</dd>
</dl>
<h4>Optional requirements</h4><dl>
<dt>A dedicated domain name</dt>
<dd>To host the program properly, instead of in a subpath.</dd>
<dt><a href="https://github.com/yt-dlp/yt-dlp" target="_blank">yt-dlp</a> on your server</dt>
<dd>To stream videos from various platforms in MP4 format.</dd>
<dt>A <a href="https://github.com/imputnet/cobalt">cobalt</a> API server</dt>
<dd>To have a fallback for access to media files for the most popular platforms.</dd>
</dl>
</details>';
echo '<p>
Made with 🕸️ and 🧨 by <a href="https://hub.octt.eu.org">OctoSpacc</a>.

107
Tests.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
const PROXATORE_URL = 'https://proxatore.octt.eu.org/'; // getenv('PROXY_BASE_URL') ?: 'http://localhost';
const SEARCH_HEADING = '<h3>Search results:</h3>';
$tests = [
[
'name' => 'Search with "test" query',
'path' => '?proxatore-search=test',
'expectedContains' => [SEARCH_HEADING],
],
[
'name' => 'Search with inexistent term',
'path' => '?proxatore-search=ThisStringSaying'.uniqid('', true).'DoesNeverExist',
'expectedContains' => [SEARCH_HEADING, '<p>Nothing was found.</p>'],
],
// [
// 'name' => 'Invalid platform',
// 'path' => 'unknown/path',
// 'expectedContains' => ['No immediate results or search query provided.'],
// ],
];
$linkTests = [
[
'name' => 'YouTube 1',
'title' => 'Rick Astley - Never Gonna Give You Up (Official Music Video)',
'path' => 'youtube.com/watch?v=dQw4w9WgXcQ',
],
[
'name' => 'YouTube 2',
'title' => 'Me at the zoo',
'path' => 'youtube.com/watch?v=jNQXAC9IVRw',
],
[
'name' => 'Pinterest 1',
'path' => 'pinterest.com/pin/305118943524103084',
],
[
'name' => 'Telegram Image 1',
'title' => 'Pavel Durov',
'path' => 'telegram.me/durov/6',
],
[
'name' => 'Telegram Image+Text 1',
'path' => 'telegram.me/SpaccInc/7',
'expectedContains' => ['Simple spacc from yesterday, my USB wall charger is definitely close to breaking completely.'],
],
];
foreach ($linkTests as $test) {
$path = explode('/', ltrim($test['path'], '/'));
$platform = implode('.', array_slice(explode('.', reset($path)), 0, -1));
$realPath = "{$platform}/" . implode('/', array_slice($path, 1));
$tests[] = [ ...$test, 'path' => "http://{$test['path']}", 'expectedRedirect' => $realPath ];
$tests[] = [ ...$test, 'path' => "https://{$test['path']}", 'expectedRedirect' => $realPath ];
$tests[] = [ ...$test, 'expectedRedirect' => $realPath ];
$tests[] = [ ...$test, 'path' => $realPath ];
}
$allPassed = true;
foreach ($tests as $test) {
if (!isset($test['expectedCode'])) {
$test['expectedCode'] = (isset($test['expectedRedirect']) ? 302 : 200);
}
$url = rtrim(PROXATORE_URL, '/') . '/' . $test['path'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
$passed = true;
$messages = [];
if ($code !== $test['expectedCode']) {
$passed = false;
$messages[] = "Expected HTTP code {$test['expectedCode']}, got $code.";
}
if ($code !== 0 && $test['expectedCode'] !== 302) {
foreach ($test['expectedContains'] ?? (($test['title'] ?? null) ? [$test['title']] : []) as $substr) {
if (strpos($body, $substr) === false) {
$passed = false;
$messages[] = "Response body did not contain '$substr'.";
}
}
} else {
$messages[] = $error;
}
$status = $passed ? '✅ PASS' : '❌ FAIL';
$name = $test['name'] . (($test['title'] ?? null) ? ": {$test['title']}" : null);
echo "[{$status}] {$name} <{$test['path']}>\n";
if (!$passed) {
foreach ($messages as $msg) {
echo " - $msg\n";
}
$allPassed = false;
}
}
exit($allPassed ? 0 : 1);