Added GUI & fixed bugs
This commit is contained in:
parent
51d31d16fa
commit
a04efa5042
|
@ -6,7 +6,8 @@ export class Downloader {
|
|||
pool: UrlPool;
|
||||
chunks: {[U: string]: (Buffer | null)} = {};
|
||||
|
||||
chunk_size = Math.round(0.3*1024*1024);
|
||||
chunk_size = Math.round(1*1024*1024);
|
||||
cache_size = 15;
|
||||
|
||||
loading: boolean = false;
|
||||
destroyed: boolean = false;
|
||||
|
@ -44,7 +45,7 @@ export class Downloader {
|
|||
cache() {
|
||||
let chunks: string[] = [];
|
||||
let existing_chunks = Object.keys(this.chunks);
|
||||
for(let i=0; i<15; i++) {
|
||||
for(let i=0; i<this.cache_size; i++) {
|
||||
chunks.push((this.from+(this.chunk_size*i)).toString());
|
||||
}
|
||||
chunks.forEach(from => {
|
||||
|
|
30
index.html
30
index.html
|
@ -1,30 +0,0 @@
|
|||
<head>
|
||||
<link href="https://vjs.zencdn.net/7.17.0/video-js.css" rel="stylesheet" />
|
||||
|
||||
<!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
|
||||
<!-- <script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<video
|
||||
id="my-video"
|
||||
class="video-js"
|
||||
controls
|
||||
preload="auto"
|
||||
width="640"
|
||||
height="264"
|
||||
poster="MY_VIDEO_POSTER.jpg"
|
||||
data-setup="{}"
|
||||
>
|
||||
<source src="/api/stream/ulozto_id" type="video/mp4" />
|
||||
<p class="vjs-no-js">
|
||||
To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that
|
||||
<a href="https://videojs.com/html5-video-support/" target="_blank"
|
||||
>supports HTML5 video</a
|
||||
>
|
||||
</p>
|
||||
</video>
|
||||
|
||||
<script src="https://vjs.zencdn.net/7.17.0/video.min.js"></script>
|
||||
</body>
|
|
@ -1,4 +1,4 @@
|
|||
lockfileVersion: 5.3
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@types/express': ^4.17.13
|
||||
|
@ -130,6 +130,8 @@ packages:
|
|||
dependencies:
|
||||
follow-redirects: 1.5.10
|
||||
is-buffer: 2.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/axios/0.26.0:
|
||||
|
@ -160,6 +162,8 @@ packages:
|
|||
qs: 6.9.7
|
||||
raw-body: 2.4.3
|
||||
type-is: 1.6.18
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/bytes/3.1.2:
|
||||
|
@ -212,12 +216,22 @@ packages:
|
|||
|
||||
/debug/2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
dev: false
|
||||
|
||||
/debug/3.1.0:
|
||||
resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
dev: false
|
||||
|
@ -305,6 +319,8 @@ packages:
|
|||
type-is: 1.6.18
|
||||
utils-merge: 1.0.1
|
||||
vary: 1.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/extend/3.0.2:
|
||||
|
@ -335,6 +351,8 @@ packages:
|
|||
parseurl: 1.3.3
|
||||
statuses: 1.5.0
|
||||
unpipe: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/follow-redirects/1.14.9:
|
||||
|
@ -352,6 +370,8 @@ packages:
|
|||
engines: {node: '>=4.0'}
|
||||
dependencies:
|
||||
debug: 3.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/forever-agent/0.6.1:
|
||||
|
@ -639,6 +659,8 @@ packages:
|
|||
on-finished: 2.3.0
|
||||
range-parser: 1.2.1
|
||||
statuses: 1.5.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/serve-static/1.14.2:
|
||||
|
@ -649,6 +671,8 @@ packages:
|
|||
escape-html: 1.0.3
|
||||
parseurl: 1.3.3
|
||||
send: 0.17.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/setprototypeof/1.2.0:
|
||||
|
@ -707,6 +731,8 @@ packages:
|
|||
dependencies:
|
||||
axios: 0.18.1
|
||||
socks-proxy-agent: 4.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/tor-request/3.1.0:
|
||||
|
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
38
public/index.html
Normal file
38
public/index.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Ulož.to Rychle</title>
|
||||
<style>
|
||||
body {display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif; text-align: center; font-size: 20px; background: #4a0f4d; color: #fff;}
|
||||
.page {max-width: 550px; width: 100%;}
|
||||
.input {display: flex; gap: 5px; flex-flow: row; justify-content: space-between; width: 100%; margin-top: 30px;}
|
||||
.input * {background-color: #702673; border: 2px solid #330a35; border-radius: 5px; padding: 10px 15px; font-size: 17px; outline: 0; color: #fff;}
|
||||
.input input {width: 100%;}
|
||||
.input button {background: #702673;}
|
||||
.input button:hover {background-color: #4a0f4d; cursor: pointer;}
|
||||
.result {justify-content: center; margin-top: 20px; font-size: 17px; display: block; display: flex; gap: 10px;}
|
||||
.result a {color: #fff5;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<h1>Ulož.to Rychle</h1>
|
||||
<p>Stahujte z Ulož.to vysokou rychlostí</p>
|
||||
<div class="input">
|
||||
<input placeholder="Vložte odkaz z Ulož.to" /> <button onclick="download();">Získat</button>
|
||||
</div>
|
||||
<div class="result"></div>
|
||||
</div>
|
||||
<script>
|
||||
function download() {
|
||||
let url = document.querySelector("input").value;
|
||||
let regex = new RegExp(/https:\/\/.*(ulozto\.cz|uloz\.to)\/file\/(.*?)\/.*/gm);
|
||||
let res = regex.exec(url);
|
||||
if(!res) return alert("Neplatná URL!");
|
||||
let id = res[2];
|
||||
let new_url = new URL(`/u/${id}`, location.origin);
|
||||
document.querySelector(".result").innerHTML = `<code>${new_url}</code> <a href="${new_url}" download>Stáhnout</a>`;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
30
urlpool.ts
30
urlpool.ts
|
@ -12,10 +12,13 @@ function sleep(ms: number) {
|
|||
export class UrlPool {
|
||||
|
||||
id: string;
|
||||
storage: UrlPoolStorage;
|
||||
|
||||
urls: string[] = [];
|
||||
used: boolean[] = [];
|
||||
|
||||
valid_to: Date;
|
||||
|
||||
generating = false;
|
||||
downloaders: Downloader[] = [];
|
||||
|
||||
|
@ -23,8 +26,11 @@ export class UrlPool {
|
|||
is_direct = false;
|
||||
ready = false;
|
||||
|
||||
constructor(id: string) {
|
||||
constructor(storage: UrlPoolStorage, id: string) {
|
||||
this.valid_to = new Date();
|
||||
this.valid_to.setDate(this.valid_to.getDate() + 1);
|
||||
this.id = id;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
@ -49,6 +55,7 @@ export class UrlPool {
|
|||
|
||||
this.ready = true;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
get_raw(): [number, string] | undefined {
|
||||
|
@ -119,18 +126,37 @@ export class UrlPool {
|
|||
return d;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.downloaders.forEach(d => d.destroy());
|
||||
delete this.storage.pools[this.id];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class UrlPoolStorage {
|
||||
|
||||
validity_interval: NodeJS.Timer;
|
||||
|
||||
pools: {[U: string]: UrlPool} = {};
|
||||
|
||||
constructor() {
|
||||
this.validity_interval = setInterval(this.validity_check, 1000*60*60);
|
||||
}
|
||||
|
||||
validity_check() {
|
||||
for(let i in this.pools) {
|
||||
if(this.pools[i].valid_to.getTime() < new Date().getTime()) {
|
||||
this.pools[i].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async get(id: string): Promise<UrlPool | undefined> {
|
||||
return this.pools[id] ? this.pools[id] : await this.new(id);
|
||||
}
|
||||
|
||||
async new(id: string): Promise<UrlPool | undefined> {
|
||||
let pool = new UrlPool(id);
|
||||
let pool = new UrlPool(this, id);
|
||||
let check = await pool.init();
|
||||
if(!check) return undefined;
|
||||
pool.start_generation();
|
||||
|
|
|
@ -11,6 +11,8 @@ export class Webserver {
|
|||
|
||||
const app = express();
|
||||
|
||||
app.use(express.static('public'));
|
||||
|
||||
app.get("/status/:id", async (req, res) => {
|
||||
|
||||
let p = await storage.get(req.params.id);
|
||||
|
@ -37,7 +39,7 @@ export class Webserver {
|
|||
|
||||
});
|
||||
|
||||
app.get("/stream/:id", async (req, res) => {
|
||||
app.get("/u/:id", async (req, res) => {
|
||||
|
||||
let p = await storage.get(req.params.id);
|
||||
if(!p) {
|
||||
|
|
Reference in a new issue