mirror of
https://github.com/pablouser1/ProxiTok.git
synced 2024-12-06 19:27:30 +01:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6eee156541 | |||
| c682432920 | |||
| d061c210a2 | |||
| 3b5c3cd96c | |||
| 1b29950d89 | |||
| 8ece2c2b25 | |||
| 7ba324c935 | |||
| 9c95620384 | |||
| 7b5ec2211e | |||
| 2bdd433a17 | |||
| b8f8eb710f | |||
| c62df9d631 | |||
| 605e204453 | |||
| 7011867fd8 | |||
| a4a4b0497c | |||
| f1de8e979b | |||
| 1e1376506c | |||
| 198c88a1d7 | |||
| 73dd93420f | |||
| db3799c344 | |||
| 1eb6626153 | |||
| c413017b00 | |||
| 669c0d29d4 | |||
| 58170665ed | |||
| d60e4400a2 | |||
| c47d6cd6d4 | |||
| 279a4f50c6 | |||
| 9711bb903c | |||
| a11a17f9d2 | |||
| c690adab63 | |||
| 1d37d8c417 | |||
| 90cf0bfb56 |
+14
-3
@@ -1,9 +1,20 @@
|
||||
# APP_URL="http://localhost:8000" # Full url path, PLEASE REPLACE TO YOUR OWN ONE
|
||||
# SIGNER_URL="https://tiktok-sign.herokuapp.com/signature" # External signing service
|
||||
# LATTE_CACHE=/tmp/proxitok_api # Path for Latte cache, leave commented for ./cache/latte
|
||||
# API_CACHE=redis # Cache engine for TikTok Api, (more info on README)
|
||||
|
||||
# Redis cache, used on Helpers\CacheEngines\RedisCache
|
||||
# API CONFIG
|
||||
# API_FORCE_LEGACY=1 # Force legacy mode for wrapper
|
||||
# API_SIGNER_URL="https://example.com" # External signing service
|
||||
# API_BROWSER_URL="http://localhost:4444" # chromedriver url
|
||||
# API_TEST_ENDPOINTS=1 # Discomment for usage of testing TikTok endpoints, may help sometimes
|
||||
# API_CACHE=redis
|
||||
|
||||
# Proxy Config, will be used to make TikTok requests, useful if having VERIFY_CODE issues
|
||||
# PROXY_HOST=HOSTNAME
|
||||
# PROXY_PORT=8080
|
||||
# PROXY_USERNAME=USERNAME
|
||||
# PROXY_PASSWORD=PASSWORD
|
||||
|
||||
# Redis cache, used on Helpers\CacheEngines\RedisCache (CHOOSE ONE)
|
||||
# REDIS_HOST=localhost # Host or path to unix socket
|
||||
# REDIS_PORT=6379 # Set to -1 to use unix socket
|
||||
# REDIS_PASSWORD=example # Leave commented for no password
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
RewriteEngine on
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule . index.php [L]
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
|
||||
# Disable index view
|
||||
Options -Indexes
|
||||
|
||||
# Hide a specific file
|
||||
<Files .env>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
|
||||
@@ -1 +1 @@
|
||||
web: vendor/bin/heroku-php-apache2
|
||||
web: vendor/bin/heroku-php-nginx -C setup/nginx_heroku.conf
|
||||
|
||||
@@ -8,16 +8,30 @@ Use Tiktok with an alternative frontend, inspired by Nitter.
|
||||
* See tags
|
||||
* See video by id
|
||||
* Discovery
|
||||
* Create a following list, which you can later use to see all the feeds from those users
|
||||
* RSS Feed for user, trending and tag (just add /rss to the url)
|
||||
|
||||
## Extensions
|
||||
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):
|
||||
```
|
||||
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
|
||||
Pattern type: Regular Expression
|
||||
Apply to: Main window (address bar)
|
||||
```
|
||||
|
||||
## Installation
|
||||
Clone the repository and fetch the requiered external packages with:
|
||||
```bash
|
||||
composer install
|
||||
```
|
||||
|
||||
WARNING: You'll need a personal Github token for composer.
|
||||
Move the .env.example file to .env and modify it.
|
||||
|
||||
Then you can run it using for example the PHP Development Server with:
|
||||
```bash
|
||||
@@ -25,9 +39,6 @@ php -S localhost:8080
|
||||
```
|
||||
|
||||
## Configuration
|
||||
### .env
|
||||
Move the .env.example file to .env and modify it.
|
||||
|
||||
### Cache engines
|
||||
Available cache engines:
|
||||
* redis: Writes response to Redis
|
||||
@@ -37,30 +48,26 @@ Available cache engines:
|
||||
You don't have to do anything more
|
||||
|
||||
### Nginx
|
||||
Add the following to your config (you can modify the proxitok part if you have or not a subdir):
|
||||
```
|
||||
location /proxitok {
|
||||
return 302 $scheme://$host/proxitok/;
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location /proxitok/ {
|
||||
try_files $uri $uri/ /proxitok/index.php?$query_string;
|
||||
}
|
||||
|
||||
location /proxitok/.env {
|
||||
location /.env {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
```
|
||||
|
||||
## TODO
|
||||
## TODO / Known issues
|
||||
* Docker
|
||||
* Full installation instructions
|
||||
* Add a NoJS version / Make the whole program without required JS
|
||||
* Better error handling
|
||||
* Make video on /video fit screen and don't overflow
|
||||
* i18n
|
||||
|
||||
## Credits
|
||||
* [TikScraper](https://github.com/pablouser1/TikScraperPHP)
|
||||
* [TikScraperPHP](https://github.com/pablouser1/TikScraperPHP)
|
||||
* [Latte](https://github.com/nette/latte)
|
||||
* [bramus/router](https://github.com/bramus/router)
|
||||
* [PHP dotenv](https://github.com/vlucas/phpdotenv)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<?php
|
||||
namespace App\Cache;
|
||||
|
||||
use App\Helpers\Misc;
|
||||
|
||||
class JSONCache {
|
||||
private string $cache_path = '';
|
||||
private string $cache_path = __DIR__ . '/../../cache/api';
|
||||
|
||||
function __construct() {
|
||||
$this->cache_path = Misc::env('API_CACHE_JSON', __DIR__ . '/../../cache/api');
|
||||
if (isset($_ENV['API_CACHE_JSON']) && !empty($_ENV['API_CACHE_JSON'])) {
|
||||
$this->cache_path = $_ENV['API_CACHE_JSON'];
|
||||
}
|
||||
}
|
||||
|
||||
public function get(string $cache_key): ?object {
|
||||
$filename = $this->cache_path . '/' . $cache_key . '.json';
|
||||
if (is_file($filename)) {
|
||||
@@ -25,7 +24,7 @@ class JSONCache {
|
||||
return is_file($filename);
|
||||
}
|
||||
|
||||
public function set(string $cache_key, string $data, $timeout = 3600) {
|
||||
public function set(string $cache_key, mixed $data, $timeout = 3600) {
|
||||
file_put_contents($this->cache_path . '/' . $cache_key . '.json', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class RedisCache {
|
||||
return $this->client->exists($cache_key);
|
||||
}
|
||||
|
||||
public function set(string $cache_key, array $data, $timeout = 3600) {
|
||||
$this->client->set($cache_key, json_encode($data), $timeout);
|
||||
public function set(string $cache_key, string $data, $timeout = 3600) {
|
||||
$this->client->set($cache_key, $data, $timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace App\Controllers;
|
||||
|
||||
use App\Helpers\ErrorHandler;
|
||||
use App\Helpers\Misc;
|
||||
use App\Models\DiscoverTemplate;
|
||||
use App\Models\FeedTemplate;
|
||||
|
||||
class DiscoverController {
|
||||
static public function get() {
|
||||
@@ -11,7 +11,7 @@ class DiscoverController {
|
||||
$feed = $api->getDiscover();
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('discover'), new DiscoverTemplate($feed));
|
||||
$latte->render(Misc::getView('discover'), new FeedTemplate('Discover', $feed));
|
||||
} else {
|
||||
ErrorHandler::show($feed->meta);
|
||||
}
|
||||
|
||||
@@ -39,25 +39,25 @@ class ProxyController {
|
||||
}
|
||||
|
||||
static public function stream() {
|
||||
if (isset($_GET['download'])) {
|
||||
$downloader = new \TikScraper\Download();
|
||||
$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);
|
||||
}
|
||||
} else {
|
||||
self::checkUrl();
|
||||
$url = $_GET['url'];
|
||||
$streamer = new \TikScraper\Stream();
|
||||
$streamer->url($url);
|
||||
}
|
||||
|
||||
static public function download() {
|
||||
$downloader = new \TikScraper\Download();
|
||||
$watermark = isset($_GET['watermark']);
|
||||
if ($watermark) {
|
||||
self::checkUrl();
|
||||
$url = $_GET['url'];
|
||||
$streamer = new \TikScraper\Stream();
|
||||
$streamer->url($url);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ class RedirectController {
|
||||
} else if (isset($_GET['music'])) {
|
||||
$endpoint = '/music/' . $_GET['music'];
|
||||
} else if (isset($_GET['video'])) {
|
||||
$endpoint = '/video/' . $_GET['video'];
|
||||
// The @username part is not used, but
|
||||
// it is the schema that TikTok follows
|
||||
$endpoint = '/@placeholder/video/' . $_GET['video'];
|
||||
}
|
||||
|
||||
$url = Misc::url($endpoint);
|
||||
|
||||
@@ -8,7 +8,12 @@ use App\Models\SettingsTemplate;
|
||||
class SettingsController {
|
||||
static public function index() {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('settings'), new SettingsTemplate());
|
||||
$latte->render(Misc::getView('settings'), new SettingsTemplate);
|
||||
}
|
||||
|
||||
static private function redirect() {
|
||||
$url = Misc::url('/settings');
|
||||
header("Location: {$url}");
|
||||
}
|
||||
|
||||
static public function proxy() {
|
||||
@@ -17,7 +22,15 @@ class SettingsController {
|
||||
Cookies::set($proxy_element, $_POST[$proxy_element]);
|
||||
}
|
||||
}
|
||||
$url = Misc::url('/settings');
|
||||
header("Location: {$url}");
|
||||
self::redirect();
|
||||
}
|
||||
|
||||
static public function api() {
|
||||
$legacy = 'off';
|
||||
if (isset($_POST['api-legacy'])) {
|
||||
$legacy = 'on';
|
||||
}
|
||||
Cookies::set('api-legacy', $legacy);
|
||||
self::redirect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,16 @@ use App\Helpers\RSS;
|
||||
|
||||
class TrendingController {
|
||||
static public function get() {
|
||||
$cursor = Misc::getCursor();
|
||||
$page = $_GET['page'] ?? 0;
|
||||
$cursor = Misc::getTtwid();
|
||||
$api = Misc::api();
|
||||
$feed = $api->getTrending($cursor, $page);
|
||||
|
||||
// Ttwid if normal, cursor if legacy
|
||||
if ($api::class === 'TikScraper\Api') {
|
||||
$cursor = Misc::getTtwid();
|
||||
} else {
|
||||
$cursor = Misc::getCursor();
|
||||
}
|
||||
$feed = $api->getTrending($cursor);
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('trending'), new FeedTemplate('Trending', $feed));
|
||||
|
||||
@@ -13,8 +13,9 @@ class UserController {
|
||||
$feed = $api->getUserFeed($username, $cursor);
|
||||
if ($feed->meta->success) {
|
||||
if ($feed->info->detail->privateAccount) {
|
||||
http_response_code(400);
|
||||
http_response_code(403);
|
||||
echo 'Private account detected! Not supported';
|
||||
exit;
|
||||
}
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('user'), new FeedTemplate($feed->info->detail->nickname, $feed));
|
||||
@@ -23,6 +24,17 @@ class UserController {
|
||||
}
|
||||
}
|
||||
|
||||
static public function video(string $username, string $video_id) {
|
||||
$api = Misc::api();
|
||||
$feed = $api->getVideoByID($video_id);
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('video'), new FeedTemplate('Video', $feed));
|
||||
} else {
|
||||
ErrorHandler::show($feed->meta);
|
||||
}
|
||||
}
|
||||
|
||||
static public function rss(string $username) {
|
||||
$api = Misc::api();
|
||||
$feed = $api->getUserFeed($username);
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
<?php
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Helpers\ErrorHandler;
|
||||
use App\Helpers\Misc;
|
||||
use App\Models\FeedTemplate;
|
||||
|
||||
/**
|
||||
* @deprecated Please use UserController::video instead
|
||||
*/
|
||||
class VideoController {
|
||||
static public function get(string $video_id) {
|
||||
$api = Misc::api();
|
||||
$item = $api->getVideoByID($video_id);
|
||||
if ($item->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('video'), new FeedTemplate($item->info->detail->nickname, $item));
|
||||
} else {
|
||||
ErrorHandler::show($item->meta);
|
||||
}
|
||||
UserController::video('placeholder', $video_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
namespace App\Helpers;
|
||||
|
||||
class Cookies {
|
||||
const PROXY = ['proxy-host', 'proxy-port', 'proxy-username', 'proxy-password'];
|
||||
const PROXY = ['host', 'port', 'user', 'password'];
|
||||
|
||||
static public function get(string $name): string {
|
||||
static public function get(string $name): ?string {
|
||||
if (isset($_COOKIE[$name]) && !empty($_COOKIE[$name])) {
|
||||
return $_COOKIE[$name];
|
||||
}
|
||||
return '';
|
||||
return null;
|
||||
}
|
||||
|
||||
static public function exists(string $name): bool {
|
||||
|
||||
+29
-9
@@ -9,12 +9,16 @@ class Misc {
|
||||
return isset($_GET['cursor']) && is_numeric($_GET['cursor']) ? (int) $_GET['cursor'] : 0;
|
||||
}
|
||||
|
||||
static public function getTtwid(): string {
|
||||
return $_GET['cursor'] ?? '';
|
||||
}
|
||||
|
||||
static public function url(string $endpoint = '') {
|
||||
return self::env('APP_URL', '') . $endpoint;
|
||||
}
|
||||
|
||||
static public function env(string $key, string $default_value): string {
|
||||
return isset($_ENV[$key]) && !empty($_ENV[$key]) ? $_ENV[$key] : $default_value;
|
||||
static public function env(string $key, $default_value) {
|
||||
return $_ENV[$key] ?? $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,19 +30,32 @@ class Misc {
|
||||
|
||||
/**
|
||||
* Setup of TikTok Api wrapper
|
||||
* @return \TikScraper\Api|\TikScraper\Legacy
|
||||
*/
|
||||
static public function api(): \TikScraper\Api {
|
||||
static public function api() {
|
||||
$options = [
|
||||
'remote_signer' => self::env('SIGNER_URL', 'http://localhost:8080/signature')
|
||||
'use_test_endpoints' => self::env('API_TEST_ENDPOINTS', false),
|
||||
// Instance level proxy config
|
||||
'proxy' => [
|
||||
'host' => self::env('PROXY_HOST', null),
|
||||
'port' => self::env('PROXY_PORT', null),
|
||||
'user' => self::env('PROXY_USER', null),
|
||||
'password' => self::env('PROXY_PASSWORD', null)
|
||||
],
|
||||
'signer' => [
|
||||
'remote_url' => self::env('API_SIGNER_URL', ''),
|
||||
'browser_url' => self::env('API_BROWSER_URL', ''),
|
||||
'close_when_done' => false
|
||||
]
|
||||
];
|
||||
$cacheEngine = false;
|
||||
// Proxy config
|
||||
// User level proxy config, will overwrite instance config
|
||||
foreach(Cookies::PROXY as $proxy_element) {
|
||||
if (isset($_COOKIE[$proxy_element])) {
|
||||
$options['proxy'][$proxy_element] = $_COOKIE[$proxy_element];
|
||||
}
|
||||
}
|
||||
// Cache config
|
||||
$cacheEngine = false;
|
||||
if (isset($_ENV['API_CACHE'])) {
|
||||
switch ($_ENV['API_CACHE']) {
|
||||
case 'json':
|
||||
@@ -57,14 +74,17 @@ class Misc {
|
||||
} else {
|
||||
$host = $_ENV['REDIS_HOST'];
|
||||
$port = (int) $_ENV['REDIS_PORT'];
|
||||
$password = $_ENV['REDIS_PASSWORD'] ?? null;
|
||||
$password = isset($_ENV['REDIS_PASSWORD']) ? $_ENV['REDIS_PASSWORD'] : null;
|
||||
}
|
||||
$cacheEngine = new RedisCache($host, $port, $password);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$api = new \TikScraper\Api($options, $cacheEngine);
|
||||
return $api;
|
||||
|
||||
// Legacy mode
|
||||
$legacy = self::env('API_FORCE_LEGACY', false) || isset($_COOKIE['api-legacy']) && $_COOKIE['api-legacy'] === 'on';
|
||||
|
||||
return $legacy === false ? new \TikScraper\Api($options, $cacheEngine) : new \TikScraper\Legacy($options, $cacheEngine);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
namespace App\Helpers;
|
||||
|
||||
use \FeedWriter\RSS2;
|
||||
use \Sovit\TikTok\Download;
|
||||
use \TikScraper\Download;
|
||||
|
||||
class RSS {
|
||||
static public function build(string $endpoint, string $title, string $description, array $items): string {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use TikScraper\Models\Discover;
|
||||
|
||||
/**
|
||||
* Base for templates with a feed
|
||||
*/
|
||||
class DiscoverTemplate extends BaseTemplate {
|
||||
public Discover $feed;
|
||||
|
||||
function __construct(Discover $feed) {
|
||||
parent::__construct('Discover');
|
||||
$this->feed = $feed;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use TikScraper\Models\Feed;
|
||||
|
||||
/**
|
||||
* Base for templates with a feed
|
||||
*/
|
||||
class FeedTemplate extends BaseTemplate {
|
||||
public Feed $feed;
|
||||
public object $feed;
|
||||
|
||||
function __construct(string $title, Feed $feed) {
|
||||
function __construct(string $title, object $feed) {
|
||||
parent::__construct($title);
|
||||
$this->feed = $feed;
|
||||
}
|
||||
|
||||
+13
-6
@@ -6,8 +6,8 @@
|
||||
{do $share_url = 'https://tiktok.com/@' . $item->author->uniqueId . '/video/' . $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('/stream?url=' . urlencode($item->video->playAddr) . '&download=1&id=' . $item->id . '&user=' . $item->author->uniqueId) . '&watermark='}"
|
||||
data-video_download_nowatermark="{path('/stream?download=1&id=' . $item->id . '&user=' . $item->author->uniqueId)}"
|
||||
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_share_url="{$share_url}"
|
||||
data-desc="{$item->desc}"
|
||||
data-music_title="{$item->music->title}"
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<div n:ifset="$feed->info" class="buttons">
|
||||
{if isset($_GET['cursor']) && $_GET['cursor'] != 0 }
|
||||
<a class="button is-danger" href="?">First</a>
|
||||
<button class="button is-danger" onclick="history.back()">Back</button>
|
||||
@@ -47,9 +47,16 @@
|
||||
<button class="button is-primary" onclick="copyShare()">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons is-centered">
|
||||
<a target="_blank" id="download_watermark" class="button is-info">Download with watermark</a>
|
||||
<a target="_blank" id="download_nowatermark" class="button is-info">Download without watermark</a>
|
||||
<div id="download_dropdown" class="dropdown is-hoverable">
|
||||
<div class="dropdown-trigger">
|
||||
<button id="download_button" class="button" aria-haspopup="true" aria-controls="dropdown-menu">Download</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a id="download_watermark" target="_blank" class="dropdown-item">With watermark</a>
|
||||
<a id="download_nowatermark" target="_blank" class="dropdown-item">Without watermark</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p id="audio_title"></p>
|
||||
<audio id="audio" controls preload="none"></audio>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<div class="tags">
|
||||
{if !empty($following)}
|
||||
{foreach $following as $user}
|
||||
<span class="tag">{$user}</span>
|
||||
{/foreach}
|
||||
{else}
|
||||
<p>None</p>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta property="og:title" content="ProxiTok" />
|
||||
<meta property="og:description" content="Alternative frontend for TikTok" />
|
||||
<meta property="og:type" content="website" />
|
||||
<link rel="stylesheet" href="{path('/styles/bulma.min.css')}">
|
||||
<!-- <link rel="stylesheet" href="{path('/styles/vendor/fontawesome.min.css')}"> -->
|
||||
<link rel="stylesheet" href="{path('/styles/vendor/bulma.min.css')}">
|
||||
<title>{$title} - ProxiTok</title>
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<form action="{path('/settings/api')}" method="POST">
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input name="api-legacy" type="checkbox"
|
||||
checked="{isset($_COOKIE['api-legacy']) && $_COOKIE['api-legacy'] === 'on' ? 'true' : 'false'}"
|
||||
value="{isset($_COOKIE['api-legacy']) ? $_COOKIE['api-legacy'] : 'off'}">Enable legacy mode
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button class="button is-success" type="submit">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,7 +1,7 @@
|
||||
<form action="{path('/settings/proxy')}" method="POST">
|
||||
{foreach $proxy_elements as $proxy_element}
|
||||
<div class="field">
|
||||
<label class="label">{$proxy_element}</label>
|
||||
<label class="label">{$proxy_element|firstUpper}</label>
|
||||
<div class="control">
|
||||
<input name="{$proxy_element}" class="input" value="{isset($_COOKIE[$proxy_element]) ? $_COOKIE[$proxy_element] : ''}" required />
|
||||
</div>
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pablouser1/proxitok",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "1.5.0",
|
||||
"version": "2.1.0.1",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"type": "project",
|
||||
"homepage": "https://github.com/pablouser1/ProxiTok",
|
||||
@@ -14,11 +14,11 @@
|
||||
"require": {
|
||||
"ext-redis": "^5.3.2",
|
||||
"ext-mbstring": "*",
|
||||
"pablouser1/tikscraper": "^1.0",
|
||||
"latte/latte": "^2.10",
|
||||
"vlucas/phpdotenv": "^5.4",
|
||||
"bramus/router": "^1.6",
|
||||
"mibe/feedwriter": "^1.1"
|
||||
"mibe/feedwriter": "^1.1",
|
||||
"pablouser1/tikscraper": "^1.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+187
-29
@@ -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": "f5e451a254a58bf7d512421237641801",
|
||||
"content-hash": "f6b066c447574f88ad9255a88892659e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bramus/router",
|
||||
@@ -121,16 +121,16 @@
|
||||
},
|
||||
{
|
||||
"name": "latte/latte",
|
||||
"version": "v2.10.8",
|
||||
"version": "v2.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/latte.git",
|
||||
"reference": "596b28bf098ebb852732d60b00538139a009c4db"
|
||||
"reference": "a815687bfadaf3af51ae99f92edb4ea310c43426"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/596b28bf098ebb852732d60b00538139a009c4db",
|
||||
"reference": "596b28bf098ebb852732d60b00538139a009c4db",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/a815687bfadaf3af51ae99f92edb4ea310c43426",
|
||||
"reference": "a815687bfadaf3af51ae99f92edb4ea310c43426",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -161,7 +161,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.10-dev"
|
||||
"dev-master": "2.11-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -199,9 +199,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/latte/issues",
|
||||
"source": "https://github.com/nette/latte/tree/v2.10.8"
|
||||
"source": "https://github.com/nette/latte/tree/v2.11.0"
|
||||
},
|
||||
"time": "2022-01-04T14:13:28+00:00"
|
||||
"time": "2022-02-22T18:39:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mibe/feedwriter",
|
||||
@@ -306,20 +306,22 @@
|
||||
},
|
||||
{
|
||||
"name": "pablouser1/tikscraper",
|
||||
"version": "v1.2.1",
|
||||
"version": "v1.3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pablouser1/TikScraperPHP.git",
|
||||
"reference": "2022b2c2d661383d09c4727091df7fae345844a5"
|
||||
"reference": "793dde26e17362af304b9f50890c7fc178387629"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/2022b2c2d661383d09c4727091df7fae345844a5",
|
||||
"reference": "2022b2c2d661383d09c4727091df7fae345844a5",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/793dde26e17362af304b9f50890c7fc178387629",
|
||||
"reference": "793dde26e17362af304b9f50890c7fc178387629",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3|^8.0"
|
||||
"php": ">=7.3|^8.0",
|
||||
"php-webdriver/webdriver": "^1.12",
|
||||
"sapistudio/seleniumstealth": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -339,9 +341,74 @@
|
||||
"description": "Get data from TikTok API",
|
||||
"support": {
|
||||
"issues": "https://github.com/pablouser1/TikScraperPHP/issues",
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v1.2.1"
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v1.3.0.3"
|
||||
},
|
||||
"time": "2022-02-13T20:28:38+00:00"
|
||||
"time": "2022-03-13T20:53:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
"version": "1.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-webdriver/php-webdriver.git",
|
||||
"reference": "99d4856ed7dffcdf6a52eccd6551e83d8d557ceb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/99d4856ed7dffcdf6a52eccd6551e83d8d557ceb",
|
||||
"reference": "99d4856ed7dffcdf6a52eccd6551e83d8d557ceb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^5.6 || ~7.0 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.12",
|
||||
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"replace": {
|
||||
"facebook/webdriver": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
|
||||
"php-coveralls/php-coveralls": "^2.4",
|
||||
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "For Firefox profile creation"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/Exception/TimeoutException.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
|
||||
"homepage": "https://github.com/php-webdriver/php-webdriver",
|
||||
"keywords": [
|
||||
"Chromedriver",
|
||||
"geckodriver",
|
||||
"php",
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.0"
|
||||
},
|
||||
"time": "2021-10-14T09:30:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
@@ -414,9 +481,39 @@
|
||||
],
|
||||
"time": "2021-12-04T23:24:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sapistudio/seleniumstealth",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Sapistudio/SeleniumStealth.git",
|
||||
"reference": "4b392077e3d609fed564b78ae2e8becb98f01957"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Sapistudio/SeleniumStealth/zipball/4b392077e3d609fed564b78ae2e8becb98f01957",
|
||||
"reference": "4b392077e3d609fed564b78ae2e8becb98f01957",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SapiStudio\\SeleniumStealth\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Sapistudio/SeleniumStealth/issues",
|
||||
"source": "https://github.com/Sapistudio/SeleniumStealth/tree/1.0.3"
|
||||
},
|
||||
"time": "2022-01-10T20:04:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.24.0",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
@@ -448,12 +545,12 @@
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
@@ -478,7 +575,7 @@
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -498,7 +595,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.24.0",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
@@ -561,7 +658,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -581,16 +678,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.24.0",
|
||||
"version": "v1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
|
||||
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
|
||||
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
|
||||
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -644,7 +741,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -660,7 +757,68 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-09-13T13:58:33+00:00"
|
||||
"time": "2022-03-04T08:16:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v6.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "1ccceccc6497e96f4f646218f04b97ae7d9fa7a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/1ccceccc6497e96f4f646218f04b97ae7d9fa7a1",
|
||||
"reference": "1ccceccc6497e96f4f646218f04b97ae7d9fa7a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Process\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v6.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-30T18:19:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
|
||||
+12
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
/** @var \Bramus\Router\Router $router */
|
||||
use App\Helpers\Misc;
|
||||
use App\Models\BaseTemplate;
|
||||
use App\Models\HomeTemplate;
|
||||
@@ -13,7 +14,13 @@ $router->get('/about', function () {
|
||||
$latte->render(Misc::getView('about'), new BaseTemplate('About'));
|
||||
});
|
||||
|
||||
$router->get('/verify', function () {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('verify'), new BaseTemplate('Verify'));
|
||||
});
|
||||
|
||||
$router->get('/stream', 'ProxyController@stream');
|
||||
$router->get('/download', 'ProxyController@download');
|
||||
$router->get('/redirect', 'RedirectController@redirect');
|
||||
|
||||
$router->mount('/trending', function () use ($router) {
|
||||
@@ -23,9 +30,13 @@ $router->mount('/trending', function () use ($router) {
|
||||
|
||||
$router->mount('/@([^/]+)', function () use ($router) {
|
||||
$router->get('/', 'UserController@get');
|
||||
$router->get('/video/(\w+)', 'UserController@video');
|
||||
$router->get('/rss', 'UserController@rss');
|
||||
});
|
||||
|
||||
/**
|
||||
* @deprecated Please use /@username/video/id instead
|
||||
*/
|
||||
$router->get('/video/(\w+)', 'VideoController@get');
|
||||
|
||||
$router->mount('/tag', function () use ($router) {
|
||||
@@ -39,6 +50,7 @@ $router->get('/music/([^/]+)', 'MusicController@get');
|
||||
$router->mount('/settings', function () use ($router) {
|
||||
$router->get('/', 'SettingsController@index');
|
||||
$router->post('/proxy', 'SettingsController@proxy');
|
||||
$router->post('/api', 'SettingsController@api');
|
||||
});
|
||||
|
||||
$router->get('/discover', 'DiscoverController@get');
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
This facilities making the bulma.min.css and fontawesome.min.css files, install all dependencies using:
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
And then use:
|
||||
```
|
||||
yarn bulma && yarn fa
|
||||
```
|
||||
|
||||
This compiles bulma.scss and fontawesome.scss to a css file and helps lowering the size of the css that will be sent to the user.
|
||||
+1
@@ -25,6 +25,7 @@ $bulmaswatch-import-font: false;
|
||||
|
||||
// Components
|
||||
@import "./node_modules/bulma/sass/components/card.sass";
|
||||
@import "./node_modules/bulma/sass/components/dropdown.sass";
|
||||
@import "./node_modules/bulma/sass/components/modal.sass";
|
||||
@import "./node_modules/bulma/sass/components/navbar.sass";
|
||||
@import "./node_modules/bulma/sass/components/media.sass";
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
@import "./node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
||||
@import "./node_modules/@fortawesome/fontawesome-free/scss/solid.scss";
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "proxitok-scss",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bulma": "sass --style=compressed bulma.scss ./styles/vendor/bulma.min.css",
|
||||
"fa": "sass --style=compressed fontawesome.scss ./styles/vendor/fontawesome.min.css"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.0.0",
|
||||
"bulma": "^0.9.3",
|
||||
"bulmaswatch": "^0.8.1",
|
||||
"sass": "^1.46.0"
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,11 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@fortawesome/fontawesome-free@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.0.0.tgz#6f3bd8e42997c7d536a1246877ed8bcd4f005a54"
|
||||
integrity sha512-6LB4PYBST1Rx40klypw1SmSDArjFOcfBf2LeX9Zg5EKJT2eXiyiJq+CyBYKeXyK0sXS2FsCJWSPr/luyhuvh0Q==
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
@@ -113,9 +118,9 @@ readdirp@~3.6.0:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
sass@^1.46.0:
|
||||
version "1.49.7"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.7.tgz#22a86a50552b9b11f71404dfad1b9ff44c6b0c49"
|
||||
integrity sha512-13dml55EMIR2rS4d/RDHHP0sXMY3+30e1TKsyXaSz3iLWVoDWEoboY8WzJd5JMnxrRHffKO3wq2mpJ0jxRJiEQ==
|
||||
version "1.49.9"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9"
|
||||
integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
@@ -0,0 +1,15 @@
|
||||
location / {
|
||||
# try to serve file directly, fallback to rewrite
|
||||
try_files $uri @rewriteapp;
|
||||
}
|
||||
|
||||
location @rewriteapp {
|
||||
# rewrite all to index.php
|
||||
rewrite ^(.*)$ /index.php/$1 last;
|
||||
}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
try_files @heroku-fcgi @heroku-fcgi;
|
||||
# ensure that /index.php isn't accessible directly, but only through a rewrite
|
||||
internal;
|
||||
}
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,11 +0,0 @@
|
||||
This facilities making the bulma.min.css file, install all dependencies using:
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
And then use:
|
||||
```
|
||||
yarn bulma
|
||||
```
|
||||
|
||||
This compiles bulma.scss to a css file and helps lowering the size of the css that will be sent to the user.
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "proxitok-scss",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bulma": "sass --style=compressed bulma.scss ../bulma.min.css"
|
||||
},
|
||||
"dependencies": {
|
||||
"bulma": "^0.9.3",
|
||||
"bulmaswatch": "^0.8.1",
|
||||
"sass": "^1.46.0"
|
||||
}
|
||||
}
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
+6
-2
@@ -6,7 +6,11 @@
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<p class="title">Why?</p>
|
||||
<p class="title">About this instance</p>
|
||||
<p>Forcing Legacy mode: {isset($_ENV['API_FORCE_LEGACY']) ? 'yes' : 'no'}</p>
|
||||
<p>Instance-level Proxy: {isset($_ENV['PROXY_HOST']) ? 'yes' : 'no'}</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>
|
||||
@@ -20,7 +24,7 @@
|
||||
<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">TikScraper</a></li>
|
||||
<li><a rel="nofollow" href="https://github.com/ssovit/TikTok-API-PHP">TikTok-API-PHP</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/vlucas/phpdotenv">PHP dotenv</a></li>
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
<p class="subtitle">HTTP Code: {$error->http_code}</p>
|
||||
{if $error->tiktok_code}
|
||||
<p class="subtitle">API error code {$error->tiktok_code} ({$error->tiktok_msg})</p>
|
||||
{if $error->tiktok_code === 10000}
|
||||
<a href="{path('/verify')}">What does this mean?</a>
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
@@ -8,4 +8,7 @@
|
||||
<!-- Proxy settings -->
|
||||
<p class="title">Proxy</p>
|
||||
{include '../components/settings/proxy.latte'}
|
||||
<hr />
|
||||
<p class="title">Api</p>
|
||||
{include '../components/settings/api.latte'}
|
||||
{/block}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<p class="title">{$feed->info->detail->title}</p>
|
||||
<p class="subtitle">{$feed->info->detail->desc}</p>
|
||||
<p>Videos: {number($feed->info->stats->videoCount)} / Views: {number($feed->info->stats->viewCount)}</p>
|
||||
<a href="{path('tag/' . $feed->info->detail->title . '/rss')}">RSS</a>
|
||||
<a href="{path('/tag/' . $feed->info->detail->title . '/rss')}">RSS</a>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{block header}
|
||||
<p class="title">Trending</p>
|
||||
<a href="{path('trending/rss')}">RSS</a>
|
||||
<a href="{path('/trending/rss')}">RSS</a>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">VERIFY_CODE</p>
|
||||
<p class="subtitle">What can I do?</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<p>TL;DR You probably have to search for another instance or wait some hours (or even better, have your own self-hosted instance)</p>
|
||||
<p>TikTok has some mecanisms in order to stop scraping on their latest api (/api/...):</p>
|
||||
<hr />
|
||||
<div class="block">
|
||||
<p class="is-size-4">Rate limits</p>
|
||||
<p>
|
||||
This is pretty standard stuff,
|
||||
it blocks ips temporarly if you send too many requests to an endpoint and unbans you after some hours.
|
||||
</p>
|
||||
</div>
|
||||
<div class="block">
|
||||
<p class="is-size-4">IP Blacklist</p>
|
||||
<p>
|
||||
It is a list with IPs from popular Hosters (AWS, Heroku...). This IPs are banned <i>(I think) permanently</i> and
|
||||
can barely make requests.
|
||||
</p>
|
||||
<p>
|
||||
This makes hosting a public instance really hard. Even if you use a hosting platform that is not banned by TikTok, it is only a matter of time
|
||||
that it inevitably gets banned.
|
||||
</p>
|
||||
<p class="is-size-5">(For webmasters) How can I know if my server is not blacklisted?</p>
|
||||
<p>Run this command on your instance:</p>
|
||||
<code>
|
||||
curl \
|
||||
--url 'https://www.tiktok.com/@tiktok/?lang=en' \
|
||||
--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
|
||||
</code>
|
||||
<p>If you don't get an empty response or a captcha, you are good to go</p>
|
||||
</div>
|
||||
{/block}
|
||||
+17
-6
@@ -1,22 +1,33 @@
|
||||
{layout '../layouts/hero.latte'}
|
||||
|
||||
{block content}
|
||||
{do $item = $feed->items[0]}
|
||||
<div class="columns is-centered is-vcentered">
|
||||
<div class="column">
|
||||
<video controls poster="{path('/stream?url=' . urlencode($feed->items[0]->video->originCover))}">
|
||||
<source src="{path('/stream?url=' . urlencode($feed->items[0]->video->playAddr))}" type="video/mp4" />
|
||||
<video controls poster="{path('/stream?url=' . urlencode($item->video->originCover))}">
|
||||
<source src="{path('/stream?url=' . urlencode($item->video->playAddr))}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
<div class="column has-text-centered">
|
||||
<div class="box">
|
||||
<p class="title">Video by <a href="{path('/@'.$feed->info->detail->uniqueId)}">{$feed->info->detail->uniqueId}</a></p>
|
||||
<p class="subtitle">{$feed->items[0]->desc}</p>
|
||||
<p class="subtitle">{$item->desc}</p>
|
||||
<p>Played {number($feed->info->stats->playCount)} times</p>
|
||||
<p>Shared {number($feed->info->stats->shareCount)} times / {number($feed->info->stats->commentCount)} comments</p>
|
||||
<hr />
|
||||
<a href="{path('/stream?url=' . urlencode($feed->items[0]->video->playAddr) . '&download=1')}" class="button is-info">Download video</a>
|
||||
<p>{$feed->items[0]->music->title}</p>
|
||||
<audio src="{path('/stream?url=' . urlencode($feed->items[0]->music->playUrl))}" controls preload="none"></audio>
|
||||
<div class="dropdown is-hoverable">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button" aria-haspopup="true" aria-controls="dropdown-menu">Download</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a href="{path('/download?url=' . urlencode($item->video->playAddr) . '&id=' . $item->id . '&user=' . $item->author->uniqueId) . '&watermark='}" class="dropdown-item">Watermark</a>
|
||||
<a href="{path('/download?id=' . $item->id . '&user=' . $feed->info->detail->uniqueId)}" class="dropdown-item">No watermark</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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