Split HTML head, PHP, added searching tags

This commit is contained in:
Pablo Ferreiro 2022-01-03 16:11:24 +01:00
parent 477efe8486
commit 340f500206
No known key found for this signature in database
GPG key ID: 41FBCE65B779FA24
17 changed files with 262 additions and 216 deletions

View file

@ -1 +1 @@
APP_SUBDIR=/ # Subpath your app is running, defaults to /
APP_SUBDIR=/ # Subpath your app is running, LEAVE EMPTY IF RUNNING FROM /

152
index.php
View file

@ -1,162 +1,16 @@
<?php
require __DIR__ . "/vendor/autoload.php";
require __DIR__ . "/helpers/domains.php";
require __DIR__ . "/helpers/settings_elements.php";
use Steampixel\Route;
// LOAD DOTENV
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// -- HELPERS -- //
function getSubdir(): string {
return $_ENV['APP_SUBDIR'] ? $_ENV['APP_SUBDIR'] : '';
return isset($_ENV['APP_SUBDIR']) && !empty($_ENV['APP_SUBDIR']) ? $_ENV['APP_SUBDIR'] : '';
}
function getApi(array $proxy_elements): \Sovit\TikTok\Api {
$options = [];
// Proxy config
if (in_array($proxy_elements, $_COOKIE)) {
foreach ($proxy_elements as $proxy_element) {
$options[$proxy_element] = $_COOKIE[$proxy_element];
}
}
$api = new \Sovit\TikTok\Api($options);
return $api;
}
function getLatte(): \Latte\Engine {
$subdir = getSubdir();
$latte = new Latte\Engine;
$latte->setTempDirectory('./cache/views');
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
$path = "{$subdir}/{$type}/{$name}";
return $path;
});
$latte->addFunction('path', function (string $name) use ($subdir) {
$path = "{$subdir}/{$name}";
return $path;
});
return $latte;
}
function getView(string $template): string {
return "./views/{$template}.latte";
}
Route::add('/', function () {
http_response_code(302);
header('Location: ./home');
});
Route::add('/home', function () {
$latte = getLatte();
$latte->render('./views/home.latte');
});
Route::add('/images', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['image'])) {
die('Not a valid URL');
}
$img = file_get_contents($url, false, stream_context_create(['http' => ['ignore_errors' => true]]));
if ($img) {
header('Content-Type: image/jpeg');
return $img;
} else {
return 'Error while getting image!';
}
});
Route::add('/audios', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['audio'])) {
die('Not a valid URL');
}
$audio = file_get_contents($url, false, stream_context_create(['http' => ['ignore_errors' => true]]));
if ($audio) {
header('Content-Type: audio/mp3');
return $audio;
} else {
return 'Error while getting audio!';
}
});
Route::add('/stream', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['video'])) {
die('Not a valid URL');
}
if (isset($_GET['download'])) {
header('Content-Disposition: attachment; filename="tiktok.mp4"');
}
$streamer = new \Sovit\TikTok\Stream();
$streamer->stream($url);
});
Route::add("/trending", function () use ($proxy_elements) {
$cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor'];
}
$latte = getLatte();
$api = getApi($proxy_elements);
$feed = $api->getTrendingFeed($cursor);
if ($feed) {
$latte->render(getView('trending'), ['feed' => $feed]);
} else {
return 'ERROR!';
}
});
Route::add("/@([^/]+)", function (string $username) use ($proxy_elements) {
$cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor'];
}
$latte = getLatte();
$api = getApi($proxy_elements);
$feed = $api->getUserFeed($username, $cursor);
if ($feed) {
if ($feed->info->detail->user->privateAccount) {
http_response_code(400);
return 'Private account detected! Not supported';
}
$latte->render(getView('user'), ['feed' => $feed]);
} else {
return 'ERROR!';
}
});
Route::add("/settings", function () use ($proxy_elements) {
$latte = getLatte();
$latte->render(getView('settings'), ["proxy_elements" => $proxy_elements]);
});
Route::add("/settings", function () use ($proxy_elements) {
if (in_array($proxy_elements, $_POST)) {
foreach ($proxy_elements as $proxy_element) {
setcookie($proxy_element, $_POST[$proxy_element], time()+60*60*24*30, '/', '', true, true);
}
}
http_response_code(302);
header('Location: ./home');
}, 'POST');
require __DIR__ . '/routes/index.php';
Route::run(getSubdir());

60
routes/assets.php Normal file
View file

