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