Skip to content

Commit

Permalink
add ability to paginate through home
Browse files Browse the repository at this point in the history
  • Loading branch information
ericyd committed Nov 28, 2022
1 parent 91adf9d commit ed2c6b2
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions scripts/collate-home-dumps.js
Original file line number Diff line number Diff line change
@@ -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();
20 changes: 17 additions & 3 deletions src/commands/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Arguments
integer between 5 and 100.
Options:
-t, --next-token <token>
A continuation token when paginating results
--dump
Write raw JSON result to a file
-p, --profile <name>
The name of the profile to use.
Must correspond to an entry in your credentials file (~/.twitter_credentials.toml by default).
Expand All @@ -31,14 +35,16 @@ Examples:

struct Args {
count: i32,
next_token: Option<String>
}

fn parse(args: &BaseArgs) -> Args {
let count = match args.get_position::<String>(1) {
Some(count) => count.parse::<i32>().unwrap(),
None => 10,
};
Args { count }
let next_token = args.get_option("next-token", "t");
Args { count, next_token }
}

fn help() -> Result<(), TwitterError> {
Expand All @@ -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(())
}
10 changes: 7 additions & 3 deletions src/twitter/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,15 @@ impl<'c> Client<'c> {
&self,
user_id: &String,
count: i32,
) -> Result<Vec<TwitterHomeItem>, TwitterError> {
pagination_token: Option<String>
) -> Result<TwitterResponse<Vec<TwitterHomeItem>>, 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);
Expand All @@ -226,7 +230,7 @@ impl<'c> Client<'c> {
}
self.args.debug(&text);
let json: TwitterResponse<Vec<TwitterHomeItem>> = serde_json::from_str(&text)?;
Ok(json.data)
Ok(json)
} else {
Err(self.error(res))
}
Expand Down
9 changes: 9 additions & 0 deletions src/twitter/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ pub struct TwitterDeleteResponseData {
pub deleted: bool,
}

#[derive(Deserialize, Debug)]
pub struct TwitterResponseMeta {
pub next_token: Option<String>,
// pub result_count: i32,
// pub newest_id: String,
// pub oldest_id: String,
}

#[derive(Deserialize, Debug)]
pub struct TwitterResponse<T> {
pub data: T,
pub meta: Option<TwitterResponseMeta>
}

#[derive(Deserialize, Debug)]
Expand Down

0 comments on commit ed2c6b2

Please sign in to comment.