156 lines
7.5 KiB
HTML
156 lines
7.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-theme="dark">
|
|
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Hosts Converter</title>
|
|
<meta name="theme-color" content="#0f1115" />
|
|
<link rel="preload" href="{{ url_for('static', filename='css/main.css') }}" as="style">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
|
|
</head>
|
|
|
|
<body>
|
|
<header class="site-header">
|
|
<div class="brand">
|
|
<svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
|
|
<path d="M4 4h16v4H4zM4 10h10v4H4zM4 16h16v4H4z" fill="currentColor" />
|
|
</svg>
|
|
<span>Hosts Converter</span>
|
|
</div>
|
|
<nav class="actions">
|
|
<button class="btn ghost" type="button" data-action="toggle-theme" aria-label="Toggle theme">🌓</button>
|
|
<a class="btn primary" href="https://www.linuxiarz.pl" target="_blank" rel="noopener">linuxiarz.pl</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<main class="container">
|
|
<section class="card hero">
|
|
<div class="hero-text">
|
|
<h1>Convert adblock lists to MikroTik / hosts</h1>
|
|
<p class="muted">Paste a list URL (AdGuard/uBlock/hosts/dnsmasq), pick the target IP, and generate a
|
|
<kbd>/convert</kbd> link.
|
|
</p>
|
|
</div>
|
|
<div class="hero-cta">
|
|
<a class="btn primary large" href="#form">Start</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="form" class="card form-card" aria-labelledby="form-title">
|
|
<h2 id="form-title">Link generator</h2>
|
|
|
|
<form method="GET" action="/" novalidate>
|
|
<div class="grid">
|
|
<div class="form-group col-12">
|
|
<label for="url-input">URL to hosts/adblock list</label>
|
|
<input id="url-input" type="url" name="url" required placeholder="https://example.com/list.txt"
|
|
inputmode="url" autocomplete="url" aria-describedby="url-help" autofocus>
|
|
<small id="url-help" class="hint"> Supported formats: <code>||domain^</code>,
|
|
<code>address=/domain/</code>, hosts files, plain domains.</small>
|
|
<div class="error" data-error-for="url-input"></div>
|
|
</div>
|
|
|
|
<div class="form-group col-6">
|
|
<label for="ip-input">Target IP</label>
|
|
<input id="ip-input" type="text" name="ip" value="195.187.6.34" required inputmode="text"
|
|
autocomplete="off" aria-describedby="ip-help" spellcheck="false">
|
|
<small id="ip-help" class="hint">Common choices: <code>0.0.0.0</code>, <code>127.0.0.1</code>,
|
|
your device IP, supports IPv4 and IPv6.</small>
|
|
<div class="error" data-error-for="ip-input"></div>
|
|
</div>
|
|
|
|
<div class="form-group col-6">
|
|
<label for="ip-preset">Presets</label>
|
|
<select id="ip-preset" class="select">
|
|
<option value="">— choose preset —</option>
|
|
<option value="0.0.0.0">0.0.0.0 (blackhole)</option>
|
|
<option value="127.0.0.1">127.0.0.1 (localhost)</option>
|
|
<option value="195.187.6.34">195.187.6.34 (current)</option>
|
|
|
|
<option value="custom">Custom…</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-actions col-12">
|
|
<button class="btn ghost" type="button" data-action="clear">Clear</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="result-box" data-state="empty" aria-live="polite" aria-atomic="true">
|
|
<div class="result-row">
|
|
<input id="generated-link" type="text" value="{{ generated_link or '' }}" readonly
|
|
placeholder="Link will appear here…">
|
|
<div class="result-buttons">
|
|
|
|
<button class="btn" type="button" id="copy-btn" data-action="copy"
|
|
data-target="#generated-link">Copy</button>
|
|
|
|
<a class="btn outline" id="open-link" href="{{ generated_link or '#' }}" target="_blank"
|
|
rel="noopener" aria-disabled="{{ 'false' if generated_link else 'true' }}">Open</a>
|
|
|
|
</div>
|
|
</div>
|
|
<small class="hint">Paste this link in your Mikrotik (IP -> DNS -> Adlist) or other DNS server /
|
|
ad blocking tool</small>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="card recent-card">
|
|
<div class="section-head">
|
|
<h2>Recent converts</h2>
|
|
<div class="head-actions">
|
|
<button class="btn ghost" type="button" data-action="collapse" aria-expanded="false"
|
|
aria-controls="recent-list">Expand</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="recent-list" class="recent-list" style="display:none">
|
|
{% if recent_links %}
|
|
{% for link_data in recent_links %}
|
|
<article class="link-item">
|
|
<div class="link-main">
|
|
<a class="mono ellipsis" title="{{ link_data[1] }}"
|
|
href="/convert?url={{ link_data[1]|urlencode }}&ip={{ link_data[2] }}" target="_blank"
|
|
rel="noopener">
|
|
{{ link_data[1] }}
|
|
</a>
|
|
<span class="arrow">→</span>
|
|
<span class="mono ellipsis" title="{{ link_data[2] }}">{{ link_data[2] }}</span>
|
|
</div>
|
|
<div class="link-meta">
|
|
<span class="timestamp">{{ link_data[0]|datetimeformat }}</span>
|
|
<div class="link-actions">
|
|
<button class="btn tiny" type="button" data-action="copy-text"
|
|
data-text="{{ url_for('convert', _external=True) }}?url={{ link_data[1]|urlencode }}&ip={{ link_data[2] }}">Copy</button>
|
|
<a class="btn tiny outline"
|
|
href="/convert?url={{ link_data[1]|urlencode }}&ip={{ link_data[2] }}" target="_blank"
|
|
rel="noopener">Open</a>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
{% endfor %}
|
|
{% else %}
|
|
<p class="muted">Empty..</p>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<footer class="site-footer">
|
|
<div>© 2025 <a href="https://www.linuxiarz.pl" target="_blank" rel="noopener">linuxiarz.pl</a> · All rights
|
|
reserved</div>
|
|
<div class="meta">Your IP: <strong>{{ client_ip }}</strong> · UA: <strong>{{ user_agent }}</strong></div>
|
|
</footer>
|
|
|
|
<div id="toast" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
|
|
<script defer src="{{ url_for('static', filename='js/main.js') }}"></script>
|
|
<script>
|
|
// no-flash theme bootstrap
|
|
(function () { const t = localStorage.getItem('theme') || 'dark'; document.documentElement.setAttribute('data-theme', t); })();
|
|
</script>
|
|
</body>
|
|
|
|
</html> |