Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add pages in footer & about page #343

Merged
merged 1 commit into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ db.sqlite3
db.sqlite
storage/
!storage/.gitkeep
data/
!data/pages/.gitkeep
.pdm.toml
Empty file added backend/data/pages/.gitkeep
Empty file.
68 changes: 68 additions & 0 deletions backend/openapi-schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,22 @@ components:
- languages
title: ModelConfig
type: object
PageConfig:
properties:
footer_position:
title: Footer Position
type: integer
name:
title: Name
type: string
text:
title: Text
type: string
required:
- name
- text
title: PageConfig
type: object
PublicConfig:
properties:
models:
Expand All @@ -379,6 +395,18 @@ components:
- duration
title: SetDurationRequest
type: object
ShortPageConfig:
properties:
footer_position:
title: Footer Position
type: integer
name:
title: Name
type: string
required:
- name
title: ShortPageConfig
type: object
SpeakerIdentificationTask:
properties:
document_id:
Expand Down Expand Up @@ -993,6 +1021,46 @@ paths:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Get Document Tasks
/api/v1/page/:
get:
operationId: get_pages_api_v1_page__get
responses:
'200':
content:
application/json:
schema:
additionalProperties:
$ref: '#/components/schemas/ShortPageConfig'
title: Response Get Pages Api V1 Page Get
type: object
description: Successful Response
summary: Get Pages
/api/v1/page/{page_id}:
get:
operationId: get_page_api_v1_page__page_id__get
parameters:
- in: path
name: page_id
required: true
schema:
title: Page Id
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PageConfig'
description: Successful Response
'404':
description: Page not found
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
summary: Get Page
/api/v1/tasks/:
get:
operationId: list_tasks_api_v1_tasks__get
Expand Down
18 changes: 17 additions & 1 deletion backend/pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies = [
"websockets>=10.4",
"python-magic>=0.4.27",
"transcribee-proto @ file:///${PROJECT_ROOT}/../proto",
"python-frontmatter>=1.0.0",
]
requires-python = ">=3.10"
readme = "./README.md"
Expand Down
43 changes: 40 additions & 3 deletions backend/transcribee_backend/config.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from pathlib import Path
from typing import Dict, List
from typing import Dict, List, Optional

from pydantic import BaseSettings, parse_file_as
from pydantic.main import BaseModel
import frontmatter
from pydantic import BaseModel, BaseSettings, parse_file_as, parse_obj_as

pages = None


class Settings(BaseSettings):
Expand All @@ -15,6 +17,7 @@ class Settings(BaseSettings):
media_url_base = "http://localhost:8000/"

model_config_path: Path = Path("data/models.json")
pages_dir: Path = Path("data/pages/")


class ModelConfig(BaseModel):
Expand All @@ -27,10 +30,44 @@ class PublicConfig(BaseModel):
models: Dict[str, ModelConfig]


class ShortPageConfig(BaseModel):
name: str
footer_position: Optional[int]


class PageConfig(ShortPageConfig):
text: str


def get_model_config():
return parse_file_as(Dict[str, ModelConfig], settings.model_config_path)


def load_pages_from_disk() -> Dict[str, PageConfig]:
global pages
if pages is None:
pages = {}
if settings.pages_dir.exists():
for file in settings.pages_dir.glob("*.md"):
page_id = file.stem
page = frontmatter.load(file)
pages[page_id] = PageConfig(
name=page.metadata.get("name", file.stem),
footer_position=page.metadata.get("footer_position"),
text=page.content,
)

return pages


def get_page_config():
return load_pages_from_disk()


def get_short_page_config() -> Dict[str, ShortPageConfig]:
return parse_obj_as(Dict[str, ShortPageConfig], get_page_config())


def get_public_config():
return PublicConfig(models=get_model_config())

Expand Down
2 changes: 2 additions & 0 deletions backend/transcribee_backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from transcribee_backend.helpers.tasks import remove_expired_tokens, timeout_attempts
from transcribee_backend.routers.config import config_router
from transcribee_backend.routers.document import document_router
from transcribee_backend.routers.page import page_router
from transcribee_backend.routers.task import task_router
from transcribee_backend.routers.user import user_router

Expand All @@ -30,6 +31,7 @@
app.include_router(document_router, prefix="/api/v1/documents")
app.include_router(task_router, prefix="/api/v1/tasks")
app.include_router(config_router, prefix="/api/v1/config")
app.include_router(page_router, prefix="/api/v1/page")


@app.get("/")
Expand Down
25 changes: 25 additions & 0 deletions backend/transcribee_backend/routers/page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Dict

from fastapi import APIRouter, HTTPException

from transcribee_backend.config import (
PageConfig,
ShortPageConfig,
get_page_config,
get_short_page_config,
)

page_router = APIRouter()


@page_router.get("/")
def get_pages() -> Dict[str, ShortPageConfig]:
return get_short_page_config()


@page_router.get("/{page_id}", responses={404: {"description": "Page not found"}})
def get_page(page_id: str) -> PageConfig:
pages = get_page_config()
if page_id not in pages:
raise HTTPException(status_code=404)
return pages[page_id]
21 changes: 21 additions & 0 deletions doc/development_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ If you do more development on transcribee, you may wish to do the following thin
- Install the [`pre-commit`](https://pre-commit.com/) hook so that your changes are automatically
linted before you commit them. Run: `pre-commit install`
## Add pages
`transcribee` contains a minimal page system.
To add pages, add a markdown file to `backend/data/pages`.
If the file contains a frontmatter with the `footer_position` attribute, the page is shown in the footer.
To modify the name shown in the footer, set the `name` attribute in the frontmatter.
Example file named `example.md`:
```md
---
footer_position: 1
name: Example Page
---
# Example Page Showing The Page Feature
Lorem Ipsum Dolor Sit Amet....
```
This page would be available at `/pages/example.md` and shown in the footer with a link labelled `Example Page`.
## More!
There are more specific instructions in the respective readme files of the
Expand Down
2 changes: 2 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ node_modules

# typescript
*.tsbuildinfo

public/LICENSES.md
7 changes: 6 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"version": "0.1.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"build": "npm-run-all --continue-on-error build:*",
"build:licenses": "node scripts/generate_licenses.mjs public/LICENSES.md",
"build:vite": "vite build",
"preview": "vite preview",
"format": "prettier -w 'src/**/*.(ts|tsx)'",
"check": "npm-run-all --continue-on-error check:*",
Expand All @@ -29,6 +31,7 @@
"devDependencies": {
"@jest/globals": "^29.5.0",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/typography": "^0.5.9",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/react-helmet": "^6.1.6",
Expand All @@ -43,6 +46,7 @@
"favicons": "^7.1.3",
"jest": "^29.5.0",
"mime-types": "^2.1.35",
"nlf": "^2.1.1",
"npm-run-all": "^4.1.5",
"openapi-typescript": "^6.2.0",
"postcss": "^8.4.21",
Expand All @@ -69,6 +73,7 @@
"react-icons": "^4.8.0",
"react-intersection-observer": "^9.5.2",
"react-json-tree": "^0.18.0",
"react-markdown": "^8.0.7",
"react-popper": "^2.3.0",
"reconnecting-websocket": "^4.4.0",
"slate": "^0.94.0",
Expand Down
Loading