oops: added the actual file
Some checks failed
cargo_test_bench / Run Tests (push) Successful in 1m53s
cargo_test_bench / Run Benchmarks (push) Failing after 2m13s

This commit is contained in:
saji 2024-08-11 23:12:57 -05:00
parent 183ddb322b
commit bd5051777f

86
src/imageprovider.rs Normal file
View 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;
}
}