mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-26 21:41:04 +00:00
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
85 changed files with 24854 additions and 24891 deletions
|
@ -71,7 +71,7 @@ commands:
|
|||
type: string
|
||||
steps:
|
||||
- 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
|
||||
<< parameters.cmd >>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ RUN apt update &&\
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#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 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 std::process::{Command, Stdio};
|
||||
use std::{ffi::OsStr, fs::*, io::Write, path::*};
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use dotenv;
|
||||
|
||||
use clap::App;
|
||||
use diesel::Connection;
|
||||
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();
|
||||
}
|
||||
|
||||
fn unlock<'a>(args: &ArgMatches<'a>) {
|
||||
fn unlock(args: &ArgMatches) {
|
||||
let path = match args.value_of("path") {
|
||||
None => Path::new(&CONFIG.search_index),
|
||||
Some(x) => Path::new(x),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
|
||||
use plume_models::{instance::Instance, users::*, Connection};
|
||||
use rpassword;
|
||||
use std::io::{self, Write};
|
||||
|
||||
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
||||
|
|
|
@ -7,7 +7,6 @@ use rocket::{
|
|||
response::{Responder, Response},
|
||||
Outcome,
|
||||
};
|
||||
use serde_json;
|
||||
use tokio::prelude::*;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use base64;
|
||||
use chrono::{offset::Utc, DateTime};
|
||||
use openssl::hash::{Hasher, MessageDigest};
|
||||
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"));
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error();
|
||||
|
||||
pub struct Digest(String);
|
||||
|
||||
impl Digest {
|
||||
|
@ -62,16 +64,16 @@ impl Digest {
|
|||
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('=') {
|
||||
let pos = pos + 1;
|
||||
if base64::decode(&dig[pos..]).is_ok() {
|
||||
Ok(Digest(dig.to_owned()))
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error())
|
||||
}
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +112,7 @@ pub fn headers() -> HeaderMap {
|
|||
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
|
||||
.iter()
|
||||
.map(|(h, v)| {
|
||||
|
@ -130,7 +132,7 @@ pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderVal
|
|||
.join(" ")
|
||||
.to_lowercase();
|
||||
|
||||
let data = signer.sign(&signed_string).map_err(|_| ())?;
|
||||
let data = signer.sign(&signed_string).map_err(|_| Error())?;
|
||||
let sign = base64::encode(&data);
|
||||
|
||||
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(),
|
||||
signed_headers = signed_headers,
|
||||
signature = sign
|
||||
)).map_err(|_| ())
|
||||
)).map_err(|_| Error())
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use super::request;
|
||||
use base64;
|
||||
use chrono::{naive::NaiveDateTime, DateTime, Duration, Utc};
|
||||
use hex;
|
||||
use openssl::{pkey::PKey, rsa::Rsa, sha::sha256};
|
||||
use rocket::http::HeaderMap;
|
||||
use serde_json;
|
||||
|
||||
/// Returns (public key, private key)
|
||||
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 {
|
||||
type Error;
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub trait Signer {
|
|||
}
|
||||
|
||||
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
|
||||
T: Signer;
|
||||
fn verify<T>(self, creator: &T) -> bool
|
||||
|
@ -46,7 +46,7 @@ pub trait Signable {
|
|||
}
|
||||
|
||||
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 mut options = json!({
|
||||
"type": "RsaSignature2017",
|
||||
|
@ -64,7 +64,7 @@ impl Signable for serde_json::Value {
|
|||
let document_hash = Self::hash(&self.to_string());
|
||||
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);
|
||||
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]
|
||||
extern crate activitystreams_derive;
|
||||
use activitystreams_traits;
|
||||
|
||||
use serde;
|
||||
#[macro_use]
|
||||
extern crate shrinkwraprs;
|
||||
#[macro_use]
|
||||
|
|
|
@ -60,6 +60,7 @@ fn to_inline(tag: Tag<'_>) -> Tag<'_> {
|
|||
struct HighlighterContext {
|
||||
content: Vec<String>,
|
||||
}
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn highlight_code<'a>(
|
||||
context: &mut Option<HighlighterContext>,
|
||||
evt: Event<'a>,
|
||||
|
@ -119,6 +120,7 @@ fn highlight_code<'a>(
|
|||
_ => Some(vec![evt]),
|
||||
}
|
||||
}
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Event<'a>>> {
|
||||
let (s, res) = match evt {
|
||||
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)
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn inline_tags<'a>(
|
||||
(state, inline): &mut (Vec<Tag<'a>>, bool),
|
||||
evt: Event<'a>,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::CATALOG;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::sync::Mutex;
|
||||
use stdweb::{
|
||||
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![];
|
||||
for line in file.lines() {
|
||||
if sql {
|
||||
if line.starts_with("--#!") {
|
||||
if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||
if !acc.trim().is_empty() {
|
||||
actions.push(quote!(Action::Sql(#acc)));
|
||||
}
|
||||
sql = false;
|
||||
acc = line[4..].to_string();
|
||||
acc = acc_str.to_string();
|
||||
acc.push('\n');
|
||||
} else if line.starts_with("--") {
|
||||
continue;
|
||||
|
@ -102,8 +102,8 @@ fn file_to_migration(file: &str) -> TokenStream2 {
|
|||
acc.push_str(line);
|
||||
acc.push('\n');
|
||||
}
|
||||
} else if line.starts_with("--#!") {
|
||||
acc.push_str(&line[4..]);
|
||||
} else if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||
acc.push_str(&acc_str);
|
||||
acc.push('\n');
|
||||
} else if line.starts_with("--") {
|
||||
continue;
|
||||
|
|
|
@ -23,7 +23,7 @@ scheduled-thread-pool = "0.2.2"
|
|||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
tantivy = "0.12.0"
|
||||
tantivy = "0.13.3"
|
||||
url = "2.1"
|
||||
walkdir = "2.2"
|
||||
webfinger = "0.4.1"
|
||||
|
@ -31,7 +31,7 @@ whatlang = "0.11.1"
|
|||
shrinkwraprs = "0.2.1"
|
||||
diesel-derive-newtype = "0.1.2"
|
||||
glob = "0.3.0"
|
||||
lindera-tantivy = { version = "0.1.3", optional = true }
|
||||
lindera-tantivy = { version = "0.7.1", optional = true }
|
||||
tracing = "0.1.22"
|
||||
|
||||
[dependencies.chrono]
|
||||
|
|
|
@ -20,7 +20,6 @@ use plume_common::activity_pub::{
|
|||
inbox::{AsActor, FromId},
|
||||
sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source,
|
||||
};
|
||||
use serde_json;
|
||||
use url::Url;
|
||||
use webfinger::*;
|
||||
|
||||
|
@ -217,16 +216,16 @@ impl Blog {
|
|||
|
||||
pub fn outbox(&self, conn: &Connection) -> Result<ActivityStream<OrderedCollection>> {
|
||||
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
|
||||
.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
|
||||
.set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?;
|
||||
coll.collection_props
|
||||
.set_last_link(Id::new(ap_url(&format!(
|
||||
"{}?page={}",
|
||||
&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
|
||||
))))?;
|
||||
Ok(ActivityStream::new(coll))
|
||||
|
@ -237,7 +236,7 @@ impl Blog {
|
|||
(min, max): (i32, i32),
|
||||
) -> Result<ActivityStream<OrderedCollectionPage>> {
|
||||
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
|
||||
//doesn't do anything yet
|
||||
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)?;
|
||||
Ok(ActivityStream::new(coll))
|
||||
}
|
||||
fn get_activities(&self, _conn: &Connection) -> Result<Vec<serde_json::Value>> {
|
||||
Ok(vec![])
|
||||
fn get_activities(&self, _conn: &Connection) -> Vec<serde_json::Value> {
|
||||
vec![]
|
||||
}
|
||||
fn get_activity_page(
|
||||
&self,
|
||||
_conn: &Connection,
|
||||
(_min, _max): (i32, i32),
|
||||
) -> Result<Vec<serde_json::Value>> {
|
||||
Ok(vec![])
|
||||
) -> Vec<serde_json::Value> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
pub fn get_keypair(&self) -> Result<PKey<Private>> {
|
||||
|
|
|
@ -24,7 +24,6 @@ use plume_common::{
|
|||
},
|
||||
utils,
|
||||
};
|
||||
use serde_json;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
||||
|
|
|
@ -164,8 +164,8 @@ impl Default for LogoConfig {
|
|||
};
|
||||
let mut custom_icons = env::vars()
|
||||
.filter_map(|(var, val)| {
|
||||
if var.starts_with("PLUME_LOGO_") {
|
||||
Some((var[11..].to_owned(), val))
|
||||
if let Some(size) = var.strip_prefix("PLUME_LOGO_") {
|
||||
Some((size.to_owned(), val))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||
let proxy_url = url.clone();
|
||||
let only_domains: Option<HashSet<String>> = var("PROXY_DOMAINS")
|
||||
.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 only_domains = only_domains.clone();
|
||||
reqwest::Proxy::custom(move |url| {
|
||||
|
@ -303,9 +303,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||
if only_domains.contains(domain)
|
||||
|| only_domains
|
||||
.iter()
|
||||
.filter(|target| domain.ends_with(&format!(".{}", target)))
|
||||
.next()
|
||||
.is_some()
|
||||
.any(|target| domain.ends_with(&format!(".{}", target)))
|
||||
{
|
||||
Some(proxy_url.clone())
|
||||
} else {
|
||||
|
@ -316,9 +314,7 @@ fn get_proxy_config() -> Option<ProxyConfig> {
|
|||
}
|
||||
})
|
||||
} else {
|
||||
reqwest::Proxy::all(proxy_url)
|
||||
.ok()
|
||||
.expect("Invalid PROXY_URL")
|
||||
reqwest::Proxy::all(proxy_url).expect("Invalid PROXY_URL")
|
||||
};
|
||||
Some(ProxyConfig {
|
||||
url,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use activitypub::activity::*;
|
||||
use serde_json;
|
||||
|
||||
use crate::{
|
||||
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;
|
||||
#[macro_use]
|
||||
extern crate rocket;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
|
|
|
@ -30,9 +30,9 @@ impl TryFrom<i32> for ListType {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<i32> for ListType {
|
||||
fn into(self) -> i32 {
|
||||
match self {
|
||||
impl From<ListType> for i32 {
|
||||
fn from(list_type: ListType) -> Self {
|
||||
match list_type {
|
||||
ListType::User => 0,
|
||||
ListType::Blog => 1,
|
||||
ListType::Word => 2,
|
||||
|
@ -246,22 +246,22 @@ impl List {
|
|||
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}
|
||||
|
||||
/// Insert new blogs in a list
|
||||
// Insert new blogs in a list
|
||||
func! {add: add_blogs, Blog}
|
||||
|
||||
/// Insert new words in a list
|
||||
// Insert new words in a list
|
||||
func! {add: add_words, Word}
|
||||
|
||||
/// Insert new prefixes in a list
|
||||
// Insert new prefixes in a list
|
||||
func! {add: add_prefixes, Prefix}
|
||||
|
||||
/// Get all users in the list
|
||||
// Get all users in the list
|
||||
func! {list: list_users, User, users}
|
||||
|
||||
/// Get all blogs in the list
|
||||
// Get all blogs in the list
|
||||
func! {list: list_blogs, Blog, blogs}
|
||||
|
||||
/// Get all words in the list
|
||||
|
|
|
@ -10,7 +10,6 @@ use plume_common::{
|
|||
activity_pub::{inbox::FromId, Id},
|
||||
utils::MediaProcessor,
|
||||
};
|
||||
use reqwest;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
#[derive(Clone, Identifiable, Queryable)]
|
||||
|
|
|
@ -19,7 +19,6 @@ use plume_common::{
|
|||
},
|
||||
utils::md_to_html,
|
||||
};
|
||||
use serde_json;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
||||
|
@ -124,8 +123,7 @@ impl Post {
|
|||
.filter(posts::published.eq(true))
|
||||
.count()
|
||||
.load(conn)?
|
||||
.iter()
|
||||
.next()
|
||||
.get(0)
|
||||
.cloned()
|
||||
.ok_or(Error::NotFound)
|
||||
}
|
||||
|
@ -288,12 +286,11 @@ impl Post {
|
|||
}
|
||||
|
||||
pub fn get_receivers_urls(&self, conn: &Connection) -> Result<Vec<String>> {
|
||||
let followers = self
|
||||
Ok(self
|
||||
.get_authors(conn)?
|
||||
.into_iter()
|
||||
.filter_map(|a| a.get_followers(conn).ok())
|
||||
.collect::<Vec<Vec<User>>>();
|
||||
Ok(followers.into_iter().fold(vec![], |mut acc, f| {
|
||||
.fold(vec![], |mut acc, f| {
|
||||
for x in f {
|
||||
acc.push(x.ap_url);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn url_add_prefix(url: &str) -> Option<Cow<'_, str>> {
|
||||
if url.starts_with('#') && !url.starts_with("#postcontent-") {
|
||||
//if start with an #
|
||||
|
|
|
@ -11,7 +11,6 @@ use activitypub::{
|
|||
object::{Image, Tombstone},
|
||||
Activity, CustomObject, Endpoint,
|
||||
};
|
||||
use bcrypt;
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
||||
|
@ -38,7 +37,6 @@ use rocket::{
|
|||
outcome::IntoOutcome,
|
||||
request::{self, FromRequest, Request},
|
||||
};
|
||||
use serde_json;
|
||||
use std::{
|
||||
cmp::PartialEq,
|
||||
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},
|
||||
};
|
||||
use rocket_contrib::json::Json;
|
||||
use serde_json;
|
||||
|
||||
use plume_common::utils::random_hex;
|
||||
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::time::Duration;
|
||||
use tracing::warn;
|
||||
use tracing_subscriber;
|
||||
|
||||
init_i18n!(
|
||||
"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(
|
||||
Redirect::to(
|
||||
uri!(super::posts::details: blog = blog_name, slug = slug, responding_to = _),
|
||||
),
|
||||
Redirect::to(uri!(
|
||||
super::posts::details: blog = blog_name,
|
||||
slug = slug,
|
||||
responding_to = _
|
||||
)),
|
||||
i18n!(&rockets.intl.catalog, "Your comment has been posted."),
|
||||
)
|
||||
})
|
||||
|
@ -168,7 +170,11 @@ pub fn delete(
|
|||
}
|
||||
}
|
||||
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."),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use rocket::{
|
|||
use rocket_contrib::json::Json;
|
||||
use rocket_i18n::I18n;
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use serde_json;
|
||||
use std::str::FromStr;
|
||||
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()) {
|
||||
return Some(Redirect::to(
|
||||
uri!(super::posts::details: blog = post.get_blog(&rockets.conn).expect("Can't retrieve blog").fqn, slug = &post.slug, responding_to = _),
|
||||
));
|
||||
return Some(Redirect::to(uri!(
|
||||
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()) {
|
||||
|
|
|
@ -45,9 +45,11 @@ pub fn create(
|
|||
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
||||
}
|
||||
|
||||
Ok(Redirect::to(
|
||||
uri!(super::posts::details: blog = blog, slug = slug, responding_to = _),
|
||||
))
|
||||
Ok(Redirect::to(uri!(
|
||||
super::posts::details: blog = blog,
|
||||
slug = slug,
|
||||
responding_to = _
|
||||
)))
|
||||
}
|
||||
|
||||
#[post("/~/<blog>/<slug>/like", rank = 2)]
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn upload(
|
|||
let (_, boundary) = ct
|
||||
.params()
|
||||
.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() {
|
||||
let fields = entries.fields;
|
||||
|
@ -53,7 +53,7 @@ pub fn upload(
|
|||
let filename = fields
|
||||
.get("file")
|
||||
.and_then(|v| v.iter().next())
|
||||
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?
|
||||
.ok_or(status::BadRequest(Some("No file uploaded")))?
|
||||
.headers
|
||||
.filename
|
||||
.clone();
|
||||
|
|
|
@ -246,8 +246,9 @@ pub fn theme_files(file: PathBuf, _build_id: &RawStr) -> Option<ThemeFile> {
|
|||
.map(ThemeFile)
|
||||
}
|
||||
|
||||
#[get("/static/cached/<_build_id>/<file..>", rank = 2)]
|
||||
pub fn plume_static_files(file: PathBuf, _build_id: &RawStr) -> Option<CachedFile> {
|
||||
#[allow(unused_variables)]
|
||||
#[get("/static/cached/<build_id>/<file..>", rank = 2)]
|
||||
pub fn plume_static_files(file: PathBuf, build_id: &RawStr) -> Option<CachedFile> {
|
||||
static_files(file)
|
||||
}
|
||||
#[get("/static/media/<file..>")]
|
||||
|
|
|
@ -356,7 +356,11 @@ pub fn update(
|
|||
}
|
||||
|
||||
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."),
|
||||
)
|
||||
.into()
|
||||
|
@ -543,7 +547,11 @@ pub fn create(
|
|||
}
|
||||
|
||||
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."),
|
||||
)
|
||||
.into())
|
||||
|
@ -583,7 +591,11 @@ pub fn delete(
|
|||
.any(|a| a.id == user.id)
|
||||
{
|
||||
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."),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -45,9 +45,11 @@ pub fn create(
|
|||
.execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned()));
|
||||
}
|
||||
|
||||
Ok(Redirect::to(
|
||||
uri!(super::posts::details: blog = blog, slug = slug, responding_to = _),
|
||||
))
|
||||
Ok(Redirect::to(uri!(
|
||||
super::posts::details: blog = blog,
|
||||
slug = slug,
|
||||
responding_to = _
|
||||
)))
|
||||
}
|
||||
|
||||
#[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 page = query.page.unwrap_or_default();
|
||||
let mut parsed_query =
|
||||
Query::from_str(&query.q.as_ref().map(String::as_str).unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
Query::from_str(&query.q.as_deref().unwrap_or_default()).unwrap_or_default();
|
||||
|
||||
param_to_query!(query, parsed_query; normal: title, subtitle, content, tag,
|
||||
instance, author, blog, lang, license;
|
||||
|
|
|
@ -210,9 +210,7 @@ pub fn password_reset(
|
|||
.map_err(|err| password_reset_error_response(err, &rockets))?;
|
||||
|
||||
Ok(Flash::success(
|
||||
Redirect::to(uri!(
|
||||
new: m = _
|
||||
)),
|
||||
Redirect::to(uri!(new: m = _)),
|
||||
i18n!(
|
||||
rockets.intl.catalog,
|
||||
"Your password was successfully reset."
|
||||
|
|
|
@ -9,7 +9,6 @@ use rocket::{
|
|||
response::{status, Content, Flash, Redirect},
|
||||
};
|
||||
use rocket_i18n::I18n;
|
||||
use serde_json;
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use tracing::{info, warn};
|
||||
use validator::{Validate, ValidationError, ValidationErrors};
|
||||
|
@ -379,9 +378,10 @@ pub struct UpdateUserForm {
|
|||
pub hide_custom_css: bool,
|
||||
}
|
||||
|
||||
#[put("/@/<_name>/edit", data = "<form>")]
|
||||
#[allow(unused_variables)]
|
||||
#[put("/@/<name>/edit", data = "<form>")]
|
||||
pub fn update(
|
||||
_name: String,
|
||||
name: String,
|
||||
conn: DbConn,
|
||||
mut user: User,
|
||||
form: LenientForm<UpdateUserForm>,
|
||||
|
@ -402,7 +402,7 @@ pub fn update(
|
|||
user.preferred_theme = form
|
||||
.theme
|
||||
.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;
|
||||
let _: User = user.save_changes(&*conn).map_err(Error::from)?;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use rocket::http::ContentType;
|
||||
use rocket::response::Content;
|
||||
use serde_json;
|
||||
use webfinger::*;
|
||||
|
||||
use plume_models::{ap_url, blogs::Blog, users::User, PlumeRocket, CONFIG};
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
<meta charset="utf-8" />
|
||||
<title>@title ⋅ @i18n!(ctx.1, "Plume")</title>
|
||||
<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="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'/>
|
||||
@:head()
|
||||
</head>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<div id="content">
|
||||
<nav>
|
||||
<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>
|
||||
</a>
|
||||
<hr/>
|
||||
|
@ -96,6 +96,6 @@
|
|||
<a href="https://matrix.to/#/#plume-blog:matrix.org">@i18n!(ctx.1, "Matrix room")</a>
|
||||
</div>
|
||||
</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>
|
||||
</html>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<link href='@blog.ap_url' rel='canonical'>
|
||||
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
||||
@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>
|
||||
@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>
|
||||
}}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
||||
@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.")
|
||||
<a href="@uri!(medias::new)">@i18n!(ctx.1, "Upload an avatar")</a>
|
||||
</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 -->
|
||||
<input type=hidden name="_method" value="put">
|
||||
|
||||
|
|
Loading…
Reference in a new issue