Dockerized selfhosted local poem editor app https://wiersze.rplawski.pl
  • TypeScript 48.2%
  • Python 47.5%
  • HTML 2.7%
  • Dockerfile 1.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Robert Pławski 475ae8ffa6
All checks were successful
forgejo-registry / build-and-push (push) Successful in 5s
forgejo-registry / tests (push) Successful in 3m36s
fix: install httpx required by the starlette test client
2026-10-19 19:14:37 +02:00
.forgejo/workflows ci: run tests and frontend build before publishing 2026-10-19 19:08:56 +02:00
frontend feat: rename file when poem title changes 2026-10-19 19:08:09 +02:00
templates feat: added pwa support and google oauth login with yml config 2026-10-18 22:46:54 +02:00
tests test: add API test suite 2026-10-19 19:08:42 +02:00
.dockerignore ci: run tests and frontend build before publishing 2026-10-19 19:08:56 +02:00
.gitignore test: add API test suite 2026-10-19 19:08:42 +02:00
config.example.yml feat: create poems from a title with configurable footer 2026-10-19 19:07:46 +02:00
docker-compose.yml feat: added pwa support and google oauth login with yml config 2026-10-18 22:46:54 +02:00
Dockerfile Minor dockerfile changes 2025-09-23 17:57:52 +02:00
main.py fix: serve API when frontend build is missing 2026-10-19 19:08:23 +02:00
README.md test: add API test suite 2026-10-19 19:08:42 +02:00
requirements-dev.txt fix: install httpx required by the starlette test client 2026-10-19 19:14:37 +02:00
requirements.txt feat: added pwa support and google oauth login with yml config 2026-10-18 22:46:54 +02:00

Poemata Editor

A lightweight web application for managing text files with a RESTful API and web interface. Built with FastAPI and React (using Vite as the bundler).

Features

  • Web-based file management interface
  • RESTful API for file operations
  • File preview functionality with customizable templates
  • Search and filter capabilities
  • Responsive design

Project Structure

.
├── main.py              # FastAPI application
├── requirements.txt     # Python dependencies
├── storage/             # Directory for storing text files (created automatically)
├── templates/           # HTML templates for file preview
├── frontend/            # React frontend application (using Vite)
│   ├── dist/            # Built frontend files
│   ├── src/             # Source code
│   └── package.json     # Node.js dependencies
└── README.md            # This file

API Endpoints

File Management

  • GET /api/files/ - List all files (with optional search query)
  • GET /api/files/{filepath} - Read a file
  • POST /api/poems - Create a poem from a title (filename is derived from it)
  • POST /api/files/{filepath} - Create a new file
  • PUT /api/files/{filepath} - Update an existing file
  • DELETE /api/files/{filepath} - Delete a file

File Preview

  • GET /api/preview/{filepath}?template={template} - Preview a file using a specific HTML template

Authentication

  • GET /api/me - Session info (auth_enabled, email)
  • GET /auth/login - Start OAuth login
  • GET /auth/callback - OAuth callback (configure this URL with the provider)
  • GET /auth/logout - Sign out

Web Interface

  • GET / - Main web application

Authentication

OAuth login is configured in config.yml (copy from config.example.yml). Only emails listed in oauth.allowed_emails may sign in. Without a filled-in config.yml the app runs without login.

secret_key: "<random string>"   # python -c "import secrets; print(secrets.token_urlsafe(32))"
base_url: "https://poemata.example.com"
oauth:
  provider: google              # "google" or "github"
  client_id: "..."
  client_secret: "..."
  allowed_emails:
    - someone@example.com
  1. Create an OAuth app with the provider, using {base_url}/auth/callback as the redirect URI
  2. Set base_url when running behind a proxy so redirects use the public URL
  3. All /api endpoints require login once config.yml is filled in

config.yml is gitignored. A custom path can be set with POEMATA_CONFIG; docker-compose.yml mounts config.yml into the container.

Getting Started

Prerequisites

  • Python 3.8+
  • Node.js (for frontend development)

Installation

  1. Clone the repository
  2. Install Python dependencies:
    pip install -r requirements.txt
    
  3. Run the application:
    uvicorn main:app --reload
    

Frontend Development

The frontend is built with React and Vite:

  1. Navigate to the frontend directory:
    cd frontend
    
  2. Install dependencies:
    npm install
    
  3. Start the development server:
    npm run dev
    
  4. Build for production:
    npm run build
    

Tests

Backend API tests live in tests/ and use pytest:

pip install -r requirements-dev.txt
python -m pytest

The CI workflow (.forgejo/workflows/docker-publish.yml) runs the tests and a production frontend build before the Docker image is built and pushed, so a failing test blocks the image.

Docker Deployment

The application includes a multi-stage Dockerfile that:

  1. Builds the React frontend using Node.js
  2. Serves the FastAPI backend with the built frontend

To run with Docker:

docker build -t poemata-editor .
docker run -p 8000:8000 poemata-editor

Or use docker-compose:

docker-compose up

Usage

  1. Access the web interface at http://localhost:8000
  2. Use the API endpoints to manage files programmatically
  3. Preview files using the /api/preview endpoint with appropriate templates

File Format

Text files should follow this structure:

  • First line: Title
  • Middle lines: Content
  • Last line: Footer/Author information

New poems are created from a title: the title becomes the first line, the filename is derived from it, and the footer is filled in from the optional footer section of config.yml at creation time (so dates stay fixed):

footer:
  template: "{authorname} {city} {date}"
  author: "Jan Kowalski"
  city: "Warszawa"
  date_format: "%m.%d.%Y"

Placeholders: {author}/{authorname}, {city}, {date}/{date.now} (the date can also be formatted inline, e.g. {date:%d.%m.%Y}). Without a footer configuration the last line defaults to Stopka. Poems sharing a title are listed as Title (1), Title (2), ...

Templates

HTML templates in the templates/ directory can be used to preview files with different styling. The template receives:

  • title: First line of the file
  • content: Array of middle lines
  • footer: Last line of the file

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a pull request

License

This project is licensed under the MIT License.