Code Monkey home page Code Monkey logo

roux's Introduction

Roux

Build Documentation Crate GitHub

Roux is a simple, (a)synchronous Reddit API wrapper implemented in Rust.

Usage

Using OAuth

To create an OAuth client with the Reddit API, use the Reddit class.

use roux::Reddit;
let client = Reddit::new("USER_AGENT", "CLIENT_ID", "CLIENT_SECRET")
    .username("USERNAME")
    .password("PASSWORD")
    .login()
    .await;

let me = client.unwrap();

It is important that you pick a good user agent. The ideal format is platform:program:version (by /u/yourname), e.g. macos:roux:v2.0.0 (by /u/beanpup_py). This will authticate you as the user given in the username function.

Usage

Using the OAuth client, you can:

Submit A Text Post

use roux::Reddit;
let client = Reddit::new("USER_AGENT", "CLIENT_ID", "CLIENT_SECRET")
    .username("USERNAME")
    .password("PASSWORD")
    .login()
    .await;

let me = client.unwrap();
me.submit_text("TEXT_TITLE", "TEXT_BODY", "SUBREDDIT").await?;

Submit A Link Post

use roux::Reddit;
let client = Reddit::new("USER_AGENT", "CLIENT_ID", "CLIENT_SECRET")
    .username("USERNAME")
    .password("PASSWORD")
    .login()
    .await;

let me = client.unwrap();
me.submit_link("LINK_TITLE", "LINK", "SUBREDDIT").await?;

Read-Only Modules

There are also read-only modules that don't need authentication:

Blocking Client

You can use a blocking (synchronous) API instead of tokio by enabling the blocking feature.

[dependencies]
roux = { version = "2", features = ["blocking"] }
use roux::Reddit;
let client = Reddit::new("USER_AGENT", "CLIENT_ID", "CLIENT_SECRET")
    .username("USERNAME")
    .password("PASSWORD")
    .login();

let me = client.unwrap();
me.submit_link("LINK_TITLE", "LINK", "SUBREDDIT");

3rd-Party Libraries

  • roux-stream provides an API for continuously streaming new submissions and comments

Contributing

Roux is not in active development but is still being maintained and currently covers the most common and useful endpoints. If you see something missing or encounter a bug, feel free to open an issue or create a pull request.

License

Roux is licensed under the MIT license (see LICENSE file).

roux's People

Contributors

akarras avatar beanpuppy avatar benjaminbrienen avatar bocanada avatar brettmayson avatar buggstream avatar cppxor2arr avatar dark0dave avatar ddemarco5 avatar deltamaniac avatar dependabot[bot] avatar frogtd avatar harababurel avatar hyde46 avatar jaltaire avatar juliankrieger avatar kibouo avatar lironhl avatar paulotten avatar purplemyst avatar pyroraptor07 avatar reneklacan avatar sabinonweb avatar scratchyone avatar spikecodes avatar striezel avatar torfsen avatar unknowndevices avatar vikigenius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

roux's Issues

Allow customization of reqwest client

Currently, roux::Subreddit uses reqwest::Client with its default settings, which might not be applicable to all use cases. For example, the default Client does not have any timeouts, so if connectivity is lost then requests simply hang indefinitely.

I'd like the possibility to supply my own Client instance when creating a Subreddit instance.

Using Me for better requests

Issue

A. If you pull data from a subreddit you are a making this query without the truly proper headers. You are missing a proper USER_AGENT
B. You are unable to pass the Authorization Bearer header and you wont be able to access private subs.

Solution

Subreddit::new_with_me(name: String, me: &Me) having a new instance method that takes in Me. So proper headers can be used.

Ideas also to add with this.

Me#subreddit(name: String) -> Subreddit
Me#user(user: String) -> User

Allowing you to be able to create these structures easier with Me.

I would also suggest moving https://github.com/halcyonnouveau/roux/blob/master/src/me/mod.rs#L111
This to the Subreddit Object and requiring a present Me object. I think it would be more organized.

