4 Commits

7 changed files with 62 additions and 134 deletions

View File

@@ -1,33 +0,0 @@
when:
- event: pull_request
branch:
exclude: [master, release/*]
steps:
- name: prepare
image: python:3.12-alpine
commands: |
cd ./backend
python3 -m venv local
wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s latest -b ./local/bin/
source ./local/bin/activate
pip install poetry
poetry install --only=linters --no-root
- name: ruff
image: python:3.12-alpine
failure: ignore
secrets: ["reviewdog_gitea_api_token", "gitea_address"]
commands: |
cd ./backend
source ./local/bin/activate
poetry run ruff --output-format sarif . | ./local/bin/reviewdog -f sarif -reporter gitea-pr-review -filter-mode nofilter
- name: mypy
image: python:3.12-alpine
failure: ignore
secrets: ["reviewdog_gitea_api_token", "gitea_address"]
commands: |
cd ./backend
source ./local/bin/activate
poetry run mypy --no-incremental . | ./local/bin/reviewdog -f mypy -reporter gitea-pr-review -filter-mode nofilter

View File

@@ -1,10 +1,7 @@
from asyncio import sleep
from logging import getLogger
from typing import Annotated, AsyncIterator
from fastapi import Depends
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from sqlalchemy import text
from sqlalchemy.exc import OperationalError, SQLAlchemyError
from sqlalchemy.ext.asyncio import (
async_sessionmaker,
@@ -16,6 +13,7 @@ from sqlalchemy.ext.asyncio import (
from .base_class import Base
from ..settings import DatabaseSettings
logger = getLogger(__name__)
@@ -30,8 +28,7 @@ class Database:
except (SQLAlchemyError, AttributeError) as e:
logger.exception(e)
return None
raise
# TODO: Preserve UserLastStopSearchResults table from drop.
async def connect(

View File

@@ -35,26 +35,6 @@ if TYPE_CHECKING:
logger = getLogger(__name__)
# import cProfile
# import io
# import pstats
# import contextlib
# @contextlib.contextmanager
# def profiled():
# pr = cProfile.Profile()
# pr.enable()
# yield
# pr.disable()
# s = io.StringIO()
# ps = pstats.Stats(pr, stream=s).sort_stats("cumulative")
# ps.print_stats()
# # uncomment this to see who's calling what
# # ps.print_callers()
# print(s.getvalue())
class StopAreaStopAssociations(Base):
id = mapped_column(BigInteger, primary_key=True)

View File

@@ -18,14 +18,13 @@ from api.routers import line, stop
@asynccontextmanager
async def lifespan(app: FastAPI) -> None:
async def lifespan(app: FastAPI):
FastAPICache.init(redis_backend, prefix="api", enable=settings.cache.enable)
await db.connect(settings.db, settings.clear_static_data)
if settings.clear_static_data:
await idfm_interface.startup()
print("OK")
yield
await db.disconnect()

View File

@@ -24,7 +24,6 @@ psycopg = "^3.1.9"
pyyaml = "^6.0"
fastapi-cache2 = {extras = ["redis"], version = "^0.2.1"}
pydantic-settings = "^2.0.3"
ruff = "^0.2.1"
[tool.poetry.group.db_updater.dependencies]
aiofiles = "^22.1.0"
@@ -53,36 +52,28 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry.group.dev.dependencies]
pylsp-mypy = "^0.6.2"
python-lsp-black = "^1.2.1"
wrapt = "^1.14.1"
dill = "^0.3.6"
python-lsp-ruff = "^1.0.5"
python-lsp-server = "^1.7.1"
icecream = "^2.1.3"
[tool.poetry.group.linters.dependencies]
autopep8 = "^2.0.1"
black = "^22.10.0"
mccabe = "^0.7.0"
mypy = "^1.0.0"
pydocstyle = "^6.2.2"
pyflakes = "^3.0.1"
rope = "^1.3.0"
ruff = "^0.2.1"
python-lsp-black = "^1.2.1"
black = "^22.10.0"
types-aiofiles = "^22.1.0.2"
wrapt = "^1.14.1"
pydocstyle = "^6.2.2"
dill = "^0.3.6"
python-lsp-ruff = "^2.1.0"
python-lsp-server = "^1.7.1"
autopep8 = "^2.0.1"
pyflakes = "^3.0.1"
yapf = "^0.32.0"
whatthepatch = "^1.0.4"
mypy = "^1.0.0"
icecream = "^2.1.3"
types-sqlalchemy-utils = "^1.0.1"
types-pyyaml = "^6.0.12.9"
types-tqdm = "^4.65.0.1"
whatthepatch = "^1.0.4"
yapf = "^0.32.0"
sqlalchemy = "^2.0.26"
[tool.mypy]
plugins = "sqlalchemy.ext.mypy.plugin"
exclude = ['docker', 'docs']
strict = true
[tool.black]
target-version = ['py311']

View File

@@ -30,7 +30,7 @@
"@stitches/core": "^1.2.8",
"date-fns": "^2.29.3",
"matrix-widget-api": "^1.1.1",
"ol": "^7.3.0",
"ol": "^8.2.0",
"solid-js": "^1.6.6",
"solid-transition-group": "^0.0.10",
"solidjs-lazily": "^0.1.2"

View File

@@ -41,57 +41,13 @@ export const Map: ParentComponent<{}> = () => {
// TODO: Set padding according to the marker design.
const fitPointsPadding = [50, 50, 50, 50];
let mapDiv: HTMLDivElement | undefined;
let popup: StopPopup | undefined = undefined;
const [mapRef, setMapRef] = createSignal<HTMLDivElement>();
const stopVectorSource = new OlVectorSource({ features: [] });
const stopVectorLayer = new OlVectorLayer({ source: stopVectorSource });
let overlay: OlOverlay | undefined = undefined;
let map: OlMap | undefined = undefined;
const displayedFeatures: Record<number, OlFeature> = {};
const buildMap = (div: HTMLDivElement): void => {
overlay = new OlOverlay({
element: popup,
autoPan: {
animation: {
duration: 250,
},
},
});
map = new OlMap({
target: div,
controls: [], // remove controls
view: new OlView({
center: mapCenter,
zoom: 10,
}),
layers: [
new OlTileLayer({
source: new OlOSM(),
}),
stopVectorLayer,
],
overlays: [overlay],
});
console.log("map=", map);
map.on('singleclick', onClickedMap);
}
const onClickedMap = async (event): Promise<void> => {
const features = await stopVectorLayer.getFeatures(event.pixel);
// Handle only the first feature
if (features.length > 0) {
await onClickedFeature(features[0]);
}
else {
setPopupDisplayed(false);
setSelectedMapStop(undefined);
}
}
const onClickedFeature = async (feature: OlFeatureLike): Promise<void> => {
const stopId: number = feature.getId();
const stop = getStop(stopId);
@@ -109,10 +65,48 @@ export const Map: ParentComponent<{}> = () => {
}
}
onMount(() => {
buildMap(mapDiv);
})
;
const onClickedMap = async (event): Promise<void> => {
const features = await stopVectorLayer.getFeatures(event.pixel);
// Handle only the first feature
if (features.length > 0) {
await onClickedFeature(features[0]);
}
else {
setPopupDisplayed(false);
setSelectedMapStop(undefined);
}
}
const displayedFeatures: Record<number, OlFeature> = {};
const overlay = new OlOverlay({
element: popup,
autoPan: {
animation: {
duration: 250,
},
},
});
const map = new OlMap({
target: "map",
controls: [], // remove controls
view: new OlView({
center: mapCenter,
zoom: 10,
}),
layers: [
new OlTileLayer({
source: new OlOSM(),
}),
stopVectorLayer,
],
overlays: [overlay],
});
map.on('singleclick', onClickedMap);
createEffect(() => {
map.setTarget(mapRef());
});
// Filling the map with stops shape
createEffect(() => {
@@ -211,7 +205,7 @@ export const Map: ParentComponent<{}> = () => {
}
return <>
<div ref={mapDiv!} class="map">
<div ref={setMapRef!} class="map">
<StopPopup ref={popup!} stop={selectedMapStop()} show={isPopupDisplayed()} />
</div>
<For each={getFoundStops()}>{(stop) => <MapStop stop={stop} selected={selectedMapStop()} />}</For>