1 Commits

Author SHA1 Message Date
a715bcca89 feat(weather): new weather icons 2026-06-14 18:23:11 +03:00
17 changed files with 56 additions and 101 deletions

View File

@@ -2,14 +2,12 @@ FROM python:3.12 AS builder
ENV POETRY_HOME="/opt/poetry" ENV POETRY_HOME="/opt/poetry"
ENV PATH="$POETRY_HOME/bin:$PATH" ENV PATH="$POETRY_HOME/bin:$PATH"
RUN apt update && \ RUN apt update && \
apt install -y gettext apt install -y gettext
WORKDIR /app WORKDIR /app
RUN curl -sSL https://install.python-poetry.org | python3 - RUN curl -sSL https://install.python-poetry.org | python3 -
COPY pyproject.toml poetry.lock README.md ./ COPY pyproject.toml poetry.lock README.md ./
RUN poetry config virtualenvs.in-project true RUN poetry config virtualenvs.in-project true
RUN --mount=type=cache,target=/root/.cache/pypoetry/cache \ RUN poetry install --with app --no-root
--mount=type=cache,target=/root/.cache/pypoetry/artifacts \
poetry install --with app --no-root
COPY locales ./locales COPY locales ./locales
RUN cd locales/ru/LC_MESSAGES && msgfmt messages.po RUN cd locales/ru/LC_MESSAGES && msgfmt messages.po
@@ -17,8 +15,7 @@ FROM node:24 AS node-builder
ENV PATH=/app/node_modules/.bin:$PATH ENV PATH=/app/node_modules/.bin:$PATH
WORKDIR /app WORKDIR /app
COPY static/package.json static/package-lock.json ./ COPY static/package.json static/package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \ RUN npm ci
npm ci
COPY static ./ COPY static ./
RUN npm run build RUN npm run build
@@ -30,6 +27,7 @@ ENV TZ="Europe/Moscow"
COPY --from=builder /app ./ COPY --from=builder /app ./
COPY --from=node-builder /app/dist ./static/dist COPY --from=node-builder /app/dist ./static/dist
COPY gallery gallery/ COPY gallery gallery/
#COPY --from=builder /app/gallery/easel/route/view/locales /app/gallery/easel/route/view/locales
COPY --from=builder --parents locales/**/*.mo ./ COPY --from=builder --parents locales/**/*.mo ./
CMD ["uvicorn", "gallery.main:app", "--host", "0.0.0.0", "--port", "80", "--log-config", "gallery/logging.yaml"] CMD ["uvicorn", "gallery.main:app", "--host", "0.0.0.0", "--port", "80", "--log-config", "gallery/logging.yaml"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 237 KiB

View File

@@ -30,9 +30,6 @@
{% block header %}{% endblock %} {% block header %}{% endblock %}
</div> </div>
<ul class="navbar-nav flex-row flex-wrap ms-md-auto"> <ul class="navbar-nav flex-row flex-wrap ms-md-auto">
<li class="nav-item me-2">
<span class="nav-link">{{ version }}</span>
</li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center" <button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center"
id="bd-language" id="bd-language"
@@ -40,7 +37,7 @@
aria-expanded="false" aria-expanded="false"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-label="{{_('Select language')}} (default)"> aria-label="{{_('Select language')}} (default)">
<span class="fi fir fi-gb me-2 language-icon-active icon-header"></span> <span class="fi fir fi-gb me-2 language-icon-active"></span>
<span class="d-lg-none ms-2" <span class="d-lg-none ms-2"
id="bd-language-text">{{_("Select language")}}</span> id="bd-language-text">{{_("Select language")}}</span>
</button> </button>
@@ -73,7 +70,7 @@
aria-expanded="false" aria-expanded="false"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-label="Toggle theme (auto)"> aria-label="Toggle theme (auto)">
<span class="bi bi-circle-half me-2 opacity-50 theme-icon-active icon-header"></span> <span class="bi bi-circle-half me-2 opacity-50 theme-icon-active"></span>
<span class="d-lg-none ms-2" <span class="d-lg-none ms-2"
id="bd-theme-text">{{_("Toggle theme")}}</span> id="bd-theme-text">{{_("Toggle theme")}}</span>
</button> </button>

View File

@@ -1,4 +1,3 @@
import datetime
from pathlib import Path from pathlib import Path
from babel.dates import format_date from babel.dates import format_date
@@ -8,7 +7,6 @@ from fastapi.templating import Jinja2Templates
from gallery.version import __version__ from gallery.version import __version__
from ...translation import _ from ...translation import _
from .tag import TagUtil
def is_widget(request: Request) -> bool: def is_widget(request: Request) -> bool:
@@ -33,9 +31,6 @@ def build_templates(templates_dir: Path | None = None, filters: dict | None = No
"_": _, "_": _,
"version": __version__, "version": __version__,
"format_date": format_date, "format_date": format_date,
"datetime": datetime,
"tag_util": TagUtil,
"DATE_FORMAT": "E, d MMMM Y",
} }
) )
if filters: if filters:

