expose headers on Icon

This commit is contained in:
Sam Denty 2022-10-01 22:45:09 +01:00
parent 0bead553c2
commit 601d04020c
No known key found for this signature in database
GPG key ID: 7B4EAF7B9E291B79
4 changed files with 26 additions and 12 deletions

2
Cargo.lock generated
View file

@ -1513,7 +1513,7 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]] [[package]]
name = "site_icons" name = "site_icons"
version = "0.2.0" version = "0.2.1"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"clap", "clap",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "site_icons" name = "site_icons"
version = "0.2.0" version = "0.2.1"
authors = ["Sam Denty <sam@samdenty.com>"] authors = ["Sam Denty <sam@samdenty.com>"]
edition = "2018" edition = "2018"
license = "GPL-3.0" license = "GPL-3.0"

View file

@ -2,6 +2,7 @@ use super::IconInfo;
use serde::Serialize; use serde::Serialize;
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::HashMap,
fmt::{self, Display}, fmt::{self, Display},
str::FromStr, str::FromStr,
}; };
@ -40,6 +41,7 @@ impl FromStr for IconKind {
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Icon { pub struct Icon {
pub url: Url, pub url: Url,
pub headers: HashMap<String, String>,
#[serde(with = "serde_with::rust::display_fromstr")] #[serde(with = "serde_with::rust::display_fromstr")]
pub kind: IconKind, pub kind: IconKind,
#[serde(flatten)] #[serde(flatten)]

View file

@ -9,6 +9,7 @@ use html5ever::{
use reqwest::{header::*, IntoUrl}; use reqwest::{header::*, IntoUrl};
use scraper::{ElementRef, Html}; use scraper::{ElementRef, Html};
use serde::Deserialize; use serde::Deserialize;
use std::convert::TryInto;
use std::task::Poll; use std::task::Poll;
use std::{collections::HashMap, error::Error, pin::Pin, task::Context}; use std::{collections::HashMap, error::Error, pin::Pin, task::Context};
use url::Url; use url::Url;
@ -19,6 +20,7 @@ pub struct Icons {
Url, Url,
( (
IconKind, IconKind,
HashMap<String, String>,
Pin<Box<dyn Future<Output = Result<IconInfo, Box<dyn Error>>>>>, Pin<Box<dyn Future<Output = Result<IconInfo, Box<dyn Error>>>>>,
), ),
>, >,
@ -27,11 +29,17 @@ pub struct Icons {
fn add_icon_entry( fn add_icon_entry(
entries: &mut Vec<Icon>, entries: &mut Vec<Icon>,
url: Url, url: Url,
headers: HashMap<String, String>,
kind: IconKind, kind: IconKind,
info: Result<IconInfo, Box<dyn Error>>, info: Result<IconInfo, Box<dyn Error>>,
) { ) {
match info { match info {
Ok(info) => entries.push(Icon { url, kind, info }), Ok(info) => entries.push(Icon {
url,
headers,
kind,
info,
}),
Err(_) => warn_err!(info, "failed to parse icon"), Err(_) => warn_err!(info, "failed to parse icon"),
} }
} }
@ -46,7 +54,7 @@ impl Icons {
/// Add an icon URL and start fetching it /// Add an icon URL and start fetching it
pub fn add_icon(&mut self, url: Url, kind: IconKind, sizes: Option<String>) { pub fn add_icon(&mut self, url: Url, kind: IconKind, sizes: Option<String>) {
self.add_icon_with_headers(url, HeaderMap::new(), kind, sizes) self.add_icon_with_headers(url, HashMap::new(), kind, sizes)
} }
/// Add an icon URL and start fetching it, /// Add an icon URL and start fetching it,
@ -54,7 +62,7 @@ impl Icons {
pub fn add_icon_with_headers( pub fn add_icon_with_headers(
&mut self, &mut self,
url: Url, url: Url,
headers: HeaderMap, headers: HashMap<String, String>,
kind: IconKind, kind: IconKind,
sizes: Option<String>, sizes: Option<String>,
) { ) {
@ -63,7 +71,7 @@ impl Icons {
if let Some(existing_kind) = self if let Some(existing_kind) = self
.pending_entries .pending_entries
.get_mut(&url) .get_mut(&url)
.map(|(kind, _)| kind) .map(|(kind, _, _)| kind)
.or_else(|| { .or_else(|| {
entries.find_map(|icon| { entries.find_map(|icon| {
if icon.url.eq(&url) { if icon.url.eq(&url) {
@ -81,15 +89,19 @@ impl Icons {
return; return;
} }
let mut info = Box::pin(IconInfo::load(url.clone(), headers, sizes)); let mut info = Box::pin(IconInfo::load(
url.clone(),
(&headers).try_into().unwrap(),
sizes,
));
// Start fetching the icon // Start fetching the icon
let noop_waker = noop_waker(); let noop_waker = noop_waker();
let cx = &mut Context::from_waker(&noop_waker); let cx = &mut Context::from_waker(&noop_waker);
match info.poll_unpin(cx) { match info.poll_unpin(cx) {
Poll::Ready(info) => add_icon_entry(&mut self.entries, url, kind, info), Poll::Ready(info) => add_icon_entry(&mut self.entries, url, headers, kind, info),
Poll::Pending => { Poll::Pending => {
self.pending_entries.insert(url, (kind, info)); self.pending_entries.insert(url, (kind, headers, info));
} }
}; };
} }
@ -278,14 +290,14 @@ impl Icons {
let (urls, infos): (Vec<_>, Vec<_>) = self let (urls, infos): (Vec<_>, Vec<_>) = self
.pending_entries .pending_entries
.into_iter() .into_iter()
.map(|(url, (kind, info))| ((url, kind), info)) .map(|(url, (kind, headers, info))| ((url, headers, kind), info))
.unzip(); .unzip();
let mut urls = urls.into_iter(); let mut urls = urls.into_iter();
for info in join_all(infos).await { for info in join_all(infos).await {
let (url, kind) = urls.next().unwrap(); let (url, headers, kind) = urls.next().unwrap();
add_icon_entry(&mut self.entries, url, kind, info); add_icon_entry(&mut self.entries, url, headers, kind, info);
} }
self.entries.sort(); self.entries.sort();