import datetime
import logging
+import iso3166
import math
import os.path
import random
return self._get_mirror("SELECT * FROM mirrors \
WHERE hostname = %s", hostname)
+ def get_by_countries(self):
+ mirrors = {}
+
+ for m in self:
+ try:
+ mirrors[m.country].append(m)
+ except KeyError:
+ mirrors[m.country] = [m]
+
+ return mirrors
+
class Mirror(Object):
def init(self, id, data=None):
if self.location:
return self.location.longitude
+ @lazy_property
+ def country(self):
+ return iso3166.countries.get(self.country_code)
+
@property
def country_code(self):
return self.data.country_code
{% block title %}{{ _("Mirrors") }}{% end block %}
{% block content %}
+ {% set total = sum((len(m) for c, m in mirrors.items())) %}
+
+ <h4 class="my-5 text-muted text-center">
+ {{ _("We are currently running %s mirror servers") % total }}
+ </h4>
+
+ {% set countries = sorted(mirrors, key=lambda c: c.name) %}
+
<div class="row justify-content-center">
<div class="col-12 col-md-6">
- <div class="list-group">
- {% for m in mirrors %}
- <a href="/mirrors/{{ m.hostname }}" class="list-group-item list-group-item-action
- list-group-item-{% if m.state == "UP" %}success{% elif m.state == "DOWN" %}danger{% else %}warning{% end %}
- flex-column align-items-start">
- <h5 class="mb-1">{{ m.hostname }}</h5>
-
- <p class="mb-0 text-truncate text-muted">
- <span class="flag-icon flag-icon-{{ m.country_code.lower() }} small mr-1"></span> {{ m.country_name }}
- {% if m.owner %}‐ {{ m.owner }}{% end %}
- </p>
- </a>
- {% end %}
- </div>
+ {% for country in countries %}
+ <a name="{{ country.alpha2 }}"></a>
+ <div class="my-4 d-flex justify-content-between ">
+ <div>
+ <h4 class="mb-0">{{ country.name }}</h4>
+ <span class="small text-muted">
+ {{ _("One Mirror", "%(num)s Mirrors", len(mirrors[country])) % { "num" : len(mirrors[country]) } }}
+ </span>
+ </div>
+
+ <h4 class="flag-icon flag-icon-{{ country.alpha2.lower() }}"></h4>
+ </div>
+
+ <div class="list-group">
+ {% for m in mirrors[country] %}
+ <a href="/mirrors/{{ m.hostname }}" class="list-group-item list-group-item-action
+ list-group-item-{% if m.state == "UP" %}success{% elif m.state == "DOWN" %}danger{% else %}warning{% end %}
+ flex-column align-items-start">
+ <h5 class="mb-1">{{ m.hostname }}</h5>
+
+ {% if m.owner %}
+ <p class="mb-0 text-truncate text-muted">{{ m.owner }}</p>
+ {% end %}
+ </a>
+ {% end %}
+ </div>
+ {% end %}
</div>
</div>
{% end block %}
class IndexHandler(base.BaseHandler):
def get(self):
- self.render("mirrors/index.html", mirrors=self.backend.mirrors)
+ mirrors = self.backend.mirrors.get_by_countries()
+ if not mirrors:
+ raise tornado.web.HTTPError(404)
+
+ self.render("mirrors/index.html", mirrors=mirrors)
class MirrorHandler(base.BaseHandler):