Using forked repo and cache engine

This commit is contained in:
Pablo Ferreiro 2022-01-13 16:51:45 +01:00
parent a0c60397af
commit 86f6c86c4c
No known key found for this signature in database
GPG key ID: 41FBCE65B779FA24
16 changed files with 179 additions and 282 deletions

View file

@ -9,20 +9,10 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Spaces in coffee
[**.coffee]
indent_style = space
indent_size = 2
[**.js]
indent_style = space
indent_size = 2
# Tabs in less
[**.less]
indent_style = tab
indent_size = 2
[**.css]
indent_style = tab
indent_size = 2

View file

@ -1 +1,2 @@
APP_SUBDIR=/ # Subpath your app is running, defaults to /
APP_CACHE=json # Cache engine for TikTok Api, defaults to json (more info on README)

3
.gitignore vendored
View file

@ -4,4 +4,5 @@ node_modules
/vendor
/cache/views/*
!/cache/views/.gitkeep
/.new_api
/cache/api/*
!/cache/api/.gitkeep

View file

@ -15,6 +15,8 @@ Clone the repository and fetch the requiered external packages with:
composer install
```
WARNING: You'll need a personal Github token for composer.
Then you can run it using for example the PHP Development Server with:
```bash
php -S localhost:8080
@ -24,6 +26,10 @@ php -S localhost:8080
### .env
Move the .env.example file to .env and modify it.
### Cache engine
Available cache engines:
* json: Writes response to JSON file
### Apache
You don't have to do anything more
@ -44,11 +50,6 @@ location /tiktok-viewer/.env {
}
```
## Known issues
* Fetching a user fails, there is already a pull request not merged yet fixing this issue on the TikTokApi repo, you can check it out [here](https://github.com/ssovit/TikTok-API-PHP/pull/43).
* Fetching a video by id or by url fails
**These issues are automatically patched after running composer install**
## TODO
* Add a NoJS version / Make the whole program without required JS
* Better error handling

0
cache/api/.gitkeep vendored Normal file
View file

View file

@ -1,34 +1,24 @@
{
"name": "pablouser1/tiktok-viewer",
"name": "pablouser1/tiktok-alt-frontend",
"description": "An alternative frontend for TikTok",
"version": "1.1.1",
"license": "AGPL-3.0-or-later",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pablouser1/TikTok-API-PHP"
}
],
"require": {
"ext-curl": "*",
"ssovit/tiktok-api": "^2.0",
"ssovit/tiktok-api": "dev-rework",
"steampixel/simple-php-router": "^0.7.0",
"latte/latte": "^2.10",
"vlucas/phpdotenv": "^5.4",
"cweagans/composer-patches": "^1.7"
"vlucas/phpdotenv": "^5.4"
},
"autoload": {
"psr-4": {
"Helpers\\": "helpers/"
}
},
"config": {
"allow-plugins": {
"cweagans/composer-patches": true
}
},
"extra": {
"patches": {
"ssovit/tiktok-api": [
"patches/0001-Fixed-getUser.patch",
"patches/0002-Added-support-for-username-as-well-as-user-id.patch",
"patches/0003-Fixed-getVideoByUrl.patch",
"patches/0004-Allow-IDs-from-Android-iOS-share.patch"
]
}
}
}

166
composer.lock generated
View file

@ -4,56 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0d80b92323fe946eed65f7e1c64f67a4",
"content-hash": "be47923ca5eb85a99cf811122d2ecf9a",
"packages": [
{
"name": "cweagans/composer-patches",
"version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/cweagans/composer-patches.git",
"reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cweagans/composer-patches/zipball/9888dcc74993c030b75f3dd548bb5e20cdbd740c",
"reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0",
"php": ">=5.3.0"
},
"require-dev": {
"composer/composer": "~1.0 || ~2.0",
"phpunit/phpunit": "~4.6"
},
"type": "composer-plugin",
"extra": {
"class": "cweagans\\Composer\\Patches"
},
"autoload": {
"psr-4": {
"cweagans\\Composer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Cameron Eagans",
"email": "me@cweagans.net"
}
],
"description": "Provides a way to patch Composer packages.",
"support": {
"issues": "https://github.com/cweagans/composer-patches/issues",
"source": "https://github.com/cweagans/composer-patches/tree/1.7.1"
},
"time": "2021-06-08T15:12:46+00:00"
},
{
"name": "graham-campbell/result-type",
"version": "v1.0.4",
@ -272,26 +224,116 @@
"time": "2021-12-04T23:24:31+00:00"
},
{
"name": "ssovit/tiktok-api",
"version": "2.0.0",
"name": "rmccue/requests",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/ssovit/TikTok-API-PHP.git",
"reference": "bce0ed8b417ab3a09d3c41cc75c3a654ef90c6d8"
"url": "https://github.com/WordPress/Requests.git",
"reference": "7ef0774f0bf32dddb7b6c1dd01e4d285c2ba3c3f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ssovit/TikTok-API-PHP/zipball/bce0ed8b417ab3a09d3c41cc75c3a654ef90c6d8",
"reference": "bce0ed8b417ab3a09d3c41cc75c3a654ef90c6d8",
"url": "https://api.github.com/repos/WordPress/Requests/zipball/7ef0774f0bf32dddb7b6c1dd01e4d285c2ba3c3f",
"reference": "7ef0774f0bf32dddb7b6c1dd01e4d285c2ba3c3f",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=5.6"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
"php-parallel-lint/php-console-highlighter": "^0.5.0",
"php-parallel-lint/php-parallel-lint": "^1.3.1",
"phpcompatibility/php-compatibility": "^9.0",
"requests/test-server": "dev-master",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6",
"wp-coding-standards/wpcs": "^2.0",
"yoast/phpunit-polyfills": "^1.0.0"
},
"type": "library",
"autoload": {
"psr-4": {
"WpOrg\\Requests\\": "src/"
},
"classmap": [
"library/Requests.php"
],
"files": [
"library/Deprecated.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"ISC"
],
"authors": [
{
"name": "Ryan McCue",
"homepage": "https://rmccue.io/"
},
{
"name": "Alain Schlesser",
"homepage": "https://github.com/schlessera"
},
{
"name": "Juliette Reinders Folmer",
"homepage": "https://github.com/jrfnl"
},
{
"name": "Contributors",
"homepage": "https://github.com/WordPress/Requests/graphs/contributors"
}
],
"description": "A HTTP library written in PHP, for human beings.",
"homepage": "https://requests.ryanmccue.info/",
"keywords": [
"curl",
"fsockopen",
"http",
"idna",
"ipv6",
"iri",
"sockets"
],
"support": {
"docs": "https://requests.ryanmccue.info/",
"issues": "https://github.com/WordPress/Requests/issues",
"source": "https://github.com/WordPress/Requests"
},
"time": "2021-11-24T14:20:18+00:00"
},
{
"name": "ssovit/tiktok-api",
"version": "dev-rework",
"source": {
"type": "git",
"url": "https://github.com/pablouser1/TikTok-API-PHP.git",
"reference": "3cee4765f122bd13d7044236013dfbd0d18652c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pablouser1/TikTok-API-PHP/zipball/3cee4765f122bd13d7044236013dfbd0d18652c4",
"reference": "3cee4765f122bd13d7044236013dfbd0d18652c4",
"shasum": ""
},
"require": {
"rmccue/requests": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Sovit\\": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"archive": {
"exclude": [
"/example",
"/.github",
"/.editorconfig"
]
},
"license": [
"MIT"
],
@ -306,16 +348,16 @@
"description": "Unofficial TikTok API for PHP",
"homepage": "https://github.com/ssovit/TikTok-API-PHP",
"keywords": [
"TikTok ",
"tiktok",
"tiktok-api",
"tiktok-scraper"
],
"support": {
"email": "sovit.tamrakar@gmail.com",
"source": "https://github.com/ssovit/TikTok-API-PHP",
"issues": "https://github.com/ssovit/TikTok-API-PHP/issues",
"source": "https://github.com/ssovit/TikTok-API-PHP"
"email": "sovit.tamrakar@gmail.com"
},
"time": "2021-05-28T15:32:11+00:00"
"time": "2022-01-13T15:14:30+00:00"
},
{
"name": "steampixel/simple-php-router",
@ -692,7 +734,9 @@
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"ssovit/tiktok-api": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {

View file

@ -0,0 +1,26 @@
<?php
namespace Helpers\CacheEngines;
class JSONCache {
const CACHE_PATH = __DIR__ . '/../../cache/api/';
public function get(string $cache_key): object|false {
if (is_file(self::CACHE_PATH . $cache_key . '.json')) {
$time = time();
$json_string = file_get_contents(self::CACHE_PATH . $cache_key . '.json');
$element = json_decode($json_string);
if ($time < $element->expires) {
return $element->data;
}
// Remove file if expired
unlink(self::CACHE_PATH . $cache_key . '.json');
}
return false;
}
public function set(string $cache_key, mixed $data, $timeout = 3600) {
file_put_contents(self::CACHE_PATH . $cache_key . '.json', json_encode([
'data' => $data,
'expires' => time() + $timeout
]));
}
}

View file

@ -2,24 +2,11 @@
namespace Helpers;
class Error {
const list = [
'api' => [
'code' => 500,
'message' => 'API unknown error, please check back later'
],
'latte' => [
'code' => 500,
'message' => 'Template render crash, please check back later'
]
];
static public function show(object $meta) {
$http_code = $meta->http_code;
http_response_code($http_code);
static public function show(string $type) {
$keys = array_keys(self::list);
if (in_array($type, $keys)) {
$error = self::list[$type];
http_response_code($error['code']);
$latte = Misc::latte();
$latte->render(Misc::getView('error'), ['type' => $type, 'error' => $error]);
}
$latte = Misc::latte();
$latte->render(Misc::getView('error'), ['error' => $meta]);
}
}

View file

@ -1,5 +1,7 @@
<?php
namespace Helpers;
use Helpers\CacheEngines\JSONCache;
use Helpers\Settings;
class Misc {
@ -13,13 +15,22 @@ class Misc {
static public function api(): \Sovit\TikTok\Api {
$options = [];
$cacheEngine = false;
// Proxy config
if (in_array(Settings::PROXY, $_COOKIE)) {
foreach (Settings::PROXY as $proxy_element) {
$options[$proxy_element] = $_COOKIE[$proxy_element];
foreach(Settings::PROXY as $proxy_element) {
if (isset($_COOKIE[$proxy_element])) {
$options['proxy'][$proxy_element] = $_COOKIE[$proxy_element];
}
}
$api = new \Sovit\TikTok\Api($options);
// Cache config
if (isset($_ENV['APP_CACHE'])) {
switch ($_ENV['APP_CACHE']) {
case 'json':
$cacheEngine = new JSONCache();
break;
}
}
$api = new \Sovit\TikTok\Api($options, $cacheEngine);
return $api;
}

View file

@ -1,40 +0,0 @@
From 7c52f9291fbd15d912fa78d0301939e3aa9deec4 Mon Sep 17 00:00:00 2001
From: attend-dunce <96889312+attend-dunce@users.noreply.github.com>
Date: Thu, 30 Dec 2021 21:35:14 +0100
Subject: [PATCH 1/4] Fixed `getUser`
---
lib/TikTok/Api.php | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
index e605eef..4a35f61 100644
--- a/lib/TikTok/Api.php
+++ b/lib/TikTok/Api.php
@@ -385,16 +385,14 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
}
}
$username = urlencode($username);
- $result = $this->remote_call("https://www.tiktok.com/@{$username}?lang=en", false);
- if (preg_match('/<script id="__NEXT_DATA__"([^>]+)>([^<]+)<\/script>/', $result, $matches)) {
- $result = json_decode($matches[2], false);
- if (isset($result->props->pageProps->userInfo)) {
- $result = $result->props->pageProps->userInfo;
- if ($this->cacheEnabled) {
- $this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
- }
- return $result;
+ $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?userId={$username}", false);
+ $result = json_decode($result, false);
+ if (isset($result->userInfo)) {
+ $result = $result->userInfo;
+ if ($this->cacheEnabled) {
+ $this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
}
+ return $result;
}
return $this->failure();
}
--
2.34.1

View file

@ -1,26 +0,0 @@
From c948bda5d6f30929b448fe78a0920739d5792d4b Mon Sep 17 00:00:00 2001
From: attend-dunce <96889312+attend-dunce@users.noreply.github.com>
Date: Fri, 31 Dec 2021 00:55:23 +0100
Subject: [PATCH 2/4] Added support for username as well as user id
---
lib/TikTok/Api.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
index 4a35f61..8fd42ae 100644
--- a/lib/TikTok/Api.php
+++ b/lib/TikTok/Api.php
@@ -385,7 +385,8 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
}
}
$username = urlencode($username);
- $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?userId={$username}", false);
+ $param = is_numeric($username) ? "userId" : "uniqueId";
+ $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?{$param}={$username}", false);
$result = json_decode($result, false);
if (isset($result->userInfo)) {
$result = $result->userInfo;
--
2.34.1

View file

@ -1,55 +0,0 @@
From 816ebe168d12923944b81b3f10bb22baf58efd66 Mon Sep 17 00:00:00 2001
From: Pablo Ferreiro <pferreiromero@gmail.com>
Date: Tue, 11 Jan 2022 19:09:08 +0100
Subject: [PATCH 3/4] Fixed getVideoByUrl
---
lib/TikTok/Api.php | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
index 8fd42ae..21ebff1 100644
--- a/lib/TikTok/Api.php
+++ b/lib/TikTok/Api.php
@@ -483,20 +483,27 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
throw new \Exception("Invalid VIDEO URL");
}
$result = $this->remote_call($url, false);
- $result = Helper::string_between($result, '{"props":{"initialProps":{', "</script>");
+ $result = Helper::string_between($result, "window['SIGI_STATE']=", ";window['SIGI_RETRY']=");
if (!empty($result)) {
- $jsonData = json_decode('{"props":{"initialProps":{' . $result);
- if (isset($jsonData->props->pageProps->itemInfo->itemStruct)) {
+ $jsonData = json_decode($result);
+ if (isset($jsonData->ItemModule, $jsonData->ItemList, $jsonData->UserModule)) {
+ $id = $jsonData->ItemList->video->keyword;
+ $item = $jsonData->ItemModule->{$id};
+ $username = $item->author;
$result = (object) [
'statusCode' => 0,
'info' => (object) [
'type' => 'video',
- 'detail' => $url,
+ 'detail' => (object) [
+ "url" => $url,
+ "user" => $jsonData->UserModule->users->{$username},
+ "stats" => $item->stats
+ ],
],
- "items" => [$jsonData->props->pageProps->itemInfo->itemStruct],
+ "items" => [$item],
"hasMore" => false,
"minCursor" => '0',
- "maxCursor" => ' 0',
+ "maxCursor" => '0'
];
if ($this->cacheEnabled) {
$this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
@@ -590,3 +597,4 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
}
}
}
+
--
2.34.1

View file

@ -1,33 +0,0 @@
From e8dcb7cf3824803d8b431dc923c479cd10102cbc Mon Sep 17 00:00:00 2001
From: Pablo Ferreiro <pferreiromero@gmail.com>
Date: Tue, 11 Jan 2022 19:18:16 +0100
Subject: [PATCH 4/4] Allow IDs from Android/iOS share
---
lib/TikTok/Api.php | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
index 21ebff1..f83f5bd 100644
--- a/lib/TikTok/Api.php
+++ b/lib/TikTok/Api.php
@@ -462,7 +462,15 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
if (empty($video_id)) {
throw new \Exception("Invalid VIDEO ID");
}
- return $this->getVideoByUrl('https://m.tiktok.com/v/' . $video_id . '.html');
+
+ $url = '';
+ if (is_numeric($video_id)) {
+ $url = 'https://m.tiktok.com/v/' . $video_id . '.html';
+ } else {
+ $url = 'https://vm.tiktok.com/' . $video_id;
+ }
+
+ return $this->getVideoByUrl($url);
}
/**
* Get Video By URL
--
2.34.1

View file

@ -23,11 +23,11 @@ Route::add("/trending", function () {
}
$api = Misc::api();
$feed = $api->getTrendingFeed($cursor);
if ($feed) {
if ($feed->meta->success) {
$latte = Misc::latte();
$latte->render(Misc::getView('trending'), ['feed' => $feed]);
} else {
Error::show('api');
Error::show($feed->meta);
}
});
@ -38,7 +38,7 @@ Route::add("/@([^/]+)", function (string $username) {
}
$api = Misc::api();
$feed = $api->getUserFeed($username, $cursor);
if ($feed) {
if ($feed->meta->success) {
if ($feed->info->detail->user->privateAccount) {
http_response_code(400);
return 'Private account detected! Not supported';
@ -46,18 +46,18 @@ Route::add("/@([^/]+)", function (string $username) {
$latte = Misc::latte();
$latte->render(Misc::getView('user'), ['feed' => $feed]);
} else {
Error::show('api');
Error::show($feed->meta);
}
});
Route::add('/video/([^/]+)', function (string $video_id) {
$api = Misc::api();
$item = $api->getVideoByID($video_id);
if ($item) {
if ($item->meta->success) {
$latte = Misc::latte();
$latte->render(Misc::getView('video'), ['item' => $item]);
} else {
Error::show('api');
Error::show($item->meta);
}
});
@ -68,10 +68,10 @@ Route::add('/tag/(\w+)', function (string $name) {
}
$api = Misc::api();
$feed = $api->getChallengeFeed($name, $cursor);
if ($feed) {
if ($feed->meta->success) {
$latte = Misc::latte();
$latte->render(Misc::getView('tag'), ['feed' => $feed]);
} else {
Error::show('api');
Error::show($feed->meta);
}
});

View file

@ -10,8 +10,8 @@
</div>
<div class="hero-body">
<div class="container">
<p class="title">{$type|firstUpper} error</p>
<p class="subtitle">{$error['message']}</p>
<p class="title">API errror code {$error->tiktok_code}</p>
<p class="subtitle">{$error->tiktok_msg}</p>
</div>
</div>
<div class="hero-foot is-danger">