An ATProtocol powered blogging engine.
1# Blahg
2
3A Rust-based ATProtocol AppView for rendering personal blog content from the ATProtocol network.
4
5## Overview
6
7Blahg 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.
8
9## Features
10
11### Core Functionality
12- **Real-time Event Processing**: Consumes ATProtocol Jetstream events for live content updates
13- **Multi-Format Content Support**: Handles markdown, HTML, and plain text content
14- **Custom Lexicon Support**: Implements `tools.smokesignal.blahg.content.post` schema for rich blog posts
15- **Post Import Tool**: Command-line utility for importing individual posts via AT-URI
16- **Identity Resolution**: Automatic DID and handle resolution with caching
17- **Post Interactions**: Tracks likes, reposts, and other engagement metrics
18
19### Storage & Infrastructure
20- **Multi-Database Support**: Both PostgreSQL and SQLite backends supported
21- **Flexible Content Storage**: Filesystem and S3-compatible object storage
22- **Efficient Caching**: LRU caching for posts, identities, and content
23- **Template Engine**: Minijinja-based templating with hot-reload support during development
24- **Markdown Rendering**: Comrak-powered markdown with syntax highlighting
25
26### Web Interface
27- **Responsive Design**: Clean, accessible blog interface with Pico.css
28- **SEO Optimized**: Proper meta tags, OpenGraph support, and canonical URLs
29- **Post Interactions**: Display engagement metrics and interaction history
30- **Static Asset Serving**: Efficient static file serving with proper caching
31
32## Architecture
33
34Blahg consists of two main components:
35
361. **blahg**: The main server application that runs the web interface and processes real-time events
372. **blahg-import**: A command-line tool for importing individual posts from AT-URIs
38
39### Data Flow
401. ATProtocol events are consumed via Jetstream
412. Relevant records are filtered and processed
423. Post content and attachments are stored
434. Web interface serves rendered content with caching
44
45## Dependencies
46
47This project uses the following atproto crates:
48- `atproto-identity` - Identity resolution and verification
49- `atproto-record` - Record handling and parsing
50- `atproto-client` - ATProtocol client functionality
51- `atproto-jetstream` - Real-time event streaming
52
53## Installation
54
55### Prerequisites
56- Rust 1.87 or higher
57- Cargo
58- PostgreSQL or SQLite (depending on your database choice)
59
60### Building from Source
61
62```bash
63git clone https://github.com/yourusername/blahg.git
64cd blahg
65cargo build --release
66```
67
68### Docker
69
70```bash
71docker build -t blahg .
72docker run -p 8080:8080 blahg
73```
74
75## Usage
76
77### Running the Server
78
79```bash
80# Run with default configuration
81./target/release/blahg
82
83# Run with custom configuration via environment variables
84BLAHG_AUTHOR="did:plc:example" \
85BLAHG_DATABASE_URL="postgresql://user:pass@localhost/blahg" \
86BLAHG_ATTACHMENT_STORAGE="s3://your-bucket/attachments/" \
87./target/release/blahg
88```
89
90### Importing Posts
91
92```bash
93# Import a single post
94./target/release/blahg-import at://did:plc:example/tools.smokesignal.blahg.content.post/abc123
95
96# Import multiple posts
97./target/release/blahg-import \
98 at://did:plc:example/tools.smokesignal.blahg.content.post/abc123 \
99 at://did:plc:example/tools.smokesignal.blahg.content.post/def456
100```
101
102## Configuration
103
104Configuration is managed via environment variables:
105
106### Core Settings
107- `BLAHG_AUTHOR`: Your ATProtocol DID (required)
108- `BLAHG_EXTERNAL_BASE`: Base URL for your blog (default: `http://localhost:8080`)
109- `BLAHG_HTTP_PORT`: HTTP server port (default: `8080`)
110
111### Database
112- `BLAHG_DATABASE_URL`: Database connection string
113 - SQLite: `sqlite://blahg.db`
114 - PostgreSQL: `postgresql://user:pass@localhost/blahg`
115
116### Storage
117- `BLAHG_ATTACHMENT_STORAGE`: Content storage location
118 - Filesystem: `./attachments`
119 - S3: `s3://bucket/prefix/`
120
121### ATProtocol
122- `BLAHG_ENABLE_JETSTREAM`: Enable real-time event processing (default: `true`)
123- `BLAHG_JETSTREAM_CURSOR_PATH`: Path to store Jetstream cursor (optional)
124- `BLAHG_PLC_HOSTNAME`: PLC directory hostname (default: `plc.directory`)
125
126### HTTP Client
127- `BLAHG_USER_AGENT`: HTTP client user agent
128- `BLAHG_HTTP_CLIENT_TIMEOUT`: HTTP client timeout (default: `10s`)
129- `BLAHG_CERTIFICATE_BUNDLES`: Additional CA certificates (comma-separated paths)
130
131## Development
132
133### Feature Flags
134
135Blahg supports several feature flags for different deployment scenarios:
136
137- `sqlite`: Enable SQLite database support (default: enabled)
138- `postgres`: Enable PostgreSQL database support (default: enabled)
139- `s3`: Enable S3-compatible object storage (default: enabled)
140- `embed`: Embed templates in binary for production (default: disabled)
141- `reload`: Enable template hot-reloading for development (default: enabled)
142
143### Development Environment
144
145```bash
146# Run in development mode with hot-reloading
147cargo run
148
149# Run with specific features
150cargo run --no-default-features --features "sqlite,reload"
151```
152
153### Running Tests
154```bash
155cargo test
156```
157
158### Linting and Type Checking
159```bash
160cargo clippy
161cargo check
162```
163
164### Building for Production
165
166```bash
167# Build with embedded templates
168cargo build --release --no-default-features --features "embed,postgres,s3"
169```
170
171## API Endpoints
172
173Blahg provides a simple web interface with the following endpoints:
174
175- `GET /`: Homepage with list of all posts
176- `GET /posts/{slug}`: Individual post page
177- `GET /posts/{slug}/{collection}`: Post interaction references (likes, reposts, etc.)
178- `GET /static/*`: Static asset serving (CSS, JS, images)
179
180## ATProtocol Lexicon
181
182Blahg implements the `tools.smokesignal.blahg.content.post` lexicon for rich blog posts:
183
184```json
185{
186 "title": "string", // Post title (max 200 graphemes)
187 "content": "blob", // Post content (markdown/HTML/text, max 1MB)
188 "publishedAt": "datetime", // Publication timestamp
189 "langs": ["string"], // Language codes (max 3)
190 "attachments": [ // Optional image attachments
191 {
192 "content": "blob", // Image blob (max 3MB)
193 "alt": "string" // Alt text for accessibility
194 }
195 ]
196}
197```
198
199## Contributing
200
201Contributions are welcome! Please feel free to submit a Pull Request.
202
203## License
204
205Blahg is open source software released under the [MIT License](LICENSE).