@ -0,0 +1,60 @@
<?php
require __DIR__ . "/../helpers/domains.php";
use Steampixel\Route;
Route::add('/images', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['image'])) {
die('Not a valid URL');
}
$img = file_get_contents($url, false, stream_context_create(['http' => ['ignore_errors' => true]]));
if ($img) {
header('Content-Type: image/jpeg');
return $img;
} else {
return 'Error while getting image!';
}
});
Route::add('/audios', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['audio'])) {
die('Not a valid URL');
}
$audio = file_get_contents($url, false, stream_context_create(['http' => ['ignore_errors' => true]]));
if ($audio) {
header('Content-Type: audio/mp3');
return $audio;
} else {
return 'Error while getting audio!';
}
});
Route::add('/stream', function () use ($domains) {
if (!isset($_GET['url'])) {
die('You need to send a url!');
}
$url = $_GET['url'];
$host = parse_url($url, PHP_URL_HOST);
if (!filter_var($url, FILTER_VALIDATE_URL) || !in_array($host, $domains['video'])) {
die('Not a valid URL');
}
if (isset($_GET['download'])) {
header('Content-Disposition: attachment; filename="tiktok.mp4"');
}
$streamer = new \Sovit\TikTok\Stream();
$streamer->stream($url);
});

91
routes/index.php Normal file
View file

@ -0,0 +1,91 @@
<?php
require __DIR__ . '/assets.php';
require __DIR__ . '/settings.php';
require __DIR__ . "/../helpers/settings_elements.php";
use Steampixel\Route;
// - ROUTING HELPERS - //
function getApi(array $proxy_elements): \Sovit\TikTok\Api {
$options = [];
// Proxy config
if (in_array($proxy_elements, $_COOKIE)) {
foreach ($proxy_elements as $proxy_element) {
$options[$proxy_element] = $_COOKIE[$proxy_element];
}
}
$api = new \Sovit\TikTok\Api($options);
return $api;
}
function getLatte(): \Latte\Engine {
$subdir = getSubdir();
$latte = new Latte\Engine;
$latte->setTempDirectory('./cache/views');
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
$path = "{$subdir}/{$type}/{$name}";
return $path;
});
$latte->addFunction('path', function (string $name) use ($subdir) {
$path = "{$subdir}/{$name}";
return $path;
});
return $latte;
}
function getView(string $template): string {
return "./views/{$template}.latte";
}
Route::add('/', function () {
$latte = getLatte();
$latte->render(getView('home'));
});
Route::add("/trending", function () use ($proxy_elements) {
$cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor'];
}
$latte = getLatte();
$api = getApi($proxy_elements);
$feed = $api->getTrendingFeed($cursor);
if ($feed) {
$latte->render(getView('trending'), ['feed' => $feed]);
} else {
return 'ERROR!';
}
});
Route::add("/@([^/]+)", function (string $username) use ($proxy_elements) {
$cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor'];
}
$latte = getLatte();
$api = getApi($proxy_elements);
$feed = $api->getUserFeed($username, $cursor);
if ($feed) {
if ($feed->info->detail->user->privateAccount) {
http_response_code(400);
return 'Private account detected! Not supported';
}
$latte->render(getView('user'), ['feed' => $feed]);
} else {
return 'ERROR!';
}
});
Route::add('/tag/(\w+)', function (string $name) use ($proxy_elements) {
$cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor'];
}
$latte = getLatte();
$api = getApi($proxy_elements);
$feed = $api->getChallengeFeed($name, $cursor);
if ($feed) {
$latte->render(getView('tag'), ['feed' => $feed]);
} else {
return 'ERROR!';
}
});

18
routes/settings.php Normal file
View file

@ -0,0 +1,18 @@
<?php
require __DIR__ . "/../helpers/settings_elements.php";
use Steampixel\Route;
Route::add("/settings", function () use ($proxy_elements) {
$latte = getLatte();
$latte->render(getView('settings'), ["proxy_elements" => $proxy_elements]);
});
Route::add("/settings", function () use ($proxy_elements) {
if (in_array($proxy_elements, $_POST)) {
foreach ($proxy_elements as $proxy_element) {
setcookie($proxy_element, $_POST[$proxy_element], time()+60*60*24*30, '/', '', true, true);
}
}
http_response_code(302);
header('Location: ./home');
}, 'POST');

16
scripts/home.js Normal file
View file

@ -0,0 +1,16 @@
const goToUser = (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const username = formData.get('username')
window.location.href = `./@${username}`
}
const goToTag = (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const tag = formData.get('tag')
window.location.href = `./tag/${tag}`
}
document.getElementById('username_form').addEventListener('submit', goToUser, false)
document.getElementById('tag_form').addEventListener('submit', goToTag, false)

View file

@ -1,14 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>About - TikTok</title>
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
</head>
{include 'components/head.latte', title: 'About'}
<body>
{include 'navbar.latte'}
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
@ -19,6 +15,6 @@
<section class="section">
<p>TODO</p>
</section>
{include 'footer.latte'}
{include 'components/footer.latte'}
</body>
</html>

View file

