Compare commits

...

31 Commits

Author SHA1 Message Date
Pablo Ferreiro ec611478e3 implemented following (AKA discover) & fyp using new endpoints
Docker / build (push) Has been cancelled
Create Tag / build (push) Has been cancelled
2024-08-28 14:34:02 +02:00
Pablo Ferreiro 96aa2803b2 bump scraper
Docker / build (push) Has been cancelled
Create Tag / build (push) Has been cancelled
2024-08-21 19:10:32 +02:00
Pablo Ferreiro 9f63fecc18 fixed null value on download 2024-08-21 13:30:56 +02:00
Pablo Ferreiro a27d6ca767 bump scraper 2024-08-21 13:24:40 +02:00
Pablo Ferreiro 2aab1bfe24 bump scraper 2024-08-21 13:09:06 +02:00
Pablo Ferreiro bc9ff0100e region may not show 2024-08-21 03:57:26 +02:00
Pablo Ferreiro c4f3a80c3e fixed error constructor 2024-08-21 03:30:52 +02:00
Pablo Ferreiro 3b441c2683 fixed undefined addr 2024-08-21 03:28:34 +02:00
Pablo Ferreiro 03002ba835 removed redis persist storage 2024-08-21 03:26:11 +02:00
Pablo Ferreiro 76d4a581f3 init redis and no need to expose chromedriver 2024-08-21 03:15:33 +02:00
Pablo Ferreiro 36d9902c73 bump 2024-08-21 03:03:13 +02:00
Pablo Ferreiro 98405545e7 controls using cursor 2024-08-21 02:35:42 +02:00
Pablo Ferreiro 9ac169d480 download fix 2024-08-21 02:05:38 +02:00
Pablo Ferreiro b63a0b2755 official instance now in austria 2024-08-21 01:39:46 +02:00
Pablo Ferreiro 1427a94810 Merge pull request #223 from yedayak/lite-short-url
Follow lite.tiktok.com, same as v[mt].tiktok.com
2024-08-21 00:35:21 +02:00
Pablo Ferreiro 547f8460b3 Merge pull request #205 from drizzt/podman-compatibility
Podman compatibility
2024-08-21 00:00:47 +02:00
Pablo Ferreiro 4610a89810 Merge branch 'master' into podman-compatibility 2024-08-21 00:00:28 +02:00
Pablo Ferreiro 70161ec0d6 Merge pull request #209 from jamesbrown8532/instances-list-json
Add instances list in JSON format
2024-08-20 23:55:00 +02:00
Pablo Ferreiro 2592f2087c bump scraper 2024-08-20 23:50:21 +02:00
Pablo Ferreiro a033682dfb breaking changes warning 2024-08-20 23:37:21 +02:00
Pablo Ferreiro 01c39fbc0e cosign bump 2024-08-20 23:29:29 +02:00
Pablo Ferreiro 086c206920 removed discover template 2024-08-20 23:27:42 +02:00
Yedaya Katsman 3eebeb0369 Follow lite.tiktok.com, same as v[mt].tiktok.com
Fixes https://github.com/pablouser1/ProxiTok/issues/222
2024-08-18 22:59:09 +03:00
jamesbrown8532 f203dca5a2 Fix typo in instances.json 2024-02-18 12:56:03 +00:00
jamesbrown8532 db1de45ee1 Remove duplicate entry 2024-02-18 01:41:45 +00:00
jamesbrown8532 fe80102212 Put Tor instance link in correct entry 2024-02-18 01:41:28 +00:00
jamesbrown8532 a99b8ebd54 Mention instances.json in README.md 2024-02-18 01:25:11 +00:00
jamesbrown8532 d33e9d119a Add instances list in JSON format 2024-02-18 01:23:41 +00:00
Timothy Redaelli 7c51b63660 Add io.containers.autoupdate to tell podman to auto update containers
See https://docs.podman.io/en/latest/markdown/podman-auto-update.1.html
for more informations
2024-01-25 18:48:21 +01:00
Timothy Redaelli 13e686bb5a Add the full image: path in docker-compose.yml 2024-01-25 18:35:58 +01:00
Timothy Redaelli 250bbedc1d Remove persistent storage from redis in docker-compose.yml
This is needed to restore podman-compose compatibility, since it doesn't
support uid and gid options in tmpfs, moreover it's quite silly to have
persistent storage on a tmpfs since /data is deleted when the container
is stopped.

