feat: pages and faq

This commit is contained in:
Lowder
2025-11-22 03:47:18 +05:00
parent ff9a14f6ee
commit 29b421713a
7 changed files with 298 additions and 43 deletions
+14 -2
View File
@@ -16,7 +16,7 @@ use rocket::fs::FileServer;
use rocket::http::Status;
use rocket::{tokio, Request, State};
use rocket::response::content::RawJavaScript;
use rocket_dyn_templates::{context, Template};
use rocket_dyn_templates::{context, Metadata, Template};
use serde::Serialize;
use log::error;
use rocket::tokio::sync::{watch, RwLock};
@@ -47,6 +47,18 @@ fn index(info: &State<watch::Receiver<UpdateInfo>>) -> Template {
})
}
#[get("/kb/<page>")]
fn page(metadata: Metadata, page: &str) -> Option<Template> {
let page = format!("pages/{}", page);
if !metadata.contains_template(&page) {
return None;
}
Some(Template::render(page, context! {
global: GlobalContext::new(),
}))
}
#[get("/healthcheck")]
fn healthcheck(info: &State<watch::Receiver<UpdateInfo>>) -> (Status, String) {
if info.borrow().last_update.is_some() {
@@ -196,7 +208,7 @@ async fn rocket() -> _ {
.manage(rkn_list)
.manage(geo_ip)
.manage(rx)
.mount("/", routes![index, lucide, check, healthcheck])
.mount("/", routes![index, lucide, check, healthcheck, page])
.register("/", catchers![default])
.mount("/", FileServer::from(PathBuf::from("static")))
.attach(Template::fairing())
+50 -32
View File
@@ -68,8 +68,6 @@ body {
.gap-4 { gap: 1rem; }
.column { flex-direction: column; }
.hidden { display: none !important; }
h1 {
font-size: 1.5rem;
text-transform: uppercase;
@@ -135,12 +133,15 @@ h1.error-code {
text-decoration: none;
}
.footer, .footer a {
color: #525252;
}
.footer {
margin-top: 3rem;
padding-top: 1rem;
border-top: 1px solid var(--border-color);
text-align: center;
color: #525252;
}
.search-container {
@@ -190,9 +191,8 @@ h1.error-code {
}
.search-btn {
/* Убрано абсолютное позиционирование */
width: 100%; /* Полная ширина на мобильных */
height: 4rem; /* Высота совпадает с полем ввода */
width: 100%;
height: 4rem;
padding: 0 1.5rem;
background-color: var(--btn-bg);
color: var(--btn-text);
@@ -203,7 +203,7 @@ h1.error-code {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center; /* Центрируем текст и иконку */
justify-content: center;
gap: 0.5rem;
font-family: inherit;
transition: background 0.2s;
@@ -213,7 +213,6 @@ h1.error-code {
background-color: white;
}
/* Статистика под поиском */
.stats-grid {
display: grid;
grid-template-columns: 1fr;
@@ -236,18 +235,15 @@ h1.error-code {
gap: 0.5rem;
}
/* --- 6. Результаты (Blocked/Clean) --- */
.result-panel {
border: 1px solid var(--border-color);
padding: 1.5rem;
margin-top: 1rem;
/*background-color: rgba(69, 10, 10, 0.1);*/
}
/* Цветовые схемы для результатов */
.blocked-theme {
border-color: var(--red-border);
background-color: rgba(69, 10, 10, 0.1); /* Очень прозрачный красный */
background-color: rgba(69, 10, 10, 0.1);
}
.blocked-theme h2, .blocked-theme .status-icon, .blocked-theme .subheading { color: var(--red-color); }
.blocked-theme .reason-header { border-bottom: 1px solid var(--red-border); color: #f87171; }
@@ -269,7 +265,6 @@ h1.error-code {
color: #4ade80;
}
/* Общие элементы результатов */
.result-header {
display: flex;
gap: 1rem;
@@ -373,28 +368,51 @@ h1.error-code {
color: white;
}
/* --- 7. Demo Controls --- */
.demo-controls {
position: fixed;
bottom: 1rem;
right: 1rem;
display: flex;
gap: 0.5rem;
opacity: 0.3;
transition: opacity 0.2s;
.page-container ul {
list-style-position: inside;
}
.demo-controls:hover { opacity: 1; }
.demo-btn {
padding: 0.25rem 0.5rem;
font-size: 0.625rem;
text-transform: uppercase;
cursor: pointer;
border: 1px solid rgba(255,255,255,0.1);
font-family: inherit;
.page-container h1 {
font-size: 48px;
margin: 1rem 0;
}
.demo-btn.block { background-color: #450a0a; color: #fee2e2; border-color: #7f1d1d; }
.demo-btn.clean { background-color: #052e16; color: #dcfce7; border-color: #14532d; }
.page-container h2 {
font-size: 32px;
margin: 2.5rem 0 1rem;
}
.page-container h2 a {
text-decoration: none;
}
.page-container a {
color: var(--text-bright);
}
.page-container h2 a:hover {
text-decoration: underline;
}
.page-container p {
text-align: justify;
margin: 1rem 0;
}
.page-container img.fullwidth {
width: 100%;
}
.page-container img {
margin: auto;
display: block;
}
.page-container i.caption {
display: block;
text-align: center;
}
@media (min-width: 640px) {
body { padding: 2rem; }
+16 -9
View File
@@ -4,20 +4,24 @@
{% block head %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cheburcheck</title>
<link rel="stylesheet" href="/main.css"/>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<meta name="description" content="Проверка доменов и IP-адресов на наличие в реестре блокировок Роскомнадзора и заблокированных CDN.">
<meta name="keywords" content="проверка домена, заблокирован ли сайт, Роскомнадзор, чебурнет, cdn, блокировки">
<meta name="author" content="Cheburcheck">
<meta property="og:title" content="Cheburcheck">
<meta property="og:description" content="Проверка доменов и IP-адресов на наличие в реестре блокировок Роскомнадзора и заблокированных CDN.">
<meta property="og:url" content="https://cheburcheck.ru">
<meta property="og:type" content="website">
<meta property="og:image" content="https://cheburcheck.ru/og-cover.png">
{% block metadata %}
<title>Cheburcheck</title>
<meta name="description" content="Проверка доменов и IP-адресов на наличие в реестре блокировок Роскомнадзора и заблокированных CDN.">
<meta name="keywords" content="проверка домена, заблокирован ли сайт, Роскомнадзор, чебурнет, cdn, блокировки">
<meta property="og:title" content="Cheburcheck">
<meta property="og:description" content="Проверка доменов и IP-адресов на наличие в реестре блокировок Роскомнадзора и заблокированных CDN.">
<meta property="og:url" content="https://cheburcheck.ru">
<meta property="og:image" content="https://cheburcheck.ru/og-cover.png">
{% endblock metadata %}
<meta property="og:site_name" content="Cheburcheck">
<meta property="og:type" content="website">
<meta name="author" content="Cheburcheck">
{% endblock head %}
</head>
<body>
@@ -30,6 +34,7 @@
<span class="text-lg font-bold uppercase">Cheburcheck</span>
</a>
<div class="flex gap-4 text-xs text-muted">
<a href="/kb/faq" class="text-muted">FAQ</a>
<a class="version-link text-muted" href="https://github.com/LowderPlay/cheburcheck">
<span>v{{ global.version }}</span>
<svg width="20" height="20" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
@@ -46,6 +51,8 @@
<footer class="footer">
{% block footer %}
<p class="text-xs uppercase">
<a href="mailto:support@cheburcheck.ru">support@cheburcheck.ru</a>
-
Сделано в России
<i data-lucide="copyright" width="10" height="10"></i> {{ now() | date(format="%Y") }}
</p>
+18
View File
@@ -0,0 +1,18 @@
{% extends 'base' %}
{% import 'typography' as typography %}
{% macro metadata(title, description, image="https://cheburcheck.ru/og-cover.png", keywords, url="/") %}
<title>{{ title }} - Cheburcheck</title>
<meta name="description" content="{{ description }}">
<meta name="keywords" content="проверка домена, заблокирован ли сайт, Роскомнадзор, чебурнет, cdn, блокировки, {{ keywords }}">
<meta property="og:title" content="{{ title }}">
<meta property="og:description" content="{{ description }}">
<meta property="og:url" content="https://cheburcheck.ru{{ url }}">
<meta property="og:image" content="{{ image }}">
{% endmacro metadata %}
{% block content %}
<div class="page-container">
{% block page_text %}{% endblock %}
</div>
{% endblock content %}
+84
View File
@@ -0,0 +1,84 @@
{% extends 'page' %}
{% import 'page' as page %}
{% block metadata %}
{{ page::metadata(title="FAQ", description="Ответы на частые вопросы", keywords="faq", url="/kb/faq") }}
{% endblock metadata %}
{% block page_text %}
<h1>Ответы на частые вопросы</h1>
<p>
На этой странице собраны ответы на часто задаваемые вопросы.
Если вас интересует что-то ещё &mdash; пишите нам на почту <a href="mailto:support@cheburcheck.ru">support@cheburcheck.ru</a>.
</p>
{{ typography::heading(title="Что это за сайт?") }}
<p>
Этот сайт &mdash; инструмент, который позволяет проверить, находится ли сайт, домен,
IP-адрес в <a href="#{{ "Откуда вы берете эти списки?" | slugify }}">списках</a>, блокируемых Роскомнадзором на территории России.
</p>
{{ typography::heading(title="Откуда вы берете эти списки?") }}
<p>
Для поиска сайтов мы используем списки IP-подсетей популярных CDN-провайдеров,
которые могут блокироваться Роскомнадзором, а также домены из самого реестра Роскомнадзора.
</p>
<p>
Подсети, которые мы используем, публикуют сами провайдеры, либо собираются из принадлежащих им автономных сетей.
Мы используем <a href="https://github.com/123jjck/cdn-ip-ranges">этот репозиторий</a>, в котором автоматически
агрегируются эти подсети.
</p>
<p>
Данные из Реестра Роскомнадзора подгружаются из сервисов <a href="https://antifilter.download/">antifilter.download</a>
и <a href="https://antifilter.network/">antifilter.network</a>.
</p>
{{ typography::heading(title='Мне написало, что сайт "Заблокирован", но у меня все работает!') }}
<p>
Мы не можем с точностью утверждать, заблокирован сайт или нет.
Блокировки Роскомнадзора, зачастую, непредсказуемые, непубличные и незаконные.
Например, блокировка CDN-сервисов, таких, как
<a href="https://blog.cloudflare.com/russian-internet-users-are-unable-to-access-the-open-internet/">Cloudflare</a>,
никак не комментировалась официально и не публиковались в Реестре. Аналогичная ситуация с
<a href="https://ria.ru/20241219/putin-1990168675.html">YouTube</a>, информация о
блокировке которого, не добавлена в Реестр &mdash; для таких случаев мы создали
<a href="https://github.com/LowderPlay/cheburcheck/blob/master/dist-domains.txt">свой список</a> подобных сайтов.
Однако, список не исчерпывающий, поэтому
<a href="https://github.com/LowderPlay/cheburcheck/pulls">принимаются правки</a>.
</p>
<p>
Сайты помечаются как "заблокированные", в случае, если они были найдены хотя бы в одном списке.
</p>
{{ typography::heading(title='Как часто обновляются списки?') }}
<p>
Мы обновляем списки из источников раз в 6 часов.
</p>
<p>
Сами источники обновляют их с разной периодичностью:
</p>
<ul>
<li><a href="https://github.com/123jjck/cdn-ip-ranges">CDN</a> &mdash; раз в 12 часов.</li>
<li><a href="https://antifilter.download/">Домены из Реестра РКН</a> &mdash; раз в полчаса.</li>
<li><a href="https://antifilter.network/">Подсети из Реестра РКН</a> &mdash; раз в час.</li>
</ul>
{{ typography::heading(title='Как я могу помочь в развитии сайта?') }}
<p>
Самый простой способ помочь &mdash; рассказать о сайте знакомым.
</p>
<p>
Если у вас есть навыки разработки, то мы будем рады принять ваши pull-requests
на <a href="https://github.com/LowderPlay/cheburcheck">GitHub</a>.
</p>
<p>
Если вы хотите помочь финансово:
</p>
<ul>
<li>TON: <code>UQAACsiwpGryjP-kqp4TJPAWpXytuB6M_puuO0Cg5zNvaSJW</code></li>
</ul>
<p>
Большое спасибо! ❤️
</p>
{% endblock page_text %}
+111
View File
@@ -0,0 +1,111 @@
{% extends 'page' %}
{% import 'page' as page %}
{% block metadata %}
{{ page::metadata(title="Test", description="Проверка", keywords="test", url="/kb/test") }}
{% endblock metadata %}
{% block page_text %}
<img class="fullwidth" src="https://placehold.co/600x400">
<h1>Hello, world!</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
{{ typography::heading(title="Test1") }}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
<img src="https://placehold.co/600x400">
<i class="caption">Centered image</i>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
{{ typography::heading(title="Test2") }}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
{{ typography::heading(title="Test3") }}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
{{ typography::heading(title="Test4") }}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean at scelerisque purus. Integer eu justo vel mi consectetur sagittis.
Proin aliquam, nulla sit amet ornare interdum, leo orci posuere nulla, convallis consequat nibh ex id felis.
Nam dapibus enim mauris, bibendum rutrum orci blandit at.
Curabitur sed dui sit amet felis consequat cursus quis at magna.
Suspendisse at neque lobortis, pulvinar quam at, posuere lorem.
Etiam sed elit vehicula leo tincidunt rhoncus et ut metus.
Quisque egestas diam non sem pellentesque bibendum.
Fusce posuere pretium nisl sit amet pharetra.
Maecenas urna odio, dignissim non efficitur vel, varius eu nulla.
Sed convallis id lorem sed suscipit. In hac habitasse platea dictumst.
Nulla fermentum arcu urna, vitae gravida leo accumsan ut. Phasellus accumsan hendrerit erat,
nec imperdiet odio ullamcorper sed.
</p>
{% endblock page_text %}
+5
View File
@@ -0,0 +1,5 @@
{% macro heading(title) %}
<h2 id="{{ title | slugify }}">
<a href="#{{ title | slugify }}">{{ title }}</a>
</h2>
{% endmacro title %}