Skip to content

A custom feed generator server with a docker PostgreSQL database for Bluesky posts relating to the Cosmere by Brandon Sanderson.

License

Notifications You must be signed in to change notification settings

richardr1126/cosmere-feed-bsky

Repository files navigation

🌟 Cosmere ATProto Feed Generator 🌎

ATProtocol PostgreSQL Python Flask Gunicorn License

πŸ“– Overview

A specialized feed service for Brandon Sanderson's Cosmere universe fans, powered by the AT Protocol SDK for Python. This service intelligently filters and combines trending and chronological posts to deliver a curated Cosmere content stream.

πŸ’« Built upon the original Python feed generator by @MarshalX.

✨ Features

Core Capabilities

  • πŸ” Smart Filtering with advanced regexp:

    • ⚑ Individual keywords (with automatic plural forms)
    • πŸ”„ Multi-word tokens (order-independent matching)
    • πŸ“ Exact phrase matching
    • πŸ‘€ Specific handle inclusion
  • 🐘 PostgreSQL Database

    • 🐳 Docker containerization
    • πŸ’Ύ Persistent data storage
  • πŸ“ˆ Trending Posts Integration

    • βš–οΈ Interaction score calculation
    • 🧹 Automated database cleanup via apscheduler
  • 🐳 Docker Compose Deployment

    • πŸ”„ Orchestrates web, firehose, and postgres services

⚠️ Note: Posts are retained for 30 days, with trending calculations based on 24-hour interaction windows

🎯 Filters

πŸ”€ Tokens

  • allomancy, bondsmith, cosmere, dalinar, dawnshard, dragonsteel, dustbringer, edgedancer, elantris, elsecaller, stormblessed, thaidakar, kholin, lightweaver, mistborn, oathbringer, sanderlanche, sazed, shadesmar, skybreaker, spren, stoneward, stormlight, surgebinding, truthwatcher, warbreaker, willshaper, windrunner, roshar, scadrial, taldain, voidbringer, shardblade, shardplate, shardbearer, feruchemy, hemalurgy, lerasium, atium, mistcloak, kandra, koloss, skaa, highstorm, parshendi, urithiru, honorblade, surgebinder, dawnshard, worldhopper, perpendicularity, adonalsium, chasmfiend, worldbringer, allomancer, highspren, elantrian, inkspren, honorspren, cultivationspren, peakspren, ashspren, luckspren, windspren, lifespren, towerlight, voidlight, brandosando, numuhukumakiaki'ialunamor, dsnx24, dsnx2024, dragonsteelnexus, dragonsteelnexus2024

πŸ”— Inclusive Multi-Tokens

  • brandon sanderson, yumi sanderson, vin elend, yumi painter, shallan adolin, kaladin syl, kaladin adolin, kaladin shallan, navani kholin, shallan pattern, shallan veil, shallan radiant, vin kelsier, kelsier survivor, wax wayne marasi, steris marasi, cryptic spren, steris wax, szeth nightblood, shades threnody, threnody hell

πŸ“ Phrases

  • 17th shard, bands of mourning, brandon sanderson, cognitive realm, rhythm of war, shadows of self, sixth of the dusk, shadows for silence, shadows of silence, ember dark, emperor's soul, isles of the ember dark, stormlight archive, sunlit man, alloy of law, hero of ages, lost metal, way of kings, well of ascension, tress of the emerald sea, wind and truth, words of radiance, yumi and the nightmare painter, shattered planes, knight radiant, knights radiant, journey before destination, life before death, strength before weakness, dragon steel nexus

πŸ‘₯ Handles to Include

  • stormlightmemes.bsky.social, brotherwisegames.bsky.social

πŸ› οΈ Making your own Feed

πŸ“‹ Step 1: Initial Setup

πŸ”§ Clone & Configure

  1. Clone the repository

    git clone https://github.com/richardr1126/cosmere-feed-bsky.git
    cd cosmere-feed-bsky/
  2. Create and configure environment variables

    cp example.env .env

    Edit .env with your settings:

    HOSTNAME=feed.yourdomain.com          # Domain name for the feed
    HANDLE=your-handle.bsky.social        # A Bluesky handle for api access
    PASSWORD=your-password                # A Bluesky app password
    CHRONOLOGICAL_TRENDING_URI=           # Leave empty for now
    POSTGRES_USER=postgres                # Postgres user to create
    POSTGRES_PASSWORD=your-db-password    # Postgres password to create and use
    POSTGRES_DB=feed                      # Postgres db name to create and use

πŸ› οΈ Step 2: Configure Your Feed

βš™οΈ Edit Feed Details

  1. Edit publish_feed.py with your feed details:

    • RECORD_NAME: Short name for the feed identifier (lowercase, no spaces)
    • DISPLAY_NAME: User-facing feed name
    • DESCRIPTION: Feed description
    • AVATAR_PATH: Path to feed avatar image (optional)
  2. Modify filters in firehose/filter_config.json (optional):

    • HANDLES: Accounts to always include
    • EXCLUDE_HANDLES: Accounts to always exclude
    • PHRASES: Exact phrases to match
    • INCLUSIVE_MULTI_TOKENS: Multi-word matches (any order)
    • TOKENS: Single words to match
    • EXCLUDE_TOKENS: Words to exclude

πŸš€ Step 3: Publish Your Feed

πŸ“€ Install & Run

  1. Install the ATProto SDK:

    pip install atproto
  2. Run the publisher:

    python publish_feed.py
  3. Copy the output Feed URI into your .env file as CHRONOLOGICAL_TRENDING_URI

🐳 Step 4: Deploy with Docker

πŸ”₯ Build & Start Services

  1. Ensure Docker and Docker Compose are installed

  2. Build and start services:

    docker compose up --build

    This launches:

    • PostgreSQL database (with persistence)
    • Firehose data stream processor
    • Feed generator web server (4 Gunicorn workers)
  3. Your feed should now be accessible at:

    http://localhost:8000/xrpc/app.bsky.feed.getFeedSkeleton?feed=[CHRONOLOGICAL_TRENDING_URI]&limit=30
    

βš™οΈ Access Configuration

By default, the feed will be accessible at http://localhost:8000. For production deployment:

  • Deploy to a cloud provider like AWS, Azure, or Google Cloud with persistent storage for Docker volumes
  • Configure your domain's DNS records to point to the server
  • Use your domain HOSTNAME in the .env file

Alternative methods:

  • Use free ngrok for temporary public access
    • Set the ngrok domain as HOSTNAME in .env
  • Set up a free Cloudflare Tunnel for permanent local server access
    • Point your domain to the Cloudflare Tunnel endpoint, and use your domain as HOSTNAME in .env
    • Optioanlly setup your docker compose up --build as a systemctl service for automatic startup (need Linux)

πŸ“‘ Endpoints

The server provides the following endpoints:

  • πŸ”‘ Well-Known DID Document: GET /.well-known/did.json
  • πŸ“ Feed Generator Description: GET /xrpc/app.bsky.feed.describeFeedGenerator
  • πŸ”„ Feed Skeleton: GET /xrpc/app.bsky.feed.getFeedSkeleton

πŸ“œ License

This project is licensed under the MIT License.


πŸ™ Acknowledgements

Special thanks to:

  • @MarshalX for the foundational work on the AT Protocol SDK for Python
  • Bluesky Social for the AT Protocol
  • Brandon Sanderson for creating the inspiring Cosmere universe

🚫 Banned Content

Exclusion Rules

  • 🚫 Handles to Exclude: flintds.bsky.social
  • β›” Exclude Tokens: trump, sylvana, sylvanna, alleria, uriele, mormon

About

A custom feed generator server with a docker PostgreSQL database for Bluesky posts relating to the Cosmere by Brandon Sanderson.

Topics

Resources

License

Stars

Watchers

Forks