From 04ca15e97e9bb64a31f39edf3d00b6f5d1267efd Mon Sep 17 00:00:00 2001 From: Roc Sun <710989028@qq.com> Date: Thu, 18 Jan 2024 18:15:37 +0800 Subject: [PATCH] refact:ing add query operate --- Cargo.toml | 1 + README.zh-CN.md | 13 +++++ src/apis/ing/mod.rs | 52 ++++++++++++----- src/args/cmd/ing.rs | 127 ++++++++++++++++++++++++++++++++++++++++- src/args/parser/ing.rs | 35 ++++++++++++ src/bin/cnb.rs | 8 +++ src/lib.rs | 1 + src/logic/ing.rs | 43 ++++++++++++++ src/logic/mod.rs | 6 ++ 9 files changed, 270 insertions(+), 16 deletions(-) create mode 100644 src/logic/ing.rs create mode 100644 src/logic/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 481b8a3..02684e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ license = "MIT" repository = "https://github.com/cnblogs/cli" keywords = ["cli", "cnblogs", "blog"] categories = ["command-line-utilities"] +default-run = "cnb" [profile.dev] lto = true diff --git a/README.zh-CN.md b/README.zh-CN.md index 197dea1..89a95e9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -50,3 +50,16 @@ cnb user --info ```shell cnb posts [comment] [list,create,query,delete,update] --[id/file/quertset] --[pagesize,pagecount] ``` + +## 闪存cli + +闪存cli设计如下: + +```sh +cnb ing query # 默认10条 +cnb ing query --id 123456 +cnb ing query --page 1 --count 10 +cnb ing query --type All --page 1 --count 10 --tag Linux +cnb ing create --conent hello --private false --lucky false +cnb ing delete --id 123456 +``` diff --git a/src/apis/ing/mod.rs b/src/apis/ing/mod.rs index 7f76ffe..ad17840 100644 --- a/src/apis/ing/mod.rs +++ b/src/apis/ing/mod.rs @@ -15,21 +15,34 @@ pub mod comment; use anyhow::{Ok, Result}; +use clap::{ValueEnum, Parser}; use reqwest::{Client, Response}; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::{infra::http::RequestBuilderExt, openapi}; -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "PascalCase")] #[serde(default)] pub struct IngContent { pub content: String, pub is_private: bool, + pub lucky: bool, pub client_type: IngSendFrom, } +impl Default for IngContent { + fn default() -> Self { + IngContent { + content: "".to_string(), + is_private: true, + lucky: false, + client_type: IngSendFrom::default(), + } + } +} + #[derive(Clone, Debug, Serialize_repr, Deserialize_repr)] #[repr(u8)] pub enum IngSendFrom { @@ -56,7 +69,7 @@ impl Default for IngSendFrom { #[serde(default)] pub struct QeurySet { #[serde(skip)] - pub types: QueryIngType, + pub r#type: QueryIngType, pub page_index: u64, pub page_size: u64, #[serde(skip_serializing_if = "String::is_empty")] @@ -66,9 +79,9 @@ pub struct QeurySet { impl Default for QeurySet { fn default() -> Self { return Self { - types: QueryIngType::default(), + r#type: QueryIngType::default(), page_index: 1, - page_size: 30, + page_size: 10, tag: "".to_string(), }; } @@ -83,15 +96,16 @@ impl Default for QeurySet { /// Tag = 10, tag 必填 /// Comment = 13 回复我 /// Mention = 14, -#[derive(Debug)] +#[derive(Debug, Clone, ValueEnum, Parser)] pub enum QueryIngType { - Following, - My, - MyComment, - RecentComment, - Mention, - Comment, - All, + Following = 1, + My = 4, + All = 5, + RecentComment = 6, + MyComment = 7, + Tag = 10, + Comment = 13, + Mention = 14, } impl Default for QueryIngType { @@ -100,6 +114,15 @@ impl Default for QueryIngType { } } +impl From<u8> for QueryIngType { + fn from(value: u8) -> Self { + match value { + 1 => Self::Following, + _ => Self::All, + } + } +} + impl QueryIngType { fn as_u8(&self) -> u8 { match self { @@ -108,6 +131,7 @@ impl QueryIngType { QueryIngType::All => 5, QueryIngType::RecentComment => 6, QueryIngType::MyComment => 7, + QueryIngType::Tag => 10, QueryIngType::Mention => 14, QueryIngType::Comment => 13, } @@ -151,7 +175,7 @@ pub async fn lastest(token: &str) -> Result<Response> { /// 页数是从1开始的 pub async fn query(token: &str, q: &QeurySet) -> Result<Vec<IngEntry>> { let r = Client::new() - .get(openapi!("/statuses/@{}", q.types.as_u8())) + .get(openapi!("/statuses/@{}", q.r#type.as_u8())) .pat_auth(token) .query(&q) .send() @@ -163,7 +187,7 @@ pub async fn query(token: &str, q: &QeurySet) -> Result<Vec<IngEntry>> { } /// 根据ID查询 -pub async fn query_by_id(token: &str, id: &str) -> Result<IngEntry> { +pub async fn query_by_id(token: &str, id: &u64) -> Result<IngEntry> { let r = Client::new() .get(openapi!("/statuses/{}", id)) .pat_auth(token) diff --git a/src/args/cmd/ing.rs b/src/args/cmd/ing.rs index 974c6bc..fe96460 100644 --- a/src/args/cmd/ing.rs +++ b/src/args/cmd/ing.rs @@ -1,5 +1,8 @@ -use crate::api::ing::IngType; -use clap::{Parser, Subcommand}; +use crate::{ + api::ing::IngType, + apis::{self, ing::QeurySet}, +}; +use clap::{Args, Parser, Subcommand, ValueEnum}; #[derive(Parser, Debug)] #[non_exhaustive] @@ -54,4 +57,124 @@ pub enum Cmd { #[arg(default_value_t = true)] align: bool, }, + + /// 根据条件查询闪存。 + Query(QueryIng), + + /// 创建闪存 + Create(CreateIng), + + /// 根据ID删除闪存 + Delete { + #[arg(long)] + id: Vec<u64>, + }, +} + +#[derive(Debug, Args)] +pub struct CreateIng { + /// 闪存内容 + // #[arg(short, long)] + content: Option<String>, + #[arg(short, long, default_value_t = true)] + private: bool, + + #[arg(short, long, default_value_t = false)] + lucky: bool, + + #[arg(short, long)] + tag: Option<String>, +} + +#[derive(Args, Debug)] +struct Create { + /// 闪存内容 + content: String, + + /// 是否私有,默认是全站 + #[arg(short, long, default_value_t = true)] + private: bool, + + /// 是否发布为幸运 + #[arg(short, long, default_value_t = false)] + lucky: bool, + + /// 是否发布在某个标签下,默认不发布标签。 + #[arg(short, long, default_value = "")] + tag: String, +} + +/// 查询参数 +/// 当使用type为 +#[derive(Debug, Args, Clone)] +pub struct QueryIng { + /// 查询类型 + #[arg( + short, + long, + value_name = "TYPE", + default_value_t = QueryType::F, + default_missing_value = "f", + value_enum + )] + pub r#type: QueryType, + /// 分页查询,起始索引是1 + #[arg(short('n'), long, default_value_t = 1)] + pub page_index: u64, + /// 分页查询数量, 默认是10 + #[arg(short('s'), long, default_value_t = 10)] + pub page_size: u64, + /// 按照标签查询 + #[arg(short('g'), long)] + pub tag: Option<String>, + /// 根据ID查询 + #[arg(short, long)] + pub id: Option<Vec<u64>>, +} + +impl From<&QueryIng> for QeurySet { + fn from(value: &QueryIng) -> Self { + Self { + r#type: value.r#type.clone().into(), + page_index: value.page_index, + page_size: value.page_size, + tag: value.tag.clone().unwrap_or_default(), + } + } +} + +/// 过滤的类型 +#[derive(Debug, Clone, ValueEnum, Parser)] +pub enum QueryType { + /// 关注 + F = 1, + /// 我的 + My = 4, + /// 全站 + P = 5, + /// 新回应 + Rc = 6, + /// 我回应 + Mc = 7, + /// 按照Tag过滤,使用T时,如果没有Query::tag或者站点不存在,则不会有结果。 + T = 10, + /// 回复我 + C = 13, + /// 提到我 + M = 14, +} + +impl From<QueryType> for apis::ing::QueryIngType { + fn from(value: QueryType) -> Self { + match value { + QueryType::F => Self::Following, + QueryType::My => Self::My, + QueryType::P => Self::All, + QueryType::Rc => Self::RecentComment, + QueryType::Mc => Self::MyComment, + QueryType::T => Self::Tag, + QueryType::C => Self::Comment, + QueryType::M => Self::Mention, + } + } } diff --git a/src/args/parser/ing.rs b/src/args/parser/ing.rs index 62ed32b..2c8e42c 100644 --- a/src/args/parser/ing.rs +++ b/src/args/parser/ing.rs @@ -1,4 +1,5 @@ use crate::api::ing::IngType; +use crate::args::cmd::ing::QueryIng; use crate::args::parser::{get_skip, get_take}; use crate::args::{cmd, Args, Cmd}; use crate::infra::option::WrapOption; @@ -67,3 +68,37 @@ pub fn comment_ing(args: &Args) -> Option<(&String, usize)> { } .wrap_some() } + +#[allow(unused)] +pub fn query(args: &Args) -> Option<QueryIng> { + match args { + Args { + cmd: + Some(Cmd::Ing(cmd::ing::Opt { + cmd: + Some(cmd::ing::Cmd::Query(QueryIng { + r#type, + page_index, + page_size, + tag, + id, + })), + publish: None, + comment: None, + })), + id: None, + rev: _, + skip, + take, + global_opt: _, + } => QueryIng { + r#type: r#type.clone(), + page_index: page_index.clone(), + page_size: page_size.clone(), + tag: tag.clone(), + id: id.clone(), + }, + _ => return None, + } + .wrap_some() +} diff --git a/src/bin/cnb.rs b/src/bin/cnb.rs index 64fe301..0a5c1ae 100644 --- a/src/bin/cnb.rs +++ b/src/bin/cnb.rs @@ -25,6 +25,7 @@ use cnblogs_lib::infra::infer::infer; use cnblogs_lib::infra::iter::{ExactSizeIteratorExt, IntoIteratorExt}; use cnblogs_lib::infra::option::OptionExt; use cnblogs_lib::infra::result::WrapResult; +use cnblogs_lib::logic::ing::get_ings_and_comments; use colored::Colorize; use std::env; @@ -84,6 +85,13 @@ async fn main() -> Result<()> { foe.then(|| panic_if_err(&user_info)); display::user_info(style, &user_info)? } + + _ if let Some(q) = parser::ing::query(&args) => { + + get_ings_and_comments(pat.unwrap().as_str(), &q).await; + "".to_string() + } + _ if let Some((skip, take, r#type, align)) = parser::ing::list_ing(&args) => { let ing_with_comment_iter = infer::<Result<_, _>>( try { diff --git a/src/lib.rs b/src/lib.rs index 984f7bc..4c7b191 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,3 +10,4 @@ pub mod apis; pub mod args; pub mod display; pub mod infra; +pub mod logic; diff --git a/src/logic/ing.rs b/src/logic/ing.rs new file mode 100644 index 0000000..a79f2f7 --- /dev/null +++ b/src/logic/ing.rs @@ -0,0 +1,43 @@ +//! 闪存相关逻辑 +//! + +use crate::{ + apis::ing::{query_by_id, query as iq}, + args::cmd::ing::QueryIng, + infra::iter::IntoIteratorExt, +}; + +pub async fn get_ings_and_comments(t: &str, q: &QueryIng) { + println!("{:?}", q); + if let Some(ids) = &q.id { + let a = ids + .iter() + .map(|id| async move { query_by_id(t, id).await }) + .join_all() + .await + ; + + a.iter().for_each(|i| { + match i { + Ok(e) => { + println!("{:?}", e); + } + Err(e) => { + eprintln!("{:?}", e); + } + } + }) + + } + + let a: Result<Vec<crate::apis::ing::IngEntry>, anyhow::Error> = iq(t, &q.into()).await; + match a { + Ok(e) => { + println!("{:?}", e); + } + Err(e) => { + eprintln!("{:?}", e); + } + } + +} diff --git a/src/logic/mod.rs b/src/logic/mod.rs new file mode 100644 index 0000000..b9ab01d --- /dev/null +++ b/src/logic/mod.rs @@ -0,0 +1,6 @@ +//! cli操作逻辑 +//! +//! 此模块暂定封装操作逻辑,比如是闪存的curd,闪存评论的curd。 +//! + +pub mod ing; \ No newline at end of file