No description
  • Python 98.8%
  • Dockerfile 1.2%
Find a file
Erick Ruiz de Chavez 8ff95633a4 Update README, pyproject, and compose for Station mirroring
Rewrites README to document Station setup (cert/key, env vars) and
removes all tinylog/feed/SYNC_SINCE references. Updates pyproject
description and adds commented cert mount example to compose.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 12:03:49 +00:00
.env.example update outdated files (more updates to come) 2026-06-08 08:00:00 -04:00
.gitignore Initial implementation of GTS → Gemini tinylog generator 2026-05-16 07:13:28 -04:00
.python-version Initial implementation of GTS → Gemini tinylog generator 2026-05-16 07:13:28 -04:00
CLAUDE.md Replace tinylog with Station (Gemini social network) mirroring 2026-06-08 11:20:51 +00:00
compose.yml Update README, pyproject, and compose for Station mirroring 2026-06-08 12:03:49 +00:00
db.py Replace tinylog with Station (Gemini social network) mirroring 2026-06-08 11:20:51 +00:00
Dockerfile fix user permissions 2026-05-24 10:06:17 -04:00
gts.py Replace tinylog with Station (Gemini social network) mirroring 2026-06-08 11:20:51 +00:00
main.py Replace tinylog with Station (Gemini social network) mirroring 2026-06-08 11:20:51 +00:00
pyproject.toml Update README, pyproject, and compose for Station mirroring 2026-06-08 12:03:49 +00:00
README.md Update README, pyproject, and compose for Station mirroring 2026-06-08 12:03:49 +00:00
station.py Replace tinylog with Station (Gemini social network) mirroring 2026-06-08 11:20:51 +00:00
uv.lock Initial implementation of GTS → Gemini tinylog generator 2026-05-16 07:13:28 -04:00

tinylog

Mirrors public posts from a GoToSocial instance to Station, a Gemini-protocol social network, in real time. Handles new posts, self-reply threads, edits, and deletes.

Features

  • Real-time streaming via GoToSocial WebSocket API (no polling)
  • Propagates edits and deletes to Station
  • Self-replies posted as Station replies on the parent post
  • HTML-to-gemtext conversion: lists, preformatted blocks, footnote-style links
  • Media attachments appended as gemtext link lines
  • Long posts split into continuation self-replies to fit Station's 1024-byte URL limit
  • Skips posts with content warnings, replies to other accounts, non-public posts, local-only posts, and posts that mention other accounts

Setup

You need a Station account with a TLS client certificate. Export the certificate and private key from your Gemini browser as PEM files.

cp .env.example .env   # fill in the four required vars
docker compose up --build -d
docker compose logs -f

Mount your Station cert and key into the container via compose.yml:

volumes:
  - ./data:/app/data
  - /path/to/station.pem:/certs/station.pem:ro
  - /path/to/station.key:/certs/station.key:ro

Then set STATION_CERT_PATH=/certs/station.pem and STATION_KEY_PATH=/certs/station.key in .env.

Configuration

All configuration is via environment variables (.env):

Variable Required Default Description
GTS_BASE_URL yes Your GoToSocial instance URL
GTS_ACCESS_TOKEN yes OAuth bearer token with read scope
STATION_CERT_PATH yes Absolute path to your Station TLS client certificate (PEM)
STATION_KEY_PATH yes Absolute path to your Station TLS private key (PEM)
LOG_LEVEL no INFO DEBUG, INFO, WARNING, ERROR

Station integration is opt-in: if STATION_CERT_PATH or STATION_KEY_PATH are not set, the app runs without posting to Station (useful for testing the GTS connection).

GTS access token

Create an application on your GoToSocial instance and complete the OAuth flow to obtain a bearer token with read scope. No write scope is needed.

Station client certificate

Station uses TLS client certificates for authentication. Generate one in your Gemini browser (e.g. Lagrange or Amfora) when joining Station, then export the certificate and private key as separate PEM files.

Development

# Run locally (requires .env)
uv run python main.py

There are no automated tests in this project.