Git Product home page Git Product logo

mastodon-async's People

Contributors

baummarten avatar dependabot[bot] avatar dscottboggs avatar dym-sh avatar jhwgh1968 avatar joshka avatar matthiasbeyer avatar spriteovo avatar vbrandl 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

Watchers

 avatar  avatar

mastodon-async's Issues

Serde de-serialization issue with 'audio' status attachment (unknown variant)

Steps to reproduce

  1. Use Mastodon::statuses method to retrieve statuses e.g:
  let mut request = StatusesRequest::new();
  request.only_media();
  let statuses = if initial {
      manual.initial_statuses
  } else {
      manual.statuses
  };
  request.limit(statuses);
  let statuses = mastodon.statuses(&you.id, request).await?;
  1. If timeline of user contains any statuses with attachment of type audio then following error will be thrown:
Serde(
    Error("unknown variant `audio`, expected one of `image`, `video`, `gifv`, `unknown`", line: 1, column: 165623),
)

Note: Sample code available at github.

Full backtrace

stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: masto_vision::handler::Handler::run::{{closure}}::{{closure}}::{{closure}}
             at ./src/handler.rs:224:21
   3: <T as futures_util::fns::FnOnce1<A>>::call_once
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/fns.rs:15:9
   4: <futures_util::fns::UnwrapOrElseFn<F> as futures_util::fns::FnOnce1<core::result::Result<T,E>>>::call_once::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/fns.rs:332:32
   5: core::result::Result<T,E>::unwrap_or_else
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/result.rs:1430:23
   6: <futures_util::fns::UnwrapOrElseFn<F> as futures_util::fns::FnOnce1<core::result::Result<T,E>>>::call_once
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/fns.rs:332:9
   7: <futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/future/future/map.rs:57:73
   8: <futures_util::future::future::Map<Fut,F> as core::future::future::Future>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/lib.rs:91:13
   9: <futures_util::future::try_future::UnwrapOrElse<Fut,F> as core::future::future::Future>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.29/src/lib.rs:91:13
  10: masto_vision::handler::Handler::run::{{closure}}::{{closure}}
             at ./src/handler.rs:226:18
  11: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/future/future.rs:125:9
  12: tokio::runtime::task::core::Core<T,S>::poll::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/core.rs:328:17
  13: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/loom/std/unsafe_cell.rs:16:9
  14: tokio::runtime::task::core::Core<T,S>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/core.rs:317:13
  15: tokio::runtime::task::harness::poll_future::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:485:19
  16: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panic/unwind_safe.rs:272:9
  17: std::panicking::try::do_call
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:552:40
  18: ___rust_try
  19: std::panicking::try
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:516:19
  20: std::panic::catch_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panic.rs:142:14
  21: tokio::runtime::task::harness::poll_future
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:473:18
  22: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:208:27
  23: tokio::runtime::task::harness::Harness<T,S>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:153:15
  24: tokio::runtime::task::raw::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/raw.rs:271:5
  25: tokio::runtime::task::raw::RawTask::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/raw.rs:201:18
  26: tokio::runtime::task::LocalNotified<S>::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/mod.rs:408:9
  27: tokio::runtime::scheduler::multi_thread::worker::Context::run_task::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:577:13
  28: tokio::runtime::coop::with_budget
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/coop.rs:107:5
  29: tokio::runtime::coop::budget
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/coop.rs:73:5
  30: tokio::runtime::scheduler::multi_thread::worker::Context::run_task
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:576:9
  31: tokio::runtime::scheduler::multi_thread::worker::Context::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:526:24
  32: tokio::runtime::scheduler::multi_thread::worker::run::{{closure}}::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:491:21
  33: tokio::runtime::context::scoped::Scoped<T>::set
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/context/scoped.rs:40:9
  34: tokio::runtime::context::set_scheduler::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/context.rs:176:26
  35: std::thread::local::LocalKey<T>::try_with
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/thread/local.rs:270:16
  36: std::thread::local::LocalKey<T>::with
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/thread/local.rs:246:9
  37: tokio::runtime::context::set_scheduler
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/context.rs:176:9
  38: tokio::runtime::scheduler::multi_thread::worker::run::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:486:9
  39: tokio::runtime::context::runtime::enter_runtime
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/context/runtime.rs:65:16
  40: tokio::runtime::scheduler::multi_thread::worker::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:478:5
  41: tokio::runtime::scheduler::multi_thread::worker::Launch::launch::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/scheduler/multi_thread/worker.rs:447:45
  42: <tokio::runtime::blocking::task::BlockingTask<T> as core::future::future::Future>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/blocking/task.rs:42:21
  43: tokio::runtime::task::core::Core<T,S>::poll::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/core.rs:328:17
  44: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/loom/std/unsafe_cell.rs:16:9
  45: tokio::runtime::task::core::Core<T,S>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/core.rs:317:13
  46: tokio::runtime::task::harness::poll_future::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:485:19
  47: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panic/unwind_safe.rs:272:9
  48: std::panicking::try::do_call
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:552:40
  49: ___rust_try
  50: std::panicking::try
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:516:19
  51: std::panic::catch_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panic.rs:142:14
  52: tokio::runtime::task::harness::poll_future
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:473:18
  53: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:208:27
  54: tokio::runtime::task::harness::Harness<T,S>::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/harness.rs:153:15
  55: tokio::runtime::task::raw::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/raw.rs:271:5
  56: tokio::runtime::task::raw::RawTask::poll
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/raw.rs:201:18
  57: tokio::runtime::task::UnownedTask<S>::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/task/mod.rs:445:9
  58: tokio::runtime::blocking::pool::Task::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/blocking/pool.rs:159:9
  59: tokio::runtime::blocking::pool::Inner::run
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/blocking/pool.rs:513:17
  60: tokio::runtime::blocking::pool::Spawner::spawn_thread::{{closure}}
             at /Users/pecet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.34.0/src/runtime/blocking/pool.rs:471:13
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