Announcement: roux-stream provides a firehose-style streaming API for submissions and comments

(I'm not sure whether this is the right place for an announcement like this. Feel free to close as you see fit.)

I've just released the first version of roux-stream, a crate that provides a firehose-style API for streaming new submissions and comments from a subreddit (provided as a roux::subreddit::Subreddit instance). Examples of how to do that are included in the documentation, a more detailed example can be found in the project's repository.

I'm not sure whether you're interested in maintaining links to such 3rd-party libraries in the docs of roux itself. Let me know if you do, I'd be happy to prepare a PR.

Changing http libraries?

Roux is currently using an out of date version of reqwest. The latest version doesn't appear to support synchronous requests. Should this project change to a different library, so that it can use the latest version? I quite like ureq, it's simple, sync, and seems to be actively maintained. I'm worried that reqwest is permanently blocking if the server doesn't respond correctly, since sometimes my bot just completely freezes with no error. It doesn't seem to be the pushshift library I wrote, because that uses ureq and returns Err if it takes more than 10 seconds to receive a response.

Use authentication with read-only module

I'm trying to get comments from a subreddit which is private, is there a way to read from private from private subreddits? (Somewhat also applies to roux-stream)

Error when making request with no auth

When running request with no auth like fetching subreddit info:

#[tokio::main]
async fn main() {
    let reddit = roux::Subreddit::new("bitcoin");

    println!("{:#?}", reddit.about().await)
}

Output gives:

Err(
    Network(
        reqwest::Error {
            kind: Decode,
            source: Error("expected value", line: 1, column: 1),
        },
    ),
)

When running test 2 out of 5 tests fail:

running 5 tests
test util::option::tests::test_build_url_after ... ok
test util::option::tests::test_build_url_count ... ok
test util::option::tests::test_build_url_before ... ok
test models::user::tests::test_no_auth ... FAILED
test models::subreddit::tests::test_no_auth ... FAILED

failures:

---- models::user::tests::test_no_auth stdout ----
thread 'models::user::tests::test_no_auth' panicked at 'assertion failed: overview.is_ok()', src/models/user/mod.rs:135:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- models::subreddit::tests::test_no_auth stdout ----
thread 'models::subreddit::tests::test_no_auth' panicked at 'assertion failed: hot.is_ok()', src/models/subreddit/mod.rs:303:9


failures:
    models::subreddit::tests::test_no_auth
    models::user::tests::test_no_auth

test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.33s

error: test failed, to rerun pass `--lib`

Get article by id?

It would be nice to be able to get the article itself (title / body) from its id.

Perhaps this could be accomplished by querying the /api/by_id endpoint with a single full_name, and deserializing as a Submission.

Issue with SavedData and FeedOption after.

Following this comment: #36 (comment)

I am trying to iterate through my saved items. But using the after option just keeps giving me the items

        let saved1 = account.saved(None).await.unwrap();
        let last_child_id1 = match &saved1.data.children.last().unwrap().data {
            SavedData::Comment(comments_data) => comments_data.id.as_ref().unwrap(),
            SavedData::Submission(submissions_data) => &submissions_data.id,
        };
        dbg!("Child Last 1: {}", last_child_id1);
        let after_options = FeedOption::new().after(&saved1.data.after.unwrap());
        let saved2 = account.saved(Some(after_options)).await.unwrap();
        let last_child_id2 = match &saved2.data.children.last().unwrap().data {
            SavedData::Comment(comments_data) => comments_data.id.as_ref().unwrap(),
            SavedData::Submission(submissions_data) => &submissions_data.id,
        };
        dbg!("Child Last 2: {}", last_child_id2);
        assert_ne!(last_child_id1, last_child_id2);

The assertion fails. I also notice that it returns the same after value. I know for a fact that I have a lot of saved items, and I don't see any scenario where the same after value should be returned.

Doctests were reverted -> Tests fail when testing with the `blocking` feature enabled

When I opened the PR to add the blocking feature, I adjusted tests and doctests. This was seemingly reverted in dc5385f#diff-1b84118fef4e05f6f4c73c9ad3c5d469ec065f0ef62e20448683dadf6f281c6d

Was this done by mistake?

For the record: cargo test -F blocking fails with the following error message:

running 6 tests
test src\lib.rs - (line 8) - compile ... FAILED
test src\models\user\mod.rs - models::user (line 5) - compile ... FAILED
test src\lib.rs - (line 50) - compile ... FAILED
test src\models\subreddit\mod.rs - models::subreddit (line 5) - compile ... FAILED
test src\models\subreddit\mod.rs - models::subreddit (line 38) - compile ... FAILED
test src\lib.rs - (line 32) - compile ... FAILED

failures:

---- src\lib.rs - (line 8) stdout ----
error[E0277]: `Result<Me, RouxError>` is not a future
  --> src\lib.rs:17:17
   |
11 |           .login()
   |  _________________^
12 | |         .await;
   | |______________^ `Result<Me, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<Me, RouxError>`
   = note: Result<Me, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<Me, RouxError>`
help: remove the `.await`
   |
11 -         .login()
11 +         .login();
   |

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.
---- src\models\user\mod.rs - models::user (line 5) stdout ----
error[E0277]: `Result<BasicThing<Listing<BasicThing<OverviewData>>>, RouxError>` is not a future
  --> src\models\user\mod.rs:16:39
   |
13 |     let overview = user.overview(None).await;
   |                                       ^^^^^^ `Result<BasicThing<Listing<BasicThing<OverviewData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<OverviewData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<OverviewData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<OverviewData>>>, RouxError>`   
help: remove the `.await`
   |
13 -     let overview = user.overview(None).await;
13 +     let overview = user.overview(None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\user\mod.rs:19:41
   |
16 |     let submitted = user.submitted(None).await;
   |                                         ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
16 -     let submitted = user.submitted(None).await;
16 +     let submitted = user.submitted(None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>` is not a future
  --> src\models\user\mod.rs:22:39
   |
19 |     let comments = user.comments(None).await;
   |                                       ^^^^^^ `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>`    
help: remove the `.await`
   |
19 -     let comments = user.comments(None).await;
19 +     let comments = user.comments(None);
   |

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.
---- src\lib.rs - (line 50) stdout ----
error[E0277]: `Result<Me, RouxError>` is not a future
  --> src\lib.rs:59:17
   |
11 |           .login()
   |  _________________^
12 | |         .await;
   | |______________^ `Result<Me, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<Me, RouxError>`
   = note: Result<Me, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<Me, RouxError>`
help: remove the `.await`
   |
11 -         .login()
11 +         .login();
   |

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.
---- src\models\subreddit\mod.rs - models::subreddit (line 5) stdout ----
error[E0277]: `Result<BasicThing<Listing<BasicThing<ModeratorData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:15:44
   |
12 |     let moderators = subreddit.moderators().await;
   |                                            ^^^^^^ `Result<BasicThing<Listing<BasicThing<ModeratorData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<ModeratorData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<ModeratorData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<ModeratorData>>>, RouxError>`  
help: remove the `.await`
   |
12 -     let moderators = subreddit.moderators().await;
12 +     let moderators = subreddit.moderators();
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:18:38
   |
15 |     let hot = subreddit.hot(25, None).await;
   |                                      ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
15 -     let hot = subreddit.hot(25, None).await;
15 +     let hot = subreddit.hot(25, None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:21:44
   |
18 |     let rising = subreddit.rising(30, None).await;
   |                                            ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
18 -     let rising = subreddit.rising(30, None).await;
18 +     let rising = subreddit.rising(30, None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:24:38
   |
21 |     let top = subreddit.top(10, None).await;
   |                                      ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
help: remove the `.await`
   |
21 -     let top = subreddit.top(10, None).await;
21 +     let top = subreddit.top(10, None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:28:68
   |
25 |     let latest_comments = subreddit.latest_comments(None, Some(25)).await;
   |                                                                    ^^^^^^ `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<CommentData>>>, RouxError>`    
help: remove the `.await`
   |
25 -     let latest_comments = subreddit.latest_comments(None, Some(25)).await;
25 +     let latest_comments = subreddit.latest_comments(None, Some(25));
   |

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.
---- src\models\subreddit\mod.rs - models::subreddit (line 38) stdout ----
error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:49:47
   |
13 |     let top = subreddit.top(25, Some(options)).await;
   |                                               ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future       
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
13 -     let top = subreddit.top(25, Some(options)).await;
13 +     let top = subreddit.top(25, Some(options));
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:52:38
   |
16 |     let hot = subreddit.hot(25, None).await;
   |                                      ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
16 -     let hot = subreddit.hot(25, None).await;
16 +     let hot = subreddit.hot(25, None);
   |

error[E0277]: `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
  --> src\models\subreddit\mod.rs:59:58
   |
23 |     let next_hot = subreddit.hot(25, Some(after_options)).await;
   |                                                          ^^^^^^ `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>`
   = note: Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<BasicThing<Listing<BasicThing<SubmissionData>>>, RouxError>` 
help: remove the `.await`
   |
23 -     let next_hot = subreddit.hot(25, Some(after_options)).await;
23 +     let next_hot = subreddit.hot(25, Some(after_options));
   |

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.
---- src\lib.rs - (line 32) stdout ----
error[E0277]: `Result<Me, RouxError>` is not a future
  --> src\lib.rs:41:17
   |
11 |           .login()
   |  _________________^
12 | |         .await;
   | |______________^ `Result<Me, RouxError>` is not a future
   |
   = help: the trait `Future` is not implemented for `Result<Me, RouxError>`
   = note: Result<Me, RouxError> must be a future or must implement `IntoFuture` to be awaited
   = note: required because of the requirements on the impl of `IntoFuture` for `Result<Me, RouxError>`
help: remove the `.await`
   |
11 -         .login()
11 +         .login();
   |

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Couldn't compile the test.

failures:
    src\lib.rs - (line 32)
    src\lib.rs - (line 50)
    src\lib.rs - (line 8)
    src\models\subreddit\mod.rs - models::subreddit (line 38)
    src\models\subreddit\mod.rs - models::subreddit (line 5)
    src\models\user\mod.rs - models::user (line 5)

get_feed after?

currently there's no way of retrieving data in chunks, for example fetch the first 25 posts and at some point later retrieve another, say 25 posts, the get_feed function has a limit arg, however it's lacking an after arg, do you intend on adding it?

Blocking version for simple tasks

It's pretty cool that this is async, however sometimes people just want to make a single request and don't want to import 96 dependencies from tokio.

Improve handling of rate limiting

In torfsen/roux-stream#12, a user's code crashed with hard-to-understand error messages that originated from Serde not being able to decode a response of the comments API endpoint. The underlying reason was that the user violated Reddit's rate limits (which have been made more strict in July 2023), so the API returned an HTTP 429 ("Too many requests") response that Serde then unsurprisingly failed to parse as comment data.

Since dealing with rate limiting is a common issue in automated API clients, it would be nice if roux would provide better support here (both the user and roux-stream have no better way of handling this problem on their own, since roux does not expose any details about the process).

In particular, it would be great if roux

  1. Checked for HTTP 429 responses and propagated them in a suitable form. Alternatively and probably even better, any HTTP error response should be propagated (e.g. via reqwest's Response.raise_for_status) instead of trying to parse it as JSON as usual.
  2. Exposed the rate limiting information that the API provides via the X-Ratelimit-* HTTP headers (see the Reddit API rules). For example, the Subreddit methods could parse that information from the headers and store it in the Subreddit struct.

me saved issue with comments

So it seems like me saved is supposed to include comments, but the target type is just submissionsdata, which causes errors such as:

When I do:

    let saved = me.saved().await.unwrap();
    println!("{}", saved.data.children[0].data.selftext);

I get the following error (with backtrace) probably because my first saved item is a comment.

---- core::my_test stdout ----
thread 'core::my_test' panicked at 'called `Result::unwrap()` on an `Err` value: Network(reqwest::Error { kind: Decode, source: Error("missing field `domain`", line: 1, column: 4016) })', src/core/mod.rs:8:34
stack backtrace:
   0: rust_begin_unwind
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/panicking.rs:100:14
   2: core::result::unwrap_failed
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/result.rs:1616:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/result.rs:1298:23
   4: redorg::core::my_test::{{closure}}
             at ./src/core/mod.rs:8:17
   5: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/future/mod.rs:80:19
   6: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/future/future.rs:119:9
   7: tokio::runtime::basic_scheduler::Inner<P>::block_on::{{closure}}::{{closure}}
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:240:62
   8: tokio::coop::with_budget::{{closure}}
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/coop.rs:102:9
   9: std::thread::local::LocalKey<T>::try_with
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/std/src/thread/local.rs:399:16
  10: std::thread::local::LocalKey<T>::with
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/std/src/thread/local.rs:375:9
  11: tokio::coop::with_budget
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/coop.rs:95:5
  12: tokio::coop::budget
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/coop.rs:72:5
  13: tokio::runtime::basic_scheduler::Inner<P>::block_on::{{closure}}
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:240:39
  14: tokio::runtime::basic_scheduler::enter::{{closure}}
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:349:29
  15: tokio::macros::scoped_tls::ScopedKey<T>::set
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/macros/scoped_tls.rs:61:9
  16: tokio::runtime::basic_scheduler::enter
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:349:5
  17: tokio::runtime::basic_scheduler::Inner<P>::block_on
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:230:9
  18: tokio::runtime::basic_scheduler::InnerGuard<P>::block_on
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:501:9
  19: tokio::runtime::basic_scheduler::BasicScheduler<P>::block_on
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/basic_scheduler.rs:186:24
  20: tokio::runtime::Runtime::block_on
             at /home/void/.local/lib/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/mod.rs:461:46
  21: redorg::core::my_test
             at ./src/core/mod.rs:9:5
  22: redorg::core::my_test::{{closure}}
             at ./src/core/mod.rs:2:7
  23: core::ops::function::FnOnce::call_once
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/ops/function.rs:227:5
  24: core::ops::function::FnOnce::call_once
             at /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c/library/core/src/ops/function.rs:227:5

Headers for endpoints other than Me

Currently it's not possible to use the access token to call many of the endpoints, meaning accessing data from private or restricted communities is not really possible. It also means the bot headers aren't properly sent, such as the user agent which is against what Reddit asks bot developers to do

Error when trying to get moderators

I'm trying to collect all names of the moderators of a subreddit like this,

let mods: Vec<String> = sub
    .moderators()
    .await?.data.children
    .iter()
    .map(|x| String::from(&x.data.name))
    .collect();

but this returns me an error saying the following:

Error: error decoding response body: missing field `data` at line 1 column 38

Caused by:
    0: error decoding response body: missing field `data` at line 1 column 38
    1: missing field `data` at line 1 column 38

Inbox and comments

I'm worried that the inbox and comments structs aren't 100% accurate. Do you know of a good source to verify these? I've fixed most of the issues, but it seems like the only good way to test these is just to leave them running looking at new comments and see if they throw an error

Error when trying to get submission

I'm trying to get submissions by id like this,

let post = self
    .client
    .get_submissions(post_id)
    .await?
    .data;

but this returns me an error saying the following:

error decoding response body: missing field `data` at line 1 column 38

I assume the serde_json structure is broken again.

Make response objects public

Hey, thanks for the crate! Can you export all the response objects so we can build an API around them in our own projects?

memory leak?

Hello

I recently moved from 1.3.7 to 2.2.7 in roux-stream and now I am seeing a memory leak ?

Usage starts at around 100MB and keeps going up all the way to 500MB

Any idea what changed? or how to debug ?

No syntax highlighting in docs.rs docs and are in a poor state.

Probably because should_fail is given as an attribute in the code blocks so that tests still pass. To get both to work, we should follow this part of the Rust docs:

Yes, that's right: you can add lines that start with #, and they will be hidden from the output, but will be used when compiling your code. You can use this to your advantage. In this case, documentation comments need to apply to some kind of function, so if I want to show you just a documentation comment, I need to add a little function definition below it. At the same time, it's only there to satisfy the compiler, so hiding it makes the example more clear. You can use this technique to explain longer examples in detail, while still preserving the testability of your documentation.

The documentation itself is also pretty bad and needs some work.

Allow access to submitted through Me struct

Right now I use the Me struct to access my saved posts. But I have to create a separate User struct for access to submitted and comments.

Is there a way to also get access to submitted posts directly using the Me struct? That would be convenient.

Cannot access replies to top level comments

Thanks for working on roux !

I'm currently trying to parse the full comment tree for a given post. Unfortunately, I can only access top level comments.
When looking at the original .json output from reddit API, each comment has a replies attribute that contains the children comments.

It seems the replies attribute is missing from the returned comments listing in roux.

Missing fields in responses.

There seem to be a lot of missing fields in many of the responses, would be good to have them even if they are unimportant.

Keep in mind that the Reddit API sucks pee pee, so there will need to be some testing to make sure that the fields actually always come through or not (meaning they'll need to be Optional). For some responses it might be that all fields can become Optional just for consistency.

Error decoding response body when trying to fetch subreddit.article_comments

Those lines of code should be enough to replicate the issue:

use anyhow::Result;
use roux::Subreddit;

#[tokio::main]
async fn main() -> Result<()> {
    let subreddit = Subreddit::new("rust");

    let comments = subreddit.article_comments("t3_zv5znb", None, None).await?;

    Ok(())
}

And I'm getting the following output:

Error: error decoding response body: invalid type: map, expected a sequence at line 1 column 0

Caused by:
    0: error decoding response body: invalid type: map, expected a sequence at line 1 column 0
    1: invalid type: map, expected a sequence at line 1 column 0

My Cargo.toml consists of the following crates:

anyhow = "1.0.68"
roux = "2.2.4"
tokio = { version = "1.23.0", features = ["full"] }

Any ideas?

Refactor project into a model structure, similar to PRAW

I noticed that the current project architecture doesn't really lend itself to newly developed code. It's also hard to say where different structs live under. I opened #48 to fix this issue. I hope that this structure increases discoverability and extensibility of the project.

All tests still work as expected.

What's new:

  • Every struct now lives in its own file
  • Every data module now lives in a flat hierarchy under the models folder

Perhaps you find this restructuring useful.

Errors while trying to access subreddit data

Hi, I am new to rust so I am sorry in advance if this issue is my fault.
I was trying to use an example from docs, and I got the following error.

thread 'main' panicked at 'not currently running on the Tokio runtime.'

I did my research and I found out that probably roux expect tokio runtime but when I wrapped the main function with #[tokio::main] I am still getting the same error.

Whole code

use roux::Subreddit;
use tokio;

#[tokio::main]
async fn main() {
    let subreddit = Subreddit::new("rust");
    let rising = subreddit.rising(30, None).await;
    println!("{:?}", rising)
}

Code above is a shortened version of Basic Usage

Environment

  • Rust - 1.47.0
  • Roux - 1.1.3
  • Tokio - 0.3.0, features = ["full"]
  • OS - Manjaro

Thanks in advance for any suggestion or solution <3 Have a nice day :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.