@ -1,16 +1,17 @@
<link rel="stylesheet" href="{assets('feed.css', 'styles')}">
<section class="section">
<div class="columns is-multiline is-vcentered">
{foreach $feed->items as $item}
<div class="column is-one-quarter">
<a id="{$item->id}" href="#{$item->id}" class="clickable-img"
data-video_url="./stream?url={$item->video->playAddr}"
data-video_download="./stream?url={urlencode($item->video->downloadAddr)}&download=1"
data-video_url="{path('stream?url=' . urlencode($item->video->playAddr))}"
data-video_download="{path('stream?url=' . urlencode($item->video->playAddr) . '&download=1')}"
data-desc="{$item->desc}"
data-video_width="{$item->video->width}"
data-video_height="{$item->video->height}"
data-music_title="{$item->music->title}"
data-music_url="./audios?url={urlencode($item->music->playUrl)}">
<img loading="lazy" src="./images?url={urlencode($item->video->originCover)}"/>
data-music_url="{path('audios?url=' . urlencode($item->music->playUrl))}">
<img loading="lazy" src="{path('images?url=' . urlencode($item->video->originCover))}"/>
</a>
</div>
{/foreach}

View file

@ -0,0 +1,7 @@
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
<title>{$title} - Tiktok Viewer</title>
</head>

View file

@ -9,7 +9,7 @@
<div id="navbar-menu" class="navbar-menu">
<div class="navbar-start">
<a href="{path('home')}" class="navbar-item">Home</a>
<a href="{path('')}" class="navbar-item">Home</a>
<a href="{path('settings')}" class="navbar-item">Settings</a>
</div>
</div>

View file

@ -1,16 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
<title>Tiktok Viewer</title>
</head>
{include 'components/head.latte', title: 'Home'}
<body>
{include 'navbar.latte'}
{include 'components/navbar.latte'}
<section class="hero is-fullheight-with-navbar">
<div class="hero-body">
<div class="container has-text-centered">
@ -20,7 +14,19 @@
<form id="username_form">
<div class="field has-addons has-addons-centered">
<div class="control">
<input name="username" class="input" placeholder="Type username" required />
<input name="username" class="input" type="text" placeholder="Type username" required />
</div>
<div class="control">
<button class="button is-success" type="submit">Go</button>
</div>
</div>
</form>
<hr />
<p>Search tag:</p>
<form id="tag_form">
<div class="field has-addons has-addons-centered">
<div class="control">
<input name="tag" class="input" type="text" placeholder="Type tag" required />
</div>
<div class="control">
<button class="button is-success" type="submit">Go</button>
@ -33,18 +39,10 @@
</div>
</div>
<div class="hero-foot">
{include 'footer.latte'}
{include 'components/footer.latte'}
</div>
</section>
<script n:syntax=off>
const goToUser = (e) => {
e.preventDefault()
const formData = new FormData(e.target)
const username = formData.get('username')
window.location.href = `./@${username}`
}
document.getElementById('username_form').addEventListener('submit', goToUser, false)
</script>
<script src="{assets('home.js', 'scripts')}"></script>
</body>
</html>

View file

@ -1,14 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Settings - TikTok</title>
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
</head>
{include 'components/head.latte', title: 'Settings'}
<body>
{include 'navbar.latte'}
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
@ -35,6 +31,6 @@
</div>
</form>
</section>
{include 'footer.latte'}
{include 'components/footer.latte'}
</body>
</html>

19
views/tag.latte Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
{include 'components/head.latte', title: 'Challenge'}
<body>
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
<p class="title">{$feed->info->detail->challenge->title}</p>
<p class="subtitle">{$feed->info->detail->challenge->desc}</p>
</div>
</div>
</section>
{include 'components/feed.latte'}
{include 'components/footer.latte'}
</body>
</html>

View file

@ -1,15 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Trending - TikTok</title>
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
<link rel="stylesheet" href="{assets('feed.css', 'styles')}">
</head>
{include 'components/head.latte', title: 'Trending'}
<body>
{include 'navbar.latte'}
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
@ -17,7 +12,7 @@
</div>
</div>
</section>
{include 'feed.latte'}
{include 'footer.latte'}
{include 'components/feed.latte'}
{include 'components/footer.latte'}
</body>
</html>

View file

@ -1,15 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{$feed->info->detail->user->nickname} - TikTok</title>
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/superhero/bulmaswatch.min.css">
<link rel="stylesheet" href="{assets('feed.css', 'styles')}">
</head>
{include 'components/head.latte', title: $feed->info->detail->user->nickname}
<body>
{include 'navbar.latte'}
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
@ -18,7 +13,7 @@
</div>
</div>
</section>
{include 'feed.latte'}
{include 'footer.latte'}
{include 'components/feed.latte'}
{include 'components/footer.latte'}
</body>
</html>