"missing field `history`"

A few days ago I wrote a basic command-line poster against elefren. Then you released this. I upgraded mostly by sprinkling .await into approriate places.

use getopts::Options;
use std::env;
use std::error::Error;

use mastodon_async::helpers::toml; // requires `features = ["toml"]`
use mastodon_async::prelude::*;
use mastodon_async::status_builder::Visibility;
use mastodon_async::Language;

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let mut credfile = env::var("HOME").unwrap();
    credfile.push_str("/.config/mastodon-data.toml");
    let mut vis = Visibility::Public;

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help text");
    opts.optflag("u", "unlisted", "post is unlisted");
    opts.optflag("f", "followers", "post is private (followers only)");
    opts.optopt("c", "credentials", "path to credentials toml", "FILE");
    opts.reqopt("t", "text", "text of status post", "TEXT");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            print_usage(&program, opts);
            panic!("{}", f.to_string())
        }
    };
    if matches.opt_present("h") {
        print_usage(&program, opts);
        return Ok(());
    }
    if matches.opt_present("c") {
        credfile = matches.opt_str("c").unwrap();
    }
    if matches.opt_present("u") {
        vis = Visibility::Unlisted;
    }
    if matches.opt_present("f") {
        vis = Visibility::Private;
    }

    let mastodon = if let Ok(data) = toml::from_file(credfile.clone()) {
        Mastodon::from(data)
    } else {
        panic!("Unable to load credentials {}", credfile)
    };

    mastodon.verify_credentials().await?;

    let status = StatusBuilder::new()
        .status(matches.opt_str("t").unwrap())
        .visibility(vis)
        .language(Language::Eng)
        .build()?;

    mastodon.new_status(status).await?;

    Ok(())
}

and while this does indeed post, it also prints:

Error: Serde(Error("missing field 'history'", line: 1, column: 4529))

(the "history"'s actually in backquotes, which I've changed for consistent formatting).

Any suggestion as to where I should look for the cause of this?

Notifications API: Unknown variant "poll"

It seems that the notification for "a poll you voted on has ended" was simply not implemented, resulting in the Serde parsing error in the title.

I'll probably write a patch myself in the next couple days unless you can fix it before then.

log -> tracing

I'm using tracing in my app toot-rs which uses mastodon-async, and haven't yet discovered a good way to get the kv logs through into my log file easily. This makes debugging api failures a little more difficult than it could be.

I wonder if you're amenable to a PR for using tracing instead of log, or are there non-obvious blockers to this?

