radicle-feed 0.5.3

A feed service for Radicle
Documentation
mod feed;
mod models;
mod radicle_extra;
mod schema;
mod storage;

use radicle::storage::ReadStorage;
use snafu::{OptionExt, ResultExt};
use tracing::Level;
use tracing_subscriber::{EnvFilter, FmtSubscriber};

use feed::FeedProcessor;
use radicle_extra::profile::Profile;
use storage::postgres::PostgresStorage;

#[snafu::report]
fn main() -> Result<(), snafu::Whatever> {
    tracing_log::LogTracer::init().whatever_context("initializing log tracer failed")?;
    let subscriber = FmtSubscriber::builder()
        .with_max_level(Level::TRACE)
        .with_env_filter(EnvFilter::from_default_env())
        .finish();
    tracing::subscriber::set_global_default(subscriber)
        .whatever_context("setting default subscriber failed")?;

    let profiles_path = std::env::var("PROFILE_STORAGE_PATH")
        .whatever_context("getting profile storage path failed")?;
    let database_url =
        std::env::var("DATABASE_URL").whatever_context("getting database url failed")?;

    // Iterate over the profiles folder
    for path in
        std::fs::read_dir(profiles_path).whatever_context("reading profile storage path failed")?
    {
        let path = path
            .whatever_context("reading profile storage path failed")?
            .path();

        let path_str = path
            .file_name()
            .and_then(|s| s.to_str())
            .whatever_context("Unable to convert file name to string")?;

        if !path.is_dir() || !path_str.starts_with("node") {
            tracing::info!("Skipping non-node profile: {}", path_str);
            continue;
        }

        if path
            .read_dir()
            .whatever_context("Failed to read dir")?
            .next()
            .is_none()
        {
            tracing::info!("Skipping empty folders: {}", path_str);
            continue;
        }

        let profile: radicle::Profile = Profile::load(path.clone())
            .whatever_context("loading profile failed")?
            .into();
        let policy = profile
            .policies()
            .whatever_context("Unable to load policies")?;
        let mut storage = PostgresStorage::new(database_url.clone())?;
        let mut processor = FeedProcessor::new(&mut storage, profile.clone())?;

        let repos = profile
            .clone()
            .storage
            .repositories()
            .whatever_context("Failed loading repos")?;

        for repo in repos {
            if policy
                .is_seeding(&repo.rid)
                .whatever_context("Unable to check repo policies")?
                == false
            {
                continue;
            }
            tracing::info!("{} Processing repository: {}", path_str, repo.rid);
            processor.process_repository(&repo)?;
        }
        let storage_stats = processor
            .get_stats()
            .whatever_context("Failed to get stats")?;
        tracing::info!("{}", storage_stats);
    }

    Ok(())
}