mirror of
https://framagit.org/veretcle/scootaloo.git
synced 2025-07-20 17:11:19 +02:00
169 lines
5.0 KiB
Rust
169 lines
5.0 KiB
Rust
// auto imports
|
|
use crate::config::MastodonConfig;
|
|
|
|
// std
|
|
use std::{
|
|
borrow::Cow,
|
|
error::Error,
|
|
collections::HashMap,
|
|
io::stdin,
|
|
};
|
|
|
|
// htmlescape
|
|
use htmlescape::decode_html;
|
|
|
|
// egg-mode
|
|
use egg_mode::{
|
|
tweet::Tweet,
|
|
entities::{UrlEntity, MentionEntity},
|
|
};
|
|
|
|
// elefren
|
|
use elefren::{
|
|
prelude::*,
|
|
apps::App,
|
|
scopes::Scopes,
|
|
};
|
|
|
|
|
|
/// Decodes the Twitter mention to something that will make sense once Twitter has joined the
|
|
/// Fediverse
|
|
fn twitter_mentions(ums: &Vec<MentionEntity>) -> HashMap<String, String> {
|
|
let mut decoded_mentions = HashMap::new();
|
|
|
|
for um in ums {
|
|
decoded_mentions.insert(format!("@{}", um.screen_name), format!("@{}@twitter.com", um.screen_name));
|
|
}
|
|
|
|
decoded_mentions
|
|
}
|
|
|
|
/// Decodes urls from UrlEntities
|
|
fn decode_urls(urls: &Vec<UrlEntity>) -> HashMap<String, String> {
|
|
let mut decoded_urls = HashMap::new();
|
|
|
|
for url in urls {
|
|
if url.expanded_url.is_some() {
|
|
// unwrap is safe here as we just verified that there is something inside expanded_url
|
|
decoded_urls.insert(String::from(&url.url), String::from(url.expanded_url.as_deref().unwrap()));
|
|
}
|
|
}
|
|
|
|
decoded_urls
|
|
}
|
|
|
|
/// Gets Mastodon Data
|
|
pub fn get_mastodon_token(masto: &MastodonConfig) -> Mastodon {
|
|
let data = Data {
|
|
base: Cow::from(String::from(&masto.base)),
|
|
client_id: Cow::from(String::from(&masto.client_id)),
|
|
client_secret: Cow::from(String::from(&masto.client_secret)),
|
|
redirect: Cow::from(String::from(&masto.redirect)),
|
|
token: Cow::from(String::from(&masto.token)),
|
|
};
|
|
|
|
Mastodon::from(data)
|
|
}
|
|
|
|
/// Builds toot text from tweet
|
|
pub fn build_basic_status(tweet: &Tweet) -> Result<String, Box<dyn Error>> {
|
|
let mut toot = String::from(&tweet.text);
|
|
|
|
let decoded_urls = decode_urls(&tweet.entities.urls);
|
|
|
|
for decoded_url in decoded_urls {
|
|
toot = toot.replace(&decoded_url.0, &decoded_url.1);
|
|
}
|
|
|
|
let decoded_mentions = twitter_mentions(&tweet.entities.user_mentions);
|
|
|
|
for decoded_mention in decoded_mentions {
|
|
toot = toot.replace(&decoded_mention.0, &decoded_mention.1);
|
|
}
|
|
|
|
if let Ok(t) = decode_html(&toot) {
|
|
toot = t;
|
|
}
|
|
|
|
Ok(toot)
|
|
}
|
|
|
|
/// Generic register function
|
|
/// As this function is supposed to be run only once, it will panic for every error it encounters
|
|
/// Most of this function is a direct copy/paste of the official `elefren` crate
|
|
pub fn register(host: &str) {
|
|
let mut builder = App::builder();
|
|
builder.client_name(Cow::from(String::from(env!("CARGO_PKG_NAME"))))
|
|
.redirect_uris(Cow::from(String::from("urn:ietf:wg:oauth:2.0:oob")))
|
|
.scopes(Scopes::write_all())
|
|
.website(Cow::from(String::from("https://framagit.org/veretcle/scootaloo")));
|
|
|
|
let app = builder.build().expect("Cannot build the app");
|
|
|
|
let registration = Registration::new(host).register(app).expect("Cannot build registration object");
|
|
let url = registration.authorize_url().expect("Cannot generate registration URI!");
|
|
|
|
println!("Click this link to authorize on Mastodon: {}", url);
|
|
println!("Paste the returned authorization code: ");
|
|
|
|
let mut input = String::new();
|
|
stdin().read_line(&mut input).expect("Unable to read back registration code!");
|
|
|
|
let code = input.trim();
|
|
let mastodon = registration.complete(code).expect("Unable to create access token!");
|
|
|
|
let toml = toml::to_string(&*mastodon).unwrap();
|
|
|
|
println!("Please insert the following block at the end of your configuration file:\n[mastodon]\n{}", toml);
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_twitter_mentions() {
|
|
let mention_entity = MentionEntity {
|
|
id: 12345,
|
|
range: (1, 3),
|
|
name: String::from("Ta Mere l0l"),
|
|
screen_name: String::from("tamerelol"),
|
|
};
|
|
|
|
let twitter_ums = vec![mention_entity];
|
|
|
|
let mut expected_mentions = HashMap::new();
|
|
expected_mentions.insert(String::from("@tamerelol"), String::from("@tamerelol@twitter.com"));
|
|
|
|
let decoded_mentions = twitter_mentions(&twitter_ums);
|
|
|
|
assert_eq!(expected_mentions, decoded_mentions);
|
|
}
|
|
|
|
#[test]
|
|
fn test_decode_urls() {
|
|
let url_entity1 = UrlEntity {
|
|
display_url: String::from("tamerelol"),
|
|
expanded_url: Some(String::from("https://www.nintendojo.fr/dojobar")),
|
|
range: (1, 3),
|
|
url: String::from("https://t.me/tamerelol"),
|
|
};
|
|
|
|
let url_entity2 = UrlEntity {
|
|
display_url: String::from("tamerelol"),
|
|
expanded_url: None,
|
|
range: (1, 3),
|
|
url: String::from("https://t.me/tamerelol"),
|
|
};
|
|
|
|
let twitter_urls = vec![url_entity1, url_entity2];
|
|
|
|
let mut expected_urls = HashMap::new();
|
|
expected_urls.insert(String::from("https://t.me/tamerelol"), String::from("https://www.nintendojo.fr/dojobar"));
|
|
|
|
let decoded_urls = decode_urls(&twitter_urls);
|
|
|
|
assert_eq!(expected_urls, decoded_urls);
|
|
}
|
|
}
|