/* Example Zot API command line utility, part of zotapi. * Copyright (C) 2018 Harald Eilertsen * * 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 . */ use zotapi::Stream; use clap::{clap_app, crate_authors, crate_version}; use dotenv::dotenv; use std::env; #[tokio::main] async fn main() -> Result<(), Box<(dyn std::error::Error + 'static)>> { dotenv().ok(); let site = env::var("HZ_SITE").expect("SITE variable expected"); let channel = env::var("HZ_CHANNEL").expect("CHANNEL variable expected"); let password = env::var("HZ_PASSWORD").expect("PASSWORD variable expected"); let matches = clap_app!(app => (name: "zot") (version: crate_version!()) (author: crate_authors!()) (about: "zotapi command line client.") (@arg raw: --raw "Display raw json payload.") (@arg site: --site "Site to connect to.") (@arg channel: --channel "The channel to connect as.") (@arg password: --password "The password.") (@subcommand verify => (about: "Fetch the channel object of the logged in channel.") ) (@subcommand version => (about: "Return the version of a server.") ) (@subcommand channel => (about: "Work with channels") (@subcommand list => (about: "List channels for the logged in account.") ) (@subcommand stream => (about: "Fetch the channel stream.") ) (@subcommand export => (about: "Export the channel.") ) ) (@subcommand network => (about: "Fetch the network stream") ) (@subcommand abook => (about: "Fetch address book/contact info") ) (@subcommand abconfig => (about: "Fetch abconfig") ) (@subcommand group => (about: "Fetch privacy groups") (@group selector => (@arg ID: --id +takes_value "Fetch members of group ") (@arg GNAME: --name +takes_value "Fetch members of group ") ) ) (@subcommand xchan => (about: "Fetch xchan info") (@arg addr: --addr "ID is given as webbie (default)") (@arg hash: --hash "ID is given as xchan hash") (@arg guid: --guid "ID is given as a GUID") (@arg ID: +required "id (webbie, hash or GUID) of xchan to fetch") ) (@subcommand post => (about: "Post a new message") (@arg FILE: "A text file containing the body of the message") (@arg TITLE: --title +takes_value "Set a title for the message") (@arg ATTACH: --attach [FILE] "Attach a file or image to the post") (@arg GROUP: --group [groups] "Limit distribution to the specified group(s) separated by comma") ) (@subcommand photos => (about: "Post or get photos or albums") (@arg UPLOAD: --upload [FILE] requires[ALBUM] "Upload a photo") (@arg ALBUM: --album +takes_value "The album to upload the photo to") (@arg DESC: --description +takes_value "A description/title for the photo") (@arg BODY: --body +takes_value "A longer description/body text") (@arg POST: --post "Post the photo to the timeline") (@arg GROUP: --group [groups] "Limit distribution to the specified group(s) separated by comma") ) ) .get_matches(); let z = zotapi::new(&site, &channel, &password); Ok(match matches.subcommand() { ("verify", Some(_)) => { let channel = z.verify().await; println!("{:?}", channel); } ("version", Some(_)) => { println!("{}", z.version().await?); } ("channel", Some(m)) => { match m.subcommand() { ("list", Some(_)) => { for ch in z.channel_list().await? { println!("{}", ch); } } ("stream", Some(_)) => { let json = z.channel_stream().await?; std::fs::write("channel_stream.json", &json) .expect("Unable to write channel_stream.json file"); let s = Stream::from_json(&json)?; for item in s.items { if item.is_post() { let mut summary = item.title; if summary.len() == 0 { if item.summary.len() > 0 { summary = item.summary; } else { summary = item.body; } } summary.truncate(64); println!("{} | {:24} | {}", item.created.to_string(), item.author.name, summary); } } //println!("{}", z.channel_stream().await?); } ("export", Some(_)) => { println!("{}", z.channel_export().await?); } _ => { println!("Not a known subcommand for `channel`, or it's not implemented yet."); println!("{}", m.usage()); } } } /* ("network", Some(m)) => { let raw = m.is_present("raw"); zot::network_stream::fetch(&client, raw).await; } ("abconfig", _) => { zot::abconfig::fetch(&client).await; } ("abook", Some(m)) => { let r = zotapi::Abook::z(); if m.is_present("raw") { println!("{}", r.fetch_raw(&client).await.unwrap()); } else { for abook in r.fetch(&client).await.unwrap() { println!("{},{},{}", abook.xchan.name, abook.xchan.address, abook.xchan.network); } } } ("group", Some(m)) => { if let Some(id) = m.value_of("ID") { let res = zotapi::group_members() .by_group_id(u64::from_str(id).unwrap()) .fetch(&client) .await .unwrap(); if m.is_present("raw") { println!("{}", res); } else { zot::group::list_members(&res); } } else if let Some(gname) = m.value_of("GNAME") { let res = zotapi::group_members() .by_group_name(gname) .fetch(&client) .await .unwrap(); if m.is_present("raw") { println!("{}", res); } else { zot::group::list_members(&res); } } else { let res = zotapi::group().fetch(&client).await.unwrap(); if m.is_present("raw") { println!("{}", res); } else { zot::group::list(&res); } } } ("xchan", Some(m)) => { let mut r = zotapi::XChan::z(); let id = m.value_of("ID").expect("No xchan provided."); if m.is_present("guid") { r.by_guid(id) } else if m.is_present("hash") { r.by_hash(id) } else { r.by_address(id) }; if m.is_present("raw") { println!("{}", r.fetch_raw(&client).await.unwrap()); } else { println!("{:?}", r.fetch(&client).await); } } ("post", Some(m)) => { zot::item::post(&client, m).await; } */ _ => { println!("Not a known command, or it's not implemented yet."); println!("{}", matches.usage()); } }) }