update doc comments
This commit is contained in:
parent
1ffac9658d
commit
5fa3264462
13
src/db.rs
13
src/db.rs
|
@ -1,9 +1,10 @@
|
|||
//! Key-value store using the sled database. The database stores peer and
|
||||
//! post-related data retrieved via an sbot connection. It also stores data
|
||||
//! generated by the user through the lykin web-interface, such as whether
|
||||
//! a post has been read or not. Methods are exposed for convenient
|
||||
//! interaction with the database, such as adding inserting and returning
|
||||
//! posts.
|
||||
//! Key-value store using the sled database.
|
||||
//!
|
||||
//! The database stores peer and post-related data retrieved via an sbot
|
||||
//! connection. It also stores data generated by the user through the lykin
|
||||
//! web-interface, such as whether a post has been read or not. Methods are
|
||||
//! exposed for convenient interaction with the database, such as adding
|
||||
//! inserting and returning posts.
|
||||
|
||||
use std::{
|
||||
fmt,
|
||||
|
|
67
src/main.rs
67
src/main.rs
|
@ -1,3 +1,63 @@
|
|||
#![warn(missing_docs)]
|
||||
|
||||
//! # lykin
|
||||
//!
|
||||
//! _Symbiosis of SSB, key-value store and web server._
|
||||
//!
|
||||
//! ## Introduction
|
||||
//!
|
||||
//! lykin is a tutorial application funded by a Secure Scuttlebutt (SSB)
|
||||
//! community grant. It is intended to showcase one way in which an SSB
|
||||
//! application can be written using the
|
||||
//! [golgi](http://golgi.mycelial.technology) client library. The application
|
||||
//! is not intended for widespread or longterm use and will not be maintained
|
||||
//! as such; it is purely for demonstration purposes. Anyone is free to fork
|
||||
//! the repository and use it as the basis for their own application.
|
||||
//!
|
||||
//! ## Features
|
||||
//!
|
||||
//! lykin presents an email inbox-like UI and functions as a Scuttlebutt reader
|
||||
//! application. It allows the user to subscribe to peers and read the root
|
||||
//! posts of those peers. Individual posts can be marked as read or unread.
|
||||
//!
|
||||
//! A summary of the features:
|
||||
//!
|
||||
//! - Subscribe to a peer (follow)
|
||||
//! - Unsubscribe from a peer (unfollow)
|
||||
//! - List subscribed peers
|
||||
//! - List root posts for each peer
|
||||
//! - Mark a post as read
|
||||
//! - Mark a post as unread
|
||||
//! - Fetch new posts
|
||||
//!
|
||||
//! ## Design
|
||||
//!
|
||||
//! lykin has been built with the following components:
|
||||
//!
|
||||
//! - [tera](https://crates.io/crates/tera) : templating engine
|
||||
//! - [rocket](https://crates.io/crates/rocket/0.5.0-rc.1) : web server
|
||||
//! - [golgi](https://crates.io/crates/golgi) : Scuttlebutt client library
|
||||
//! - [sled](https://crates.io/crates/sled) : transactional embedded database
|
||||
//! (key-value store)
|
||||
//! - [sbot](https://github.com/cryptoscope/ssb) : Scuttlebutt server (in our
|
||||
//! case, go-ssb)
|
||||
//!
|
||||
//! ## Thanks
|
||||
//!
|
||||
//! I am grateful to the Butts who voted to fund this work, all contributors to
|
||||
//! the SSBC and Erick Lavoie in particular - both for partially funding this
|
||||
//! work and for developing and overseeing the community grant process.
|
||||
//!
|
||||
//! ## Contact
|
||||
//!
|
||||
//! I can be reached via email:
|
||||
//! [glyph@mycelial.technology](mailto:glyph@mycelial.technology) or
|
||||
//! Scuttlebutt: `@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519`.
|
||||
//!
|
||||
//! ## License
|
||||
//!
|
||||
//! TBD.
|
||||
|
||||
mod db;
|
||||
mod routes;
|
||||
mod sbot;
|
||||
|
@ -18,9 +78,8 @@ use xdg::BaseDirectories;
|
|||
|
||||
use crate::{db::Database, routes::*, task_loop::Task};
|
||||
|
||||
pub struct WhoAmI {
|
||||
pub public_key: String,
|
||||
}
|
||||
/// The public key of the local sbot instance.
|
||||
pub struct WhoAmI(String);
|
||||
|
||||
#[launch]
|
||||
async fn rocket() -> _ {
|
||||
|
@ -31,7 +90,7 @@ async fn rocket() -> _ {
|
|||
.await
|
||||
.expect("whoami rpc call failed. please ensure the sbot is running before trying again");
|
||||
info!("Public key of the local sbot instance: {}", public_key);
|
||||
let whoami = WhoAmI { public_key };
|
||||
let whoami = WhoAmI(public_key);
|
||||
|
||||
// Create the key-value database.
|
||||
let xdg_dirs = BaseDirectories::with_prefix("lykin").unwrap();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Web server route handlers.
|
||||
|
||||
use async_std::channel::Sender;
|
||||
use log::{debug, warn};
|
||||
use rocket::{form::Form, get, post, response::Redirect, uri, FromForm, State};
|
||||
|
@ -175,7 +177,7 @@ pub async fn subscribe_form(
|
|||
// Follow the peer if our local instance is not already following.
|
||||
if db.add_peer(peer_info).is_ok() {
|
||||
debug!("added {} to peer tree in database", &peer.public_key);
|
||||
match sbot::is_following(&whoami.public_key, &peer.public_key).await {
|
||||
match sbot::is_following(&whoami.0, &peer.public_key).await {
|
||||
Ok(status) if status.as_str() == "false" => {
|
||||
match sbot::follow_peer(&peer.public_key).await {
|
||||
Ok(_) => debug!("followed {}", &peer.public_key),
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
//! Asynchronous task loop.
|
||||
//!
|
||||
//! Allows for the execution of potentially long-running actions involving sbot
|
||||
//! RPC calls, data transformations and database interactions.
|
||||
|
||||
use async_std::{channel::Receiver, task};
|
||||
use log::{info, warn};
|
||||
|
||||
|
@ -10,6 +15,14 @@ pub enum Task {
|
|||
FetchLatestName(String),
|
||||
}
|
||||
|
||||
/// Retrieve a set of posts from the local sbot instance and add them to the
|
||||
/// posts tree of the database.
|
||||
///
|
||||
/// A stream of messages is first requested for the peer represented by the
|
||||
/// given public key (ID), starting after the given sequence number. The root
|
||||
/// posts are filtered from the set of messages and added to the database as a
|
||||
/// batch. Finally, the value of the latest sequence for the peer is updated
|
||||
/// and saved to the existing database entry.
|
||||
async fn fetch_posts_and_update_db(db: &Database, peer_id: String, after_sequence: u64) {
|
||||
let peer_msgs = sbot::get_message_stream(&peer_id, after_sequence).await;
|
||||
let (latest_sequence, root_posts) = sbot::get_root_posts(peer_msgs).await;
|
||||
|
@ -35,6 +48,8 @@ async fn fetch_posts_and_update_db(db: &Database, peer_id: String, after_sequenc
|
|||
}
|
||||
}
|
||||
|
||||
/// Request the name of the peer represented by the given public key (ID)
|
||||
/// and update the existing entry in the database.
|
||||
async fn fetch_name_and_update_db(db: &Database, peer_id: String) {
|
||||
match sbot::get_name(&peer_id).await {
|
||||
Ok(name) => {
|
||||
|
@ -52,6 +67,8 @@ async fn fetch_name_and_update_db(db: &Database, peer_id: String) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Spawn an asynchronous loop which receives tasks over an unbounded channel
|
||||
/// and invokes task functions accordingly.
|
||||
pub async fn spawn(db: Database, rx: Receiver<Task>) {
|
||||
task::spawn(async move {
|
||||
while let Ok(task) = rx.recv().await {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Public key validation.
|
||||
|
||||
/// Ensure that the given public key is a valid ed25519 key.
|
||||
///
|
||||
/// Return an error string if the key is invalid.
|
||||
|
|
Loading…
Reference in New Issue