Compare commits

..
1 Commits
Author SHA1 Message Date
shmyga ad94deb9b7 ci(action): add setup composite action
test / test (push) Failing after 39s
2026-09-26 15:39:27 +03:00
17 changed files with 102 additions and 119 deletions
+32
View File
@@ -0,0 +1,32 @@
name: "Setup"
description: "Setup project"
inputs:
python-version:
default: "3.14"
runs:
using: "composite"
steps:
- id: setup-python
uses: actions/setup-python@v7
with:
python-version: ${{ inputs.python-version }}
cache: "pip"
- run: |
pip install project-manager \
--index-url https://git.shmyga.ru/api/packages/InfernalGames/pypi/simple/ \
--extra-index-url https://pypi.org/simple
- run: pm setup:config -vv
# setup python venv
- run: pip install poetry
- id: cache-venv
uses: actions/cache@v6
with:
path: .venv
key: venv-${{ runner.os }}-python-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- if: steps.cache-venv.outputs.cache-hit != 'true'
run: pm setup:python -vv
+42
View File
@@ -0,0 +1,42 @@
name: build
on:
push:
tags: ["*"]
jobs:
build:
runs-on: ubuntu-latest
steps:
# repo
- name: Check out repository
uses: actions/checkout@v7
# python
- name: Set up python
id: setup-python
uses: actions/setup-python@v7
with:
python-version: "3.14"
cache: "pip"
# project-manager
- name: Install Project Manager
run: |
pip install project-manager \
--index-url https://git.shmyga.ru/api/packages/InfernalGames/pypi/simple/ \
--extra-index-url https://pypi.org/simple
# setup
- name: Setup config
run: pm setup:config -vv
# build
- name: Build docker
run: pm build:docker -vv
# login docker
- name: Login to Docker Hub
uses: docker/login-action@v4
with:
registry: git.shmyga.ru
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# pubish
- name: Publish docker
run: pm publish:docker -vv
-22
View File
@@ -1,22 +0,0 @@
name: deploy
on:
workflow_run:
workflows: [release]
types: [completed]
jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USERNAME }}
key: ${{ secrets.DEPLOY_KEY }}
passphrase: ${{ secrets.DEPLOY_PASSPHRASE }}
script: |
cd /opt/gallery
docker compose pull
docker compose up -d
-20
View File
@@ -1,20 +0,0 @@
name: release
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: https://git.shmyga.ru/InfernalGames/project-manager@master
- run: pm build:docker -vv
- uses: docker/login-action@v4
with:
registry: git.shmyga.ru
username: ${{ vars.PUBLISH_USERNAME }}
password: ${{ secrets.PUBLISH_TOKEN }}
- run: pm publish:docker -vv
+1 -3
View File
@@ -7,8 +7,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
- uses: https://git.shmyga.ru/InfernalGames/project-manager@master - uses: ./.gitea/actions/setup
with:
setup-python: true
- run: pm lint -vv - run: pm lint -vv
- run: pm test -vv - run: pm test -vv
+1 -1
View File
@@ -27,7 +27,7 @@ FROM python:3.14-slim
ENV PLAYWRIGHT_BROWSERS_PATH="/opt/playwright-browsers" ENV PLAYWRIGHT_BROWSERS_PATH="/opt/playwright-browsers"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \
pip install playwright==1.62 && \ pip install playwright && \
playwright install --with-deps chromium playwright install --with-deps chromium
ENV PATH="/app/.venv/bin:$PATH" ENV PATH="/app/.venv/bin:$PATH"
-2
View File
@@ -1,7 +1,5 @@
# API Gallery # API Gallery
[![test](https://git.shmyga.ru/InfernalGames/gallery/actions/workflows/test.yaml/badge.svg?branch=master)](https://git.shmyga.ru/InfernalGames/gallery/actions?workflow=test.yaml)
Currently implemented APIs: Currently implemented APIs:
- Weather forecast - Weather forecast
+11 -23
View File
@@ -1,3 +1,4 @@
import datetime
from pathlib import Path from pathlib import Path
from urllib import parse from urllib import parse
@@ -12,7 +13,9 @@ from gallery.easel.depends.schedule import (
ScheduleApiDepends, ScheduleApiDepends,
ScheduleGroupChannelsDepends, ScheduleGroupChannelsDepends,
) )
from gallery.sketch.bundle import ApiBundle
from gallery.sketch.schedule.api import ScheduleApi from gallery.sketch.schedule.api import ScheduleApi
from gallery.sketch.schedule.model import Schedule
from ..common.utils.template import build_templates from ..common.utils.template import build_templates
from .filters import timedelta_format from .filters import timedelta_format
@@ -49,6 +52,12 @@ async def get_schedule_index(request: AppRequest, provider: str | None = None, q
) )
async def _get_group_schedule(api: ApiBundle, channels: list[tuple[str, str]], date: datetime.date) -> list[Schedule]:
return [
await api.get_api(ScheduleApi, provider).get_schedule(channel_id, date) for provider, channel_id in channels
]
@router.get("/group/{group_id}", response_class=RedirectResponse) @router.get("/group/{group_id}", response_class=RedirectResponse)
async def get_group_default(group_id: str): async def get_group_default(group_id: str):
return RedirectResponse(f"{parse.quote(group_id)}/today") return RedirectResponse(f"{parse.quote(group_id)}/today")
@@ -63,16 +72,7 @@ async def get_group(request: AppRequest, channels: ScheduleGroupChannelsDepends,
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="group.html", name="group.html",
context={ context={"responses": responses},
"responses": responses,
"api_route": "/".join(
[
"/api/schedule/group",
request.path_params["group_id"],
request.path_params["date"],
]
),
},
) )
@@ -87,17 +87,5 @@ async def get_channel(request: AppRequest, schedule_api: ScheduleApiDepends, cha
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="channel.html", name="channel.html",
context={ context={"response": response},
"response": response,
"api_route": (
"/".join(
[
"/api/schedule",
request.path_params["provider"],
request.path_params["channel"],
request.path_params["date"],
]
)
),
},
) )
@@ -10,9 +10,6 @@ locale=request.state.language)}}
{% block header %} {% block header %}
<app-link href="/schedule" <app-link href="/schedule"
icon="tv">{{_("TV program")}}</app-link> icon="tv">{{_("TV program")}}</app-link>
<app-link target="_blank"
href="{{ api_route }}"
icon="filetype-json"></app-link>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@@ -47,8 +44,7 @@ locale=request.state.language)}}
{% for value in response.values %} {% for value in response.values %}
<tr class="{{'d-none' if (live and not value.live) else 'table-success' if (not live and value.live) else ''}}"> <tr class="{{'d-none' if (live and not value.live) else 'table-success' if (not live and value.live) else ''}}">
<td> <td>
<span>{{value.start.strftime('%H:%M')}}</span>&nbsp;<span class="small ms-1">({{(value.end - value.start) | <span>{{value.start.strftime('%H:%M')}}</span>&nbsp;<span class="small ms-1">({{(value.end - value.start) | timedelta_format}})</span>
timedelta_format}})</span>
</td> </td>
<td>{{value.label}}</td> <td>{{value.label}}</td>
</tr> </tr>
@@ -9,9 +9,6 @@
{% block header %} {% block header %}
<app-link href="/schedule" <app-link href="/schedule"
icon="tv">{{_("TV program")}}</app-link> icon="tv">{{_("TV program")}}</app-link>
<app-link target="_blank"
href="{{ api_route }}"
icon="filetype-json"></app-link>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
+1 -20
View File
@@ -3,7 +3,6 @@ from typing import Literal
from fastapi import APIRouter from fastapi import APIRouter
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse
from starlette.datastructures import URL
from gallery.easel.core import AppRequest from gallery.easel.core import AppRequest
from gallery.easel.depends.api import api_resolver from gallery.easel.depends.api import api_resolver
@@ -37,18 +36,7 @@ def build_weather_response(request: AppRequest, response: WeatherResponse):
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="weather.html", name="weather.html",
context={ context={"response": response},
"response": response,
"api_route": "/".join(
[
"/api/weather",
request.path_params["provider"],
request.path_params["location"],
response.period,
request.path_params.get("date") or request.path_params.get("days") or "",
]
),
},
) )
@@ -80,13 +68,6 @@ async def get_weather_days(request: AppRequest, weather_api: WeatherApiDepends,
return build_weather_response(request, response) return build_weather_response(request, response)
# TODO: tag mode route deprecated, used in tizen app
@router.get("/{provider}/{location}/tag/days-{days}", response_class=RedirectResponse)
async def get_tag_days(request: AppRequest, days: int):
url = URL(path=f"../days/{days}", query=request.url.query)
return RedirectResponse(url)
# TODO: tag mode route deprecated, used in tizen app # TODO: tag mode route deprecated, used in tizen app
@router.get("/{provider}/{location}/{mode:str}/{date}", response_class=HTMLResponse) @router.get("/{provider}/{location}/{mode:str}/{date}", response_class=HTMLResponse)
async def get_weather_day( async def get_weather_day(
@@ -7,9 +7,6 @@ locale=request.state.language)}}{% endblock %}
{% block header %} {% block header %}
<app-link href="/weather" <app-link href="/weather"
icon="brightness-high">{{_("Weather")}}</app-link> icon="brightness-high">{{_("Weather")}}</app-link>
<app-link target="_blank"
href="{{ api_route }}"
icon="filetype-json"></app-link>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
+1 -2
View File
@@ -29,7 +29,6 @@ class YandexTVApi(ScheduleApi):
return self.channel_parser.parse(data) return self.channel_parser.parse(data)
async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule: async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
channel_path_part = "channel" if "-" in channel_id else "channels" endpoint = f"{self.lr}/channel/{channel_id}?date={date:%Y-%m-%d}"
endpoint = f"{self.lr}/{channel_path_part}/{channel_id}?date={date:%Y-%m-%d}"
data = await self.source.request(endpoint) data = await self.source.request(endpoint)
return self.schedule_parser.parse(ScheduleData(date, channel_id, data)) return self.schedule_parser.parse(ScheduleData(date, channel_id, data))
+9 -9
View File
@@ -1,16 +1,16 @@
[project] [project]
name = "gallery" name = "gallery"
description = "" description = ""
version = "0.10.5" version = "0.10.1"
readme = "README.md" readme = "README.md"
authors = [{ name = "shmyga", email = "shmyga.z@gmail.com" }] authors = [{ name = "shmyga", email = "shmyga.z@gmail.com" }]
requires-python = ">=3.14,<4.0" requires-python = '>=3.14,<4.0'
dependencies = [ dependencies = [
"aiohttp (>=3.14,<4.0)", 'aiohttp (>=3.14,<4.0)',
"beautifulsoup4 (>=4.15,<5.0)", 'beautifulsoup4 (>=4.15,<5.0)',
"dateparser (>=1.4,<2.0)", 'dateparser (>=1.4,<2.0)',
"pydantic (>=2.13,<3.0)", 'pydantic (>=2.13,<3.0)',
"aiocache[redis] (>=0.12,<0.13)", 'aiocache[redis] (>=0.12,<0.13)',
"playwright (>=1.62.0,<2.0.0)", "playwright (>=1.62.0,<2.0.0)",
] ]
@@ -30,10 +30,10 @@ gallery = "gallery.main:run"
[tool.poetry] [tool.poetry]
packages = [{ include = "gallery" }] packages = [{ include = "gallery" }]
requires-poetry = ">=2.0.0,<3.0.0" requires-poetry = '>=2.0.0,<3.0.0'
[build-system] [build-system]
requires = ["poetry-core (>=2.0.0,<3.0.0)"] requires = ['poetry-core (>=2.0.0,<3.0.0)']
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.black] [tool.black]
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "gallery", "name": "gallery",
"version": "0.10.5", "version": "0.10.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "gallery", "name": "gallery",
"version": "0.10.5", "version": "0.10.1",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "gallery", "name": "gallery",
"version": "0.10.5", "version": "0.10.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "webpack --mode production", "build": "webpack --mode production",
-3
View File
@@ -48,7 +48,4 @@
&.bi-cast { &.bi-cast {
mask-image: url(bootstrap-icons/icons/cast.svg); mask-image: url(bootstrap-icons/icons/cast.svg);
} }
&.bi-filetype-json {
mask-image: url(bootstrap-icons/icons/filetype-json.svg);
}
} }