Compare commits
9 Commits
a715bcca89
...
0.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 2bca3dd75a | |||
| 469bd9bc1f | |||
| 027d1e2d55 | |||
| 7cf0012229 | |||
| edc014d98c | |||
| 1813ec213b | |||
| 1b700086f2 | |||
| 02a6ffc931 | |||
| 2dfedfea57 |
10
Dockerfile
10
Dockerfile
@@ -2,12 +2,14 @@ FROM python:3.12 AS builder
|
||||
ENV POETRY_HOME="/opt/poetry"
|
||||
ENV PATH="$POETRY_HOME/bin:$PATH"
|
||||
RUN apt update && \
|
||||
apt install -y gettext
|
||||
apt install -y gettext
|
||||
WORKDIR /app
|
||||
RUN curl -sSL https://install.python-poetry.org | python3 -
|
||||
COPY pyproject.toml poetry.lock README.md ./
|
||||
RUN poetry config virtualenvs.in-project true
|
||||
RUN poetry install --with app --no-root
|
||||
RUN --mount=type=cache,target=/root/.cache/pypoetry/cache \
|
||||
--mount=type=cache,target=/root/.cache/pypoetry/artifacts \
|
||||
poetry install --with app --no-root
|
||||
COPY locales ./locales
|
||||
RUN cd locales/ru/LC_MESSAGES && msgfmt messages.po
|
||||
|
||||
@@ -15,7 +17,8 @@ FROM node:24 AS node-builder
|
||||
ENV PATH=/app/node_modules/.bin:$PATH
|
||||
WORKDIR /app
|
||||
COPY static/package.json static/package-lock.json ./
|
||||
RUN npm ci
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm ci
|
||||
COPY static ./
|
||||
RUN npm run build
|
||||
|
||||
@@ -27,7 +30,6 @@ ENV TZ="Europe/Moscow"
|
||||
COPY --from=builder /app ./
|
||||
COPY --from=node-builder /app/dist ./static/dist
|
||||
COPY gallery gallery/
|
||||
#COPY --from=builder /app/gallery/easel/route/view/locales /app/gallery/easel/route/view/locales
|
||||
COPY --from=builder --parents locales/**/*.mo ./
|
||||
|
||||
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: 237 KiB After Width: | Height: | Size: 182 KiB |
@@ -30,6 +30,9 @@
|
||||
{% block header %}{% endblock %}
|
||||
</div>
|
||||
<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">
|
||||
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center"
|
||||
id="bd-language"
|
||||
@@ -37,7 +40,7 @@
|
||||
aria-expanded="false"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-label="{{_('Select language')}} (default)">
|
||||
<span class="fi fir fi-gb me-2 language-icon-active"></span>
|
||||
<span class="fi fir fi-gb me-2 language-icon-active icon-header"></span>
|
||||
<span class="d-lg-none ms-2"
|
||||
id="bd-language-text">{{_("Select language")}}</span>
|
||||
</button>
|
||||
@@ -70,7 +73,7 @@
|
||||
aria-expanded="false"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-label="Toggle theme (auto)">
|
||||
<span class="bi bi-circle-half me-2 opacity-50 theme-icon-active"></span>
|
||||
<span class="bi bi-circle-half me-2 opacity-50 theme-icon-active icon-header"></span>
|
||||
<span class="d-lg-none ms-2"
|
||||
id="bd-theme-text">{{_("Toggle theme")}}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from babel.dates import format_date
|
||||
@@ -7,6 +8,7 @@ from fastapi.templating import Jinja2Templates
|
||||
from gallery.version import __version__
|
||||
|
||||
from ...translation import _
|
||||
from .tag import TagUtil
|
||||
|
||||
|
||||
def is_widget(request: Request) -> bool:
|
||||
@@ -31,6 +33,9 @@ def build_templates(templates_dir: Path | None = None, filters: dict | None = No
|
||||
"_": _,
|
||||
"version": __version__,
|
||||
"format_date": format_date,
|
||||
"datetime": datetime,
|
||||
"tag_util": TagUtil,
|
||||
"DATE_FORMAT": "E, d MMMM Y",
|
||||
}
|
||||
)
|
||||
if filters:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
{{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}
|
||||
{{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, DATE_FORMAT,
|
||||
locale=request.state.language)}}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
@@ -10,13 +11,19 @@
|
||||
|
||||
{% block content %}
|
||||
<h4>
|
||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||
<a class="button"
|
||||
href="../..">⬆️</a>
|
||||
<span>{{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
|
||||
<a class="button"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">
|
||||
<i class="bi bi-arrow-left-square"></i>
|
||||
</a>
|
||||
<a class="icon-link"
|
||||
href="../..">
|
||||
<i class="bi bi-arrow-up-square"></i>
|
||||
</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>
|
||||
<table class="table">
|
||||
<thead>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}
|
||||
{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, DATE_FORMAT,
|
||||
locale=request.state.language)}}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
@@ -10,13 +11,20 @@
|
||||
|
||||
{% block content %}
|
||||
<h4>
|
||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||
<a class="button"
|
||||
href="..">⬆️</a>
|
||||
<span>{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
|
||||
<a class="button"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">
|
||||
<i class="bi bi-arrow-left-square"></i>
|
||||
</a>
|
||||
<a class="icon-link"
|
||||
href="..">
|
||||
<i class="bi bi-arrow-up-square"></i>
|
||||
</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>
|
||||
<div>
|
||||
<table class="table">
|
||||
|
||||
@@ -25,8 +25,6 @@ def build_weather_response(request: AppRequest, response: WeatherResponse):
|
||||
request=request,
|
||||
name="weather.html",
|
||||
context={
|
||||
"tag_util": TagUtil,
|
||||
"datetime": datetime,
|
||||
"response": response,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import datetime
|
||||
|
||||
from gallery.sketch.weather.model import Cloudness, Precipitation, Sky, WindDirection, WindDirectionDeg
|
||||
from gallery.sketch.weather.model import (
|
||||
Cloudness,
|
||||
Precipitation,
|
||||
Sky,
|
||||
WindDirection,
|
||||
WindDirectionDeg,
|
||||
)
|
||||
|
||||
|
||||
def wind_direction_icon(wind_direction_deg: float) -> str:
|
||||
@@ -8,7 +14,7 @@ def wind_direction_icon(wind_direction_deg: float) -> str:
|
||||
if wind_direction == WindDirection.CALM:
|
||||
return "wind-calm"
|
||||
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]:
|
||||
|
||||
@@ -9,16 +9,24 @@
|
||||
{% block content %}
|
||||
<h4>
|
||||
{% if response.period == 'day' %}
|
||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||
<a class="button"
|
||||
href="../tag/days-10">⬆️</a>
|
||||
<span>{{response.location}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
|
||||
<a class="button"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||
<a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">
|
||||
<i class="bi bi-arrow-left-square"></i>
|
||||
</a>
|
||||
<a class="icon-link"
|
||||
href="../tag/days-10">
|
||||
<i class="bi bi-arrow-up-square"></i>
|
||||
</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 %}
|
||||
{% if response.period == 'days' %}
|
||||
<span>{{response.location}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
|
||||
<span>{{response.location}} | {{format_date(response.date, DATE_FORMAT, 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 %}
|
||||
</h4>
|
||||
<div class="table-responsive">
|
||||
@@ -58,8 +66,7 @@
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-title="{{ value.sky }}">
|
||||
{% for icon in value.sky | cloudness_icon(value.date, response.period) %}
|
||||
<div class="wi wi-{{icon}} text-primary"
|
||||
style="font-size: 3.5rem;"></div>
|
||||
<div class="wi wi-{{icon}} wi-xl text-primary"></div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
@@ -95,7 +102,7 @@
|
||||
<td class="wind"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-title="{{ value.wind_direction }}">
|
||||
<div class="wi wi-wind-deg wi-{{value.wind_direction | wind_direction_icon}} fs-1 text-primary"></div>
|
||||
<div class="wi wi-wind-deg wi-{{value.wind_direction | wind_direction_icon}} wi-l text-primary"></div>
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
__version__ = "0.2.2"
|
||||
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "gallery"
|
||||
version = "0.2.3"
|
||||
version = "0.3.1"
|
||||
description = ""
|
||||
authors = ["shmyga <shmyga.z@gmail.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
4
static/package-lock.json
generated
4
static/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "gallery",
|
||||
"version": "0.2.3",
|
||||
"version": "0.3.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gallery",
|
||||
"version": "0.2.3",
|
||||
"version": "0.3.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gallery",
|
||||
"version": "0.2.3",
|
||||
"version": "0.3.1",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite build --watch"
|
||||
|
||||
19
static/src/lib/bootstrap-icons.scss
vendored
19
static/src/lib/bootstrap-icons.scss
vendored
@@ -1,4 +1,6 @@
|
||||
//$bootstrap-icons: "circle-half", "moon-stars-fill", "brightness-high", "gear", "sun-fill", "tv";
|
||||
.icon-link {
|
||||
vertical-align: -0.25rem;
|
||||
}
|
||||
|
||||
.bi {
|
||||
display: inline-block;
|
||||
@@ -13,12 +15,6 @@
|
||||
mask-repeat: no-repeat;
|
||||
background-color: currentColor;
|
||||
|
||||
//@each $icon in $bootstrap-icons {
|
||||
// &.bi-#{$icon} {
|
||||
// mask-image: url("bootstrap-icons/icons/#{$icon}.svg");
|
||||
// }
|
||||
///
|
||||
|
||||
&.bi-circle-half {
|
||||
mask-image: url(bootstrap-icons/icons/circle-half.svg);
|
||||
}
|
||||
@@ -37,4 +33,13 @@
|
||||
&.bi-tv {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,6 @@
|
||||
.fir {
|
||||
@extend .fis;
|
||||
border-radius: 50%;
|
||||
height: 1em;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
@@ -13,4 +13,11 @@
|
||||
mask-position: 50%;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: currentColor;
|
||||
|
||||
&.wi-l {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
&.wi-xl {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-size: contain;
|
||||
.icon-header {
|
||||
@include font-size($h4-font-size);
|
||||
}
|
||||
|
||||
.app-header {
|
||||
|
||||
Reference in New Issue
Block a user