mirror of https://github.com/LemmyNet/lemmy.git
rewrite link fields for avatar, banner etc
parent
ef79422632
commit
ae96d863a4
|
@ -2681,6 +2681,7 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"ts-rs",
|
"ts-rs",
|
||||||
"url",
|
"url",
|
||||||
|
"urlencoding",
|
||||||
"uuid",
|
"uuid",
|
||||||
"webpage",
|
"webpage",
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,7 +2,12 @@ use actix_web::web::{Data, Json};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::SaveUserSettings,
|
person::SaveUserSettings,
|
||||||
utils::{local_site_to_slur_regex, process_markdown_opt, send_verification_email},
|
utils::{
|
||||||
|
local_site_to_slur_regex,
|
||||||
|
process_markdown_opt,
|
||||||
|
proxy_image_link_opt,
|
||||||
|
send_verification_email,
|
||||||
|
},
|
||||||
SuccessResponse,
|
SuccessResponse,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -12,7 +17,7 @@ use lemmy_db_schema::{
|
||||||
person::{Person, PersonUpdateForm},
|
person::{Person, PersonUpdateForm},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{diesel_option_overwrite, diesel_option_overwrite_to_url},
|
utils::diesel_option_overwrite,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -31,8 +36,8 @@ pub async fn save_user_settings(
|
||||||
let slur_regex = local_site_to_slur_regex(&site_view.local_site);
|
let slur_regex = local_site_to_slur_regex(&site_view.local_site);
|
||||||
let bio = process_markdown_opt(&data.bio, &slur_regex, &context).await?;
|
let bio = process_markdown_opt(&data.bio, &slur_regex, &context).await?;
|
||||||
|
|
||||||
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
let avatar = proxy_image_link_opt(&data.avatar, &context).await?;
|
||||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
let banner = proxy_image_link_opt(&data.banner, &context).await?;
|
||||||
let bio = diesel_option_overwrite(bio);
|
let bio = diesel_option_overwrite(bio);
|
||||||
let display_name = diesel_option_overwrite(data.display_name.clone());
|
let display_name = diesel_option_overwrite(data.display_name.clone());
|
||||||
let matrix_user_id = diesel_option_overwrite(data.matrix_user_id.clone());
|
let matrix_user_id = diesel_option_overwrite(data.matrix_user_id.clone());
|
||||||
|
|
|
@ -53,10 +53,6 @@ reqwest-middleware = { workspace = true, optional = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
rosetta-i18n = { workspace = true, optional = true }
|
rosetta-i18n = { workspace = true, optional = true }
|
||||||
percent-encoding = { workspace = true, optional = true }
|
percent-encoding = { workspace = true, optional = true }
|
||||||
webpage = { version = "1.6", default-features = false, features = [
|
|
||||||
"serde",
|
|
||||||
], optional = true }
|
|
||||||
encoding = { version = "0.2.33", optional = true }
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
futures = { workspace = true, optional = true }
|
futures = { workspace = true, optional = true }
|
||||||
uuid = { workspace = true, optional = true }
|
uuid = { workspace = true, optional = true }
|
||||||
|
@ -65,10 +61,15 @@ reqwest = { workspace = true, optional = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
once_cell = { workspace = true, optional = true }
|
once_cell = { workspace = true, optional = true }
|
||||||
actix-web = { workspace = true, optional = true }
|
actix-web = { workspace = true, optional = true }
|
||||||
|
enum-map = { workspace = true }
|
||||||
|
urlencoding = { workspace = true }
|
||||||
|
webpage = { version = "1.6", default-features = false, features = [
|
||||||
|
"serde",
|
||||||
|
], optional = true }
|
||||||
|
encoding = { version = "0.2.33", optional = true }
|
||||||
jsonwebtoken = { version = "8.3.0", optional = true }
|
jsonwebtoken = { version = "8.3.0", optional = true }
|
||||||
# necessary for wasmt compilation
|
# necessary for wasmt compilation
|
||||||
getrandom = { version = "0.2.10", features = ["js"] }
|
getrandom = { version = "0.2.10", features = ["js"] }
|
||||||
enum-map = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -24,7 +24,7 @@ use lemmy_db_schema::{
|
||||||
post::{Post, PostRead},
|
post::{Post, PostRead},
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::DbPool,
|
utils::{diesel_option_overwrite_to_url, DbPool},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{comment_view::CommentQuery, structs::LocalUserView};
|
use lemmy_db_views::{comment_view::CommentQuery, structs::LocalUserView};
|
||||||
use lemmy_db_views_actor::structs::{
|
use lemmy_db_views_actor::structs::{
|
||||||
|
@ -37,7 +37,7 @@ use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||||
location_info,
|
location_info,
|
||||||
rate_limit::{ActionType, BucketConfig},
|
rate_limit::{ActionType, BucketConfig},
|
||||||
settings::structs::Settings,
|
settings::{structs::Settings, SETTINGS},
|
||||||
utils::{
|
utils::{
|
||||||
markdown::markdown_rewrite_image_links,
|
markdown::markdown_rewrite_image_links,
|
||||||
slurs::{build_slur_regex, remove_slurs},
|
slurs::{build_slur_regex, remove_slurs},
|
||||||
|
@ -48,6 +48,7 @@ use rosetta_i18n::{Language, LanguageId};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use url::{ParseError, Url};
|
use url::{ParseError, Url};
|
||||||
|
use urlencoding::encode;
|
||||||
|
|
||||||
pub static AUTH_COOKIE_NAME: &str = "auth";
|
pub static AUTH_COOKIE_NAME: &str = "auth";
|
||||||
|
|
||||||
|
@ -797,7 +798,7 @@ pub async fn process_markdown(
|
||||||
) -> LemmyResult<String> {
|
) -> LemmyResult<String> {
|
||||||
let text = remove_slurs(text, slur_regex);
|
let text = remove_slurs(text, slur_regex);
|
||||||
let (text, links) = markdown_rewrite_image_links(text);
|
let (text, links) = markdown_rewrite_image_links(text);
|
||||||
RemoteImage::create_many(&mut context.pool(), links).await?;
|
RemoteImage::create(&mut context.pool(), links).await?;
|
||||||
Ok(text)
|
Ok(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,6 +813,36 @@ pub async fn process_markdown_opt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
|
||||||
|
// Dont rewrite links pointing to local domain.
|
||||||
|
if link.domain() == Some(&SETTINGS.hostname) {
|
||||||
|
return Ok(link.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxied = format!(
|
||||||
|
"{}/api/v3/image_proxy?url={}",
|
||||||
|
SETTINGS.get_protocol_and_hostname(),
|
||||||
|
encode(link.as_str())
|
||||||
|
);
|
||||||
|
RemoteImage::create(&mut context.pool(), vec![link]).await?;
|
||||||
|
Ok(Url::parse(&proxied)?.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn proxy_image_link_opt(
|
||||||
|
link: &Option<String>,
|
||||||
|
context: &LemmyContext,
|
||||||
|
) -> LemmyResult<Option<Option<DbUrl>>> {
|
||||||
|
let link = diesel_option_overwrite_to_url(link)?;
|
||||||
|
if let Some(Some(l)) = link {
|
||||||
|
proxy_image_link(l.into(), context)
|
||||||
|
.await
|
||||||
|
.map(Some)
|
||||||
|
.map(Some)
|
||||||
|
} else {
|
||||||
|
Ok(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|
|
@ -12,6 +12,7 @@ use lemmy_api_common::{
|
||||||
is_admin,
|
is_admin,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
process_markdown_opt,
|
process_markdown_opt,
|
||||||
|
proxy_image_link_opt,
|
||||||
EndpointType,
|
EndpointType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -28,7 +29,6 @@ use lemmy_db_schema::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
traits::{ApubActor, Crud, Followable, Joinable},
|
traits::{ApubActor, Crud, Followable, Joinable},
|
||||||
utils::diesel_option_overwrite_to_url_create,
|
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -52,14 +52,12 @@ pub async fn create_community(
|
||||||
Err(LemmyErrorType::OnlyAdminsCanCreateCommunities)?
|
Err(LemmyErrorType::OnlyAdminsCanCreateCommunities)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure the icon and banners are urls
|
|
||||||
let icon = diesel_option_overwrite_to_url_create(&data.icon)?;
|
|
||||||
let banner = diesel_option_overwrite_to_url_create(&data.banner)?;
|
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
check_slurs(&data.name, &slur_regex)?;
|
check_slurs(&data.name, &slur_regex)?;
|
||||||
check_slurs(&data.title, &slur_regex)?;
|
check_slurs(&data.title, &slur_regex)?;
|
||||||
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
||||||
|
let icon = proxy_image_link_opt(&data.icon, &context).await?.unwrap();
|
||||||
|
let banner = proxy_image_link_opt(&data.banner, &context).await?.unwrap();
|
||||||
|
|
||||||
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
||||||
is_valid_body_field(&data.description, false)?;
|
is_valid_body_field(&data.description, false)?;
|
||||||
|
|
|
@ -5,7 +5,12 @@ use lemmy_api_common::{
|
||||||
community::{CommunityResponse, EditCommunity},
|
community::{CommunityResponse, EditCommunity},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
send_activity::{ActivityChannel, SendActivityData},
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{check_community_mod_action, local_site_to_slur_regex, process_markdown_opt},
|
utils::{
|
||||||
|
check_community_mod_action,
|
||||||
|
local_site_to_slur_regex,
|
||||||
|
process_markdown_opt,
|
||||||
|
proxy_image_link_opt,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
@ -14,7 +19,7 @@ use lemmy_db_schema::{
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now},
|
utils::{diesel_option_overwrite, naive_now},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -35,9 +40,9 @@ pub async fn update_community(
|
||||||
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
let description = process_markdown_opt(&data.description, &slur_regex, &context).await?;
|
||||||
is_valid_body_field(&data.description, false)?;
|
is_valid_body_field(&data.description, false)?;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
|
||||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
|
||||||
let description = diesel_option_overwrite(description);
|
let description = diesel_option_overwrite(description);
|
||||||
|
let icon = proxy_image_link_opt(&data.icon, &context).await?;
|
||||||
|
let banner = proxy_image_link_opt(&data.banner, &context).await?;
|
||||||
|
|
||||||
// Verify its a mod (only mods can edit it)
|
// Verify its a mod (only mods can edit it)
|
||||||
check_community_mod_action(
|
check_community_mod_action(
|
||||||
|
|
|
@ -53,9 +53,6 @@ pub async fn create_post(
|
||||||
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
||||||
honeypot_check(&data.honeypot)?;
|
honeypot_check(&data.honeypot)?;
|
||||||
|
|
||||||
let data_url = data.url.as_ref();
|
|
||||||
let url = data_url.map(clean_url_params).map(Into::into); // TODO no good way to handle a "clear"
|
|
||||||
|
|
||||||
is_valid_post_title(&data.name)?;
|
is_valid_post_title(&data.name)?;
|
||||||
is_valid_body_field(&body, true)?;
|
is_valid_body_field(&body, true)?;
|
||||||
check_url_scheme(&data.url)?;
|
check_url_scheme(&data.url)?;
|
||||||
|
@ -83,12 +80,29 @@ pub async fn create_post(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch post links and pictrs cached image
|
// Fetch post links and pictrs cached image
|
||||||
let (metadata_res, thumbnail_url) =
|
let (metadata_res, thumbnail_url) = fetch_site_data(
|
||||||
fetch_site_data(context.client(), context.settings(), data_url, true).await;
|
context.client(),
|
||||||
|
context.settings(),
|
||||||
|
data.url.as_ref(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
let (embed_title, embed_description, embed_video_url) = metadata_res
|
let (embed_title, embed_description, embed_video_url) = metadata_res
|
||||||
.map(|u| (u.title, u.description, u.embed_video_url))
|
.map(|u| (u.title, u.description, u.embed_video_url))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// TODO No good way to handle a clear.
|
||||||
|
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
||||||
|
let url = data.url.as_ref().map(clean_url_params).map(Into::into);
|
||||||
|
|
||||||
|
// TODO: not sure how to get this working
|
||||||
|
/*
|
||||||
|
let url_is_image = todo!();
|
||||||
|
if url_is_image {
|
||||||
|
proxy_image_link_opt(url, &context).await?;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Only need to check if language is allowed in case user set it explicitly. When using default
|
// Only need to check if language is allowed in case user set it explicitly. When using default
|
||||||
// language, it already only returns allowed languages.
|
// language, it already only returns allowed languages.
|
||||||
CommunityLanguage::is_allowed_community_language(
|
CommunityLanguage::is_allowed_community_language(
|
||||||
|
|
|
@ -35,12 +35,6 @@ pub async fn update_post(
|
||||||
) -> Result<Json<PostResponse>, LemmyError> {
|
) -> Result<Json<PostResponse>, LemmyError> {
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
let data_url = data.url.as_ref();
|
|
||||||
|
|
||||||
// TODO No good way to handle a clear.
|
|
||||||
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
|
||||||
let url = Some(data_url.map(clean_url_params).map(Into::into));
|
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
check_slurs_opt(&data.name, &slur_regex)?;
|
check_slurs_opt(&data.name, &slur_regex)?;
|
||||||
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
let body = process_markdown_opt(&data.body, &slur_regex, &context).await?;
|
||||||
|
@ -75,6 +69,19 @@ pub async fn update_post(
|
||||||
.map(|u| (Some(u.title), Some(u.description), Some(u.embed_video_url)))
|
.map(|u| (Some(u.title), Some(u.description), Some(u.embed_video_url)))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// TODO No good way to handle a clear.
|
||||||
|
// Issue link: https://github.com/LemmyNet/lemmy/issues/2287
|
||||||
|
let url = Some(data.url.as_ref().map(clean_url_params).map(Into::into));
|
||||||
|
|
||||||
|
// TODO: not sure how to get this working
|
||||||
|
/*
|
||||||
|
let url_is_image = todo!();
|
||||||
|
if url_is_image {
|
||||||
|
data_url = proxy_image_link_opt(url, &context).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
let language_id = data.language_id;
|
let language_id = data.language_id;
|
||||||
CommunityLanguage::is_allowed_community_language(
|
CommunityLanguage::is_allowed_community_language(
|
||||||
&mut context.pool(),
|
&mut context.pool(),
|
||||||
|
|
|
@ -10,6 +10,7 @@ use lemmy_api_common::{
|
||||||
local_site_rate_limit_to_rate_limit_config,
|
local_site_rate_limit_to_rate_limit_config,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
process_markdown_opt,
|
process_markdown_opt,
|
||||||
|
proxy_image_link_opt,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -21,7 +22,7 @@ use lemmy_db_schema::{
|
||||||
tagline::Tagline,
|
tagline::Tagline,
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now},
|
utils::{diesel_option_overwrite, naive_now},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -58,13 +59,15 @@ pub async fn create_site(
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
let sidebar = process_markdown_opt(&data.sidebar, &slur_regex, &context).await?;
|
let sidebar = process_markdown_opt(&data.sidebar, &slur_regex, &context).await?;
|
||||||
|
let icon = proxy_image_link_opt(&data.icon, &context).await?;
|
||||||
|
let banner = proxy_image_link_opt(&data.banner, &context).await?;
|
||||||
|
|
||||||
let site_form = SiteUpdateForm {
|
let site_form = SiteUpdateForm {
|
||||||
name: Some(data.name.clone()),
|
name: Some(data.name.clone()),
|
||||||
sidebar: diesel_option_overwrite(sidebar),
|
sidebar: diesel_option_overwrite(sidebar),
|
||||||
description: diesel_option_overwrite(data.description.clone()),
|
description: diesel_option_overwrite(data.description.clone()),
|
||||||
icon: diesel_option_overwrite_to_url(&data.icon)?,
|
icon,
|
||||||
banner: diesel_option_overwrite_to_url(&data.banner)?,
|
banner,
|
||||||
actor_id: Some(actor_id),
|
actor_id: Some(actor_id),
|
||||||
last_refreshed_at: Some(naive_now()),
|
last_refreshed_at: Some(naive_now()),
|
||||||
inbox_url,
|
inbox_url,
|
||||||
|
|
|
@ -8,6 +8,7 @@ use lemmy_api_common::{
|
||||||
local_site_rate_limit_to_rate_limit_config,
|
local_site_rate_limit_to_rate_limit_config,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
process_markdown_opt,
|
process_markdown_opt,
|
||||||
|
proxy_image_link_opt,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
@ -22,7 +23,7 @@ use lemmy_db_schema::{
|
||||||
tagline::Tagline,
|
tagline::Tagline,
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now},
|
utils::{diesel_option_overwrite, naive_now},
|
||||||
RegistrationMode,
|
RegistrationMode,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
|
@ -61,13 +62,15 @@ pub async fn update_site(
|
||||||
|
|
||||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||||
let sidebar = process_markdown_opt(&data.sidebar, &slur_regex, &context).await?;
|
let sidebar = process_markdown_opt(&data.sidebar, &slur_regex, &context).await?;
|
||||||
|
let icon = proxy_image_link_opt(&data.icon, &context).await?;
|
||||||
|
let banner = proxy_image_link_opt(&data.banner, &context).await?;
|
||||||
|
|
||||||
let site_form = SiteUpdateForm {
|
let site_form = SiteUpdateForm {
|
||||||
name: data.name.clone(),
|
name: data.name.clone(),
|
||||||
sidebar: diesel_option_overwrite(sidebar),
|
sidebar: diesel_option_overwrite(sidebar),
|
||||||
description: diesel_option_overwrite(data.description.clone()),
|
description: diesel_option_overwrite(data.description.clone()),
|
||||||
icon: diesel_option_overwrite_to_url(&data.icon)?,
|
icon,
|
||||||
banner: diesel_option_overwrite_to_url(&data.banner)?,
|
banner,
|
||||||
updated: Some(Some(naive_now())),
|
updated: Some(Some(naive_now())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
newtypes::{DbUrl, LocalImageId, LocalUserId},
|
newtypes::{DbUrl, LocalImageId, LocalUserId},
|
||||||
schema::{
|
schema::{
|
||||||
local_image::dsl::{local_image, local_user_id, pictrs_alias},
|
local_image::dsl::{local_image, local_user_id, pictrs_alias},
|
||||||
remote_image::dsl::{remote_image, link},
|
remote_image::dsl::{link, remote_image},
|
||||||
},
|
},
|
||||||
source::images::{LocalImage, LocalImageForm, RemoteImage, RemoteImageForm},
|
source::images::{LocalImage, LocalImageForm, RemoteImage, RemoteImageForm},
|
||||||
utils::{get_conn, DbPool},
|
utils::{get_conn, DbPool},
|
||||||
|
@ -60,7 +60,7 @@ impl LocalImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteImage {
|
impl RemoteImage {
|
||||||
pub async fn create_many(pool: &mut DbPool<'_>, links: Vec<Url>) -> Result<Self, Error> {
|
pub async fn create(pool: &mut DbPool<'_>, links: Vec<Url>) -> Result<usize, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
let forms = links
|
let forms = links
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -68,7 +68,8 @@ impl RemoteImage {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
insert_into(remote_image)
|
insert_into(remote_image)
|
||||||
.values(forms)
|
.values(forms)
|
||||||
.get_result::<Self>(conn)
|
.on_conflict_do_nothing()
|
||||||
|
.execute(conn)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ async fn image_proxy(
|
||||||
// for arbitrary purposes.
|
// for arbitrary purposes.
|
||||||
RemoteImage::validate(&mut context.pool(), url.clone().into()).await?;
|
RemoteImage::validate(&mut context.pool(), url.clone().into()).await?;
|
||||||
|
|
||||||
// TODO: Once pictrs 0.5 is out, use it for proxying like GET /image/original?proxy={url}
|
// TODO: Once pictrs 0.5 is out, use it for proxying like `GET /image/original?proxy={url}`. In
|
||||||
|
// case pictrs is unavailable, fallback to this impl.
|
||||||
// https://git.asonix.dog/asonix/pict-rs/#api
|
// https://git.asonix.dog/asonix/pict-rs/#api
|
||||||
let image_response = context.client().get(url).send().await?;
|
let image_response = context.client().get(url).send().await?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue