diff --git a/app.py b/app.py
index 69df2ab..e924377 100644
--- a/app.py
+++ b/app.py
@@ -1,30 +1,23 @@
import threading
import time
-import json
+import re
from os import path, listdir
-from datetime import date, datetime, timezone
+from datetime import date
from configparser import ConfigParser
from urllib.request import urlopen
import sass
-from flask import (
- Flask,
- redirect,
- render_template,
- request,
- url_for,
- g,
- Response
-)
+from flask import Flask, redirect, render_template, request, url_for, g, Response
# ---------- ENV VARS --------------------------------------------------------
-GIT_URL = "https://git.kolibrios.org/api/v1/repos/KolibriOS/kolibrios/branches/main"
-GIT_FETCH_DELAY_SEC = 300 # 5 minutes
+STATUS_URL = "https://builds.kolibrios.org/status.html"
+STATUS_FETCH_DELAY_SEC = 300 # 5 minutes
+
# ---------- APP CONFIG ------------------------------------------------------
@@ -41,18 +34,64 @@ if app.debug:
autobuild_date = "DD.MM.YYYY"
+autobuild_vers = "0.0.0.0+0000-0000000"
def _refresh_build_date_once():
- global autobuild_date
+ global autobuild_date, autobuild_vers
try:
- with urlopen(GIT_URL, timeout=10) as r:
- b = json.load(r)
- c = b.get("commit", {}) or {}
- ts = c.get("timestamp")
- if ts:
- dt = datetime.fromisoformat(ts.replace("Z", "+00:00")).astimezone(timezone.utc)
- autobuild_date = dt.strftime("%d.%m.%Y")
+ from urllib.request import Request, urlopen
+ import re
+
+ req = Request(
+ STATUS_URL,
+ headers={
+ "User-Agent": "Mozilla/5.0",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+ },
+ )
+ with urlopen(req, timeout=10) as r:
+ html = r.read().decode(
+ r.headers.get_content_charset() or "utf-8", "replace"
+ )
+
+ rows = re.findall(r"(
]*>.*?
)", html, flags=re.I | re.S)
+ if not rows:
+ return
+
+ last_commit_ver = None
+
+ for row in rows:
+ cls = re.search(r'class\s*=\s*"([^"]*)"', row, flags=re.I)
+ classes = cls.group(1).lower() if cls else ""
+
+ text = re.sub(r"<[^>]+>", " ", row)
+
+ if "commit" in classes:
+ mver = re.search(
+ r"\b(\d+\.\d+\.\d+\.\d+\+\d{3,8}-[0-9a-fA-F]{7,40})\b", row
+ )
+ if mver:
+ last_commit_ver = mver.group(1)
+
+ elif "success" in classes:
+ mts = re.search(
+ r"\b(\d{4})\.(\d{2})\.(\d{2})\s+\d{2}:\d{2}:\d{2}\b", text
+ )
+ if not mts:
+ mds = re.search(r"\b(\d{2})\.(\d{2})\.(\d{4})\b", text)
+ if mds:
+ autobuild_date = f"{mds.group(1)}.{mds.group(2)}.{mds.group(3)}"
+ else:
+ return
+ else:
+ y, mo, d = mts.groups()
+ autobuild_date = f"{d}.{mo}.{y}"
+
+ if last_commit_ver:
+ autobuild_vers = last_commit_ver
+ return
+
except Exception:
pass
@@ -60,7 +99,7 @@ def _refresh_build_date_once():
def _updater_loop():
while True:
_refresh_build_date_once()
- time.sleep(GIT_FETCH_DELAY_SEC)
+ time.sleep(STATUS_FETCH_DELAY_SEC)
_started = False
@@ -69,6 +108,7 @@ _refresh_build_date_once()
# Flask 3.x fix: start updater lazily on first request (since before_first_request is removed)
_updater_lock = threading.Lock()
+
@app.before_request
def _ensure_updater_started():
global _started
@@ -79,9 +119,14 @@ def _ensure_updater_started():
threading.Thread(target=_updater_loop, daemon=True).start()
+@app.context_processor
+def _inject_autobuild_vers():
+ return {'autobuild_vers': autobuild_vers}
+
+
@app.context_processor
def _inject_autobuild_date():
- return {"autobuild_date": autobuild_date}
+ return {'autobuild_date': autobuild_date}
# ---------- LOCALES FUNCTIONS -----------------------------------------------
@@ -138,7 +183,7 @@ def render_localized_template(lang, template_name):
@app.before_request
def before_request():
if args := request.view_args:
- g.locale = args.get('lang', 'en')
+ g.locale = args.get("lang", "en")
g.translations = translations.get(g.locale, get_best_lang())
g.locales_name = locales_name
diff --git a/locales/de.ini b/locales/de.ini
index abf854a..aafe58b 100644
--- a/locales/de.ini
+++ b/locales/de.ini
@@ -49,6 +49,9 @@ p_subscription = Wir hoffen, es gefällt Ihnen!
[downloads]
header = Herunterladen
+version = Version:
+date = Build-Datum:
+
img-descr = Disketten-Image
iso-descr = LiveCD-Abbild
distr-descr = Universal Flash/Multi-Boot-Abbild
@@ -75,6 +78,10 @@ download_description = Auf dieser Seite können Sie die nächtlichen
vertrieben, und der Quellcode ist auf unserem {git} verfügbar.
git-server = Git-Server
+download_warn = Gelegentlich stufen einige Antivirenprogramme das {kolibrios}-Image fälschlicherweise als Bedrohung ein.
+ Das ist ein Fehlalarm.
+ {kolibrios} ist vollständig quelloffen, und Sie können es jederzeit selbst erstellen, um sicherzugehen, dass es vollständig sicher ist.
+
[screenshots]
header = Bildschirmfotos
diff --git a/locales/en.ini b/locales/en.ini
index d133bc0..2631137 100644
--- a/locales/en.ini
+++ b/locales/en.ini
@@ -47,6 +47,9 @@ p_subscription = We hope you will enjoy it!
[downloads]
header = Downloads
+version = Version:
+date = Build date:
+
img-descr = Floppy disk image
iso-descr = LiveCD image
distr-descr = Universal Flash/Multi-boot image
@@ -71,6 +74,10 @@ download_description = On this page you can download the nightly builds
available on our {git}.
git-server = Git server
+download_warn = Occasionally, some antivirus software may incorrectly flag the {kolibrios} image as a threat.
+ This is a false positive.
+ {kolibrios} is fully open source, and you can always build it yourself to be sure that it is completely safe.
+
[screenshots]
header = Screenshots
diff --git a/locales/es.ini b/locales/es.ini
index fee15c4..443432b 100644
--- a/locales/es.ini
+++ b/locales/es.ini
@@ -49,6 +49,9 @@ p_subscription = ¡Esperamos que lo disfrutes!
[downloads]
header = Descargas
+version = Versión:
+date = Fecha de compilación:
+
img-descr = Imagen de disquete
iso-descr = Imagen LiveCD
distr-descr = Imagen Flash Universal/Multi-boot
@@ -73,6 +76,10 @@ download_description = En esta página puedes descargar la distribución de
licencia {gpl} y su código fuente está disponible en nuestro {git}.
git-server = servidor Git
+download_warn = Ocasionalmente, algunos programas antivirus pueden marcar incorrectamente la imagen de {kolibrios} como una amenaza.
+ Esto es un falso positivo.
+ {kolibrios} es completamente de código abierto y siempre puedes compilarlo tú mismo para asegurarte de que es totalmente seguro.
+
[screenshots]
header = Pantallas
diff --git a/locales/fr.ini b/locales/fr.ini
index ecebc0e..349d29a 100644
--- a/locales/fr.ini
+++ b/locales/fr.ini
@@ -49,6 +49,9 @@ p_subscription = Nous espérons que vous l`apprécierez !
[downloads]
header = Téléchargements
+version = Version :
+date = Date de compilation :
+
img-descr = Image de la disquette
iso-descr = Image du LiveCD
distr-descr = Image Universal Flash/Multi-boot
@@ -73,6 +76,10 @@ download_description = Sur cette page, vous pouvez télécharger la distribution
licence {gpl} et son code source est disponible sur notre {git}.
git-server = serveur Git
+download_warn = Il arrive que certains antivirus signalent à tort l’image {kolibrios} comme une menace.
+ Il s’agit d’un faux positif.
+ {kolibrios} est entièrement open source et vous pouvez toujours le compiler vous-même pour vous assurer qu’il est totalement sûr.
+
[screenshots]
header = Captures d`écran
diff --git a/locales/it.ini b/locales/it.ini
index 987fc06..e150505 100644
--- a/locales/it.ini
+++ b/locales/it.ini
@@ -48,6 +48,9 @@ p_subscription = Ci auguriamo che vi piaccia!
[downloads]
header = Scaricamento
+version = Versione:
+date = Data di compilazione:
+
img-descr = Immagine su dischetto
iso-descr = Immagine LiveCD
distr-descr = Immagine universale Flash/MultiBoot
@@ -72,6 +75,10 @@ download_description = In questa pagina puoi scaricare la distribuzione delle
suo codice sorgente è disponibile sul nostro {git}.
git-server = server Git
+download_warn = Occasionalmente, alcuni software antivirus potrebbero segnalare erroneamente l’immagine di {kolibrios} come una minaccia.
+ Si tratta di un falso positivo.
+ {kolibrios} è completamente open source e puoi sempre compilarlo tu stesso per essere certo che è del tutto sicuro.
+
[screenshots]
header = Captures d`écran
diff --git a/locales/nl.ini b/locales/nl.ini
index df26340..e953fc9 100644
--- a/locales/nl.ini
+++ b/locales/nl.ini
@@ -49,6 +49,9 @@ p_subscription = We hopen dat je ervan zult genieten!
[downloads]
header = Downloads
+version = Versie:
+date = Builddatum:
+
img-descr = Afbeelding op diskette
iso-descr = LiveCD-afbeelding
distr-descr = Universele Flash/Multi-boot image
@@ -73,6 +76,10 @@ download_description = Op deze pagina kunt u de nightly builds-distributie
broncode is beschikbaar op onze {git}.
git-server = Git-server
+download_warn = Af en toe kunnen sommige antivirusprogramma’s het {kolibrios}-image ten onrechte als een bedreiging aanmerken.
+ Dit is een vals-positief.
+ {kolibrios} is volledig open-source en je kunt het altijd zelf bouwen om er zeker van te zijn dat het volledig veilig is.
+
[screenshots]
header = Schermafbeeldingen
diff --git a/locales/ru.ini b/locales/ru.ini
index ecf86ee..c22f8b6 100644
--- a/locales/ru.ini
+++ b/locales/ru.ini
@@ -24,7 +24,7 @@ p1 = {kolibrios} — это крошечная, но невероятно мощ
мегабайт места на диске, процессора i586 и 12 МБ оперативной памяти. При
этом она содержит богатый набор приложений, таких как текстовый редактор,
просмотрщик изображений, графический редактор, веб-браузер и более 30
- захватывающих игр.Имеется полная поддержка файловых систем FAT12/16/32,
+ захватывающих игр. Имеется полная поддержка файловых систем FAT12/16/32,
только на чтение доступны NTFS, exFAT, ISO9660 и Ext2/3/4, а также
присутсвтвует обширный набор {drivers} для популярных звуковых, сетевых и
графических карт.
@@ -49,6 +49,9 @@ p_subscription = Надеемся, вам понравится!
[downloads]
header = Скачать
+version = Версия:
+date = Дата сборки:
+
img-descr = Образ дискеты
iso-descr = Образ LiveCD
distr-descr = Универсальный образ Flash/Multi-boot
@@ -73,6 +76,10 @@ download_description = На этой странице вы можете скач
исходный код доступен на нашем {git}.
git-server = Git-сервере
+download_warn = Иногда антивирусы могут по ошибке помечать образ {kolibrios} как угрозу.
+ Это ложное срабатывание.
+ {kolibrios} имеет полностью открытый исходный код, и вы всегда можете собрать её самостоятельно, чтобы убедиться, что она абсолютно безопасна.
+
[screenshots]
header = Скриншоты
diff --git a/static/img/icons/i_info.png b/static/img/icons/i_info.png
new file mode 100644
index 0000000..e18f150
Binary files /dev/null and b/static/img/icons/i_info.png differ
diff --git a/static/img/icons/i_kolibrios.png b/static/img/icons/i_kolibrios.png
new file mode 100644
index 0000000..11d76ed
Binary files /dev/null and b/static/img/icons/i_kolibrios.png differ
diff --git a/static/img/icons/i_warn.png b/static/img/icons/i_warn.png
new file mode 100644
index 0000000..4ae4cfe
Binary files /dev/null and b/static/img/icons/i_warn.png differ
diff --git a/static/style.scss b/static/style.scss
index 8ab257f..7d041af 100644
--- a/static/style.scss
+++ b/static/style.scss
@@ -223,6 +223,13 @@ p {
&-subscription {
text-align: center;
}
+
+ &-warn {
+ img {
+ margin-bottom: -2px;
+ margin-right: 0.25em;
+ }
+ }
}
/* DOWNLOADS */
@@ -247,13 +254,21 @@ tr {
vertical-align: middle;
}
-.tr-margin {
- &-bot > td {
- padding-bottom: 1em;
+.tr {
+ &-header {
+ b {
+ display: inline;
+ }
}
- &-top > td {
- padding-top: 1em;
+ &-margin {
+ &-bot > td {
+ padding-bottom: 1em;
+ }
+
+ &-top > td {
+ padding-top: 1em;
+ }
}
}
@@ -284,18 +299,17 @@ td {
}
}
- &-date {
- text-align: right;
- padding-right: 2em;
- }
-
&-languages {
text-align: right;
+ padding-left: 2em;
+
+ a {
+ display: inline-block;
+ white-space: nowrap;
+ }
a + a {
- display: inline;
margin-left: 1em;
- margin-top: 0em;
}
}
}
@@ -307,16 +321,10 @@ hr {
.help-button {
cursor: pointer;
display: inline-block;
- background: #FF9800;
- border-radius: 4px;
- box-shadow: inset 0 1px rgba(254,181,94,0.9), inset 0 -2px rgba(0,0,0,0.04);
- color: #FFFFFF;
- padding: 0.5em 1em;
- text-align: center;
- transition: 0.5s;
+ color: #609A21;
- &:hover {
- background: #F6920B;
+ img {
+ padding-bottom: 1px;
}
}
@@ -444,22 +452,28 @@ iframe {
margin: 0 0.5em;
}
+ .tr {
+ &-header {
+ b {
+ display: block;
+ }
+ }
+ }
+
.td {
&-description {
width: auto;
}
- &-date {
- display: none;
- padding-right: 1em;
- padding-left: 1em;
- }
+ &-languages a {
+ display: block;
+ width: max-content;
+ margin-left: auto;
+ }
&-languages a + a {
- display: inline-block;
- white-space: nowrap;
margin-top: 0.5em;
- margin-left: 0em;
+ margin-left: auto;
}
}
diff --git a/templates/download.html b/templates/download.html
index 08cd1a0..a82a921 100644
--- a/templates/download.html
+++ b/templates/download.html
@@ -11,7 +11,28 @@
{{ _('downloads:header') }}
+
+
+
|
+
+
+
+
+
+
|
+
+
{% for ext, alt in (
('img', 'floppy'),
('iso', 'cd'),
@@ -28,9 +49,6 @@
BETA
{% endif %}
-
- {{ autobuild_date }}
- |
{% for l, lang in (
('en_US', 'English'),
@@ -38,27 +56,42 @@
('es_ES', 'Español')
) %}
{{ lang }}
+ title="ver. $autobuild_cmtid_{{ l }}, $autobuild_size_{{ l }}_{{ ext }}"
+ class="button">
+ {{ lang }}
+ {% if l == 'en_US' %}
+
+ {% elif l == 'ru_RU' %}
+
+ {% elif l == 'es_ES' %}
+
+ {% endif %}
{% endfor %}
|
{% endfor %}
+
-
-
- |
+
|
+
+
+
@@ -66,12 +99,17 @@
{{ _(
'downloads:download_description',
- kolibrios="{0}"
- .format(_('title:index')),
+ kolibrios="{0}".format(_('title:index')),
zip="7zip",
gpl="GPLv2",
- git="{0}"
- .format(_('downloads:git-server'))
+ git="{0}".format(_('downloads:git-server'))
+ ) | safe }}
+
+
+
+
{{ _(
+ 'downloads:download_warn',
+ kolibrios="{0}".format(_('title:index'))
) | safe }}
@@ -96,4 +134,4 @@
{% include 'tmpl/_footer.htm' %}