Initial commit

This commit is contained in:
2026-06-03 17:33:19 +03:30
commit 9608342428
48 changed files with 3562 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
{% extends "base.html" %}
{% block title %}{% if mirror %}ویرایش{% else %}ایجاد{% endif %} میرور{% endblock %}
{% block content %}
<h2>{% if mirror %}ویرایش میرور{% else %}میرور جدید{% endif %}</h2>
<form method="post" class="card p-4 mt-3">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">دسته</label>
<select name="category" class="form-select" required id="category">
{% for cat in categories %}
<option value="{{ cat }}" {% if mirror and mirror.category == cat %}selected{% endif %}>{{ category_labels[cat] }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="form-label">نام</label>
<input type="text" name="name" class="form-control" required value="{{ mirror.name if mirror else '' }}">
</div>
<div class="col-md-6">
<label class="form-label">URL</label>
<input type="text" name="url" class="form-control" value="{{ mirror.url if mirror and mirror.url else '' }}" placeholder="https://...">
<div class="form-text">برای APT، Docker، GitHub، pip، npm</div>
</div>
<div class="col-md-6">
<label class="form-label">IPها (DNS)</label>
<input type="text" name="ips" class="form-control" value="{{ mirror.ips if mirror and mirror.ips else '' }}" placeholder="1.2.3.4,5.6.7.8">
</div>
<div class="col-md-6" id="github-prefix-field">
<label class="form-label">GitHub insteadOf prefix</label>
<input type="text" name="instead_prefix" class="form-control" value="{{ mirror.get_meta().get('instead_prefix', '') if mirror else '' }}">
</div>
<div class="col-md-3">
<label class="form-label">اولویت (کمتر = بالاتر)</label>
<input type="number" name="priority" class="form-control" value="{{ mirror.priority if mirror else 100 }}">
</div>
<div class="col-md-3 d-flex align-items-end">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="enabled" id="enabled" {% if not mirror or mirror.enabled %}checked{% endif %}>
<label class="form-check-label" for="enabled">فعال</label>
</div>
</div>
<div class="col-12">
<label class="form-label">یادداشت</label>
<textarea name="notes" class="form-control" rows="2">{{ mirror.notes if mirror and mirror.notes else '' }}</textarea>
</div>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary">ذخیره</button>
<a href="{{ url_for('mirrors.list_mirrors') }}" class="btn btn-secondary">انصراف</a>
</div>
</form>
{% endblock %}
+64
View File
@@ -0,0 +1,64 @@
{% extends "base.html" %}
{% block title %}میرورها{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>مدیریت میرورها</h2>
<div>
<a href="{{ url_for('mirrors.create') }}" class="btn btn-primary">+ میرور جدید</a>
<a href="{{ url_for('mirrors.results') }}" class="btn btn-outline-secondary">نتایج تست</a>
</div>
</div>
<div class="btn-group mb-3 flex-wrap" role="group">
<a href="{{ url_for('mirrors.list_mirrors') }}" class="btn btn-sm {% if not current_category %}btn-dark{% else %}btn-outline-dark{% endif %}">همه</a>
{% for cat in categories %}
<a href="{{ url_for('mirrors.list_mirrors', category=cat) }}" class="btn btn-sm {% if current_category == cat %}btn-dark{% else %}btn-outline-dark{% endif %}">
{{ category_labels[cat] }}
</a>
{% endfor %}
</div>
{% if current_category and guides.get(current_category) %}
<div class="alert alert-info d-flex justify-content-between">
<span>{{ guides[current_category].summary }}</span>
<a href="{{ url_for('main.guide', section=current_category) }}" class="alert-link">راهنمای {{ guides[current_category].title }}</a>
</div>
{% endif %}
<form method="post" action="{{ url_for('mirrors.test_all') }}" class="mb-3">
{% if current_category %}<input type="hidden" name="category" value="{{ current_category }}">{% endif %}
<button type="submit" class="btn btn-sm btn-info">تست همه{% if current_category %} {{ category_labels[current_category] }}{% endif %}</button>
</form>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th>دسته</th><th>نام</th><th>URL / IP</th><th>اولویت</th><th>فعال</th><th>عملیات</th>
</tr>
</thead>
<tbody>
{% for m in mirrors %}
<tr>
<td><span class="badge bg-secondary">{{ category_labels.get(m.category, m.category) }}</span></td>
<td>{{ m.name }}</td>
<td><code class="small">{{ m.url or m.ips or '-' }}</code></td>
<td>{{ m.priority }}</td>
<td>{% if m.enabled %}<span class="text-success">بله</span>{% else %}<span class="text-muted">خیر</span>{% endif %}</td>
<td>
<form method="post" action="{{ url_for('mirrors.test_one', mirror_id=m.id) }}" class="d-inline">
<button type="submit" class="btn btn-sm btn-outline-info">تست</button>
</form>
<a href="{{ url_for('mirrors.edit', mirror_id=m.id) }}" class="btn btn-sm btn-outline-primary">ویرایش</a>
<form method="post" action="{{ url_for('mirrors.delete', mirror_id=m.id) }}" class="d-inline" onsubmit="return confirm('حذف شود؟')">
<button type="submit" class="btn btn-sm btn-outline-danger">حذف</button>
</form>
</td>
</tr>
{% else %}
<tr><td colspan="6" class="text-center text-muted">میروری یافت نشد</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
+32
View File
@@ -0,0 +1,32 @@
{% extends "base.html" %}
{% block title %}نتایج تست{% endblock %}
{% block content %}
<h2>نتایج تست میرورها</h2>
<div class="btn-group mb-3">
<a href="{{ url_for('mirrors.results') }}" class="btn btn-sm btn-outline-dark">همه</a>
{% for cat in categories %}
<a href="{{ url_for('mirrors.results', category=cat) }}" class="btn btn-sm btn-outline-dark">{{ category_labels[cat] }}</a>
{% endfor %}
</div>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead><tr><th>میرور</th><th>دسته</th><th>تست</th><th>موفق</th><th>ms</th><th>خطا</th><th>زمان</th></tr></thead>
<tbody>
{% for r in results %}
<tr>
<td>{{ r.mirror.name }}</td>
<td>{{ category_labels.get(r.mirror.category, r.mirror.category) }}</td>
<td>{{ r.test_type }}</td>
<td>{% if r.success %}✓{% else %}✗{% endif %}</td>
<td>{{ '%.0f'|format(r.latency_ms) if r.latency_ms else '-' }}</td>
<td class="small text-danger">{{ r.error or '' }}</td>
<td>{{ r.tested_at.strftime('%m-%d %H:%M') }}</td>
</tr>
{% else %}
<tr><td colspan="7" class="text-center">نتیجه‌ای نیست — تست را اجرا کنید</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<a href="{{ url_for('mirrors.list_mirrors') }}" class="btn btn-secondary">بازگشت</a>
{% endblock %}