diff --git a/.env.example b/.env.example index 0e63d29..3e24066 100644 --- a/.env.example +++ b/.env.example @@ -1 +1 @@ -APP_SUBDIR=/ # Subpath your app is running, defaults to / +APP_SUBDIR=/ # Subpath your app is running, LEAVE EMPTY IF RUNNING FROM / diff --git a/README.md b/README.md index 951f6c9..2418db8 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,10 @@ Move the .env.example file to .env and modify it. If you are using Apache you don't have to do anything more ### Nginx -Add the following to your config (you can modify the tiktok-viewer part if you have or not a subdir): +Add the following to your config (you can modify the tiktok-viewer part if you have or not a subdir): ``` location /tiktok-viewer { - return 302 $scheme://$host/tiktok-viewer/; + return 302 $scheme://$host/tiktok-viewer/; } location /tiktok-viewer/ { diff --git a/index.php b/index.php index 1c241be..8dd2089 100644 --- a/index.php +++ b/index.php @@ -1,162 +1,16 @@ 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()); diff --git a/routes/assets.php b/routes/assets.php new file mode 100644 index 0000000..8400336 --- /dev/null +++ b/routes/assets.php @@ -0,0 +1,60 @@ + ['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); +}); diff --git a/routes/index.php b/routes/index.php new file mode 100644 index 0000000..6b16386 --- /dev/null +++ b/routes/index.php @@ -0,0 +1,91 @@ +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!'; + } +}); diff --git a/routes/settings.php b/routes/settings.php new file mode 100644 index 0000000..6614df7 --- /dev/null +++ b/routes/settings.php @@ -0,0 +1,18 @@ +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'); diff --git a/scripts/home.js b/scripts/home.js new file mode 100644 index 0000000..5947b27 --- /dev/null +++ b/scripts/home.js @@ -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) diff --git a/views/about.latte b/views/about.latte index 7701f1a..ca02cd1 100644 --- a/views/about.latte +++ b/views/about.latte @@ -1,14 +1,10 @@ - - - - - About - TikTok - - + +{include 'components/head.latte', title: 'About'} + - {include 'navbar.latte'} + {include 'components/navbar.latte'}
@@ -19,6 +15,6 @@

TODO

- {include 'footer.latte'} + {include 'components/footer.latte'} diff --git a/views/feed.latte b/views/components/feed.latte similarity index 81% rename from views/feed.latte rename to views/components/feed.latte index 56d0bd7..55fee55 100644 --- a/views/feed.latte +++ b/views/components/feed.latte @@ -1,16 +1,17 @@ +
{foreach $feed->items as $item} {/foreach} diff --git a/views/footer.latte b/views/components/footer.latte similarity index 100% rename from views/footer.latte rename to views/components/footer.latte diff --git a/views/components/head.latte b/views/components/head.latte new file mode 100644 index 0000000..1268bac --- /dev/null +++ b/views/components/head.latte @@ -0,0 +1,7 @@ + + + + + + {$title} - Tiktok Viewer + diff --git a/views/navbar.latte b/views/components/navbar.latte similarity index 90% rename from views/navbar.latte rename to views/components/navbar.latte index 1c0be42..92a87e2 100644 --- a/views/navbar.latte +++ b/views/components/navbar.latte @@ -9,7 +9,7 @@ diff --git a/views/home.latte b/views/home.latte index 61ee982..a6520db 100644 --- a/views/home.latte +++ b/views/home.latte @@ -1,16 +1,10 @@ - - - - - - Tiktok Viewer - +{include 'components/head.latte', title: 'Home'} - {include 'navbar.latte'} + {include 'components/navbar.latte'}
@@ -20,7 +14,19 @@
- + +
+
+ +
+
+
+
+

Search tag:

+
+
+
+
@@ -33,18 +39,10 @@
- {include 'footer.latte'} + {include 'components/footer.latte'}
- + diff --git a/views/settings.latte b/views/settings.latte index abbd5cf..f3e2891 100644 --- a/views/settings.latte +++ b/views/settings.latte @@ -1,14 +1,10 @@ - - - - - Settings - TikTok - - + +{include 'components/head.latte', title: 'Settings'} + - {include 'navbar.latte'} + {include 'components/navbar.latte'}
@@ -35,6 +31,6 @@
- {include 'footer.latte'} + {include 'components/footer.latte'} diff --git a/views/tag.latte b/views/tag.latte new file mode 100644 index 0000000..085cb9b --- /dev/null +++ b/views/tag.latte @@ -0,0 +1,19 @@ + + + +{include 'components/head.latte', title: 'Challenge'} + + + {include 'components/navbar.latte'} +
+
+
+

{$feed->info->detail->challenge->title}

+

{$feed->info->detail->challenge->desc}

+
+
+
+ {include 'components/feed.latte'} + {include 'components/footer.latte'} + + diff --git a/views/trending.latte b/views/trending.latte index de50072..80344c8 100644 --- a/views/trending.latte +++ b/views/trending.latte @@ -1,15 +1,10 @@ - - - - - Trending - TikTok - - - + +{include 'components/head.latte', title: 'Trending'} + - {include 'navbar.latte'} + {include 'components/navbar.latte'}
@@ -17,7 +12,7 @@
- {include 'feed.latte'} - {include 'footer.latte'} + {include 'components/feed.latte'} + {include 'components/footer.latte'} diff --git a/views/user.latte b/views/user.latte index 696c73f..592281a 100644 --- a/views/user.latte +++ b/views/user.latte @@ -1,15 +1,10 @@ - - - - - {$feed->info->detail->user->nickname} - TikTok - - - + +{include 'components/head.latte', title: $feed->info->detail->user->nickname} + - {include 'navbar.latte'} + {include 'components/navbar.latte'}
@@ -18,7 +13,7 @@
- {include 'feed.latte'} - {include 'footer.latte'} + {include 'components/feed.latte'} + {include 'components/footer.latte'}