RSS initial support
This commit is contained in:
parent
ecdc8241e7
commit
bd1642957c
|
@ -1,4 +1,4 @@
|
||||||
# APP_SUBDIR=/ # Subpath your app is running, leave commented for /
|
# APP_URL="http://localhost:8000" # Full url path, PLEASE REPLACE TO YOUR OWN ONE
|
||||||
|
|
||||||
# LATTE_CACHE=/tmp/proxitok_api # Path for Latte cache, leave commented for ./cache/latte
|
# 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)
|
# API_CACHE=redis # Cache engine for TikTok Api, (more info on README)
|
||||||
|
|
|
@ -8,6 +8,7 @@ Use Tiktok with an alternative frontend, inspired by Nitter.
|
||||||
* See tags
|
* See tags
|
||||||
* See video by id
|
* See video by id
|
||||||
* Create a following list, which you can later use to see all the feeds from those users
|
* 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)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Clone the repository and fetch the requiered external packages with:
|
Clone the repository and fetch the requiered external packages with:
|
||||||
|
@ -28,7 +29,7 @@ Move the .env.example file to .env and modify it.
|
||||||
|
|
||||||
### Cache engines
|
### Cache engines
|
||||||
Available cache engines:
|
Available cache engines:
|
||||||
* redis: Writes response to Redis (check .env.example for config!)
|
* redis: Writes response to Redis
|
||||||
* json: Writes response to JSON file
|
* json: Writes response to JSON file
|
||||||
|
|
||||||
### Apache
|
### Apache
|
||||||
|
@ -58,7 +59,7 @@ location /tiktok-viewer/.env {
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
* [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP)
|
* [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP)
|
||||||
* [steampixel/simplePHPRouter](https://github.com/steampixel/simplePHPRouter)
|
* [bramus/router](https://github.com/bramus/router)
|
||||||
* [PHP dotenv](https://github.com/vlucas/phpdotenv)
|
* [PHP dotenv](https://github.com/vlucas/phpdotenv)
|
||||||
* [Bulma](https://github.com/jgthms/bulma)
|
* [Bulma](https://github.com/jgthms/bulma)
|
||||||
* [Bulmaswatch](https://github.com/jenil/bulmaswatch)
|
* [Bulmaswatch](https://github.com/jenil/bulmaswatch)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "pablouser1/proxitok",
|
"name": "pablouser1/proxitok",
|
||||||
"description": "An alternative frontend for TikTok",
|
"description": "An alternative frontend for TikTok",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"repositories": [
|
"repositories": [
|
||||||
{
|
{
|
||||||
|
@ -12,9 +12,10 @@
|
||||||
"require": {
|
"require": {
|
||||||
"ext-redis": "^5.3.2",
|
"ext-redis": "^5.3.2",
|
||||||
"ssovit/tiktok-api": "dev-rework",
|
"ssovit/tiktok-api": "dev-rework",
|
||||||
"steampixel/simple-php-router": "^0.7.0",
|
|
||||||
"latte/latte": "^2.10",
|
"latte/latte": "^2.10",
|
||||||
"vlucas/phpdotenv": "^5.4"
|
"vlucas/phpdotenv": "^5.4",
|
||||||
|
"bramus/router": "^1.6",
|
||||||
|
"bhaktaraz/php-rss-generator": "dev-master"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
148
composer.lock
generated
148
composer.lock
generated
|
@ -4,8 +4,108 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2c6e8300b7f0672000799c44a5fd19a3",
|
"content-hash": "c86d4aba41374f807418dde1044dba45",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "bhaktaraz/php-rss-generator",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/bhaktaraz/php-rss-generator.git",
|
||||||
|
"reference": "53cf11db18d87e65973e6df453fb8c1382e5a3bd"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/bhaktaraz/php-rss-generator/zipball/53cf11db18d87e65973e6df453fb8c1382e5a3bd",
|
||||||
|
"reference": "53cf11db18d87e65973e6df453fb8c1382e5a3bd",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Bhaktaraz\\RSSGenerator\\": "Source/Bhaktaraz/RSSGenerator/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bhaktaraz Bhatta",
|
||||||
|
"email": "bhattabhakta@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Simple RSS generator library for PHP 5.5 or later.",
|
||||||
|
"homepage": "https://github.com/bhaktaraz/php-rss-generator",
|
||||||
|
"keywords": [
|
||||||
|
"Facebook product feed generator",
|
||||||
|
"feed",
|
||||||
|
"generator",
|
||||||
|
"rss",
|
||||||
|
"writer"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/bhaktaraz/php-rss-generator/issues",
|
||||||
|
"source": "https://github.com/bhaktaraz/php-rss-generator/tree/master"
|
||||||
|
},
|
||||||
|
"time": "2021-03-15T10:59:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bramus/router",
|
||||||
|
"version": "1.6.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/bramus/router.git",
|
||||||
|
"reference": "55657b76da8a0a509250fb55b9dd24e1aa237eba"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/bramus/router/zipball/55657b76da8a0a509250fb55b9dd24e1aa237eba",
|
||||||
|
"reference": "55657b76da8a0a509250fb55b9dd24e1aa237eba",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "~2.14",
|
||||||
|
"phpunit/php-code-coverage": "~2.0",
|
||||||
|
"phpunit/phpunit": "~4.8"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Bramus": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bram(us) Van Damme",
|
||||||
|
"email": "bramus@bram.us",
|
||||||
|
"homepage": "http://www.bram.us"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A lightweight and simple object oriented PHP Router",
|
||||||
|
"homepage": "https://github.com/bramus/router",
|
||||||
|
"keywords": [
|
||||||
|
"router",
|
||||||
|
"routing"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/bramus/router/issues",
|
||||||
|
"source": "https://github.com/bramus/router/tree/1.6.1"
|
||||||
|
},
|
||||||
|
"time": "2021-11-18T19:24:07+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "graham-campbell/result-type",
|
"name": "graham-campbell/result-type",
|
||||||
"version": "v1.0.4",
|
"version": "v1.0.4",
|
||||||
|
@ -275,49 +375,6 @@
|
||||||
},
|
},
|
||||||
"time": "2022-01-22T19:37:07+00:00"
|
"time": "2022-01-22T19:37:07+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "steampixel/simple-php-router",
|
|
||||||
"version": "0.7.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/steampixel/simplePHPRouter.git",
|
|
||||||
"reference": "91aec2d0bca3619c0552e2bfcebb8936e6f83bb9"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/steampixel/simplePHPRouter/zipball/91aec2d0bca3619c0552e2bfcebb8936e6f83bb9",
|
|
||||||
"reference": "91aec2d0bca3619c0552e2bfcebb8936e6f83bb9",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Steampixel": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Christoph Stitz",
|
|
||||||
"email": "info@steampixel.de",
|
|
||||||
"homepage": "https://steampixel.de/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Maximilian Götz",
|
|
||||||
"email": "contact@maxbits.net",
|
|
||||||
"homepage": "https://www.maxbits.net/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "This is a simple and small PHP router that can handel the whole url routing for your project.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/steampixel/simplePHPRouter/issues",
|
|
||||||
"source": "https://github.com/steampixel/simplePHPRouter/tree/0.7.0"
|
|
||||||
},
|
|
||||||
"time": "2021-03-22T08:11:59+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.24.0",
|
"version": "v1.24.0",
|
||||||
|
@ -651,7 +708,8 @@
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"ssovit/tiktok-api": 20
|
"ssovit/tiktok-api": 20,
|
||||||
|
"bhaktaraz/php-rss-generator": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Helpers;
|
namespace Helpers;
|
||||||
|
|
||||||
class Error {
|
class ErrorHandler {
|
||||||
static public function show(object $meta) {
|
static public function show(object $meta) {
|
||||||
$http_code = $meta->http_code;
|
http_response_code($meta->http_code);
|
||||||
http_response_code($http_code);
|
|
||||||
|
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('error'), ['error' => $meta]);
|
$latte->render(Misc::getView('error'), ['error' => $meta]);
|
||||||
}
|
}
|
|
@ -2,11 +2,36 @@
|
||||||
namespace Helpers;
|
namespace Helpers;
|
||||||
|
|
||||||
class Following {
|
class Following {
|
||||||
static public function get (): array {
|
static public function getUsers (): array {
|
||||||
$following_string = Settings::get('following');
|
$following_string = Settings::get('following');
|
||||||
if ($following_string) {
|
if ($following_string) {
|
||||||
return explode(',', $following_string);
|
return explode(',', $following_string);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function getAll (array $users): object {
|
||||||
|
$allowed_items_total = isset($_GET['max']) && is_numeric($_GET['max']) && $_GET['max'] <= 100 ? $_GET['max'] : 20;
|
||||||
|
$items = [];
|
||||||
|
if (count($users) !== 0) {
|
||||||
|
$api = Misc::api();
|
||||||
|
$max_items_per_user = $allowed_items_total / count($users);
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$user_feed = $api->getUserFeed($user);
|
||||||
|
if ($user_feed) {
|
||||||
|
$max = count($user_feed->items) > $max_items_per_user ? $max_items_per_user : count($user_feed->items);
|
||||||
|
for ($i = 0; $i < $max; $i++) {
|
||||||
|
$item = $user_feed->items[$i];
|
||||||
|
array_push($items, $item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$feed = (object) [
|
||||||
|
'items' => $items,
|
||||||
|
'hasMore' => false
|
||||||
|
];
|
||||||
|
return $feed;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,14 +7,20 @@ use Helpers\CacheEngines\RedisCache;
|
||||||
use Helpers\Settings;
|
use Helpers\Settings;
|
||||||
|
|
||||||
class Misc {
|
class Misc {
|
||||||
static public function getSubDir(): string {
|
static public function env(string $key, mixed $default_value): string {
|
||||||
return isset($_ENV['APP_SUBDIR']) && !empty($_ENV['APP_SUBDIR']) ? $_ENV['APP_SUBDIR'] : '/';
|
return isset($_ENV[$key]) && !empty($_ENV[$key]) ? $_ENV[$key] : $default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns absolute path for view
|
||||||
|
*/
|
||||||
static public function getView(string $template): string {
|
static public function getView(string $template): string {
|
||||||
return __DIR__ . "/../views/{$template}.latte";
|
return __DIR__ . "/../views/{$template}.latte";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup of TikTok Api wrapper
|
||||||
|
*/
|
||||||
static public function api(): \Sovit\TikTok\Api {
|
static public function api(): \Sovit\TikTok\Api {
|
||||||
$options = [];
|
$options = [];
|
||||||
$cacheEngine = false;
|
$cacheEngine = false;
|
||||||
|
@ -47,26 +53,25 @@ class Misc {
|
||||||
return $api;
|
return $api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup of Latte template engine
|
||||||
|
*/
|
||||||
static public function latte(): \Latte\Engine {
|
static public function latte(): \Latte\Engine {
|
||||||
// Workaround to avoid weird path issues
|
// Workaround to avoid weird path issues
|
||||||
$subdir = Misc::getSubDir();
|
$url = self::env('APP_URL', '');
|
||||||
if ($subdir === '/') {
|
|
||||||
$subdir = '';
|
|
||||||
}
|
|
||||||
$latte = new \Latte\Engine;
|
$latte = new \Latte\Engine;
|
||||||
$cache_path = isset($_ENV['LATTE_CACHE']) && !empty($_ENV['LATTE_CACHE']) ? $_ENV['LATTE_CACHE'] : __DIR__ . '/../cache/latte';
|
$cache_path = self::env('LATTE_CACHE', __DIR__ . '/../cache/latte');
|
||||||
$latte->setTempDirectory($cache_path);
|
$latte->setTempDirectory($cache_path);
|
||||||
|
|
||||||
// -- CUSTOM FUNCTIONS -- //
|
// -- CUSTOM FUNCTIONS -- //
|
||||||
// Import assets
|
// Import assets
|
||||||
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
|
$latte->addFunction('assets', function (string $name, string $type) use ($url) {
|
||||||
$path = "{$subdir}/{$type}/{$name}";
|
$path = "{$url}/{$type}/{$name}";
|
||||||
return $path;
|
return $path;
|
||||||
});
|
});
|
||||||
// Relative path
|
// Get base URL
|
||||||
$latte->addFunction('path', function (string $name) use ($subdir) {
|
$latte->addFunction('path', function (string $path = '') use ($url) {
|
||||||
$path = "{$subdir}/{$name}";
|
return "{$url}/{$path}";
|
||||||
return $path;
|
|
||||||
});
|
});
|
||||||
// Version being used
|
// Version being used
|
||||||
$latte->addFunction('version', function () {
|
$latte->addFunction('version', function () {
|
||||||
|
@ -86,6 +91,10 @@ class Misc {
|
||||||
}
|
}
|
||||||
return $x;
|
return $x;
|
||||||
});
|
});
|
||||||
|
$latte->addFunction('size', function (string $url) {
|
||||||
|
$download = new \Sovit\TikTok\Download();
|
||||||
|
return $download->file_size($url);
|
||||||
|
});
|
||||||
return $latte;
|
return $latte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
helpers/RSS.php
Normal file
40
helpers/RSS.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
namespace Helpers;
|
||||||
|
|
||||||
|
use \Bhaktaraz\RSSGenerator\Feed;
|
||||||
|
use \Bhaktaraz\RSSGenerator\Channel;
|
||||||
|
use \Bhaktaraz\RSSGenerator\Item;
|
||||||
|
use \Sovit\TikTok\Download;
|
||||||
|
|
||||||
|
class RSS {
|
||||||
|
static public function build (string $endpoint, string $title, string $description, array $items, string $image = ''): Feed {
|
||||||
|
$url = Misc::env('APP_URL', '');
|
||||||
|
$download = new Download();
|
||||||
|
$rss_feed = new Feed();
|
||||||
|
$rss_channel = new Channel();
|
||||||
|
$rss_channel
|
||||||
|
->title($title)
|
||||||
|
->description($description)
|
||||||
|
->url($url . $endpoint)
|
||||||
|
->atomLinkSelf($url . $endpoint . '/rss')
|
||||||
|
->appendTo($rss_feed);
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$rss_item = new Item();
|
||||||
|
$video = $item->video->playAddr;
|
||||||
|
$rss_item
|
||||||
|
->title($item->desc)
|
||||||
|
->description($item->desc)
|
||||||
|
->url($url . '/video/' . $item->id)
|
||||||
|
->pubDate((int)$item->createTime)
|
||||||
|
->guid($item->id, false)
|
||||||
|
->enclosure($url . '/stream?url=' . urlencode($video), $download->file_size($video), 'video/mp4')
|
||||||
|
->appendTo($rss_channel);
|
||||||
|
}
|
||||||
|
return $rss_feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function setHeaders (string $filename) {
|
||||||
|
header('Content-Type: application/rss+xml');
|
||||||
|
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,6 @@ class Settings {
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function set(string $name, string $value) {
|
static public function set(string $name, string $value) {
|
||||||
setcookie($name, $value, time()+60*60*24*30, Misc::getSubDir(), '', isset($_SERVER['HTTPS']), true);
|
setcookie($name, $value, time()+60*60*24*30, '/', '', isset($_SERVER['HTTPS']), true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
require __DIR__ . "/vendor/autoload.php";
|
require __DIR__ . "/vendor/autoload.php";
|
||||||
use Steampixel\Route;
|
|
||||||
use Helpers\Misc;
|
|
||||||
|
|
||||||
// LOAD DOTENV
|
// LOAD DOTENV
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
||||||
$dotenv->safeLoad();
|
$dotenv->safeLoad();
|
||||||
|
|
||||||
|
// ROUTER
|
||||||
|
$router = new Bramus\Router\Router();
|
||||||
require __DIR__ . '/routes/index.php';
|
require __DIR__ . '/routes/index.php';
|
||||||
|
$router->run();
|
||||||
Route::run(Misc::getSubDir());
|
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
{block content}{/block}
|
{block content}{/block}
|
||||||
</section>
|
</section>
|
||||||
{include '../components/footer.latte'}
|
{include '../components/footer.latte'}
|
||||||
</body>
|
|
||||||
{block extra}{/block}
|
{block extra}{/block}
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
use Steampixel\Route;
|
|
||||||
|
|
||||||
const VALID_TIKTOK_DOMAINS = [
|
const VALID_TIKTOK_DOMAINS = [
|
||||||
"tiktokcdn.com", "tiktokcdn-us.com", "tiktok.com"
|
"tiktokcdn.com", "tiktokcdn-us.com", "tiktok.com"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**@var Bramus\Router\Router $router */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an url has a valid domain
|
* Check if an url has a valid domain
|
||||||
* @param string $url URL you want to check
|
* @param string $url URL you want to check
|
||||||
|
@ -16,7 +16,7 @@ function isValidDomain(string $url): bool {
|
||||||
return count($host_split) === 3 && in_array($host_split[1] . '.' . $host_split[2], VALID_TIKTOK_DOMAINS);
|
return count($host_split) === 3 && in_array($host_split[1] . '.' . $host_split[2], VALID_TIKTOK_DOMAINS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Route::add('/stream', function () {
|
$router->get('/stream', function () {
|
||||||
if (!isset($_GET['url'])) {
|
if (!isset($_GET['url'])) {
|
||||||
die('You need to send a url!');
|
die('You need to send a url!');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**@var Bramus\Router\Router $router */
|
||||||
|
|
||||||
use Helpers\Following;
|
use Helpers\Following;
|
||||||
use Helpers\Misc;
|
use Helpers\Misc;
|
||||||
use Steampixel\Route;
|
|
||||||
use Views\Models\FollowingTemplate;
|
use Views\Models\FollowingTemplate;
|
||||||
|
|
||||||
// Showing
|
// Showing
|
||||||
Route::add('/following', function () {
|
$router->get('/following', function () {
|
||||||
$allowed_items_total = isset($_GET['max']) && is_numeric($_GET['max']) && $_GET['max'] <= 100 ? $_GET['max'] : 20;
|
$users = Following::getUsers();
|
||||||
$following = Following::get();
|
$feed = Following::getAll($users);
|
||||||
$items = [];
|
|
||||||
if (count($following) !== 0) {
|
|
||||||
$api = Misc::api();
|
|
||||||
$max_items_per_user = $allowed_items_total / count($following);
|
|
||||||
foreach ($following as $user) {
|
|
||||||
$user_feed = $api->getUserFeed($user);
|
|
||||||
if ($user_feed) {
|
|
||||||
$max = count($user_feed->items) > $max_items_per_user ? $max_items_per_user : count($user_feed->items);
|
|
||||||
for ($i = 0; $i < $max; $i++) {
|
|
||||||
$item = $user_feed->items[$i];
|
|
||||||
array_push($items, $item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$feed = (object) [
|
|
||||||
'items' => $items,
|
|
||||||
'hasMore' => false
|
|
||||||
];
|
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('following'), new FollowingTemplate($following, $feed));
|
$latte->render(Misc::getView('following'), new FollowingTemplate($users, $feed));
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,25 +2,27 @@
|
||||||
require __DIR__ . '/assets.php';
|
require __DIR__ . '/assets.php';
|
||||||
require __DIR__ . '/settings.php';
|
require __DIR__ . '/settings.php';
|
||||||
require __DIR__ . '/following.php';
|
require __DIR__ . '/following.php';
|
||||||
|
require __DIR__ . '/rss.php';
|
||||||
|
|
||||||
|
/**@var Bramus\Router\Router $router */
|
||||||
|
|
||||||
use Steampixel\Route;
|
|
||||||
use Helpers\Misc;
|
use Helpers\Misc;
|
||||||
use Helpers\Error;
|
use Helpers\ErrorHandler;
|
||||||
use Views\Models\BaseTemplate;
|
use Views\Models\BaseTemplate;
|
||||||
use Views\Models\FeedTemplate;
|
use Views\Models\FeedTemplate;
|
||||||
use Views\Models\ItemTemplate;
|
use Views\Models\ItemTemplate;
|
||||||
|
|
||||||
Route::add('/', function () {
|
$router->get('/', function () {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('home'), new BaseTemplate('Home'));
|
$latte->render(Misc::getView('home'), new BaseTemplate('Home'));
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add('/about', function () {
|
$router->get('/about', function () {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('about'), new BaseTemplate('About'));
|
$latte->render(Misc::getView('about'), new BaseTemplate('About'));
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add("/trending", function () {
|
$router->get("/trending", function () {
|
||||||
$cursor = 0;
|
$cursor = 0;
|
||||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||||
$cursor = (int) $_GET['cursor'];
|
$cursor = (int) $_GET['cursor'];
|
||||||
|
@ -31,11 +33,11 @@ Route::add("/trending", function () {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('trending'), new FeedTemplate('Trending', $feed));
|
$latte->render(Misc::getView('trending'), new FeedTemplate('Trending', $feed));
|
||||||
} else {
|
} else {
|
||||||
Error::show($feed->meta);
|
ErrorHandler::show($feed->meta);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add("/@([^/]+)", function (string $username) {
|
$router->get("/@([^/]+)", function (string $username) {
|
||||||
$cursor = 0;
|
$cursor = 0;
|
||||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||||
$cursor = (int) $_GET['cursor'];
|
$cursor = (int) $_GET['cursor'];
|
||||||
|
@ -50,22 +52,22 @@ Route::add("/@([^/]+)", function (string $username) {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('user'), new FeedTemplate($feed->info->detail->user->nickname, $feed));
|
$latte->render(Misc::getView('user'), new FeedTemplate($feed->info->detail->user->nickname, $feed));
|
||||||
} else {
|
} else {
|
||||||
Error::show($feed->meta);
|
ErrorHandler::show($feed->meta);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add('/video/([^/]+)', function (string $video_id) {
|
$router->get('/video/([^/]+)', function (string $video_id) {
|
||||||
$api = Misc::api();
|
$api = Misc::api();
|
||||||
$item = $api->getVideoByID($video_id);
|
$item = $api->getVideoByID($video_id);
|
||||||
if ($item->meta->success) {
|
if ($item->meta->success) {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('video'), new ItemTemplate($item->info->detail->user->nickname, $item));
|
$latte->render(Misc::getView('video'), new ItemTemplate($item->info->detail->user->nickname, $item));
|
||||||
} else {
|
} else {
|
||||||
Error::show($item->meta);
|
ErrorHandler::show($item->meta);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add('/music/([^/]+)', function (string $music_id) {
|
$router->get('/music/([^/]+)', function (string $music_id) {
|
||||||
$cursor = 0;
|
$cursor = 0;
|
||||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||||
$cursor = (int) $_GET['cursor'];
|
$cursor = (int) $_GET['cursor'];
|
||||||
|
@ -77,11 +79,11 @@ Route::add('/music/([^/]+)', function (string $music_id) {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('music'), new FeedTemplate('Music', $feed));
|
$latte->render(Misc::getView('music'), new FeedTemplate('Music', $feed));
|
||||||
} else {
|
} else {
|
||||||
Error::show($feed->meta);
|
ErrorHandler::show($feed->meta);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::add('/tag/(\w+)', function (string $name) {
|
$router->get('/tag/(\w+)', function (string $name) {
|
||||||
$cursor = 0;
|
$cursor = 0;
|
||||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||||
$cursor = (int) $_GET['cursor'];
|
$cursor = (int) $_GET['cursor'];
|
||||||
|
@ -92,6 +94,6 @@ Route::add('/tag/(\w+)', function (string $name) {
|
||||||
$latte = Misc::latte();
|
$latte = Misc::latte();
|
||||||
$latte->render(Misc::getView('tag'), new FeedTemplate('Tag', $feed));
|
$latte->render(Misc::getView('tag'), new FeedTemplate('Tag', $feed));
|
||||||
} else {
|
} else {
|
||||||
Error::show($feed->meta);
|
ErrorHandler::show($feed->meta);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
46
routes/rss.php
Normal file
46
routes/rss.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**@var Bramus\Router\Router $router */
|
||||||
|
|
||||||
|
use Helpers\Misc;
|
||||||
|
use Helpers\RSS;
|
||||||
|
use Helpers\ErrorHandler;
|
||||||
|
|
||||||
|
$router->all("/@([^/]+)/rss", function (string $username) {
|
||||||
|
$api = Misc::api();
|
||||||
|
$feed = $api->getUserFeed($username);
|
||||||
|
if ($feed->meta->success) {
|
||||||
|
$feed = RSS::build('/@'.$username, $feed->info->detail->user->nickname, $feed->info->detail->user->signature, $feed->items);
|
||||||
|
// Setup headers
|
||||||
|
RSS::setHeaders('user.rss');
|
||||||
|
echo $feed;
|
||||||
|
} else {
|
||||||
|
ErrorHandler::show($feed->meta);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$router->all("/trending/rss", function () {
|
||||||
|
$api = Misc::api();
|
||||||
|
$feed = $api->getTrendingFeed();
|
||||||
|
if ($feed->meta->success) {
|
||||||
|
$feed = RSS::build('/trending', 'Trending', 'Tiktok trending', $feed->items);
|
||||||
|
// Setup headers
|
||||||
|
RSS::setHeaders('trending.rss');
|
||||||
|
echo $feed;
|
||||||
|
} else {
|
||||||
|
ErrorHandler::show($feed->meta);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$router->all("/tag/(\w+)/rss", function (string $name) {
|
||||||
|
$api = Misc::api();
|
||||||
|
$feed = $api->getChallengeFeed($name);
|
||||||
|
if ($feed->meta->success) {
|
||||||
|
$feed = RSS::build("/tag/{$name}", "{$name} Tag", $feed->info->detail->challenge->desc, $feed->items);
|
||||||
|
// Setup headers
|
||||||
|
RSS::setHeaders('tag.rss');
|
||||||
|
echo $feed;
|
||||||
|
} else {
|
||||||
|
ErrorHandler::show($feed->meta);
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,52 +1,54 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**@var Bramus\Router\Router $router */
|
||||||
|
|
||||||
use Helpers\Following;
|
use Helpers\Following;
|
||||||
use Helpers\Settings;
|
use Helpers\Settings;
|
||||||
use Helpers\Misc;
|
use Helpers\Misc;
|
||||||
use Views\Models\SettingsTemplate;
|
use Views\Models\SettingsTemplate;
|
||||||
use Steampixel\Route;
|
|
||||||
|
|
||||||
Route::add("/settings", function () {
|
$router->mount('/settings', function () use ($router) {
|
||||||
$latte = Misc::latte();
|
$router->get('/', function () {
|
||||||
$latte->render(Misc::getView('settings'), new SettingsTemplate());
|
$latte = Misc::latte();
|
||||||
});
|
$latte->render(Misc::getView('settings'), new SettingsTemplate());
|
||||||
|
});
|
||||||
|
|
||||||
Route::add("/settings/proxy", function () {
|
$router->post('/proxy', function () {
|
||||||
if (in_array(Settings::PROXY, $_POST)) {
|
if (in_array(Settings::PROXY, $_POST)) {
|
||||||
foreach (Settings::PROXY as $proxy_element) {
|
foreach (Settings::PROXY as $proxy_element) {
|
||||||
Settings::set($proxy_element, $_POST[$proxy_element]);
|
Settings::set($proxy_element, $_POST[$proxy_element]);
|
||||||
}
|
|
||||||
}
|
|
||||||
http_response_code(302);
|
|
||||||
header('Location: ./home');
|
|
||||||
}, 'POST');
|
|
||||||
|
|
||||||
|
|
||||||
Route::add("/settings/following", function () {
|
|
||||||
$following = Following::get();
|
|
||||||
if (!isset($_POST['mode']) || empty($_POST['mode'])) {
|
|
||||||
die('You need to send a mode');
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($_POST['mode']) {
|
|
||||||
case 'add':
|
|
||||||
// Add following
|
|
||||||
array_push($following, $_POST['account']);
|
|
||||||
break;
|
|
||||||
case 'remove':
|
|
||||||
// Remove following
|
|
||||||
$index = array_search($_POST['account'], $following);
|
|
||||||
if ($index !== false) {
|
|
||||||
unset($following[$index]);
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
http_response_code(302);
|
||||||
// Invalid
|
header('Location: ./home');
|
||||||
die('Invalid mode');
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Build string
|
$router->post('/following', function () {
|
||||||
$following_string = implode(',', $following);
|
$following = Following::getUsers();
|
||||||
Settings::set('following', $following_string);
|
if (!isset($_POST['mode']) || empty($_POST['mode'])) {
|
||||||
header('Location: ../settings');
|
die('You need to send a mode');
|
||||||
}, 'POST');
|
}
|
||||||
|
|
||||||
|
switch ($_POST['mode']) {
|
||||||
|
case 'add':
|
||||||
|
// Add following
|
||||||
|
array_push($following, $_POST['account']);
|
||||||
|
break;
|
||||||
|
case 'remove':
|
||||||
|
// Remove following
|
||||||
|
$index = array_search($_POST['account'], $following);
|
||||||
|
if ($index !== false) {
|
||||||
|
unset($following[$index]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Invalid
|
||||||
|
die('Invalid mode');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build string
|
||||||
|
$following_string = implode(',', $following);
|
||||||
|
Settings::set('following', $following_string);
|
||||||
|
header('Location: ../settings');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -14,6 +14,6 @@ class SettingsTemplate extends BaseTemplate {
|
||||||
function __construct() {
|
function __construct() {
|
||||||
parent::__construct('Settings');
|
parent::__construct('Settings');
|
||||||
$this->proxy_elements = Settings::PROXY;
|
$this->proxy_elements = Settings::PROXY;
|
||||||
$this->following = Following::get();
|
$this->following = Following::getUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<p class="title">{$feed->info->detail->challenge->title}</p>
|
<p class="title">{$feed->info->detail->challenge->title}</p>
|
||||||
<p class="subtitle">{$feed->info->detail->challenge->desc}</p>
|
<p class="subtitle">{$feed->info->detail->challenge->desc}</p>
|
||||||
<p>Videos: {number($feed->info->detail->stats->videoCount)} / Views: {number($feed->info->detail->stats->viewCount)}</p>
|
<p>Videos: {number($feed->info->detail->stats->videoCount)} / Views: {number($feed->info->detail->stats->viewCount)}</p>
|
||||||
|
<a href="{path('tag/' . $feed->info->detail->challenge->title . '/rss')}">RSS</a>
|
||||||
{/block}
|
{/block}
|
||||||
|
|
||||||
{block content}
|
{block content}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
{block header}
|
{block header}
|
||||||
<p class="title">Trending</p>
|
<p class="title">Trending</p>
|
||||||
|
<a href="{path('trending/rss')}">RSS</a>
|
||||||
{/block}
|
{/block}
|
||||||
|
|
||||||
{block content}
|
{block content}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<p class="subtitle">{$feed->info->detail->user->signature}</p>
|
<p class="subtitle">{$feed->info->detail->user->signature}</p>
|
||||||
<p>Following: {number($feed->info->detail->stats->followingCount)} / Followers: {number($feed->info->detail->stats->followerCount)}</p>
|
<p>Following: {number($feed->info->detail->stats->followingCount)} / Followers: {number($feed->info->detail->stats->followerCount)}</p>
|
||||||
<p>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p>
|
<p>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p>
|
||||||
|
<a href="{path('@' . $feed->info->detail->user->uniqueId . '/rss')}">RSS</a>
|
||||||
{/block}
|
{/block}
|
||||||
|
|
||||||
{block content}
|
{block content}
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
{block content}
|
{block content}
|
||||||
<div class="columns is-centered is-vcentered">
|
<div class="columns is-centered is-vcentered">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<video autoplay controls src="{path('stream?url=' . urlencode($item->items[0]->video->playAddr))}"></video>
|
<video controls poster="{path('stream?url=' . urlencode($item->items[0]->video->originCover))}">
|
||||||
|
<source src="{path('stream?url=' . urlencode($item->items[0]->video->playAddr))}" type="video/mp4" />
|
||||||
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<div class="column has-text-centered">
|
<div class="column has-text-centered">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
|
Loading…
Reference in a new issue