Build without OpenSSL

I'm trying to use mastodon-async without depending on OpenSSL. On docs.rs I can see, that the default features use reqwest/default-tls but there is a rusttls-tls feature for mastodon-async.

I'm trying the following in Cargo.toml:

mastodon-async = { version = "1.2.2", default-features = false, features = ["rustls-tls"] }

This causes an error since I don't have OpenSSL available in my environment.

thiserror?

When reading the codebase, I found that the error type in this codebase is hand-written.

Would you be interested in me rewriting the error module using thiserror (and probably reducing the code size quite a bit there...)?

I'd rather ask before I invest a few minutes that then get rejected anyways 😆

User-agent missing in http requests

Hi there 👋 Merry Christmas 🎅 🎄
Tried to use the mastodon-async with GoToSocial - ActivityPub server which implements subset of the Mastodon API. Faced a problem that it rejects requests if no user-agent header set.
Not sure if this header should be required really, but I think it worth to add the user-agent into the default http client anyway. Any thoughts? I can prepare the PR if you're Ok to merge this change.

"only-entities" feature?

I have a problem in my project... I need to pass data from mastodon-async to my frontend, which is compiled to WASM. For example mastodon_async::entities::status::Status.
Compiling mastodon-async to WASM is not possible, because of tokio, which cannot be compiled to WASM with the features mastodon-async needs.

I could, theoretically, copy all entity-types and add conversion from mastodon-async entity types to my own.

Another way would be to add a feature to mastodon-async for disabling everything except the entity types (which is the only thing I need to be able to pass them to the frontend). This way I could use the crate in my frontend only for the entity types.

I know this is a niche issue, but I figured that asking would be better than copying about 500 LOC into my codebase.

Any thoughts on this?

Invalidinput, message "invalid socket address"

Hello,
I just finished writing a bot with your library, so I get the authorize link I get the token from my account on my site
I enter it and I get:

Error: Error { kind: InvalidInput, message: "invalid socket address" }

How can I solve this? not sure if this is related to the server, my desktop or my bot?
I am using it like:

// Function to register the Mastodon client
pub async fn register(api_base_url: &str) -> Result<mastodon_async::Data, Box<dyn Error>> {
    let registration = Registration::new(api_base_url)
        .client_name("masto2usenet")
        .build()
        .await?;
    let mastodon = cli::authenticate(registration).await?;
    toml::to_file(&mastodon.data, "mastodon-data.toml")?;
    Ok(mastodon.data.clone())
}

I have run this curl and I do get a valid_key

curl \
	-H 'Authorization: Bearer our_access_token_here' \
	https://mastodon.example/api/v1/apps/verify_credentials

ok, so I ran your /examples/ and was able to get that working, so must be in my bot.
I must be parsing/implementing something wrong, here is the code:
https://git.sr.ht/~rek2/Masto2Usenet

Any help will be appreciated.

404 on dismiss_notification() call

mastodon-async version 1.3.0
mastodon server version 4.1.9

When making a call to client.dismiss_notification(), the following error is returned:

Error: Api { status: 404, response: ApiError { error: "Not Found", error_description: None } }

It would seem that the route in mastodon.rs needs to be updated from notifications/dismiss with form data to notifications/:id/dismiss with the id being provided as a path parameter.

Comb-through A.K.A. v2

It has come to my attention that the Mastodon API has been updated a lot since the original work this was based on, and we need to comb through the API documentation ensuring that each type is implemented according to the spec.

When this is released, we will cut a new v2.0 release. Breaking changes will be a part of this.

Tasks for this PR

Comb through entities