View File

@@ -1,7 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %} {% block title %}
{{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, DATE_FORMAT, {{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}
locale=request.state.language)}}
{% endblock %} {% endblock %}
{% block header %} {% block header %}
@@ -11,19 +10,13 @@ locale=request.state.language)}}
{% block content %} {% block content %}
<h4> <h4>
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}" <a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}"> href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
<i class="bi bi-arrow-left-square"></i> <a class="button"
</a> href="../..">⬆️</a>
<a class="icon-link" <span>{{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
href="../.."> <a class="button"
<i class="bi bi-arrow-up-square"></i> href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
</a>
<span>{{response.channel.name}} | {{format_date(response.date, DATE_FORMAT, locale=request.state.language)}}</span>
<a class="icon-link"
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">
<i class="bi bi-arrow-right-square"></i>
</a>
</h4> </h4>
<table class="table"> <table class="table">
<thead> <thead>

View File

@@ -1,7 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %} {% block title %}
{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, DATE_FORMAT, {{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}
locale=request.state.language)}}
{% endblock %} {% endblock %}
{% block header %} {% block header %}
@@ -11,20 +10,13 @@ locale=request.state.language)}}
{% block content %} {% block content %}
<h4> <h4>
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}" <a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}"> href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
<i class="bi bi-arrow-left-square"></i> <a class="button"
</a> href="..">⬆️</a>
<a class="icon-link" <span>{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
href=".."> <a class="button"
<i class="bi bi-arrow-up-square"></i> href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
</a>
<span>{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, DATE_FORMAT,
locale=request.state.language)}}</span>
<a class="icon-link"
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">
<i class="bi bi-arrow-right-square"></i>
</a>
</h4> </h4>
<div> <div>
<table class="table"> <table class="table">

View File

@@ -25,6 +25,8 @@ def build_weather_response(request: AppRequest, response: WeatherResponse):
request=request, request=request,
name="weather.html", name="weather.html",
context={ context={
"tag_util": TagUtil,
"datetime": datetime,
"response": response, "response": response,
}, },
) )

View File

@@ -1,12 +1,6 @@
import datetime import datetime
from gallery.sketch.weather.model import ( from gallery.sketch.weather.model import Cloudness, Precipitation, Sky, WindDirection, WindDirectionDeg
Cloudness,
Precipitation,
Sky,
WindDirection,
WindDirectionDeg,
)
def wind_direction_icon(wind_direction_deg: float) -> str: def wind_direction_icon(wind_direction_deg: float) -> str:
@@ -14,7 +8,7 @@ def wind_direction_icon(wind_direction_deg: float) -> str:
if wind_direction == WindDirection.CALM: if wind_direction == WindDirection.CALM:
return "wind-calm" return "wind-calm"
else: else:
return f"wind-from-{wind_direction.name.lower()}" return f"wind-from-{wind_direction.name.lower()}"
def cloudness_icon(sky: Sky, date: datetime.datetime, period: str) -> list[str]: def cloudness_icon(sky: Sky, date: datetime.datetime, period: str) -> list[str]:

View File

