oops: added the actual file
This commit is contained in:
parent
183ddb322b
commit
bd5051777f
86
src/imageprovider.rs
Normal file
86
src/imageprovider.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// provides NASA image of the day.
|
||||||
|
//
|
||||||
|
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use bytes::Buf;
|
||||||
|
use image::{
|
||||||
|
imageops::{crop_imm, resize, FilterType},
|
||||||
|
ImageReader, RgbImage,
|
||||||
|
};
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio::time::sleep;
|
||||||
|
|
||||||
|
use rss::Channel;
|
||||||
|
use tracing::{info, instrument};
|
||||||
|
|
||||||
|
use crate::{app::AppState, dither::DitherMethod, dither::DitheredImage, eink::Palette};
|
||||||
|
|
||||||
|
const NASA_IOTD_RSS_FEED: &str = "https://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss";
|
||||||
|
|
||||||
|
const TARGET_ASPECT: f32 = 800.0 / 480.0;
|
||||||
|
|
||||||
|
async fn get_latest_image() -> Result<Box<RgbImage>> {
|
||||||
|
let content = reqwest::get(NASA_IOTD_RSS_FEED).await?.bytes().await?;
|
||||||
|
let channel = Channel::read_from(content.reader())?;
|
||||||
|
|
||||||
|
let latest_item = &channel.items()[0];
|
||||||
|
let image_enc = latest_item
|
||||||
|
.enclosure()
|
||||||
|
.context("no enclosure in first item")?;
|
||||||
|
|
||||||
|
// now we have an image url
|
||||||
|
info!(
|
||||||
|
"found image with type {}, size {}",
|
||||||
|
image_enc.mime_type(),
|
||||||
|
image_enc.length()
|
||||||
|
);
|
||||||
|
|
||||||
|
let image_request = reqwest::get(image_enc.url()).await?;
|
||||||
|
let reader =
|
||||||
|
ImageReader::new(Cursor::new(image_request.bytes().await?)).with_guessed_format()?;
|
||||||
|
|
||||||
|
let image = reader.decode()?;
|
||||||
|
Ok(Box::new(image.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_nasa() -> Result<RgbImage> {
|
||||||
|
let img = get_latest_image().await?;
|
||||||
|
let (width, height) = img.dimensions();
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
let input_aspect = width as f32 / height as f32;
|
||||||
|
let resize = if input_aspect > TARGET_ASPECT {
|
||||||
|
let new_width = (height as f32 * TARGET_ASPECT) as u32;
|
||||||
|
let offset = (width - new_width) / 2;
|
||||||
|
(offset, 0, new_width, height)
|
||||||
|
} else {
|
||||||
|
let new_height = (width as f32 / TARGET_ASPECT) as u32;
|
||||||
|
let offset = (height - new_height) / 2;
|
||||||
|
(0, offset, width, new_height)
|
||||||
|
};
|
||||||
|
|
||||||
|
let cropped = crop_imm(&*img, resize.0, resize.1, resize.2, resize.3).to_image();
|
||||||
|
|
||||||
|
Ok(cropped)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(ctx))]
|
||||||
|
pub async fn nasa_task(ctx: AppState) {
|
||||||
|
info!("Starting NASA IOTD task");
|
||||||
|
loop {
|
||||||
|
if let Ok(img) = get_nasa().await {
|
||||||
|
let mut buf = DitheredImage::new(800, 480, Palette::Default.value().to_vec());
|
||||||
|
let resized = resize(&img, 800, 480, FilterType::Lanczos3);
|
||||||
|
{
|
||||||
|
let mut dither = DitherMethod::Atkinson.get_ditherer();
|
||||||
|
dither.dither(&resized, &mut buf);
|
||||||
|
}
|
||||||
|
ctx.display_channel.send(Box::new(buf));
|
||||||
|
info!("Nasa image updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(Duration::from_secs(60 * 60 * 24)).await;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue