Update push

This commit is contained in:
2023-11-01 11:39:58 +00:00
committed by GitHub
parent c7cdfac896
commit 061a3160d6
7 changed files with 239 additions and 6 deletions

1
Cargo.lock generated
View File

@@ -1576,6 +1576,7 @@ dependencies = [
"multipart",
"openssl",
"parse-size",
"percent-encoding",
"proc_macros",
"rand",
"regex",

View File

@@ -39,6 +39,7 @@ modular-bitfield = "0.11"
multipart = { features = ["server"], git = 'https://github.com/lifegpc/multipart', optional = true, default-features = false }
openssl = { version = "0.10", optional = true }
parse-size = "1"
percent-encoding = { version = "*", optional = true }
proc_macros = { path = "proc_macros" }
rand = { version = "0", optional = true }
regex = "1"
@@ -65,7 +66,7 @@ db_all = ["db", "db_sqlite"]
db_sqlite = ["rusqlite"]
docker = []
exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"]
server = ["async-trait", "base64", "db", "hex", "hyper", "multipart", "openssl", "serde_json", "rand", "serde_urlencoded"]
server = ["async-trait", "base64", "db", "hex", "hyper", "multipart", "openssl", "serde_json", "rand", "serde_urlencoded", "percent-encoding"]
ugoira = ["avdict", "bindgen", "cmake", "link-cplusplus"]
[patch.crates-io]

View File

@@ -996,7 +996,7 @@ pub fn pushdeer_api_quick_test(item: TokenStream) -> TokenStream {
match std::env::var("PUSHDEER_SERVER") {
Ok(server) => match std::env::var("PUSHDEER_TOKEN") {
Ok(token) => {
let client = PushdeerClient::new(server);
let client = PushdeerClient::new(&server);
match #expr.await {
Ok(_) => {},
Err(e) => {

View File

@@ -93,10 +93,48 @@ pub struct EveryPushConfig {
pub add_translated_tag: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PushDeerConfig {
/// Push server
pub push_server: String,
/// Push key
pub pushkey: String,
/// Push type
pub typ: EveryPushTextType,
#[serde(default = "defualt_author_locations")]
/// Author locations
/// Not supported when type is `Image`.
pub author_locations: Vec<AuthorLocation>,
#[serde(default = "default_true")]
/// Whether to filter author name
pub filter_author: bool,
#[serde(default = "default_true")]
/// Whether to add artwork link
pub add_link: bool,
#[serde(default = "default_true")]
/// Whether to add artwork link to title
/// Supported when type is `Text`.
pub add_link_to_title: bool,
#[serde(default = "default_true")]
/// Whether to add image link to image
pub add_link_to_image: bool,
#[serde(default = "default_true")]
/// Whether to add tags
pub add_tags: bool,
#[serde(default = "default_true")]
/// Whether to add AI tag
pub add_ai_tag: bool,
#[serde(default = "default_true")]
/// Whether to add translated tag
pub add_translated_tag: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum PushConfig {
EveryPush(EveryPushConfig),
PushDeer(PushDeerConfig),
}
#[derive(Debug, Serialize, Deserialize)]

View File

@@ -9,10 +9,10 @@ pub struct PushdeerClient {
}
impl PushdeerClient {
pub fn new(server: String) -> Self {
pub fn new<S: AsRef<str> + ?Sized>(server: &S) -> Self {
Self {
client: WebClient::default(),
server,
server: server.as_ref().to_owned(),
}
}

View File

@@ -11,6 +11,7 @@ use crate::get_helper;
use crate::gettext;
use crate::pixiv_app::PixivAppClient;
use crate::pixiv_web::PixivWebClient;
use crate::utils::get_file_name_from_url;
use futures_util::lock::Mutex;
use hyper::{http::response::Builder, Body, Request, Response};
use json::JsonValue;
@@ -63,7 +64,15 @@ impl ServerContext {
sha512.update(u.as_str().as_bytes());
let sign = hex::encode(sha512.finish());
map.insert("sign", &sign);
let url = format!("{}/proxy/pixiv?{}", base, serde_urlencoded::to_string(map)?);
let name = get_file_name_from_url(u.as_str())
.map(|v| format!("/{}", v))
.unwrap_or_default();
let url = format!(
"{}/proxy/pixiv{}?{}",
base,
name,
serde_urlencoded::to_string(map)?
);
Ok(url)
}

View File

@@ -1,12 +1,14 @@
use super::super::super::preclude::*;
use crate::db::push_task::{AuthorLocation, EveryPushConfig, PushConfig};
use crate::db::push_task::{AuthorLocation, EveryPushConfig, PushConfig, PushDeerConfig};
use crate::error::PixivDownloaderError;
use crate::opt::author_name_filter::AuthorFiler;
use crate::parser::description::DescriptionParser;
use crate::pixivapp::illust::PixivAppIllust;
use crate::push::every_push::{EveryPushClient, EveryPushTextType};
use crate::push::pushdeer::PushdeerClient;
use crate::{get_helper, gettext};
use json::JsonValue;
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
struct RunContext<'a> {
ctx: Arc<ServerContext>,
@@ -99,6 +101,7 @@ impl<'a> RunContext<'a> {
pub fn filter_author(&self) -> bool {
match self.cfg {
PushConfig::EveryPush(e) => e.filter_author,
PushConfig::PushDeer(e) => e.filter_author,
}
}
@@ -344,9 +347,190 @@ impl<'a> RunContext<'a> {
}
Ok(())
}
pub async fn send_push_deer(&self, cfg: &PushDeerConfig) -> Result<(), PixivDownloaderError> {
let client = PushdeerClient::new(&cfg.push_server);
match &cfg.typ {
EveryPushTextType::Text => {
let mut title = self.title().map(|s| {
if cfg.add_link_to_title {
if let Some(id) = self.id() {
format!("[{}](https://www.pixiv.net/artworks/{})", s, id)
} else {
s.to_owned()
}
} else {
s.to_owned()
}
});
let author = self.author();
if cfg.author_locations.contains(&AuthorLocation::Title) {
if let Some(t) = &title {
if let Some(a) = &author {
let au = if let Some(uid) = self.user_id() {
format!("[{}](https://www.pixiv.net/users/{})", a, uid)
} else {
a.to_owned()
};
title = Some(format!("{} - {}", t, au));
}
}
}
let mut text = String::new();
if let Some(t) = &title {
text.push_str(t);
text.push_str("\n\n");
}
if cfg.author_locations.contains(&AuthorLocation::Top) {
if let Some(a) = &author {
self.add_author(&mut text, a);
}
}
if cfg.add_link {
if let Some(id) = self.id() {
let link = format!("https://www.pixiv.net/artworks/{}", id);
text.push_str(&format!("[{}]({}) \n", link, link));
}
}
if let Some(desc) = self.desc() {
let mut p = DescriptionParser::new(true);
p.parse(desc)?;
while !text.ends_with("\n\n") {
text.push_str("\n");
}
text.push_str(&p.data);
if !p.data.ends_with("\n\n") {
text.push_str("\n\n");
}
}
if cfg.add_tags {
if cfg.add_ai_tag && self.is_ai() {
text.push_str("#");
text.push_str(gettext("AI generated"));
text.push_str(" ");
}
if let Some(i) = self.illust {
for tag in i.tags() {
if let Some(name) = tag.name() {
let encoded = percent_encode(name.as_bytes(), NON_ALPHANUMERIC);
text.push_str(&format!(
"[#{}](https://www.pixiv.net/tags/{}) ",
name, &encoded
));
if cfg.add_translated_tag {
if let Some(t) = tag.translated_name() {
text.push_str(&format!(
"[#{}](https://www.pixiv.net/tags/{}) ",
t, &encoded
));
}
}
}
}
}
text.push_str(" \n");
}
if cfg.author_locations.contains(&AuthorLocation::Bottom) {
if let Some(a) = &author {
self.add_author(&mut text, a);
}
}
client.push_text_message(&cfg.pushkey, &text).await?;
}
EveryPushTextType::Markdown => {
let mut title = self.title().map(|s| s.to_owned());
let author = self.author();
if cfg.author_locations.contains(&AuthorLocation::Title) {
if let Some(t) = &title {
if let Some(a) = &author {
title = Some(format!("{} - {}", t, a));
}
}
}
let title = title.ok_or("title not found.")?;
let mut text = String::new();
let len = self.len().unwrap_or(1);
for i in 0..len {
if let Some(url) = self.get_image_url(i).await? {
if cfg.add_link_to_image {
text.push_str("[");
}
text.push_str(&format!("![​]({})", url));
if cfg.add_link_to_image {
text.push_str(&format!("]({})", url));
}
}
}
if cfg.author_locations.contains(&AuthorLocation::Top) {
if let Some(a) = &author {
self.add_author(&mut text, a);
}
}
if cfg.add_link {
if let Some(id) = self.id() {
let link = format!("https://www.pixiv.net/artworks/{}", id);
text.push_str(&format!("[{}]({}) \n", link, link));
}
}
if let Some(desc) = self.desc() {
let mut p = DescriptionParser::new(true);
p.parse(desc)?;
while !text.ends_with("\n\n") {
text.push_str("\n");
}
text.push_str(&p.data);
if !p.data.ends_with("\n\n") {
text.push_str("\n\n");
}
}
if cfg.add_tags {
if cfg.add_ai_tag && self.is_ai() {
text.push_str("#");
text.push_str(gettext("AI generated"));
text.push_str(" ");
}
if let Some(i) = self.illust {
for tag in i.tags() {
if let Some(name) = tag.name() {
let encoded = percent_encode(name.as_bytes(), NON_ALPHANUMERIC);
text.push_str(&format!(
"[#{}](https://www.pixiv.net/tags/{}) ",
name, &encoded
));
if cfg.add_translated_tag {
if let Some(t) = tag.translated_name() {
text.push_str(&format!(
"[#{}](https://www.pixiv.net/tags/{}) ",
t, &encoded
));
}
}
}
}
}
text.push_str(" \n");
}
if cfg.author_locations.contains(&AuthorLocation::Bottom) {
if let Some(a) = &author {
self.add_author(&mut text, a);
}
}
client
.push_markdown_message(&cfg.pushkey, &title, &text)
.await?;
}
EveryPushTextType::Image => {
let url = self.get_image_url(0).await?.ok_or("image url not found.")?;
client.push_image(&cfg.pushkey, &url).await?;
}
}
Ok(())
}
pub async fn run(&self) -> Result<(), PixivDownloaderError> {
match self.cfg {
PushConfig::EveryPush(e) => self.send_every_push(e).await,
PushConfig::PushDeer(e) => self.send_push_deer(e).await,
}
}
}