mirror of
https://github.com/pablouser1/ProxiTok.git
synced 2024-12-06 19:27:30 +01:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96fb2fd428 | |||
| af4d98b8dd | |||
| 40e5d45956 | |||
| 2f20cf8c02 | |||
| aa2fff2b31 | |||
| fbc9061b21 | |||
| 67c080e5f4 | |||
| 086c95ca71 | |||
| 931191bcaf | |||
| ebe5941fa2 | |||
| 574ae51582 | |||
| 90a2d2ec28 | |||
| 3880da35ea | |||
| 8d8fe43431 | |||
| e7ee03e3cc | |||
| d0057e77e3 | |||
| d52dc8687f | |||
| bc3777d74c | |||
| 9acc40618a | |||
| 5e33b93031 | |||
| 76bfcbe34a | |||
| e2282f9dcc | |||
| cfe3a0c51b | |||
| 3b0ed28ad9 | |||
| 9d37bc433d | |||
| 26bde1e4a8 | |||
| 59029e48ad |
+9
-3
@@ -2,9 +2,9 @@
|
||||
# LATTE_CACHE=/tmp/proxitok_api # Path for Latte cache, leave commented for ./cache/latte
|
||||
|
||||
# API CONFIG
|
||||
# API_SIGNER_URL="https://example.com" # External signing service
|
||||
# API_BROWSER_URL="http://localhost:4444" # chromedriver url
|
||||
# API_TEST_ENDPOINTS=true # Discomment for usage of testing TikTok endpoints, may help sometimes
|
||||
# API_SIGNER="remote"
|
||||
# API_SIGNER_URL="http://localhost:8080"
|
||||
# API_TEST_ENDPOINTS=true # Uncomment for usage of testing TikTok endpoints, may help sometimes
|
||||
# API_CACHE=redis
|
||||
|
||||
# Redis cache, used on Helpers\CacheEngines\RedisCache (CHOOSE ONE)
|
||||
@@ -14,3 +14,9 @@
|
||||
|
||||
# JSON cache, used on Helpers\CacheEngines\JSONCache
|
||||
# API_CACHE_JSON=/tmp/proxitok_api # Path for JSON API Cache, leave commented for ./cache/api
|
||||
|
||||
# Proxy Config
|
||||
# PROXY_HOST=http://EXAMPLE_IP # Host to be used as proxy, make sure to type a valid protocol. Available: http:// | https:// | socks4:// | socks5://
|
||||
# PROXY_PORT=8080
|
||||
# PROXY_USERNAME=username
|
||||
# PROXY_PASSWORD=password
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
liberapay: 'pablouser1'
|
||||
custom: 'https://paypal.me/pablouser1'
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: Add my instance
|
||||
about: Add public instance to the list
|
||||
title: "[INSTANCES] New public instance"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
- URL: https://proxitok.example.com
|
||||
- Cloudflare: Yes / No
|
||||
- Country: Type the name of the country you are hosting the instance here
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: pablouser1
|
||||
|
||||
---
|
||||
|
||||
Before submitting an issue, please make sure you are using the latest version of ProxiTok.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Logs**
|
||||
If applicable, add PHP logs to help explain the issue.
|
||||
|
||||
**Enviroment (please complete the following information):**
|
||||
|
||||
- Deployment method (if possible): [e.g docker, heroku, manual...]
|
||||
- Frontend version: [e.g. 2.2.0.0]
|
||||
- Scrapper version: [e.g. 2.4.0.0]
|
||||
- PHP Version: [e.g. 8.0]
|
||||
|
||||
You can find the frontend and scrapper version on /about
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM php:8-apache
|
||||
FROM php:8.1-apache
|
||||
WORKDIR /var/www/html
|
||||
COPY --from=composer /usr/bin/composer /usr/bin/composer
|
||||
RUN apt update -y && apt upgrade -y \
|
||||
|
||||
@@ -1 +1 @@
|
||||
web: vendor/bin/heroku-php-nginx -C setup/nginx_heroku.conf
|
||||
web: vendor/bin/heroku-php-nginx -C setup/heroku/nginx.conf
|
||||
|
||||
@@ -33,8 +33,12 @@ Apply to: Main window (address bar)
|
||||
```
|
||||
|
||||
## TODO / Known issues
|
||||
* Replace placeholder favicon
|
||||
* Make video on /video fit screen and don't overflow
|
||||
* 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
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "ProxiTok",
|
||||
"description": "Open source alternative frontend for TikTok",
|
||||
"keywords": [
|
||||
"php",
|
||||
"tiktok",
|
||||
"alternative-frontends"
|
||||
],
|
||||
"website": "https://github.com/pablouser1/ProxiTok",
|
||||
"repository": "https://github.com/pablouser1/ProxiTok",
|
||||
"env": {
|
||||
"APP_URL": {
|
||||
"description": "Your instance url (example: https://proxitok.herokuapp.com)"
|
||||
},
|
||||
"API_CACHE": {
|
||||
"description": "Cache system in use",
|
||||
"value": "redis"
|
||||
},
|
||||
"LATTE_CACHE": {
|
||||
"description": "Latte cache path",
|
||||
"value": "/tmp/latte"
|
||||
},
|
||||
"API_SIGNER_URL": {
|
||||
"description": "Remote signer url",
|
||||
"value": "https://signtok.vercel.app/api"
|
||||
}
|
||||
},
|
||||
"addons": [
|
||||
{
|
||||
"plan": "heroku-redis:hobby-dev",
|
||||
"as": "REDIS"
|
||||
}
|
||||
],
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "heroku/php"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
namespace App\Cache;
|
||||
|
||||
class JSONCache {
|
||||
use TikScraper\CacheInterface;
|
||||
|
||||
class JSONCache implements CacheInterface {
|
||||
private string $cache_path = __DIR__ . '/../../cache/api';
|
||||
|
||||
function __construct() {
|
||||
@@ -24,7 +26,7 @@ class JSONCache {
|
||||
return is_file($filename);
|
||||
}
|
||||
|
||||
public function set(string $cache_key, mixed $data, $timeout = 3600) {
|
||||
public function set(string $cache_key, string $data, $timeout = 3600) {
|
||||
file_put_contents($this->cache_path . '/' . $cache_key . '.json', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
namespace App\Cache;
|
||||
|
||||
class RedisCache {
|
||||
use TikScraper\CacheInterface;
|
||||
|
||||
class RedisCache implements CacheInterface {
|
||||
private \Redis $client;
|
||||
function __construct(string $host, int $port, ?string $password) {
|
||||
$this->client = new \Redis();
|
||||
@@ -21,10 +23,7 @@ class RedisCache {
|
||||
|
||||
public function get(string $cache_key): ?object {
|
||||
$data = $this->client->get($cache_key);
|
||||
if ($data) {
|
||||
return json_decode($data);
|
||||
}
|
||||
return null;
|
||||
return $data ? json_decode($data) : null;
|
||||
}
|
||||
|
||||
public function exists(string $cache_key): bool {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace App\Constants;
|
||||
|
||||
class CacheMethods {
|
||||
const JSON = 'json';
|
||||
const REDIS = 'redis';
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace App\Controllers;
|
||||
use App\Helpers\ErrorHandler;
|
||||
use App\Helpers\Misc;
|
||||
|
||||
/**
|
||||
@@ -11,6 +12,13 @@ class RedirectController {
|
||||
if (isset($_GET['type'], $_GET['term'])) {
|
||||
$term = trim($_GET['term']);
|
||||
switch ($_GET['type']) {
|
||||
case 'url':
|
||||
$endpoint = self::to_endpoint($term);
|
||||
if (!$endpoint) {
|
||||
echo 'Invalid or unknown TikTok URL format';
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'user':
|
||||
// Remove @ if sent
|
||||
if ($term[0] === '@') {
|
||||
@@ -39,4 +47,33 @@ class RedirectController {
|
||||
$url = Misc::url($endpoint);
|
||||
header("Location: {$url}");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
// Short video URL
|
||||
return '/@placeholder/video/' . $m[1];
|
||||
} elseif (preg_match('%^https://www\.tiktok\.com/(.+)%', $url, $m)) {
|
||||
// Username component (which may indicate a user profile URL or a video URL)
|
||||
if (preg_match('%^(@[A-Za-z0-9_.]+)(?:/|$)(.*)%', $m[1], $u)) {
|
||||
if ($u[2] == '') {
|
||||
// User profile URL
|
||||
return '/' . $u[1];
|
||||
} elseif (preg_match('%^video/(\d+)%', $u[2], $v)) {
|
||||
// Video URL
|
||||
return '/' . $u[1] . '/video/' . $v[1];
|
||||
}
|
||||
} elseif (preg_match('%^tag/([^ ]+?)(?:/|$)%', $m[1], $t)) {
|
||||
// Tag URL
|
||||
return '/tag/' . $t[1];
|
||||
} elseif (preg_match('%^music/([^ ]+?)(?:/|$)%', $m[1], $m)) {
|
||||
// Music URL
|
||||
return '/music/' . $m[1];
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,6 @@ class SettingsController {
|
||||
$latte->render(Misc::getView('settings'), new BaseTemplate('Settings'));
|
||||
}
|
||||
|
||||
static private function redirect() {
|
||||
$url = Misc::url('/settings');
|
||||
header("Location: {$url}");
|
||||
}
|
||||
|
||||
static public function general() {
|
||||
if (isset($_POST['theme'])) {
|
||||
$theme = $_POST['theme'];
|
||||
@@ -26,6 +21,15 @@ class SettingsController {
|
||||
}
|
||||
static public function api() {
|
||||
// TODO, ADD COUNT
|
||||
if (isset($_POST['api-test_endpoints'])) {
|
||||
$test_endpoints = $_POST['api-test_endpoints'];
|
||||
Cookies::set('api-test_endpoints', $test_endpoints);
|
||||
}
|
||||
self::redirect();
|
||||
}
|
||||
|
||||
static private function redirect() {
|
||||
$url = Misc::url('/settings');
|
||||
header("Location: {$url}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<?php
|
||||
namespace App\Controllers;
|
||||
|
||||
/**
|
||||
* @deprecated Please use UserController::video instead
|
||||
*/
|
||||
class VideoController {
|
||||
static public function get(string $video_id) {
|
||||
UserController::video('placeholder', $video_id);
|
||||
|
||||
@@ -23,6 +23,10 @@ class Cookies {
|
||||
return isset($_COOKIE[$name]);
|
||||
}
|
||||
|
||||
static public function check(string $name, string $value): bool {
|
||||
return self::exists($name) && $_COOKIE[$name] === $value;
|
||||
}
|
||||
|
||||
static public function set(string $name, string $value) {
|
||||
setcookie($name, $value, time()+60*60*24*30, '/', '', isset($_SERVER['HTTPS']), true);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace App\Helpers;
|
||||
|
||||
use App\Cache\JSONCache;
|
||||
use App\Cache\RedisCache;
|
||||
use App\Constants\CacheMethods;
|
||||
|
||||
class Wrappers {
|
||||
/**
|
||||
@@ -19,9 +20,12 @@ class Wrappers {
|
||||
return Misc::url($endpoint);
|
||||
});
|
||||
// Version being used
|
||||
$latte->addFunction('version', function (): string {
|
||||
$latte->addFunction('version_frontend', function (): string {
|
||||
return \Composer\InstalledVersions::getVersion('pablouser1/proxitok');
|
||||
});
|
||||
$latte->addFunction('version_scraper', function (): string {
|
||||
return \Composer\InstalledVersions::getVersion('pablouser1/tikscraper');
|
||||
});
|
||||
$latte->addFunction('theme', function(): string {
|
||||
return Cookies::theme();
|
||||
});
|
||||
@@ -46,22 +50,49 @@ class Wrappers {
|
||||
* Setup of TikTok Api wrapper
|
||||
*/
|
||||
static public function api(): \TikScraper\Api {
|
||||
$method = Misc::env('API_SIGNER', '');
|
||||
$url = Misc::env('API_SIGNER_URL', '');
|
||||
if (!$method) {
|
||||
// Legacy support
|
||||
$browser_url = Misc::env('API_BROWSER_URL', '');
|
||||
if ($url) {
|
||||
$method = 'remote';
|
||||
} elseif ($browser_url) {
|
||||
$url = $browser_url;
|
||||
$method = 'browser';
|
||||
}
|
||||
}
|
||||
|
||||
$options = [
|
||||
'use_test_endpoints' => Misc::env('API_TEST_ENDPOINTS', false),
|
||||
'use_test_endpoints' => Misc::env('API_TEST_ENDPOINTS', false) || isset($_COOKIE['api-test_endpoints']) && $_COOKIE['api-test_endpoints'] === 'yes',
|
||||
'signer' => [
|
||||
'remote_url' => Misc::env('API_SIGNER_URL', ''),
|
||||
'browser_url' => Misc::env('API_BROWSER_URL', ''),
|
||||
'method' => $method,
|
||||
'url' => $url,
|
||||
'close_when_done' => false
|
||||
]
|
||||
];
|
||||
|
||||
// -- PROXY CONFIG -- //
|
||||
$proxy_host = Misc::env('PROXY_HOST', '');
|
||||
$proxy_port = Misc::env('PROXY_PORT', '');
|
||||
|
||||
if ($proxy_host && $proxy_port) {
|
||||
$options['proxy'] = [
|
||||
'host' => $proxy_host,
|
||||
'port' => $proxy_port,
|
||||
'username' => Misc::env('PROXY_USERNAME', null),
|
||||
'password' => Misc::env('PROXY_PASSWORD', null)
|
||||
];
|
||||
}
|
||||
|
||||
// Cache config
|
||||
$cacheEngine = false;
|
||||
$cacheEngine = null;
|
||||
if (isset($_ENV['API_CACHE'])) {
|
||||
switch ($_ENV['API_CACHE']) {
|
||||
case 'json':
|
||||
case CacheMethods::JSON:
|
||||
$cacheEngine = new JSONCache();
|
||||
break;
|
||||
case 'redis':
|
||||
case CacheMethods::REDIS:
|
||||
if (!(isset($_ENV['REDIS_URL']) || isset($_ENV['REDIS_HOST'], $_ENV['REDIS_PORT']))) {
|
||||
throw new \Exception('You need to set REDIS_URL or REDIS_HOST and REDIS_PORT to use Redis Cache!');
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
@@ -2,9 +2,16 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{path('/apple-touch-icon.png')}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{path('/favicon-32x32.png')}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{path('/favicon-16x16.png')}">
|
||||
<link rel="manifest" href="{path('/site.webmanifest')}">
|
||||
<meta property="og:title" content="ProxiTok" />
|
||||
<meta property="og:description" content="Alternative frontend for TikTok" />
|
||||
<meta property="og:type" content="website" />
|
||||
{if isset($has_rss)}
|
||||
<link rel="alternate" type="application/rss+xml" title="{$title}" href="{$_SERVER['REQUEST_URI'] . '/rss'}" />
|
||||
{/if}
|
||||
<link rel="stylesheet" href="{path('/styles/vendor/cssgg.min.css')}">
|
||||
<link rel="stylesheet" href="{path('/styles/vendor/bulma.min.css')}">
|
||||
<title>{$title} - ProxiTok</title>
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
{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">
|
||||
<p>TODO</p>
|
||||
<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" />
|
||||
<span>Yes</span>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="api-test_endpoints" value="no" n:attr="checked => !$use_endpoints" />
|
||||
<span>No</span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">This <i>may</i> help bypass rate limits</p>
|
||||
</div>
|
||||
{/block}
|
||||
{/embed}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
data-video_download_nowatermark="{path('/download?id=' . $item->id . '&user=' . $item->author->uniqueId)}"
|
||||
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))}" />
|
||||
@@ -36,6 +37,7 @@
|
||||
</section>
|
||||
<footer class="modal-card-foot has-text-centered">
|
||||
<div class="container">
|
||||
<p id="item_date"></p>
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<div class="control">
|
||||
<input id="share_input" class="input" readonly />
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<div n:ifset="$data->info" 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 }
|
||||
{if isset($_GET['cursor']) && is_numeric($_GET['cursor']) && $_GET['cursor'] != 0}
|
||||
<a class="button is-danger" href="?cursor=0">First</a>
|
||||
<a class="button is-danger" href="?cursor={$data->feed->minCursor}">Back</a>
|
||||
{/if}
|
||||
<a n:attr="disabled => !$data->feed->hasMore" class="button is-success" href="?cursor={$data->feed->maxCursor}">Next</a>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
<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>
|
||||
<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>
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pablouser1/proxitok",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "2.3.1.0",
|
||||
"version": "2.4.1.0",
|
||||
"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.1"
|
||||
"pablouser1/tikscraper": "^2.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+25
-19
@@ -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": "387c0d1d767d85d4d08fadad9b583080",
|
||||
"content-hash": "a7e4990ac4c1935a8cdc93939bf26dc9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bramus/router",
|
||||
@@ -117,16 +117,16 @@
|
||||
},
|
||||
{
|
||||
"name": "latte/latte",
|
||||
"version": "v2.11.4",
|
||||
"version": "v2.11.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/latte.git",
|
||||
"reference": "3a5ed09d92b3bb2c428814bb919c2f8637bc49b1"
|
||||
"reference": "89e647e51213af8a270fe9903b8735a2f6c83ad1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/3a5ed09d92b3bb2c428814bb919c2f8637bc49b1",
|
||||
"reference": "3a5ed09d92b3bb2c428814bb919c2f8637bc49b1",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/89e647e51213af8a270fe9903b8735a2f6c83ad1",
|
||||
"reference": "89e647e51213af8a270fe9903b8735a2f6c83ad1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -195,9 +195,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/latte/issues",
|
||||
"source": "https://github.com/nette/latte/tree/v2.11.4"
|
||||
"source": "https://github.com/nette/latte/tree/v2.11.5"
|
||||
},
|
||||
"time": "2022-05-30T13:34:15+00:00"
|
||||
"time": "2022-06-26T10:12:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "m1/env",
|
||||
@@ -263,23 +263,29 @@
|
||||
},
|
||||
{
|
||||
"name": "pablouser1/tikscraper",
|
||||
"version": "v2.1.0.1",
|
||||
"version": "v2.2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pablouser1/TikScraperPHP.git",
|
||||
"reference": "443225d18f02073ea154b907f93400acd1fd49a4"
|
||||
"reference": "535ed6db108c9a0ec41b271bea8a6a10700cc5d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/443225d18f02073ea154b907f93400acd1fd49a4",
|
||||
"reference": "443225d18f02073ea154b907f93400acd1fd49a4",
|
||||
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/535ed6db108c9a0ec41b271bea8a6a10700cc5d7",
|
||||
"reference": "535ed6db108c9a0ec41b271bea8a6a10700cc5d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-xml": "*",
|
||||
"php": ">=7.4|^8.0",
|
||||
"php-webdriver/webdriver": "^1.12",
|
||||
"sapistudio/seleniumstealth": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -298,9 +304,9 @@
|
||||
"description": "Get data from TikTok API",
|
||||
"support": {
|
||||
"issues": "https://github.com/pablouser1/TikScraperPHP/issues",
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.1.0.1"
|
||||
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.2.1.1"
|
||||
},
|
||||
"time": "2022-06-04T18:53:49+00:00"
|
||||
"time": "2022-09-03T11:19:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
@@ -565,16 +571,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v5.4.8",
|
||||
"version": "v5.4.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
|
||||
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1",
|
||||
"reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -607,7 +613,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.8"
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.11"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -623,7 +629,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-08T05:07:18+00:00"
|
||||
"time": "2022-06-27T16:58:25+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@@ -11,6 +11,7 @@ services:
|
||||
- API_CACHE=redis
|
||||
- REDIS_HOST=proxitok-redis
|
||||
- REDIS_PORT=6379
|
||||
- API_SIGNER=remote
|
||||
- API_SIGNER_URL=http://proxitok-signer:8080/signature
|
||||
volumes:
|
||||
- proxitok-cache:/cache
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 626 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
+3
-3
@@ -34,10 +34,10 @@ $router->mount('/@([^/]+)', function () use ($router) {
|
||||
$router->get('/rss', 'UserController@rss');
|
||||
});
|
||||
|
||||
/**
|
||||
* @deprecated Please use /@username/video/id instead
|
||||
*/
|
||||
// Deprecated, please use /@USERNAME/video/VIDEO_ID instead
|
||||
$router->get('/video/(\w+)', 'VideoController@get');
|
||||
// Workaround that allows /t endpoints
|
||||
$router->get('/t/([^/]+)', 'VideoController@get');
|
||||
|
||||
$router->mount('/tag/([^/]+)', function () use ($router) {
|
||||
$router->get('/', 'TagController@get');
|
||||
|
||||
@@ -2,6 +2,7 @@ var opened_video_id = null
|
||||
|
||||
const video = document.getElementById('video')
|
||||
const item_title = document.getElementById('item_title')
|
||||
const item_date = document.getElementById('item_date')
|
||||
const audio = document.getElementById('audio')
|
||||
const audio_title = document.getElementById('audio_title')
|
||||
const modal = document.getElementById('modal')
|
||||
@@ -15,7 +16,7 @@ const getVideoDataById = id => {
|
||||
opened_video_id = id
|
||||
return el.dataset
|
||||
}
|
||||
return false
|
||||
return null
|
||||
}
|
||||
|
||||
const isModalActive = () => modal.classList.contains('is-active')
|
||||
@@ -23,9 +24,10 @@ const isModalActive = () => modal.classList.contains('is-active')
|
||||
const toggleButton = (id, force) => document.getElementById(id).toggleAttribute('disabled', force)
|
||||
|
||||
// -- MODAL -- //
|
||||
const swapData = ({ video_url, desc, video_download_watermark, video_download_nowatermark, video_share_url, music_title, music_url }) => {
|
||||
const swapData = ({ video_url, desc, createtime, video_download_watermark, video_download_nowatermark, video_share_url, music_title, music_url }) => {
|
||||
video.src = video_url
|
||||
item_title.innerText = desc
|
||||
item_date.innerText = new Date(createtime * 1000).toLocaleString()
|
||||
download_watermark.href = video_download_watermark
|
||||
download_nowatermark.href = video_download_nowatermark
|
||||
share_input.value = video_share_url
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
This facilities making the bulma.min.css and fontawesome.min.css files, install all dependencies using:
|
||||
This facilities making the compressed bulma.min.css and cssgg.min.css files, install all dependencies using:
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
And then use:
|
||||
```
|
||||
yarn bulma && yarn fa
|
||||
yarn bulma && yarn cssgg
|
||||
```
|
||||
|
||||
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.
|
||||
This compiles bulma.scss and cssgg.scss to a css file and helps lowering the size of the css that will be sent to the user.
|
||||
|
||||
+7
-7
@@ -72,9 +72,9 @@ glob-parent@~5.1.2:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
immutable@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
|
||||
integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
|
||||
integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
@@ -86,7 +86,7 @@ is-binary-path@~2.1.0:
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
@@ -118,9 +118,9 @@ readdirp@~3.6.0:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
sass@^1.46.0:
|
||||
version "1.52.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.52.1.tgz#554693da808543031f9423911d62c60a1acf7889"
|
||||
integrity sha512-fSzYTbr7z8oQnVJ3Acp9hV80dM1fkMN7mSD/25mpcct9F7FPBMOI8krEYALgU1aZoqGhQNhTPsuSmxjnIvAm4Q==
|
||||
version "1.53.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.53.0.tgz#eab73a7baac045cc57ddc1d1ff501ad2659952eb"
|
||||
integrity sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "ProxiTok",
|
||||
"short_name": "ProxiTok",
|
||||
"description": "Use TikTok with a privacy-friendly alternative frontend",
|
||||
"orientation": "portrait-primary",
|
||||
"icons": [
|
||||
{
|
||||
"src": "./android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "./android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"id": "./",
|
||||
"start_url": "./",
|
||||
"theme_color": "#4040ff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">Welcome to Proxitok!</p>
|
||||
<p class="title">Welcome to ProxiTok!</p>
|
||||
<p class="subtitle">
|
||||
Made with <span style="color: #e25555;">♥</span> in <a href="https://github.com/pablouser1/ProxiTok">Github</a>
|
||||
</p>
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
{block content}
|
||||
<p class="title">About this instance</p>
|
||||
<p>Version: {version()}</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>
|
||||
@@ -28,7 +29,7 @@
|
||||
<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/vlucas/phpdotenv">PHP dotenv</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>
|
||||
|
||||
+3
-5
@@ -3,10 +3,8 @@
|
||||
{block content}
|
||||
<p class="title">There was an error processing your request!</p>
|
||||
<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}
|
||||
<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}
|
||||
{/block}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="type">
|
||||
<option value="url">TikTok URL</option>
|
||||
<option value="user">Username</option>
|
||||
<option value="tag">Tag</option>
|
||||
<option value="music">Music ID</option>
|
||||
|
||||
+2
-4
@@ -1,7 +1,6 @@
|
||||
{contentType application/rss+xml}
|
||||
{do header('Content-Disposition: attachment; filename="' . $title . '.rss' . '"')}
|
||||
{do $full_link = path($link)}
|
||||
{var $download = new \TikScraper\Download}
|
||||
{var $full_link = path($link)}
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
@@ -12,11 +11,10 @@
|
||||
{foreach $items as $item}
|
||||
<item>
|
||||
<title>{$item->desc}</title>
|
||||
<description><![CDATA[{$item->desc}]]></description>
|
||||
<description><![CDATA[<p>{$item->desc}</p><video controls="controls" preload="auto" src="{path('/stream?url=' . urlencode($item->video->playAddr))}"></video>]]></description>
|
||||
<link>{path('/@' . $item->author->uniqueId . '/video/' . $item->id)}</link>
|
||||
<pubDate>{date('r', $item->createTime)}</pubDate>
|
||||
<guid isPermaLink="false">{$item->id}</guid>
|
||||
<enclosure length="{$download->file_size($item->video->playAddr)}" type="video/mp4" url="{path('/stream?url=' . urlencode($item->video->playAddr))}"></enclosure>
|
||||
</item>
|
||||
{/foreach}
|
||||
</channel>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{layout '../layouts/default.latte'}
|
||||
|
||||
{var $has_rss = true}
|
||||
|
||||
{block header}
|
||||
{if $data->info->detail->profileThumb !== ''}
|
||||
<figure class="figure is-96x96">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{layout '../layouts/default.latte'}
|
||||
|
||||
{var $has_rss = true}
|
||||
|
||||
{block header}
|
||||
<p class="title">Trending</p>
|
||||
<p class="subtitle">{include '../components/rss.latte'}</p>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{layout '../layouts/default.latte'}
|
||||
|
||||
{var $has_rss = true}
|
||||
|
||||
{block header}
|
||||
<figure class="figure is-96x96">
|
||||
<img src="{path('/stream?url=' . urlencode($data->info->detail->avatarThumb))}" />
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
|
||||
{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>
|
||||
<p>TikTok has some mecanisms in order to stop scraping on their api:</p>
|
||||
<hr />
|
||||
<div class="block">
|
||||
<p class="is-size-4">Rate limits</p>
|
||||
|
||||
Reference in New Issue
Block a user