podping-api 0.1.0

A library for the Podping API.
Documentation
use reqwest::Client;

use crate::podping::OpPayload;

use super::{
    request::BlockId, HiveMessage, HiveOperation, HiveResponse, HiveResponseResult, Operations,
    Transactions, HIVE_API,
};

/// Get operations for the current block
/// We filter for notifications with the name `podping`
pub async fn get_operations(
    client: &Client,
    block: &BlockId,
) -> Result<Vec<Operations>, reqwest::Error> {
    let transactions = get_transactions(client, block).await?;
    tracing::debug!("Transactions: {transactions:?}, Block Id: {block:?}");

    let mut operations = vec![];
    for transaction in transactions {
        for operation in transaction.operations {
            for op in operation {
                match op {
                    HiveOperation::Operations(operation) => {
                        if let Some(name) = &operation.id {
                            // We only care about podping messages.
                            // WARNING: The id names of podcast updates likely need to be expanded.
                            let queries = vec!["podping", "pp_podcast", "pp_podcast_update"];

                            if queries.contains(&name.as_str()) {
                                operations.push(operation);
                            }
                        }
                    }
                    // We don't care about any of these messages.
                    HiveOperation::String(_)
                    | HiveOperation::Vote(_)
                    | HiveOperation::Transfer(_)
                    | HiveOperation::Transactions(_)
                    | HiveOperation::Comment(_) => {}
                }
            }
        }
    }
    Ok(operations)
}

pub async fn get_transactions(
    client: &Client,
    block: &BlockId,
) -> Result<Vec<Transactions>, reqwest::Error> {
    let hive_response = get_block(client, block).await?;
    if let Some(HiveResponseResult::Block(block)) = &hive_response.result {
        Ok(block.transactions.clone())
    } else {
        Ok(vec![])
    }
}

/// Get information about the specified Block
pub async fn get_block(client: &Client, block: &BlockId) -> Result<HiveResponse, reqwest::Error> {
    let block_response = HiveMessage::get_block(block.get());
    let resp = client
        .post(HIVE_API)
        .json(&block_response)
        .send()
        .await?
        .text()
        .await?;
    // reqwest can't properly serialize the type into json,
    // but serde_json can.
    Ok(serde_json::from_str::<HiveResponse>(&resp).unwrap())
}

/// Extract Url's from the Operations
/// TODO: Maybe move into a FROM impl?
pub async fn get_payloads(operations: Vec<Operations>, _block: &BlockId) -> Vec<String> {
    // Extract the updated uri's
    let mut payloads = vec![];
    for tr in operations {
        let json_payload = serde_json::from_str::<OpPayload>(&tr.json.unwrap()).unwrap();
        payloads = json_payload.iris;
    }

    payloads
}

/// Get the current head block number
pub async fn get_head_block_number(client: &Client) -> Result<u64, reqwest::Error> {
    let resp = client
        .post(HIVE_API)
        .json(&HiveMessage::get_dynamic_global_properties())
        .send()
        .await?
        .json::<HiveResponse>()
        .await?;
    Ok(resp.get_head_block_number().unwrap())
}