Entities, second pass

  • Enums renamed for serde (#82)
  • Enums impl IsVariant
  • Examples tested (#80)
  • cargo doc (#83)
  • prelude (#84)

Comb through methods

  • apps (#91)
  • accounts (#124)
    • bookmarks
    • favourites
    • mutes
    • blocks
    • domain_blocks
    • filters
    • reports
    • follow_requests
    • endorsements
    • featured_tags
    • preferences
    • followed_tags
    • suggestions
    • tags
  • statuses
    • media
    • polls
    • scheduled_statuses
  • timelines
    • conversations
    • lists
    • markers
    • streaming
  • notifications
    • push
  • search
  • instance
    • trends
    • directory
    • custom_emojis
    • announcements
  • admin
    • admin/accounts
    • admin/domain_blocks
    • admin/reports
    • admin/trends
    • canonical_email_blocks
    • dimensions
    • domain_allows
    • email_domain_blocks
    • ip_blocks
    • measures
    • retention
  • proofs
  • oembed

Finishing up/other tasks

  • Ensure mastodon_async::requests module is migrated entirely into mastodon_async_entities::forms
  • Revisit/review the prelude and public-facing API.

Clone implementation as Into

impl<'a> Into<Option<StatusesRequest<'a>>> for &'a mut StatusesRequest<'a> {
fn into(self) -> Option<StatusesRequest<'a>> {
Some(StatusesRequest {
only_media: self.only_media,
exclude_replies: self.exclude_replies,
pinned: self.pinned,
max_id: self.max_id.clone(),
since_id: self.since_id.clone(),
limit: self.limit.clone(),
min_id: self.min_id.clone(),
})
}
}

I found this during my work on #14 - this is a implicit Clone implementation that should be removed and implemented properly, IMO.
Not sure why it was done this way, but I am pretty sure that this shouldn't be in here...

get_home_timeline throws serde deserialization error about filter::Filter

This bug is present in the comb branch.

get_home_timeline returns a page of status::Status data that contains a vector of filter::Result data as the filtered field, which in turn contains filter::Filter data. The Filter type assumes the keywords and statuses fields to be always present, but when fetching the timeline from /api/v1/timelines/public endpoint, the contained filter objects do not have those fields present. This causes a deserialization error from serde. This can be verified by adding a filter in Mastodon that targets some posts in the user's current home timeline, and hitting the API endpoint.

This can be fixed by adding #[serde(default)] annotation over the fields.

Missing parameter "code" in authorization

Hi,

I am getting the following error in my application:

Api { status: 400, response: ApiError { error: "invalid_request", error_description: Some("Missing required parameter: code.") } }

The code that causes this issue is

pub async fn complete(&self, code: &str) -> Result<Mastodon> {
let url = format!(
"{}/oauth/token?client_id={}&client_secret={}&code={}&grant_type=authorization_code&\
redirect_uri={}",
self.base, self.client_id, self.client_secret, code, self.redirect
);
debug!(url = url; "completing registration");
let response = self.client.post(&url).send().await?;
debug!(
status = log_serde!(response Status), url = url,
headers = log_serde!(response Headers);
"received API response"
);
let token: AccessToken = read_response(response).await?;
debug!(url = url, body = as_serde!(token); "parsed response body");
let data = self.registered(token.access_token);
trace!(auth_data = as_serde!(data); "registered");
Ok(Mastodon::new(self.client.clone(), data))
}

But from what I see, the code parameter is there. I'm not yet sure how to debug this issue any further...

Replace chrono dependency

This crate depends on chrono, which itself depends on a vulnerable time version (0.1.*).

Maybe it is a good idea to remove chrono from the equation? 😆

reqwest::Error in streaming example

Trying out the streaming example, I get this error:

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

Version: v1.0.3

The first example that prints user information works for me.

[Feature Request] Server may take time to process media

After I attached a GIF media and tried to post a new status with it, I got an error:

Api { status: 422, response: ApiError { error: "Cannot attach files that have not finished processing. Try again in a moment!", error_description: None } }

According to the API /media docs.

202: Accepted

MediaAttachment was created successfully, but the full-size file is still processing. Note that the MediaAttachment’s url will still be null, as the media is still being processed in the background. However, the preview_url should be available. Use GET /api/v1/media/:id to check the status of the media attachment.

Checking if an attachment has finished processing is impossible for now. I suggest:

  • Make Mastodon::media method returns an enum to indicate if it is still being processing.

  • Add a new method Mastodon::check_media_status to check if a media is finished processing.

  • Add a new method Mastodon::upload_media (maybe another better name) to wrap the wait process, it receives a timeout value from users.

Help on streaming event handling

Hi, I'm in the process of learning rust and I thought it would be good practice to code a small bot that does simple things. But I've already hit an issue I can't really wrap my head around.

For example, I'd like to get notifications from and reblog the status if I'm mentioned in it.
So I thought of doing something like that taking one of the examples:

async fn run() -> Result<()> {
    use log::warn;

    let mastodon = if let Ok(data) = toml::from_file("mastodon-data.toml") {
        Mastodon::from(data)
    } else {
        register().await?
    };
    let stream = mastodon.stream_user().await?;
    println!("watching mastodon for events. This will run forever, press Ctrl+C to kill the program.");
    stream
        .try_for_each(|event| async move {
            match event {
                // fill in how you want to handle events here.
                Event::Notification(notif) => {
                    if notif.notification_type == NotificationType::Mention {
                        // mastodon.reblog(&notif.status.unwrap().id).await?;
                        println!("I have reblogged the status");
                    } else {
                        println!("Haven't done anything with notif");
                    }
                },
                _ => warn!(event = as_serde!(event); "unrecognized event received"),
            }
            Ok(())
        })
        .await?;
    Ok(())
}

However, I have an issue with the commented line // mastodon.reblog(&notif.status.unwrap().id).await?; as I don't really know how to work with the mastodon client variable. It seems I cannot borrow it to handle the event.

This looks like a really simple beginner issue but I would really appreciate some help.
I'm not sure how I'm supposed to handle events if it requires an action from the client?

Alexis

Replacing hyper-old-types

This crate currently uses hyper-old-types, which is deprecated and also depends on a time version which has a CVE (0.1.* version).

Probably not that easy, tbh.

Switch to thiserror was semver breaking

Unfortunately, I found out that the switch to thiserror was semver breaking.

There are some other small semver breaking changes in main since 1.0.0 which are fixable I guess, but the switch to thiserror is probably not fixable.

I am not sure what we want here,... I don't care too much about this particular semver breaking change and this crate isn't used widely yet... but still. Should we roll back and postpone the switch to thiserror?

🤔

get_home_timeline throws serde deserialization error about card::Card.author_url

This bug is present in the comb branch.

get_home_timeline returns a page of status::Status data that contains card::Card that has an author_url field of type Option<Url>. This causes serde to validate that the field value is an actual URL. However, this data comes from the oembed data of the linked web pages in posts, and hence may be invalid. For example, this post has the author URL set to a person's name.

So, either the validation should be relaxed to ignore invalid values present in the field, or the field type should be changed to String.

The same issue may be present for the provider_url and embed_url fields of the card::Card type as well.

search_accounts got a RelativeUrlWithoutBase error

Version

v1.2.2

Error log

mastodon_async::mastodon making API request
    url /api/v1/accounts/search?q=test&following=false
    method get
    call_id b3623b8d-357d-456d-82bd-661973127a97
Error: Http(reqwest::Error { kind: Builder, source: RelativeUrlWithoutBase })

Test Code

use futures_util::StreamExt;
use mastodon_async::prelude::*;
use mastodon_async::mastodon::Mastodon;
use mastodon_async::helpers::toml;
use mastodon_async::{helpers::cli, Result};
use mastodon_async::entities::account::Account;

#[tokio::main]
async fn main() -> Result<()> {
    femme::with_level(log::LevelFilter::Trace);
    let mastodon = if let Ok(data) = toml::from_file("settings.toml") {
        Mastodon::from(data)
    } else {
        register().await?
    };
    let base_url = &mastodon.data.base;
    let me = mastodon.verify_credentials().await?;

    let result = mastodon.search_accounts("test", None, false).await?;
    for account in result.initial_items {
        println!("{} {}", account.acct, account.id);
    }

    Ok(())
}

404 error when trying to use stream_notifications

I've used stream_user without issue but only need the notifications so I tried switching to using stream_notifications.
However I'm receiving a 404 error:

Error: Api { status: 404, response: ApiError { error: "Not found", error_description: None } }

Both streaming APIs need the same authorizations so I don't think it's coming from there.

No error when I revert back to using stream_user

1.0.2 incompatible to 1.0.1

The 1.0.2 release is semver incompatible to the 1.0.1 release!

The newly added dependency made the Mastodon type not Send anymore!

Please roll back this change!

directory API?

I don't see any way to access the list of profiles on a particular server... is this something that is supported and I just couldn't find it? if not, would you consider this addition?

How to set the media description?

Hi there,

I am planning to use your library to create a cross poster from my website to my mastodon account. After checking the docs it seems as if you don't support setting a media description is this correct?

Media description is vital to a11y, so it would be nice if this could be implemented.

Or am I missing something?

Best regards and, if you celebrate it, merry christmas,
CK

400 bad request with `media` and `media_with_thumbnail` methods

Hi there,

when trying to upload a picture with the media request I get a 400 bad request response. Doesn't matter if I post to my local test installation or an publicly available Mastodon instance.

Creating a status w/o medium works.

This is my code:

    let toml_path = env::var("MASTODON_TOML").expect("env variable MASTODON_TOML not set");
    let mastodon = Mastodon::from(toml::from_file(toml_path).unwrap());

    let path = format!(
        "{}/{}/original/{}",
        image_base_path(),
        picture.id,
        picture.image_file_name
    );

    let thumbnail_path = format!(
        "{}/{}/thumbnail/{}",
        image_base_path(),
        picture.id,
        picture.image_file_name
    );

    let attachment = mastodon
        .media_with_thumbnail(path, thumbnail_path, picture.alt.clone())
        .await
        .map_err(|e| {
            println!("Error uploading media: {}", e);
            e
        })?;

That produces this error message:

Error uploading media: Api { status: 400, response: ApiError { error: "Bad Request", error_description: None } }

Am I doing something wrong or is this a bug in the library?

Best regards,
CK

the trait `tracing::Value` is not implemented for `valuable::Value<'_>` in comb branch

Hi again :) Faced this while working on #112 I'm just learning rust, so sorry if I'm doing something wrong. The example runs Ok, but simplest test app fails to compile for some reason. Here's the example:

/tmp ❯ cargo new mastodon-async-test
/tmp ❯ cd mastodon-async-test/
/tmp ❯ cargo add --git 'https://github.com/dscottboggs/mastodon-async.git' --branch comb  mastodon-async
    Updating git repository `https://github.com/dscottboggs/mastodon-async.git`
      Adding mastodon-async (git) to dependencies.
             Features:
             - all
             - env
             - envy
             - json
             - mt
             - rustls-tls
             - toml
    Updating git repository `https://github.com/dscottboggs/mastodon-async.git`
    Updating crates.io index
/tmp ❯ cargo build
SKIPPED...
SKIPPED...
   Compiling mastodon-async-entities v1.2.2 (https://github.com/dscottboggs/mastodon-async.git?branch=comb#9b73e2dc)
error[E0277]: the trait bound `valuable::Value<'_>: tracing::Value` is not satisfied
  --> /home/akkerman/.cargo/git/checkouts/mastodon-async-37543d46befb091a/9b73e2d/src/helpers/read_response.rs:23:5
   |
23 | /     trace!(
24 | |         response = as_value!(response, Response),
25 | |         "attempting to stream response"
26 | |     );
   | |_____^ the trait `tracing::Value` is not implemented for `valuable::Value<'_>`
   |
   = help: the following other types implement trait `tracing::Value`:
             &'a T
             &'a mut T
             (dyn StdError + 'static)
             (dyn StdError + Sync + 'static)
             (dyn StdError + std::marker::Send + 'static)
             (dyn StdError + std::marker::Send + Sync + 'static)
             Arguments<'a>
             DebugValue<T>
           and 34 others
   = note: required for the cast from `&valuable::Value<'_>` to `&dyn tracing::Value`
   = note: this error originates in the macro `$crate::valueset` which comes from the expansion of the macro `trace` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `valuable::Value<'_>: tracing::Value` is not satisfied
   --> /home/akkerman/.cargo/git/checkouts/mastodon-async-37543d46befb091a/9b73e2d/src/registration.rs:362:9
    |
362 | /         debug!(
363 | |             url,
364 | |             response = as_value!(response, Response),
365 | |             "received API response"
366 | |         );
    | |_________^ the trait `tracing::Value` is not implemented for `valuable::Value<'_>`
    |
    = help: the following other types implement trait `tracing::Value`:
              &'a T
              &'a mut T
              (dyn StdError + 'static)
              (dyn StdError + Sync + 'static)
              (dyn StdError + std::marker::Send + 'static)
              (dyn StdError + std::marker::Send + Sync + 'static)
              Arguments<'a>
              DebugValue<T>
            and 34 others
    = note: required for the cast from `&valuable::Value<'_>` to `&dyn tracing::Value`
    = note: this error originates in the macro `$crate::valueset` which comes from the expansion of the macro `debug` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `valuable::Value<'_>: tracing::Value` is not satisfied
   --> /home/akkerman/.cargo/git/checkouts/mastodon-async-37543d46befb091a/9b73e2d/src/mastodon.rs:128:5
    |
128 | /     streaming! {
129 | |         "returns events that are relevant to the authorized user, i.e. home timeline & notifications"
130 | |         stream_user@"user",
131 | |         "All public posts known to the server. Analogous to the federated timeline."
...   |
148 | |         stream_direct@"direct",
149 | |     }
    | |_____^ the trait `tracing::Value` is not implemented for `valuable::Value<'_>`
    |
    = help: the following other types implement trait `tracing::Value`:
              &'a T
              &'a mut T
              (dyn StdError + 'static)
              (dyn StdError + Sync + 'static)
              (dyn StdError + std::marker::Send + 'static)
              (dyn StdError + std::marker::Send + Sync + 'static)
              Arguments<'a>
              DebugValue<T>
            and 34 others
    = note: required for the cast from `&valuable::Value<'_>` to `&dyn tracing::Value`
    = note: this error originates in the macro `$crate::valueset` which comes from the expansion of the macro `streaming` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `valuable::Value<'_>: tracing::Value` is not satisfied
   --> /home/akkerman/.cargo/git/checkouts/mastodon-async-37543d46befb091a/9b73e2d/src/mastodon.rs:204:9
    |
204 | /         debug!(
205 | |             response = as_value!(response, Response),
206 | |             "received API response"
207 | |         );
    | |_________^ the trait `tracing::Value` is not implemented for `valuable::Value<'_>`
    |
    = help: the following other types implement trait `tracing::Value`:
              &'a T
              &'a mut T
              (dyn StdError + 'static)
              (dyn StdError + Sync + 'static)
              (dyn StdError + std::marker::Send + 'static)
              (dyn StdError + std::marker::Send + Sync + 'static)
              Arguments<'a>
              DebugValue<T>
            and 34 others
    = note: required for the cast from `&valuable::Value<'_>` to `&dyn tracing::Value`
    = note: this error originates in the macro `$crate::valueset` which comes from the expansion of the macro `debug` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `mastodon-async` (lib) due to 13 previous errors

Pagination for local Timeline

Hello,

Currently get_public_timeline() returns a Result<Vec<Status>> would it be possible to have it return a Result<Page<Status>> like get_home_timeline() does? the API seems to be capable of pagination.

Best regards,

Daniel

`magic` feature leads to compile error: future created by async block is not `Send`

Hi,

due to the magic handle in the MastodonClient struct now the struct is no longer + Send. This leads to problems in async code.

I understand that is has performance implications to create the magic database handle on every request, but are you open to do so?

Complete error trace:

error: future cannot be sent between threads safely
   --> src/pictures/new.rs:88:36
    |
88  |                   tokio::task::spawn(async move {
    |  ____________________________________^
89  | |                     let _ = post_picture(&picture).await;
90  | |                 });
    | |_________________^ future created by async block is not `Send`
    |
    = help: within `MastodonClient`, the trait `std::marker::Send` is not implemented for `*mut magic_sys::magic_set`
note: future is not `Send` as this value is used across an await
   --> src/posse/mastodon.rs:77:9
    |
59  |     let mastodon = Mastodon::from(toml::from_file(toml_path).unwrap());
    |         -------- has type `mastodon_async::Mastodon` which is not `Send`
...
77  |         .await
    |         ^^^^^^ await occurs here, with `mastodon` maybe used later
...
95  | }
    | - `mastodon` is later dropped here
note: required by a bound in `tokio::spawn`
   --> /Users/ckruse/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.23.0/src/task/spawn.rs:163:21
    |
163 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `tokio::spawn`

Best regards,
CK

[Feature Request] Upload media from memory stream

Currently Mastodon::media only accepts impl AsRef<Path> as an argument, it would be nice to have a new method that accepts data from a memory stream, which would avoid writing out files to disks.

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.