aboutsummaryrefslogblamecommitdiffstats
path: root/src/zotapi.rs
blob: a15b51a8ee3be47a39b297409bdb2fa0dfbff584 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                         



            
























                                                                       


                                                           







                                                                               








                                                                               












                                                                                         







                                                                 








                                                                                      



                                                             
 



















                                                                     

     
// zotapi - Rust wrapper for Zot API as implemented by Hubzilla
// Copyright (C) 2023  Harald Eilertsen <haraldei@anduin.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::{
    Channel,
    Error,
};
use url::Url;
use reqwest::{
    self,
    header::{ACCEPT},
};
use serde::Serialize;

#[derive(Debug)]
pub struct ZotApi {
    client: reqwest::Client,
    base_url: Url,
    channel: String,
    pw: String,
}

pub fn new(url: &str, channel: &str, pw: &str) -> ZotApi {
    ZotApi {
        client: reqwest::Client::new(),
        base_url: Url::parse(url).unwrap().join("api/z/1.0/").unwrap(),
        channel: String::from(channel),
        pw: String::from(pw),
    }
}

impl ZotApi {
    /**
     * Returns the channel object of the logged in channel.
     */
    pub async fn verify(&self) -> Result<Channel, Box<dyn std::error::Error>> {
        let raw = self.get("verify").send().await?.text().await?;
        let mut channel: Channel = serde_json::from_str(&raw)?;
        channel.xchan = serde_json::from_str(&raw)?;

        Ok(channel)
    }

    /**
     * Returns the version of the server.
     *
     * This API can be invoked without authentication.
     */
    pub async fn version(&self) -> Result<String, Box<dyn std::error::Error>> {
        Ok(self.get("version").send().await?.text().await?)
    }

    /**
     * Returns the list of channels for this account.
     */
    pub async fn channel_list(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let json = self.get("channel/list")
            .send().await?
            .text().await?;
        Ok(serde_json::from_str(&json)?)
    }

    /**
     * Return the channel stream as json.
     */
    pub async fn channel_stream(&self) -> Result<String, Error> {
        let response = self.get("channel/stream").send().await?;

        if response.status().is_success() {
            Ok(response.text().await?)
        } else {
            Err(response.status().into())
        }
    }

    /**
     * Return all data from channel for export.
     */
    pub async fn channel_export(&self) -> Result<String, Box<dyn std::error::Error>> {
        Ok(self.get("channel/export/basic").send().await?.text().await?)
    }

    pub async fn abook_list(&self) -> Result<String, Error> {
        Ok(self.get("abook").send().await?.text().await?)
    }



    /// Return a RequestBuilder object that's set up with the correct
    /// path and headers for performing a zot api request.
    pub fn get(&self, path: &str) -> reqwest::RequestBuilder {
        self.client.get(&self.url(path, &()))
            .header(ACCEPT, "application/json")
            .basic_auth(self.channel.clone(), Some(self.pw.clone()))
    }

    fn url<T>(&self, path: &str, args: &T) -> String
    where
        T: Serialize + std::fmt::Debug,
    {
        let mut r = self.base_url.clone().join(path).unwrap();

        if let Ok(a) = serde_qs::to_string(dbg!(args)) {
            r.set_query(Some(&a));
        }

        r.to_string()
    }
}