mirror of
https://github.com/pablouser1/ProxiTok.git
synced 2024-12-06 19:27:30 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6fafcdcd11 | |||
| 5e1b009f75 | |||
| 7aa869f567 | |||
| c076ba65a6 | |||
| 2504ba6e93 | |||
| 38557fafa6 |
@@ -21,13 +21,13 @@ If you want to automatically redirect Tiktok links to ProxiTok you can use:
|
||||
* [Libredirect](https://github.com/libredirect/libredirect)
|
||||
* [Redirector](https://github.com/einaregilsson/Redirector)
|
||||
|
||||
You can use the following config if you want to use Redirector (you can change https://proxitok.herokuapp.com with whatever instance you want to use):
|
||||
You can use the following config if you want to use Redirector (you can change https://proxitok.pabloferreiro.es with whatever instance you want to use):
|
||||
```
|
||||
Description: TikTok to ProxiTok
|
||||
Example URL: https://www.tiktok.com/@tiktok
|
||||
Include pattern: (.*//.*)(tiktok.com)(.*)
|
||||
Redirect to: https://proxitok.herokuapp.com$3
|
||||
Example result: https://proxitok.herokuapp.com/@tiktok
|
||||
Redirect to: https://proxitok.pabloferreiro.es$3
|
||||
Example result: https://proxitok.pabloferreiro.es/@tiktok
|
||||
Pattern type: Regular Expression
|
||||
Apply to: Main window (address bar)
|
||||
```
|
||||
@@ -38,7 +38,6 @@ Apply to: Main window (address bar)
|
||||
* Fix embed styling
|
||||
* Fix crash when invalid vm.tiktok.com/CODE or www.tiktok.com/t/CODE is provided
|
||||
* Add custom amount of videos per page
|
||||
* Discover does not work
|
||||
|
||||
## Credits
|
||||
[@TheFrenchGhosty](https://github.com/TheFrenchGhosty): Initial Dockerfile and fixes to a usable state. You can check his Docker image [here](https://github.com/PussTheCat-org/docker-proxitok-quay) on Github or [here](https://quay.io/repository/pussthecatorg/proxitok) on Quay
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace App\Cache;
|
||||
|
||||
use TikScraper\CacheInterface;
|
||||
use TikScraper\Interfaces\CacheInterface;
|
||||
|
||||
class JSONCache implements CacheInterface {
|
||||
private string $cache_path = __DIR__ . '/../../cache/api';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace App\Cache;
|
||||
|
||||
use TikScraper\CacheInterface;
|
||||
use TikScraper\Interfaces\CacheInterface;
|
||||
|
||||
class RedisCache implements CacheInterface {
|
||||
private \Redis $client;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace App\Constants;
|
||||
|
||||
abstract class Themes {
|
||||
const DEFAULT = "default";
|
||||
const CARD = "card";
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class DiscoverController {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('discover'), new FeedTemplate('Discover', $feed));
|
||||
} else {
|
||||
ErrorHandler::show($feed->meta);
|
||||
ErrorHandler::showMeta($feed->meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@ use App\Models\VideoTemplate;
|
||||
class EmbedController {
|
||||
static public function v2(int $id) {
|
||||
$api = Wrappers::api();
|
||||
$feed = $api->getVideoByID($id);
|
||||
if ($feed->meta->success) {
|
||||
$video = $api->video($id);
|
||||
$video->feed();
|
||||
if ($video->ok()) {
|
||||
$data = $video->getFull();
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('video'), new VideoTemplate($feed->items[0], $feed->info->detail, true));
|
||||
$latte->render(Misc::getView('video'), new VideoTemplate($data->feed->items[0], $data->info->detail, true));
|
||||
} else {
|
||||
ErrorHandler::show($feed->meta);
|
||||
ErrorHandler::showMeta($video->error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class MusicController {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('music'), new FullTemplate('Music', $data));
|
||||
} else {
|
||||
ErrorHandler::show($music->error());
|
||||
ErrorHandler::showMeta($music->error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?php
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Helpers\Cookies;
|
||||
use TikScraper\Helpers\Converter;
|
||||
|
||||
class ProxyController {
|
||||
const VALID_TIKTOK_DOMAINS = [
|
||||
"tiktokcdn.com", "tiktokcdn-us.com", "tiktok.com"
|
||||
@@ -30,11 +33,9 @@ class ProxyController {
|
||||
|
||||
}
|
||||
|
||||
static private function getFileName(): string {
|
||||
$filename = 'tiktok-video';
|
||||
if (isset($_GET['user'])) {
|
||||
$filename .= '-' . $_GET['user'] . '-' . $_GET['id'];
|
||||
}
|
||||
static private function getFilename(string $url, string $user): string {
|
||||
$id = Converter::urlToId($url);
|
||||
$filename = 'tiktok-video-' . $id . '-' . $user;
|
||||
return $filename;
|
||||
}
|
||||
|
||||
@@ -46,18 +47,17 @@ class ProxyController {
|
||||
}
|
||||
|
||||
static public function download() {
|
||||
$downloader = new \TikScraper\Download();
|
||||
self::checkUrl();
|
||||
$method = Cookies::downloader();
|
||||
$downloader = new \TikScraper\Download($method);
|
||||
|
||||
// Params
|
||||
$watermark = isset($_GET['watermark']);
|
||||
if ($watermark) {
|
||||
self::checkUrl();
|
||||
$filename = self::getFileName();
|
||||
$downloader->url($_GET['url'], $filename, true);
|
||||
} else {
|
||||
if (!isset($_GET['id'])) {
|
||||
die('You need to send an ID!');
|
||||
}
|
||||
$filename = self::getFileName();
|
||||
$downloader->url($_GET['id'], $filename, false);
|
||||
}
|
||||
$url = $_GET['url'];
|
||||
$user = $_GET['user'] ?? '';
|
||||
// Filename
|
||||
$filename = self::getFilename($url, $user);
|
||||
// Running
|
||||
$downloader->url($_GET['url'], $filename, $watermark);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ class RedirectController {
|
||||
static public function redirect() {
|
||||
$endpoint = '/';
|
||||
if (isset($_GET['type'], $_GET['term'])) {
|
||||
$term = trim($_GET['term']);
|
||||
$term = urlencode(trim($_GET['term']));
|
||||
switch ($_GET['type']) {
|
||||
case 'url':
|
||||
$endpoint = self::to_endpoint($term);
|
||||
if (!$endpoint) {
|
||||
echo 'Invalid or unknown TikTok URL format';
|
||||
ErrorHandler::showText(400, 'Invalid TikTok URL');
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -4,12 +4,12 @@ namespace App\Controllers;
|
||||
use App\Helpers\Misc;
|
||||
use App\Helpers\Cookies;
|
||||
use App\Helpers\Wrappers;
|
||||
use App\Models\BaseTemplate;
|
||||
use App\Models\SettingsTemplate;
|
||||
|
||||
class SettingsController {
|
||||
static public function index() {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('settings'), new BaseTemplate('Settings'));
|
||||
$latte->render(Misc::getView('settings'), new SettingsTemplate());
|
||||
}
|
||||
|
||||
static public function general() {
|
||||
@@ -25,6 +25,11 @@ class SettingsController {
|
||||
$test_endpoints = $_POST['api-test_endpoints'];
|
||||
Cookies::set('api-test_endpoints', $test_endpoints);
|
||||
}
|
||||
|
||||
if (isset($_POST['api-downloader'])) {
|
||||
$downloader = $_POST['api-downloader'];
|
||||
Cookies::set("api-downloader", $downloader);
|
||||
}
|
||||
self::redirect();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ class TagController {
|
||||
if ($hashtag->ok()) {
|
||||
$data = $hashtag->getFull();
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('tag'), new FullTemplate('Tag', $data));
|
||||
$latte->render(Misc::getView('tag'), new FullTemplate($data->info->detail->title, $data));
|
||||
} else {
|
||||
ErrorHandler::show($hashtag->error());
|
||||
ErrorHandler::showMeta($hashtag->error());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class TrendingController {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('trending'), new FeedTemplate('Trending', $feed));
|
||||
} else {
|
||||
ErrorHandler::show($trending->error());
|
||||
ErrorHandler::showMeta($trending->error());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,13 @@ class UserController {
|
||||
if ($user->ok()) {
|
||||
$data = $user->getFull();
|
||||
if ($data->info->detail->privateAccount) {
|
||||
http_response_code(403);
|
||||
echo 'Private account detected! Not supported';
|
||||
exit;
|
||||
ErrorHandler::showText(401, "Private account detected! Not supported");
|
||||
return;
|
||||
}
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('user'), new FullTemplate($data->info->detail->nickname, $data));
|
||||
} else {
|
||||
ErrorHandler::show($user->error());
|
||||
ErrorHandler::showMeta($user->error());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +36,7 @@ class UserController {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('video'), new VideoTemplate($data->feed->items[0], $data->info->detail));
|
||||
} else {
|
||||
ErrorHandler::show($video->error());
|
||||
ErrorHandler::showMeta($video->error());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-3
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
namespace App\Helpers;
|
||||
|
||||
class Cookies {
|
||||
const ALLOWED_THEMES = ['default', 'card'];
|
||||
use App\Constants\Themes;
|
||||
|
||||
class Cookies {
|
||||
static public function get(string $name, string $default_value = ''): string {
|
||||
if (isset($_COOKIE[$name]) && !empty($_COOKIE[$name])) {
|
||||
return $_COOKIE[$name];
|
||||
@@ -13,12 +13,19 @@ class Cookies {
|
||||
|
||||
static public function theme(): string {
|
||||
$theme = self::get('theme');
|
||||
if ($theme && in_array($theme, self::ALLOWED_THEMES)) {
|
||||
$ref = new \ReflectionClass(Themes::class);
|
||||
$themes = $ref->getConstants();
|
||||
if ($theme && in_array($theme, $themes)) {
|
||||
return $theme;
|
||||
}
|
||||
return 'default';
|
||||
}
|
||||
|
||||
static public function downloader(): string {
|
||||
$downloader = self::get('api-downloader', 'default');
|
||||
return $downloader;
|
||||
}
|
||||
|
||||
static public function exists(string $name): bool {
|
||||
return isset($_COOKIE[$name]);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,15 @@ use App\Models\ErrorTemplate;
|
||||
use TikScraper\Models\Meta;
|
||||
|
||||
class ErrorHandler {
|
||||
static public function show(Meta $meta) {
|
||||
static public function showMeta(Meta $meta) {
|
||||
http_response_code($meta->http_code);
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('error'), new ErrorTemplate($meta));
|
||||
$latte->render(Misc::getView('error'), new ErrorTemplate($meta->http_code, $meta->tiktok_msg, $meta->tiktok_code));
|
||||
}
|
||||
|
||||
static public function showText(int $code, string $msg) {
|
||||
http_response_code($code);
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('error'), new ErrorTemplate($code, $msg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace App\Helpers;
|
||||
|
||||
class UrlBuilder {
|
||||
static public function stream(string $url): string {
|
||||
return Misc::url('/stream?url=' . urlencode($url));
|
||||
}
|
||||
|
||||
static public function download(string $url, string $username, bool $watermark): string {
|
||||
// {path('/download?url=' . urlencode($playAddr) . '&id=' . $id . '&user=' . $uniqueId) . '&watermark=1'}
|
||||
$down_url = Misc::url('/download?url=' . urlencode($url) . '&user=' . $username);
|
||||
if ($watermark) $down_url .= '&watermark=1';
|
||||
return $down_url;
|
||||
}
|
||||
|
||||
static public function user(string $username): string {
|
||||
return Misc::url('/@' . $username);
|
||||
}
|
||||
|
||||
static public function video_internal(string $username, string $id): string {
|
||||
return Misc::url('/@' . $username . "/video/" . $id);
|
||||
}
|
||||
|
||||
static public function video_external(string $username, string $id): string {
|
||||
return "https://www.tiktok.com/@" . $username . "/video/" . $id;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,23 @@ class Wrappers {
|
||||
$latte->addFunction('theme', function(): string {
|
||||
return Cookies::theme();
|
||||
});
|
||||
|
||||
// UrlBuilder
|
||||
$latte->addFunction('url_stream', function (string $url): string {
|
||||
return UrlBuilder::stream($url);
|
||||
});
|
||||
$latte->addFunction('url_user', function (string $username): string {
|
||||
return UrlBuilder::user($username);
|
||||
});
|
||||
$latte->addFunction('url_video_internal', function (string $username, string $id): string {
|
||||
return UrlBuilder::video_internal($username, $id);
|
||||
});
|
||||
$latte->addFunction('url_video_external', function (string $username, string $id): string {
|
||||
return UrlBuilder::video_external($username, $id);
|
||||
});
|
||||
$latte->addFunction('url_download', function (string $url, string $username, bool $watermark): string {
|
||||
return UrlBuilder::download($url, $username, $watermark);
|
||||
});
|
||||
// https://stackoverflow.com/a/36365553
|
||||
$latte->addFunction('number', function (float $x) {
|
||||
if($x > 1000) {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use TikScraper\Models\Meta;
|
||||
|
||||
class ErrorTemplate extends BaseTemplate {
|
||||
public Meta $error;
|
||||
public int $http_code = 502;
|
||||
public ?int $tiktok_code = -1;
|
||||
public string $msg = '';
|
||||
|
||||
function __construct(object $error) {
|
||||
|
||||
function __construct(int $http_code, string $msg, ?int $tiktok_code = null) {
|
||||
parent::__construct('Error');
|
||||
$this->error = $error;
|
||||
$this->http_code = $http_code;
|
||||
$this->msg = $msg;
|
||||
$this->tiktok_code = $tiktok_code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use App\Constants\Themes;
|
||||
use App\Helpers\Cookies;
|
||||
use TikScraper\Constants\DownloadMethods;
|
||||
|
||||
/**
|
||||
* Base for templates with a feed
|
||||
*/
|
||||
class SettingsTemplate extends BaseTemplate {
|
||||
public array $downloaders = [];
|
||||
public array $themes = [];
|
||||
public bool $isTestEndpoints = false;
|
||||
public string $currentDownloader;
|
||||
public string $currentTheme;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct("Settings");
|
||||
// Downloaders list
|
||||
$ref = new \ReflectionClass(DownloadMethods::class);
|
||||
$this->downloaders = $ref->getConstants();
|
||||
// Themes list
|
||||
$ref = new \ReflectionClass(Themes::class);
|
||||
$this->themes = $ref->getConstants();
|
||||
// Cookies data
|
||||
$this->isTestEndpoints = Cookies::check('api-test_endpoints', 'yes');
|
||||
$this->currentDownloader = Cookies::downloader();
|
||||
$this->currentTheme = Cookies::theme();
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -1,5 +1,8 @@
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a href="{path('/')}" class="navbar-item">
|
||||
{include './icon.latte', icon: 'home', text: 'ProxiTok'}
|
||||
</a>
|
||||
<a role="button" id="navbar-burger" class="navbar-burger" aria-label="menu" aria-expanded="false">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
@@ -9,14 +12,18 @@
|
||||
|
||||
<div id="navbar-menu" class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
<a href="{path('/')}" class="navbar-item">
|
||||
{include './icon.latte', icon: 'home', text: 'Home'}
|
||||
<a href="{path('/settings')}" class="navbar-item">
|
||||
{include './icon.latte', icon: 'options', text: 'Settings'}
|
||||
</a>
|
||||
<a href="{path('/settings')}" class="navbar-item">Settings</a>
|
||||
<a href="{path('/about')}" class="navbar-item">
|
||||
{include './icon.latte', icon: 'info', text: 'About'}
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<a href="https://github.com/pablouser1/ProxiTok" class="navbar-item" target="_blank">
|
||||
{include './icon.latte', icon: 'code-slash', text: 'Source'}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<script src="{path('/scripts/navbar.js')}"></script>
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
{embed '../form.latte', path: '/settings/api', method: 'POST', submit: true}
|
||||
{block fields}
|
||||
{var $use_endpoints = \App\Helpers\Cookies::check('api-test_endpoints', 'yes')}
|
||||
<div class="field">
|
||||
<label class="label">Use test endpoints</label>
|
||||
<div class="control">
|
||||
<label class="radio">
|
||||
<input type="radio" name="api-test_endpoints" value="yes" n:attr="checked => $use_endpoints" />
|
||||
<input type="radio" name="api-test_endpoints" value="yes" n:attr="checked => $isTestEndpoints" />
|
||||
<span>Yes</span>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="api-test_endpoints" value="no" n:attr="checked => !$use_endpoints" />
|
||||
<input type="radio" name="api-test_endpoints" value="no" n:attr="checked => !$isTestEndpoints" />
|
||||
<span>No</span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">This <i>may</i> help bypass rate limits</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Downloader</label>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="api-downloader">
|
||||
{foreach $downloaders as $downloader}
|
||||
<option value="{$downloader}" n:attr="selected => $currentDownloader === $downloader">{$downloader|firstUpper}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help">Watermark downloads will <i>not</i> use third party methods</p>
|
||||
</div>
|
||||
{/block}
|
||||
{/embed}
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
{block fields}
|
||||
<div class="field">
|
||||
<label class="label">Theme</label>
|
||||
<div class="select">
|
||||
<select name="theme">
|
||||
<option hidden disabled selected value> -- Select an option -- </option>
|
||||
<option value="default">Default</option>
|
||||
<option value="card">Card</option>
|
||||
</select>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="theme">
|
||||
{foreach $themes as $theme}
|
||||
<option value="{$theme}" n:attr="selected => $currentTheme === $theme">{$theme|firstUpper}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
{/embed}
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
<section class="section">
|
||||
<div class="columns is-multiline is-vcentered">
|
||||
{foreach $data->feed->items as $item}
|
||||
{do $share_url = 'https://tiktok.com/@' . $item->author->uniqueId . '/video/' . $item->id}
|
||||
{do $share_url = url_video_external($item->author->uniqueId, $item->id)}
|
||||
<div class="column is-one-quarter clickable-img" id="{$item->id}" onclick="openVideo(this.id)"
|
||||
data-video_url="{path('/stream?url=' . urlencode($item->video->playAddr))}"
|
||||
data-video_download_watermark="{path('/download?url=' . urlencode($item->video->playAddr) . '&id=' . $item->id . '&user=' . $item->author->uniqueId) . '&watermark='}"
|
||||
data-video_download_nowatermark="{path('/download?id=' . $item->id . '&user=' . $item->author->uniqueId)}"
|
||||
data-video_url="{url_stream($item->video->playAddr)}"
|
||||
data-video_download_watermark="{url_download($item->video->playAddr, $item->author->uniqueId, true)}"
|
||||
data-video_download_nowatermark="{url_download($item->video->playAddr, $item->author->uniqueId, false)}"
|
||||
data-video_share_url="{$share_url}"
|
||||
data-desc="{$item->desc}"
|
||||
data-createtime="{$item->createTime}"
|
||||
data-music_title="{$item->music->title}"
|
||||
data-music_url="{path('/stream?url=' . urlencode($item->music->playUrl))}">
|
||||
<img loading="lazy" src="{path('/stream?url=' . urlencode($item->video->originCover))}" />
|
||||
<img class="hidden" loading="lazy" data-src="{path('/stream?url=' . urlencode($item->video->dynamicCover))}" />
|
||||
data-music_url="{url_stream($item->music->playUrl)}">
|
||||
<img loading="lazy" src="{url_stream($item->video->originCover)}" />
|
||||
<img class="hidden" loading="lazy" data-src="{url_stream($item->video->dynamicCover)}" />
|
||||
</div>
|
||||
{/foreach}
|
||||
{if empty($data->feed->items)}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
</div>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a target="_blank" href="{path('/download?url=' . urlencode($playAddr) . '&id=' . $id . '&user=' . $uniqueId) . '&watermark=1'}" class="dropdown-item">Watermark</a>
|
||||
<a target="_blank" href="{path('/download?id=' . $id . '&user=' . $uniqueId)}" class="dropdown-item">No watermark</a>
|
||||
<a target="_blank" href="{url_download($playAddr, $uniqueId, true)}" class="dropdown-item">Watermark</a>
|
||||
<a target="_blank" href="{url_download(url_video_external($uniqueId, $id), $uniqueId, false)}" class="dropdown-item">No watermark</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{do $endpoint = '/@' . $uniqueId . '/video/' . $id}
|
||||
<div class="buttons is-centered">
|
||||
<a class="button is-success is-small" href="{path($endpoint)}">Instance Link</a>
|
||||
<a class="button is-danger is-small" href="https://www.tiktok.com{$endpoint}">Original Link</a>
|
||||
<a class="button is-success is-small" href="{url_video_internal($uniqueId, $id)}">Instance Link</a>
|
||||
<a class="button is-danger is-small" href="{url_video_external($uniqueId, $id)}">Original Link</a>
|
||||
</div>
|
||||
|
||||
@@ -3,27 +3,25 @@
|
||||
<article class="media">
|
||||
<figure class="media-left">
|
||||
<p class="image is-64x64">
|
||||
<img src="{path('/stream?url=' . urlencode($item->author->avatarThumb))}" />
|
||||
<img src="{url_stream($item->author->avatarThumb)}" />
|
||||
</p>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<p>
|
||||
<strong>{$item->author->nickname}</strong>
|
||||
<small>
|
||||
<a href="{path('/@' . $item->author->uniqueId)}">@{$item->author->uniqueId}</a>
|
||||
</small>
|
||||
<small title="{date('M d, Y H:i:s e', $item->createTime)}">{date('M d, Y', $item->createTime)}</small>
|
||||
</p>
|
||||
{if !empty($item->challenges)}
|
||||
<p>{include './common/tags.latte', challenges: $item->challenges}</p>
|
||||
{/if}
|
||||
<p n:ifcontent>{$item->desc}</p>
|
||||
{include './common/stats.latte', playCount: $item->stats->playCount, diggCount: $item->stats->diggCount, commentCount: $item->stats->commentCount, shareCount: $item->stats->shareCount}
|
||||
</div>
|
||||
<p>
|
||||
<strong>{$item->author->nickname}</strong>
|
||||
<small>
|
||||
<a href="{url_user($item->author->uniqueId)}">@{$item->author->uniqueId}</a>
|
||||
</small>
|
||||
<small title="{date('M d, Y H:i:s e', $item->createTime)}">{date('M d, Y', $item->createTime)}</small>
|
||||
</p>
|
||||
{if !empty($item->challenges)}
|
||||
<p>{include './common/tags.latte', challenges: $item->challenges}</p>
|
||||
{/if}
|
||||
<p n:ifcontent>{$item->desc}</p>
|
||||
{include './common/stats.latte', playCount: $item->stats->playCount, diggCount: $item->stats->diggCount, commentCount: $item->stats->commentCount, shareCount: $item->stats->shareCount}
|
||||
<div class="has-text-centered">
|
||||
<video width="{$item->video->width}" height="{$item->video->height}" controls preload="none" poster="{path('/stream?url=' . urlencode($item->video->originCover))}">
|
||||
<source src="{path('/stream?url=' . $item->video->playAddr)}" type="video/mp4" />
|
||||
<video width="{$item->video->width}" height="{$item->video->height}" controls preload="none" poster="{url_stream($item->video->originCover)}">
|
||||
<source src="{url_stream($item->video->playAddr)}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
<div class="has-text-centered">
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pablouser1/proxitok",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "2.4.1.0",
|
||||
"version": "2.4.2.3",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"type": "project",
|
||||
"authors": [
|
||||
@@ -24,7 +24,7 @@
|
||||
"latte/latte": "^2.11",
|
||||
"bramus/router": "^1.6",
|
||||
"josegonzalez/dotenv": "dev-master",
|
||||
"pablouser1/tikscraper": "^2.2"
|
||||
"pablouser1/tikscraper": "^2.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+16
-15
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "a7e4990ac4c1935a8cdc93939bf26dc9",
|
||||
"content-hash": "0b40437551f24ae25f01113a85564867",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bramus/router",
|
||||
@@ -263,16 +263,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pablouser1/tikscraper",
|
||||
"version": "v2.2.1.1",
|
||||
"version": "v2.3.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pablouser1/TikScraperPHP.git",
|
||||
"reference": "535ed6db108c9a0ec41b271bea8a6a10700cc5d7"
|
||||
"reference": "4b3c5952e1f9e126e2e1c80d006e70e759338c45"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/535ed6db108c9a0ec41b271bea8a6a10700cc5d7",
|
||||
"reference": "535ed6db108c9a0ec41b271bea8a6a10700cc5d7",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/4b3c5952e1f9e126e2e1c80d006e70e759338c45",
|
||||
"reference": "4b3c5952e1f9e126e2e1c80d006e70e759338c45",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -284,7 +284,7 @@
|
||||
"sapistudio/seleniumstealth": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5"
|
||||
"pestphp/pest": "^1.22"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -298,28 +298,29 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Pablo Ferreiro"
|
||||
"name": "Pablo Ferreiro",
|
||||
"homepage": "https://pabloferreiro.es"
|
||||
}
|
||||
],
|
||||
"description": "Get data from TikTok API",
|
||||
"support": {
|
||||
"issues": "https://github.com/pablouser1/TikScraperPHP/issues",
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.2.1.1"
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.3.2.0"
|
||||
},
|
||||
"time": "2022-09-03T11:19:59+00:00"
|
||||
"time": "2022-10-24T18:36:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
"version": "1.12.1",
|
||||
"version": "1.13.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-webdriver/php-webdriver.git",
|
||||
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a"
|
||||
"reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
|
||||
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c",
|
||||
"reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -369,9 +370,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1"
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.13.1"
|
||||
},
|
||||
"time": "2022-05-03T12:16:34+00:00"
|
||||
"time": "2022-10-11T11:49:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sapistudio/seleniumstealth",
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<?php
|
||||
/** @var \Bramus\Router\Router $router */
|
||||
|
||||
use App\Helpers\ErrorHandler;
|
||||
use App\Helpers\Misc;
|
||||
use App\Helpers\Wrappers;
|
||||
use App\Models\BaseTemplate;
|
||||
|
||||
$router->set404(function () {
|
||||
ErrorHandler::showText(404, "That endpoint doesn't exist");
|
||||
});
|
||||
|
||||
$router->get('/', function () {
|
||||
$latte = Wrappers::latte();
|
||||
$latte->render(Misc::getView('home'), new BaseTemplate('Home'));
|
||||
|
||||
Vendored
+2
@@ -10,8 +10,10 @@ $bulmaswatch-import-font: false;
|
||||
@import "./node_modules/bulma/sass/base/_all.sass";
|
||||
|
||||
// Elements
|
||||
@import "./node_modules/bulma/sass/elements/box.sass";
|
||||
@import "./node_modules/bulma/sass/elements/button.sass";
|
||||
@import "./node_modules/bulma/sass/elements/container.sass";
|
||||
@import "./node_modules/bulma/sass/elements/content.sass";
|
||||
@import "./node_modules/bulma/sass/elements/icon.sass";
|
||||
@import "./node_modules/bulma/sass/elements/image.sass";
|
||||
@import "./node_modules/bulma/sass/elements/other.sass";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
@charset "utf-8";
|
||||
// Common
|
||||
@import "./node_modules/css.gg/icons/scss/home.scss";
|
||||
@import "./node_modules/css.gg/icons/scss/options.scss";
|
||||
@import "./node_modules/css.gg/icons/scss/info.scss";
|
||||
@import "./node_modules/css.gg/icons/scss/code-slash.scss";
|
||||
|
||||
// Home
|
||||
@import "./node_modules/css.gg/icons/scss/search.scss";
|
||||
@@ -13,3 +15,6 @@
|
||||
@import "./node_modules/css.gg/icons/scss/comment.scss";
|
||||
@import "./node_modules/css.gg/icons/scss/share.scss";
|
||||
@import "./node_modules/css.gg/icons/scss/software-download.scss";
|
||||
|
||||
// Video
|
||||
@import "./node_modules/css.gg/icons/scss/music.scss";
|
||||
|
||||
+3
-3
@@ -118,9 +118,9 @@ readdirp@~3.6.0:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
sass@^1.46.0:
|
||||
version "1.53.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.53.0.tgz#eab73a7baac045cc57ddc1d1ff501ad2659952eb"
|
||||
integrity sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c"
|
||||
integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/node_modules/css.gg/icons/scss/home.scss","../../scss/node_modules/css.gg/icons/scss/info.scss","../../scss/node_modules/css.gg/icons/scss/search.scss","../../scss/node_modules/css.gg/icons/scss/feed.scss","../../scss/node_modules/css.gg/icons/scss/eye.scss","../../scss/node_modules/css.gg/icons/scss/heart.scss","../../scss/node_modules/css.gg/icons/scss/comment.scss","../../scss/node_modules/css.gg/icons/scss/share.scss","../../scss/node_modules/css.gg/icons/scss/software-download.scss"],"names":[],"mappings":"AAAA,SACE,yLACA,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,aACA,gBACA,4BACA,2BACA,6BACA,4BACA,mBAEA,gBACE,WACA,cACA,sBACA,kBAGF,iBACE,WACA,cACA,sBACA,kBACA,qBACA,sBACA,2BACA,wBACA,SACA,kBACA,WACA,YACA,OAGF,gBACE,UACA,YACA,iBACA,oBACA,4BACA,6BACA,gBACA,SACA,SCjDJ,SACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,mBAEA,iCACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,wBACA,SAGF,gBACE,WACA,WAGF,iBACE,WACA,QC5BN,WACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,mBACA,iBACA,gBAEA,kBACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,WACA,wBACA,yBACA,SACA,UCvBN,SACI,cACA,sBACA,wBACA,sBASA,iBACA,gBACA,kBACA,+BACA,UACA,WACA,kBAbA,iCACE,cACA,sBACA,wBACA,sBAWF,iCACE,WACA,kBACA,kBACA,WACA,WACA,QACA,SACA,WAGF,gBACE,UACA,QACA,WCnCN,QACI,kBACA,cACA,+BACA,WACA,YACA,iCACA,gCACA,gBACA,sBAEA,+BACE,WACA,cACA,oBACA,kBACA,sBAGF,eACE,QACA,8CACA,WACA,YAGF,gBACE,UACA,WACA,iBACA,WACA,SC/BN,UACI,iBACA,6BACA,8BACA,WACA,WACA,gBAeA,sBACA,kBACA,gHACA,cAhBA,iBACE,iBACA,6BACA,8BACA,WACA,WACA,gBACA,WACA,cACA,sBACA,kBAQF,kBACE,WACA,cACA,sBACA,kBAGF,iBACE,WACA,wBACA,QAGF,kBACE,WACA,YACA,sBACA,wBACA,UACA,QC7CN,YACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,gBACA,0CAEA,mBACE,WACA,cACA,sBACA,kBACA,UAGF,oBACE,WACA,cACA,sBACA,kBACA,UACA,iBACA,+BACA,+BACA,UACA,YACA,WAGF,mBACE,WACA,wBACA,qBACA,SACA,QCtCN,UACI,sBACA,kBACA,cACA,+BACA,UACA,WACA,wBACA,oBACA,kCAEA,iBACE,WACA,cACA,sBACA,kBACA,kBACA,WACA,WACA,wBACA,SAGF,kBACE,WACA,cACA,sBACA,kBACA,kBACA,WACA,WACA,wBACA,SACA,MACA,yBAGF,iBACE,SACA,wBCvCN,sBACI,sBACA,kBACA,cACA,+BACA,WACA,WACA,iBACA,aACA,8BACA,+BACA,eAEA,6BACE,WACA,cACA,sBACA,kBACA,UACA,WACA,sBACA,wBACA,yBACA,SACA,WAGF,8BACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,YACA,wBACA,SACA","file":"cssgg.min.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/node_modules/css.gg/icons/scss/home.scss","../../scss/node_modules/css.gg/icons/scss/options.scss","../../scss/node_modules/css.gg/icons/scss/info.scss","../../scss/node_modules/css.gg/icons/scss/code-slash.scss","../../scss/node_modules/css.gg/icons/scss/search.scss","../../scss/node_modules/css.gg/icons/scss/feed.scss","../../scss/node_modules/css.gg/icons/scss/eye.scss","../../scss/node_modules/css.gg/icons/scss/heart.scss","../../scss/node_modules/css.gg/icons/scss/comment.scss","../../scss/node_modules/css.gg/icons/scss/share.scss","../../scss/node_modules/css.gg/icons/scss/software-download.scss","../../scss/node_modules/css.gg/icons/scss/music.scss"],"names":[],"mappings":"AAAA,SACE,yLACA,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,aACA,gBACA,4BACA,2BACA,6BACA,4BACA,mBAEA,gBACE,WACA,cACA,sBACA,kBAGF,iBACE,WACA,cACA,sBACA,kBACA,qBACA,sBACA,2BACA,wBACA,SACA,kBACA,WACA,YACA,OAGF,gBACE,UACA,YACA,iBACA,oBACA,4BACA,6BACA,gBACA,SACA,SCjDJ,YACI,sBACA,kBACA,cACA,+BACA,WACA,WACA,qCAEA,mBACE,WACA,cACA,sBACA,kBACA,UACA,WACA,iBACA,mBAGF,oBACE,WACA,cACA,sBACA,kBACA,UACA,WACA,iBACA,mBACA,SACA,UAGF,mBACE,YACA,WCnCN,SACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,mBAEA,iCACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,wBACA,SAGF,gBACE,WACA,WAGF,iBACE,WACA,QC5BN,eACI,cACA,kBACA,sBACA,6CACA,UACA,YACA,wBAEA,sBACE,WACA,cACA,sBACA,kBACA,UACA,WACA,yBAGF,uBACE,WACA,cACA,sBACA,kBACA,UACA,WACA,yBACA,sBACA,qBACA,UACA,QAGF,sBACE,uBACA,wBACA,WACA,QCrCN,WACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,mBACA,iBACA,gBAEA,kBACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,WACA,wBACA,yBACA,SACA,UCvBN,SACI,cACA,sBACA,wBACA,sBASA,iBACA,gBACA,kBACA,+BACA,UACA,WACA,kBAbA,iCACE,cACA,sBACA,wBACA,sBAWF,iCACE,WACA,kBACA,kBACA,WACA,WACA,QACA,SACA,WAGF,gBACE,UACA,QACA,WCnCN,QACI,kBACA,cACA,+BACA,WACA,YACA,iCACA,gCACA,gBACA,sBAEA,+BACE,WACA,cACA,oBACA,kBACA,sBAGF,eACE,QACA,8CACA,WACA,YAGF,gBACE,UACA,WACA,iBACA,WACA,SC/BN,UACI,iBACA,6BACA,8BACA,WACA,WACA,gBAeA,sBACA,kBACA,gHACA,cAhBA,iBACE,iBACA,6BACA,8BACA,WACA,WACA,gBACA,WACA,cACA,sBACA,kBAQF,kBACE,WACA,cACA,sBACA,kBAGF,iBACE,WACA,wBACA,QAGF,kBACE,WACA,YACA,sBACA,wBACA,UACA,QC7CN,YACI,sBACA,kBACA,cACA,+BACA,WACA,YACA,iBACA,gBACA,0CAEA,mBACE,WACA,cACA,sBACA,kBACA,UAGF,oBACE,WACA,cACA,sBACA,kBACA,UACA,iBACA,+BACA,+BACA,UACA,YACA,WAGF,mBACE,WACA,wBACA,qBACA,SACA,QCtCN,UACI,sBACA,kBACA,cACA,+BACA,UACA,WACA,wBACA,oBACA,kCAEA,iBACE,WACA,cACA,sBACA,kBACA,kBACA,WACA,WACA,wBACA,SAGF,kBACE,WACA,cACA,sBACA,kBACA,kBACA,WACA,WACA,wBACA,SACA,MACA,yBAGF,iBACE,SACA,wBCvCN,sBACI,sBACA,kBACA,cACA,+BACA,WACA,WACA,iBACA,aACA,8BACA,+BACA,eAEA,6BACE,WACA,cACA,sBACA,kBACA,UACA,WACA,sBACA,wBACA,yBACA,SACA,WAGF,8BACE,WACA,cACA,sBACA,kBACA,kBACA,UACA,YACA,wBACA,SACA,WCrCN,UACI,cACA,sBACA,iBAQA,2BACA,4BACA,gBACA,gBACA,kBACA,6CACA,WACA,YAbA,mCACE,cACA,sBACA,iBAYF,mCACE,WACA,kBACA,UACA,WACA,QACA,UACA,uBACA,mBAGF,iBACE","file":"cssgg.min.css"}
|
||||
+29
-25
@@ -8,29 +8,33 @@
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<p class="title">About this instance</p>
|
||||
<p>Frontend version: {version_frontend()}</p>
|
||||
<p>Scraper version: {version_scraper()}</p>
|
||||
<hr />
|
||||
<p class="title">Why would I want to use ProxiTok?</p>
|
||||
<p>
|
||||
There are already
|
||||
<a rel="nofollow" href="https://penetrum.com/tiktok/Penetrum_TikTok_Security_Analysis_whitepaper.pdf">multiple</a>
|
||||
<a rel="nofollow" href="https://rufposten.de/blog/2019/12/05/privacy-analysis-of-tiktoks-app-and-website">articles</a>
|
||||
<a rel="nofollow" href="https://citizenlab.ca/2021/03/tiktok-vs-douyin-security-privacy-analysis">explaining</a>
|
||||
Tiktok's privacy issues.
|
||||
This program allows you to browse TikTok without having to worry about privacy concerns.
|
||||
</p>
|
||||
<hr />
|
||||
<p class="title">Third party</p>
|
||||
<p>
|
||||
This project wouldn't be possible without the help of the following projects:
|
||||
<ul>
|
||||
<li><a rel="nofollow" href="https://github.com/pablouser1/TikScraperPHP">TikScraperPHP</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/nette/latte">Latte</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/bramus/router">bramus/router</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/josegonzalez/php-dotenv">php-dotenv</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/jgthms/bulma">Bulma</a> and <a href="https://github.com/jenil/bulmaswatch">Bulmaswatch</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
<div class="content">
|
||||
<p class="title">About this instance</p>
|
||||
<p>Frontend version: <b>{version_frontend()}</b></p>
|
||||
<p>Scraper version: <b>{version_scraper()}</b></p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p class="title">Why would I want to use ProxiTok?</p>
|
||||
<p>
|
||||
There are already
|
||||
<a rel="nofollow" href="https://penetrum.com/tiktok/Penetrum_TikTok_Security_Analysis_whitepaper.pdf">multiple</a>
|
||||
<a rel="nofollow" href="https://rufposten.de/blog/2019/12/05/privacy-analysis-of-tiktoks-app-and-website">articles</a>
|
||||
<a rel="nofollow" href="https://citizenlab.ca/2021/03/tiktok-vs-douyin-security-privacy-analysis">explaining</a>
|
||||
Tiktok's privacy issues.
|
||||
This program allows you to browse TikTok without having to worry about privacy concerns.
|
||||
</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p class="title">Third party</p>
|
||||
<p>
|
||||
This project wouldn't be possible without the help of the following projects:
|
||||
<ul>
|
||||
<li><a rel="nofollow" href="https://github.com/pablouser1/TikScraperPHP">TikScraperPHP</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/nette/latte">Latte</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/bramus/router">bramus/router</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/josegonzalez/php-dotenv">php-dotenv</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/jgthms/bulma">Bulma</a> and <a href="https://github.com/jenil/bulmaswatch">Bulmaswatch</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
+13
-5
@@ -2,9 +2,17 @@
|
||||
|
||||
{block content}
|
||||
<p class="title">There was an error processing your request!</p>
|
||||
<p class="subtitle">HTTP Code: {$error->http_code}</p>
|
||||
<p class="subtitle">API error code {$error->tiktok_code} ({$error->tiktok_msg})</p>
|
||||
{if $error->tiktok_code === 10000 || $error->tiktok_code === -1}
|
||||
<a href="{path('/verify')}">What does this mean?</a>
|
||||
{/if}
|
||||
<div class="content">
|
||||
<p>HTTP Code: {$http_code}</p>
|
||||
{if isset($tiktok_code)}
|
||||
<p>
|
||||
<span>API error code {$tiktok_code} ({$msg})</span>
|
||||
{if $tiktok_code === 10000 || $tiktok_code === -1}
|
||||
<a href="{path('/verify')}">What does this mean?</a>
|
||||
{/if}
|
||||
</p>
|
||||
{else}
|
||||
<p>{$msg}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
+10
-8
@@ -1,22 +1,24 @@
|
||||
{layout "../layouts/{$layout}.latte"}
|
||||
|
||||
{block content}
|
||||
<div class="columns is-centered is-vcentered is-gapless">
|
||||
<div class="column is-three-quarters">
|
||||
<video controls autoplay playsinline poster="{path('/stream?url=' . urlencode($item->video->originCover))}">
|
||||
<source src="{path('/stream?url=' . urlencode($item->video->playAddr))}" type="video/mp4" />
|
||||
<div class="columns has-text-centered is-centered is-vcentered is-gapless">
|
||||
<div class="column">
|
||||
<video controls autoplay poster="{url_stream($item->video->originCover)}">
|
||||
<source src="{url_stream($item->video->playAddr)}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
<div class="column has-text-centered">
|
||||
<div class="column">
|
||||
<div class="box">
|
||||
<p class="title">Video by <a href="{path('/@'.$detail->uniqueId)}">{$detail->uniqueId}</a></p>
|
||||
<p class="title">Video by <a href="{url_user($detail->uniqueId)}">{$detail->uniqueId}</a></p>
|
||||
<p class="subtitle">{$item->desc}</p>
|
||||
{include '../components/themes/common/stats.latte', playCount: $item->stats->playCount, diggCount: $item->stats->diggCount, commentCount: $item->stats->commentCount, shareCount: $item->stats->shareCount}
|
||||
<div class="container mt-4">
|
||||
<p>{include '../components/icon.latte', icon: 'music', text: $item->music->title}</p>
|
||||
<audio src="{url_stream($item->music->playUrl)}" controls preload="none"></audio>
|
||||
</div>
|
||||
<hr />
|
||||
{include '../components/themes/common/share.latte', uniqueId: $detail->uniqueId, id: $item->id}
|
||||
{include '../components/themes/common/download.latte', playAddr: $item->video->playAddr, id: $item->id, uniqueId: $detail->uniqueId}
|
||||
<p>{$item->music->title}</p>
|
||||
<audio src="{path('/stream?url=' . urlencode($item->music->playUrl))}" controls preload="none"></audio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user