From ed2c6b2cb0e3c8a12b1f2d6d6cff5aa546cfce9e Mon Sep 17 00:00:00 2001 From: Eric Dauenhauer Date: Mon, 28 Nov 2022 15:29:31 -0600 Subject: [PATCH] add ability to paginate through home --- README.md | 4 ++++ scripts/collate-home-dumps.js | 22 ++++++++++++++++++++++ src/commands/home.rs | 20 +++++++++++++++++--- src/twitter/client.rs | 10 +++++++--- src/twitter/response.rs | 9 +++++++++ 5 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 scripts/collate-home-dumps.js diff --git a/README.md b/README.md index ee332c2..43b6a76 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,10 @@ Arguments - `count` (Optional) - Must be between 5 and 100 + +Options + +- `next-token` (Optional) next pagination token - `dump` (Optional) writes the raw JSON response to a file Examples diff --git a/scripts/collate-home-dumps.js b/scripts/collate-home-dumps.js new file mode 100644 index 0000000..34c5288 --- /dev/null +++ b/scripts/collate-home-dumps.js @@ -0,0 +1,22 @@ +const fs = require("fs"); +const path = require("path"); + +function main() { + const files = fs + .readdirSync(process.env.HOME) + .filter((filename) => filename.match(/^home.*\.json$/)) + .sort(); + const results = files.reduce((all, file) => { + const data = fs.readFileSync(path.join(process.env.HOME, file)).toString(); + const json = JSON.parse(data); + return [...all, ...json.data]; + }, []); + + fs.writeFileSync( + path.join(process.env.HOME, "home-collated.json"), + JSON.stringify({ data: results }, null, 2) + ); + console.log("done"); +} + +main(); diff --git a/src/commands/home.rs b/src/commands/home.rs index a6c698f..f10e8d9 100644 --- a/src/commands/home.rs +++ b/src/commands/home.rs @@ -11,6 +11,10 @@ Arguments integer between 5 and 100. Options: + -t, --next-token + A continuation token when paginating results + --dump + Write raw JSON result to a file -p, --profile The name of the profile to use. Must correspond to an entry in your credentials file (~/.twitter_credentials.toml by default). @@ -31,6 +35,7 @@ Examples: struct Args { count: i32, + next_token: Option } fn parse(args: &BaseArgs) -> Args { @@ -38,7 +43,8 @@ fn parse(args: &BaseArgs) -> Args { Some(count) => count.parse::().unwrap(), None => 10, }; - Args { count } + let next_token = args.get_option("next-token", "t"); + Args { count, next_token } } fn help() -> Result<(), TwitterError> { @@ -60,11 +66,19 @@ pub fn execute(base_args: &BaseArgs) -> Result<(), TwitterError> { base_args.debug(&credentials); let me = twitter::Client::new(&credentials, base_args).me()?; - let home = twitter::Client::new(&credentials, base_args).home_v2(&me.id, args.count)?; + let home = twitter::Client::new(&credentials, base_args).home_v2(&me.id, args.count, args.next_token)?; - for item in home { + for item in home.data { item.display(); } + match home.meta { + Some(meta) => match meta.next_token { + Some(token) => println!("Next page token: {}", token), + None => () + }, + None => () + } + Ok(()) } diff --git a/src/twitter/client.rs b/src/twitter/client.rs index 24c9891..f654082 100644 --- a/src/twitter/client.rs +++ b/src/twitter/client.rs @@ -203,11 +203,15 @@ impl<'c> Client<'c> { &self, user_id: &String, count: i32, - ) -> Result, TwitterError> { + pagination_token: Option + ) -> Result>, TwitterError> { self.args .debug(&format!("Fetching home with count: {}", count)); - let base_url = format!("https://api.twitter.com/2/users/{}/tweets?max_results={}&tweet.fields=created_at,author_id,public_metrics", user_id, count); + let mut base_url = format!("https://api.twitter.com/2/users/{}/tweets?max_results={}&tweet.fields=created_at,author_id,public_metrics", user_id, count); + if pagination_token.is_some() { + base_url = format!("{}&pagination_token={}", base_url, pagination_token.unwrap()); + } let req = self.client.get(&base_url).bearer_auth(self.bearer_token()?); self.args.debug(&req); @@ -226,7 +230,7 @@ impl<'c> Client<'c> { } self.args.debug(&text); let json: TwitterResponse> = serde_json::from_str(&text)?; - Ok(json.data) + Ok(json) } else { Err(self.error(res)) } diff --git a/src/twitter/response.rs b/src/twitter/response.rs index 5fba127..edeb564 100644 --- a/src/twitter/response.rs +++ b/src/twitter/response.rs @@ -11,9 +11,18 @@ pub struct TwitterDeleteResponseData { pub deleted: bool, } +#[derive(Deserialize, Debug)] +pub struct TwitterResponseMeta { + pub next_token: Option, + // pub result_count: i32, + // pub newest_id: String, + // pub oldest_id: String, +} + #[derive(Deserialize, Debug)] pub struct TwitterResponse { pub data: T, + pub meta: Option } #[derive(Deserialize, Debug)]