An ATProtocol powered blogging engine.
Rust 94.8%
HTML 4.0%
Dockerfile 1.1%
8 1 0

Clone this repository

https://tangled.org/smokesignal.events/blahg
git@tangled.org:smokesignal.events/blahg

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Blahg#

A Rust-based ATProtocol AppView for rendering personal blog content from the ATProtocol network.

Overview#

Blahg is a high-performance blog engine that consumes ATProtocol records to create a traditional blog-like reading experience. It processes both custom blog post records (tools.smokesignal.blahg.content.post) and standard ATProtocol social media posts (app.bsky.feed.post), providing a unified interface for content discovery and presentation.

Features#

Core Functionality#

  • Real-time Event Processing: Consumes ATProtocol Jetstream events for live content updates
  • Multi-Format Content Support: Handles markdown, HTML, and plain text content
  • Custom Lexicon Support: Implements tools.smokesignal.blahg.content.post schema for rich blog posts
  • Post Import Tool: Command-line utility for importing individual posts via AT-URI
  • Identity Resolution: Automatic DID and handle resolution with caching
  • Post Interactions: Tracks likes, reposts, and other engagement metrics

Storage & Infrastructure#

  • Multi-Database Support: Both PostgreSQL and SQLite backends supported
  • Flexible Content Storage: Filesystem and S3-compatible object storage
  • Efficient Caching: LRU caching for posts, identities, and content
  • Template Engine: Minijinja-based templating with hot-reload support during development
  • Markdown Rendering: Comrak-powered markdown with syntax highlighting

Web Interface#

  • Responsive Design: Clean, accessible blog interface with Pico.css
  • SEO Optimized: Proper meta tags, OpenGraph support, and canonical URLs
  • Post Interactions: Display engagement metrics and interaction history
  • Static Asset Serving: Efficient static file serving with proper caching

Architecture#

Blahg consists of two main components:

  1. blahg: The main server application that runs the web interface and processes real-time events
  2. blahg-import: A command-line tool for importing individual posts from AT-URIs

Data Flow#

  1. ATProtocol events are consumed via Jetstream
  2. Relevant records are filtered and processed
  3. Post content and attachments are stored
  4. Web interface serves rendered content with caching

Dependencies#

This project uses the following atproto crates:

  • atproto-identity - Identity resolution and verification
  • atproto-record - Record handling and parsing
  • atproto-client - ATProtocol client functionality
  • atproto-jetstream - Real-time event streaming

Installation#

Prerequisites#

  • Rust 1.87 or higher
  • Cargo
  • PostgreSQL or SQLite (depending on your database choice)

Building from Source#

git clone https://github.com/yourusername/blahg.git
cd blahg
cargo build --release

Docker#

docker build -t blahg .
docker run -p 8080:8080 blahg

Usage#

Running the Server#

# Run with default configuration
./target/release/blahg

# Run with custom configuration via environment variables
BLAHG_AUTHOR="did:plc:example" \
BLAHG_DATABASE_URL="postgresql://user:pass@localhost/blahg" \
BLAHG_ATTACHMENT_STORAGE="s3://your-bucket/attachments/" \
./target/release/blahg

Importing Posts#

# Import a single post
./target/release/blahg-import at://did:plc:example/tools.smokesignal.blahg.content.post/abc123

# Import multiple posts
./target/release/blahg-import \
  at://did:plc:example/tools.smokesignal.blahg.content.post/abc123 \
  at://did:plc:example/tools.smokesignal.blahg.content.post/def456

Configuration#

Configuration is managed via environment variables:

Core Settings#

  • BLAHG_AUTHOR: Your ATProtocol DID (required)
  • BLAHG_EXTERNAL_BASE: Base URL for your blog (default: http://localhost:8080)
  • BLAHG_HTTP_PORT: HTTP server port (default: 8080)

Database#

  • BLAHG_DATABASE_URL: Database connection string
    • SQLite: sqlite://blahg.db
    • PostgreSQL: postgresql://user:pass@localhost/blahg

Storage#

  • BLAHG_ATTACHMENT_STORAGE: Content storage location
    • Filesystem: ./attachments
    • S3: s3://bucket/prefix/

ATProtocol#

  • BLAHG_ENABLE_JETSTREAM: Enable real-time event processing (default: true)
  • BLAHG_JETSTREAM_CURSOR_PATH: Path to store Jetstream cursor (optional)
  • BLAHG_PLC_HOSTNAME: PLC directory hostname (default: plc.directory)

HTTP Client#

  • BLAHG_USER_AGENT: HTTP client user agent
  • BLAHG_HTTP_CLIENT_TIMEOUT: HTTP client timeout (default: 10s)
  • BLAHG_CERTIFICATE_BUNDLES: Additional CA certificates (comma-separated paths)

Development#

Feature Flags#

Blahg supports several feature flags for different deployment scenarios:

  • sqlite: Enable SQLite database support (default: enabled)
  • postgres: Enable PostgreSQL database support (default: enabled)
  • s3: Enable S3-compatible object storage (default: enabled)
  • embed: Embed templates in binary for production (default: disabled)
  • reload: Enable template hot-reloading for development (default: enabled)

Development Environment#

# Run in development mode with hot-reloading
cargo run

# Run with specific features
cargo run --no-default-features --features "sqlite,reload"

Running Tests#

cargo test

Linting and Type Checking#

cargo clippy
cargo check

Building for Production#

# Build with embedded templates
cargo build --release --no-default-features --features "embed,postgres,s3"

API Endpoints#

Blahg provides a simple web interface with the following endpoints:

  • GET /: Homepage with list of all posts
  • GET /posts/{slug}: Individual post page
  • GET /posts/{slug}/{collection}: Post interaction references (likes, reposts, etc.)
  • GET /static/*: Static asset serving (CSS, JS, images)

ATProtocol Lexicon#

Blahg implements the tools.smokesignal.blahg.content.post lexicon for rich blog posts:

{
  "title": "string",           // Post title (max 200 graphemes)
  "content": "blob",          // Post content (markdown/HTML/text, max 1MB)
  "publishedAt": "datetime",  // Publication timestamp
  "langs": ["string"],        // Language codes (max 3)
  "attachments": [            // Optional image attachments
    {
      "content": "blob",      // Image blob (max 3MB)
      "alt": "string"         // Alt text for accessibility
    }
  ]
}

Contributing#

Contributions are welcome! Please feel free to submit a Pull Request.

License#

Blahg is open source software released under the MIT License.