feat(extractor): implement Mixdrop via MediaFlow Proxy
This commit is contained in:
parent
0f415b7521
commit
7c600427e6
11 changed files with 582 additions and 2 deletions
|
|
@ -31,7 +31,7 @@ export class ExtractorRegistry {
|
|||
|
||||
urlResults = await extractor.extract(ctx, normalizedUrl, countryCode, title);
|
||||
|
||||
if (!urlResults.some(urlResult => urlResult.error)) {
|
||||
if (!urlResults.some(urlResult => urlResult.error) && extractor.ttl) {
|
||||
this.urlResultCache.set(normalizedUrl.href, urlResults, { ttl: extractor.ttl });
|
||||
}
|
||||
|
||||
|
|
|
|||
21
src/extractor/Mixdrop.test.ts
Normal file
21
src/extractor/Mixdrop.test.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import winston from 'winston';
|
||||
import { FetcherMock } from '../utils';
|
||||
import { CountryCode } from '../types';
|
||||
import { ExtractorRegistry } from './ExtractorRegistry';
|
||||
import { Mixdrop } from './Mixdrop';
|
||||
import { createTestContext } from '../test';
|
||||
|
||||
const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] });
|
||||
const extractorRegistry = new ExtractorRegistry(logger, [new Mixdrop(new FetcherMock(`${__dirname}/__fixtures__/Mixdrop`))]);
|
||||
|
||||
const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg' });
|
||||
|
||||
describe('Mixdrop', () => {
|
||||
test('mixdrop.my /e/', async () => {
|
||||
expect(await extractorRegistry.handle(ctx, new URL('https://mixdrop.my/e/knq0kj8waq44l8'), CountryCode.de)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('deleted or expired file', async () => {
|
||||
expect(await extractorRegistry.handle(ctx, new URL('https://mixdrop.ag/e/123456789'), CountryCode.de)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
56
src/extractor/Mixdrop.ts
Normal file
56
src/extractor/Mixdrop.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import bytes from 'bytes';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { Extractor } from './Extractor';
|
||||
import { buildMediaFlowProxyUrl, Fetcher, hasMediaFlowProxy } from '../utils';
|
||||
import { Context, CountryCode, UrlResult } from '../types';
|
||||
import { NotFoundError } from '../error';
|
||||
|
||||
export class Mixdrop extends Extractor {
|
||||
public readonly id = 'mixdrop';
|
||||
|
||||
public readonly label = 'Mixdrop';
|
||||
|
||||
public override readonly ttl = 0;
|
||||
|
||||
private readonly fetcher: Fetcher;
|
||||
|
||||
public constructor(fetcher: Fetcher) {
|
||||
super();
|
||||
|
||||
this.fetcher = fetcher;
|
||||
}
|
||||
|
||||
public supports(ctx: Context, url: URL): boolean {
|
||||
return null !== url.host.match(/mixdrop/) && hasMediaFlowProxy(ctx.config);
|
||||
}
|
||||
|
||||
protected async extractInternal(ctx: Context, url: URL, countryCode: CountryCode): Promise<UrlResult[]> {
|
||||
const fileUrl = new URL(url.href.replace('/e/', '/f/'));
|
||||
const html = await this.fetcher.text(ctx, fileUrl);
|
||||
|
||||
if (/can't find the (file|video)/.test(html)) {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
|
||||
const sizeMatch = html.match(/([\d.,]+ ?[GM]B)/);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
const title = $('.title b').text().trim();
|
||||
|
||||
return [
|
||||
{
|
||||
url: buildMediaFlowProxyUrl(ctx.config, 'Mixdrop', url),
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${countryCode}`,
|
||||
ttl: this.ttl,
|
||||
meta: {
|
||||
countryCode,
|
||||
title,
|
||||
...(sizeMatch && {
|
||||
bytes: bytes.parse((sizeMatch[1] as string).replace(',', '')) as number,
|
||||
}),
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
}
|
||||
192
src/extractor/__fixtures__/Mixdrop/https:mixdrop.agf123456789
generated
Normal file
192
src/extractor/__fixtures__/Mixdrop/https:mixdrop.agf123456789
generated
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
<title>MixDrop - File not found</title>
|
||||
<meta name="description" content="" />
|
||||
<meta name="keywords" content="mixdrop,share file,share video,upload file,upload video" />
|
||||
<meta property="og:title" content="MixDrop - File not found" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta name="verified-code" content="035b8906-2381-4a3a-9d4c-3b2ae07293e4">
|
||||
<!--<meta name="robots" content="nosnippet">-->
|
||||
<meta name="a.validate.02" content="ctm1Vhh9zx0o7ew5xlkxmA8MjHBDjK2gY_5x" />
|
||||
<link rel="icon" type="image/png" href="/imgs/v2/favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="/imgs/v2/favicon-16x16.png" sizes="16x16" />
|
||||
<meta name="csrf" content="9e0a3388f70e9e3704f7ffb9f1cd84dc">
|
||||
<meta name="clckd" content="ebd626d580ab61986c788e761c305e41" />
|
||||
<meta name="monetag" content="d1dda856d50c7dd239c4daa5c545e3d3">
|
||||
<meta name="41e891e66eaaca8fc8294c24cc35a2b1eee3aa09" content="41e891e66eaaca8fc8294c24cc35a2b1eee3aa09" />
|
||||
<link rel="stylesheet" href="/js/slidebars/slidebars.css?v=0.1" />
|
||||
<link rel="stylesheet" href="/css/style.v2.0.2.min.css" />
|
||||
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" canvas="container">
|
||||
<div class="panel header">
|
||||
<div class="wrapper">
|
||||
<a href="/"><img src="/imgs/v2/logo.png" class="logo" alt="mixdrop" /></a>
|
||||
|
||||
|
||||
<div class="menu">
|
||||
<a href="javascript:void(0)" class="btn btn1 openModal" data-modal="signup">SIGNUP</a>
|
||||
<a href="javascript:void(0)" class="btn btn2 openModal" data-modal="login">LOGIN</a>
|
||||
</div> <div class="menu-mobile"><img src="/imgs/v2/menu.png" alt="menu"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel download error txt-c">
|
||||
<div class="wrapper">
|
||||
<img src="/imgs/illustration-notfound.png" style="width: 250px;max-width: 80%;" />
|
||||
<h2>WE ARE SORRY</h2>
|
||||
<h3>We can't find the file you are looking for.</h3>
|
||||
<script data-cfasync="false" async type="text/javascript" src="//el.sokajecorin.com/si7MCVE6lXyG8/117018"></script> <div style="padding: 30px 0">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="panel">
|
||||
<div class="wrapper">
|
||||
<div class="col-3">
|
||||
<a href="/"><img src="/imgs/v2/logo.png" class="logo" alt="mixdrop" /></a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="contact">Contact</a>
|
||||
<a href="/news/">News</a>
|
||||
<a href="/faq/">FAQ</a>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="hdr">POLICY</div>
|
||||
<a href="/terms/">Terms And Conditions</a>
|
||||
<a href="/privacy/">Privacy Policy</a>
|
||||
<a href="/copyright/">Copyright Policy</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="abuse">Report Abuse</a>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="hdr">SERVICES</div>
|
||||
<a href="/panel/">User Panel</a>
|
||||
<a href="/api/">API</a>
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-lang">
|
||||
<div class="langSwitch">
|
||||
<a href="javascript:void(0)" title="English"><img src="/imgs/flag_en.png" alt="english"> EN</a>
|
||||
<div class="langOptions" style="display: none;">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<div class="uploadbox">
|
||||
<div class="header">Uploads ( <span>0 / 0</span> ) <i class="toggle"></i></div>
|
||||
<div class="scroll">
|
||||
<div class="tbl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="goUp" class="scrollTo floating" data-scrollto='.container'></div>
|
||||
<div class="modal" id="modal-login">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<input type="password" name="password" placeholder="Password" class="ic ic-in-pass" />
|
||||
<div class="2fa-content" style="display:none">
|
||||
<label class="hdr">2FA Confirmation Code</label>
|
||||
|
||||
<p>A confirmation code was sent to your e-mail address, please confirm it below</p>
|
||||
<input type="text" name="code" placeholder="" style="text-transform: uppercase;font-size: 2rem;letter-spacing: .5rem;" />
|
||||
</div>
|
||||
<button type="button" class="submit btn2">LOGIN</button>
|
||||
<a href="javascript:void(0)" class="forgot">Forgot your password?</a>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="step" value="0" />
|
||||
<input type="hidden" name="a" value="login" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-recover">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<button type="button" class="submit btn2">RECOVER</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="recover" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-signup">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<input type="password" name="password" placeholder="Password" class="ic ic-in-pass" />
|
||||
<input type="password" name="passwordconfirm" placeholder="Repeat Password" class="ic ic-in-pass" />
|
||||
<button type="button" class="submit btn2">SIGNUP</button>
|
||||
<a href="javascript:void(0)" class="mlogin">Already have an account?</a>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="signup" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-contact">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="name" placeholder="Your name" class="ic ic-in-user" />
|
||||
<input type="text" name="email" placeholder="Your E-Mail" class="ic ic-in-mail" />
|
||||
<textarea name="message" placeholder="Your message" class="ic ic-in-compose" rows="6"></textarea>
|
||||
<button type="button" class="submit btn2">SEND MESSAGE</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="contact" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-abuse">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<select name="reason" class="ic ic-in-list">
|
||||
<option>Reason</option>
|
||||
<option value="copyright">Copyright infringement</option>
|
||||
<option value="cp">Child Pornography</option>
|
||||
<option value="terrorism">Terrorism Content</option>
|
||||
</select>
|
||||
<input type="text" name="name" placeholder="Your name" class="ic ic-in-user" />
|
||||
<input type="text" name="email" placeholder="Your E-Mail" class="ic ic-in-mail" />
|
||||
<textarea name="message" placeholder="Your message" class="ic ic-in-compose" rows="6"></textarea>
|
||||
<button type="button" class="submit btn2">SEND MESSAGE</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="abuse" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div off-canvas="menu right push" class="toggleMenu">
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="login">LOGIN</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="signup">SIGNUP</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".landing">HOME</a>
|
||||
<a href="/panel/">USER PANEL</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".share">SHARE</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".embed">EMBED</a>
|
||||
<a href="" class="scrollTo" data-scrollto=".affiliate">AFFILIATE</a>
|
||||
<a href="/faq/">FAQ</a>
|
||||
<a href="/news/">NEWS</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="contact">CONTACT</a>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" integrity="sha256-lSjKY0/srUM9BE3dPm+c4fBo1dky2v27Gdjm2uoZaL0=" crossorigin="anonymous"></script>
|
||||
<script src="/js/modal/modal.js?v=2.0.1"></script>
|
||||
<script src="/js/slidebars/slidebars.min.js?v=2.0.1"></script>
|
||||
<script src="/js/circular-progress/circle-progress.min.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/jquery.iframe-transport.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/jquery.fileupload.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/main.js?v=2.0.1"></script>
|
||||
<script src="/panel/js/scroll/perfect-scrollbar.min.js?v=2.0.1"></script>
|
||||
<link rel="stylesheet" href="/panel/js/scroll/perfect-scrollbar.css?v=2.0.1" />
|
||||
<script src="/js/script.v2.min.js?v=2.0.1"></script>
|
||||
<script src="/js/ads.js"></script>
|
||||
|
||||
<script defer data-domain="mixdrop.ag/f" src="https://mdstats.info/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
213
src/extractor/__fixtures__/Mixdrop/https:mixdrop.myfknq0kj8waq44l8
generated
Normal file
213
src/extractor/__fixtures__/Mixdrop/https:mixdrop.myfknq0kj8waq44l8
generated
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
<title>MixDrop - Watch 28_giorni_dopo_2002_HD_-_Altadefinizione01</title>
|
||||
<meta name="description" content="" />
|
||||
<meta name="keywords" content="mixdrop,share file,share video,upload file,upload video" />
|
||||
<meta property="og:title" content="MixDrop - Watch 28_giorni_dopo_2002_HD_-_Altadefinizione01" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta name="verified-code" content="035b8906-2381-4a3a-9d4c-3b2ae07293e4">
|
||||
<!--<meta name="robots" content="nosnippet">-->
|
||||
<meta name="a.validate.02" content="ctm1Vhh9zx0o7ew5xlkxmA8MjHBDjK2gY_5x" />
|
||||
<link rel="icon" type="image/png" href="/imgs/v2/favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="/imgs/v2/favicon-16x16.png" sizes="16x16" />
|
||||
<meta name="csrf" content="2928b10d4f03dafd5a62f1db31d164f0">
|
||||
<meta name="clckd" content="ebd626d580ab61986c788e761c305e41" />
|
||||
<meta name="monetag" content="d1dda856d50c7dd239c4daa5c545e3d3">
|
||||
<meta name="41e891e66eaaca8fc8294c24cc35a2b1eee3aa09" content="41e891e66eaaca8fc8294c24cc35a2b1eee3aa09" />
|
||||
<link rel="stylesheet" href="/js/slidebars/slidebars.css?v=0.1" />
|
||||
<link rel="stylesheet" href="/css/style.v2.0.2.min.css" />
|
||||
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" canvas="container">
|
||||
<div class="panel header">
|
||||
<div class="wrapper">
|
||||
<a href="/"><img src="/imgs/v2/logo.png" class="logo" alt="mixdrop" /></a>
|
||||
|
||||
|
||||
<div class="menu">
|
||||
<a href="javascript:void(0)" class="btn btn1 openModal" data-modal="signup">SIGNUP</a>
|
||||
<a href="javascript:void(0)" class="btn btn2 openModal" data-modal="login">LOGIN</a>
|
||||
</div> <div class="menu-mobile"><img src="/imgs/v2/menu.png" alt="menu"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel download video">
|
||||
<div class="wrapper">
|
||||
<div class="download-top">
|
||||
<iframe width="100%" height="100%" src="/e/knq0kj8waq44l8" frameborder="0" scrolling="no" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<div class="player-bottom block">
|
||||
<div class="tbl">
|
||||
<div class="tbl-c c-l title">
|
||||
<img src="/imgs/v2/i-download.png" class="icon" /> <b title="28_giorni_dopo_2002_HD_-_Altadefinizione01.mp4">28_giorni_dopo_2002_HD_-_Altadefinizione01.mp4</b> 1,010.71 MB </div>
|
||||
|
||||
<div class="tbl-c txt-r">
|
||||
<div class="download download-wrapper">
|
||||
<div class="s-wrapper">
|
||||
<a class="sc fb" onclick="MDCore.share_fb('https://mxdrop.to/f/knq0kj8waq44l8');return false;" title="Share"></a><a class="sc tw" onclick="MDCore.share_twitter('https://mxdrop.to/f/knq0kj8waq44l8','Watch%2028_giorni_dopo_2002_HD_-_Altadefinizione01%0A');return false;" title="Share"></a>
|
||||
</div>
|
||||
<a class="btn btn3 download-btn player" href="?download">DOWNLOAD</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="download-embed block">
|
||||
<div class="embed-wrapper">
|
||||
<label>EMBED</label>
|
||||
<textarea onclick="this.select()"><iframe width="560" height="315" src="https://mxdrop.to/e/knq0kj8waq44l8" frameborder="0" allowfullscreen></iframe></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 30px 0">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="panel">
|
||||
<div class="wrapper">
|
||||
<div class="col-3">
|
||||
<a href="/"><img src="/imgs/v2/logo.png" class="logo" alt="mixdrop" /></a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="contact">Contact</a>
|
||||
<a href="/news/">News</a>
|
||||
<a href="/faq/">FAQ</a>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="hdr">POLICY</div>
|
||||
<a href="/terms/">Terms And Conditions</a>
|
||||
<a href="/privacy/">Privacy Policy</a>
|
||||
<a href="/copyright/">Copyright Policy</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="abuse">Report Abuse</a>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="hdr">SERVICES</div>
|
||||
<a href="/panel/">User Panel</a>
|
||||
<a href="/api/">API</a>
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-lang">
|
||||
<div class="langSwitch">
|
||||
<a href="javascript:void(0)" title="English"><img src="/imgs/flag_en.png" alt="english"> EN</a>
|
||||
<div class="langOptions" style="display: none;">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<div class="uploadbox">
|
||||
<div class="header">Uploads ( <span>0 / 0</span> ) <i class="toggle"></i></div>
|
||||
<div class="scroll">
|
||||
<div class="tbl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="goUp" class="scrollTo floating" data-scrollto='.container'></div>
|
||||
<div class="modal" id="modal-login">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<input type="password" name="password" placeholder="Password" class="ic ic-in-pass" />
|
||||
<div class="2fa-content" style="display:none">
|
||||
<label class="hdr">2FA Confirmation Code</label>
|
||||
|
||||
<p>A confirmation code was sent to your e-mail address, please confirm it below</p>
|
||||
<input type="text" name="code" placeholder="" style="text-transform: uppercase;font-size: 2rem;letter-spacing: .5rem;" />
|
||||
</div>
|
||||
<button type="button" class="submit btn2">LOGIN</button>
|
||||
<a href="javascript:void(0)" class="forgot">Forgot your password?</a>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="step" value="0" />
|
||||
<input type="hidden" name="a" value="login" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-recover">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<button type="button" class="submit btn2">RECOVER</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="recover" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-signup">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="email" placeholder="E-Mail" class="ic ic-in-mail" />
|
||||
<input type="password" name="password" placeholder="Password" class="ic ic-in-pass" />
|
||||
<input type="password" name="passwordconfirm" placeholder="Repeat Password" class="ic ic-in-pass" />
|
||||
<button type="button" class="submit btn2">SIGNUP</button>
|
||||
<a href="javascript:void(0)" class="mlogin">Already have an account?</a>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="signup" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-contact">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<input type="text" name="name" placeholder="Your name" class="ic ic-in-user" />
|
||||
<input type="text" name="email" placeholder="Your E-Mail" class="ic ic-in-mail" />
|
||||
<textarea name="message" placeholder="Your message" class="ic ic-in-compose" rows="6"></textarea>
|
||||
<button type="button" class="submit btn2">SEND MESSAGE</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="contact" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal-abuse">
|
||||
<div class="modal-wrapper">
|
||||
<form action="/actions/global.php">
|
||||
<select name="reason" class="ic ic-in-list">
|
||||
<option>Reason</option>
|
||||
<option value="copyright">Copyright infringement</option>
|
||||
<option value="cp">Child Pornography</option>
|
||||
<option value="terrorism">Terrorism Content</option>
|
||||
</select>
|
||||
<input type="text" name="name" placeholder="Your name" class="ic ic-in-user" />
|
||||
<input type="text" name="email" placeholder="Your E-Mail" class="ic ic-in-mail" />
|
||||
<textarea name="message" placeholder="Your message" class="ic ic-in-compose" rows="6"></textarea>
|
||||
<button type="button" class="submit btn2">SEND MESSAGE</button>
|
||||
<div class="mbError"> </div>
|
||||
<input type="hidden" name="a" value="abuse" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div off-canvas="menu right push" class="toggleMenu">
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="login">LOGIN</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="signup">SIGNUP</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".landing">HOME</a>
|
||||
<a href="/panel/">USER PANEL</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".share">SHARE</a>
|
||||
<a href="javascript:void(0)" class="scrollTo" data-scrollto=".embed">EMBED</a>
|
||||
<a href="" class="scrollTo" data-scrollto=".affiliate">AFFILIATE</a>
|
||||
<a href="/faq/">FAQ</a>
|
||||
<a href="/news/">NEWS</a>
|
||||
<a href="javascript:void(0)" class="openModal" data-modal="contact">CONTACT</a>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" integrity="sha256-lSjKY0/srUM9BE3dPm+c4fBo1dky2v27Gdjm2uoZaL0=" crossorigin="anonymous"></script>
|
||||
<script src="/js/modal/modal.js?v=2.0.1"></script>
|
||||
<script src="/js/slidebars/slidebars.min.js?v=2.0.1"></script>
|
||||
<script src="/js/circular-progress/circle-progress.min.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/jquery.iframe-transport.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/jquery.fileupload.js?v=2.0.1"></script>
|
||||
<script src="/js/jquery-upload/js/main.js?v=2.0.1"></script>
|
||||
<script src="/panel/js/scroll/perfect-scrollbar.min.js?v=2.0.1"></script>
|
||||
<link rel="stylesheet" href="/panel/js/scroll/perfect-scrollbar.css?v=2.0.1" />
|
||||
<script src="/js/script.v2.min.js?v=2.0.1"></script>
|
||||
<script src="/js/ads.js"></script>
|
||||
|
||||
<script defer data-domain="mixdrop.ag/f" src="https://mdstats.info/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
19
src/extractor/__snapshots__/Mixdrop.test.ts.snap
Normal file
19
src/extractor/__snapshots__/Mixdrop.test.ts.snap
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Mixdrop deleted or expired file 1`] = `[]`;
|
||||
|
||||
exports[`Mixdrop mixdrop.my /e/ 1`] = `
|
||||
[
|
||||
{
|
||||
"label": "Mixdrop",
|
||||
"meta": {
|
||||
"bytes": 1059806248,
|
||||
"countryCode": "de",
|
||||
"title": "28_giorni_dopo_2002_HD_-_Altadefinizione01.mp4",
|
||||
},
|
||||
"sourceId": "mixdrop_de",
|
||||
"ttl": 0,
|
||||
"url": "https://mediaflow-proxy.test/extractor/video?host=Mixdrop&redirect_stream=true&api_password=asdfg&d=https%3A%2F%2Fmixdrop.my%2Fe%2Fknq0kj8waq44l8",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
@ -8,6 +8,7 @@ import { Soaper } from './Soaper';
|
|||
import { SuperVideo } from './SuperVideo';
|
||||
import { VidSrc } from './VidSrc';
|
||||
import { Fetcher } from '../utils';
|
||||
import { Mixdrop } from './Mixdrop';
|
||||
|
||||
export * from './Extractor';
|
||||
export * from './ExtractorRegistry';
|
||||
|
|
@ -18,6 +19,7 @@ export const createExtractors = (fetcher: Fetcher): Extractor[] => [
|
|||
new Fsst(fetcher),
|
||||
new SuperVideo(fetcher),
|
||||
new KinoGer(fetcher),
|
||||
new Mixdrop(fetcher),
|
||||
new Soaper(fetcher),
|
||||
new VidSrc(fetcher),
|
||||
new ExternalUrl(fetcher), // fallback extractor which must come last
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export interface Context {
|
|||
|
||||
export type ManifestWithConfig = Manifest & { config: ManifestConfig[] };
|
||||
|
||||
export type Config = Partial<Record<CountryCode | 'includeExternalUrls', string>>;
|
||||
export type Config = Partial<Record<CountryCode | 'includeExternalUrls' | 'mediaFlowProxyUrl' | 'mediaFlowProxyPassword', string>>;
|
||||
|
||||
export enum CountryCode {
|
||||
de = 'de',
|
||||
|
|
|
|||
|
|
@ -8,6 +8,18 @@ exports[`buildManifest has checked includeExternalUrls 1`] = `
|
|||
"title": "Include external URLs from results",
|
||||
"type": "checkbox",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyUrl",
|
||||
"title": "MediaFlow Proxy URL",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyPassword",
|
||||
"title": "MediaFlow Proxy Password",
|
||||
"type": "password",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
|
|
@ -35,6 +47,18 @@ exports[`buildManifest has checked source with appropriate config 1`] = `
|
|||
"title": "Include external URLs from results",
|
||||
"type": "checkbox",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyUrl",
|
||||
"title": "MediaFlow Proxy URL",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyPassword",
|
||||
"title": "MediaFlow Proxy Password",
|
||||
"type": "password",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
|
|
@ -60,6 +84,18 @@ exports[`buildManifest has unchecked source without a config 1`] = `
|
|||
"title": "Include external URLs from results",
|
||||
"type": "checkbox",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyUrl",
|
||||
"title": "MediaFlow Proxy URL",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyPassword",
|
||||
"title": "MediaFlow Proxy Password",
|
||||
"type": "password",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
|
|
@ -70,5 +106,17 @@ exports[`buildManifest includeExternalUrls is unchecked by default 1`] = `
|
|||
"title": "Include external URLs from results",
|
||||
"type": "checkbox",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyUrl",
|
||||
"title": "MediaFlow Proxy URL",
|
||||
"type": "text",
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"key": "mediaFlowProxyPassword",
|
||||
"title": "MediaFlow Proxy Password",
|
||||
"type": "password",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -5,3 +5,18 @@ export const getDefaultConfig = (): Config => {
|
|||
};
|
||||
|
||||
export const showExternalUrls = (config: Config): boolean => 'includeExternalUrls' in config;
|
||||
|
||||
export const hasMediaFlowProxy = (config: Config): boolean => !!(config['mediaFlowProxyUrl'] && config['mediaFlowProxyPassword']);
|
||||
|
||||
export const buildMediaFlowProxyUrl = (config: Config, host: string, url: URL): URL => {
|
||||
const mediaFlowProxyUrl = new URL(`${config.mediaFlowProxyUrl}/extractor/video`);
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('host', host);
|
||||
params.append('redirect_stream', 'true');
|
||||
params.append('api_password', `${config.mediaFlowProxyPassword}`);
|
||||
params.append('d', url.href);
|
||||
mediaFlowProxyUrl.search = params.toString();
|
||||
|
||||
return mediaFlowProxyUrl;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -57,5 +57,19 @@ export const buildManifest = (sources: Source[], config: Config): ManifestWithCo
|
|||
...('includeExternalUrls' in config && { default: 'checked' }),
|
||||
});
|
||||
|
||||
manifest.config.push({
|
||||
key: 'mediaFlowProxyUrl',
|
||||
type: 'text',
|
||||
title: 'MediaFlow Proxy URL',
|
||||
default: config['mediaFlowProxyUrl'] ?? '',
|
||||
});
|
||||
|
||||
manifest.config.push({
|
||||
key: 'mediaFlowProxyPassword',
|
||||
type: 'password',
|
||||
title: 'MediaFlow Proxy Password',
|
||||
default: config['mediaFlowProxyPassword'] ?? '',
|
||||
});
|
||||
|
||||
return manifest;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue