Files
porn365/porn365.js

188 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function () {
'use strict';
var FLAG = 'lampa_p365x_parser_started';
if (window[FLAG]) return;
window[FLAG] = true;
var BASE = 'https://m.porno365x.space';
var PROXY_KEY = 'porn365_proxy_url'; // example: https://your-proxy/fetch?url=
var STATE = { items: [], page: 1, loading: false };
function $(sel, root) { return (root || document).querySelector(sel); }
function el(tag, cls, txt) { var n = document.createElement(tag); if (cls) n.className = cls; if (txt != null) n.textContent = txt; return n; }
function getProxy() { try { return localStorage.getItem(PROXY_KEY) || ''; } catch (e) { return ''; } }
function setProxy(v) { try { localStorage.setItem(PROXY_KEY, v || ''); } catch (e) {} }
function buildFetchUrl(url) {
var p = getProxy().trim();
if (!p) return url;
if (p.indexOf('{url}') >= 0) return p.replace('{url}', encodeURIComponent(url));
return p + encodeURIComponent(url);
}
function extractCards(html) {
var out = [];
var re = /<li id="(\d+)"[\s\S]*?<a class="image" href="([^"]+)"[\s\S]*?<img src="([^"]+)"[\s\S]*?<p>([^<]+)<\/p>[\s\S]*?<span class="duration">([^<]*)<\/span>/g;
var m;
while ((m = re.exec(html))) {
out.push({
id: m[1],
url: m[2].startsWith('http') ? m[2] : BASE + m[2],
poster: m[3],
title: m[4].trim(),
duration: (m[5] || '').trim()
});
}
return out;
}
function extractMp4(movieHtml) {
var all = [];
var re = /file\s*:\s*"([^"]+\.mp4[^"]*)"/g;
var m;
while ((m = re.exec(movieHtml))) all.push(m[1]);
if (!all.length) {
var v = movieHtml.match(/<video[^>]+src="([^"]+\.mp4[^"]*)"/i);
if (v) all.push(v[1]);
}
all.sort(function (a, b) {
function q(x) { var mm = x.match(/_(\d{3,4})p\.mp4/i); return mm ? Number(mm[1]) : 0; }
return q(b) - q(a);
});
return all[0] || '';
}
async function request(url) {
var finalUrl = buildFetchUrl(url);
var r = await fetch(finalUrl, { credentials: 'omit' });
if (!r.ok) throw new Error('HTTP ' + r.status);
return await r.text();
}
async function fetchList(page) {
var url = page > 1 ? (BASE + '/page/' + page + '/') : (BASE + '/');
var html = await request(url);
return extractCards(html);
}
async function fetchStream(movieUrl) {
var html = await request(movieUrl);
return extractMp4(html);
}
function openProxyPrompt() {
var current = getProxy();
var next = window.prompt(
'Proxy URL для обхода CORS.\nФорматы:\n1) https://your-proxy/fetch?url=\n2) https://your-proxy/fetch/{url}\n\nПустое значение отключает proxy.',
current
);
if (next === null) return;
setProxy((next || '').trim());
setStatus(getProxy() ? 'Proxy сохранён' : 'Proxy отключен');
}
function createUi() {
if ($('#p365x-root')) return;
var css = el('style');
css.textContent = '' +
'#p365x-fab{position:fixed;right:24px;bottom:24px;z-index:99999;background:#e91e63;color:#fff;border:none;border-radius:999px;padding:10px 14px;font-weight:700;}' +
'#p365x-root{position:fixed;inset:0;z-index:99998;background:#111;color:#fff;display:none;}' +
'#p365x-head{padding:12px 16px;display:flex;gap:10px;align-items:center;border-bottom:1px solid #333;flex-wrap:wrap;}' +
'#p365x-list{padding:10px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px;overflow:auto;height:calc(100% - 84px);}' +
'.p365x-card{background:#1b1b1b;border:1px solid #333;border-radius:8px;overflow:hidden;cursor:pointer;}' +
'.p365x-card img{width:100%;height:130px;object-fit:cover;display:block;}' +
'.p365x-meta{padding:8px;font-size:13px;}' +
'#p365x-player{position:fixed;inset:0;z-index:100000;background:#000;display:none;}' +
'#p365x-player video{width:100%;height:100%;}' +
'#p365x-close-player{position:absolute;top:10px;right:10px;z-index:2;}';
document.head.appendChild(css);
var fab = el('button');
fab.id = 'p365x-fab';
fab.textContent = 'P365';
var root = el('div');
root.id = 'p365x-root';
root.innerHTML = '<div id="p365x-head"><button id="p365x-close">Закрыть</button><button id="p365x-more">Ещё</button><button id="p365x-proxy">Proxy</button><span id="p365x-status"></span></div><div id="p365x-list"></div>';
var player = el('div');
player.id = 'p365x-player';
player.innerHTML = '<button id="p365x-close-player">Закрыть</button><video id="p365x-video" controls autoplay playsinline></video>';
document.body.appendChild(fab);
document.body.appendChild(root);
document.body.appendChild(player);
fab.addEventListener('click', function () {
root.style.display = 'block';
if (!STATE.items.length) loadNextPage();
if (getProxy()) setStatus('Proxy: включен');
});
$('#p365x-close').addEventListener('click', function () { root.style.display = 'none'; });
$('#p365x-more').addEventListener('click', loadNextPage);
$('#p365x-proxy').addEventListener('click', openProxyPrompt);
$('#p365x-close-player').addEventListener('click', function () {
player.style.display = 'none';
var v = $('#p365x-video');
v.pause();
v.removeAttribute('src');
v.load();
});
}
function setStatus(t) { var s = $('#p365x-status'); if (s) s.textContent = t || ''; }
function renderItems() {
var list = $('#p365x-list');
if (!list) return;
list.innerHTML = '';
STATE.items.forEach(function (item) {
var c = el('div', 'p365x-card');
c.innerHTML = '<img src="' + item.poster + '" alt=""><div class="p365x-meta"><div>' + item.title + '</div><div style="opacity:.7">' + item.duration + '</div></div>';
c.addEventListener('click', async function () {
try {
setStatus('Загрузка видео...');
var src = await fetchStream(item.url);
if (!src) throw new Error('Поток не найден');
var p = $('#p365x-player');
var v = $('#p365x-video');
v.src = src;
p.style.display = 'block';
setStatus('');
} catch (e) {
setStatus('Ошибка: ' + e.message + '. Попробуй настроить Proxy.');
}
});
list.appendChild(c);
});
}
async function loadNextPage() {
if (STATE.loading) return;
STATE.loading = true;
try {
setStatus('Загрузка страницы ' + STATE.page + '...');
var items = await fetchList(STATE.page);
STATE.items = STATE.items.concat(items);
STATE.page += 1;
renderItems();
setStatus('Найдено: ' + STATE.items.length + (getProxy() ? ' | Proxy on' : ' | Proxy off'));
} catch (e) {
setStatus('Не удалось загрузить: ' + e.message + '. Настрой Proxy.');
} finally {
STATE.loading = false;
}
}
function start() { createUi(); }
if (window.appready) start();
else if (window.Lampa && Lampa.Listener) {
Lampa.Listener.follow('app', function (e) { if (e.type === 'ready') start(); });
} else {
window.addEventListener('load', start);
}
})();