mirror of
https://github.com/pablouser1/ProxiTok.git
synced 2024-12-06 19:27:30 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33c723d786 | |||
| faee8d58f2 | |||
| 75e13bc7d2 | |||
| 08145ee90b | |||
| 6194324452 | |||
| 48eccbc5ec | |||
| cac97ff05e | |||
| eeaa8cdf1c | |||
| ecba96eaf4 | |||
| 013feeb679 | |||
| bf86e0d36a | |||
| 72ea5d43fd | |||
| 288f87504c | |||
| 3d5890d821 | |||
| 5dea2468f8 | |||
| e8ec0ab293 | |||
| 78fe44070c |
@@ -1,5 +1,6 @@
|
||||
node_modules
|
||||
/.env
|
||||
/.git
|
||||
/.vscode
|
||||
/vendor
|
||||
/cache/latte/*
|
||||
|
||||
@@ -20,3 +20,5 @@
|
||||
# PROXY_PORT=8080
|
||||
# PROXY_USERNAME=username
|
||||
# PROXY_PASSWORD=password
|
||||
|
||||
# USER_AGENT="Mozilla/5.0 (Android 12; Mobile; rv:109.0) Gecko/109.0 Firefox/109.0"
|
||||
|
||||
@@ -3,16 +3,16 @@ namespace App\Controllers;
|
||||
|
||||
use App\Helpers\ErrorHandler;
|
||||
use App\Helpers\Wrappers;
|
||||
use App\Models\FeedTemplate;
|
||||
use App\Models\DiscoverTemplate;
|
||||
|
||||
class DiscoverController {
|
||||
static public function get() {
|
||||
$api = Wrappers::api();
|
||||
$feed = $api->discover();
|
||||
if ($feed->meta->success) {
|
||||
Wrappers::latte('discover', new FeedTemplate('Discover', $feed));
|
||||
$data = $api->discover();
|
||||
if ($data->meta->success) {
|
||||
Wrappers::latte('discover', new DiscoverTemplate($data));
|
||||
} else {
|
||||
ErrorHandler::showMeta($feed->meta);
|
||||
ErrorHandler::showMeta($data->meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Helpers\Cookies;
|
||||
use App\Helpers\Misc;
|
||||
use TikScraper\Constants\UserAgents as TikScraperUserAgents;
|
||||
|
||||
class ProxyController {
|
||||
const VALID_TIKTOK_DOMAINS = [
|
||||
@@ -11,7 +13,8 @@ class ProxyController {
|
||||
static public function stream() {
|
||||
self::checkUrl();
|
||||
$url = $_GET['url'];
|
||||
$streamer = new \TikScraper\Stream();
|
||||
$config['user_agent'] = Misc::env("USER_AGENT", TikScraperUserAgents::DEFAULT);
|
||||
$streamer = new \TikScraper\Stream($config);
|
||||
$streamer->url($url);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class RedirectController {
|
||||
* to_endpoint maps a TikTok URL into a ProxiTok-compatible endpoint URL.
|
||||
*/
|
||||
static private function to_endpoint(string $url): string {
|
||||
if (preg_match('%^(?:https?://|www\.)?(?:vm\.|vt\.)?tiktok\.com/(?:t/)?([A-Za-z0-9]+)%', $url, $m)) {
|
||||
if (preg_match('%^(?:https?://)?(?:www\.)?(?:vm\.|vt\.)?tiktok\.com/(?:t/)?([A-Za-z0-9]+)%', $url, $m)) {
|
||||
// Short video URL
|
||||
return '/@placeholder/video/' . $m[1];
|
||||
} elseif (preg_match('%^https://www\.tiktok\.com/(.+)%', $url, $m)) {
|
||||
|
||||
@@ -18,10 +18,6 @@ class UserController {
|
||||
if ($user->ok()) {
|
||||
$info = $user->getInfo();
|
||||
$feed = $user->getFeed();
|
||||
if ($info->detail->privateAccount) {
|
||||
ErrorHandler::showText(401, "Private account detected! Not supported");
|
||||
return;
|
||||
}
|
||||
Wrappers::latte('user', new FullTemplate($info->detail->nickname, $info, $feed));
|
||||
} else {
|
||||
ErrorHandler::showMeta($user->error());
|
||||
|
||||
@@ -7,6 +7,8 @@ use App\Cache\RedisCache;
|
||||
use App\Constants\CacheMethods;
|
||||
use App\Models\BaseTemplate;
|
||||
|
||||
use TikScraper\Constants\UserAgents as TikScraperUserAgents;
|
||||
|
||||
class Wrappers {
|
||||
/**
|
||||
* Setup of Latte template engine
|
||||
@@ -162,6 +164,12 @@ class Wrappers {
|
||||
}
|
||||
}
|
||||
|
||||
$customUa = Misc::env("USER_AGENT", '');
|
||||
|
||||
if ($customUa) {
|
||||
$options['user_agent'] = $customUa;
|
||||
}
|
||||
|
||||
return new \TikScraper\Api($options, $cacheEngine);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use TikScraper\Models\Discover;
|
||||
|
||||
class DiscoverTemplate extends BaseTemplate {
|
||||
public Discover $data;
|
||||
|
||||
function __construct(Discover $data) {
|
||||
parent::__construct("Discover");
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use TikScraper\Models\Feed;
|
||||
|
||||
/**
|
||||
* Base for templates with a feed
|
||||
*/
|
||||
class FeedTemplate extends BaseTemplate {
|
||||
public object $data;
|
||||
public Feed $feed;
|
||||
|
||||
function __construct(string $title, object $feed) {
|
||||
function __construct(string $title, Feed $feed) {
|
||||
parent::__construct($title);
|
||||
$this->data = (object) [
|
||||
'feed' => $feed
|
||||
];
|
||||
$this->feed = $feed;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pablouser1/proxitok",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "2.4.4.3",
|
||||
"version": "2.4.8.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"type": "project",
|
||||
"authors": [
|
||||
|
||||
Generated
+67
-25
@@ -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": "acb47eb00001b55dbf6825b0ce79cd0b",
|
||||
"content-hash": "edc1f7ddb80ad13369e0536c32518ece",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bramus/router",
|
||||
@@ -57,6 +57,46 @@
|
||||
},
|
||||
"time": "2021-11-18T19:24:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "deemon47/user-agent-generator",
|
||||
"version": "v1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Deemon47/user-agent-generator.git",
|
||||
"reference": "5af13fd2e905c5441eb4d61aad3a71bd1e801709"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Deemon47/user-agent-generator/zipball/5af13fd2e905c5441eb4d61aad3a71bd1e801709",
|
||||
"reference": "5af13fd2e905c5441eb4d61aad3a71bd1e801709",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Deemon47\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-3.0-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "phpfail",
|
||||
"email": "phpfail@gihub.com"
|
||||
},
|
||||
{
|
||||
"name": "Dee",
|
||||
"email": "deemon47@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Generate random User-Agent http header with parameters",
|
||||
"support": {
|
||||
"source": "https://github.com/Deemon47/user-agent-generator/tree/v1.0.1"
|
||||
},
|
||||
"time": "2020-04-11T12:05:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "josegonzalez/dotenv",
|
||||
"version": "dev-master",
|
||||
@@ -263,19 +303,20 @@
|
||||
},
|
||||
{
|
||||
"name": "pablouser1/tikscraper",
|
||||
"version": "v2.3.3.5",
|
||||
"version": "v2.3.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pablouser1/TikScraperPHP.git",
|
||||
"reference": "d3b51e6e0fab4cacce27dbbdf76bcb6fa8bf41ef"
|
||||
"reference": "10394fb5fb5213d05fe0eb29f7582423fc15d08a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/d3b51e6e0fab4cacce27dbbdf76bcb6fa8bf41ef",
|
||||
"reference": "d3b51e6e0fab4cacce27dbbdf76bcb6fa8bf41ef",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/10394fb5fb5213d05fe0eb29f7582423fc15d08a",
|
||||
"reference": "10394fb5fb5213d05fe0eb29f7582423fc15d08a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"deemon47/user-agent-generator": "^1.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-xml": "*",
|
||||
@@ -305,43 +346,44 @@
|
||||
"description": "Get data from TikTok API",
|
||||
"support": {
|
||||
"issues": "https://github.com/pablouser1/TikScraperPHP/issues",
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.3.3.5"
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.3.6.2"
|
||||
},
|
||||
"time": "2023-01-26T16:19:23+00:00"
|
||||
"time": "2023-04-01T13:46:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
"version": "1.13.1",
|
||||
"version": "1.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-webdriver/php-webdriver.git",
|
||||
"reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c"
|
||||
"reference": "3ea4f924afb43056bf9c630509e657d951608563"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c",
|
||||
"reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/3ea4f924afb43056bf9c630509e657d951608563",
|
||||
"reference": "3ea4f924afb43056bf9c630509e657d951608563",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^5.6 || ~7.0 || ^8.0",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.12",
|
||||
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
|
||||
"symfony/process": "^5.0 || ^6.0"
|
||||
},
|
||||
"replace": {
|
||||
"facebook/webdriver": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
|
||||
"ergebnis/composer-normalize": "^2.20.0",
|
||||
"ondram/ci-detector": "^4.0",
|
||||
"php-coveralls/php-coveralls": "^2.4",
|
||||
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
|
||||
"php-mock/php-mock-phpunit": "^2.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
|
||||
"symfony/var-dumper": "^5.0 || ^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "For Firefox profile creation"
|
||||
@@ -370,9 +412,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.13.1"
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.14.0"
|
||||
},
|
||||
"time": "2022-10-11T11:49:44+00:00"
|
||||
"time": "2023-02-09T12:12:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sapistudio/seleniumstealth",
|
||||
@@ -572,16 +614,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v5.4.19",
|
||||
"version": "v5.4.22",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1"
|
||||
"reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/c5ba874c9b636dbccf761e22ce750e88ec3f55e1",
|
||||
"reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/4b850da0cc3a2a9181c1ed407adbca4733dc839b",
|
||||
"reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -614,7 +656,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.19"
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.22"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -630,7 +672,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-01T08:32:19+00:00"
|
||||
"time": "2023-03-06T21:29:33+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@@ -18,13 +18,47 @@ services:
|
||||
depends_on:
|
||||
- redis
|
||||
- signer
|
||||
networks:
|
||||
- proxitok
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- SETGID
|
||||
- SETUID
|
||||
|
||||
redis:
|
||||
container_name: proxitok-redis
|
||||
image: redis:7-alpine
|
||||
command: redis-server --save 60 1 --loglevel warning
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- proxitok
|
||||
user: nobody
|
||||
read_only: true
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
tmpfs:
|
||||
- /data:size=10M,mode=0770,uid=65534,gid=65534,noexec,nosuid,nodev
|
||||
cap_drop:
|
||||
- ALL
|
||||
|
||||
signer:
|
||||
container_name: proxitok-signer
|
||||
image: ghcr.io/pablouser1/signtok:master
|
||||
networks:
|
||||
- proxitok
|
||||
user: nobody
|
||||
read_only: true
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
|
||||
volumes:
|
||||
proxitok-cache:
|
||||
|
||||
networks:
|
||||
proxitok:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{if !isset($item->imagePost)}
|
||||
<video controls n:attr="autoplay => $isAutoplay" poster="{url_stream($item->video->originCover)}" preload="none">
|
||||
<source src="{url_stream($item->video->playAddr)}" type="video/mp4" />
|
||||
</video>
|
||||
{else}
|
||||
<div n:class="columns, is-centered, is-vcentered, is-multiline, $isBig ? is-mobile">
|
||||
{foreach $item->imagePost->images as $image}
|
||||
{if $isBig}
|
||||
<div class="column is-half">
|
||||
{else}
|
||||
<div class="column is-one-third-tablet is-one-third-desktop is-one-quarter-widescreen is-one-fifth-fullhd">
|
||||
{/if}
|
||||
<figure class="image">
|
||||
<img width="{$image->imageWidth}" height="{$image->imageHeight}" src="{$image->imageURL->urlList[0]}" />
|
||||
</figure>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1,4 +1,4 @@
|
||||
<div n:ifset="$info" class="buttons">
|
||||
<div class="buttons">
|
||||
{* is_numeric is used to avoid having a back button with ttwid cursors *}
|
||||
{if isset($_GET['cursor']) && is_numeric($_GET['cursor']) && $_GET['cursor'] != 0}
|
||||
<a class="button is-danger" href="?cursor=0">First</a>
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
<p>{include './common/tags.latte', challenges: $item->challenges}</p>
|
||||
{/if}
|
||||
<p n:ifcontent>{$item->desc}</p>
|
||||
<p>Song: {$item->music->title}</p>
|
||||
<audio controls preload="none" src="{$item->music->playUrl}"></audio>
|
||||
{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="{url_stream($item->video->originCover)}">
|
||||
<source src="{url_stream($item->video->playAddr)}" type="video/mp4" />
|
||||
</video>
|
||||
{include './common/content.latte', item: $item, isAutoplay: false, isBig: false}
|
||||
</div>
|
||||
<p class="has-text-centered"><b>Download video</b></p>
|
||||
{include './common/download.latte', playAddr: $item->video->playAddr, id: $item->id, uniqueId: $item->author->uniqueId}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
{foreach $data->feed->items as $type => $items}
|
||||
{foreach $data->items as $type => $items}
|
||||
<p class="title">{$type|firstUpper}</p>
|
||||
<div class="columns is-multiline is-vcentered">
|
||||
{foreach $items as $item}
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
</figure>
|
||||
<p class="title">{$info->detail->uniqueId}</p>
|
||||
<p class="subtitle">{include '../components/rss.latte'}</p>
|
||||
{if $info->detail->privateAccount}
|
||||
<p><strong>Private account</strong></p>
|
||||
{/if}
|
||||
<p></p>
|
||||
<p>{$info->detail->signature}</p>
|
||||
<p>Following: {number($info->stats->followingCount)} / Followers: {number($info->stats->followerCount)}</p>
|
||||
<p>Hearts: {number($info->stats->heartCount)} / Videos: {$info->stats->videoCount}</p>
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
{var $og_content = $item->video->originCover}
|
||||
{var $og_url = url_video_internal($info->detail->uniqueId, $item->id)}
|
||||
|
||||
{if !empty($item->desc)}
|
||||
{var $title = trim($item->desc)}
|
||||
{/if}
|
||||
|
||||
{block content}
|
||||
<div class="columns is-centered is-vcentered is-gapless">
|
||||
<div class="columns is-centered is-vcentered">
|
||||
<div class="column has-text-centered">
|
||||
<video controls autoplay poster="{url_stream($item->video->originCover)}">
|
||||
<source src="{url_stream($item->video->playAddr)}" type="video/mp4" />
|
||||
</video>
|
||||
{include '../components/themes/common/content.latte', item: $item, isAutoplay: true, isBig: true}
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box">
|
||||
@@ -32,6 +34,8 @@
|
||||
{/if}
|
||||
<div class="content">
|
||||
<p n:ifcontent>{$item->desc}</p>
|
||||
<p>Song: {$item->music->title}</p>
|
||||
<audio controls preload="none" src="{$item->music->playUrl}"></audio>
|
||||
{include '../components/themes/common/stats.latte', playCount: $item->stats->playCount, diggCount: $item->stats->diggCount, commentCount: $item->stats->commentCount, shareCount: $item->stats->shareCount}
|
||||
<div class="has-text-centered">
|
||||
{include '../components/themes/common/share.latte', uniqueId: $info->detail->uniqueId, id: $item->id}
|
||||
@@ -41,6 +45,34 @@
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{if !empty($item->comments)}
|
||||
<div class="box">
|
||||
<p class="is-size-5 has-text-centered">Comments</p>
|
||||
{foreach $item->comments as $comment}
|
||||
<article class="media">
|
||||
<figure class="media-left">
|
||||
<p class="image is-64x64">
|
||||
<img src="{url_stream($comment->user->avatar_thumb->url_list[0])}" />
|
||||
</p>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="content">
|
||||
<p>
|
||||
<strong>{$comment->user->unique_id}</strong>
|
||||
<small>
|
||||
<a href="{url_user($comment->user->unique_id)}">@{$comment->user->nickname}</a>
|
||||
</small>
|
||||
<small title="{date('M d, Y H:i:s e', $comment->create_time)}">{date('M d, Y', $comment->create_time)}</small>
|
||||
<br>
|
||||
{$comment->text}
|
||||
</p>
|
||||
</div>
|
||||
<p>{include '../components/icon.latte', icon: 'heart', text: number($comment->digg_count)}</p>
|
||||
</div>
|
||||
</article>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
Reference in New Issue
Block a user