fanbox api update

This commit is contained in:
2022-06-26 04:59:37 +00:00
committed by GitHub
parent 7cae064ed6
commit 742877489b
5 changed files with 193 additions and 4 deletions

View File

@@ -3,6 +3,7 @@ use quote::quote;
use syn::parse::Parse;
use syn::parse_macro_input;
use syn::token;
use syn::Block;
use syn::Expr;
use syn::Ident;
use syn::ItemFn;
@@ -112,12 +113,55 @@ pub fn async_timeout_test(attr: TokenStream, item: TokenStream) -> TokenStream {
}
struct FanboxApiTest {
pub name: Ident,
pub block: Block,
}
impl Parse for FanboxApiTest {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let name = Ident::parse(input)?;
token::Comma::parse(input)?;
let block = syn::Block::parse(input)?;
Ok(Self { name, block })
}
}
#[proc_macro]
pub fn fanbox_api_test(item: TokenStream) -> TokenStream {
let FanboxApiTest { name, block } = parse_macro_input!(item as FanboxApiTest);
let stmts = block.stmts;
let stream = quote! {
#[proc_macros::async_timeout_test(120s)]
#[tokio::test(flavor = "multi_thread")]
async fn #name() {
match std::env::var("FANBOX_COOKIES_FILE") {
Ok(path) => {
let client = FanboxClient::new();
if !client.init(Some(path)) {
panic!("Failed to initiailze the client.");
}
if !client.check_login().await {
println!("The client is not logined. Skip test.");
return;
}
#(#stmts)*
}
Err(_) => {
println!("No cookies files specified, skip test.")
}
}
}
};
stream.into()
}
struct FanboxApiQuickTest {
pub name: Ident,
pub expr: Expr,
pub errmsg: LitStr,
}
impl Parse for FanboxApiTest {
impl Parse for FanboxApiQuickTest {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let name = Ident::parse(input)?;
token::Comma::parse(input)?;
@@ -133,7 +177,7 @@ impl Parse for FanboxApiTest {
#[proc_macro]
pub fn fanbox_api_quick_test(item: TokenStream) -> TokenStream {
let FanboxApiTest { name, expr, errmsg } = parse_macro_input!(item as FanboxApiTest);
let FanboxApiQuickTest { name, expr, errmsg } = parse_macro_input!(item as FanboxApiQuickTest);
let stream = quote! {
#[proc_macros::async_timeout_test(120s)]
#[tokio::test(flavor = "multi_thread")]

1
src/fanbox/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod paginated_creator_posts;

View File

@@ -0,0 +1,86 @@
#[cfg(test)]
use crate::fanbox_api::FanboxClient;
use crate::fanbox_api::FanboxClientInternal;
use crate::gettext;
use json::JsonValue;
use proc_macros::fanbox_api_test;
use std::fmt::Debug;
use std::sync::Arc;
#[derive(Debug, derive_more::From, derive_more::Display)]
pub enum PaginatedCreatorPostsError {
String(String),
}
impl From<&'static str> for PaginatedCreatorPostsError {
fn from(v: &'static str) -> Self {
Self::String(v.to_owned())
}
}
/// List creator posts
pub struct PaginatedCreatorPosts {
/// Fanbox API Client
client: Arc<FanboxClientInternal>,
/// Pages
pages: Vec<String>,
}
impl PaginatedCreatorPosts {
/// Create a new instance.
/// * `value` - Data from fanbox api
/// * `client` - The instance of the fanbox api client
pub fn new(
value: &JsonValue,
client: Arc<FanboxClientInternal>,
) -> Result<Self, PaginatedCreatorPostsError> {
let body = &value["body"];
if !body.is_array() {
return Err(PaginatedCreatorPostsError::from(gettext(
"Failed to parse paginated data.",
)));
}
let mut pages = Vec::new();
for i in body.members() {
match i.as_str() {
Some(s) => {
pages.push(s.to_owned());
}
None => {
return Err(PaginatedCreatorPostsError::from(gettext(
"Failed to parse paginated data.",
)));
}
}
}
Ok(Self { client, pages })
}
}
impl Debug for PaginatedCreatorPosts {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let size = self.pages.len();
let mut index = 0usize;
if size == 0 {
f.write_str("PaginatedCreatorPosts { Empty }")
} else {
f.write_str("PaginatedCreatorPosts {\n")?;
for page in self.pages.iter() {
f.write_fmt(format_args!("{} {}\n", index, page))?;
index += 1;
}
f.write_str("}\n")
}
}
}
fanbox_api_test!(test_paginate_creator_posts, {
match client.paginate_creator_post("mozukun43").await {
Some(pages) => {
println!("{:?}", pages);
}
None => {
panic!("Failed to paginate creator's posts.")
}
}
});

View File

@@ -1,17 +1,20 @@
use crate::ext::atomic::AtomicQuick;
use crate::ext::replace::ReplaceWith2;
use crate::ext::rw_lock::GetRwLock;
use crate::fanbox::paginated_creator_posts::PaginatedCreatorPosts;
use crate::gettext;
use crate::opthelper::get_helper;
use crate::parser::metadata::MetaDataParser;
use crate::webclient::WebClient;
use json::JsonValue;
use proc_macros::fanbox_api_quick_test;
use std::ops::Deref;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::sync::RwLock;
/// Fanbox API client
pub struct FanboxClient {
pub struct FanboxClientInternal {
/// Web client
client: WebClient,
/// true if in is initialized
@@ -53,7 +56,7 @@ macro_rules! handle_data {
};
}
impl FanboxClient {
impl FanboxClientInternal {
/// Create an new instance
pub fn new() -> Self {
Self {
@@ -138,6 +141,7 @@ impl FanboxClient {
}
}
#[allow(dead_code)]
/// Get creator's info
/// * `creator_id` - The id of the creator
pub async fn get_creator<S: AsRef<str> + ?Sized>(&self, creator_id: &S) -> Option<JsonValue> {
@@ -153,6 +157,7 @@ impl FanboxClient {
)
}
#[allow(dead_code)]
/// List home page's post list. All supported and followed creators' posts are included.
/// * `limit` - The max count. 10 is used on Fanbox website.
pub async fn list_home_post(&self, limit: u64) -> Option<JsonValue> {
@@ -168,6 +173,7 @@ impl FanboxClient {
)
}
#[allow(dead_code)]
/// List all supporting plans.
pub async fn list_supporting_plan(&self) -> Option<JsonValue> {
self.auto_init();
@@ -179,6 +185,7 @@ impl FanboxClient {
)
}
#[allow(dead_code)]
/// List supported creators' posts.
/// * `limit` - The max count. 10 is used on Fanbox website.
pub async fn list_supporting_post(&self, limit: u64) -> Option<JsonValue> {
@@ -208,6 +215,56 @@ impl FanboxClient {
}
}
/// Fanbox API Client
pub struct FanboxClient {
/// Internal client
client: Arc<FanboxClientInternal>,
}
impl FanboxClient {
/// Create an new instance
pub fn new() -> Self {
Self {
client: Arc::new(FanboxClientInternal::new()),
}
}
#[allow(dead_code)]
/// Paginate creator posts
/// * `creator_id` - The id of the creator
pub async fn paginate_creator_post<S: AsRef<str> + ?Sized>(
&self,
creator_id: &S,
) -> Option<PaginatedCreatorPosts> {
self.auto_init();
match handle_data!(
self.client.client.get_with_param(
"https://api.fanbox.cc/post.paginateCreator",
json::object! {"creatorId": creator_id.as_ref()},
None,
),
gettext("Failed to paginate creator post:"),
gettext("Paginated data:")
) {
Some(s) => match PaginatedCreatorPosts::new(&s, Arc::clone(&self.client)) {
Ok(re) => Some(re),
Err(e) => {
println!("{}", e);
None
}
},
None => None,
}
}
}
impl Deref for FanboxClient {
type Target = FanboxClientInternal;
fn deref(&self) -> &Self::Target {
&self.client
}
}
fanbox_api_quick_test!(
test_list_home_post,
client.list_home_post(10),

View File

@@ -25,6 +25,7 @@ mod error;
mod exif;
/// Used to extend some thirdparty library
mod ext;
mod fanbox;
mod fanbox_api;
mod i18n;
mod list;