1
0
mirror of https://codeberg.org/diginaut/digimarks.git synced 2026-02-04 11:30:27 +01:00

4 Commits

4 changed files with 34 additions and 12 deletions

View File

@@ -10,7 +10,7 @@ authors = [
] ]
description = 'Simple bookmarking service, using a SQLite database to store bookmarks, supporting tags, automatic title fetching and REST API calls.' description = 'Simple bookmarking service, using a SQLite database to store bookmarks, supporting tags, automatic title fetching and REST API calls.'
readme = "README.rst" readme = "README.rst"
requires-python = ">=3.10" requires-python = ">=3.11"
keywords = ["bookmarks", "api"] keywords = ["bookmarks", "api"]
license = { text = "Apache" } license = { text = "Apache" }
classifiers = [ classifiers = [

View File

@@ -1,7 +1,7 @@
# Core application # Core application
fastapi[all] fastapi[all]
sqlmodel sqlmodel
sqlalchemy sqlalchemy[asyncio]
pydantic pydantic
pydantic_settings pydantic_settings
alembic alembic

View File

@@ -4,7 +4,7 @@ import logging
from collections.abc import Sequence from collections.abc import Sequence
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from datetime import UTC, datetime from datetime import UTC, datetime
from typing import Annotated from typing import Annotated, AsyncGenerator, cast
import httpx import httpx
from fastapi import Depends, FastAPI, HTTPException, Query, Request from fastapi import Depends, FastAPI, HTTPException, Query, Request
@@ -54,22 +54,32 @@ engine = create_async_engine(f'sqlite+aiosqlite:///{settings.database_file}', co
async def get_session() -> AsyncSession: async def get_session() -> AsyncSession:
"""SQLAlchemy session factory.""" """SQLAlchemy session factory."""
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) async_session = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
async with async_session() as session: async with async_session() as session:
yield session yield session
# Shorter way of getting the DB session in an endpoint
SessionDep = Annotated[AsyncSession, Depends(get_session)] SessionDep = Annotated[AsyncSession, Depends(get_session)]
@asynccontextmanager @asynccontextmanager
async def lifespan(the_app: FastAPI): async def lifespan(the_app: FastAPI) -> AsyncGenerator[None, None]:
"""Upon start, initialise an AsyncClient and assign it to an attribute named requests_client on the app object.""" """Upon start, initialise an AsyncClient and assign it to an attribute named requests_client on the app object."""
the_app.requests_client = httpx.AsyncClient() async with httpx.AsyncClient() as requests_client:
the_app.state.requests_client = requests_client
yield yield
await the_app.requests_client.aclose() await the_app.state.requests_client.aclose()
async def get_requests_client(request: Request) -> httpx.AsyncClient:
"""Get the httpx client from the application object."""
return cast(httpx.AsyncClient, request.app.state.requests_client)
# Shorter way of getting the httpx client in an endpoint
RequestsDep = Annotated[AsyncSession, Depends(get_requests_client)]
app = FastAPI(lifespan=lifespan) app = FastAPI(lifespan=lifespan)
app.mount('/static', StaticFiles(directory=settings.static_dir), name='static') app.mount('/static', StaticFiles(directory=settings.static_dir), name='static')
app.mount('/content/favicons', StaticFiles(directory=settings.favicons_dir), name='favicons') app.mount('/content/favicons', StaticFiles(directory=settings.favicons_dir), name='favicons')
@@ -275,12 +285,24 @@ async def bookmarks_changed_since(
) )
latest_created_bookmark = result.first() latest_created_bookmark = result.first()
latest_modification = max(latest_modified_bookmark.modified_date, latest_created_bookmark.created_date) # There needs to be at least one bookmark of course
if latest_created_bookmark:
latest_created_datetime = latest_created_bookmark.created_date
else:
latest_created_datetime = datetime.min
# We only have a modified datetime when at least one has been edited
if latest_modified_bookmark:
latest_modified_datetime = latest_modified_bookmark.modified_date
else:
latest_modified_datetime = datetime.min
latest_modification = max(latest_modified_datetime, latest_created_datetime)
return { return {
'current_time': datetime.now(UTC), 'current_time': datetime.now(UTC),
'latest_change': latest_modified_bookmark.modified_date, 'latest_change': latest_modified_datetime,
'latest_created': latest_created_bookmark.created_date, 'latest_created': latest_created_datetime,
'latest_modification': latest_modification, 'latest_modification': latest_modification,
} }

View File

@@ -105,7 +105,7 @@ document.addEventListener('alpine:init', () => {
this.cache[this.userKey]['tags'] = await tagsResponse.json(); this.cache[this.userKey]['tags'] = await tagsResponse.json();
/* Filter bookmarks by (blacklisted) tags */ /* Filter bookmarks by (blacklisted) tags */
await this.filterBookmarksByTags(); this.filterBookmarksByTags();
this.loading = false; this.loading = false;
}, },