mirror of
https://github.com/Steffo99/patched-porobot.git
synced 2024-12-22 17:44:22 +00:00
Use imgproxy to convert images on the fly
This commit is contained in:
parent
f469776a1d
commit
0d3c1329c4
3 changed files with 128 additions and 41 deletions
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -347,6 +347,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
|||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -652,6 +653,21 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "htmlescape"
|
||||
version = "0.3.1"
|
||||
|
@ -1088,8 +1104,11 @@ name = "patched_porobot"
|
|||
version = "0.9.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.0",
|
||||
"data-encoding",
|
||||
"glob",
|
||||
"hex",
|
||||
"hmac",
|
||||
"itertools 0.10.5",
|
||||
"lazy_static",
|
||||
"log",
|
||||
|
@ -1101,6 +1120,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serenity",
|
||||
"sha2",
|
||||
"tantivy",
|
||||
"teloxide",
|
||||
"tokio",
|
||||
|
@ -1563,6 +1583,17 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
|
@ -1624,6 +1655,12 @@ version = "0.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
|
|
|
@ -26,6 +26,11 @@ data-encoding = { version = "2.3.2" }
|
|||
varint-rs = { version = "2.2.0" }
|
||||
glob = { version = "0.3.0" }
|
||||
reqwest = { version = "0.11.11", features = ["rustls-tls", "json"], default-features = false }
|
||||
# jpg
|
||||
hex = { version = "0.4.3", optional = true }
|
||||
base64 = { version = "0.21.0", optional = true }
|
||||
hmac = { version = "0.12.1", optional = true }
|
||||
sha2 = { version = "0.10.6", optional = true }
|
||||
# exec
|
||||
pretty_env_logger = { version = "0.4.0", optional = true }
|
||||
# data
|
||||
|
@ -45,9 +50,10 @@ anyhow = { version = "^1.0.68", optional = true }
|
|||
|
||||
|
||||
[features]
|
||||
jpg = ["hmac", "sha2", "base64", "hex"]
|
||||
exec = ["pretty_env_logger"]
|
||||
search = ["tantivy"]
|
||||
telegram = ["exec", "search", "teloxide", "tokio", "md5", "rand"]
|
||||
telegram = ["exec", "search", "jpg", "teloxide", "tokio", "md5", "rand"]
|
||||
discord = ["exec", "search", "serenity", "tokio", "anyhow"]
|
||||
matrix = ["exec", "search"]
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//! Module defining [CardArt].
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use base64::Engine;
|
||||
use hmac::Mac;
|
||||
use std::env;
|
||||
|
||||
/// The illustration of a [Card](super::card::Card), also referred to as an *art asset*.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
|
||||
|
@ -30,52 +31,95 @@ pub struct CardArt {
|
|||
}
|
||||
|
||||
impl CardArt {
|
||||
/// URL to the `.jpg` image of the `en_us` locale of the rendered card, via my custom S3 mirror.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```text
|
||||
/// https://objectstorage.eu-milan-1.oraclecloud.com/n/axxdmk4y92aq/b/porobot-storage/o/set1-en_us/en_us/img/cards/01DE001.jpg
|
||||
/// ```
|
||||
///
|
||||
pub fn card_jpg(&self) -> String {
|
||||
lazy_static! {
|
||||
static ref GET_JPG: Regex = Regex::new(
|
||||
r#"https?://dd[.]b[.]pvp[.]net/[^/]+/(?P<bundle>[^/]+)/(?P<locale>[^/]+)/img/cards/(?P<code>.+)[.]png$"#
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
GET_JPG
|
||||
.replace_all(
|
||||
&self.card_png,
|
||||
"https://objectstorage.eu-milan-1.oraclecloud.com/n/axxdmk4y92aq/b/porobot-storage/o/$bundle-$locale/$locale/img/cards/$code.jpg",
|
||||
)
|
||||
.to_string()
|
||||
/// Get the URL to convert the image at the given URL into JPG using imgproxy.
|
||||
#[cfg(feature = "jpg")]
|
||||
fn imgproxy_convert_to_jpg(url: &str) -> String {
|
||||
let url = base64::prelude::BASE64_URL_SAFE.encode(url);
|
||||
let url = format!("/{url}.jpg");
|
||||
|
||||
log::trace!("Created JPG conversion URL: {url}");
|
||||
|
||||
url
|
||||
}
|
||||
|
||||
/// URL to the `.jpg` image of the `en_us` locale of the full card art, via my custom S3 mirror.
|
||||
/// Add the HMAC required by imgproxy to authenticate the source of the image requester to the URL.
|
||||
///
|
||||
/// # Example
|
||||
/// # Panics
|
||||
///
|
||||
/// ```text
|
||||
/// https://objectstorage.eu-milan-1.oraclecloud.com/n/axxdmk4y92aq/b/porobot-storage/o/set1-en_us/en_us/img/cards/01DE001-full.jpg
|
||||
/// ```
|
||||
/// If the `POROXY_KEY` or `POROXY_SALT` variables are not defined.
|
||||
///
|
||||
pub fn full_jpg(&self) -> String {
|
||||
lazy_static! {
|
||||
static ref GET_JPG: Regex = Regex::new(
|
||||
r#"https?://dd[.]b[.]pvp[.]net/[^/]+/(?P<bundle>[^/]+)/(?P<locale>[^/]+)/img/cards/(?P<code>.+)[.]png$"#
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
#[cfg(feature = "jpg")]
|
||||
fn imgproxy_authenticate_url(url: &str) -> String {
|
||||
let key = env::var("POROXY_KEY")
|
||||
.expect("POROXY_KEY to be set");
|
||||
let key = hex::decode(key)
|
||||
.expect("POROXY_KEY to be a valid hex code");
|
||||
|
||||
GET_JPG
|
||||
.replace_all(
|
||||
&self.full_png,
|
||||
"https://objectstorage.eu-milan-1.oraclecloud.com/n/axxdmk4y92aq/b/porobot-storage/o/$bundle-$locale/$locale/img/cards/$code.jpg",
|
||||
let salt = env::var("POROXY_SALT")
|
||||
.expect("POROXY_SALT to be set");
|
||||
let salt = hex::decode(salt)
|
||||
.expect("POROXY_SALT to be a valid hex code");
|
||||
let salt: String = String::from_utf8(salt)
|
||||
.expect("salt to be a valid UTF-8 string");
|
||||
|
||||
let mut hmac = hmac::Hmac::<sha2::Sha256>::new_from_slice(key.as_slice())
|
||||
.expect("HMAC to be initialized successfully");
|
||||
hmac.update(&format!("{salt}{url}").into_bytes());
|
||||
let hmac = hmac.finalize().into_bytes();
|
||||
let hmac = base64::prelude::BASE64_URL_SAFE_NO_PAD.encode(hmac);
|
||||
|
||||
let url = format!("/{hmac}{url}");
|
||||
|
||||
log::trace!("Created authenticated URL: {url}");
|
||||
|
||||
url
|
||||
}
|
||||
|
||||
/// URL to the `.jpg` image of the rendered card, via imgproxy.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the `POROXY_HOST`, `POROXY_KEY` and `POROXY_SALT` variables are not defined.
|
||||
///
|
||||
#[cfg(feature = "jpg")]
|
||||
pub fn card_jpg(&self) -> String {
|
||||
let host = env::var("POROXY_HOST")
|
||||
.expect("POROXY_HOST to be set");
|
||||
|
||||
let url = Self::imgproxy_authenticate_url(
|
||||
&Self::imgproxy_convert_to_jpg(
|
||||
&self.card_png
|
||||
)
|
||||
.to_string()
|
||||
);
|
||||
|
||||
let url = format!("{host}{url}");
|
||||
log::trace!("Accessed card_jpg: {url}");
|
||||
|
||||
url
|
||||
}
|
||||
|
||||
/// URL to the `.jpg` image of the rendered card, via imgproxy.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the `POROXY_HOST`, `POROXY_KEY` and `POROXY_SALT` variables are not defined.
|
||||
///
|
||||
#[cfg(feature = "jpg")]
|
||||
pub fn full_jpg(&self) -> String {
|
||||
let host = env::var("POROXY_HOST")
|
||||
.expect("POROXY_HOST to be set");
|
||||
|
||||
let url = Self::imgproxy_authenticate_url(
|
||||
&Self::imgproxy_convert_to_jpg(
|
||||
&self.full_png
|
||||
)
|
||||
);
|
||||
|
||||
let url = format!("{host}{url}");
|
||||
log::trace!("Accessed full_jpg: {url}");
|
||||
|
||||
url
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue