A Rust-based comment server using SQLite and an intuitive REST API.

Related tags

Database soudan
Overview

soudan

A Rust-based comment server using SQLite and an intuitive REST API. Soudan is built with simplicity and static sites in mind.

CLI usage

See soudan --help for help information.

soudan 0.1.0
ElnuDev <[email protected]>
A Rust-based comment server using SQLite and an intuitive REST API.

USAGE:
    soudan [OPTIONS] [CONFIG]

ARGS:
    <CONFIG>    Set configuration file [default: soudan.yaml]

OPTIONS:
    -h, --help           Print help information
    -p, --port <PORT>    Set port where HTTP requests will be received [default: 8080]
    -t, --testing        Run in testing mode, with in-memory database(s) and permissive CORS policy
    -V, --version        Print version information

Soudan uses a YAML configuration file for most configuration options. By default, this configuration file is soudan.yaml, but you can override this by passing in the configuration file path to Soudan as an argument.

For example, to run Soudan on port 8081 with test.yaml as the configuration file, use the following command.

soudan -p 8081 test.yaml

In addition, you can add the -t/--testing flag to run Soudan in testing mode. In this mode, Soudan stores all comments in a fresh in-memory database, and all comments will be lost once Soudan is closed. In addition, a permissive CORS policy is used to make testing easier.

Configuration file

Here’s an example configuration file:

"localhost:3000":
  file: databases/test.db
  nameRequired: true
  emailRequired: true
"localhost:5000": {}

Here, we have two sites, one hosted locally at port 3000 and one hosted locally at port 5000.

For the first site, we specify that we want the SQLite database file to be stored in databases/test.db, and we want the name and email fields of each comment to be required to prevent anonymous comments. (Keep in mind that the JavaScript in soudan.js assumes that these flags are not set, so you would need to manually add the required flag to the name and email <input> fields respectively.)

For the second site, we can leave all the configuration fields as their defaults by giving an empty YAML object {}. If the database file path isn’t provided, it will default to the domain plus the .db extension, so in this case it will be localhost:5000.db in the current directory. Name and email are not required by default.

Moderation

Soudan does not have any spam filtering or moderation built in. However, going into the database manually to browse and remove comments is very easy. If you need an SQLite database browser, I'd recommend DB Browser for SQLite.

API usage

Fetching comments

Comments can be fetched using a simple GET request to /{content_id}, where content_id is the content ID of the post set in the page's meta tags. (See Site configuration for information about how to set up your site's HTML to use Soudan.) It is important to note that the content ID is not unique across sites. The way the intended site of the request is determined is through the Origin header. Requests without a valid Origin header are rejected. Requests made through the browser will always have this header.

Here is an example API response from real-world usage of Soudan (beautified).

Each comment will have an id, text, and timestamp fields, and optionally an author (if absent, comment is anonymous) and a gravatar field (the MD5 hash of the commenter's email address. https://www.gravatar.com/avatar/{gravatar}). Root level comments will have a replies field if replies exist.

[
	{
		"id": 1,
		"author": "Elnu",
		"gravatar": "1cfb9e38feea40e5150bc0fa69faf693",
		"text": "Nice post, me!",
		"timestamp": 1658541512,
		"replies": [
			{
				"id": 2,
				"author": "Drago",
				"text": "HELLO ELNU",
				"timestamp": 1658541674
			},
			{
				"id": 3,
				"author": "Elnu",
				"gravatar": "1cfb9e38feea40e5150bc0fa69faf693",
				"text": "HELLO DRAGO",
				"timestamp": 1658541732
			},
			{
				"id": 4,
				"author": "Drago",
				"text": "You should get to drawing ( ͡° ͜ʖ ͡°)",
				"timestamp": 1658541778
			},
			{
				"id": 5,
				"author": "Elnu",
				"gravatar": "1cfb9e38feea40e5150bc0fa69faf693",
				"text": "*soon™*",
				"timestamp": 1658541863
			}
		]
	}
]

Creating comments

Comments can be likewise created using a simple POST request to / (not /{content_id}).

Here is an example API response from real-world usage of Soudan (beautified).

The request must have a url field which is the current page URL. The comment field must contain contentId, the page content ID (see Site configuration), and text. Optionally, the author, email, and parent (the parent comment ID).

{
	"url": "http://localhost:3000/a/",
	"comment": {
		"contentId": "a",
		"author": "Elnu",
		"email": "[email protected]",
		"text": "Test comment",
		"parent": null
	}
}

Site configuration

Site configuration for Soudan is very straightforward. All you need to do is add the following meta tag to the <head> of all pages you want to enable comments on, where you insert your content ID into the content attribute of the tag:

<meta name="soudan-content-id" content="{content_id}">

The content ID can be pretty much anything, provided it's URL-safe (e.g. there must be no forward slashes (/)). Spaces are okay, as they will be escaped. A good value to use for the content ID is the slug of your page, as this will be unique and will be obvious what page it is associated with in the database. However, one must make sure that if the page is renamed/moved, either this content ID remains constant or the associated comments are manually updated accordingly in the database (see Moderation).

Reference JavaScript client implementation

There is a reference JavaScript client implementation available under demo. It supports Markdown comment rendering via markdown-it (images have been disabled) and human-readable relative timestamps for comments via moment.js. The icons are from Heroicons.

To use it, first add these two dependencies to your page's <head>, here using a CDN. You may want to check if there has been a newer version released on cdnjs since the time of writing. (markdown-it, moment.js)

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js" integrity="sha512-SYfDUYPg5xspsG6OOpXU366G8SZsdHOhqk/icdrYJ2E/WKZxPxze7d2HD3AyXpT7U22PZ5y74xRpqZ6A2bJ+kQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

The demo HTML pages use the Sakura CSS framework/theme in addition to a small stylesheet just for Soudan. Optionally, you can copy this stylesheet into your project. It's pretty theme-agnostic, so it should work fine regardless of your preexisting styles.

<link rel="stylesheet" href="/path/to/style.css">

Next, copy soudan.js into your project. Open it up in your favorite text editor and update the value of url here to URL of your own Soudan server.

Finally, on each page where you want comments (and where the meta tag is present), add the following container <div> and script tag where you want your comment section to be. The comment form, etc. will be automatically generated once your page loads, and will be hidden if there is a critical error (i.e. Soudan server offline). The <script> tag must be after the <div>.

<div id="soudan"></div>
<script src="/path/to/soudan.js"></script>

And... you're done!

You might also like...
SQLite-based on-disk cache for Rust.

sqlite-cache SQLite-based on-disk cache for Rust. Usage let cache = Cache::new( CacheConfig::default(), rusqlite::Connection::open_in_memory()

Rusqlite is an ergonomic wrapper for using SQLite from Rust

Rusqlite Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to expose an interface similar to rust-postgres. use rusqlite::{para

Using embedded database modeled off SQLite - in Rust
Using embedded database modeled off SQLite - in Rust

Rust-SQLite (SQLRite) Rust-SQLite, aka SQLRite , is a simple embedded database modeled off SQLite, but developed with Rust. The goal is get a better u

Simple and handy btrfs snapshoting tool. Supports unattended snapshots, tracking, restoring, automatic cleanup and more. Backed with SQLite.
Simple and handy btrfs snapshoting tool. Supports unattended snapshots, tracking, restoring, automatic cleanup and more. Backed with SQLite.

Description Simple and handy btrfs snapshoting tool. Supports unattended snapshots, tracking, restoring, automatic cleanup and more. Backed with SQLit

🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx 🧰 The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

🐸Slippi DB ingests Slippi replays and puts the data into a SQLite database for easier parsing.
🐸Slippi DB ingests Slippi replays and puts the data into a SQLite database for easier parsing.

The primary goal of this project is to make it easier to analyze large amounts of Slippi data. Its end goal is to create something similar to Ballchasing.com but for Melee.

A tool for automated migrations for PostgreSQL, SQLite and MySQL.

Models Models is an implementation for a SQL migration management tool. It supports PostgreSQL, MySQL, and SQLite. Quick Start install the CLI by runn

XLite - query Excel (.xlsx, .xls) and Open Document spreadsheets (.ods) as SQLite virtual tables

XLite - query Excel (.xlsx, .xls) and Open Document spreadsheets (.ods) as SQLite virtual tables XLite is a SQLite extension written in Rust. The main

A SQLite extension for quickly generating random numbers, booleans, characters, and blobs

sqlite-fastrandom A SQLite extension for quickly generating random numbers, booleans, characters, and blobs. Not cryptographically secure. Based on sq

rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

rust_arango enables you to connect with ArangoDB server, access to database, execute AQL query, manage ArangoDB in an easy and intuitive way, both async and plain synchronous code with any HTTP ecosystem you love.

Foretag 3 Mar 24, 2022
SubZero - a standalone web server that turns your database directly into a REST/GraphQL api

What is this? This is a demo repository for the new subzero codebase implemented in Rust. subZero is a standalone web server that turns your database

subZero 82 Jan 1, 2023
Provides a Rust-based SQLite extension for using Hypercore as the VFS for your databases.

SQLite and Hypercore A Rust library providing SQLite with an virtual file system to enable Hypercore as a means of storage. Contributing The primary r

Jacky Alciné 14 Dec 5, 2022
Query is a Rust server for your remote SQLite databases and a CLI to manage them.

Query Query is a Rust server for your remote SQLite databases and a CLI to manage them. Table Of Contents Run A Query Server CLI Install Use The Insta

Víctor García 6 Oct 6, 2023
High performance and distributed KV store w/ REST API. 🦀

About Lucid KV High performance and distributed KV store w/ REST API. ?? Introduction Lucid is an high performance, secure and distributed key-value s

Lucid ᵏᵛ 306 Dec 28, 2022
The most efficient, scalable, and fast production-ready serverless REST API backend which provides CRUD operations for a MongoDB collection

Optimal CRUD Mongo Goals of This Project This is meant to be the most efficient, scalable, and fast production-ready serverless REST API backend which

Evaluates2 1 Feb 22, 2022
Grsql is a great tool to allow you set up your remote sqlite database as service and CRUD(create/read/update/delete) it using gRPC.

Grsql is a great tool to allow you set up your remote sqlite database as service and CRUD (create/ read/ update/ delete) it using gRPC. Why Create Thi

Bruce Yuan 33 Dec 16, 2022
A Rust client for the ElasticSearch REST API

rs-es Introduction An ElasticSearch client for Rust via the REST API. Targetting ElasticSearch 2.0 and higher. Other clients For later versions of Ela

Ben Ashford 218 Dec 27, 2022
An Elasticsearch REST API client for Rust

elastic elastic is an efficient, modular API client for Elasticsearch written in Rust. The API is targeting the Elastic Stack 7.x. elastic provides st

null 249 Oct 18, 2022
🦀 REST API client implementation for freee, auto-generated from OpenAPI specification.

freee-rs REST API client implementation for freee, auto-generated from OpenAPI specification. Getting Started Add to your Cargo.toml as follows: [depe

Naoki Ikeguchi 3 Jul 14, 2022