feat: add home link
@@ -1,9 +1,37 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI, Request
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
|
from gallery.version import __version__
|
||||||
|
|
||||||
|
|
||||||
|
class Section(NamedTuple):
|
||||||
|
link: str
|
||||||
|
title: str
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS = [
|
||||||
|
Section("weather", "Погода"),
|
||||||
|
Section("schedule", "Телепрограмма"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def mount(app: FastAPI):
|
def mount(app: FastAPI):
|
||||||
base_dir = Path(__file__).parent
|
base_dir = Path(__file__).parent
|
||||||
app.mount("/static/common", StaticFiles(directory=base_dir / "static"))
|
app.mount("/static/common", StaticFiles(directory=base_dir / "static"))
|
||||||
|
templates = Jinja2Templates(directory=base_dir / "templates")
|
||||||
|
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def get_section_list(request: Request):
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
request=request,
|
||||||
|
name="index.html",
|
||||||
|
context={
|
||||||
|
"version": __version__,
|
||||||
|
"sections": SECTIONS,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
gallery/easel/route/view/common/static/gallery.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
@@ -52,6 +52,33 @@ app
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-header {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-link-home > * {
|
||||||
|
margin-left: 2rem;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
background-image: url("/static/common/gallery.png");
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
ul.app-list {
|
ul.app-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
@@ -61,7 +88,8 @@ ul.app-list > li {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul.app-list > li > a {
|
ul.app-list > li > a {
|
||||||
display: block;
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
padding: 0.5rem 2rem;
|
padding: 0.5rem 2rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|||||||
41
gallery/easel/route/view/common/templates/index.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible"
|
||||||
|
content="ie=edge">
|
||||||
|
<title>Информация</title>
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="/static/common/style.css?v={{version}}">
|
||||||
|
<link rel="icon"
|
||||||
|
href="/static/common/favicon.ico?v={{version}}"
|
||||||
|
type="image/x-icon">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="app-container">
|
||||||
|
<h3 class="app-header">
|
||||||
|
<a class="app-link-home"
|
||||||
|
href="/">
|
||||||
|
<div></div>
|
||||||
|
</a>
|
||||||
|
<div class="app-title">
|
||||||
|
<span>Информация</span>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
<ul class="app-list">
|
||||||
|
{% for section in sections %}
|
||||||
|
<li>
|
||||||
|
<a href="{{section.link}}">
|
||||||
|
<span class="icon"
|
||||||
|
style="background-image: url(/static/{{section.link}}/{{section.link}}.png);"></span>
|
||||||
|
<span>{{section.title}}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
BIN
gallery/easel/route/view/schedule/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
gallery/easel/route/view/schedule/static/schedule.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
@@ -1,3 +1,7 @@
|
|||||||
|
tr {
|
||||||
|
border-bottom: 1px solid lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,25 @@
|
|||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="/static/schedule/style.css?v={{version}}">
|
href="/static/schedule/style.css?v={{version}}">
|
||||||
<link rel="icon"
|
<link rel="icon"
|
||||||
href="/static/common/favicon.ico"
|
href="/static/schedule/favicon.ico?v={{version}}"
|
||||||
type="image/x-icon">
|
type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="app-container">
|
<body class="app-container">
|
||||||
<h3>
|
<h3 class="app-header">
|
||||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
<a class="app-link-home"
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
href="/">
|
||||||
<a class="button"
|
<div></div>
|
||||||
href="../..">⬆️</a>
|
</a>
|
||||||
<span>{{response.channel.name}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
<div class="app-title">
|
||||||
<a class="button"
|
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||||
|
<a class="button"
|
||||||
|
href="../..">⬆️</a>
|
||||||
|
<span>{{response.channel.name}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||||
|
<a class="button"
|
||||||
|
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||||
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
|
|||||||
@@ -13,12 +13,22 @@
|
|||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="/static/schedule/style.css?v={{version}}">
|
href="/static/schedule/style.css?v={{version}}">
|
||||||
<link rel="icon"
|
<link rel="icon"
|
||||||
href="/static/common/favicon.ico"
|
href="/static/schedule/favicon.ico?v={{version}}"
|
||||||
type="image/x-icon">
|
type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="app-container">
|
<body class="app-container">
|
||||||
|
<h3 class="app-header">
|
||||||
|
<a class="app-link-home"
|
||||||
|
href="/">
|
||||||
|
<div></div>
|
||||||
|
</a>
|
||||||
|
<div class="app-title">
|
||||||
|
<span>Телепрограмма</span>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
<ul class="app-list">
|
<ul class="app-list">
|
||||||
|
<li style="margin-bottom: 0.25rem;"><a href="schedule/tag/today">all</a></li>
|
||||||
{% for channel in channels %}
|
{% for channel in channels %}
|
||||||
<li><a href="schedule/{{channel}}">{{channel}}</a></li>
|
<li><a href="schedule/{{channel}}">{{channel}}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -13,19 +13,25 @@
|
|||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="/static/schedule/style.css?v={{version}}">
|
href="/static/schedule/style.css?v={{version}}">
|
||||||
<link rel="icon"
|
<link rel="icon"
|
||||||
href="/static/common/favicon.ico"
|
href="/static/schedule/favicon.ico?v={{version}}"
|
||||||
type="image/x-icon">
|
type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="app-container">
|
<body class="app-container">
|
||||||
<h3>
|
<h3 class="app-header">
|
||||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
<a class="app-link-home"
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
href="/">
|
||||||
<a class="button"
|
<div></div>
|
||||||
href="../..">⬆️</a>
|
</a>
|
||||||
<span>Прямые трансляции | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
<div class="app-title">
|
||||||
<a class="button"
|
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||||
|
<a class="button"
|
||||||
|
href="..">⬆️</a>
|
||||||
|
<span>{{'Прямые трансляции' if live else 'Программа'}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||||
|
<a class="button"
|
||||||
|
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||||
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<table class="{{'live' if live else ''}}">
|
<table class="{{'live' if live else ''}}">
|
||||||
|
|||||||
BIN
gallery/easel/route/view/weather/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
gallery/easel/route/view/weather/static/weather.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
@@ -13,11 +13,20 @@
|
|||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="/static/weather/style.css?v={{version}}">
|
href="/static/weather/style.css?v={{version}}">
|
||||||
<link rel="icon"
|
<link rel="icon"
|
||||||
href="/static/common/favicon.ico"
|
href="/static/weather/favicon.ico?v={{version}}"
|
||||||
type="image/x-icon">
|
type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="app-container">
|
<body class="app-container">
|
||||||
|
<h3 class="app-header">
|
||||||
|
<a class="app-link-home"
|
||||||
|
href="/">
|
||||||
|
<div></div>
|
||||||
|
</a>
|
||||||
|
<div class="app-title">
|
||||||
|
<span>Погода</span>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
<ul class="app-list">
|
<ul class="app-list">
|
||||||
{% for location in locations %}
|
{% for location in locations %}
|
||||||
<li><a href="weather/{{location}}">{{location}}</a></li>
|
<li><a href="weather/{{location}}">{{location}}</a></li>
|
||||||
|
|||||||
@@ -13,24 +13,30 @@
|
|||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="/static/weather/style.css?v={{version}}">
|
href="/static/weather/style.css?v={{version}}">
|
||||||
<link rel="icon"
|
<link rel="icon"
|
||||||
href="/static/common/favicon.ico"
|
href="/static/weather/favicon.ico?v={{version}}"
|
||||||
type="image/x-icon">
|
type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="app-container">
|
<body class="app-container">
|
||||||
<h3>
|
<h3 class="app-header">
|
||||||
{% if response.period == 'day' %}
|
<a class="app-link-home"
|
||||||
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
href="/">
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
<div></div>
|
||||||
<a class="button"
|
</a>
|
||||||
href="../tag/days-10">⬆️</a>
|
<div class="app-title">
|
||||||
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
{% if response.period == 'day' %}
|
||||||
<a class="button"
|
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
|
||||||
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
|
||||||
{% endif %}
|
<a class="button"
|
||||||
{% if response.period == 'days' %}
|
href="../tag/days-10">⬆️</a>
|
||||||
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||||
{% endif %}
|
<a class="button"
|
||||||
|
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if response.period == 'days' %}
|
||||||
|
<span>{{response.location}} | {{response.date.strftime('%a, %d %B %Y')}}</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</h3>
|
</h3>
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||