RSS/Atom -> ntfy bridge with web UI, OPML import/export and RU/EN localization
Web-managed fork of nurefexc/rss-bridge-ntfy: Flask UI + REST API, background sync engine (SQLite dedup, quiet hours, filters, flood protection, images), OPML import/export and switchable interface/notification language. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RSS → ntfy bridge</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<span class="logo">📡</span>
|
||||
<div>
|
||||
<h1>RSS → ntfy</h1>
|
||||
<small data-i18n="subtitle">веб-панель управления мостом</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<span id="engine-pill" class="pill pill-muted">…</span>
|
||||
<button id="btn-sync" class="btn btn-primary" data-i18n="sync_now">⟳ Синхронизировать</button>
|
||||
<button id="btn-toggle" class="btn" data-i18n="pause">Пауза</button>
|
||||
<select id="lang-select" class="lang-select" title="Language">
|
||||
<option value="ru">RU</option>
|
||||
<option value="en">EN</option>
|
||||
</select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="tabs">
|
||||
<button class="tab active" data-tab="dashboard" data-i18n="tab_dashboard">Дашборд</button>
|
||||
<button class="tab" data-tab="feeds" data-i18n="tab_feeds">Фиды</button>
|
||||
<button class="tab" data-tab="settings" data-i18n="tab_settings">Настройки</button>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
<!-- DASHBOARD -->
|
||||
<section id="tab-dashboard" class="tab-panel active">
|
||||
<div class="cards">
|
||||
<div class="card"><div class="card-val" id="stat-feeds">–</div><div class="card-lbl" data-i18n="card_feeds">Фидов (активно)</div></div>
|
||||
<div class="card"><div class="card-val" id="stat-topics">–</div><div class="card-lbl" data-i18n="card_topics">Топиков</div></div>
|
||||
<div class="card"><div class="card-val" id="stat-sent">–</div><div class="card-lbl" data-i18n="card_sent">Отправлено всего</div></div>
|
||||
<div class="card"><div class="card-val" id="stat-history">–</div><div class="card-lbl" data-i18n="card_history">В истории</div></div>
|
||||
</div>
|
||||
|
||||
<div class="grid-2">
|
||||
<div class="panel">
|
||||
<h2 data-i18n="status">Состояние</h2>
|
||||
<table class="kv">
|
||||
<tr><td data-i18n="engine">Движок</td><td id="dash-engine">–</td></tr>
|
||||
<tr><td data-i18n="last_sync">Последняя синхронизация</td><td id="dash-last">–</td></tr>
|
||||
<tr><td data-i18n="next_sync">Следующая</td><td id="dash-next">–</td></tr>
|
||||
<tr><td data-i18n="interval">Интервал</td><td id="dash-interval">–</td></tr>
|
||||
<tr><td data-i18n="error">Ошибка</td><td id="dash-error">–</td></tr>
|
||||
</table>
|
||||
|
||||
<h2 style="margin-top:1.5rem" data-i18n="test_notification">Тестовое уведомление</h2>
|
||||
<div class="row">
|
||||
<input id="test-topic" data-i18n-ph="ph_topic" placeholder="топик (напр. news)">
|
||||
<input id="test-msg" data-i18n-ph="ph_message" placeholder="сообщение">
|
||||
<button id="btn-test" class="btn" data-i18n="send">Отправить</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2 data-i18n="log">Журнал</h2>
|
||||
<button id="btn-clear-history" class="btn btn-sm btn-danger" data-i18n="clear_history">Очистить историю</button>
|
||||
</div>
|
||||
<div id="log" class="log"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FEEDS -->
|
||||
<section id="tab-feeds" class="tab-panel">
|
||||
<div class="panel-head">
|
||||
<h2 data-i18n="feeds">Фиды</h2>
|
||||
<div class="feed-toolbar">
|
||||
<button id="btn-import-opml" class="btn" data-i18n="import_opml">Импорт OPML</button>
|
||||
<button id="btn-export-opml" class="btn" data-i18n="export_opml">Экспорт OPML</button>
|
||||
<button id="btn-add-feed" class="btn btn-primary" data-i18n="add_feed">+ Добавить фид</button>
|
||||
<input id="opml-file" type="file" accept=".opml,.xml,text/x-opml,application/xml" class="hidden">
|
||||
</div>
|
||||
</div>
|
||||
<div id="feeds-list"></div>
|
||||
</section>
|
||||
|
||||
<!-- SETTINGS -->
|
||||
<section id="tab-settings" class="tab-panel">
|
||||
<div class="panel" style="max-width:680px">
|
||||
<h2 data-i18n="settings_global">Глобальные настройки</h2>
|
||||
<form id="settings-form">
|
||||
<label><span data-i18n="s_ntfy_url">ntfy сервер (URL)</span>
|
||||
<input name="ntfy_url" placeholder="https://ntfy.sh">
|
||||
</label>
|
||||
<label><span data-i18n="s_ntfy_token">ntfy токен (необязательно)</span>
|
||||
<input name="ntfy_token" type="password" placeholder="tk_...">
|
||||
</label>
|
||||
<div class="row">
|
||||
<label><span data-i18n="s_interval">Интервал синхронизации (сек)</span>
|
||||
<input name="sync_interval" type="number" min="30">
|
||||
</label>
|
||||
<label><span data-i18n="s_tz">Часовой пояс (IANA)</span>
|
||||
<input name="tz" placeholder="Europe/Moscow">
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label><span data-i18n="s_batch">Лимит новых записей за цикл</span>
|
||||
<input name="batch_limit" type="number" min="1">
|
||||
</label>
|
||||
<label><span data-i18n="s_maxdesc">Макс. длина описания</span>
|
||||
<input name="max_desc_length" type="number" min="50">
|
||||
</label>
|
||||
</div>
|
||||
<label><span data-i18n="s_ua">User-Agent</span>
|
||||
<input name="user_agent">
|
||||
</label>
|
||||
<label class="check">
|
||||
<input name="flood_protection" type="checkbox"> <span data-i18n="s_flood">Флуд-защита (задержки для низкого приоритета)</span>
|
||||
</label>
|
||||
<button class="btn btn-primary" type="submit" data-i18n="save">Сохранить</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<!-- Feed editor modal -->
|
||||
<div id="modal" class="modal hidden">
|
||||
<div class="modal-box">
|
||||
<div class="modal-head">
|
||||
<h2 id="modal-title" data-i18n="feed_edit">Фид</h2>
|
||||
<button id="modal-close" class="icon-btn">✕</button>
|
||||
</div>
|
||||
<form id="feed-form">
|
||||
<input type="hidden" name="id">
|
||||
<label><span data-i18n="f_name">Название</span>
|
||||
<input name="name" placeholder="Example News">
|
||||
</label>
|
||||
<label><span data-i18n="f_url">URL фида *</span>
|
||||
<input name="url" placeholder="https://example.com/rss" required>
|
||||
</label>
|
||||
<div class="row">
|
||||
<label><span data-i18n="f_topic">Топик ntfy *</span>
|
||||
<input name="topic" placeholder="news" required>
|
||||
</label>
|
||||
<label><span data-i18n="f_priority">Приоритет (1–5)</span>
|
||||
<input name="priority" type="number" min="1" max="5" value="3">
|
||||
</label>
|
||||
</div>
|
||||
<label><span data-i18n="f_icon">Иконка (URL)</span>
|
||||
<input name="icon" placeholder="https://example.com/icon.png">
|
||||
</label>
|
||||
<div class="row">
|
||||
<label><span data-i18n="f_quiet_hours">Тихие часы (напр. 22-7)</span>
|
||||
<input name="quiet_hours" placeholder="">
|
||||
</label>
|
||||
<label><span data-i18n="f_quiet_priority">Приоритет в тихие часы</span>
|
||||
<input name="quiet_priority" type="number" min="1" max="5" value="1">
|
||||
</label>
|
||||
</div>
|
||||
<label><span data-i18n="f_include">Include regex</span>
|
||||
<input name="include_regex" placeholder="">
|
||||
</label>
|
||||
<label><span data-i18n="f_exclude">Exclude regex</span>
|
||||
<input name="exclude_regex" placeholder="">
|
||||
</label>
|
||||
<label class="check">
|
||||
<input name="enabled" type="checkbox" checked> <span data-i18n="f_enabled">Включён</span>
|
||||
</label>
|
||||
<div class="modal-actions">
|
||||
<button type="button" id="btn-preview" class="btn" data-i18n="check_feed">Проверить фид</button>
|
||||
<div class="spacer"></div>
|
||||
<button type="submit" class="btn btn-primary" data-i18n="save">Сохранить</button>
|
||||
</div>
|
||||
<div id="preview-result" class="preview"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="toast" class="toast hidden"></div>
|
||||
<script src="/static/js/i18n.js"></script>
|
||||
<script src="/static/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user