Fixes: 48eccbc5ec ("harden docker-compose")
Cc: admin@nullnet.services
2024-01-25 18:35:58 +01:00
20 changed files with 280 additions and 68 deletions
+2 -2
View File
@@ -42,9 +42,9 @@ jobs:
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@v3.1.1
uses: sigstore/cosign-installer@v3.6.0
with:
cosign-release: 'v2.1.1'
cosign-release: 'v2.4.0'
# Workaround: https://github.com/docker/build-push-action/issues/461
+5
View File
@@ -1,6 +1,9 @@
# ProxiTok
Use Tiktok with an alternative frontend, inspired by Nitter.
## WARNING
THE LATEST VERSION **v2.5.0.0** INCLUDES BREAKING CHANGES, CHECK THE [PULL REQUEST](https://github.com/pablouser1/ProxiTok/pull/224) FOR MORE INFO
## Features
* Privacy: All requests made to TikTok are server-side, so you will never connect to their servers
* See user's feed
@@ -15,6 +18,8 @@ Please check [this](https://github.com/pablouser1/ProxiTok/wiki/Self-hosting) wi
## Public instances
[This](https://github.com/pablouser1/ProxiTok/wiki/Public-instances) wiki article contains a list with all the known public instances.
Instances list in JSON format can be found in [instances.json](instances.json) file.
## Extensions
If you want to automatically redirect Tiktok links to ProxiTok you can use:
* [Libredirect](https://github.com/libredirect/libredirect)
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Controllers;
use App\Helpers\ErrorHandler;
use App\Helpers\Misc;
use App\Helpers\Wrappers;
use App\Models\FeedTemplate;
class FollowingController {
public static function get() {
$cursor = Misc::getCursor();
$api = Wrappers::api();
$following = $api->following();
$following->feed($cursor);
if ($following->ok()) {
$feed = $following->getFeed();
Wrappers::latte('following', new FeedTemplate('Following / Discover', $feed));
} else {
ErrorHandler::showMeta($following->error());
}
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Controllers;
use App\Helpers\ErrorHandler;
use App\Helpers\Misc;
use App\Helpers\Wrappers;
use App\Models\FeedTemplate;
use App\Models\RSSTemplate;
class ForYouController {
public static function get() {
$api = Wrappers::api();
$fyp = $api->foryou();
$fyp->feed();
if ($fyp->ok()) {
$feed = $fyp->getFeed();
Wrappers::latte('foryou', new FeedTemplate('For you', $feed));
} else {
ErrorHandler::showMeta($fyp->error());
}
}
public static function rss() {
$api = Wrappers::api();
$fyp = $api->foryou();
$fyp->feed();
if ($fyp->ok()) {
$feed = $fyp->getFeed();
Misc::rss('For you');
Wrappers::latte('rss', new RSSTemplate('For you', 'For you Page', '', Misc::url('/foryou'), $feed->items));
}
}
}
+1 -1
View File
@@ -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\.|lite\.)?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)) {
+1 -1
View File
@@ -12,6 +12,6 @@ class ErrorHandler {
public static function showText(int $code, string $msg) {
http_response_code($code);
Wrappers::latte('error', new ErrorTemplate($code, $msg));
Wrappers::latte('error', new ErrorTemplate($code, $msg, null, null));
}
}
+2
View File
@@ -26,12 +26,14 @@ class Misc {
}
public static function getScraperOptions(): array {
$debug = self::env('APP_DEBUG', false);
$url = self::env('API_CHROMEDRIVER', 'http://localhost:4444');
$verifyFp = self::env('API_VERIFYFP', '');
$device_id = self::env('API_DEVICE_ID', '');
$ua = self::env('USER_AGENT', '');
$options = [
'debug' => $debug,
'browser' => [
'url' => $url,
'close_when_done' => false
-13
View File
@@ -1,13 +0,0 @@
<?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 -1
View File
@@ -10,7 +10,7 @@ class ErrorTemplate extends BaseTemplate {
public ?Response $response = null;
function __construct(int $http_code, string $msg, ?int $tiktok_code = null, ?Response $response) {
function __construct(int $http_code, string $msg, ?int $tiktok_code, ?Response $response) {
parent::__construct('Error');
$this->http_code = $http_code;
$this->msg = $msg;
Generated
+8 -39
View File
@@ -589,23 +589,22 @@
},
{
"name": "pablouser1/tikscraper",
"version": "v2.6.0.2",
"version": "v2.6.2.0",
"source": {
"type": "git",
"url": "https://github.com/pablouser1/TikScraperPHP.git",
"reference": "b13a1a0ffd108651d5b54008941d9405db8bf873"
"reference": "051f3b4dd5debc05b1d49ab21e6ab831ed04ed9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/b13a1a0ffd108651d5b54008941d9405db8bf873",
"reference": "b13a1a0ffd108651d5b54008941d9405db8bf873",
"url": "https://api.github.com/repos/pablouser1/TikScraperPHP/zipball/051f3b4dd5debc05b1d49ab21e6ab831ed04ed9a",
"reference": "051f3b4dd5debc05b1d49ab21e6ab831ed04ed9a",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^7.8",
"guzzlehttp/guzzle": "^7.9",
"php": "^8.1",
"php-webdriver/webdriver": "^1.12",
"sapistudio/seleniumstealth": "^1.0"
"php-webdriver/webdriver": "^1.12"
},
"require-dev": {
"pestphp/pest": "^1.22"
@@ -629,9 +628,9 @@
"description": "Get data from TikTok API",
"support": {
"issues": "https://github.com/pablouser1/TikScraperPHP/issues",
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.6.0.2"
"source": "https://github.com/pablouser1/TikScraperPHP/tree/v2.6.2.0"
},
"time": "2024-08-20T20:46:45+00:00"
"time": "2024-08-28T12:27:55+00:00"
},
{
"name": "php-webdriver/webdriver",
@@ -903,36 +902,6 @@
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "sapistudio/seleniumstealth",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/Sapistudio/SeleniumStealth.git",
"reference": "4b392077e3d609fed564b78ae2e8becb98f01957"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Sapistudio/SeleniumStealth/zipball/4b392077e3d609fed564b78ae2e8becb98f01957",
"reference": "4b392077e3d609fed564b78ae2e8becb98f01957",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-4": {
"SapiStudio\\SeleniumStealth\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"support": {
"issues": "https://github.com/Sapistudio/SeleniumStealth/issues",
"source": "https://github.com/Sapistudio/SeleniumStealth/tree/1.0.3"
},
"time": "2022-01-10T20:04:41+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.5.0",
+8 -6
View File
@@ -12,6 +12,8 @@ services:
- API_CHROMEDRIVER=http://proxitok-chromedriver:9515
# - API_VERIFYFP=verify_...
# - API_DEVICE_ID=4586...
labels:
- "io.containers.autoupdate=registry"
volumes:
- proxitok-cache:/cache
depends_on:
@@ -30,17 +32,17 @@ services:
# Redis, used for caching
redis:
container_name: proxitok-redis
image: redis:7.4-alpine
command: redis-server --save 60 1 --loglevel warning
image: docker.io/library/redis:7.4-alpine
restart: unless-stopped
labels:
- "io.containers.autoupdate=registry"
networks:
- proxitok
init: true
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
# Chromedriver instance, used for sending requests to TikTok
@@ -48,13 +50,13 @@ services:
container_name: proxitok-chromedriver
image: zenika/alpine-chrome:with-chromedriver
init: true
labels:
- "io.containers.autoupdate=registry"
shm_size: 1g
networks:
- proxitok
security_opt:
- seccomp:./misc/setup/docker/chrome.json
ports:
- 9515:9515
volumes:
proxitok-cache:
+120
View File
@@ -0,0 +1,120 @@
[
{
"clearnet": "https://proxitok.pabloferreiro.es/",
"cdn": false,
"country": "AT"
},
{
"clearnet": "https://proxitok.pussthecat.org/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://proxitok.esmailelbob.xyz/",
"tor": "http://proxitok.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd.onion/",
"cdn": false,
"country": "CA"
},
{
"clearnet": "https://proxitok.privacydev.net/",
"tor": "http://proxitok.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid.onion/",
"cdn": false,
"country": "FR"
},
{
"clearnet": "https://tok.artemislena.eu/",
"tor": "http://tok.lpoaj7z2zkajuhgnlltpeqh3zyq7wk2iyeggqaduhgxhyajtdt2j7wad.onion/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://tok.adminforge.de/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://tik.hostux.net/",
"cdn": false,
"country": "FR"
},
{
"clearnet": "https://tt.vern.cc/",
"tor": "http://tt.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion/",
"i2p": "http://vern2gwxbtxzhb3rgchv4kbhlqppijhjqg7rmgvp4c5bxihxcm3a.b32.i2p/",
"cdn": false,
"country": "US"
},
{
"clearnet": "https://cringe.whatever.social/",
"cdn": false,
"country": "US"
},
{
"clearnet": "https://proxitok.lunar.icu/",
"cdn": true,
"country": "DE"
},
{
"clearnet": "https://proxitok.privacy.com.de/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://cringe.whateveritworks.org/",
"cdn": true,
"country": "DE"
},
{
"clearnet": "https://cringe.seitan-ayoub.lol/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://proxitok.kyun.li/",
"cdn": false,
"country": "RO"
},
{
"clearnet": "https://cringe.datura.network/",
"tor": "http://cringe.daturab6drmkhyeia4ch5gvfc2f3wgo6bhjrv3pz6n7kxmvoznlkq4yd.onion/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://tt.opnxng.com/",
"cdn": false,
"country": "SG"
},
{
"clearnet": "https://proxitok.tinfoil-hat.net/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://tiktok.wpme.pl/",
"cdn": true,
"country": "DE"
},
{
"clearnet": "https://proxitok.r4fo.com/",
"tor": "http://proxitok.r4focoma7gu2zdwwcjjad47ysxt634lg73sxmdbkdozanwqslho5ohyd.onion/",
"cdn": true,
"country": "NL"
},
{
"clearnet": "https://proxitok.belloworld.it/",
"cdn": false,
"country": "DE"
},
{
"clearnet": "https://tok.habedieeh.re/",
"tor": "http://tok.habeehrhadazsw3izbrbilqajalfyqqln54mrja3iwpqxgcuxnus7eid.onion/",
"cdn": false,
"country": "CA"
},
{
"tor": "http://pt.skunky7dhv7nohsoalpwe3sxfz3fbkad7r3wk632riye25vqm3meqead.onion/",
"i2p": "http://hm4d5t5jeycvraam3ptvmhlegfttjmxpxgl4lou2hibde7gzfsvq.b32.i2p/",
"cdn": false
}
]
+8
View File
@@ -72,6 +72,14 @@ $router->mount('/tag/([^/]+)', function () use ($router) {
$router->get('/music/([^/]+)', 'MusicController@get');
// For you
$router->mount('/foryou', function () use ($router) {
$router->get('/', 'ForYouController@get');
$router->get('/rss', 'ForYouController@rss');
});
$router->get('/following', 'FollowingController@get');
// -- Settings -- //
$router->mount('/settings', function () use ($router) {
$router->get('/', 'SettingsController@index');
@@ -3,5 +3,5 @@
{if isset($_GET['cursor']) && is_numeric($_GET['cursor']) && $_GET['cursor'] != 0}
<a class="button is-danger" href="?cursor=0">First</a>
{/if}
<a n:attr="disabled => !$feed->hasMore" class="button is-success" href="?cursor={$feed->maxCursor}">Next</a>
<a n:attr="disabled => !$feed->hasMore" class="button is-success" href="?cursor={$feed->cursor}">Next</a>
</div>
@@ -1,8 +1,8 @@
<div class="field is-grouped is-grouped-centered">
<p class="control">
<a target="_blank" href="{url_download($playAddr, $uniqueId, $id, true)}" class="button is-info">Watermark</a>
<a target="_blank" href="{url_download($downloadAddr, $uniqueId, $id, true)}" class="button is-info">Watermark</a>
</p>
<p class="control">
<a target="_blank" href="{url_download(url_video_external($uniqueId, $id), $uniqueId, $id, false)}" class="button is-success">No watermark</a>
<a target="_blank" href="{url_download($playAddr, $uniqueId, $id, false)}" class="button is-success">No watermark</a>
</p>
</div>
+1 -1
View File
@@ -32,7 +32,7 @@
{if isset($item->video->playAddr) && $item->video->playAddr !== ""}
<!-- Download links, not shown if item is a gallery -->
<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}
{include './common/download.latte', id: $item->id, uniqueId: $item->author->uniqueId, playAddr: $item->video->playAddr, downloadAddr: isset($item->video->downloadAddr) ? $item->video->downloadAddr : $item->video->playAddr}
{/if}
<p class="has-text-centered"><b>Share link</b></p>
{include './common/share.latte', uniqueId: $item->author->uniqueId, id: $item->id}
+39
View File
@@ -0,0 +1,39 @@
{layout '../layouts/default.latte'}
{block header}
<p class="title">Discover</p>
{/block}
{block content}
<div class="columns is-multiline is-vcentered">
{foreach $feed->items as $item}
<div class="column is-one-quarter">
{embed '../components/card.latte'}
{block content}
<div class="media">
<!-- Show image if exists -->
{if !empty($item->info->detail->avatarLarger)}
<div class="media-left">
<figure class="image is-96x96">
<img loading="lazy" width="96" height="96" src="{url_stream($item->info->detail->avatarLarger)}" />
</figure>
</div>
{/if}
<div class="media-content">
<p class="title">{$item->info->detail->nickname}</p>
<p class="subtitle">{$item->info->detail->uniqueId}</p>
</div>
</div>
<div class="content">
<p>{$item->info->detail->signature}</p>
</div>
{/block}
{block footer}
<a href="{url_user($item->info->detail->uniqueId)}" class="card-footer-item">Go</a>
{/block}
{/embed}
</div>
{/foreach}
</div>
{include '../components/themes/common/controls.latte', feed: $feed}
{/block}
+12
View File
@@ -0,0 +1,12 @@
{layout '../layouts/default.latte'}
{var $has_rss = true}
{block header}
<p class="title">For you</p>
<p class="subtitle">{include '../components/rss.latte'}</p>
{/block}
{block content}
{include '../components/feed.latte'}
{/block}
+10
View File
@@ -28,4 +28,14 @@
</div>
{/block}
{/embed}
<div class="columns is-centered is-mobile mt-2">
<div class="column is-narrow">
<p>For you</p>
<a class="button is-success" href="{path('/foryou')}">Go</a>
</div>
<div class="column is-narrow">
<p>Following</p>
<a class="button is-success" href="{path('/following')}">Go</a>
</div>
</div>
{/block}
+3 -1
View File
@@ -31,7 +31,9 @@
<p>Hearts: {number($info->stats->heartCount)} / Videos: {$info->stats->videoCount}</p>
{embed '../components/details.latte', title: "Details"}
{block content}
<p>Region: {$info->detail->region}</p>
{if isset($info->detail->region)}
<p>Region: {$info->detail->region}</p>
{/if}
{if $info->detail->commerceUserInfo->commerceUser}
<p>Category: {$info->detail->commerceUserInfo->category}</p>
{/if}