@ -123,24 +123,29 @@ pub(crate) async fn fetch_pictrs(
let pictrs_config = settings . pictrs_config ( ) ? ;
is_image_content_type ( client , image_url ) . await ? ;
let fetch_url = format! (
"{}image/download?url={}" ,
pictrs_config . url ,
utf8_percent_encode ( image_url . as_str ( ) , NON_ALPHANUMERIC ) // TODO this might not be needed
) ;
let response = client
. get ( & fetch_url )
. timeout ( REQWEST_TIMEOUT )
. send ( )
. await ? ;
if pictrs_config . cache_remote_images {
// fetch remote non-pictrs images for persistent thumbnail link
let fetch_url = format! (
"{}image/download?url={}" ,
pictrs_config . url ,
utf8_percent_encode ( image_url . as_str ( ) , NON_ALPHANUMERIC ) // TODO this might not be needed
) ;
let response : PictrsResponse = response . json ( ) . await . map_err ( LemmyError ::from ) ? ;
let response = client
. get ( & fetch_url )
. timeout ( REQWEST_TIMEOUT )
. send ( )
. await ? ;
if response . msg = = "ok" {
Ok ( response )
let response : PictrsResponse = response . json ( ) . await . map_err ( LemmyError ::from ) ? ;
if response . msg = = "ok" {
Ok ( response )
} else {
Err ( LemmyErrorType ::PictrsResponseError ( response . msg ) ) ?
}
} else {
Err ( LemmyErrorType ::PictrsResponseError ( response . msg ) ) ?
Err ( LemmyErrorType ::Pictrs CachingDisabled ) ?
}
}
@ -185,7 +190,7 @@ pub async fn purge_image_from_pictrs(
}
/// Both are options, since the URL might be either an html page, or an image
/// Returns the SiteMetadata, and a Pictrs URL, if there is a picture associated
/// Returns the SiteMetadata, and a n image URL, if there is a picture associated
#[ tracing::instrument(skip_all) ]
pub async fn fetch_site_data (
client : & ClientWithMiddleware ,
@ -200,50 +205,46 @@ pub async fn fetch_site_data(
// Warning, this may ignore SSL errors
let metadata_option = fetch_site_metadata ( client , url ) . await . ok ( ) ;
if ! include_image {
return ( metadata_option , None ) ;
}
let missing_pictrs_file =
| r : PictrsResponse | r . files . first ( ) . expect ( "missing pictrs file" ) . file . clone ( ) ;
// Fetch pictrs thumbnail
let pictrs_hash = match & metadata_option {
Some ( metadata_res ) = > match & metadata_res . image {
// Metadata, with image
// Try to generate a small thumbnail if there's a full sized one from post-links
Some ( metadata_image ) = > fetch_pictrs ( client , settings , metadata_image )
. await
. map ( missing_pictrs_file ) ,
// Metadata, but no image
None = > fetch_pictrs ( client , settings , url )
( metadata_option , None )
} else {
let thumbnail_url =
fetch_pictrs_url_from_site_metadata ( client , & metadata_option , settings , url )
. await
. map ( missing_pictrs_file ) ,
} ,
// No metadata, try to fetch the URL as an image
None = > fetch_pictrs ( client , settings , url )
. await
. map ( missing_pictrs_file ) ,
} ;
// The full urls are necessary for federation
let pictrs_thumbnail = pictrs_hash
. map ( | p | {
Url ::parse ( & format! (
"{}/pictrs/image/{}" ,
settings . get_protocol_and_hostname ( ) ,
p
) )
. ok ( )
} )
. ok ( )
. flatten ( ) ;
( metadata_option , pictrs_thumbnail . map ( Into ::into ) )
. ok ( ) ;
( metadata_option , thumbnail_url )
}
}
None = > ( None , None ) ,
}
}
async fn fetch_pictrs_url_from_site_metadata (
client : & ClientWithMiddleware ,
metadata_option : & Option < SiteMetadata > ,
settings : & Settings ,
url : & Url ,
) -> Result < DbUrl , LemmyError > {
let pictrs_res = match metadata_option {
Some ( metadata_res ) = > match & metadata_res . image {
// Metadata, with image
// Try to generate a small thumbnail if there's a full sized one from post-links
Some ( metadata_image ) = > fetch_pictrs ( client , settings , metadata_image ) . await ,
// Metadata, but no image
None = > fetch_pictrs ( client , settings , url ) . await ,
} ,
// No metadata, try to fetch the URL as an image
None = > fetch_pictrs ( client , settings , url ) . await ,
} ? ;
Url ::parse ( & format! (
"{}/pictrs/image/{}" ,
settings . get_protocol_and_hostname ( ) ,
pictrs_res . files . first ( ) . expect ( "missing pictrs file" ) . file
) )
. map ( Into ::into )
. map_err ( Into ::into )
}
#[ tracing::instrument(skip_all) ]
async fn is_image_content_type ( client : & ClientWithMiddleware , url : & Url ) -> Result < ( ) , LemmyError > {
let response = client . get ( url . as_str ( ) ) . send ( ) . await ? ;