Browse Source

Basic proof of concept

master
Jamie Quigley 10 months ago
parent
commit
b6cb06c18a
Signed by: jamie GPG Key ID: 8E8FF66E2AE8D970
  1. 8
      .gitignore
  2. 1528
      Cargo.lock
  3. 7
      Cargo.toml
  4. 6
      readme.md
  5. 88
      src/main.rs

8
.gitignore

@ -1,8 +1,2 @@
/target
# Added by cargo
#
# already existing elements were commented out
#/target
token

1528
Cargo.lock
File diff suppressed because it is too large
View File

7
Cargo.toml

@ -7,3 +7,10 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = "0.10.10"
tokio = {version = "0.2", features = ["macros"]}
[dependencies.serenity]
default-features=false
features=["client", "gateway", "rustls_backend", "model"]
version = "0.9.3"

6
readme.md

@ -1,3 +1,9 @@
# emoji-archiver
A small discord bot to archive the emojis from a server
Based on [Serenity](https://github.com/serenity-rs/serenity).
---
Available under the terms of the GNU AGPL.

88
src/main.rs

@ -1,3 +1,87 @@
fn main() {
println!("Hello, world!");
use std::env;
use std::path::Path;
use std::fs::File;
use std::io;
use serenity::{
async_trait,
model::{channel::Message, gateway::Ready},
prelude::*,
};
const PATH_PREFIX: &'static str = "/dev/shm/";
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN")
.expect("Expected a token in the environment");
// Create a new instance of the Client, logging in as a bot. This will
// automatically prepend your bot token with "Bot ", which is a requirement
// by Discord for bot users.
let mut client = Client::builder(&token)
.event_handler(Handler)
.await
.expect("Err creating client");
// Finally, start a single shard, and start listening to events.
//
// Shards will automatically attempt to reconnect, and will perform
// exponential backoff until it reconnects.
if let Err(why) = client.start().await {
println!("Client error: {:?}", why);
}
}
struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn message(&self, ctx: Context, msg: Message) {
if msg.content == "!archive" {
let server_id = msg.guild_id.unwrap();
let emojis = server_id.emojis(ctx.http).await.unwrap();
for emoji in emojis {
println!("{:?}", emoji);
let url = emoji.url();
println!("{}", url);
let name = emoji.name;
let ext = if emoji.animated {
"gif"
} else {
"png"
};
let path = format!("{}/{}.{}", PATH_PREFIX, name, ext);
download_url(&url, &path).await.unwrap();
}
}
}
// Set a handler to be called on the `ready` event. This is called when a
// shard is booted, and a READY payload is sent by Discord. This payload
// contains data like the current user's guild Ids, current user data,
// private channels, and more.
//
// In this case, just print what the current user's username is.
async fn ready(&self, _: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
}
}
async fn download_url<P: AsRef<Path>>(url: &str, destination: P) -> Result<(), Box<dyn std::error::Error>> {
let response = reqwest::get(url).await.unwrap();
let mut dest = {
let fname = response.url().path_segments().and_then(|segments| segments.last()).and_then(|name| if name.is_empty() {None} else {Some(name)}).unwrap_or("<unnamed>");
println!("file to download: '{}'", fname);
println!("Will be stored in '{:?}'", destination.as_ref());
File::create(destination.as_ref())?
};
let mut content = io::Cursor::new(response.bytes().await?);
std::io::copy(&mut content, &mut dest)?;
Ok(())
}
Loading…
Cancel
Save