This repository contains a web application for managing the Lojban dictionary/corpus and searching Lojban mailing list emails. It consists of a Rust backend API and a Vue.js frontend.
- Docker
- Docker Compose
- Clone this repository:
git clone https://github.com/lojban/lensisku.git cd lensisku - Copy .env.example to .env:
cp .env.example .env
Pay attention for MAILDIR_PATH variable in .env
Build and run the Docker container from the root of the cloned repository:
docker compose up --build
Or run in detached mode:
docker compose up -d --build
This will start the application along with all required services (database, infinity, etc.), and it will be accessible at http://localhost:8051.
Required environment variables (set in your .env file):
JWT_SECRET- Secret key for JWT tokensDB_USER- PostgreSQL usernameDB_PASSWORD- PostgreSQL passwordDB_NAME- PostgreSQL database nameDB_PORT- PostgreSQL port (defaults to 5432)MAILDIR_PATH- Path to maildir directory
Optional (local development):
DISABLE_EMBEDDINGS=1(ortrue/yes) - Skip loading the embedding model and all embedding computation; semantic search returns 503 with a message, and the background embedding job no-ops
The Makefile provides convenient commands for managing the Docker environment:
# Start the development environment
make up
# Rebuild Docker images
make build
# View logs from all containers
make logs
# List running containers
make ps
# Stop services
make down
# Clean up (remove containers and volumes)
make cleanIf you want to build and run the Dockerfile directly without docker-compose:
# Build the image
docker build -t lenisku:latest .
# Run the container
docker run -d \
-p 8051:80 \
-e DATABASE_URL=postgres://lojban:password@host.docker.internal/lojban_lens \
-e JWT_SECRET=your-secret-key \
-v ./maildir:/usr/src/app/maildir:ro \
lenisku:latestNote: When using direct Docker commands, you'll need to ensure:
- A PostgreSQL database is available and accessible
- The
DATABASE_URLenvironment variable points to your database - The maildir volume is properly mounted
- All required environment variables are set
# Build the image
podman build -t mail_archive_app .
# Create and run the container
podman run -d \
--name mail_archive_app \
-p 8051:80 \
-v ./mail_archive.db:/usr/src/app/mail_archive.db:Z \
-e DATABASE_URL=sqlite:///usr/src/app/mail_archive.db \
--restart unless-stopped \
mail_archive_app
Setup autoreturn
Go to your Account Settings. Click Website payments. Click Update across from "Website preferences." Click On under "Auto Return." In the Return URL field, enter the URL where you want to send your buyer after the payment. The Return URL is applied to all Auto Return payments unless otherwise specified within the payment button or link. Click Save.
Frontend developers should follow these steps to implement PayPal balance top-up:
-
Create a payment form with:
- Amount input (minimum $0.50)
- Currency selector (only USD supported)
- PayPal payment button
-
When user submits form:
- Call POST /payments with payload:
{ "provider": "paypal", "amount_cents": 10000, // Amount in cents (e.g. $100.00 = 10000 cents) "currency": "USD" // Must be "USD" } - Handle response:
{ "payment_id": "PAYPAL-ORDER-ID", "redirect_url": "https://www.paypal.com/checkout/ORDER-ID" }
- Call POST /payments with payload:
-
Redirect user to the returned redirect_url
-
Handle payment completion:
- Option 1: Listen for websocket events on /ws/payments
- Option 2: Poll GET /payments/balance periodically
- Update UI with new balance when payment succeeds
-
Required environment variables:
- PAYPAL_CLIENT_ID: Your PayPal client ID
- PAYPAL_CLIENT_SECRET: Your PayPal client secret
- PAYPAL_SANDBOX_MODE: Set to "true" for testing, "false" for production
Example frontend code:
async function createPayPalPayment(amountCents) {
const response = await fetch('/payments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${userToken}`
},
body: JSON.stringify({
provider: 'paypal',
amount_cents: amountCents,
currency: 'USD'
})
});
const data = await response.json();
if (response.ok) {
window.location.href = data.redirect_url;
} else {
alert(`Payment failed: ${data.message}`);
}
}To test Stripe, you'll need to:
- Set up Stripe CLI to forward webhooks to your local development server:
stripe listen --forward-to localhost:8080/payments/webhook
- Trigger test webhooks:
stripe trigger payment_intent.succeeded
stripe trigger payment_intent.payment_failed
The webhook handler will verify the signature using your webhook secret, then process the payment events accordingly. Successful payments will update both the payment status and user balance, while failed payments will only update the payment status.
src/: Contains the Rust backend codefrontend/: Contains the Vue.js frontend codeDockerfile: Defines the Docker image for the applicationdocker-compose.yml: Defines the Docker Compose configuration
For building lensisku for hosting on the actual lojban.org infrastructure, see building/README.txt
To develop the application locally:
-
Pre-install libs. For Ubuntu/Debian, run:
sudo apt-get update && sudo apt-get install -y \ build-essential \ libharfbuzz-dev \ libfreetype6-dev \ libfontconfig1-dev \ libicu-dev \ zlib1g-dev \ pkg-config \ texlive-xetex \ texlive-fonts-recommended \ texlive-fonts-extra \ texlive-latex-extra \ texlive-lang-chinese \ texlive-lang-japanese \ fonts-noto-cjk fonts-noto-cjk-extra \ fonts-linuxlibertineFor Fedora/RHEL:
sudo dnf install -y \ @development-tools \ harfbuzz-devel \ freetype-devel \ fontconfig-devel \ libicu-devel \ zlib-devel \ pkg-config \ texlive-xetex \ texlive-collection-fontsrecommended \ texlive-collection-fontsextra \ texlive-collection-latexextra \ texlive-collection-langchinese \ texlive-collection-langjapanese \ google-noto-cjk-fonts \ linux-libertine-fonts -
For the backend:
docker compose -f ./docker-compose.dev.yml up -dBefore running database migrations (which
make backwill do for you), you need to import the baselojban_lensdatabase dump so that migrations can run on top of it.From the project root, with the Postgres container (usually named
lenpostgres) running, and using the default database namelojban_lensfrom.env.example:# Copy the dump into the Postgres container docker cp dump/jbocma.sql lenpostgres:/tmp/jbocma.sql # Import it into the target database (uses lojban_lens by default) docker exec -it lenpostgres \ psql -U "$DB_USER" -d "$DB_NAME" \ -f /tmp/jbocma.sql
Once the dump has been imported, you can run:
make back
-
For the frontend:
cd frontend && pnpm i && cd .. make frontThen access the frontend at http://localhost:5173/
API documentation is available at http://localhost:8080/swagger-ui/ when the application is running.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.