Added link requesting & better captcha

This commit is contained in:
Filip Znachor 2023-02-06 21:43:07 +01:00
parent a04efa5042
commit 22b5017b8f
5 changed files with 40 additions and 31 deletions

View file

@ -1,26 +1,34 @@
# Ulož.to streamer # Ulož.to Rychle
Stream ulož.to video content without downloading Program na streamování a stahování obsahu z Ulož.to vysokou rychlostí.
## Instalation ## Instalace
### Python libraries ### Captcha solver
Install all python libraries for `captcha.py`: Pro automatické řešení captchi používáme script `captcha.py`, pro nějž je potřeba nainstalovat Python a následující knihovny.
``` ```sh
numpy, requests, tensorflow, PIL pip install requests tflite_runtime Pillow
``` ```
### Install node modules Může se stát, že v nejnovější verzi Pythonu není **tflite_runtime** dostupný. Doporučujeme proto nainstalovat např. Python 3.9 a vytvořit spustitelný soubor pomocí programu **pyinstaller**.
```sh
pyinstaller captcha.py --onefile
``` ```
### Instalce node modulů
Pro spuštění projektu je potřeba nainstalovat **Node.js** a následně potřebné knihovny pomocí tohoto příkazu.
```sh
npm i --save npm i --save
``` ```
### Setup Tor proxy ### Nastavení Tor proxy
Set `ControlPort`, `SocksPort` and `HashedControlPassword` in /etc/tor/torrc: V konfiguračním souboru `/etc/tor/torrc` nastavte hodnoty `ControlPort`, `SocksPort` a `HashedControlPassword`.
``` ```
SocksPort 9050 SocksPort 9050
@ -28,7 +36,7 @@ ControlPort 9051
HashedControlPassword 16:872230D6EA809D4760AD5894ADB7A5A07191882EBCD188378544794F8F HashedControlPassword 16:872230D6EA809D4760AD5894ADB7A5A07191882EBCD188378544794F8F
``` ```
Password can be generated with: Hesla ke control portu je možno generovat následovně.
``` ```
tor --hash-password giraffe tor --hash-password giraffe

View file

@ -2,7 +2,8 @@ import numpy
import requests import requests
import string import string
import sys import sys
import tensorflow #import tensorflow
import tflite_runtime.interpreter as tflite
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image
@ -16,7 +17,8 @@ def decode(li) -> string:
def solve(url: string) -> string: def solve(url: string) -> string:
interpreter = tensorflow.lite.Interpreter( # for tensorflow tensorflow.lite.Interpreter
interpreter = tflite.Interpreter(
model_content=open("./model.tflite", "rb").read()) model_content=open("./model.tflite", "rb").read())
u = requests.get(url) u = requests.get(url)
raw_data = u.content raw_data = u.content
@ -48,6 +50,6 @@ def solve(url: string) -> string:
try: try:
result = solve(sys.argv[1]) result = solve(sys.argv[1])
print(result, end = "") print(result, end="")
except: except:
pass pass

View file

@ -92,7 +92,7 @@ export class Links {
async captcha(url: string): Promise<string> { async captcha(url: string): Promise<string> {
return new Promise((resolve) => { return new Promise((resolve) => {
exec("python3 captcha.py "+url, (e, o) => { exec("./captcha "+url, (e, o) => {
resolve(o); resolve(o);
}); });
}); });

View file

@ -5,9 +5,9 @@ import { random_int } from "./tools";
let links = new Links; let links = new Links;
function sleep(ms: number) { let unixtime = () => {
return new Promise(resolve => setTimeout(resolve, ms)); return new Date().getTime()/1000;
} };
export class UrlPool { export class UrlPool {
@ -20,11 +20,11 @@ export class UrlPool {
valid_to: Date; valid_to: Date;
generating = false; generating = false;
last_generated: number = unixtime();
downloaders: Downloader[] = []; downloaders: Downloader[] = [];
total_size: number = 0; total_size: number = 0;
is_direct = false; is_direct = false;
ready = false;
constructor(storage: UrlPoolStorage, id: string) { constructor(storage: UrlPoolStorage, id: string) {
this.valid_to = new Date(); this.valid_to = new Date();
@ -53,7 +53,7 @@ export class UrlPool {
this.total_size = parseInt(r.headers["content-range"].split("/")[1]); this.total_size = parseInt(r.headers["content-range"].split("/")[1]);
this.return(url[0]); this.return(url[0]);
this.ready = true; this.generating = true;
return true; return true;
} }
@ -75,6 +75,8 @@ export class UrlPool {
if(url) { if(url) {
clearInterval(check); clearInterval(check);
complete(url); complete(url);
} else {
this.request_generation();
} }
}, 100); }, 100);
}); });
@ -99,16 +101,13 @@ export class UrlPool {
return count ? available.slice(0, count) : available; return count ? available.slice(0, count) : available;
} }
async start_generation() { async request_generation() {
this.generating = true; if(!this.generating || this.last_generated+10 > unixtime()) return;
while(this.urls.length < 15 && this.generating) { console.log(this.id, "| new link:", (await this.generate()) ? true : false);
console.log(this.id, "| new link:", (await this.generate()) ? true : false);
await sleep(2000);
}
this.generating = false;
} }
async generate(): Promise<string | undefined> { async generate(): Promise<string | undefined> {
this.last_generated = unixtime();
try { try {
let link = await (this.is_direct ? links.direct_link(this.id) : links.captcha_link(this.id)); let link = await (this.is_direct ? links.direct_link(this.id) : links.captcha_link(this.id));
if(link) this.add(link); if(link) this.add(link);
@ -159,7 +158,7 @@ export class UrlPoolStorage {
let pool = new UrlPool(this, id); let pool = new UrlPool(this, id);
let check = await pool.init(); let check = await pool.init();
if(!check) return undefined; if(!check) return undefined;
pool.start_generation(); pool.request_generation();
this.pools[id] = pool; this.pools[id] = pool;
return pool; return pool;
} }

View file

@ -30,9 +30,9 @@ export class Webserver {
total: p.urls.length, total: p.urls.length,
available: p.available().length, available: p.available().length,
generating: p.generating, generating: p.generating,
urls: p.urls,
total_size: p.total_size, total_size: p.total_size,
downloaders: p.downloaders.length downloaders: p.downloaders.length,
urls: p.urls
} }
})); }));
res.end(); res.end();