Merge pull request 'Upgrade Tantivy to 0.13.3' (#878) from upgrade-tantivy into main
Reviewed-on: https://git.joinplu.me/Plume/Plume/pulls/878
This commit is contained in:
commit
a11205324b
@ -71,7 +71,7 @@ commands:
|
|||||||
type: string
|
type: string
|
||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
export RUSTFLAGS="-Zprofile -Zfewer-names -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads -Clink-arg=-Xlinker -Clink-arg=--no-keep-memory -Clink-arg=-Xlinker -Clink-arg=--reduce-memory-overheads"
|
export RUSTFLAGS="-Zprofile -Zfewer-names -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Clink-arg=-Xlinker -Clink-arg=--no-keep-memory -Clink-arg=-Xlinker -Clink-arg=--reduce-memory-overheads"
|
||||||
export CARGO_INCREMENTAL=0
|
export CARGO_INCREMENTAL=0
|
||||||
<< parameters.cmd >>
|
<< parameters.cmd >>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ RUN apt update &&\
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
#install and configure rust
|
#install and configure rust
|
||||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2020-12-07 -y &&\
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-01-15 -y &&\
|
||||||
rustup component add rustfmt clippy &&\
|
rustup component add rustfmt clippy &&\
|
||||||
rustup component add rust-std --target wasm32-unknown-unknown
|
rustup component add rust-std --target wasm32-unknown-unknown
|
||||||
|
|
||||||
|
3938
Cargo.lock
generated
3938
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
2
build.rs
2
build.rs
@ -1,5 +1,3 @@
|
|||||||
use rsass;
|
|
||||||
|
|
||||||
use ructe::Ructe;
|
use ructe::Ructe;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::{ffi::OsStr, fs::*, io::Write, path::*};
|
use std::{ffi::OsStr, fs::*, io::Write, path::*};
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use dotenv;
|
|
||||||
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
use plume_models::{instance::Instance, Connection as Conn, CONFIG};
|
use plume_models::{instance::Instance, Connection as Conn, CONFIG};
|
||||||
|
@ -106,7 +106,7 @@ fn refill<'a>(args: &ArgMatches<'a>, conn: &Connection, searcher: Option<Searche
|
|||||||
searcher.commit();
|
searcher.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock<'a>(args: &ArgMatches<'a>) {
|
fn unlock(args: &ArgMatches) {
|
||||||
let path = match args.value_of("path") {
|
let path = match args.value_of("path") {
|
||||||
None => Path::new(&CONFIG.search_index),
|
None => Path::new(&CONFIG.search_index),
|
||||||
Some(x) => Path::new(x),
|
Some(x) => Path::new(x),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
|
|
||||||
use plume_models::{instance::Instance, users::*, Connection};
|
use plume_models::{instance::Instance, users::*, Connection};
|
||||||
use rpassword;
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
||||||
|
@ -7,7 +7,6 @@ use rocket::{
|
|||||||
response::{Responder, Response},
|
response::{Responder, Response},
|
||||||
Outcome,
|
Outcome,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use base64;
|
|
||||||
use chrono::{offset::Utc, DateTime};
|
use chrono::{offset::Utc, DateTime};
|
||||||
use openssl::hash::{Hasher, MessageDigest};
|
use openssl::hash::{Hasher, MessageDigest};
|
||||||
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, DATE, USER_AGENT};
|
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, DATE, USER_AGENT};
|
||||||
@ -10,6 +9,9 @@ use crate::activity_pub::{ap_accept_header, AP_CONTENT_TYPE};
|
|||||||
|
|
||||||
const PLUME_USER_AGENT: &str = concat!("Plume/", env!("CARGO_PKG_VERSION"));
|
const PLUME_USER_AGENT: &str = concat!("Plume/", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error();
|
||||||
|
|
||||||
pub struct Digest(String);
|
pub struct Digest(String);
|
||||||
|
|
||||||
impl Digest {
|
impl Digest {
|
||||||
@ -62,16 +64,16 @@ impl Digest {
|
|||||||
base64::decode(&self.0[pos..]).expect("Digest::value: invalid encoding error")
|
base64::decode(&self.0[pos..]).expect("Digest::value: invalid encoding error")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_header(dig: &str) -> Result<Self, ()> {
|
pub fn from_header(dig: &str) -> Result<Self, Error> {
|
||||||
if let Some(pos) = dig.find('=') {
|
if let Some(pos) = dig.find('=') {
|
||||||
let pos = pos + 1;
|
let pos = pos + 1;
|
||||||
if base64::decode(&dig[pos..]).is_ok() {
|
if base64::decode(&dig[pos..]).is_ok() {
|
||||||
Ok(Digest(dig.to_owned()))
|
Ok(Digest(dig.to_owned()))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,7 @@ pub fn headers() -> HeaderMap {
|
|||||||
headers
|
headers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderValue, ()> {
|
pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderValue, Error> {
|
||||||
let signed_string = headers
|
let signed_string = headers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(h, v)| {
|
.map(|(h, v)| {
|
||||||
@ -130,7 +132,7 @@ pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderVal
|
|||||||
.join(" ")
|
.join(" ")
|
||||||
.to_lowercase();
|
.to_lowercase();
|
||||||
|
|
||||||
let data = signer.sign(&signed_string).map_err(|_| ())?;
|
let data = signer.sign(&signed_string).map_err(|_| Error())?;
|
||||||
let sign = base64::encode(&data);
|
let sign = base64::encode(&data);
|
||||||
|
|
||||||
HeaderValue::from_str(&format!(
|
HeaderValue::from_str(&format!(
|
||||||
@ -138,5 +140,5 @@ pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderVal
|
|||||||
key_id = signer.get_key_id(),
|
key_id = signer.get_key_id(),
|
||||||
signed_headers = signed_headers,
|
signed_headers = signed_headers,
|
||||||
signature = sign
|
signature = sign
|
||||||
)).map_err(|_| ())
|
)).map_err(|_| Error())
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
use super::request;
|
use super::request;
|
||||||
use base64;
|
|
||||||
use chrono::{naive::NaiveDateTime, DateTime, Duration, Utc};
|
use chrono::{naive::NaiveDateTime, DateTime, Duration, Utc};
|
||||||
use hex;
|
|
||||||
use openssl::{pkey::PKey, rsa::Rsa, sha::sha256};
|
use openssl::{pkey::PKey, rsa::Rsa, sha::sha256};
|
||||||
use rocket::http::HeaderMap;
|
use rocket::http::HeaderMap;
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
/// Returns (public key, private key)
|
/// Returns (public key, private key)
|
||||||
pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
||||||
@ -20,6 +17,9 @@ pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error();
|
||||||
|
|
||||||
pub trait Signer {
|
pub trait Signer {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ pub trait Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Signable {
|
pub trait Signable {
|
||||||
fn sign<T>(&mut self, creator: &T) -> Result<&mut Self, ()>
|
fn sign<T>(&mut self, creator: &T) -> Result<&mut Self, Error>
|
||||||
where
|
where
|
||||||
T: Signer;
|
T: Signer;
|
||||||
fn verify<T>(self, creator: &T) -> bool
|
fn verify<T>(self, creator: &T) -> bool
|
||||||
@ -46,7 +46,7 @@ pub trait Signable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Signable for serde_json::Value {
|
impl Signable for serde_json::Value {
|
||||||
fn sign<T: Signer>(&mut self, creator: &T) -> Result<&mut serde_json::Value, ()> {
|
fn sign<T: Signer>(&mut self, creator: &T) -> Result<&mut serde_json::Value, Error> {
|
||||||
let creation_date = Utc::now().to_rfc3339();
|
let creation_date = Utc::now().to_rfc3339();
|
||||||
let mut options = json!({
|
let mut options = json!({
|
||||||
"type": "RsaSignature2017",
|
"type": "RsaSignature2017",
|
||||||
@ -64,7 +64,7 @@ impl Signable for serde_json::Value {
|
|||||||
let document_hash = Self::hash(&self.to_string());
|
let document_hash = Self::hash(&self.to_string());
|
||||||
let to_be_signed = options_hash + &document_hash;
|
let to_be_signed = options_hash + &document_hash;
|
||||||
|
|
||||||
let signature = base64::encode(&creator.sign(&to_be_signed).map_err(|_| ())?);
|
let signature = base64::encode(&creator.sign(&to_be_signed).map_err(|_| Error())?);
|
||||||
|
|
||||||
options["signatureValue"] = serde_json::Value::String(signature);
|
options["signatureValue"] = serde_json::Value::String(signature);
|
||||||
self["signature"] = options;
|
self["signature"] = options;
|
||||||
|
3
plume-common/src/lib.rs
Normal file → Executable file
3
plume-common/src/lib.rs
Normal file → Executable file
@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate activitystreams_derive;
|
extern crate activitystreams_derive;
|
||||||
use activitystreams_traits;
|
|
||||||
|
|
||||||
use serde;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate shrinkwraprs;
|
extern crate shrinkwraprs;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -60,6 +60,7 @@ fn to_inline(tag: Tag<'_>) -> Tag<'_> {
|
|||||||
struct HighlighterContext {
|
struct HighlighterContext {
|
||||||
content: Vec<String>,
|
content: Vec<String>,
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn highlight_code<'a>(
|
fn highlight_code<'a>(
|
||||||
context: &mut Option<HighlighterContext>,
|
context: &mut Option<HighlighterContext>,
|
||||||
evt: Event<'a>,
|
evt: Event<'a>,
|
||||||
@ -119,6 +120,7 @@ fn highlight_code<'a>(
|
|||||||
_ => Some(vec![evt]),
|
_ => Some(vec![evt]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Event<'a>>> {
|
fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Event<'a>>> {
|
||||||
let (s, res) = match evt {
|
let (s, res) = match evt {
|
||||||
Event::Text(txt) => match state.take() {
|
Event::Text(txt) => match state.take() {
|
||||||
@ -137,6 +139,7 @@ fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Ev
|
|||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn inline_tags<'a>(
|
fn inline_tags<'a>(
|
||||||
(state, inline): &mut (Vec<Tag<'a>>, bool),
|
(state, inline): &mut (Vec<Tag<'a>>, bool),
|
||||||
evt: Event<'a>,
|
evt: Event<'a>,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::CATALOG;
|
use crate::CATALOG;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json;
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use stdweb::{
|
use stdweb::{
|
||||||
unstable::{TryFrom, TryInto},
|
unstable::{TryFrom, TryInto},
|
||||||
|
8
plume-macro/src/lib.rs
Normal file → Executable file
8
plume-macro/src/lib.rs
Normal file → Executable file
@ -89,12 +89,12 @@ fn file_to_migration(file: &str) -> TokenStream2 {
|
|||||||
let mut actions = vec![];
|
let mut actions = vec![];
|
||||||
for line in file.lines() {
|
for line in file.lines() {
|
||||||
if sql {
|
if sql {
|
||||||
if line.starts_with("--#!") {
|
if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||||
if !acc.trim().is_empty() {
|
if !acc.trim().is_empty() {
|
||||||
actions.push(quote!(Action::Sql(#acc)));
|
actions.push(quote!(Action::Sql(#acc)));
|
||||||
}
|
}
|
||||||
sql = false;
|
sql = false;
|
||||||
acc = line[4..].to_string();
|
acc = acc_str.to_string();
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
} else if line.starts_with("--") {
|
} else if line.starts_with("--") {
|
||||||
continue;
|
continue;
|
||||||
@ -102,8 +102,8 @@ fn file_to_migration(file: &str) -> TokenStream2 {
|
|||||||
acc.push_str(line);
|
acc.push_str(line);
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
}
|
}
|
||||||
} else if line.starts_with("--#!") {
|
} else if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||||
acc.push_str(&line[4..]);
|
acc.push_str(&acc_str);
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
} else if line.starts_with("--") {
|
} else if line.starts_with("--") {
|
||||||
continue;
|
continue;
|
||||||
|
@ -23,7 +23,7 @@ scheduled-thread-pool = "0.2.2"
|
|||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tantivy = "0.12.0"
|
tantivy = "0.13.3"
|
||||||
url = "2.1"
|
url = "2.1"
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
webfinger = "0.4.1"
|
webfinger = "0.4.1"
|
||||||
@ -31,7 +31,7 @@ whatlang = "0.11.1"
|
|||||||
shrinkwraprs = "0.2.1"
|
shrinkwraprs = "0.2.1"
|
||||||
diesel-derive-newtype = "0.1.2"
|
diesel-derive-newtype = "0.1.2"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
lindera-tantivy = { version = "0.1.3", optional = true }
|
lindera-tantivy = { version = "0.7.1", optional = true }
|
||||||
tracing = "0.1.22"
|
tracing = "0.1.22"
|
||||||
|
|
||||||
[dependencies.chrono]
|
[dependencies.chrono]
|
||||||
|
@ -20,7 +20,6 @@ use plume_common::activity_pub::{
|
|||||||
inbox::{AsActor, FromId},
|
inbox::{AsActor, FromId},
|
||||||
sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source,
|
sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webfinger::*;
|
use webfinger::*;
|
||||||
|
|
||||||
@ -217,16 +216,16 @@ impl Blog {
|
|||||||
|
|
||||||
pub fn outbox(&self, conn: &Connection) -> Result<ActivityStream<OrderedCollection>> {
|
pub fn outbox(&self, conn: &Connection) -> Result<ActivityStream<OrderedCollection>> {
|
||||||
let mut coll = OrderedCollection::default();
|
let mut coll = OrderedCollection::default();
|
||||||
coll.collection_props.items = serde_json::to_value(self.get_activities(conn)?)?;
|
coll.collection_props.items = serde_json::to_value(self.get_activities(conn))?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_total_items_u64(self.get_activities(conn)?.len() as u64)?;
|
.set_total_items_u64(self.get_activities(conn).len() as u64)?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?;
|
.set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_last_link(Id::new(ap_url(&format!(
|
.set_last_link(Id::new(ap_url(&format!(
|
||||||
"{}?page={}",
|
"{}?page={}",
|
||||||
&self.outbox_url,
|
&self.outbox_url,
|
||||||
(self.get_activities(conn)?.len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64
|
(self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64
|
||||||
/ ITEMS_PER_PAGE as u64
|
/ ITEMS_PER_PAGE as u64
|
||||||
))))?;
|
))))?;
|
||||||
Ok(ActivityStream::new(coll))
|
Ok(ActivityStream::new(coll))
|
||||||
@ -237,7 +236,7 @@ impl Blog {
|
|||||||
(min, max): (i32, i32),
|
(min, max): (i32, i32),
|
||||||
) -> Result<ActivityStream<OrderedCollectionPage>> {
|
) -> Result<ActivityStream<OrderedCollectionPage>> {
|
||||||
let mut coll = OrderedCollectionPage::default();
|
let mut coll = OrderedCollectionPage::default();
|
||||||
let acts = self.get_activity_page(&conn, (min, max))?;
|
let acts = self.get_activity_page(&conn, (min, max));
|
||||||
//This still doesn't do anything because the outbox
|
//This still doesn't do anything because the outbox
|
||||||
//doesn't do anything yet
|
//doesn't do anything yet
|
||||||
coll.collection_page_props.set_next_link(Id::new(&format!(
|
coll.collection_page_props.set_next_link(Id::new(&format!(
|
||||||
@ -253,15 +252,15 @@ impl Blog {
|
|||||||
coll.collection_props.items = serde_json::to_value(acts)?;
|
coll.collection_props.items = serde_json::to_value(acts)?;
|
||||||
Ok(ActivityStream::new(coll))
|
Ok(ActivityStream::new(coll))
|
||||||
}
|
}
|
||||||
fn get_activities(&self, _conn: &Connection) -> Result<Vec<serde_json::Value>> {
|
fn get_activities(&self, _conn: &Connection) -> Vec<serde_json::Value> {
|
||||||
Ok(vec![])
|
vec![]
|
||||||
}
|
}
|
||||||
fn get_activity_page(
|
fn get_activity_page(
|
||||||
&self,
|
&self,
|
||||||
_conn: &Connection,
|
_conn: &Connection,
|
||||||
(_min, _max): (i32, i32),
|
(_min, _max): (i32, i32),
|
||||||
) -> Result<Vec<serde_json::Value>> {
|
) -> Vec<serde_json::Value> {
|
||||||
Ok(vec![])
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_keypair(&self) -> Result<PKey<Private>> {
|
pub fn get_keypair(&self) -> Result<PKey<Private>> {
|
||||||
|
@ -24,7 +24,6 @@ use plume_common::{
|
|||||||
},
|
},
|
||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
||||||
|
@ -164,8 +164,8 @@ impl Default for LogoConfig {
|
|||||||
};
|
};
|
||||||
let mut custom_icons = env::vars()
|
let mut custom_icons = env::vars()
|
||||||
.filter_map(|(var, val)| {
|
.filter_map(|(var, val)| {
|
||||||
if var.starts_with("PLUME_LOGO_") {
|
if let Some(size) = var.strip_prefix("PLUME_LOGO_") {
|
||||||
Some((var[11..].to_owned(), val))
|
Some((size.to_owned(), val))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||||||
let proxy_url = url.clone();
|
let proxy_url = url.clone();
|
||||||
let only_domains: Option<HashSet<String>> = var("PROXY_DOMAINS")
|
let only_domains: Option<HashSet<String>> = var("PROXY_DOMAINS")
|
||||||
.ok()
|
.ok()
|
||||||
.map(|ods| ods.split(",").map(str::to_owned).collect());
|
.map(|ods| ods.split(',').map(str::to_owned).collect());
|
||||||
let proxy = if let Some(ref only_domains) = only_domains {
|
let proxy = if let Some(ref only_domains) = only_domains {
|
||||||
let only_domains = only_domains.clone();
|
let only_domains = only_domains.clone();
|
||||||
reqwest::Proxy::custom(move |url| {
|
reqwest::Proxy::custom(move |url| {
|
||||||
@ -303,9 +303,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||||||
if only_domains.contains(domain)
|
if only_domains.contains(domain)
|
||||||
|| only_domains
|
|| only_domains
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|target| domain.ends_with(&format!(".{}", target)))
|
.any(|target| domain.ends_with(&format!(".{}", target)))
|
||||||
.next()
|
|
||||||
.is_some()
|
|
||||||
{
|
{
|
||||||
Some(proxy_url.clone())
|
Some(proxy_url.clone())
|
||||||
} else {
|
} else {
|
||||||
@ -316,9 +314,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
reqwest::Proxy::all(proxy_url)
|
reqwest::Proxy::all(proxy_url).expect("Invalid PROXY_URL")
|
||||||
.ok()
|
|
||||||
.expect("Invalid PROXY_URL")
|
|
||||||
};
|
};
|
||||||
Some(ProxyConfig {
|
Some(ProxyConfig {
|
||||||
url,
|
url,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use activitypub::activity::*;
|
use activitypub::activity::*;
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comments::Comment,
|
comments::Comment,
|
||||||
|
1
plume-models/src/lib.rs
Normal file → Executable file
1
plume-models/src/lib.rs
Normal file → Executable file
@ -11,7 +11,6 @@ extern crate lazy_static;
|
|||||||
extern crate plume_macro;
|
extern crate plume_macro;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
@ -30,9 +30,9 @@ impl TryFrom<i32> for ListType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<i32> for ListType {
|
impl From<ListType> for i32 {
|
||||||
fn into(self) -> i32 {
|
fn from(list_type: ListType) -> Self {
|
||||||
match self {
|
match list_type {
|
||||||
ListType::User => 0,
|
ListType::User => 0,
|
||||||
ListType::Blog => 1,
|
ListType::Blog => 1,
|
||||||
ListType::Word => 2,
|
ListType::Word => 2,
|
||||||
@ -246,22 +246,22 @@ impl List {
|
|||||||
private::ListElem::prefix_in_list(conn, self, word)
|
private::ListElem::prefix_in_list(conn, self, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert new users in a list
|
// Insert new users in a list
|
||||||
func! {add: add_users, User}
|
func! {add: add_users, User}
|
||||||
|
|
||||||
/// Insert new blogs in a list
|
// Insert new blogs in a list
|
||||||
func! {add: add_blogs, Blog}
|
func! {add: add_blogs, Blog}
|
||||||
|
|
||||||
/// Insert new words in a list
|
// Insert new words in a list
|
||||||
func! {add: add_words, Word}
|
func! {add: add_words, Word}
|
||||||
|
|
||||||
/// Insert new prefixes in a list
|
// Insert new prefixes in a list
|
||||||
func! {add: add_prefixes, Prefix}
|
func! {add: add_prefixes, Prefix}
|
||||||
|
|
||||||
/// Get all users in the list
|
// Get all users in the list
|
||||||
func! {list: list_users, User, users}
|
func! {list: list_users, User, users}
|
||||||
|
|
||||||
/// Get all blogs in the list
|
// Get all blogs in the list
|
||||||
func! {list: list_blogs, Blog, blogs}
|
func! {list: list_blogs, Blog, blogs}
|
||||||
|
|
||||||
/// Get all words in the list
|
/// Get all words in the list
|
||||||
|
@ -10,7 +10,6 @@ use plume_common::{
|
|||||||
activity_pub::{inbox::FromId, Id},
|
activity_pub::{inbox::FromId, Id},
|
||||||
utils::MediaProcessor,
|
utils::MediaProcessor,
|
||||||
};
|
};
|
||||||
use reqwest;
|
|
||||||
use std::{fs, path::Path};
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
#[derive(Clone, Identifiable, Queryable)]
|
#[derive(Clone, Identifiable, Queryable)]
|
||||||
|
@ -19,7 +19,6 @@ use plume_common::{
|
|||||||
},
|
},
|
||||||
utils::md_to_html,
|
utils::md_to_html,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
||||||
@ -124,8 +123,7 @@ impl Post {
|
|||||||
.filter(posts::published.eq(true))
|
.filter(posts::published.eq(true))
|
||||||
.count()
|
.count()
|
||||||
.load(conn)?
|
.load(conn)?
|
||||||
.iter()
|
.get(0)
|
||||||
.next()
|
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(Error::NotFound)
|
.ok_or(Error::NotFound)
|
||||||
}
|
}
|
||||||
@ -288,12 +286,11 @@ impl Post {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_receivers_urls(&self, conn: &Connection) -> Result<Vec<String>> {
|
pub fn get_receivers_urls(&self, conn: &Connection) -> Result<Vec<String>> {
|
||||||
let followers = self
|
Ok(self
|
||||||
.get_authors(conn)?
|
.get_authors(conn)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|a| a.get_followers(conn).ok())
|
.filter_map(|a| a.get_followers(conn).ok())
|
||||||
.collect::<Vec<Vec<User>>>();
|
.fold(vec![], |mut acc, f| {
|
||||||
Ok(followers.into_iter().fold(vec![], |mut acc, f| {
|
|
||||||
for x in f {
|
for x in f {
|
||||||
acc.push(x.ap_url);
|
acc.push(x.ap_url);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ lazy_static! {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn url_add_prefix(url: &str) -> Option<Cow<'_, str>> {
|
fn url_add_prefix(url: &str) -> Option<Cow<'_, str>> {
|
||||||
if url.starts_with('#') && !url.starts_with("#postcontent-") {
|
if url.starts_with('#') && !url.starts_with("#postcontent-") {
|
||||||
//if start with an #
|
//if start with an #
|
||||||
|
@ -11,7 +11,6 @@ use activitypub::{
|
|||||||
object::{Image, Tombstone},
|
object::{Image, Tombstone},
|
||||||
Activity, CustomObject, Endpoint,
|
Activity, CustomObject, Endpoint,
|
||||||
};
|
};
|
||||||
use bcrypt;
|
|
||||||
use chrono::{NaiveDateTime, Utc};
|
use chrono::{NaiveDateTime, Utc};
|
||||||
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
||||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
use ldap3::{LdapConn, Scope, SearchEntry};
|
||||||
@ -38,7 +37,6 @@ use rocket::{
|
|||||||
outcome::IntoOutcome,
|
outcome::IntoOutcome,
|
||||||
request::{self, FromRequest, Request},
|
request::{self, FromRequest, Request},
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::PartialEq,
|
cmp::PartialEq,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
|
1068
po/plume/af.po
1068
po/plume/af.po
File diff suppressed because it is too large
Load Diff
1118
po/plume/ar.po
1118
po/plume/ar.po
File diff suppressed because it is too large
Load Diff
1170
po/plume/bg.po
1170
po/plume/bg.po
File diff suppressed because it is too large
Load Diff
1168
po/plume/ca.po
1168
po/plume/ca.po
File diff suppressed because it is too large
Load Diff
1146
po/plume/cs.po
1146
po/plume/cs.po
File diff suppressed because it is too large
Load Diff
1096
po/plume/cy.po
1096
po/plume/cy.po
File diff suppressed because it is too large
Load Diff
1068
po/plume/da.po
1068
po/plume/da.po
File diff suppressed because it is too large
Load Diff
1174
po/plume/de.po
1174
po/plume/de.po
File diff suppressed because it is too large
Load Diff
1068
po/plume/el.po
1068
po/plume/el.po
File diff suppressed because it is too large
Load Diff
1068
po/plume/en.po
1068
po/plume/en.po
File diff suppressed because it is too large
Load Diff
1082
po/plume/eo.po
1082
po/plume/eo.po
File diff suppressed because it is too large
Load Diff
1174
po/plume/es.po
1174
po/plume/es.po
File diff suppressed because it is too large
Load Diff
1166
po/plume/fa.po
1166
po/plume/fa.po
File diff suppressed because it is too large
Load Diff
1070
po/plume/fi.po
1070
po/plume/fi.po
File diff suppressed because it is too large
Load Diff
1178
po/plume/fr.po
1178
po/plume/fr.po
File diff suppressed because it is too large
Load Diff
1158
po/plume/gl.po
1158
po/plume/gl.po
File diff suppressed because it is too large
Load Diff
1072
po/plume/he.po
1072
po/plume/he.po
File diff suppressed because it is too large
Load Diff
1092
po/plume/hi.po
1092
po/plume/hi.po
File diff suppressed because it is too large
Load Diff
1072
po/plume/hr.po
1072
po/plume/hr.po
File diff suppressed because it is too large
Load Diff
1068
po/plume/hu.po
1068
po/plume/hu.po
File diff suppressed because it is too large
Load Diff
1166
po/plume/it.po
1166
po/plume/it.po
File diff suppressed because it is too large
Load Diff
1152
po/plume/ja.po
1152
po/plume/ja.po
File diff suppressed because it is too large
Load Diff
1066
po/plume/ko.po
1066
po/plume/ko.po
File diff suppressed because it is too large
Load Diff
1192
po/plume/nb.po
1192
po/plume/nb.po
File diff suppressed because it is too large
Load Diff
1162
po/plume/nl.po
1162
po/plume/nl.po
File diff suppressed because it is too large
Load Diff
1128
po/plume/no.po
1128
po/plume/no.po
File diff suppressed because it is too large
Load Diff
1172
po/plume/pl.po
1172
po/plume/pl.po
File diff suppressed because it is too large
Load Diff
1064
po/plume/plume.pot
1064
po/plume/plume.pot
File diff suppressed because it is too large
Load Diff
1134
po/plume/pt.po
1134
po/plume/pt.po
File diff suppressed because it is too large
Load Diff
1074
po/plume/ro.po
1074
po/plume/ro.po
File diff suppressed because it is too large
Load Diff
1088
po/plume/ru.po
1088
po/plume/ru.po
File diff suppressed because it is too large
Load Diff
1068
po/plume/sat.po
1068
po/plume/sat.po
File diff suppressed because it is too large
Load Diff
1070
po/plume/si.po
1070
po/plume/si.po
File diff suppressed because it is too large
Load Diff
1154
po/plume/sk.po
1154
po/plume/sk.po
File diff suppressed because it is too large
Load Diff
1072
po/plume/sl.po
1072
po/plume/sl.po
File diff suppressed because it is too large
Load Diff
1070
po/plume/sr.po
1070
po/plume/sr.po
File diff suppressed because it is too large
Load Diff
1072
po/plume/sv.po
1072
po/plume/sv.po
File diff suppressed because it is too large
Load Diff
1134
po/plume/tr.po
1134
po/plume/tr.po
File diff suppressed because it is too large
Load Diff
1072
po/plume/uk.po
1072
po/plume/uk.po
File diff suppressed because it is too large
Load Diff
1066
po/plume/vi.po
1066
po/plume/vi.po
File diff suppressed because it is too large
Load Diff
1116
po/plume/zh.po
1116
po/plume/zh.po
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
nightly-2020-01-15
|
nightly-2021-01-15
|
||||||
|
1
src/api/mod.rs
Normal file → Executable file
1
src/api/mod.rs
Normal file → Executable file
@ -4,7 +4,6 @@ use rocket::{
|
|||||||
response::{self, Responder},
|
response::{self, Responder},
|
||||||
};
|
};
|
||||||
use rocket_contrib::json::Json;
|
use rocket_contrib::json::Json;
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
use plume_common::utils::random_hex;
|
use plume_common::utils::random_hex;
|
||||||
use plume_models::{api_tokens::*, apps::App, users::User, Error, PlumeRocket};
|
use plume_models::{api_tokens::*, apps::App, users::User, Error, PlumeRocket};
|
||||||
|
@ -28,7 +28,6 @@ use std::process::exit;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use tracing_subscriber;
|
|
||||||
|
|
||||||
init_i18n!(
|
init_i18n!(
|
||||||
"plume", af, ar, bg, ca, cs, cy, da, de, el, en, eo, es, fa, fi, fr, gl, he, hi, hr, hu, it,
|
"plume", af, ar, bg, ca, cs, cy, da, de, el, en, eo, es, fa, fi, fr, gl, he, hi, hr, hu, it,
|
||||||
|
@ -91,9 +91,11 @@ pub fn create(
|
|||||||
});
|
});
|
||||||
|
|
||||||
Flash::success(
|
Flash::success(
|
||||||
Redirect::to(
|
Redirect::to(uri!(
|
||||||
uri!(super::posts::details: blog = blog_name, slug = slug, responding_to = _),
|
super::posts::details: blog = blog_name,
|
||||||
),
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)),
|
||||||
i18n!(&rockets.intl.catalog, "Your comment has been posted."),
|
i18n!(&rockets.intl.catalog, "Your comment has been posted."),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -168,7 +170,11 @@ pub fn delete(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Flash::success(
|
Ok(Flash::success(
|
||||||
Redirect::to(uri!(super::posts::details: blog = blog, slug = slug, responding_to = _)),
|
Redirect::to(uri!(
|
||||||
|
super::posts::details: blog = blog,
|
||||||
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)),
|
||||||
i18n!(&rockets.intl.catalog, "Your comment has been deleted."),
|
i18n!(&rockets.intl.catalog, "Your comment has been deleted."),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ use rocket::{
|
|||||||
use rocket_contrib::json::Json;
|
use rocket_contrib::json::Json;
|
||||||
use rocket_i18n::I18n;
|
use rocket_i18n::I18n;
|
||||||
use scheduled_thread_pool::ScheduledThreadPool;
|
use scheduled_thread_pool::ScheduledThreadPool;
|
||||||
use serde_json;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use validator::{Validate, ValidationErrors};
|
use validator::{Validate, ValidationErrors};
|
||||||
|
|
||||||
@ -409,9 +408,14 @@ pub fn interact(rockets: PlumeRocket, user: Option<User>, target: String) -> Opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(post) = Post::from_id(&rockets, &target, None, CONFIG.proxy()) {
|
if let Ok(post) = Post::from_id(&rockets, &target, None, CONFIG.proxy()) {
|
||||||
return Some(Redirect::to(
|
return Some(Redirect::to(uri!(
|
||||||
uri!(super::posts::details: blog = post.get_blog(&rockets.conn).expect("Can't retrieve blog").fqn, slug = &post.slug, responding_to = _),
|
super::posts::details: blog = post
|
||||||
));
|
.get_blog(&rockets.conn)
|
||||||
|
.expect("Can't retrieve blog")
|
||||||
|
.fqn,
|
||||||
|
slug = &post.slug,
|
||||||
|
responding_to = _
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(comment) = Comment::from_id(&rockets, &target, None, CONFIG.proxy()) {
|
if let Ok(comment) = Comment::from_id(&rockets, &target, None, CONFIG.proxy()) {
|
||||||
|
@ -45,9 +45,11 @@ pub fn create(
|
|||||||
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Redirect::to(
|
Ok(Redirect::to(uri!(
|
||||||
uri!(super::posts::details: blog = blog, slug = slug, responding_to = _),
|
super::posts::details: blog = blog,
|
||||||
))
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/~/<blog>/<slug>/like", rank = 2)]
|
#[post("/~/<blog>/<slug>/like", rank = 2)]
|
||||||
|
@ -45,7 +45,7 @@ pub fn upload(
|
|||||||
let (_, boundary) = ct
|
let (_, boundary) = ct
|
||||||
.params()
|
.params()
|
||||||
.find(|&(k, _)| k == "boundary")
|
.find(|&(k, _)| k == "boundary")
|
||||||
.ok_or_else(|| status::BadRequest(Some("No boundary")))?;
|
.ok_or(status::BadRequest(Some("No boundary")))?;
|
||||||
|
|
||||||
if let SaveResult::Full(entries) = Multipart::with_body(data.open(), boundary).save().temp() {
|
if let SaveResult::Full(entries) = Multipart::with_body(data.open(), boundary).save().temp() {
|
||||||
let fields = entries.fields;
|
let fields = entries.fields;
|
||||||
@ -53,7 +53,7 @@ pub fn upload(
|
|||||||
let filename = fields
|
let filename = fields
|
||||||
.get("file")
|
.get("file")
|
||||||
.and_then(|v| v.iter().next())
|
.and_then(|v| v.iter().next())
|
||||||
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?
|
.ok_or(status::BadRequest(Some("No file uploaded")))?
|
||||||
.headers
|
.headers
|
||||||
.filename
|
.filename
|
||||||
.clone();
|
.clone();
|
||||||
|
@ -246,8 +246,9 @@ pub fn theme_files(file: PathBuf, _build_id: &RawStr) -> Option<ThemeFile> {
|
|||||||
.map(ThemeFile)
|
.map(ThemeFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/static/cached/<_build_id>/<file..>", rank = 2)]
|
#[allow(unused_variables)]
|
||||||
pub fn plume_static_files(file: PathBuf, _build_id: &RawStr) -> Option<CachedFile> {
|
#[get("/static/cached/<build_id>/<file..>", rank = 2)]
|
||||||
|
pub fn plume_static_files(file: PathBuf, build_id: &RawStr) -> Option<CachedFile> {
|
||||||
static_files(file)
|
static_files(file)
|
||||||
}
|
}
|
||||||
#[get("/static/media/<file..>")]
|
#[get("/static/media/<file..>")]
|
||||||
|
@ -356,7 +356,11 @@ pub fn update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Flash::success(
|
Flash::success(
|
||||||
Redirect::to(uri!(details: blog = blog, slug = new_slug, responding_to = _)),
|
Redirect::to(uri!(
|
||||||
|
details: blog = blog,
|
||||||
|
slug = new_slug,
|
||||||
|
responding_to = _
|
||||||
|
)),
|
||||||
i18n!(intl, "Your article has been updated."),
|
i18n!(intl, "Your article has been updated."),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
@ -543,7 +547,11 @@ pub fn create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Flash::success(
|
Ok(Flash::success(
|
||||||
Redirect::to(uri!(details: blog = blog_name, slug = slug, responding_to = _)),
|
Redirect::to(uri!(
|
||||||
|
details: blog = blog_name,
|
||||||
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)),
|
||||||
i18n!(&rockets.intl.catalog, "Your article has been saved."),
|
i18n!(&rockets.intl.catalog, "Your article has been saved."),
|
||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
@ -583,7 +591,11 @@ pub fn delete(
|
|||||||
.any(|a| a.id == user.id)
|
.any(|a| a.id == user.id)
|
||||||
{
|
{
|
||||||
return Ok(Flash::error(
|
return Ok(Flash::error(
|
||||||
Redirect::to(uri!(details: blog = blog_name, slug = slug, responding_to = _)),
|
Redirect::to(uri!(
|
||||||
|
details: blog = blog_name,
|
||||||
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)),
|
||||||
i18n!(intl.catalog, "You are not allowed to delete this article."),
|
i18n!(intl.catalog, "You are not allowed to delete this article."),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,11 @@ pub fn create(
|
|||||||
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Redirect::to(
|
Ok(Redirect::to(uri!(
|
||||||
uri!(super::posts::details: blog = blog, slug = slug, responding_to = _),
|
super::posts::details: blog = blog,
|
||||||
))
|
slug = slug,
|
||||||
|
responding_to = _
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/~/<blog>/<slug>/reshare", rank = 1)]
|
#[post("/~/<blog>/<slug>/reshare", rank = 1)]
|
||||||
|
@ -55,8 +55,7 @@ pub fn search(query: Option<Form<SearchQuery>>, rockets: PlumeRocket) -> Ructe {
|
|||||||
let query = query.map(Form::into_inner).unwrap_or_default();
|
let query = query.map(Form::into_inner).unwrap_or_default();
|
||||||
let page = query.page.unwrap_or_default();
|
let page = query.page.unwrap_or_default();
|
||||||
let mut parsed_query =
|
let mut parsed_query =
|
||||||
Query::from_str(&query.q.as_ref().map(String::as_str).unwrap_or_default())
|
Query::from_str(&query.q.as_deref().unwrap_or_default()).unwrap_or_default();
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
param_to_query!(query, parsed_query; normal: title, subtitle, content, tag,
|
param_to_query!(query, parsed_query; normal: title, subtitle, content, tag,
|
||||||
instance, author, blog, lang, license;
|
instance, author, blog, lang, license;
|
||||||
|
@ -210,9 +210,7 @@ pub fn password_reset(
|
|||||||
.map_err(|err| password_reset_error_response(err, &rockets))?;
|
.map_err(|err| password_reset_error_response(err, &rockets))?;
|
||||||
|
|
||||||
Ok(Flash::success(
|
Ok(Flash::success(
|
||||||
Redirect::to(uri!(
|
Redirect::to(uri!(new: m = _)),
|
||||||
new: m = _
|
|
||||||
)),
|
|
||||||
i18n!(
|
i18n!(
|
||||||
rockets.intl.catalog,
|
rockets.intl.catalog,
|
||||||
"Your password was successfully reset."
|
"Your password was successfully reset."
|
||||||
|
@ -9,7 +9,6 @@ use rocket::{
|
|||||||
response::{status, Content, Flash, Redirect},
|
response::{status, Content, Flash, Redirect},
|
||||||
};
|
};
|
||||||
use rocket_i18n::I18n;
|
use rocket_i18n::I18n;
|
||||||
use serde_json;
|
|
||||||
use std::{borrow::Cow, collections::HashMap};
|
use std::{borrow::Cow, collections::HashMap};
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use validator::{Validate, ValidationError, ValidationErrors};
|
use validator::{Validate, ValidationError, ValidationErrors};
|
||||||
@ -379,9 +378,10 @@ pub struct UpdateUserForm {
|
|||||||
pub hide_custom_css: bool,
|
pub hide_custom_css: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/@/<_name>/edit", data = "<form>")]
|
#[allow(unused_variables)]
|
||||||
|
#[put("/@/<name>/edit", data = "<form>")]
|
||||||
pub fn update(
|
pub fn update(
|
||||||
_name: String,
|
name: String,
|
||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
mut user: User,
|
mut user: User,
|
||||||
form: LenientForm<UpdateUserForm>,
|
form: LenientForm<UpdateUserForm>,
|
||||||
@ -402,7 +402,7 @@ pub fn update(
|
|||||||
user.preferred_theme = form
|
user.preferred_theme = form
|
||||||
.theme
|
.theme
|
||||||
.clone()
|
.clone()
|
||||||
.and_then(|t| if &t == "" { None } else { Some(t) });
|
.and_then(|t| if t.is_empty() { None } else { Some(t) });
|
||||||
user.hide_custom_css = form.hide_custom_css;
|
user.hide_custom_css = form.hide_custom_css;
|
||||||
let _: User = user.save_changes(&*conn).map_err(Error::from)?;
|
let _: User = user.save_changes(&*conn).map_err(Error::from)?;
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use rocket::http::ContentType;
|
use rocket::http::ContentType;
|
||||||
use rocket::response::Content;
|
use rocket::response::Content;
|
||||||
use serde_json;
|
|
||||||
use webfinger::*;
|
use webfinger::*;
|
||||||
|
|
||||||
use plume_models::{ap_url, blogs::Blog, users::User, PlumeRocket, CONFIG};
|
use plume_models::{ap_url, blogs::Blog, users::User, PlumeRocket, CONFIG};
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>@title ⋅ @i18n!(ctx.1, "Plume")</title>
|
<title>@title ⋅ @i18n!(ctx.1, "Plume")</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(ctx.2.clone().and_then(|u| u.preferred_theme).unwrap_or_else(|| CONFIG.default_theme.clone())).join("theme.css"), _build_id = CACHE_NAME)" />
|
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(ctx.2.clone().and_then(|u| u.preferred_theme).unwrap_or_else(|| CONFIG.default_theme.clone())).join("theme.css"), build_id = CACHE_NAME)" />
|
||||||
<link rel="manifest" href="@uri!(instance::web_manifest)" />
|
<link rel="manifest" href="@uri!(instance::web_manifest)" />
|
||||||
<link rel="icon" type="image/png" href="@uri!(plume_static_files: file = CONFIG.logo.favicon.as_str(), _build_id = CACHE_NAME)">
|
<link rel="icon" type="image/png" href="@uri!(plume_static_files: file = CONFIG.logo.favicon.as_str(), build_id = CACHE_NAME)">
|
||||||
<meta content='#282c37' name='theme-color'/>
|
<meta content='#282c37' name='theme-color'/>
|
||||||
@:head()
|
@:head()
|
||||||
</head>
|
</head>
|
||||||
@ -26,7 +26,7 @@
|
|||||||
<div id="content">
|
<div id="content">
|
||||||
<nav>
|
<nav>
|
||||||
<a href="@uri!(instance::index)" class="title">
|
<a href="@uri!(instance::index)" class="title">
|
||||||
<img src="@uri!(plume_static_files: file = CONFIG.logo.main.as_str(), _build_id = CACHE_NAME)">
|
<img src="@uri!(plume_static_files: file = CONFIG.logo.main.as_str(), build_id = CACHE_NAME)">
|
||||||
<p>@i18n!(ctx.1, "Plume")</p>
|
<p>@i18n!(ctx.1, "Plume")</p>
|
||||||
</a>
|
</a>
|
||||||
<hr/>
|
<hr/>
|
||||||
@ -96,6 +96,6 @@
|
|||||||
<a href="https://matrix.to/#/#plume-blog:matrix.org">@i18n!(ctx.1, "Matrix room")</a>
|
<a href="https://matrix.to/#/#plume-blog:matrix.org">@i18n!(ctx.1, "Matrix room")</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="@uri!(plume_static_files: file = "plume-front.js", _build_id = CACHE_NAME)"></script>
|
<script src="@uri!(plume_static_files: file = "plume-front.js", build_id = CACHE_NAME)"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<link href='@blog.ap_url' rel='canonical'>
|
<link href='@blog.ap_url' rel='canonical'>
|
||||||
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
||||||
@if let Some(ref theme) = blog.theme {
|
@if let Some(ref theme) = blog.theme {
|
||||||
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(theme).join("theme.css"), _build_id = CACHE_NAME)">
|
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(theme).join("theme.css"), build_id = CACHE_NAME)">
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
}
|
}
|
||||||
</main>
|
</main>
|
||||||
@for res in &comment_tree.responses {
|
@for res in &comment_tree.responses {
|
||||||
@:comment_html(ctx, res, comm.ap_url.as_ref().map(|u| &**u), blog, slug)
|
@:comment_html(ctx, res, comm.ap_url.as_deref(), blog, slug)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}}
|
}}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
||||||
@if let Some(ref theme) = blog.theme {
|
@if let Some(ref theme) = blog.theme {
|
||||||
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(theme).join("theme.css"), _build_id = CACHE_NAME)">
|
<link rel="stylesheet" href="@uri!(plume_static_files: file = Path::new("css").join(theme).join("theme.css"), build_id = CACHE_NAME)">
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
@i18n!(ctx.1, "To change your avatar, upload it to your gallery and then select from there.")
|
@i18n!(ctx.1, "To change your avatar, upload it to your gallery and then select from there.")
|
||||||
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload an avatar")</a>
|
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload an avatar")</a>
|
||||||
</p>
|
</p>
|
||||||
<form method="post" action="@uri!(user::update: _name = u.username.clone())">
|
<form method="post" action="@uri!(user::update: name = u.username.clone())">
|
||||||
<!-- Rocket hack to use various HTTP methods -->
|
<!-- Rocket hack to use various HTTP methods -->
|
||||||
<input type=hidden name="_method" value="put">
|
<input type=hidden name="_method" value="put">
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user