mirror of
https://gitlab.com/octospacc/Snippets.git
synced 2025-06-27 09:02:56 +02:00
Replace Proxatore.php
This commit is contained in:
389
Proxatore.php
389
Proxatore.php
@ -1,5 +1,31 @@
|
|||||||
<?php
|
<?php
|
||||||
const APPNAME = '🎭️ Proxatore';
|
/*
|
||||||
|
* Proxatore, a content proxy for viewing and embedding media and text from various platforms.
|
||||||
|
* Copyright (C) 2025 OctoSpacc
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********** Configuration ***********/
|
||||||
|
|
||||||
|
const APP_NAME = '🎭️ Proxatore';
|
||||||
|
const APP_DESCRIPTION = 'a content proxy for viewing and embedding media and text from various platforms.';
|
||||||
|
|
||||||
|
// if you make changes to the source code, please modify this to point to your modified version
|
||||||
|
const SOURCE_CODE = 'https://hlb0.octt.eu.org/Drive/Misc/Scripts/Proxatore.php';
|
||||||
|
|
||||||
|
// cobalt API server URL; set to false or null or '' to avoid using cobalt
|
||||||
const COBALT_API = 'http://192.168.1.125:9010/';
|
const COBALT_API = 'http://192.168.1.125:9010/';
|
||||||
|
|
||||||
const OPTIONS_DEFAULTS = [
|
const OPTIONS_DEFAULTS = [
|
||||||
@ -8,13 +34,26 @@ const OPTIONS_DEFAULTS = [
|
|||||||
'htmlmedia' => false,
|
'htmlmedia' => false,
|
||||||
'relativemedia' => false,
|
'relativemedia' => false,
|
||||||
'mediaproxy' => false,
|
'mediaproxy' => false,
|
||||||
|
'viewmode' => 'normal',
|
||||||
];
|
];
|
||||||
|
|
||||||
const OPTIONS_OVERRIDES = [
|
const GOOGLE_VERIFICATION = 'HjNf-db8xb7lkRNgD3Q8-qeF1lWsbxmCZptRyjLBnrI';
|
||||||
'bbs.spacc.eu.org' => [
|
const BING_VERIFICATION = '45DC0FC265FF4059D48677970BE86150';
|
||||||
'embedfirst' => true,
|
|
||||||
],
|
define('USER_AGENT', "Proxatore/2025/1 ({$_SERVER['SERVER_NAME']})");
|
||||||
];
|
//define('USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0');
|
||||||
|
|
||||||
|
/*************************************/
|
||||||
|
|
||||||
|
//define('SCRIPT_NAME', $_SERVER['SCRIPT_NAME'] /* '/' */);
|
||||||
|
define('SCRIPT_NAME', ($_SERVER['SCRIPT_NAME'] === '/' ? $_SERVER['SCRIPT_NAME'] : "{$_SERVER['SCRIPT_NAME']}/"));
|
||||||
|
define('HISTORY_FILE', './Proxatore.history.jsonl');
|
||||||
|
|
||||||
|
// const OPTIONS_OVERRIDES = [
|
||||||
|
// 'bbs.spacc.eu.org' => [
|
||||||
|
// 'embedfirst' => true,
|
||||||
|
// ],
|
||||||
|
// ];
|
||||||
|
|
||||||
const PLATFORMS = [
|
const PLATFORMS = [
|
||||||
'spaccbbs' => ['bbs.spacc.eu.org'],
|
'spaccbbs' => ['bbs.spacc.eu.org'],
|
||||||
@ -22,6 +61,7 @@ const PLATFORMS = [
|
|||||||
'facebook' => ['facebook.com', 'm.facebook.com'],
|
'facebook' => ['facebook.com', 'm.facebook.com'],
|
||||||
'instagram' => ['instagram.com'],
|
'instagram' => ['instagram.com'],
|
||||||
//'juxt' => ['juxt.pretendo.network'],
|
//'juxt' => ['juxt.pretendo.network'],
|
||||||
|
'raiplay' => ['raiplay.it'],
|
||||||
'reddit' => ['old.reddit.com', 'reddit.com'],
|
'reddit' => ['old.reddit.com', 'reddit.com'],
|
||||||
'spotify' => ['open.spotify.com'],
|
'spotify' => ['open.spotify.com'],
|
||||||
'telegram' => ['t.me', 'telegram.me'],
|
'telegram' => ['t.me', 'telegram.me'],
|
||||||
@ -50,14 +90,23 @@ const PLATFORMS_PROXIES = [
|
|||||||
|
|
||||||
const PLATFORMS_REDIRECTS = [
|
const PLATFORMS_REDIRECTS = [
|
||||||
'vm.tiktok.com' => 'tiktok',
|
'vm.tiktok.com' => 'tiktok',
|
||||||
//'youtu.be' => 'youtube',
|
'youtu.be' => 'youtube',
|
||||||
];
|
];
|
||||||
|
|
||||||
const PLATFORMS_API = [
|
const PLATFORMS_API = [
|
||||||
'tiktok' => ['https://www.tiktok.com/player/api/v1/items?item_ids=', [
|
'spotify' => [
|
||||||
|
'id' => '__NEXT_DATA__',
|
||||||
|
'data' => [
|
||||||
|
'audio' => "['props']['pageProps']['state']['data']['entity']['audioPreview']['url']",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'tiktok' => [
|
||||||
|
'url' => 'https://www.tiktok.com/player/api/v1/items?item_ids=',
|
||||||
|
'data' => [
|
||||||
'description' => "['items'][0]['desc']",
|
'description' => "['items'][0]['desc']",
|
||||||
'video' => "['items'][0]['video_info']['url_list'][0]",
|
'video' => "['items'][0]['video_info']['url_list'][0]",
|
||||||
]],
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
const PLATFORMS_COBALT = ['instagram'];
|
const PLATFORMS_COBALT = ['instagram'];
|
||||||
@ -70,6 +119,8 @@ const PLATFORMS_ORDERED = ['telegram'];
|
|||||||
|
|
||||||
//const PLATFORMS_VIDEO = ['facebook', 'instagram'];
|
//const PLATFORMS_VIDEO = ['facebook', 'instagram'];
|
||||||
|
|
||||||
|
const PLATFORMS_WEBVIDEO = ['raiplay'];
|
||||||
|
|
||||||
const PLATFORMS_NOIMAGES = ['altervista.org', 'wordpress.com'];
|
const PLATFORMS_NOIMAGES = ['altervista.org', 'wordpress.com'];
|
||||||
|
|
||||||
const PLATFORMS_PARAMS = [
|
const PLATFORMS_PARAMS = [
|
||||||
@ -101,10 +152,6 @@ define('EMBEDS_PREFIXES_FULL', [
|
|||||||
'facebook' => 'www.facebook.com/plugins/post.php?href=' . urlencode('https://www.facebook.com/'),
|
'facebook' => 'www.facebook.com/plugins/post.php?href=' . urlencode('https://www.facebook.com/'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
define('APP_SLUG', explode(' ', APPNAME)[1]);
|
|
||||||
define('SCRIPT_NAME', /* $_SERVER['SCRIPT_NAME'] . */ '/');
|
|
||||||
define('HISTORY_FILE', './' . APP_SLUG . '.history.jsonl');
|
|
||||||
|
|
||||||
function normalizePlatform(string $platform): string {
|
function normalizePlatform(string $platform): string {
|
||||||
if (str_contains($platform, '.')) {
|
if (str_contains($platform, '.')) {
|
||||||
$platform = lstrip($platform, '.', -2); //implode('.', array_slice(explode('.', $platform), -2));
|
$platform = lstrip($platform, '.', -2); //implode('.', array_slice(explode('.', $platform), -2));
|
||||||
@ -131,18 +178,22 @@ function urlLast(string $url): string {
|
|||||||
function parseAbsoluteUrl(string $str) {
|
function parseAbsoluteUrl(string $str) {
|
||||||
$strlow = strtolower($str);
|
$strlow = strtolower($str);
|
||||||
if (str_starts_with($strlow, 'http://') || str_starts_with($strlow, 'https://')) {
|
if (str_starts_with($strlow, 'http://') || str_starts_with($strlow, 'https://')) {
|
||||||
return implode('://', array_slice(explode('://', $str), 1));
|
return lstrip($str, '://', 1); //implode('://', array_slice(explode('://', $str), 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function redirectTo($url): void {
|
function redirectTo($url): void {
|
||||||
if (!($absolute = parseAbsoluteUrl($url)) && !readProxatoreParam('history') /* && !(str_contains($url, '?proxatore-history=false') || str_contains($url, '&proxatore-history=false')) */) {
|
if (!($absolute = parseAbsoluteUrl($url)) && !readProxatoreBool('history') /* && !(str_contains($url, '?proxatore-history=false') || str_contains($url, '&proxatore-history=false')) */) {
|
||||||
parse_str(parse_url($url, PHP_URL_QUERY), $params);
|
parse_str(parse_url($url, PHP_URL_QUERY), $params);
|
||||||
if (!isset($params['proxatore-history'])) {
|
if (!isset($params['proxatore-history'])) {
|
||||||
$url = $url . (str_contains($url, '?') ? '&' : '?') . 'proxatore-history=false';
|
$url = $url . (str_contains($url, '?') ? '&' : '?') . 'proxatore-history=false';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if ($_SERVER['REQUEST_METHOD'] === 'GET' || $absolute) {
|
||||||
header('Location: ' . ($absolute ? '' : SCRIPT_NAME) . $url);
|
header('Location: ' . ($absolute ? '' : SCRIPT_NAME) . $url);
|
||||||
|
// } else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// echo postRequest(SCRIPT_NAME, 'proxatore-url=' . str_replace('?', '&', $url));
|
||||||
|
// }
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,17 +236,9 @@ function makeEmbedUrl(string $platform, string $relativeUrl): string {
|
|||||||
} else if (isset(EMBEDS_PREFIXES_FULL[$platform])) {
|
} else if (isset(EMBEDS_PREFIXES_FULL[$platform])) {
|
||||||
$url = EMBEDS_PREFIXES_FULL[$platform] . urlencode($relativeUrl);
|
$url = EMBEDS_PREFIXES_FULL[$platform] . urlencode($relativeUrl);
|
||||||
} else {
|
} else {
|
||||||
$url = (EMBEDS[$platform][0] ?: PLATFORMS[$platform][0] ?: PLATFORMS_PROXIES[$platform][0] ?: $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? '');
|
$url = (EMBEDS[$platform][0] ?? PLATFORMS[$platform][0] ?? PLATFORMS_PROXIES[$platform][0] ?? $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? '');
|
||||||
}
|
}
|
||||||
return "https://{$url}";
|
return "https://{$url}";
|
||||||
// switch ($platform) {
|
|
||||||
// case 'tiktok':
|
|
||||||
// return 'https://www.tiktok.com/embed/v3/' . urlLast($relativeUrl);
|
|
||||||
// case 'twitter':
|
|
||||||
// return 'https://platform.twitter.com/embed/Tweet.html?id=' . urlLast($relativeUrl);
|
|
||||||
// default:
|
|
||||||
// return 'https://' . (EMBEDS[$platform][0] ?: PLATFORMS_PROXIES[$platform][0] ?: PLATFORMS[$platform][0] ?: '') . '/' . $relativeUrl . (EMBEDS_SUFFIXES[$platform] ?? '');
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeScrapeUrl(string $platform, string $relativeUrl): string {
|
function makeScrapeUrl(string $platform, string $relativeUrl): string {
|
||||||
@ -237,7 +280,7 @@ function loadHistory(): array {
|
|||||||
return $history;
|
return $history;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveHistory($entry): void {
|
function saveHistory(array $entry): void {
|
||||||
if (inPlatformArray($entry['platform'], PLATFORMS_FAKE404)) {
|
if (inPlatformArray($entry['platform'], PLATFORMS_FAKE404)) {
|
||||||
$history = searchExactHistory($entry['platform'], implode('/', array_slice(explode('/', $entry['relativeurl']), -1)));
|
$history = searchExactHistory($entry['platform'], implode('/', array_slice(explode('/', $entry['relativeurl']), -1)));
|
||||||
if (sizeof($history)) {
|
if (sizeof($history)) {
|
||||||
@ -291,8 +334,10 @@ function searchExactHistory(string $platform, string $relativeUrl): array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function htmldom(string $body): DOMDocument {
|
function htmldom(string $body): DOMDocument {
|
||||||
|
libxml_use_internal_errors(true);
|
||||||
$doc = new DOMDocument();
|
$doc = new DOMDocument();
|
||||||
$doc->loadHTML(mb_convert_encoding($body, 'HTML-ENTITIES', 'UTF-8'));
|
$doc->loadHTML(mb_convert_encoding($body, 'HTML-ENTITIES', 'UTF-8'));
|
||||||
|
libxml_clear_errors();
|
||||||
return $doc;
|
return $doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +354,7 @@ function getAnyVideoUrl(string $txt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeResultObject(string $platform, string $relativeUrl, array $metaTags): array {
|
function makeResultObject(string $platform, string $relativeUrl, array $metaTags): array {
|
||||||
return [
|
$data = [
|
||||||
'platform' => $platform,
|
'platform' => $platform,
|
||||||
'relativeurl' => $relativeUrl,
|
'relativeurl' => $relativeUrl,
|
||||||
//'datetime' => date('Y-m-d H:i:s'),
|
//'datetime' => date('Y-m-d H:i:s'),
|
||||||
@ -317,13 +362,35 @@ function makeResultObject(string $platform, string $relativeUrl, array $metaTags
|
|||||||
'locale' => $metaTags['og:locale'] ?? '',
|
'locale' => $metaTags['og:locale'] ?? '',
|
||||||
'type' => $metaTags['og:type'] ?? '',
|
'type' => $metaTags['og:type'] ?? '',
|
||||||
'image' => $metaTags['og:image'] ?? '',
|
'image' => $metaTags['og:image'] ?? '',
|
||||||
'video' => $metaTags['og:video'] ?: $metaTags['og:video:url'] ?: '',
|
'video' => $metaTags['og:video'] ?? $metaTags['og:video:url'] ?? '',
|
||||||
'videotype' => $metaTags['og:video:type'] ?? '',
|
'videotype' => $metaTags['og:video:type'] ?? '',
|
||||||
'title' => $metaTags['og:title'] ?: $metaTags['og:title'] ?: '',
|
'htmlvideo' => $metaTags['og:video'] ?? $metaTags['og:video:url'] ?? '',
|
||||||
|
'audio' => $metaTags['og:audio'] ?? '',
|
||||||
|
'title' => $metaTags['og:title'] ?? $metaTags['og:title'] ?? '',
|
||||||
//'author' => $metaTags['og:site_name'] ?? '',
|
//'author' => $metaTags['og:site_name'] ?? '',
|
||||||
'description' => $metaTags['og:description'] ?: $metaTags['description'] ?: '',
|
'description' => $metaTags['og:description'] ?? $metaTags['description'] ?? '',
|
||||||
'images' => [],
|
'images' => [],
|
||||||
];
|
];
|
||||||
|
if (inPlatformArray($platform, PLATFORMS_WEBVIDEO) && !$data['video']) {
|
||||||
|
$data['video'] = makeCanonicalUrl($data);
|
||||||
|
$data['videotype'] = 'text/html';
|
||||||
|
}
|
||||||
|
if ($data['video'] && $data['videotype'] === 'text/html') {
|
||||||
|
$proxy = ((inPlatformArray($platform, PLATFORMS_WEBVIDEO) || readProxatoreBool('mediaproxy') || getQueryArray()['proxatore-mediaproxy'] === 'video') ? 'file' : '');
|
||||||
|
$data['htmlvideo'] = SCRIPT_NAME . "__{$proxy}proxy__/{$platform}/{$data['video']}";
|
||||||
|
if (readProxatoreBool('htmlmedia')) {
|
||||||
|
$data['video'] = $data['htmlvideo'];
|
||||||
|
$data['videotype'] = 'video/mp4';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// } else if (readProxatoreBool('mediaproxy') || getQueryArray()['proxatore-mediaproxy'] === 'video') {
|
||||||
|
// $data['htmlvideo'] = SCRIPT_NAME . "__mediaproxy__/{$platform}/{$data['video']}";
|
||||||
|
// if (readProxatoreBool('htmlmedia')) {
|
||||||
|
// $data['video'] = $data['htmlvideo'];
|
||||||
|
// $data['videotype'] = 'video/mp4';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeParamsRelativeUrl(string $platform, string $url): string {
|
function makeParamsRelativeUrl(string $platform, string $url): string {
|
||||||
@ -337,9 +404,18 @@ function makeParamsRelativeUrl(string $platform, string $url): string {
|
|||||||
return rtrim($url, '?&');
|
return rtrim($url, '?&');
|
||||||
}
|
}
|
||||||
|
|
||||||
function readBoolParam(string $key, $default=null, $array=null) {
|
function getQueryArray(): array {
|
||||||
|
// switch ($_SERVER['REQUEST_METHOD']) {
|
||||||
|
// case 'GET':
|
||||||
|
return $_GET;
|
||||||
|
// case 'POST':
|
||||||
|
// return $_POST;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBoolParam(string $key, bool|null $default=null, array $array=null) {
|
||||||
if (!$array) {
|
if (!$array) {
|
||||||
$array = $_GET;
|
$array = getQueryArray();
|
||||||
}
|
}
|
||||||
$value = $array[$key] ?? null;
|
$value = $array[$key] ?? null;
|
||||||
if ($value && $value !== '') {
|
if ($value && $value !== '') {
|
||||||
@ -349,11 +425,18 @@ function readBoolParam(string $key, $default=null, $array=null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readProxatoreParam(string $key, $array=null) {
|
function readProxatoreBool(string $key, array $array=null) {
|
||||||
return readBoolParam("proxatore-{$key}", OPTIONS_DEFAULTS[$key], $array);
|
return readBoolParam("proxatore-{$key}", OPTIONS_DEFAULTS[$key], $array);
|
||||||
// TODO handle domain HTTP referer overrides
|
// TODO handle domain HTTP referer overrides
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readProxatoreParam(string $key, array $array=null) {
|
||||||
|
if (!$array) {
|
||||||
|
$array = getQueryArray();
|
||||||
|
}
|
||||||
|
return ($array["proxatore-{$key}"] ?? OPTIONS_DEFAULTS[$key] ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
function getPageData($platform, $relativeUrl) {
|
function getPageData($platform, $relativeUrl) {
|
||||||
if ($platform && $relativeUrl && ($data = fetchContent(makeScrapeUrl($platform, $relativeUrl)))['body']) {
|
if ($platform && $relativeUrl && ($data = fetchContent(makeScrapeUrl($platform, $relativeUrl)))['body']) {
|
||||||
// if (!in_array($platform, PLATFORMS_TRACKING)) {
|
// if (!in_array($platform, PLATFORMS_TRACKING)) {
|
||||||
@ -374,15 +457,19 @@ function getPageData($platform, $relativeUrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function postRequest(string $url, string $body, array $headers=null): string|false {
|
||||||
|
return file_get_contents($url, false, stream_context_create(['http' => [
|
||||||
|
'header' => $headers,
|
||||||
|
'method' => 'POST',
|
||||||
|
'content' => $body,
|
||||||
|
]]));
|
||||||
|
}
|
||||||
|
|
||||||
function getCobaltVideo(string $url) {
|
function getCobaltVideo(string $url) {
|
||||||
$cobaltData = json_decode(file_get_contents(COBALT_API, false, stream_context_create(['http' => [
|
$cobaltData = json_decode(postRequest(COBALT_API, json_encode(['url' => $url]), [
|
||||||
'header' => [
|
|
||||||
'Accept: application/json',
|
'Accept: application/json',
|
||||||
'Content-Type: application/json',
|
'Content-Type: application/json',
|
||||||
],
|
]));
|
||||||
'method' => 'POST',
|
|
||||||
'content' => json_encode(['url' => $url]),
|
|
||||||
]])));
|
|
||||||
if ($cobaltData->status === 'redirect' && strpos($cobaltData->url, '.mp4')) {
|
if ($cobaltData->status === 'redirect' && strpos($cobaltData->url, '.mp4')) {
|
||||||
return $cobaltData->url;
|
return $cobaltData->url;
|
||||||
}
|
}
|
||||||
@ -393,9 +480,16 @@ function fetchPageMedia(string $url, array &$result): void {
|
|||||||
$relativeUrl = $result['relativeurl'];
|
$relativeUrl = $result['relativeurl'];
|
||||||
//if ((in_array($platform, PLATFORMS_VIDEO) && !$immediateResult['video']) || !$immediateResult['image']) {
|
//if ((in_array($platform, PLATFORMS_VIDEO) && !$immediateResult['video']) || !$immediateResult['image']) {
|
||||||
if ($api = platformMapGet($platform, PLATFORMS_API)) {
|
if ($api = platformMapGet($platform, PLATFORMS_API)) {
|
||||||
$data = json_decode(fetchContent($api[0] . urlLast($relativeUrl))['body'], true);
|
$json = null;
|
||||||
|
if (isset($api['url'])) {
|
||||||
|
$json = fetchContent($api['url'] . urlLast($relativeUrl))['body'];
|
||||||
|
} else if (isset($api['id'])) {
|
||||||
|
$doc = htmldom(fetchContent(makeEmbedUrl($platform, $relativeUrl))['body']);
|
||||||
|
$json = $doc->getElementById($api['id'])->textContent;
|
||||||
|
}
|
||||||
|
$data = json_decode($json, true);
|
||||||
$values = [];
|
$values = [];
|
||||||
foreach ($api[1] as $key => $query) {
|
foreach ($api['data'] as $key => $query) {
|
||||||
$values[$key] = eval("return \$data{$query};");
|
$values[$key] = eval("return \$data{$query};");
|
||||||
}
|
}
|
||||||
$result = array_merge($result, $values);
|
$result = array_merge($result, $values);
|
||||||
@ -406,7 +500,7 @@ function fetchPageMedia(string $url, array &$result): void {
|
|||||||
}
|
}
|
||||||
$html = fetchContent(makeEmbedUrl($platform, $relativeUrl))['body'];
|
$html = fetchContent(makeEmbedUrl($platform, $relativeUrl))['body'];
|
||||||
if (!$result['video']) {
|
if (!$result['video']) {
|
||||||
$result['video'] = $cobaltVideo ?? getAnyVideoUrl($html);
|
$result['video'] = $cobaltVideo ?? getAnyVideoUrl($html) ?? '';
|
||||||
}
|
}
|
||||||
if (!inPlatformArray($platform, PLATFORMS_NOIMAGES) /* !$immediateResult['image'] */) {
|
if (!inPlatformArray($platform, PLATFORMS_NOIMAGES) /* !$immediateResult['image'] */) {
|
||||||
$result['images'] = getHtmlAttributes($html, 'img', 'src');
|
$result['images'] = getHtmlAttributes($html, 'img', 'src');
|
||||||
@ -417,12 +511,38 @@ function fetchPageMedia(string $url, array &$result): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getYoutubeStreamUrl(string $relativeUrl): string {
|
function getWebStreamUrls(string $absoluteUrl, string $options='') {
|
||||||
if ($video = preg_replace("/[^A-Za-z0-9-_]/", '', escapeshellarg(substr($relativeUrl, -11)))) {
|
if (($url = parseAbsoluteUrl($absoluteUrl)) && ($url = preg_replace('/[^A-Za-z0-9-_\/\.]/', '', $url))) {
|
||||||
return trim(shell_exec("yt-dlp -g '{$video}'"));
|
return explode("\n", trim(shell_exec("yt-dlp {$options} -g 'https://{$url}'")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getYoutubeStreamUrl(string $relativeUrl): string {
|
||||||
|
if ($video = preg_replace('/[^A-Za-z0-9-_]/', '', substr($relativeUrl, -11))) {
|
||||||
|
return getWebStreamUrls("https://youtu.be/{$video}", '-f mp4')[0]; //trim(shell_exec("yt-dlp -g 'https://youtube.com/watch?v={$video}'"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ffmpegStream(string $absoluteUrl): void {
|
||||||
|
if ($urls = getWebStreamUrls($absoluteUrl, '--user-agent "' . USER_AGENT . '"')) {
|
||||||
|
$inputs = '';
|
||||||
|
foreach ($urls as $url) {
|
||||||
|
$inputs .= " -i '{$url}' ";
|
||||||
|
}
|
||||||
|
header('Content-Type: video/mp4');
|
||||||
|
passthru("ffmpeg -user_agent '" . USER_AGENT . "' {$inputs} -c:v copy -f ismv -");
|
||||||
|
}
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// function ytdlpStream(string $absoluteUrl): void {
|
||||||
|
// if (($url = parseAbsoluteUrl($absoluteUrl)) && ($url = preg_replace('/[^A-Za-z0-9-_\/\.]/', '', $url))) {
|
||||||
|
// header('Content-Type: video/mp4');
|
||||||
|
// passthru("yt-dlp -f mp4 -o - 'https://{$url}' | ffmpeg -i - -c:v copy -f ismv -");
|
||||||
|
// }
|
||||||
|
// die();
|
||||||
|
// }
|
||||||
|
|
||||||
// TODO: redesign the endpoint names, they're kind of a mess
|
// TODO: redesign the endpoint names, they're kind of a mess
|
||||||
function handleApiRequest(array $segments): void {
|
function handleApiRequest(array $segments): void {
|
||||||
$api = substr($segments[0], 2, -2);
|
$api = substr($segments[0], 2, -2);
|
||||||
@ -438,15 +558,25 @@ function handleApiRequest(array $segments): void {
|
|||||||
header('Location: ' . $url);
|
header('Location: ' . $url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ($api === 'fileproxy' && $platform === 'youtube') {
|
} else if ($api === 'fileproxy') {
|
||||||
|
switch ($platform) {
|
||||||
|
case 'youtube':
|
||||||
header('Content-Type: video/mp4');
|
header('Content-Type: video/mp4');
|
||||||
readfile(getYoutubeStreamUrl($relativeUrl));
|
readfile(getYoutubeStreamUrl($relativeUrl));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ffmpegStream('https://' . PLATFORMS[$platform][0] . '/' . lstrip($relativeUrl, '/', 3));
|
||||||
|
}
|
||||||
} else if ($api === 'embed') {
|
} else if ($api === 'embed') {
|
||||||
header('Location: ' . makeEmbedUrl($platform, $relativeUrl));
|
header('Location: ' . makeEmbedUrl($platform, $relativeUrl));
|
||||||
}
|
}
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function linkifyUrls(string $text): string {
|
||||||
|
return preg_replace('/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', '<a href="$0" target="_blank" rel="noopener nofollow" title="$0">$0</a>', $text);
|
||||||
|
}
|
||||||
|
|
||||||
function iframeHtml($result): void { ?>
|
function iframeHtml($result): void { ?>
|
||||||
<?php if (inPlatformArray($result['platform'], PLATFORMS_ORDERED)): ?>
|
<?php if (inPlatformArray($result['platform'], PLATFORMS_ORDERED)): ?>
|
||||||
<div>
|
<div>
|
||||||
@ -454,13 +584,13 @@ function iframeHtml($result): void { ?>
|
|||||||
<a class="button" style="float:right;" href="<?= end(explode('/', $result['relativeurl']))+1 ?>">➡️ Next</a>
|
<a class="button" style="float:right;" href="<?= end(explode('/', $result['relativeurl']))+1 ?>">➡️ Next</a>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<iframe src="<?= htmlspecialchars(makeEmbedUrl($result['platform'], $result['relativeurl'])) ?>"></iframe>
|
<iframe src="<?= htmlspecialchars(makeEmbedUrl($result['platform'], $result['relativeurl'])) ?>" hidden="hidden" onload="this.hidden=false;"></iframe>
|
||||||
<?php }
|
<?php }
|
||||||
|
|
||||||
$path = $_SERVER['REQUEST_URI']; //parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
$path = lstrip($_SERVER['REQUEST_URI'], SCRIPT_NAME, 1); //$_SERVER['REQUEST_URI']; //parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
$immediateResult = null;
|
$immediateResult = null;
|
||||||
|
|
||||||
if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !== '') {
|
if (isset(getQueryArray()['proxatore-search']) && ($search = getQueryArray()['proxatore-search']) !== '') {
|
||||||
if ($url = parseAbsoluteUrl($search)) {
|
if ($url = parseAbsoluteUrl($search)) {
|
||||||
return redirectTo($url);
|
return redirectTo($url);
|
||||||
} else {
|
} else {
|
||||||
@ -474,9 +604,9 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
}
|
}
|
||||||
|
|
||||||
$segments = explode('/', $path);
|
$segments = explode('/', $path);
|
||||||
if (SCRIPT_NAME !== '/') {
|
// if (SCRIPT_NAME !== '/') {
|
||||||
array_shift($segments);
|
// array_shift($segments);
|
||||||
}
|
// }
|
||||||
|
|
||||||
$platform = null;
|
$platform = null;
|
||||||
$upstream = $segments[0] ?? null;
|
$upstream = $segments[0] ?? null;
|
||||||
@ -498,13 +628,15 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
return redirectTo($platform . '/' . $relativeUrl);
|
return redirectTo($platform . '/' . $relativeUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unset($platform);
|
//unset($platform);
|
||||||
|
$platform = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$platform && isset(PLATFORMS_REDIRECTS[$upstream])) {
|
if (!$platform && isset(PLATFORMS_REDIRECTS[$upstream])) {
|
||||||
// TODO: only strip query params for platforms that don't need them
|
// // TODO: only strip query params for platforms that don't need them
|
||||||
$relativeUrl = trim(parse_url(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], PHP_URL_PATH), '/');
|
//$relativeUrl = trim(parse_url(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], PHP_URL_PATH), '/');
|
||||||
|
$relativeUrl = trim(lstrip(fetchContent("{$upstream}/{$relativeUrl}", 1)['url'], '/', 3), '/');
|
||||||
$platform = PLATFORMS_REDIRECTS[$upstream];
|
$platform = PLATFORMS_REDIRECTS[$upstream];
|
||||||
return redirectTo("{$platform}/{$relativeUrl}");
|
return redirectTo("{$platform}/{$relativeUrl}");
|
||||||
} else if (!$platform) {
|
} else if (!$platform) {
|
||||||
@ -520,26 +652,26 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
if ($data = getPageData($platform, $relativeUrl)) {
|
if ($data = getPageData($platform, $relativeUrl)) {
|
||||||
http_response_code($data['code']);
|
http_response_code($data['code']);
|
||||||
$immediateResult = $data['result'];
|
$immediateResult = $data['result'];
|
||||||
if ($immediateResult['video'] && $immediateResult['videotype'] === 'text/html' && readProxatoreParam('htmlmedia')) {
|
//if ($immediateResult['video'] && $immediateResult['videotype'] === 'text/html' && readProxatoreBool('htmlmedia')) {
|
||||||
$proxy = ((readProxatoreParam('mediaproxy') || $_GET['proxatore-mediaproxy'] === 'video') ? 'file' : '');
|
// $proxy = ((readProxatoreBool('mediaproxy') || getQueryArray()['proxatore-mediaproxy'] === 'video') ? 'file' : '');
|
||||||
$immediateResult['video'] = SCRIPT_NAME . "__{$proxy}proxy__/{$platform}/{$immediateResult['video']}";
|
// $immediateResult['video'] = SCRIPT_NAME . "__{$proxy}proxy__/{$platform}/{$immediateResult['video']}";
|
||||||
$immediateResult['videotype'] = 'video/mp4';
|
// $immediateResult['videotype'] = 'video/mp4';
|
||||||
}
|
//}
|
||||||
fetchPageMedia($data['url'], $immediateResult);
|
fetchPageMedia($data['url'], $immediateResult);
|
||||||
//}
|
//}
|
||||||
//if ($immediateResult['title'] || $immediateResult['description']) {
|
//if ($immediateResult['title'] || $immediateResult['description']) {
|
||||||
// saveHistory($immediateResult);
|
// saveHistory($immediateResult);
|
||||||
//} else
|
//} else
|
||||||
if ($content['code'] >= 400) {
|
if ($data['code'] >= 400) {
|
||||||
$searchResults = searchExactHistory($platform, $immediateResult['relativeurl']);
|
$searchResults = searchExactHistory($platform, $immediateResult['relativeurl']);
|
||||||
if (sizeof($searchResults)) {
|
if (sizeof($searchResults)) {
|
||||||
$immediateResult = $searchResults[0];
|
$immediateResult = $searchResults[0];
|
||||||
}
|
}
|
||||||
} else if (readProxatoreParam('history')) {
|
} else if (readProxatoreBool('history')) {
|
||||||
saveHistory($immediateResult);
|
saveHistory($immediateResult);
|
||||||
}
|
}
|
||||||
$immediateResult['description'] = preg_replace('/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', '<a href="$0" target="_blank" rel="noopener nofollow" title="$0">$0</a>', $immediateResult['description']);
|
$immediateResult['description'] = linkifyUrls($immediateResult['description']);
|
||||||
if (readProxatoreParam('relativemedia')) {
|
if (readProxatoreBool('relativemedia')) {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
foreach (['video', 'image'] as $type) {
|
foreach (['video', 'image'] as $type) {
|
||||||
if ($immediateResult[$type]) {
|
if ($immediateResult[$type]) {
|
||||||
@ -549,7 +681,7 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$searchResults = [$immediateResult];
|
$searchResults = [$immediateResult];
|
||||||
} else {
|
} else if ($path) {
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,10 +691,10 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title><?= APPNAME ?></title>
|
<title><?= APP_NAME ?></title>
|
||||||
<meta name="description" content="<?= htmlspecialchars($immediateResult['description'] ?? 'Content Proxy for viewing media and text from various platforms.') ?>" />
|
<meta name="description" content="<?= htmlspecialchars($immediateResult['description'] ?? ucfirst(APP_DESCRIPTION)) ?>" />
|
||||||
<meta property="og:title" content="<?= htmlspecialchars($immediateResult['title'] ?? APPNAME) ?>" />
|
<meta property="og:title" content="<?= htmlspecialchars($immediateResult['title'] ?? APP_NAME) ?>" />
|
||||||
<meta property="og:description" content="<?= htmlspecialchars($immediateResult['description'] ?? 'View content from supported platforms.') ?>" />
|
<meta property="og:description" content="<?= htmlspecialchars($immediateResult['description'] ?? ucfirst(APP_DESCRIPTION)) ?>" />
|
||||||
<!--<meta property="og:locale" content="<?= htmlspecialchars($immediateResult['locale'] ?? '') ?>" />-->
|
<!--<meta property="og:locale" content="<?= htmlspecialchars($immediateResult['locale'] ?? '') ?>" />-->
|
||||||
<meta property="og:type" content="<?= htmlspecialchars($immediateResult['type'] ?? '') ?>" />
|
<meta property="og:type" content="<?= htmlspecialchars($immediateResult['type'] ?? '') ?>" />
|
||||||
<meta property="og:image" content="<?= htmlspecialchars($immediateResult['image'] ?? '') ?>" />
|
<meta property="og:image" content="<?= htmlspecialchars($immediateResult['image'] ?? '') ?>" />
|
||||||
@ -570,11 +702,17 @@ if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !=
|
|||||||
<meta property="og:video" content="<?= htmlspecialchars($immediateResult['video']) ?>" />
|
<meta property="og:video" content="<?= htmlspecialchars($immediateResult['video']) ?>" />
|
||||||
<meta property="og:video:type" content="<?= htmlspecialchars($immediateResult['videotype'] ?: 'video/mp4') ?>" />
|
<meta property="og:video:type" content="<?= htmlspecialchars($immediateResult['videotype'] ?: 'video/mp4') ?>" />
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<meta property="og:site_name" content="<?= APPNAME . ' ' . $immediateResult['platform'] ?>" />
|
<?php if ($immediateResult['audio']): ?>
|
||||||
|
<meta property="og:audio" content="<?= htmlspecialchars($immediateResult['audio']) ?>" />
|
||||||
|
<meta property="og:audio:type" content="audio/mpeg" />
|
||||||
|
<?php endif; ?>
|
||||||
|
<meta property="og:site_name" content="<?= APP_NAME . ' ' . ($immediateResult['platform'] ?? '') ?>" />
|
||||||
<meta property="og:url" content="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
<meta property="og:url" content="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
||||||
<link rel="canonical" href="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
<link rel="canonical" href="<?= htmlspecialchars(makeCanonicalUrl($immediateResult)) ?>" />
|
||||||
<!--<link rel="alternate" type="application/json+oembed" href="" />
|
<!--<link rel="alternate" type="application/json+oembed" href="" />
|
||||||
<link rel="alternate" type="application/xml+oembed" href="" />-->
|
<link rel="alternate" type="application/xml+oembed" href="" />-->
|
||||||
|
<meta name="google-site-verification" content="<?= GOOGLE_VERIFICATION ?>" />
|
||||||
|
<meta name="msvalidate.01" content="<?= BING_VERIFICATION ?>" />
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -596,14 +734,19 @@ iframe {
|
|||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
width: 90%;
|
|
||||||
margin: 20px;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
body.normal .container {
|
||||||
|
width: 90%;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
body.embed .container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
a.button {
|
a.button {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
@ -638,23 +781,27 @@ h2 {
|
|||||||
.history-item {
|
.history-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: 1px solid #e6e6e6;
|
}
|
||||||
|
body.normal .history-item {
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
}
|
}
|
||||||
.history-item:hover {
|
body.normal .history-item:hover {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
.history-item img, .history-item video, .history-item .video {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
.history-item img, .history-item video {
|
.history-item img, .history-item video {
|
||||||
/*width: 49%;
|
/*width: 49%;
|
||||||
max-width: 49%;*/
|
max-width: 49%;*/
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
/* max-width: 100px;
|
/* max-width: 100px;
|
||||||
max-height: 100px; */
|
max-height: 100px; */
|
||||||
margin-right: 15px;
|
/* margin-right: 15px; */
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
object-fit: cover;
|
/* object-fit: cover; */
|
||||||
}
|
}
|
||||||
.history-item div {
|
.history-item div {
|
||||||
/*display: flex;*/
|
/*display: flex;*/
|
||||||
@ -667,16 +814,22 @@ h2 {
|
|||||||
.img {
|
.img {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
img, video {
|
img, .video {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
img[src=""], video[src=""] {
|
img[src=""], video[src=""] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.img + .img,
|
.img + .img,
|
||||||
video:not(video[src=""]) + .img {
|
.video:not(video[src=""]) + .img {
|
||||||
max-width: 45% !important;
|
max-width: 45% !important;
|
||||||
}
|
}
|
||||||
|
.description {
|
||||||
|
white-space: preserve-breaks;
|
||||||
|
border-left: 2px solid black;
|
||||||
|
padding: 1em;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
.history-item strong {
|
.history-item strong {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
color: #1c1e21;
|
color: #1c1e21;
|
||||||
@ -779,42 +932,68 @@ ul.platforms a {
|
|||||||
} */
|
} */
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="<?= readProxatoreParam('viewmode'); ?>">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1><a href="<?= SCRIPT_NAME ?>"><?= APPNAME; ?></a></h1>
|
<?php if (readProxatoreParam('viewmode') !== 'embed'): ?>
|
||||||
<form method="get" action="<?= SCRIPT_NAME ?>">
|
<h1><a href="<?= SCRIPT_NAME ?>"><?= APP_NAME; ?></a></h1>
|
||||||
|
<form method="GET" action="<?= SCRIPT_NAME ?>">
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
<input type="text" required="required" name="proxatore-search" placeholder="Search or Input URL" value="<?= htmlspecialchars($_GET['proxatore-search'] ?: makeCanonicalUrl($immediateResult) ?: '') ?>">
|
<input type="text" required="required" name="proxatore-search" placeholder="Search or Input URL" value="<?= htmlspecialchars(getQueryArray()['proxatore-search'] ?? makeCanonicalUrl($immediateResult) ?: '') ?>">
|
||||||
<button type="submit">Go 💣️</button>
|
<button type="submit">Go 💣️</button>
|
||||||
</div>
|
</div>
|
||||||
<details style="margin-bottom: 20px;">
|
<details style="margin-bottom: 20px;">
|
||||||
<summary>Options</summary>
|
<summary>Options</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li><label><input type="checkbox" name="proxatore-history" value="false" <?php if ($_GET['proxatore-history'] === 'false') echo 'checked="true"' ?> /> Incognito Mode (don't save query to global cache/history)</label></li>
|
<li><label><input type="checkbox" name="proxatore-history" value="false" <?php if (!readProxatoreBool('history')) echo 'checked="checked"' ?> /> Incognito Mode (don't save query to global cache/history)</label></li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
</form>
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
<?php if (!isset($searchResults)) {
|
<?php if (!isset($searchResults)) {
|
||||||
$platforms = '';
|
$platforms = '';
|
||||||
$searchPrefix = (SCRIPT_NAME . '?proxatore-search=');
|
$searchPrefix = (SCRIPT_NAME . '?proxatore-search=');
|
||||||
echo '<p>Supported Platforms:</p><ul class="platforms">';
|
echo '<p>Supported Platforms:</p><ul class="platforms">';
|
||||||
foreach (array_keys(PLATFORMS) as $platform) {
|
foreach (array_keys(PLATFORMS) as $platform) {
|
||||||
//echo ((isset(PLATFORMS_ALIASES[$platform])) ? "/" : "</li><li>") . $platform;
|
|
||||||
$platforms .= ((isset(PLATFORMS_ALIASES[$platform])) ? '/' : "</a></li><li><a href='{$searchPrefix}\"platform\":\"{$platform}\"'>") . $platform;
|
$platforms .= ((isset(PLATFORMS_ALIASES[$platform])) ? '/' : "</a></li><li><a href='{$searchPrefix}\"platform\":\"{$platform}\"'>") . $platform;
|
||||||
}
|
}
|
||||||
foreach (PLATFORMS_USERSITES as $platform) {
|
foreach (PLATFORMS_USERSITES as $platform) {
|
||||||
$platforms .= "</a></li><li><a href='{$searchPrefix}.{$platform}\",\"relativeurl\"'>{$platform}";
|
$platforms .= "</a></li><li><a href='{$searchPrefix}.{$platform}\",\"relativeurl\"'>{$platform}";
|
||||||
}
|
}
|
||||||
echo substr($platforms, strlen('</a></li>')) . '</a></li></ul>';
|
echo substr($platforms, strlen('</a></li>')) . '</a></li></ul>';
|
||||||
// echo '<details><summary>Query API</summary><ul>
|
// echo '<details><summary>Query string API</summary><ul>
|
||||||
// <li>/?<code>proxatore-search=</code>{search term} — Make a full-text search or load a given URL</li>
|
// <li>/?<code>proxatore-search=</code>{search term} — Make a full-text search or load a given URL</li>
|
||||||
// <li>...?<code>proxatore-history=</code>{true,false} — Specify if a given query must be stored in the global search history (default: true)</li>
|
// <li>...?<code>proxatore-history=</code>{true,false} — Specify if a given query must be stored in the global search history (default: true)</li>
|
||||||
// </ul></details>';
|
// </ul></details>';
|
||||||
|
echo '<details><summary>Help & Info</summary>
|
||||||
|
<h3>What is this?</h3><p>
|
||||||
|
'.APP_NAME.' is '.APP_DESCRIPTION.'
|
||||||
|
<br />It allows you to bypass ratelimits and georestrictions when accessing contents from many specific Internet platforms,
|
||||||
|
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 YouTube videos 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 most platforms.</dd>
|
||||||
|
</dl>
|
||||||
|
</details>';
|
||||||
echo '<p>Made with 🕸️ and 🧨 by <a href="https://hub.octt.eu.org">OctoSpacc</a>.
|
echo '<p>Made with 🕸️ and 🧨 by <a href="https://hub.octt.eu.org">OctoSpacc</a>.
|
||||||
<small>Source Code: <a href="https://hlb0.octt.eu.org/Drive/Misc/Scripts/Proxatore.php">Proxatore.php</a>.</small>
|
<br /><small>Licensed under <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank">AGPLv3</a>. Source Code: <a href="' . SOURCE_CODE . '">Proxatore.php</a>.</small>
|
||||||
</p>';
|
</p>';
|
||||||
} ?>
|
} ?>
|
||||||
<?php if (isset($immediateResult) && readProxatoreParam('embedfirst')) iframeHtml($immediateResult); ?>
|
<?php if (isset($immediateResult) && readProxatoreBool('embedfirst') && readProxatoreParam('viewmode') !== 'embed') iframeHtml($immediateResult); ?>
|
||||||
<?php if (isset($searchResults)): ?>
|
<?php if (isset($searchResults)): ?>
|
||||||
<?php if (!isset($immediateResult)): ?>
|
<?php if (!isset($immediateResult)): ?>
|
||||||
<h3>Search results:</h3>
|
<h3>Search results:</h3>
|
||||||
@ -829,31 +1008,43 @@ ul.platforms a {
|
|||||||
?>">
|
?>">
|
||||||
<p class="title">
|
<p class="title">
|
||||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime']) ?> --></small>
|
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime'] ?? '') ?> --></small>
|
||||||
</p>
|
</p>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<?php if ($item['video'] /* $item['video'] && $item['videotype'] !== 'text/html' */): ?>
|
<?php if ($item['video'] && (isset($immediateResult) /* || !inPlatformArray($item['platform'], PLATFORMS_WEBVIDEO) */) /* $item['video'] && $item['videotype'] !== 'text/html' */): ?>
|
||||||
<video src="<?= htmlspecialchars($item['platform'] === 'youtube' ? (SCRIPT_NAME . '__proxy__/youtube/' . $immediateResult['video']) : ($item['video'] ?? '')) ?>" controls="controls"></video>
|
<div class="video">
|
||||||
|
<video src="<?= htmlspecialchars(/* $item['platform'] === 'youtube' ? (SCRIPT_NAME . '__proxy__/youtube/' . $item['video']) : ($item['video'] ?? '') */ $item['htmlvideo'] ?: $item['video']) ?>" controls="controls"></video>
|
||||||
|
<a class="button block" href="<?= htmlspecialchars($item['htmlvideo'] ?: $item['video']) ?>" download="<?= htmlspecialchars($item['title']); ?>" target="_blank" rel="noopener nofollow">Download video</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($item['audio']): ?>
|
||||||
|
<audio src="<?= htmlspecialchars($item['audio']) ?>" controls="controls"></audio>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php foreach (array_merge([$item['image']], $item['images']) as $image): ?>
|
<?php foreach (array_merge([$item['image']], $item['images']) as $image): ?>
|
||||||
<a class="img" href="<?= htmlspecialchars($image ?? '') ?>" target="_blank" rel="noopener nofollow"><img src="<?= htmlspecialchars($image ?? '') ?>" onerror="this.hidden=true" /></a>
|
<a class="img" href="<?= htmlspecialchars($image ?? '') ?>" target="_blank" rel="noopener nofollow">
|
||||||
|
<img src="<?= htmlspecialchars($image ?? '') ?>" onerror="this.hidden=true" />
|
||||||
|
</a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
<strong><?= htmlspecialchars($item['title']) ?></strong>
|
||||||
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime']) ?> --></small>
|
<small><?= htmlspecialchars($item['platform']) ?><!-- <?= htmlspecialchars($item['datetime'] ?? '') ?> --></small>
|
||||||
</p>
|
</p>
|
||||||
<p style="white-space: preserve-breaks; border-left: 2px solid black; padding: 1em; word-break: break-word;"><?= /*htmlspecialchars*/($item['description']) ?></p>
|
<?php if ($item['description']): ?><p class="description"><?= /*htmlspecialchars*/($item['description']) ?></p><?php endif; ?>
|
||||||
<p>
|
<p>
|
||||||
<a class="button block" href="<?= htmlspecialchars(makeCanonicalUrl($item)) ?>" target="_blank" rel="noopener nofollow">Original on <code><?= htmlspecialchars(PLATFORMS[$item['platform']][0] ?: $item['platform']) ?>/<?= htmlspecialchars($item['relativeurl']) ?></code></a>
|
<a class="button block" href="<?= htmlspecialchars(makeCanonicalUrl($item)) ?>" target="_blank" rel="noopener nofollow">
|
||||||
<a class="button block" href="<?= htmlspecialchars(SCRIPT_NAME . $item['platform'] . '/' . $item['relativeurl']) ?>"><?= APPNAME ?> Permalink</a>
|
Original on <code><?= htmlspecialchars(PLATFORMS[$item['platform']][0] ?: $item['platform']) ?>/<?= htmlspecialchars($item['relativeurl']) ?></code>
|
||||||
|
</a>
|
||||||
|
<a class="button block" href="<?= htmlspecialchars(SCRIPT_NAME . $item['platform'] . '/' . $item['relativeurl']) ?>" <?php if (readProxatoreParam('viewmode') === 'embed') echo 'target="_blank"'; ?> >
|
||||||
|
<?= readProxatoreParam('viewmode') === 'embed' ? ('Powered by ' . APP_NAME) : (APP_NAME . ' Permalink') ?>
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if (isset($immediateResult) && !readProxatoreParam('embedfirst')) iframeHtml($immediateResult); ?>
|
<?php if (isset($immediateResult) && !readProxatoreBool('embedfirst') && readProxatoreParam('viewmode') !== 'embed') iframeHtml($immediateResult); ?>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user