@@ -9,24 +9,16 @@
{% block content %} {% block content %}
<h4> <h4>
{% if response.period == 'day' %} {% if response.period == 'day' %}
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}" <a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}"> href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
<i class="bi bi-arrow-left-square"></i> <a class="button"
</a> href="../tag/days-10">⬆️</a>
<a class="icon-link" <span>{{response.location}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
href="../tag/days-10"> <a class="button"
<i class="bi bi-arrow-up-square"></i> href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
</a>
<span>{{response.location}} | {{format_date(response.date, DATE_FORMAT, locale=request.state.language)}}</span>
<a class="icon-link"
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">
<i class="bi bi-arrow-right-square"></i>
</a>
{% endif %} {% endif %}
{% if response.period == 'days' %} {% if response.period == 'days' %}
<span>{{response.location}} | {{format_date(response.date, DATE_FORMAT, locale=request.state.language)}}</span> <span>{{response.location}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
<span>- {{format_date(response.date + datetime.timedelta(days=(response.values | length - 1)), DATE_FORMAT,
locale=request.state.language)}}</span>
{% endif %} {% endif %}
</h4> </h4>
<div class="table-responsive"> <div class="table-responsive">
@@ -66,7 +58,8 @@
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
data-bs-title="{{ value.sky }}"> data-bs-title="{{ value.sky }}">
{% for icon in value.sky | cloudness_icon(value.date, response.period) %} {% for icon in value.sky | cloudness_icon(value.date, response.period) %}
<div class="wi wi-{{icon}} wi-xl text-primary"></div> <div class="wi wi-{{icon}} text-primary"
style="font-size: 3.5rem;"></div>
{% endfor %} {% endfor %}
</td> </td>
{% endfor %} {% endfor %}
@@ -102,7 +95,7 @@
<td class="wind" <td class="wind"
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
data-bs-title="{{ value.wind_direction }}"> data-bs-title="{{ value.wind_direction }}">
<div class="wi wi-wind-deg wi-{{value.wind_direction | wind_direction_icon}} wi-l text-primary"></div> <div class="wi wi-wind-deg wi-{{value.wind_direction | wind_direction_icon}} fs-1 text-primary"></div>
</td> </td>
{% endfor %} {% endfor %}
</tr> </tr>

View File

@@ -1,3 +1,5 @@
__version__ = "0.2.2"
import tomllib import tomllib
from pathlib import Path from pathlib import Path

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "gallery" name = "gallery"
version = "0.3.1" version = "0.2.3"
description = "" description = ""
authors = ["shmyga <shmyga.z@gmail.com>"] authors = ["shmyga <shmyga.z@gmail.com>"]
readme = "README.md" readme = "README.md"

View File

@@ -1,12 +1,12 @@
{ {
"name": "gallery", "name": "gallery",
"version": "0.3.1", "version": "0.2.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "gallery", "name": "gallery",
"version": "0.3.1", "version": "0.2.3",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",

View File

@@ -1,6 +1,6 @@
{ {
"name": "gallery", "name": "gallery",
"version": "0.3.1", "version": "0.2.3",
"scripts": { "scripts": {
"build": "vite build", "build": "vite build",
"dev": "vite build --watch" "dev": "vite build --watch"

View File

@@ -1,6 +1,4 @@
.icon-link { //$bootstrap-icons: "circle-half", "moon-stars-fill", "brightness-high", "gear", "sun-fill", "tv";
vertical-align: -0.25rem;
}
.bi { .bi {
display: inline-block; display: inline-block;
@@ -15,6 +13,12 @@
mask-repeat: no-repeat; mask-repeat: no-repeat;
background-color: currentColor; background-color: currentColor;
//@each $icon in $bootstrap-icons {
// &.bi-#{$icon} {
// mask-image: url("bootstrap-icons/icons/#{$icon}.svg");
// }
///
&.bi-circle-half { &.bi-circle-half {
mask-image: url(bootstrap-icons/icons/circle-half.svg); mask-image: url(bootstrap-icons/icons/circle-half.svg);
} }
@@ -33,13 +37,4 @@
&.bi-tv { &.bi-tv {
mask-image: url(bootstrap-icons/icons/tv.svg); mask-image: url(bootstrap-icons/icons/tv.svg);
} }
&.bi-arrow-left-square {
mask-image: url(bootstrap-icons/icons/arrow-left-square.svg);
}
&.bi-arrow-right-square {
mask-image: url(bootstrap-icons/icons/arrow-right-square.svg);
}
&.bi-arrow-up-square {
mask-image: url(bootstrap-icons/icons/arrow-up-square.svg);
}
} }

View File

@@ -12,6 +12,4 @@
.fir { .fir {
@extend .fis; @extend .fis;
border-radius: 50%; border-radius: 50%;
height: 1em;
border: 1px solid gray;
} }

View File

@@ -13,11 +13,4 @@
mask-position: 50%; mask-position: 50%;
mask-repeat: no-repeat; mask-repeat: no-repeat;
background-color: currentColor; background-color: currentColor;
&.wi-l {
font-size: 2.5rem;
}
&.wi-xl {
font-size: 3.5rem;
}
} }

View File

@@ -12,8 +12,11 @@
} }
} }
.icon-header { .icon {
@include font-size($h4-font-size); display: inline-block;
width: 2rem;
height: 2rem;
background-size: contain;
} }
.app-header { .app-header {